i stumbled around in the original firmware and came across the DMA
channels.
There seems to be a pair of dma channels reserved for graphics usage.
600D v1.0.1
0xF075CB8 int __cdecl dma_memcpy(unsigned __int8 *dest, unsigned
__int8 *src, int length, void *callback);
From task context you can call this function to copy specified data
around and after it is done, your callback function gets called.
I tried it with bmp_idle_copy and it works fine. It should be slightly
better than LDR/STR memcpy.
The big advantage is that you can do your memcpy asynchronously.
But beware not to start another dma_memcpy within the callback
handler.
When testing, it conflicted with liveview after some time. I guess the
reason is the semaphore at dword_89A8 that
gets locked by liveview (sub_FF278B18) and only is released in its
callback handler (sub_FF27818C).
If we are locking DMA all the time and block the dma again during
interrupt (i guess), it never gets unlocked.
Is there some reason why DMA is not used yet?
BR,
g3gg0
I suppose the reason is that we do not know how it works...
If you can explain more on this, maybe it can be used within Magic
Lantern.
what are those DMA channels and how does it work ?
Kind regards,
Indy
DMA channels are hardware blocks that do not more than loading data
from a memory bus and writing it again.
E.g. you set up "copy 8192 byte from address a to b".
The DMA controller does that copy operation without any CPU
interaction.
This means you have a copy operation that is a) expensive to set up
but b) is very fast and c) causes no CPU load.
When doing memcpy, you are faster than DMA memcpy if you copy maybe up
to 100 byte.
For graphics copy operation i would prefer using the DMA controller.
We paint the menu in some backbuffer and when done, fire the DMA
memcpy and return to the next task.
Now the menu gets displayed (written into VRAM) while the CPU alreay
executes the next tasks.
Less flickering and less CPU load.
Just give it a try, its not much more complicated than memcpy ;)
example: (bmp.c)
volatile int bmp_dma_done = 0;
void bmp_dma_cb() { bmp_dma_done = 1; }
void bmp_idle_copy(int direction)
{
uint8_t* real = bmp_vram_real();
uint8_t* idle = bmp_vram_idle();
bmp_dma_done = 0;
if(direction)
dma_memcpy(real, idle, BMP_HEIGHT * BMPPITCH, bmp_dma_cb);
else
dma_memcpy(idle, real, BMP_HEIGHT * BMPPITCH, bmp_dma_cb);
/* actively wait for DMA being finished, the other code needs to
be touched to run asynchronously */
while(bmp_dma_done == 0);
}
This code just uses DMA memcpy for transferring the idle buffer into
vram buffer.
I think it should already be a speedup, although we are waiting
actively for DMA to finish.
On modern CPUs (not our CPU) have seen that using DMA speeds up memcpy
by factor ~2.5.
BR,
g3gg0
Which DMA channels are reserved for graphics ?
do you see any other usage of DMA ?
Indy
I have started a wiki page: http://magiclantern.wikia.com/wiki/DMA
Indy
But when looking at the code, yes 0xC0A10000 seems to be the DMA
controller base address.
0xC0A10000 DMA channel 0
+ 0x04 [32] unknown, written with 0x00 on DMA setup
+ 0x08 [32] control bits
--------------1----------------1 written when
---------------1---------------- gets set when (delta(source,dest)
& 0x1F) != 0
maybe some cache line issues
+ 0x10 [32] unknown, written with 0x00 on DMA setup
+ 0x14 [32] unknown, written with 0x07 on DMA setup (data
width?)
+ 0x18 [32] source address
+ 0x1C [32] destination address
+ 0x20 [32] transfer count (ignoring 2 LSB)
0xC0A11000 DMA channel 1 (see above)
BR,
g3gg0
int irq_register(char *name, unsigned int id, void *handler, void
*ctx)
which is at 0xFF1F5828 on 600D v1.0.1
its used to set up an interrupt handler like the DMA handler (ID =
0xA2 + channel#)
here a (auto generated) .idc for v1.0.1 on 600D for marking all calls
to irq_register.
there might be some interesting stuff to do with :)
#include <idc.idc>
static main()
{
MakeStr ( 0xFF01BFBC, BADADDR );
MakeRptCmt ( 0xFF01BDB0, "R1: 0x0056 - R0: VIDEODET - R2:
0xFF01BFA0 - R3: 0x0000 - " );
MakeStr ( 0xFF01BFCC, BADADDR );
MakeRptCmt ( 0xFF01BDC4, "R1: 0x0044 - R0: USBDET - R2: 0xFF01BFA0
- R3: 0x0000 - " );
MakeStr ( 0xFF01BFD8, BADADDR );
MakeRptCmt ( 0xFF01BDD8, "R1: 0x0054 - R0: HDMIDET - R2:
0xFF01BFA0 - R3: 0x0000 - " );
MakeStr ( 0xFF01BFE0, BADADDR );
MakeRptCmt ( 0xFF01BDEC, "R1: 0x0047 - R0: MICDET - R2: 0xFF01B428
- R3: 0x0000 - " );
MakeStr ( 0xFF01BFEC, BADADDR );
MakeRptCmt ( 0xFF01BE00, "R1: 0x0057 - R0: VARISW3 - R2:
0xFF01B428 - R3: 0x0000 - " );
MakeStr ( 0xFF0353F8, BADADDR );
MakeRptCmt ( 0xFF035268, "R1: 0x00C9 - R0: Fencing_A - R2: 0x0001
- R3: 0x0000 - " );
MakeStr ( 0xFF035780, BADADDR );
MakeRptCmt ( 0xFF0355D0, "R1: 0x00D0 - R0: Fencing_B - R2: 0x0000
- R3: 0x0000 - " );
MakeFunction ( 0xFF035798, BADADDR );
MakeStr ( 0xFF0359AC, BADADDR );
MakeRptCmt ( 0xFF03582C, "R1: 0x00D1 - R0: Fencing_C - R2:
0xFF034A18 - R3: 0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF05564C, "R1: 0x002C - R0: - R2: 0xFF055284 - R3:
0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF055660, "R1: 0x002D - R0: - R2: 0xFF055284 - R3:
0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF055674, "R1: 0x0042 - R0: - R2: 0xFF055284 - R3:
0x0000 - " );
MakeFunction ( 0xFF0560EC, BADADDR );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF056160, "R1: 0x0000 - R0: - R2: 0xFF0560C0 - R3:
0xFFFFFFFF - " );
MakeFunction ( 0xFF066930, BADADDR );
MakeFunction ( 0xFF066908, BADADDR );
MakeFunction ( 0xFF0668D8, BADADDR );
MakeStr ( 0xFF066B8C, BADADDR );
MakeRptCmt ( 0xFF066970, "R1: 0x0068 - R0: - R2: 0xFF066B90 - R3:
0x0000 - " );
MakeFunction ( 0xFF066930, BADADDR );
MakeFunction ( 0xFF066908, BADADDR );
MakeStr ( 0xFF066BAC, BADADDR );
MakeRptCmt ( 0xFF066984, "R1: 0x0069 - R0: Pb error - R2:
0xFF066B90 - R3: 0x0000 - " );
MakeFunction ( 0xFF06C358, BADADDR );
MakeStr ( 0xFF06C458, BADADDR );
MakeRptCmt ( 0xFF06C3B4, "R1: 0x0055 - R0: REMIN_ISR - R2:
0xFF06C1EC - R3: 0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF06D3C4, "R1: 0x0040 - R0: - R2: 0xFFFFFFFF - R3:
0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF06D3D8, "R1: 0x0002 - R0: - R2: 0xFF06D0AC - R3:
0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF06D3EC, "R1: 0x0001 - R0: - R2: 0xFF06D190 - R3:
0x0000 - " );
MakeStr ( 0xFF070644, BADADDR );
MakeRptCmt ( 0xFF070450, "R1: 0x0000 - R0: OCH_SPx - R2:
0xFF070288 - R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF07064C, BADADDR );
MakeRptCmt ( 0xFF070464, "R1: 0x0000 - R0: OCHxEPx - R2:
0xFF0702EC - R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF070654, BADADDR );
MakeRptCmt ( 0xFF070484, "R1: 0x0010 - R0: OC4_14 - R2: 0xFF0700A4
- R3: 0x0000 - " );
MakeStr ( 0xFF07065C, BADADDR );
MakeRptCmt ( 0xFF07049C, "R1: 0x0010 - R0: ICAPCHx - R2:
0xFF070350 - R3: 0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF074DCC, "R1: 0xFFFFFFFF - R0: - R2: 0xFF074C64 -
R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF075AB0, BADADDR );
MakeRptCmt ( 0xFF0759EC, "R1: 0x002F - R0: BLTDMA - R2: 0xFF075908
- R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF075AB0, BADADDR );
MakeRptCmt ( 0xFF075BA4, "R1: 0x002F - R0: BLTDMA - R2: 0xFF075908
- R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF075AB0, BADADDR );
MakeRptCmt ( 0xFF075D8C, "R1: 0x002F - R0: BLTDMA - R2: 0xFF075C3C
- R3: 0xFFFFFFFF - " );
MakeStr ( 0xFF075AB0, BADADDR );
MakeRptCmt ( 0xFF075F1C, "R1: 0x002F - R0: BLTDMA - R2: 0xFF075C3C
- R3: 0xFFFFFFFF - " );
MakeStr ( 0x00000007, BADADDR );
MakeRptCmt ( 0xFF0760D0, "R1: 0x002F - R0: - R2: 0xFF075F90 - R3:
0xFFFFFFFF - " );
MakeStr ( 0xFF079F04, BADADDR );
MakeRptCmt ( 0xFF079DA8, "R1: 0x009C - R0: SEQ - R2: 0xFF079C44 -
R3: 0x0000 - " );
MakeStr ( 0xFF1C3078, BADADDR );
MakeRptCmt ( 0xFF1C2DB0, "R1: 0x0052 - R0: IMGPOWDET - R2:
0xFF1C2D00 - R3: 0x0000 - " );
MakeStr ( 0xFF1D248C, BADADDR );
MakeRptCmt ( 0xFF1D229C, "R1: 0x007B - R0: DiUSB20Hal - R2:
0xFF1D1F58 - R3: 0x0000 - " );
MakeFunction ( 0xFF1DB44C, BADADDR );
MakeStr ( 0xFF1DB70C, BADADDR );
MakeRptCmt ( 0xFF1DB4E0, "R1: 0x0014 - R0: MREQ_ISR - R2:
0xFF1DB324 - R3: 0x0000 - " );
MakeStr ( 0xFF1DB718, BADADDR );
MakeRptCmt ( 0xFF1DB4F4, "R1: 0x0036 - R0: SIO3_ISR - R2:
0xFF1DB3B4 - R3: 0x0000 - " );
MakeFunction ( 0xFF1E033C, BADADDR );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF1E03A8, "R1: 0x0000 - R0: - R2: 0xFFFFFFFF - R3:
0xFF1DFF84 - " );
MakeFunction ( 0xFF1E246C, BADADDR );
MakeStr ( 0xFF1E2684, BADADDR );
MakeRptCmt ( 0xFF1E24E8, "R1: 0x0064 - R0: JpCoreIntrHandler - R2:
0xFF1E2140 - R3: 0x0000 - " );
MakeFunction ( 0xFF1E2EF8, BADADDR );
MakeStr ( 0xFF1E3170, BADADDR );
MakeRptCmt ( 0xFF1E2F90, "R1: 0x00A3 - R0: JpCore2IntrHandler -
R2: 0xFF1E2CD8 - R3: 0x0000 - " );
MakeFunction ( 0xFF2DCBC0, BADADDR );
MakeFunction ( 0xFF2DCB8C, BADADDR );
MakeFunction ( 0xFF2DCB64, BADADDR );
MakeStr ( 0xFF2DCD48, BADADDR );
MakeRptCmt ( 0xFF2DCC00, "R1: 0x0051 - R0: CAPREADY - R2:
0xFF2DCB8C - R3: 0x0000 - " );
MakeFunction ( 0xFF2DE790, BADADDR );
MakeStr ( 0xFF2DE8B4, BADADDR );
MakeRptCmt ( 0xFF2DE7F0, "R1: 0x006A - R0: HEAD1 - R2: 0xFF2DE790
- R3: 0x0000 - " );
MakeFunction ( 0xFF2DEB74, BADADDR );
MakeStr ( 0xFF2DEC54, BADADDR );
MakeRptCmt ( 0xFF2DEB90, "R1: 0x006C - R0: HEADERROR - R2:
0xFF2DE8E4 - R3: 0x0000 - " );
MakeStr ( 0xFF2FE9A8, BADADDR );
MakeRptCmt ( 0xFF2FE780, "R1: 0x00D1 - R0: Fencing_C - R2:
0xFF2FE52C - R3: 0x0000 - " );
MakeStr ( 0xFF2FEBCC, BADADDR );
MakeRptCmt ( 0xFF2FEB60, "R1: 0x00D0 - R0: Fencing_B - R2:
0xFF2FEBA8 - R3: 0x0000 - " );
MakeStr ( 0x00000001, BADADDR );
MakeRptCmt ( 0xFF34C28C, "R1: 0x004F - R0: - R2: 0xFF34C218 - R3:
0x0000 - " );
MakeStr ( 0x00000001, BADADDR );
MakeRptCmt ( 0xFF34C2A0, "R1: 0x004F - R0: - R2: 0xFF34C1C8 - R3:
0x0000 - " );
MakeFunction ( 0xFF34C740, BADADDR );
MakeStr ( 0x00000001, BADADDR );
MakeRptCmt ( 0xFF34C798, "R1: 0x004F - R0: - R2: 0xFF34C4A8 - R3:
0x0000 - " );
MakeFunction ( 0xFF3B9464, BADADDR );
MakeStr ( 0x00000037, BADADDR );
MakeRptCmt ( 0xFF3B94E0, "R1: 0x0006 - R0: - R2: 0xFF3B9594 - R3:
0x0000 - " );
MakeFunction ( 0xFF3D08A4, BADADDR );
MakeFunction ( 0xFF3D087C, BADADDR );
MakeFunction ( 0xFF3D0824, BADADDR );
MakeStr ( 0xFF3D0A08, BADADDR );
MakeRptCmt ( 0xFF3D08C0, "R1: 0x0065 - R0: ADKIZDET - R2:
0xFF3D087C - R3: 0x0000 - " );
MakeFunction ( 0xFF3D17CC, BADADDR );
MakeFunction ( 0xFF3D17AC, BADADDR );
MakeStr ( 0xFF3D19CC, BADADDR );
MakeRptCmt ( 0xFF3D1810, "R1: 0x0052 - R0: IMGPOWDET - R2:
0xFF3D19B0 - R3: 0x0000 - " );
MakeFunction ( 0xFF3D2880, BADADDR );
MakeStr ( 0xFF3D29B0, BADADDR );
MakeRptCmt ( 0xFF3D28CC, "R1: 0x006A - R0: HEAD1 - R2: 0xFF3D2880
- R3: 0x0000 - " );
MakeFunction ( 0xFF3D29C0, BADADDR );
MakeStr ( 0xFF3D2BF0, BADADDR );
MakeRptCmt ( 0xFF3D2A0C, "R1: 0x006B - R0: HEAD2 - R2: 0xFF3D29C0
- R3: 0x0000 - " );
MakeFunction ( 0xFF3D2A78, BADADDR );
MakeFunction ( 0xFF3D2A54, BADADDR );
MakeStr ( 0xFF3D2C08, BADADDR );
MakeRptCmt ( 0xFF3D2AC4, "R1: 0x00D9 - R0: HEAD3 - R2: 0xFF3D2A78
- R3: 0x0000 - " );
MakeFunction ( 0xFF3D2B30, BADADDR );
MakeFunction ( 0xFF3D2B0C, BADADDR );
MakeStr ( 0xFF3D2C20, BADADDR );
MakeRptCmt ( 0xFF3D2B7C, "R1: 0x00E0 - R0: HEAD4 - R2: 0xFF3D2B30
- R3: 0x0000 - " );
MakeFunction ( 0xFF3D2E64, BADADDR );
MakeStr ( 0xFF3D2F44, BADADDR );
MakeRptCmt ( 0xFF3D2E80, "R1: 0x006C - R0: HEADERROR - R2:
0xFF3D2C30 - R3: 0x0000 - " );
MakeFunction ( 0xFF3DCCA8, BADADDR );
MakeStr ( 0xFF3DCE34, BADADDR );
MakeRptCmt ( 0xFF3DCD34, "R1: 0x00D8 - R0: Kaiser - R2: 0xFF3DCC78
- R3: 0x0000 - " );
MakeFunction ( 0xFF42705C, BADADDR );
MakeFunction ( 0xFF427038, BADADDR );
MakeFunction ( 0xFF42701C, BADADDR );
MakeStr ( 0xFF42726C, BADADDR );
MakeRptCmt ( 0xFF427098, "R1: 0x0060 - R0: CompleteReadOperation -
R2: 0xFF42701C - R3: 0x0000 - " );
MakeFunction ( 0xFF429DCC, BADADDR );
MakeStr ( 0x00000010, BADADDR );
MakeRptCmt ( 0xFF429DE8, "R1: 0x0065 - R0: - R2: 0xFF42A0CC - R3:
0x0000 - " );
MakeFunction ( 0xFF42A358, BADADDR );
MakeFunction ( 0xFF42A2F4, BADADDR );
MakeStr ( 0xFF42A444, BADADDR );
MakeRptCmt ( 0xFF42A374, "R1: 0x0065 - R0: ADMERG - R2: 0xFF42A2F4
- R3: 0x0000 - " );
MakeFunction ( 0xFF43B778, BADADDR );
MakeStr ( 0xFF43B9A8, BADADDR );
MakeRptCmt ( 0xFF43B7EC, "R1: 0x0003 - R0: WDTInterrupt - R2:
0xFF43B740 - R3: 0x0000 - " );
MakeFunction ( 0xFF4E0B9C, BADADDR );
MakeStr ( 0x00000002, BADADDR );
MakeRptCmt ( 0xFF4E0BBC, "R1: 0xFFFFFFFF - R0: - R2: 0xFFFFFFFF -
R3: 0x0000 - " );
MakeFunction ( 0xFF4E0B9C, BADADDR );
MakeStr ( 0x00000002, BADADDR );
MakeRptCmt ( 0xFF4E0BE4, "R1: 0xFFFFFFFF - R0: - R2: 0xFFFFFFFF -
R3: 0x0000 - " );
MakeFunction ( 0xFF4ED84C, BADADDR );
MakeFunction ( 0xFF4ED81C, BADADDR );
MakeFunction ( 0xFF4ED7F4, BADADDR );
MakeStr ( 0xFF4EDC50, BADADDR );
MakeRptCmt ( 0xFF4ED874, "R1: 0x0066 - R0: WbInteg - R2:
0xFF4ED7F4 - R3: 0x0000 - " );
MakeFunction ( 0xFF4EFF84, BADADDR );
MakeFunction ( 0xFF4EFF58, BADADDR );
MakeStr ( 0xFF4F0104, BADADDR );
MakeRptCmt ( 0xFF4EFFCC, "R1: 0x0061 - R0: AfComplete - R2:
0xFF4EFDD4 - R3: 0x0000 - " );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF4F2A08, "R1: 0x0001 - R0: - R2: 0xFFFFFFFF - R3:
0x0000 - " );
MakeStr ( 0x00000001, BADADDR );
MakeRptCmt ( 0xFF4F8770, "R1: 0x0001 - R0: - R2: 0xFF4F7DD0 - R3:
0x0000 - " );
MakeFunction ( 0xFF52AF18, BADADDR );
MakeStr ( 0x00000000, BADADDR );
MakeRptCmt ( 0xFF52AF7C, "R1: 0x0000 - R0: - R2: 0xFF52AEB4 - R3:
0x0000 - " );
MakeFunction ( 0xFF52BEF8, BADADDR );
MakeFunction ( 0xFF52BEC4, BADADDR );
MakeStr ( 0x00000001, BADADDR );
MakeRptCmt ( 0xFF52BF2C, "R1: 0x0000 - R0: - R2: 0xFF52BEC4 - R3:
0x0000 - " );
}
about Tx19: http://magiclantern.wikia.com/wiki/Tx19a
Indy
> MakeRptCmt ( 0xFF4ED874, "R1: 0x0066 - R0:...
>
> read more »
these are the very first lines of the DIGIC programming manual ;-)
Indy
Indy
and in ML source code: ptp.c and ptp-chdk.h.
Reading memory and file uploading/downloading already works. Writing
memory is commented out (I didn't try it, but should work).
> --
> http://magiclantern.wikia.com/
>
> To post to this group, send email to ml-d...@googlegroups.com
> To unsubscribe from this group, send email to ml-devel+u...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/ml-devel?hl=en