From 0fd2edbf98a07d6838a4fdc415e53e2bc63b4a0e Mon Sep 17 00:00:00 2001 From: hrydgard Date: Mon, 6 Apr 2009 18:47:21 +0000 Subject: [PATCH] DSP: Remove all mentions of the mysterious DROM. Write protect the ROMs and IRAM as much as possible while loaded (to make sure they don't get corrupted by some memory overwrite or whatever). Make instruction reads stricter - iram and irom don't wrap anymore (not 100% sure about this one). Misc cleanup + changes. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2904 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/MemoryUtil.h | 6 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h | 16 +++- .../Plugin_DSP_LLE-testing/Src/Config.h | 1 - .../Src/DSPInterpreter.cpp | 1 + .../Src/DSPInterpreter.h | 7 +- .../Plugin_DSP_LLE-testing/Src/DSPTables.cpp | 22 ++++- .../Plugin_DSP_LLE-testing/Src/DSPTables.h | 4 + .../Src/gdsp_interface.cpp | 9 +- .../Src/gdsp_interpreter.cpp | 87 ++++++++----------- .../Src/gdsp_interpreter.h | 71 ++++++++------- .../Src/gdsp_memory.cpp | 25 +++--- .../Plugin_DSP_LLE-testing/Src/main.cpp | 14 +-- 12 files changed, 147 insertions(+), 116 deletions(-) diff --git a/Source/Core/Common/Src/MemoryUtil.h b/Source/Core/Common/Src/MemoryUtil.h index 29bd911c9d..7f568d3701 100644 --- a/Source/Core/Common/Src/MemoryUtil.h +++ b/Source/Core/Common/Src/MemoryUtil.h @@ -22,10 +22,8 @@ void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateMemoryPages(size_t size); void FreeMemoryPages(void* ptr, size_t size); void WriteProtectMemory(void* ptr, size_t size, bool executable = false); -void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute); - - -inline int GetPageSize() {return 4096;} +void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false); +inline int GetPageSize() { return 4096; } #endif diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h index a50ce13e98..0842e14fb2 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -54,11 +54,18 @@ public: virtual bool Open(u32 _CommandAddress, u32 _Mode) { - ERROR_LOG(WII_IPC_SD, "STM: Open"); + ERROR_LOG(WII_IPC_SD, "STM immediate: Open"); Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; } + virtual bool Close(u32 _CommandAddress) + { + ERROR_LOG(WII_IPC_SD, "STM immediate: Close"); + Memory::Write_U32(0, _CommandAddress+4); + return true; + } + virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); @@ -141,6 +148,13 @@ public: return true; } + virtual bool Close(u32 _CommandAddress) + { + INFO_LOG(WII_IPC_SD, "STM eventhook: Close"); + Memory::Write_U32(0, _CommandAddress+4); + return true; + } + virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h index ab76a47482..9d2f1f2c6a 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h @@ -26,7 +26,6 @@ struct CConfig CConfig(); void Load(); - void Save(); }; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp index 7b1d6701d9..4156b587c5 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp @@ -288,6 +288,7 @@ void srr(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_dmem_write(g_dsp.r[dreg], val); } + // SRRD @$D, $S // 0001 1010 1dds ssss // Store value from source register $S to a memory location pointed by diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h index 012bb23275..3241736403 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h @@ -114,6 +114,7 @@ void msubc(const UDSPInstruction& opc); void srs(const UDSPInstruction& opc); void lrs(const UDSPInstruction& opc); void nx(const UDSPInstruction& opc); +void cmpi(const UDSPInstruction& opc); // FIXME inside void rti(const UDSPInstruction& opc); @@ -122,7 +123,6 @@ void srbith(const UDSPInstruction& opc); void andfc(const UDSPInstruction& opc); void andf(const UDSPInstruction& opc); -void cmpi(const UDSPInstruction& opc); void xori(const UDSPInstruction& opc); void andi(const UDSPInstruction& opc); void ori(const UDSPInstruction& opc); @@ -130,11 +130,14 @@ void ori(const UDSPInstruction& opc); // TODO: PENDING IMPLEMENTATION / UNIMPLEMENTED +// The mysterious a100 + // END OF UNIMPLEMENTED // Helpers inline void tsta(int reg); -}; + +} // namespace #endif // _DSPINTERPRETER_H diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp index 178d9e06bd..dbc3729fa6 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp @@ -336,9 +336,27 @@ dspInstFunc opTable[OPTABLE_SIZE]; dspInstFunc prologueTable[OPTABLE_SIZE]; dspInstFunc epilogueTable[OPTABLE_SIZE]; +const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst) +{ + for (int i = 0; i < opcodes_size; i++) + { + u16 mask = opcodes[i].opcode_mask; + if (opcodes[i].size & P_EXT) { + // Ignore extension bits. + mask &= 0xFF00; + } + if ((mask & inst.hex) == opcodes[i].opcode) + return &opcodes[i]; + } + return NULL; +} + + +// This function could use the above GetOpTemplate, but then we'd lose the +// nice property that it catches colliding op masks. void InitInstructionTable() { - for (u32 i = 0; i < OPTABLE_SIZE; i++) + for (int i = 0; i < OPTABLE_SIZE; i++) { opTable[i] = DSPInterpreter::unknown; prologueTable[i] = NULL; @@ -346,7 +364,7 @@ void InitInstructionTable() opSize[i] = 0; } - for (u32 i = 0; i < OPTABLE_SIZE; i++) + for (int i = 0; i < OPTABLE_SIZE; i++) { for (u32 j = 0; j < opcodes_size; j++) { diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h index 309cd9bad5..4805f1cbd4 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h @@ -118,4 +118,8 @@ void InitInstructionTable(); void ComputeInstruction(const UDSPInstruction& inst); +// This one's pretty slow, try to use it only at init or seldomly. +// returns NULL if no matching instruction. +const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst); + #endif // _DSPTABLES_H diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp index d38f9ec910..ec9b5af594 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp @@ -24,8 +24,10 @@ ====================================================================*/ #include + #include "Globals.h" #include "Thread.h" +#include "MemoryUtil.h" #include "gdsp_aram.h" #include "gdsp_interpreter.h" @@ -163,11 +165,8 @@ void gdsp_ifx_write(u16 addr, u16 val) switch (addr & 0xff) { case 0xfb: // DIRQ - if (val & 0x1) - { g_dsp.irq_request(); - } break; @@ -246,13 +245,15 @@ u16 gdsp_ifx_read(u16 addr) void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size) { - u8* dst = ((u8*)g_dsp.iram); + UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); + u8* dst = ((u8*)g_dsp.iram); for (u32 i = 0; i < size; i += 2) { // TODO : this may be different on Wii. *(u16*)&dst[dsp_addr + i] = *(u16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]; } + WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); g_dsp.iram_crc = GenerateCRC(g_dsp.cpu_ram + (addr & 0x0fffffff), size); INFO_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)\n", addr, dsp_addr, g_dsp.iram_crc); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp index 6ccd1ec611..76228191fd 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp @@ -31,34 +31,12 @@ #include "gdsp_interface.h" #include "gdsp_opcodes_helper.h" #include "Tools.h" +#include "MemoryUtil.h" //------------------------------------------------------------------------------- SDSP g_dsp; -u16 SDSP::r[32]; -u16 SDSP::pc = 0; -u16 SDSP::err_pc = 0; -u16* SDSP::iram = 0; -u16* SDSP::dram = 0; -u16* SDSP::irom = 0; -u16* SDSP::drom = 0; -u16* SDSP::coef = 0; -u8* SDSP::cpu_ram = 0; -u16 SDSP::cr = 0; -u8 SDSP::reg_stack_ptr[4]; -u8 SDSP::exceptions; - -// lets make stack depth to 32 for now -u16 SDSP::reg_stack[4][DSP_STACK_DEPTH]; -void (*SDSP::irq_request)() = NULL; -bool SDSP::exception_in_progress_hack = false; // should be replaced with bit9 in SR? - -// for debugger only -bool SDSP::dump_imem = true; -u32 SDSP::iram_crc = 0; -u64 SDSP::step_counter = 0; - bool gdsp_running; extern volatile u32 dsp_running; @@ -75,28 +53,17 @@ void UpdateCachedCR() void gdsp_init() { - // Why do we have DROM? Does it exist? Has it been dumped? - g_dsp.irom = (u16*)malloc(DSP_IROM_SIZE * sizeof(u16)); - g_dsp.iram = (u16*)malloc(DSP_IRAM_SIZE * sizeof(u16)); - g_dsp.drom = (u16*)malloc(DSP_DROM_SIZE * sizeof(u16)); - g_dsp.dram = (u16*)malloc(DSP_DRAM_SIZE * sizeof(u16)); - g_dsp.coef = (u16*)malloc(DSP_COEF_SIZE * sizeof(u16)); + // Dump IMEM when ucodes get uploaded. Why not... still a plugin heavily in dev. + g_dsp.dump_imem = true; - // Fill memories with junk. - for (int i = 0; i < DSP_IRAM_SIZE; i++) - { - g_dsp.iram[i] = 0x0021; // HALT opcode - } - - for (int i = 0; i < DSP_DRAM_SIZE; i++) - { - g_dsp.dram[i] = 0x0021; // HALT opcode - } + g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE); + g_dsp.iram = (u16*)AllocateMemoryPages(DSP_IRAM_BYTE_SIZE); + g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE); + g_dsp.coef = (u16*)AllocateMemoryPages(DSP_COEF_BYTE_SIZE); // Fill roms with zeros. - memset(g_dsp.irom, 0, DSP_IROM_SIZE * sizeof(u16)); - memset(g_dsp.drom, 0, DSP_DROM_SIZE * sizeof(u16)); - memset(g_dsp.coef, 0, DSP_COEF_SIZE * sizeof(u16)); + memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE); + memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE); for (int i = 0; i < 32; i++) { @@ -113,6 +80,17 @@ void gdsp_init() } } + // Fill memories with junk. + for (int i = 0; i < DSP_IRAM_SIZE; i++) + { + g_dsp.iram[i] = 0x0021; // HALT opcode + } + + for (int i = 0; i < DSP_DRAM_SIZE; i++) + { + g_dsp.dram[i] = 0x0021; // HALT opcode + } + // copied from a real console after the custom UCode has been loaded g_dsp.r[0x08] = 0xffff; g_dsp.r[0x09] = 0xffff; @@ -123,12 +101,23 @@ void gdsp_init() gdsp_ifx_init(); UpdateCachedCR(); + + // Mostly keep IRAM write protected. We unprotect only when DMA-ing + // in new ucodes. + WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); +} + +void gdsp_shutdown() +{ + FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); + FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE); } void gdsp_reset() { -// _assert_msg_(0, "gdsp_reset()"); _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception"); g_dsp.pc = DSP_RESET_VECTOR; g_dsp.exception_in_progress_hack = false; @@ -140,11 +129,9 @@ void gdsp_generate_exception(u8 level) g_dsp.exceptions |= 1 << level; } - -bool gdsp_load_rom(const char *fname) +bool gdsp_load_irom(const char *fname) { FILE *pFile = fopen(fname, "rb"); - if (pFile) { size_t size_in_bytes = DSP_IROM_SIZE * sizeof(u16); @@ -158,15 +145,14 @@ bool gdsp_load_rom(const char *fname) fclose(pFile); return true; } - + // Always keep IROM write protected. + WriteProtectMemory(g_dsp.irom, DSP_IROM_BYTE_SIZE, false); return false; } - bool gdsp_load_coef(const char *fname) { FILE *pFile = fopen(fname, "rb"); - if (pFile) { size_t size_in_bytes = DSP_COEF_SIZE * sizeof(u16); @@ -180,7 +166,8 @@ bool gdsp_load_coef(const char *fname) fclose(pFile); return true; } - + // Always keep COEF write protected. We unprotect only when DMA-ing + WriteProtectMemory(g_dsp.coef, DSP_COEF_BYTE_SIZE, false); return false; } diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h index 6a7891b0cb..4c614397e8 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h @@ -45,55 +45,60 @@ #include "Globals.h" -// Are these in bytes or 16-bit words? Probably 16-bit words. -#define DSP_IRAM_SIZE (0x1000) -#define DSP_IRAM_MASK (0x0fff) -#define DSP_IROM_SIZE (0x1000) -#define DSP_IROM_MASK (0x0fff) -#define DSP_DRAM_SIZE (0x1000) -#define DSP_DRAM_MASK (0x0fff) -#define DSP_DROM_SIZE (0x1000) -#define DSP_DROM_MASK (0x0fff) -#define DSP_COEF_SIZE (0x1000) -#define DSP_COEF_MASK (0x0fff) +#define DSP_IRAM_BYTE_SIZE 0x2000 +#define DSP_IRAM_SIZE 0x1000 +#define DSP_IRAM_MASK 0x0fff -#define DSP_RESET_VECTOR (0x8000) +#define DSP_IROM_BYTE_SIZE 0x2000 +#define DSP_IROM_SIZE 0x1000 +#define DSP_IROM_MASK 0x0fff + +#define DSP_DRAM_BYTE_SIZE 0x2000 +#define DSP_DRAM_SIZE 0x1000 +#define DSP_DRAM_MASK 0x0fff + +#define DSP_COEF_BYTE_SIZE 0x2000 +#define DSP_COEF_SIZE 0x1000 +#define DSP_COEF_MASK 0x0fff + +#define DSP_RESET_VECTOR 0x8000 #define DSP_STACK_DEPTH 0x20 #define DSP_STACK_MASK 0x1f struct SDSP { - static u16 r[32]; - static u16 pc; - static u16 err_pc; - static u16* iram; - static u16* dram; - static u16* irom; - static u16* drom; - static u16* coef; - static u8* cpu_ram; - static u16 cr; - static u8 reg_stack_ptr[4]; - static u8 exceptions; // pending exceptiosn? + u16 r[32]; + u16 pc; + u16 err_pc; + u16* iram; + u16* dram; + u16* irom; + u16* coef; + u8* cpu_ram; + u16 cr; + u8 reg_stack_ptr[4]; + u8 exceptions; // pending exceptiosn? // lets make stack depth to 32 for now - static u16 reg_stack[4][DSP_STACK_DEPTH]; - static void (* irq_request)(void); + u16 reg_stack[4][DSP_STACK_DEPTH]; + void (* irq_request)(void); // for debugger only - static bool dump_imem; - static u32 iram_crc; - static u64 step_counter; - static bool exception_in_progress_hack; + bool dump_imem; + u32 iram_crc; + u64 step_counter; + bool exception_in_progress_hack; }; extern SDSP g_dsp; -void gdsp_init(void); -void gdsp_reset(void); -bool gdsp_load_rom(const char *fname); +void gdsp_init(); +void gdsp_reset(); +void gdsp_shutdown(); + +bool gdsp_load_irom(const char *fname); bool gdsp_load_coef(const char *fname); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp index 233b1cecb8..055af25534 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp @@ -37,15 +37,22 @@ u16 dsp_swap16(u16 x) u16 dsp_imem_read(u16 addr) { - if (g_dsp.pc & 0x8000) - return dsp_swap16(g_dsp.irom[addr & DSP_IROM_MASK]); - else + switch (addr >> 12) + { + case 0: return dsp_swap16(g_dsp.iram[addr & DSP_IRAM_MASK]); + case 8: + return dsp_swap16(g_dsp.irom[addr & DSP_IROM_MASK]); + default: + ERROR_LOG(DSPLLE, "%04x DSP ERROR: Executing from invalid (%04x) memory", g_dsp.pc, addr); + return 0; + } } u16 dsp_dmem_read(u16 addr) { - switch (addr >> 12) { + switch (addr >> 12) + { case 0x0: // 0xxx DRAM return dsp_swap16(g_dsp.dram[addr & DSP_DRAM_MASK]); @@ -58,10 +65,6 @@ u16 dsp_dmem_read(u16 addr) case 0x4: break;*/ - case 0x8: // 8xxx DROM - ERROR_LOG(DSPLLE, "someone reads from ROM"); - return dsp_swap16(g_dsp.drom[addr & DSP_DROM_MASK]); - case 0xf: // Fxxx HW regs return gdsp_ifx_read(addr); @@ -84,12 +87,6 @@ void dsp_dmem_write(u16 addr, u16 val) ERROR_LOG(DSPLLE, "someone writes to COEF"); break; - case 0x8: // 8xxx DROM - ERROR_LOG(DSPLLE, "someone writes to DROM"); - /* val = dsp_swap16(val); - g_dsp.drom[addr & DSP_DROM_MASK] = val;*/ - break; - case 0xf: // Fxxx HW regs gdsp_ifx_write(addr, val); break; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp index 8f001dc156..08af7d09da 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp @@ -231,14 +231,17 @@ void Initialize(void *init) g_dsp.step_counter = 0; g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); g_dsp.irq_request = dspi_req_dsp_irq; +// g_dsp.exception_in_progress_hack = false; gdsp_reset(); - if (!gdsp_load_rom(DSP_IROM_FILE)) { + if (!gdsp_load_irom(DSP_IROM_FILE)) + { bCanWork = false; PanicAlert("Failed loading DSP ROM from " DSP_IROM_FILE); } - if (!gdsp_load_coef(DSP_COEF_FILE)) { + if (!gdsp_load_coef(DSP_COEF_FILE)) + { bCanWork = false; PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE); } @@ -248,10 +251,10 @@ void Initialize(void *init) bIsRunning = true; + InitInstructionTable(); + g_hDSPThread = new Common::Thread(dsp_thread, NULL); soundStream = AudioCommon::InitSoundStream(); - - InitInstructionTable(); } void DSP_StopSoundStream() @@ -262,9 +265,10 @@ void DSP_StopSoundStream() g_hDSPThread = NULL; } -void Shutdown(void) +void Shutdown() { AudioCommon::ShutdownSoundStream(); + gdsp_shutdown(); } u16 DSP_WriteControlRegister(u16 _uFlag)