From 6f9f5784bf0a720522c4ecb0915e20229c126aed Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Fri, 19 Feb 2021 23:24:55 +0100 Subject: [PATCH 1/9] vr4300: Fix improper handling of valid bit in TLB probe function This fix restores GoldenEye support (#78) --- arch/x86_64/tlb/tlb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/x86_64/tlb/tlb.c b/arch/x86_64/tlb/tlb.c index 0e050d2..d6ee000 100644 --- a/arch/x86_64/tlb/tlb.c +++ b/arch/x86_64/tlb/tlb.c @@ -40,7 +40,7 @@ unsigned tlb_probe(const struct cen64_tlb *tlb, for (i = 0; i < 32; i += 8) { __m128i check_l, check_h, vpn_check; __m128i check_a, check_g, asid_check; - __m128i check, check_v; + __m128i check; __m128i page_mask_l = _mm_load_si128((__m128i*) (tlb->page_mask.data + i + 0)); __m128i page_mask_h = _mm_load_si128((__m128i*) (tlb->page_mask.data + i + 4)); @@ -64,10 +64,6 @@ unsigned tlb_probe(const struct cen64_tlb *tlb, // Match only on VPN match && (asid match || global) check = _mm_and_si128(vpn_check, asid_check); - // Match only on all of the above >= 1 valid bit set. - check_v = _mm_loadl_epi64((__m128i*) (tlb->valid + i)); - check = _mm_and_si128(check, check_v); - if ((one_hot_idx = _mm_movemask_epi8(check)) != 0) { *index = i + cen64_one_hot_lut[one_hot_idx & 0xFF]; return 0; From a54cbe042f08f1058d90f6f58f0ad735c9f692a8 Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Fri, 19 Feb 2021 20:45:45 +0100 Subject: [PATCH 2/9] si: Fix Memory Pak initialization Thanks to bryc for researching this issue and reviewing this fix --- si/pak.c | 18 ++++++++++-------- si/pak.h | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/si/pak.c b/si/pak.c index 7874290..56ee6ae 100644 --- a/si/pak.c +++ b/si/pak.c @@ -109,9 +109,7 @@ uint8_t controller_pak_crc(uint8_t *data) { } void controller_pak_format(uint8_t *ptr) { - off_t pos; - - static uint8_t init[] = { + static uint8_t init_id_area[] = { 0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x1A, 0x5F, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -128,12 +126,16 @@ void controller_pak_format(uint8_t *ptr) { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x66, 0x25, 0x99, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, }; - memcpy(ptr, init, sizeof(init)); - for (pos = sizeof(init); pos < MEMPAK_SIZE; pos += 2) { - ptr[pos+0] = 0x00; - ptr[pos+1] = 0x03; + memset(ptr, 0, MEMPAK_SIZE); + memcpy(ptr, init_id_area, sizeof(init_id_area)); + + ptr[(MEMPAK_PAGE_SIZE * 1) + 1] = 0x71; + ptr[(MEMPAK_PAGE_SIZE * 2) + 1] = 0x71; + + for (off_t i = 5; i < MEMPAK_NUM_PAGES; i++) { + ptr[(MEMPAK_PAGE_SIZE * 1) + (i * 2) + 1] = 0x03; + ptr[(MEMPAK_PAGE_SIZE * 2) + (i * 2) + 1] = 0x03; } } diff --git a/si/pak.h b/si/pak.h index 6710960..aa659d8 100644 --- a/si/pak.h +++ b/si/pak.h @@ -16,6 +16,8 @@ #include "gb.h" #define MEMPAK_SIZE 0x8000 +#define MEMPAK_NUM_PAGES 128 +#define MEMPAK_PAGE_SIZE (MEMPAK_SIZE / MEMPAK_NUM_PAGES) enum pak_type { PAK_NONE = 0, From 89e47d2968af2227017e52008d6c893e58b300c5 Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Sat, 20 Feb 2021 18:39:05 +0100 Subject: [PATCH 3/9] Add Dinosaur Planet to cart DB --- device/cart_db.c | 1 + 1 file changed, 1 insertion(+) diff --git a/device/cart_db.c b/device/cart_db.c index 3ec0cc7..bb822ee 100644 --- a/device/cart_db.c +++ b/device/cart_db.c @@ -58,6 +58,7 @@ static const struct cart_db_entry cart_db_table[] = { {"NDA", "J", CART_DB_SAVE_TYPE_FLASH_1MBIT, "Derby Stallion 64"}, {"NDK", "J", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Space Dynamites"}, {"NDO", "EJP", CART_DB_SAVE_TYPE_EEPROM_16KBIT, "Donkey Kong 64"}, + {"NDP", "E", CART_DB_SAVE_TYPE_FLASH_1MBIT, "Dinosaur Planet"}, {"NDR", "J", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Doraemon: Nobita to 3tsu no Seireiseki"}, {"NDU", "EP", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Duck Dodgers"}, {"NDY", "EJP", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Diddy Kong Racing"}, From 27917c7df82cf4cc23e28af16923a7a3982296d0 Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Mon, 8 Mar 2021 20:07:19 +0100 Subject: [PATCH 4/9] rsp: Fix VNOP and VNULL --- rsp/opcodes_priv.h | 4 ++-- rsp/vfunctions.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rsp/opcodes_priv.h b/rsp/opcodes_priv.h index f17ccfe..3099784 100644 --- a/rsp/opcodes_priv.h +++ b/rsp/opcodes_priv.h @@ -102,9 +102,9 @@ #define VMULU RSP_BUILD_OP(VMULU, VMULF_VMULU, INFO3(VECTOR, NEEDVS, NEEDVT)) #define VNAND RSP_BUILD_OP(VNAND, VAND_VNAND, INFO3(VECTOR, NEEDVS, NEEDVT)) #define VNE RSP_BUILD_OP(VNE, VEQ_VGE_VLT_VNE, INFO3(VECTOR, NEEDVS, NEEDVT)) -#define VNOP RSP_BUILD_OP(VNOP, VNOP, INFO2(VECTOR, NEEDVS)) +#define VNOP RSP_BUILD_OP(VNOP, VNOP, INFO1(VECTOR)) #define VNOR RSP_BUILD_OP(VNOR, VOR_VNOR, INFO3(VECTOR, NEEDVS, NEEDVT)) -#define VNULL RSP_BUILD_OP(VNULL, VNOP, INFO2(VECTOR, NEEDVS)) +#define VNULL RSP_BUILD_OP(VNULL, VNOP, INFO1(VECTOR)) #define VNXOR RSP_BUILD_OP(VNXOR, VXOR_VNXOR, INFO3(VECTOR, NEEDVS, NEEDVT)) #define VOR RSP_BUILD_OP(VOR, VOR_VNOR, INFO3(VECTOR, NEEDVS, NEEDVT)) #define VRCP RSP_BUILD_OP(VRCP, VRCP_VRSQ, INFO2(VECTOR, NEEDVT)) diff --git a/rsp/vfunctions.c b/rsp/vfunctions.c index 09e79ac..f674571 100644 --- a/rsp/vfunctions.c +++ b/rsp/vfunctions.c @@ -343,7 +343,8 @@ rsp_vect_t RSP_VMULF_VMULU(struct rsp *rsp, uint32_t iw, // rsp_vect_t RSP_VNOP(struct rsp *rsp, uint32_t iw, rsp_vect_t vt_shuffle, rsp_vect_t vs, rsp_vect_t zero) { - return vs; + + return rsp_vect_load_unshuffled_operand(rsp->cp2.regs[GET_VD(iw)].e); } // From deda9f970942b7f12c47882cd88e6a1d4ffcb485 Mon Sep 17 00:00:00 2001 From: James Lambert Date: Fri, 5 Mar 2021 11:35:22 -0700 Subject: [PATCH 5/9] Have debugger handle memory exceptions --- vr4300/fault.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vr4300/fault.c b/vr4300/fault.c index 072710a..7fc8f65 100644 --- a/vr4300/fault.c +++ b/vr4300/fault.c @@ -345,6 +345,7 @@ void VR4300_DTLB(struct vr4300 *vr4300, unsigned miss, unsigned inv, unsigned mo vr4300_exception_epilogue(vr4300, (cause & ~0xFF) | (type << 2), status, epc, offs); + vr4300_debug_exception(&vr4300->debug); } // IADE: Instruction address error exception. From 9316569eff81721ae32a4cd270ecaf60152fb3a2 Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Tue, 9 Mar 2021 22:20:12 +0100 Subject: [PATCH 6/9] pi: Fix PI DMA length alignment Fixes Yoshi's Story, F-1 World Grand Prix and probably many other games --- pi/controller.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pi/controller.c b/pi/controller.c index 3a178b9..fee1ab0 100644 --- a/pi/controller.c +++ b/pi/controller.c @@ -55,11 +55,11 @@ void pi_cycle_(struct pi_controller *pi) { // Copies data from RDRAM to the PI static int pi_dma_read(struct pi_controller *pi) { uint32_t dest = pi->regs[PI_CART_ADDR_REG] & 0xFFFFFFE; - uint32_t source = pi->regs[PI_DRAM_ADDR_REG] & 0x7FFFFF; + uint32_t source = pi->regs[PI_DRAM_ADDR_REG] & 0x7FFFF8; uint32_t length = (pi->regs[PI_RD_LEN_REG] & 0xFFFFFF) + 1; - if (length & 7) - length = (length + 7) & ~7; + if (length & 1) + length = (length + 1) & ~1; // SRAM and FlashRAM if (dest >= 0x08000000 && dest < 0x08010000) { @@ -84,12 +84,12 @@ static int pi_dma_read(struct pi_controller *pi) { // Copies data from the the PI into RDRAM. static int pi_dma_write(struct pi_controller *pi) { - uint32_t dest = pi->regs[PI_DRAM_ADDR_REG] & 0x7FFFFF; + uint32_t dest = pi->regs[PI_DRAM_ADDR_REG] & 0x7FFFF8; uint32_t source = pi->regs[PI_CART_ADDR_REG] & 0xFFFFFFE; uint32_t length = (pi->regs[PI_WR_LEN_REG] & 0xFFFFFF) + 1; - if (length & 7) - length = (length + 7) & ~7; + if (length & 1) + length = (length + 1) & ~1; if (pi->bus->dd->ipl_rom && (source & 0x06000000) == 0x06000000) { source &= 0x003FFFFF; From 1b31ca9b3c3bb783391ab9773bd26c50db2056a8 Mon Sep 17 00:00:00 2001 From: James Lambert Date: Fri, 12 Mar 2021 09:46:15 -0700 Subject: [PATCH 7/9] Report full pc instead of truncated address --- gdb/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb/protocol.c b/gdb/protocol.c index cd680e8..18a7786 100644 --- a/gdb/protocol.c +++ b/gdb/protocol.c @@ -222,7 +222,7 @@ void gdb_reply_registers(struct gdb* gdb) { current = gdb_write_hex64(current, vr4300_get_register(gdb->device->vr4300, VR4300_REGISTER_HI), sizeof(uint64_t)); current = gdb_write_hex64(current, vr4300_get_register(gdb->device->vr4300, VR4300_CP0_REGISTER_BADVADDR), sizeof(uint64_t)); current = gdb_write_hex64(current, vr4300_get_register(gdb->device->vr4300, VR4300_CP0_REGISTER_CAUSE), sizeof(uint64_t)); - current += sprintf(current, "%08x%08x", 0, (int32_t)vr4300_get_pc(gdb->device->vr4300)); + current = gdb_write_hex64(current, vr4300_get_pc(gdb->device->vr4300), sizeof(uint64_t)); for (int i = VR4300_REGISTER_CP1_0; i <= VR4300_REGISTER_CP1_31; i++) { current = gdb_write_hex64(current, vr4300_get_register(gdb->device->vr4300, i), sizeof(uint64_t)); From 622dd402f0429e7fb008276db568002a2d4b8ec7 Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Tue, 4 May 2021 00:18:03 +0200 Subject: [PATCH 8/9] vr4300: fix badvaddr register in TLB exceptions. Currently, all load/store opcodes (with the exception of LWL/LWR) mask the lowest bit of address that causes a TLB exception in the BADVADDR COP0 register. This is wrong because the VR4300 reports the exact faulting address in that register, the reason being that the exception handler must require it. --- vr4300/functions.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vr4300/functions.c b/vr4300/functions.c index cf14f6a..e181fdd 100644 --- a/vr4300/functions.c +++ b/vr4300/functions.c @@ -1209,7 +1209,7 @@ cen64_hot int VR4300_LOAD_STORE(struct vr4300 *vr4300, unsigned lshiftamt = (3 - request_size) << 3; unsigned rshiftamt = (address & 0x3) << 3; - exdc_latch->request.vaddr = address & ~(sel_mask & 0x3); + exdc_latch->request.vaddr = address; exdc_latch->request.data = dqm | (sel_mask & ((rt << lshiftamt) >> rshiftamt)); exdc_latch->request.wdqm = ((uint32_t) sel_mask << lshiftamt) >> rshiftamt; exdc_latch->request.postshift = 0; @@ -1529,7 +1529,7 @@ int VR4300_SDL_SDR(struct vr4300 *vr4300, dqm = mask >> shiftamt; } - exdc_latch->request.vaddr = address & ~0x3ULL; + exdc_latch->request.vaddr = address; exdc_latch->request.data = data; exdc_latch->request.wdqm = dqm; exdc_latch->request.access_type = VR4300_ACCESS_DWORD; @@ -1568,7 +1568,7 @@ int VR4300_SWL_SWR(struct vr4300 *vr4300, dqm = mask >> shiftamt; } - exdc_latch->request.vaddr = address & ~0x3ULL; + exdc_latch->request.vaddr = address; exdc_latch->request.data = data; exdc_latch->request.wdqm = dqm; exdc_latch->request.access_type = VR4300_ACCESS_WORD; From eb935a85f78bf2aa879e8f29fbdaa6850a264579 Mon Sep 17 00:00:00 2001 From: Simon Eriksson Date: Tue, 4 May 2021 18:45:54 +0200 Subject: [PATCH 9/9] rsp: Align RSP memory address in DMA to 8 --- rsp/interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rsp/interface.c b/rsp/interface.c index 3671c21..bdb1a94 100644 --- a/rsp/interface.c +++ b/rsp/interface.c @@ -24,7 +24,7 @@ void rsp_dma_read(struct rsp *rsp) { // Force alignment. length = (length + 0x7) & ~0x7; - rsp->regs[RSP_CP0_REGISTER_DMA_CACHE] &= ~0x3; + rsp->regs[RSP_CP0_REGISTER_DMA_CACHE] &= ~0x7; rsp->regs[RSP_CP0_REGISTER_DMA_DRAM] &= ~0x7; // Check length. @@ -69,7 +69,7 @@ void rsp_dma_write(struct rsp *rsp) { // Force alignment. length = (length + 0x7) & ~0x7; - rsp->regs[RSP_CP0_REGISTER_DMA_CACHE] &= ~0x3; + rsp->regs[RSP_CP0_REGISTER_DMA_CACHE] &= ~0x7; rsp->regs[RSP_CP0_REGISTER_DMA_DRAM] &= ~0x7; // Check length.