From d0a537adb5899b496c239809f15a228f90ddf9f2 Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Sun, 12 Jan 2025 02:38:29 +0100 Subject: [PATCH] WIP RDRAM initialization patch --- .../src/device/rcp/ri/ri_controller.c | 1 + .../src/device/rcp/ri/ri_controller.h | 12 +++ .../mupen64plus-core/src/device/rdram/rdram.c | 95 ++++++++----------- .../mupen64plus-core/src/main/savestates.c | 4 +- 4 files changed, 52 insertions(+), 60 deletions(-) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c index d74dd66c..a1aa0323 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c @@ -33,6 +33,7 @@ void init_ri(struct ri_controller* ri, struct rdram* rdram) void poweron_ri(struct ri_controller* ri) { memset(ri->regs, 0, RI_REGS_COUNT*sizeof(uint32_t)); + //ri->regs[RI_SELECT_REG] = 1; } diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h index 940fa80e..7f853070 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h @@ -54,6 +54,18 @@ static osal_inline uint32_t ri_reg(uint32_t address) return (address & 0xffff) >> 2; } +static osal_inline uint32_t rdram_address_to_ri_address(uint32_t address) +{ + /* https://n64brew.dev/wiki/RDRAM_Interface#Memory_addressing */ + return (((address >> 20) == 0x03f) + ? (((address & 0x3FF))) | /* Adr[10:0] */ + (((address >> 10) & 0x1FF) << 11) | /* Adr[19:11] */ + (((address >> 10) & 0x1FF) << 20) /* Adr[28:20] */ + : (((address & 0x7FF))) | /* Adr[10:0] */ + (((address >> 11) & 0x1FF) << 11) | /* Adr[19:11] */ + (((address >> 20) & 0x3F) << 20)); /* Adr[28:20] */ +} + static osal_inline uint16_t ri_address_to_id_field(uint32_t address) { /* XXX: pure guessing, need harware test */ diff --git a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c index 28065eaf..766b29cc 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c @@ -31,7 +31,7 @@ #include #define RDRAM_BCAST_ADDRESS_MASK UINT32_C(0x00080000) - +#define RDRAM_MODE_CE_MASK UINT32_C(0x80000000) /* XXX: deduce # of RDRAM modules from it's total size * Assume only 2Mo RDRAM modules. @@ -63,15 +63,25 @@ static osal_inline uint16_t idfield_value(uint32_t device_id) | (((device_id >> 7) & 0x01) << 15)); } +static osal_inline uint16_t ri_address_to_idfield(uint32_t address) +{ + const uint32_t swapfield = 0; // TODO + + return ((((swapfield & ((address >> 11) & 0xFF)) | ((~swapfield & (address >> 20 & 0xFF))))) | /* AdrS[28:20] */ + (((address >> 29) & 0x3F) << 9)); /* AdrS[35:29] */ +} + +#include static size_t get_module(const struct rdram* rdram, uint32_t address) { size_t module; size_t modules = get_modules_count(rdram); - uint16_t id_field = ri_address_to_id_field(address); - + uint16_t id_field = ri_address_to_idfield(rdram_address_to_ri_address(address)); for (module = 0; module < modules; ++module) { - if (id_field == idfield_value(rdram->regs[module][RDRAM_DEVICE_ID_REG])) { + // TODO: move shift to elsewhere + // TODO: figure out why using more bits than 6 will fail this check + if (((id_field >> 1) & 0x3F) == (((idfield_value(rdram->regs[module][RDRAM_DEVICE_ID_REG]) >> 1 & 0x3F)))) { return module; } } @@ -81,48 +91,6 @@ static size_t get_module(const struct rdram* rdram, uint32_t address) return RDRAM_MAX_MODULES_COUNT; } -static void read_rdram_dram_corrupted(void* opaque, uint32_t address, uint32_t* value) -{ - struct rdram* rdram = (struct rdram*)opaque; - uint32_t addr = rdram_dram_address(address); - size_t module; - - *value = rdram->dram[addr]; - - module = get_module(rdram, address); - if (module == RDRAM_MAX_MODULES_COUNT) { - *value = 0; - return; - } - - /* corrupt read value if CC value is not calibrated */ - uint32_t mode = rdram->regs[module][RDRAM_MODE_REG] ^ UINT32_C(0xc0c0c0c0); - if ((mode & 0x80000000) && (cc_value(mode) == 0)) { - *value = 0; - } -} - -static void map_corrupt_rdram(struct rdram* rdram, int corrupt) -{ - struct mem_mapping mapping; - - mapping.begin = MM_RDRAM_DRAM; - mapping.end = MM_RDRAM_DRAM + rdram->dram_size - 1; - mapping.type = M64P_MEM_RDRAM; - mapping.handler.opaque = rdram; - mapping.handler.read32 = (corrupt) - ? read_rdram_dram_corrupted - : read_rdram_dram; - mapping.handler.write32 = write_rdram_dram; - - apply_mem_mapping(rdram->r4300->mem, &mapping); -#ifndef NEW_DYNAREC - rdram->r4300->recomp.fast_memory = (corrupt) ? 0 : 1; - invalidate_r4300_cached_code(rdram->r4300, 0, 0); -#endif -} - - void init_rdram(struct rdram* rdram, uint32_t* dram, size_t dram_size, @@ -155,7 +123,7 @@ void poweron_rdram(struct rdram* rdram) } } - +#include void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value) { struct rdram* rdram = (struct rdram*)opaque; @@ -188,11 +156,13 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m size_t module; size_t modules = get_modules_count(rdram); +#ifndef NEW_DYNAREC /* HACK: Detect when current Control calibration is about to start, - * so we can set corrupted rdram_dram handler + * so we can disable dynarec it's fast_memory */ if (address & RDRAM_BCAST_ADDRESS_MASK && reg == RDRAM_DELAY_REG) { - map_corrupt_rdram(rdram, 1); + rdram->r4300->recomp.fast_memory = 1; + invalidate_r4300_cached_code(rdram->r4300, 0, 0); } /* HACK: Detect when current Control calibration is over, @@ -200,16 +170,10 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m * and let dynarec have it's fast_memory enabled. */ if (address & RDRAM_BCAST_ADDRESS_MASK && reg == RDRAM_MODE_REG) { - map_corrupt_rdram(rdram, 0); - - /* HACK: In the IPL3 procedure, at this point, - * the amount of detected memory can be found in s4 */ - size_t ipl3_rdram_size = r4300_regs(rdram->r4300)[20] & UINT32_C(0x0fffffff); - if (ipl3_rdram_size != rdram->dram_size) { - DebugMessage(M64MSG_WARNING, "IPL3 detected %u MB of RDRAM != %u MB", - (uint32_t) ipl3_rdram_size / (1024*1024), (uint32_t) rdram->dram_size / (1024*1024)); - } + rdram->r4300->recomp.fast_memory = 0; + invalidate_r4300_cached_code(rdram->r4300, 0, 0); } +#endif // NEW_DYNAREC if (address & RDRAM_BCAST_ADDRESS_MASK) { @@ -230,6 +194,21 @@ void read_rdram_dram(void* opaque, uint32_t address, uint32_t* value) { struct rdram* rdram = (struct rdram*)opaque; uint32_t addr = rdram_dram_address(address); + size_t module = get_module(rdram, address); + + if (module == RDRAM_MAX_MODULES_COUNT) + { + *value = 0; + return; + } + + /* corrupt read value if CC value is not calibrated */ + uint32_t mode = rdram->regs[module][RDRAM_MODE_REG] ^ UINT32_C(0xc0c0c0c0); + if ((mode & RDRAM_MODE_CE_MASK) && (cc_value(mode) == 0)) + { + *value = 0; + return; + } if (address < rdram->dram_size) { diff --git a/Source/3rdParty/mupen64plus-core/src/main/savestates.c b/Source/3rdParty/mupen64plus-core/src/main/savestates.c index 664edd1c..69217f98 100644 --- a/Source/3rdParty/mupen64plus-core/src/main/savestates.c +++ b/Source/3rdParty/mupen64plus-core/src/main/savestates.c @@ -932,7 +932,7 @@ static int savestates_load_m64p(struct device* dev, char *filepath) */ for (i = 0; i < RDRAM_MAX_MODULES_COUNT; ++i) { memcpy(dev->rdram.regs[i], dev->rdram.regs[0], RDRAM_REGS_COUNT*sizeof(dev->rdram.regs[0][0])); - dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; + //dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; } /* dd state */ @@ -1286,7 +1286,7 @@ static int savestates_load_pj64(struct device* dev, */ for (i = 0; i < (SaveRDRAMSize / 0x200000); ++i) { memcpy(dev->rdram.regs[i], dev->rdram.regs[0], RDRAM_REGS_COUNT*sizeof(dev->rdram.regs[0][0])); - dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; + //dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; } /* dd state */