Corelink DMA Engines: Difference between revisions

Yuriks (talk | contribs)
Create page by moving some stuff from SVC
 
Yuriks (talk | contribs)
No edit summary
Line 4: Line 4:
  struct DmaConfig {
  struct DmaConfig {
     sint8_t channel_sel; // @0 Selects which DMA channel to use: 0-7, -1 = don't care.
     sint8_t channel_sel; // @0 Selects which DMA channel to use: 0-7, -1 = don't care.
     uint8_t endian_swap_size; // @1 Accepted values: 0=none,2=16bit,4=32bit,8=64bit.
     uint8_t endian_swap_size; // @1 Accepted values: 0=none, 2=16bit, 4=32bit, 8=64bit.
     uint8_t flags;       // @2 bit0: DST_CFG, bit1: SRC_CFG, bit2: SHALL_BLOCK, bit3: ???, bit6: DST_ALT_CFG, bit7: SRC_ALT_CFG
     uint8_t flags; // @2 bit0: DST_CFG, bit1: SRC_CFG, bit2: SHALL_BLOCK, bit3: ???, bit6: DST_ALT_CFG, bit7: SRC_ALT_CFG
     uint8_t padding;
     uint8_t padding;
     uint8_t dst_cfg[10];
    DmaSubConfig dst_cfg;
     // @5 Accepted values (u8): 4, 8, 12, 15.
    DmaSubConfig src_cfg;
     // @15 Accepted values (u8): 4, 8, 12, 15.
}
     uint8_t src_cfg[10]; // @14
 
struct DmaSubConfig {
     uint8_t peripheral_id; // @0
     uint8_t unk2; // @1 Accepted values: 4, 8, 12, 15
     uint16_t unk3; // @2
    uint16_t transfer_size?; // @4
     uint16_t unk4; // @6
    uint16_t transfer_stride?; // @8
  }
  }


Line 16: Line 23:


If CFG or ALT_CFG is not set, default configuration is loaded:
If CFG or ALT_CFG is not set, default configuration is loaded:
FF 0F 80 00 00 00 80 00 00 00


If SHALL_BLOCK is set, the thread will sleep until the DMA engine is ready. If not set, the SVC will return 0xD04007F0 if the DMA channel is busy.
.peripheral_id = 0xFF,
.unk2 = 0xF,
.unk3 = 0x80,
.transfer_size = 0,
.unk4 = 0x80,
.unk5 = 0,


The format of src_cfg/dst_cfg is unknown, but both have the same format. Checks suggest that the second byte of cfg equalling 4 means NO_INCREMENT (don't increment after read/write).
Checks suggest that unk2 of DmaSubConfig equalling 4 means NO_INCREMENT (don't increment after read/write).


Each src/dst config:
If SHALL_BLOCK is set, the thread will sleep until the DMA engine is ready. If not set, the SVC will return 0xD04007F0 if the DMA channel is busy.
struct DmaSubConfig {
    uint8_t peripheral_id;  // @0
    uint8_t unk2;  // @1 Seen: 2
    uint16_t unk3; // @2
    uint16_t transfer_size?; // @4
    uint16_t unk4; // @6
    uint16_t unk5; // @8
}


The generated bytecode starts with a FLUSHP on the peripheral_ids for src/dst (if specified). After that, it always moves 0 into DAR. Then it moves the src/dst addresses into SAR/DAR respectively...
The generated bytecode starts with a FLUSHP on the peripheral_ids for src/dst (if specified). After that, it always moves 0 into DAR. Then it moves the src/dst addresses into SAR/DAR respectively...