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
This commit is contained in:
hrydgard 2009-04-06 18:47:21 +00:00
parent 13ac45db1a
commit 0fd2edbf98
12 changed files with 147 additions and 116 deletions

View File

@ -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

View File

@ -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);

View File

@ -26,7 +26,6 @@ struct CConfig
CConfig();
void Load();
void Save();
};

View File

@ -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

View File

@ -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

View File

@ -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++)
{

View File

@ -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

View File

@ -24,8 +24,10 @@
====================================================================*/
#include <stdlib.h>
#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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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)