diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 333a51a..b211cf0 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -331,6 +331,17 @@ uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size, bool* is_writable) } } + +void mmu_dma_store_quad(uint32_t addr, uint32_t value) { + mmu_write_vmem(ppc_effective_address, value); +} + +uint8_t* mmu_dma_load_quad(uint32_t addr) { + uint32_t ret_value = mmu_read_vmem(addr); + uint8_t ret_array[4] = {(uint8_t)ret_value, (uint8_t)(ret_value >> 8), (uint8_t)(ret_value >> 16), (uint8_t)(ret_value >> 24)}; + return ret_array; +} + // primary ITLB for all MMU modes static std::array itlb1_mode1; static std::array itlb1_mode2; diff --git a/cpu/ppc/ppcmmu.h b/cpu/ppc/ppcmmu.h index f0d3ea5..0ffd9ff 100644 --- a/cpu/ppc/ppcmmu.h +++ b/cpu/ppc/ppcmmu.h @@ -107,6 +107,8 @@ extern std::function ibat_update; extern std::function dbat_update; extern uint8_t* mmu_get_dma_mem(uint32_t addr, uint32_t size, bool* is_writable); +extern void mmu_dma_store_quad(uint32_t addr, uint32_t value); +extern uint8_t* mmu_dma_load_quad(uint32_t addr); extern void mmu_change_mode(void); extern void mmu_pat_ctx_changed(); diff --git a/devices/common/dbdma.cpp b/devices/common/dbdma.cpp index a4b1a49..ca10a21 100644 --- a/devices/common/dbdma.cpp +++ b/devices/common/dbdma.cpp @@ -116,10 +116,33 @@ uint8_t DMAChannel::interpret_cmd() { this->cmd_in_progress = true; break; case DBDMA_Cmd::STORE_QUAD: - LOG_F(ERROR, "Unsupported DMA Command STORE_QUAD"); + if (cmd_struct.cmd_key != 6) { + LOG_F(ERROR, "Illegal key value for STORE_QUAD"); + } + else { + if (cmd_struct.req_count & 0x4) { + cmd_struct.req_count = 4; + } + else if (cmd_struct.req_count & 0x2) { + cmd_struct.req_count = 2; + } + else { + cmd_struct.req_count = 1; + } + + mmu_dma_store_quad(cmd_struct.address, cmd_struct.cmd_arg); + this->queue_len = 4; + this->cmd_in_progress = true; + } break; case DBDMA_Cmd::LOAD_QUAD: - LOG_F(ERROR, "Unsupported DMA Command LOAD_QUAD"); + if (cmd_struct.cmd_key != 6) { + LOG_F(ERROR, "Illegal key value for LOAD_QUAD"); + } else { + this->queue_data = mmu_dma_load_quad(cmd_struct.address); + this->queue_len = 4; + this->cmd_in_progress = true; + } break; case DBDMA_Cmd::NOP: LOG_F(ERROR, "Unsupported DMA Command NOP");