diff --git a/include/ipc_handler.h b/include/ipc_handler.h index a7aaed1..ee5ace8 100644 --- a/include/ipc_handler.h +++ b/include/ipc_handler.h @@ -21,43 +21,54 @@ #include "types.h" -#define IPC_MAX_PARAMS (16) -#define IPC_CMD_MASK(cmd) ((cmd) & 0xFFu) -#define IPC_PARAM_MASK(cmd) ((cmd)>>16 & 0xFFu) +#define IPC_MAX_PARAMS (16) +#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)>>26 & 0xFu) +#define IPC_CMD_PARAMS_MASK(cmd) ((cmd)>>12 & 0xFu) -#define CMD_PARAMS(n) ((n)<<16) + +#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) + typedef enum { - IPC_CMD9_FMOUNT = CMD_PARAMS(3) | 0, - IPC_CMD9_FUNMOUNT = CMD_PARAMS(1) | 1, - IPC_CMD9_FOPEN = CMD_PARAMS(3) | 2, - IPC_CMD9_FCLOSE = CMD_PARAMS(1) | 3, - IPC_CMD9_FREAD = CMD_PARAMS(4) | 4, - IPC_CMD9_FWRITE = CMD_PARAMS(4) | 5, - IPC_CMD9_FOPEN_DIR = CMD_PARAMS(2) | 6, - IPC_CMD9_FREAD_DIR = CMD_PARAMS(2) | 7, - IPC_CMD9_FCLOSE_DIR = CMD_PARAMS(1) | 8, - IPC_CMD9_FUNLINK = CMD_PARAMS(1) | 9, - IPC_CMD9_FGETFREE = CMD_PARAMS(3) | 10, - IPC_CMD9_READ_SECTORS = CMD_PARAMS(17) | 11, // Invalid param num on purpose. Will be decided later. - IPC_CMD9_WRITE_SECTORS = CMD_PARAMS(17) | 12, // Invalid param num on purpose. Will be decided later. - IPC_CMD9_MALLOC = CMD_PARAMS(1) | 13, - IPC_CMD9_FREE = CMD_PARAMS(1) | 14, - IPC_CMD9_LOAD_VERIFY_FIRM = CMD_PARAMS(17) | 15, // Invalid param num on purpose. Will be decided later. - IPC_CMD9_FIRM_LAUNCH = CMD_PARAMS(17) | 16, // Invalid param num on purpose. Will be decided later. - IPC_CMD9_PREPA_POWER = CMD_PARAMS(0) | 17, - IPC_CMD9_PANIC = CMD_PARAMS(0) | 18, - IPC_CMD9_EXCEPTION = CMD_PARAMS(0) | 19 + IPC_CMD9_FMOUNT = CMD_ID(0) | CMD_IN_BUFS(1) | 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_FOPEN = CMD_ID(2) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), + IPC_CMD9_FCLOSE = CMD_ID(3) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FREAD = CMD_ID(4) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(4), + IPC_CMD9_FWRITE = CMD_ID(5) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(4), + IPC_CMD9_FOPEN_DIR = CMD_ID(6) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), + IPC_CMD9_FREAD_DIR = CMD_ID(7) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(2), + IPC_CMD9_FCLOSE_DIR = CMD_ID(8) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FUNLINK = CMD_ID(9) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FGETFREE = CMD_ID(10) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(3), + IPC_CMD9_READ_SECTORS = CMD_ID(11) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD9_WRITE_SECTORS = CMD_ID(12) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD9_MALLOC = CMD_ID(13) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FREE = CMD_ID(14) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_LOAD_VERIFY_FIRM = CMD_ID(15) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD9_FIRM_LAUNCH = CMD_ID(16) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD9_PREPA_POWER = CMD_ID(17) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), + IPC_CMD9_PANIC = CMD_ID(18) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), + IPC_CMD9_EXCEPTION = CMD_ID(19) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(0) } IpcCmd9; typedef enum { - IPC_CMD11_PRINT_MSG = CMD_PARAMS(17) | 0, // Invalid param num on purpose. Will be decided later. - IPC_CMD11_PANIC = CMD_PARAMS(17) | 1, // Invalid param num on purpose. Will be decided later. - IPC_CMD11_EXCEPTION = CMD_PARAMS(17) | 2 // Invalid param num on purpose. Will be decided later. + IPC_CMD11_PRINT_MSG = CMD_ID(0) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD11_PANIC = CMD_ID(1) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(17), // Invalid on purpose. Will be decided later. + IPC_CMD11_EXCEPTION = CMD_ID(2) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(17) // Invalid on purpose. Will be decided later. } IpcCmd11; + +#undef CMD_ID +#undef CMD_IN_BUFS +#undef CMD_OUT_BUFS #undef CMD_PARAMS -u32 IPC_handleCmd(u8 cmd, const u32 *buf); +u32 IPC_handleCmd(u8 cmdId, u8 inBufs, u8 outBufs, const u32 *buf); diff --git a/source/arm11/hardware/pxi.c b/source/arm11/hardware/pxi.c index 1d66a79..a2a41da 100644 --- a/source/arm11/hardware/pxi.c +++ b/source/arm11/hardware/pxi.c @@ -45,21 +45,21 @@ static void pxiIrqHandler(UNUSED u32 intSource) { const u32 cmdCode = REG_PXI_RECV11; - const u8 params = IPC_PARAM_MASK(cmdCode); + const u8 inBufs = IPC_CMD_IN_BUFS_MASK(cmdCode); + const u8 outBufs = IPC_CMD_OUT_BUFS_MASK(cmdCode); + const u8 params = IPC_CMD_PARAMS_MASK(cmdCode); + const u32 cmdBufSize = (inBufs * 2) + (outBufs * 2) + params; - if(params > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC11)) + if(cmdBufSize > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC11)) { panic(); } u32 buf[IPC_MAX_PARAMS]; - for(u32 i = 0; i < params; i++) - { - if(REG_PXI_SYNC11 & PXI_EMPTY_FULL_ERROR) panic(); - buf[i] = REG_PXI_RECV11; - } + for(u32 i = 0; i < cmdBufSize; i++) buf[i] = REG_PXI_RECV11; + if(REG_PXI_SYNC11 & PXI_EMPTY_FULL_ERROR) panic(); - REG_PXI_SEND11 = IPC_handleCmd(IPC_CMD_MASK(cmdCode), buf); + REG_PXI_SEND11 = IPC_handleCmd(IPC_CMD_ID_MASK(cmdCode), inBufs, outBufs, buf); } u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) @@ -69,11 +69,8 @@ while(REG_PXI_CNT11 & PXI_SEND_FIFO_FULL); REG_PXI_SEND11 = cmd; - for(u32 i = 0; i < words; i++) - { - if(REG_PXI_SYNC11 & PXI_EMPTY_FULL_ERROR) panic(); - REG_PXI_SEND11 = buf[i]; - } + for(u32 i = 0; i < words; i++) REG_PXI_SEND11 = buf[i]; + if(REG_PXI_SYNC11 & PXI_EMPTY_FULL_ERROR) panic(); REG_PXI_SYNC11 = PXI_DATA_SENT(REG_PXI_SYNC11, words) | PXI_NOTIFY_9; diff --git a/source/arm11/ipc_handler.c b/source/arm11/ipc_handler.c index 8e69a6c..34451c0 100644 --- a/source/arm11/ipc_handler.c +++ b/source/arm11/ipc_handler.c @@ -18,7 +18,7 @@ #include "types.h" #include "ipc_handler.h" -#include "hardware/pxi.h" +#include "hardware/cache.h" //#include "arm11/debug.h" @@ -27,17 +27,22 @@ -u32 IPC_handleCmd(u8 cmd, UNUSED const u32 *buf) +u32 IPC_handleCmd(u8 cmdId, u8 inBufs, u8 outBufs, UNUSED const u32 *buf) { - u32 result = 0; + for(u32 i = 0; i < inBufs; i++) + invalidateDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); - switch(cmd) + for(u32 i = inBufs; i < inBufs + outBufs; i++) + flushDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); + + u32 result = 0; + switch(cmdId) { - case IPC_CMD_MASK(IPC_CMD11_PRINT_MSG): + case IPC_CMD_ID_MASK(IPC_CMD11_PRINT_MSG): break; - case IPC_CMD_MASK(IPC_CMD11_PANIC): + case IPC_CMD_ID_MASK(IPC_CMD11_PANIC): break; - case IPC_CMD_MASK(IPC_CMD11_EXCEPTION): + case IPC_CMD_ID_MASK(IPC_CMD11_EXCEPTION): break; default: panic(); diff --git a/source/arm9/hardware/pxi.c b/source/arm9/hardware/pxi.c index fe9a63a..89fe045 100644 --- a/source/arm9/hardware/pxi.c +++ b/source/arm9/hardware/pxi.c @@ -41,21 +41,21 @@ static void pxiIrqHandler(UNUSED u32 id) { const u32 cmdCode = REG_PXI_RECV9; - const u8 params = IPC_PARAM_MASK(cmdCode); + const u8 inBufs = IPC_CMD_IN_BUFS_MASK(cmdCode); + const u8 outBufs = IPC_CMD_OUT_BUFS_MASK(cmdCode); + const u8 params = IPC_CMD_PARAMS_MASK(cmdCode); + const u32 cmdBufSize = (inBufs * 2) + (outBufs * 2) + params; - if(params > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC9)) + if(cmdBufSize > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC9)) { panic(); } u32 buf[IPC_MAX_PARAMS]; - for(u32 i = 0; i < params; i++) - { - if(REG_PXI_SYNC9 & PXI_EMPTY_FULL_ERROR) panic(); - buf[i] = REG_PXI_RECV9; - } + for(u32 i = 0; i < cmdBufSize; i++) buf[i] = REG_PXI_RECV9; + if(REG_PXI_SYNC9 & PXI_EMPTY_FULL_ERROR) panic(); - REG_PXI_SEND9 = IPC_handleCmd(IPC_CMD_MASK(cmdCode), buf); + REG_PXI_SEND9 = IPC_handleCmd(IPC_CMD_ID_MASK(cmdCode), inBufs, outBufs, buf); } u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) @@ -65,11 +65,8 @@ while(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL); REG_PXI_SEND9 = cmd; - for(u32 i = 0; i < words; i++) - { - if(REG_PXI_SYNC9 & PXI_EMPTY_FULL_ERROR) panic(); - REG_PXI_SEND9 = buf[i]; - } + for(u32 i = 0; i < words; i++) REG_PXI_SEND9 = buf[i]; + if(REG_PXI_SYNC9 & PXI_EMPTY_FULL_ERROR) panic(); REG_PXI_SYNC9 = PXI_DATA_SENT(REG_PXI_SYNC9, words) | PXI_NOTIFY_11; diff --git a/source/arm9/ipc_handler.c b/source/arm9/ipc_handler.c index 1988518..1b69719 100644 --- a/source/arm9/ipc_handler.c +++ b/source/arm9/ipc_handler.c @@ -19,48 +19,53 @@ #include #include "types.h" #include "ipc_handler.h" -#include "hardware/pxi.h" +#include "hardware/cache.h" #include "arm9/debug.h" #include "fatfs/ff.h" -u32 IPC_handleCmd(u8 cmd, const u32 *buf) +u32 IPC_handleCmd(u8 cmdId, u8 inBufs, u8 outBufs, const u32 *buf) { - u32 result = 0; + for(u32 i = 0; i < inBufs; i++) + invalidateDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); - switch(cmd) + for(u32 i = inBufs; i < inBufs + outBufs; i++) + flushDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); + + u32 result = 0; + switch(cmdId) { - case IPC_CMD_MASK(IPC_CMD9_FMOUNT): + case IPC_CMD_ID_MASK(IPC_CMD9_FMOUNT): break; - case IPC_CMD_MASK(IPC_CMD9_FUNMOUNT): + case IPC_CMD_ID_MASK(IPC_CMD9_FUNMOUNT): break; - case IPC_CMD_MASK(IPC_CMD9_FOPEN): + case IPC_CMD_ID_MASK(IPC_CMD9_FOPEN): break; - case IPC_CMD_MASK(IPC_CMD9_FCLOSE): + case IPC_CMD_ID_MASK(IPC_CMD9_FCLOSE): break; - case IPC_CMD_MASK(IPC_CMD9_FREAD): + case IPC_CMD_ID_MASK(IPC_CMD9_FREAD): break; - case IPC_CMD_MASK(IPC_CMD9_FWRITE): + case IPC_CMD_ID_MASK(IPC_CMD9_FWRITE): break; - case IPC_CMD_MASK(IPC_CMD9_FOPEN_DIR): + case IPC_CMD_ID_MASK(IPC_CMD9_FOPEN_DIR): break; - case IPC_CMD_MASK(IPC_CMD9_FREAD_DIR): + case IPC_CMD_ID_MASK(IPC_CMD9_FREAD_DIR): break; - case IPC_CMD_MASK(IPC_CMD9_FCLOSE_DIR): + case IPC_CMD_ID_MASK(IPC_CMD9_FCLOSE_DIR): break; - case IPC_CMD_MASK(IPC_CMD9_FUNLINK): + case IPC_CMD_ID_MASK(IPC_CMD9_FUNLINK): break; - case IPC_CMD_MASK(IPC_CMD9_FGETFREE): + case IPC_CMD_ID_MASK(IPC_CMD9_FGETFREE): break; - case IPC_CMD_MASK(IPC_CMD9_READ_SECTORS): + case IPC_CMD_ID_MASK(IPC_CMD9_READ_SECTORS): break; - case IPC_CMD_MASK(IPC_CMD9_WRITE_SECTORS): + case IPC_CMD_ID_MASK(IPC_CMD9_WRITE_SECTORS): break; - case IPC_CMD_MASK(IPC_CMD9_MALLOC): + case IPC_CMD_ID_MASK(IPC_CMD9_MALLOC): //result = (u32)malloc(buf[0]); break; - case IPC_CMD_MASK(IPC_CMD9_FREE): + case IPC_CMD_ID_MASK(IPC_CMD9_FREE): /*{ extern char* fake_heap_start; extern char* fake_heap_end; @@ -68,13 +73,13 @@ free((void*)buf[0]); }*/ break; - case IPC_CMD_MASK(IPC_CMD9_LOAD_VERIFY_FIRM): + case IPC_CMD_ID_MASK(IPC_CMD9_LOAD_VERIFY_FIRM): break; - case IPC_CMD_MASK(IPC_CMD9_FIRM_LAUNCH): + case IPC_CMD_ID_MASK(IPC_CMD9_FIRM_LAUNCH): break; - case IPC_CMD_MASK(IPC_CMD9_PREPA_POWER): - case IPC_CMD_MASK(IPC_CMD9_PANIC): - case IPC_CMD_MASK(IPC_CMD9_EXCEPTION): + case IPC_CMD_ID_MASK(IPC_CMD9_PREPA_POWER): + case IPC_CMD_ID_MASK(IPC_CMD9_PANIC): + case IPC_CMD_ID_MASK(IPC_CMD9_EXCEPTION): // Close and deinitalize everything. break; default: