diff --git a/include/arm11/debug.h b/include/arm11/debug.h index f5c7f70..1bf0726 100644 --- a/include/arm11/debug.h +++ b/include/arm11/debug.h @@ -22,7 +22,6 @@ -void debugHashCodeRoData(); noreturn void panic(); noreturn void panicMsg(const char *msg); void debugMemdump(const char *filepath, void *mem, size_t size); diff --git a/include/hardware/pxi.h b/include/hardware/pxi.h index 6938d7b..797f6e5 100644 --- a/include/hardware/pxi.h +++ b/include/hardware/pxi.h @@ -69,3 +69,4 @@ void PXI_init(void); u32 PXI_sendCmd(u32 cmd, const u32 *buf, u32 words); +void PXI_sendPanicCmd(u32 cmd); // Not intended for normal use! diff --git a/include/ipc_handler.h b/include/ipc_handler.h index 616d1e4..299b8a3 100644 --- a/include/ipc_handler.h +++ b/include/ipc_handler.h @@ -22,71 +22,66 @@ #define IPC_MAX_PARAMS (15) -#define IPC_CMD_ID_MASK(cmd) ((cmd)>>24) -#define IPC_CMD_IN_BUFS_MASK(cmd) ((cmd)>>20 & 0xFu) -#define IPC_CMD_OUT_BUFS_MASK(cmd) ((cmd)>>16 & 0xFu) -#define IPC_CMD_PARAMS_MASK(cmd) ((cmd)>>12 & 0xFu) +#define IPC_CMD_RESP_FLAG (1u<<15) +#define IPC_CMD_ID_MASK(cmd) ((cmd)>>8) // Max 127 +#define IPC_CMD_IN_BUFS_MASK(cmd) ((cmd)>>6 & 3u) // Max 3 +#define IPC_CMD_OUT_BUFS_MASK(cmd) ((cmd)>>4 & 3u) // Max 3 +#define IPC_CMD_PARAMS_MASK(cmd) ((cmd) & 15u) // Max 15 -#define CMD_ID(id) ((id)<<24) -#define CMD_IN_BUFS(n) ((n)<<20) -#define CMD_OUT_BUFS(n) ((n)<<16) -#define CMD_PARAMS(n) ((n)<<12) +#define MAKE_CMD(id, inBufs, outBufs, params) ((id)<<8 | (inBufs)<<6 | (outBufs)<<4 | params) typedef enum { - IPC_CMD9_FMOUNT = CMD_ID(0) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FUNMOUNT = CMD_ID(1) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FIS_DRIVE_MOUNTED = CMD_ID(2) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FGETFREE = CMD_ID(3) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(1), - IPC_CMD9_FGET_DEV_SIZE = CMD_ID(4) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FIS_DEV_ACTIVE = CMD_ID(5) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FPREP_RAW_ACCESS = CMD_ID(6) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FFINAL_RAW_ACCESS = CMD_ID(7) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FCREATE_DEV_BUF = CMD_ID(8) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FFREE_DEV_BUF = CMD_ID(9) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FREAD_TO_DEV_BUF = CMD_ID(10) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(4), - IPC_CMD9_FWRITE_FROM_DEV_BUF = CMD_ID(11) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(4), - IPC_CMD9_FOPEN = CMD_ID(12) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FREAD = CMD_ID(13) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(1), - IPC_CMD9_FWRITE = CMD_ID(14) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FSYNC = CMD_ID(15) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FLSEEK = CMD_ID(16) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), - IPC_CMD9_FTELL = CMD_ID(17) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FSIZE = CMD_ID(18) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FCLOSE = CMD_ID(19) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FEXPAND = CMD_ID(20) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), - IPC_CMD9_FSTAT = CMD_ID(21) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(1) | CMD_PARAMS(0), - IPC_CMD9_FOPEN_DIR = CMD_ID(22) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FREAD_DIR = CMD_ID(23) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(2), - IPC_CMD9_FCLOSE_DIR = CMD_ID(24) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FMKDIR = CMD_ID(25) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FRENAME = CMD_ID(26) | CMD_IN_BUFS(2) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FUNLINK = CMD_ID(27) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FVERIFY_NAND_IMG = CMD_ID(28) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FSET_NAND_PROT = CMD_ID(29) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_WRITE_FIRM_PART = CMD_ID(30) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_LOAD_VERIFY_FIRM = CMD_ID(31) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FIRM_LAUNCH = CMD_ID(32) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_LOAD_VERIFY_UPDATE = CMD_ID(33) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(1) | CMD_PARAMS(0), - IPC_CMD9_GET_BOOT_ENV = CMD_ID(34) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_TOGGLE_SUPERHAX = CMD_ID(35) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_PREPARE_POWER = CMD_ID(36) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_PANIC = CMD_ID(37) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_EXCEPTION = CMD_ID(38) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0) + IPC_CMD9_FMOUNT = MAKE_CMD(0, 0, 0, 1), + IPC_CMD9_FUNMOUNT = MAKE_CMD(1, 0, 0, 1), + IPC_CMD9_FIS_DRIVE_MOUNTED = MAKE_CMD(2, 0, 0, 1), + IPC_CMD9_FGETFREE = MAKE_CMD(3, 0, 1, 1), + IPC_CMD9_FGET_DEV_SIZE = MAKE_CMD(4, 0, 0, 1), + IPC_CMD9_FIS_DEV_ACTIVE = MAKE_CMD(5, 0, 0, 1), + IPC_CMD9_FPREP_RAW_ACCESS = MAKE_CMD(6, 0, 0, 1), + IPC_CMD9_FFINAL_RAW_ACCESS = MAKE_CMD(7, 0, 0, 1), + IPC_CMD9_FCREATE_DEV_BUF = MAKE_CMD(8, 0, 0, 1), + IPC_CMD9_FFREE_DEV_BUF = MAKE_CMD(9, 0, 0, 1), + IPC_CMD9_FREAD_TO_DEV_BUF = MAKE_CMD(10, 0, 0, 4), + IPC_CMD9_FWRITE_FROM_DEV_BUF = MAKE_CMD(11, 0, 0, 4), + IPC_CMD9_FOPEN = MAKE_CMD(12, 1, 0, 1), + IPC_CMD9_FREAD = MAKE_CMD(13, 0, 1, 1), + IPC_CMD9_FWRITE = MAKE_CMD(14, 1, 0, 1), + IPC_CMD9_FSYNC = MAKE_CMD(15, 0, 0, 1), + IPC_CMD9_FLSEEK = MAKE_CMD(16, 0, 0, 2), + IPC_CMD9_FTELL = MAKE_CMD(17, 0, 0, 1), + IPC_CMD9_FSIZE = MAKE_CMD(18, 0, 0, 1), + IPC_CMD9_FCLOSE = MAKE_CMD(19, 0, 0, 1), + IPC_CMD9_FEXPAND = MAKE_CMD(20, 0, 0, 2), + IPC_CMD9_FSTAT = MAKE_CMD(21, 1, 1, 0), + IPC_CMD9_FOPEN_DIR = MAKE_CMD(22, 1, 0, 0), + IPC_CMD9_FREAD_DIR = MAKE_CMD(23, 0, 1, 2), + IPC_CMD9_FCLOSE_DIR = MAKE_CMD(24, 0, 0, 1), + IPC_CMD9_FMKDIR = MAKE_CMD(25, 1, 0, 0), + IPC_CMD9_FRENAME = MAKE_CMD(26, 2, 0, 0), + IPC_CMD9_FUNLINK = MAKE_CMD(27, 1, 0, 0), + IPC_CMD9_FVERIFY_NAND_IMG = MAKE_CMD(28, 1, 0, 0), + IPC_CMD9_FSET_NAND_PROT = MAKE_CMD(29, 0, 0, 1), + IPC_CMD9_WRITE_FIRM_PART = MAKE_CMD(30, 1, 0, 1), + IPC_CMD9_LOAD_VERIFY_FIRM = MAKE_CMD(31, 1, 0, 1), + IPC_CMD9_FIRM_LAUNCH = MAKE_CMD(32, 0, 0, 0), + IPC_CMD9_LOAD_VERIFY_UPDATE = MAKE_CMD(33, 1, 1, 0), + IPC_CMD9_GET_BOOT_ENV = MAKE_CMD(34, 0, 0, 0), + IPC_CMD9_TOGGLE_SUPERHAX = MAKE_CMD(35, 0, 0, 1), + IPC_CMD9_PREPARE_POWER = MAKE_CMD(36, 0, 0, 0), + IPC_CMD9_PANIC = MAKE_CMD(37, 0, 0, 0), + IPC_CMD9_EXCEPTION = MAKE_CMD(38, 0, 0, 0) } IpcCmd9; typedef enum { - IPC_CMD11_PRINT_MSG = CMD_ID(0) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(15), // Invalid on purpose. Will be decided later. - IPC_CMD11_PANIC = CMD_ID(1) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD11_EXCEPTION = CMD_ID(2) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0) + IPC_CMD11_PRINT_MSG = MAKE_CMD(0, 0, 0, 0), // Invalid on purpose. Will be decided later. + IPC_CMD11_PANIC = MAKE_CMD(1, 0, 0, 0), + IPC_CMD11_EXCEPTION = MAKE_CMD(2, 0, 0, 0) } IpcCmd11; -#undef CMD_ID -#undef CMD_IN_BUFS -#undef CMD_OUT_BUFS -#undef CMD_PARAMS +#undef MAKE_CMD typedef struct diff --git a/source/arm11/debug.c b/source/arm11/debug.c index bae56d9..b4e014d 100644 --- a/source/arm11/debug.c +++ b/source/arm11/debug.c @@ -32,41 +32,18 @@ #include "arm11/hardware/hid.h" -#ifndef NDEBUG -static u32 debugHash = 0; -#endif - - - -void debugHashCodeRoData() -{ -#ifndef NDEBUG - extern u32 __start__[]; - extern u32 __exidx_start[]; - - u32 *start = __start__; - u32 *end = __exidx_start; - - debugHash = 0; - - for(u32 *ptr = start; ptr < end; ptr++) - debugHash += *ptr; -#endif -} noreturn void panic() { - register u32 lr __asm__("lr"); - enterCriticalSection(); consoleInit(SCREEN_SUB, NULL, false); - ee_printf("\x1b[41m\x1b[0J\x1b[15C****PANIC!!!****\n\nlr = 0x%08" PRIX32 "\n", lr); + ee_printf("\x1b[41m\x1b[0J\x1b[15C****PANIC!!!****\n"); GX_textureCopy((u64*)RENDERBUF_TOP, 0, (u64*)GFX_getFramebuffer(SCREEN_TOP), 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); GFX_swapFramebufs(); - PXI_sendCmd(IPC_CMD9_PANIC, NULL, 0); + PXI_sendPanicCmd(IPC_CMD9_PANIC); // Wait for any button. do @@ -74,25 +51,22 @@ hidScanInput(); } while(!(hidKeysDown() & HID_KEY_MASK_ALL)); - MCU_powerOffLCDs(); MCU_triggerPowerOff(); while(1) __wfi(); } noreturn void panicMsg(const char *msg) { - register u32 lr __asm__("lr"); - enterCriticalSection(); consoleInit(SCREEN_SUB, NULL, false); - ee_printf("\x1b[41m\x1b[0J\x1b[15C****PANIC!!!****\n\nlr = 0x%08" PRIX32 "\n", lr); + ee_printf("\x1b[41m\x1b[0J\x1b[15C****PANIC!!!****\n\n"); ee_printf("\nERROR MESSAGE:\n%s\n", msg); GX_textureCopy((u64*)RENDERBUF_TOP, 0, (u64*)GFX_getFramebuffer(SCREEN_TOP), 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); GFX_swapFramebufs(); - PXI_sendCmd(IPC_CMD9_PANIC, NULL, 0); + PXI_sendPanicCmd(IPC_CMD9_PANIC); // Wait for any button. do @@ -100,7 +74,6 @@ hidScanInput(); } while(!(hidKeysDown() & HID_KEY_MASK_ALL)); - MCU_powerOffLCDs(); MCU_triggerPowerOff(); while(1) __wfi(); } @@ -162,7 +135,7 @@ 0, SCREEN_SIZE_TOP + SCREEN_SIZE_SUB); GFX_swapFramebufs(); - PXI_sendCmd(IPC_CMD9_EXCEPTION, NULL, 0); + PXI_sendPanicCmd(IPC_CMD9_EXCEPTION); // Wait for any button. do @@ -170,7 +143,6 @@ hidScanInput(); } while(!(hidKeysDown() & HID_KEY_MASK_ALL)); - MCU_powerOffLCDs(); MCU_triggerPowerOff(); while(1) __wfi(); } diff --git a/source/arm11/ipc_handler.c b/source/arm11/ipc_handler.c index 94b8925..5e511c5 100644 --- a/source/arm11/ipc_handler.c +++ b/source/arm11/ipc_handler.c @@ -36,9 +36,7 @@ switch(cmdId) { case IPC_CMD_ID_MASK(IPC_CMD11_PRINT_MSG): - break; case IPC_CMD_ID_MASK(IPC_CMD11_PANIC): - break; case IPC_CMD_ID_MASK(IPC_CMD11_EXCEPTION): break; default: diff --git a/source/arm9/debug.c b/source/arm9/debug.c index c95b041..3c527ff 100644 --- a/source/arm9/debug.c +++ b/source/arm9/debug.c @@ -55,7 +55,7 @@ { enterCriticalSection(); fsDeinit(); - PXI_sendCmd(IPC_CMD11_PANIC, NULL, 0); + PXI_sendPanicCmd(IPC_CMD11_PANIC); while(1) { @@ -69,7 +69,7 @@ { enterCriticalSection(); fsDeinit(); - PXI_sendCmd(IPC_CMD11_PANIC, NULL, 0); + PXI_sendPanicCmd(IPC_CMD11_PANIC); while(1) { @@ -85,7 +85,7 @@ { // avoid fs corruptions fsDeinit(); - PXI_sendCmd(IPC_CMD11_EXCEPTION, NULL, 0); + PXI_sendPanicCmd(IPC_CMD11_EXCEPTION); while(1) { diff --git a/source/hardware/pxi.c b/source/hardware/pxi.c index 0b49f49..92a3d87 100644 --- a/source/hardware/pxi.c +++ b/source/hardware/pxi.c @@ -30,6 +30,9 @@ #include "hardware/cache.h" +static vu32 g_lastResp[2] = {0}; + + static void pxiIrqHandler(UNUSED u32 id); @@ -76,6 +79,13 @@ static void pxiIrqHandler(UNUSED u32 id) { const u32 cmdCode = pxiRecvWord(); + if(cmdCode & IPC_CMD_RESP_FLAG) + { + g_lastResp[0] = cmdCode; + g_lastResp[1] = pxiRecvWord(); + return; + } + const u32 inBufs = IPC_CMD_IN_BUFS_MASK(cmdCode); const u32 outBufs = IPC_CMD_OUT_BUFS_MASK(cmdCode); const u32 params = IPC_CMD_PARAMS_MASK(cmdCode); @@ -86,7 +96,9 @@ for(u32 i = 0; i < words; i++) buf[i] = pxiRecvWord(); if(pxiFifoError()) panic(); + pxiSendWord(IPC_CMD_RESP_FLAG | cmdCode); pxiSendWord(IPC_handleCmd(IPC_CMD_ID_MASK(cmdCode), inBufs, outBufs, buf)); + pxiSyncRequest(); } u32 PXI_sendCmd(u32 cmd, const u32 *buf, u32 words) @@ -113,7 +125,9 @@ while(words--) pxiSendWord(*buf++); if(pxiFifoError()) panic(); - const u32 res = pxiRecvWord(); + while(g_lastResp[0] != (IPC_CMD_RESP_FLAG | cmd)) __wfi(); + g_lastResp[0] = 0; + const u32 res = g_lastResp[1]; #ifdef ARM11 // The CPU may do speculative prefetches of data after the first invalidation @@ -127,3 +141,11 @@ return res; } + +void PXI_sendPanicCmd(u32 cmd) +{ + pxiSendWord(cmd); + pxiSyncRequest(); + while(pxiRecvWord() != (IPC_CMD_RESP_FLAG | cmd)); + // We don't care about the result +}