diff --git a/arm11/Makefile b/arm11/Makefile index 0eb2e68..74bc49e 100644 --- a/arm11/Makefile +++ b/arm11/Makefile @@ -15,7 +15,7 @@ # all directories are relative to this makefile #--------------------------------------------------------------------------------- BUILD := build -SOURCES := ../source ../source/arm11 ../source/arm11/hardware +SOURCES := ../source ../source/hardware ../source/arm11 ../source/arm11/hardware INCLUDES := ../include DEFINES := -DARM11 -D_3DS -DVERS_STRING=\"$(VERS_STRING)\" \ -DVERS_MAJOR=$(VERS_MAJOR) -DVERS_MINOR=$(VERS_MINOR) diff --git a/arm9/Makefile b/arm9/Makefile index ecbe23f..d382564 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -15,7 +15,7 @@ # all directories are relative to this makefile #--------------------------------------------------------------------------------- BUILD := build -SOURCES := ../source ../source/arm9 ../source/arm9/gui ../source/arm9/hardware ../thirdparty/fatfs +SOURCES := ../source ../source/hardware ../source/arm9 ../source/arm9/hardware ../thirdparty/fatfs INCLUDES := ../include ../thirdparty DEFINES := -DARM9 -D_3DS -DVERS_STRING=\"$(VERS_STRING)\" \ -DVERS_MAJOR=$(VERS_MAJOR) -DVERS_MINOR=$(VERS_MINOR) diff --git a/include/arm9/hardware/ndma.h b/include/arm9/hardware/ndma.h index 9ac4b4b..4999370 100644 --- a/include/arm9/hardware/ndma.h +++ b/include/arm9/hardware/ndma.h @@ -118,7 +118,7 @@ #define NDMA_SRC_ADDR_RELOAD (1u<<15) // The block length is 2^n words (Example: 2^15 = 32768 words = 0x20000 bytes) #define NDMA_BURST_SIZE(n) ((u32)log2(n)<<16) -#define NDMA_IMMEDIATE_MODE (16<<24) +#define NDMA_IMMEDIATE_MODE (16u<<24) #define NDMA_TOTAL_CNT_MODE (0u) #define NDMA_REPEATING_MODE (1u<<29) #define NDMA_IRQ_ENABLE (1u<<30) diff --git a/include/hardware/pxi.h b/include/hardware/pxi.h index 9d439cb..9dedec6 100644 --- a/include/hardware/pxi.h +++ b/include/hardware/pxi.h @@ -23,39 +23,33 @@ #ifdef ARM9 -#define PXI9_REGS_BASE (IO_MEM_ARM9_ONLY + 0x8000) -#define REG_PXI_SYNC9 *((vu32*)(PXI9_REGS_BASE + 0x00)) -#define REG_PXI_CNT9 *((vu32*)(PXI9_REGS_BASE + 0x04)) -#define REG_PXI_SEND9 *((vu32*)(PXI9_REGS_BASE + 0x08)) -#define REG_PXI_RECV9 *((vu32*)(PXI9_REGS_BASE + 0x0C)) +#define PXI_REGS_BASE (IO_MEM_ARM9_ONLY + 0x8000) +#elif ARM11 +#define PXI_REGS_BASE (IO_MEM_ARM9_ARM11 + 0x63000) #endif - -#ifdef ARM11 -#define PXI11_REGS_BASE (IO_MEM_ARM9_ARM11 + 0x63000) -#define REG_PXI_SYNC11 *((vu32*)(PXI11_REGS_BASE + 0x00)) -#define REG_PXI_CNT11 *((vu32*)(PXI11_REGS_BASE + 0x04)) -#define REG_PXI_SEND11 *((vu32*)(PXI11_REGS_BASE + 0x08)) -#define REG_PXI_RECV11 *((vu32*)(PXI11_REGS_BASE + 0x0C)) -#endif +#define REG_PXI_SYNC *((vu32*)(PXI_REGS_BASE + 0x00)) +#define REG_PXI_CNT *((vu32*)(PXI_REGS_BASE + 0x04)) +#define REG_PXI_SEND *((vu32*)(PXI_REGS_BASE + 0x08)) +#define REG_PXI_RECV *((vu32*)(PXI_REGS_BASE + 0x0C)) // Defines for PX_SYNC regs -#define PXI_DATA_RECEIVED(reg) ((reg) & 0xFFu) -#define PXI_DATA_SENT(reg, sent) (((reg) & ~(0xFFu<<8)) | sent<<8) -#define PXI_NOTIFY_11 (1u<<29) -#define PXI_NOTIFY_9 (1u<<30) -#define PXI_IRQ_ENABLE (1u<<31) +#define PXI_DATA_RECEIVED(reg) ((reg) & 0xFFu) +#define PXI_DATA_SENT(reg, sent) (((reg) & ~(0xFFu<<8)) | sent<<8) +#define PXI_NOTIFY_11 (1u<<29) +#define PXI_NOTIFY_9 (1u<<30) +#define PXI_IRQ_ENABLE (1u<<31) // Defines for PXI_CNT regs -#define PXI_SEND_FIFO_EMPTY (1u<<0) -#define PXI_SEND_FIFO_FULL (1u<<1) -#define PXI_SEND_FIFO_EMPTY_IRQ (1u<<2) -#define PXI_FLUSH_SEND_FIFO (1u<<3) -#define PXI_RECV_FIFO_EMPTY (1u<<8) -#define PXI_RECV_FIFO_FULL (1u<<9) -#define PXI_RECV_FIFO_NOT_EMPTY_IRQ (1u<<10) -#define PXI_EMPTY_FULL_ERROR (1u<<14) -#define PXI_ENABLE_SEND_RECV_FIFO (1u<<15) +#define PXI_SEND_FIFO_EMPTY (1u<<0) +#define PXI_SEND_FIFO_FULL (1u<<1) +#define PXI_SEND_FIFO_EMPTY_IRQ (1u<<2) +#define PXI_FLUSH_SEND_FIFO (1u<<3) +#define PXI_RECV_FIFO_EMPTY (1u<<8) +#define PXI_RECV_FIFO_FULL (1u<<9) +#define PXI_RECV_FIFO_NOT_EMPTY_IRQ (1u<<10) +#define PXI_EMPTY_FULL_ERROR (1u<<14) +#define PXI_ENABLE_SEND_RECV_FIFO (1u<<15) diff --git a/source/arm11/hardware/pxi.c b/source/arm11/hardware/pxi.c deleted file mode 100644 index a2a41da..0000000 --- a/source/arm11/hardware/pxi.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "types.h" -#include "hardware/pxi.h" -#include "arm11/hardware/interrupt.h" -//#include "arm11/debug.h" -#include "fb_assert.h" -#include "ipc_handler.h" - - -// Temporary until we have a panic() function. -#define panic() *((vu32*)4) = 0xDEADBEEF - - - -static void pxiIrqHandler(UNUSED u32 intSource); - -void PXI_init(void) -{ - REG_PXI_SYNC11 = PXI_IRQ_ENABLE; - REG_PXI_CNT11 = PXI_FLUSH_SEND_FIFO | PXI_EMPTY_FULL_ERROR | PXI_ENABLE_SEND_RECV_FIFO; - - while(PXI_DATA_RECEIVED(REG_PXI_SYNC11) != 9u); - REG_PXI_SYNC11 |= 11u<<8; - - IRQ_registerHandler(IRQ_PXI_SYNC, 13, 0, true, pxiIrqHandler); -} - -static void pxiIrqHandler(UNUSED u32 intSource) -{ - const u32 cmdCode = REG_PXI_RECV11; - 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(cmdBufSize > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC11)) - { - panic(); - } - - u32 buf[IPC_MAX_PARAMS]; - 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_ID_MASK(cmdCode), inBufs, outBufs, buf); -} - -u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) -{ - if(!buf) words = 0; - fb_assert(words <= IPC_MAX_PARAMS); - - while(REG_PXI_CNT11 & PXI_SEND_FIFO_FULL); - REG_PXI_SEND11 = cmd; - 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; - - while(REG_PXI_CNT11 & PXI_RECV_FIFO_EMPTY); - return REG_PXI_RECV11; -} diff --git a/source/arm9/hardware/pxi.c b/source/arm9/hardware/pxi.c deleted file mode 100644 index 89fe045..0000000 --- a/source/arm9/hardware/pxi.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of fastboot 3DS - * Copyright (C) 2017 derrek, profi200 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "types.h" -#include "hardware/pxi.h" -#include "arm9/hardware/interrupt.h" -#include "arm9/debug.h" -#include "fb_assert.h" -#include "ipc_handler.h" - - - -static void pxiIrqHandler(UNUSED u32 id); - -void PXI_init(void) -{ - REG_PXI_SYNC9 = PXI_IRQ_ENABLE; - REG_PXI_CNT9 = PXI_FLUSH_SEND_FIFO | PXI_EMPTY_FULL_ERROR | PXI_ENABLE_SEND_RECV_FIFO; - - REG_PXI_SYNC9 |= 9u<<8; - while(PXI_DATA_RECEIVED(REG_PXI_SYNC9) != 11u); - - IRQ_registerHandler(IRQ_PXI_SYNC, pxiIrqHandler); -} - -static void pxiIrqHandler(UNUSED u32 id) -{ - const u32 cmdCode = REG_PXI_RECV9; - 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(cmdBufSize > IPC_MAX_PARAMS || params != PXI_DATA_RECEIVED(REG_PXI_SYNC9)) - { - panic(); - } - - u32 buf[IPC_MAX_PARAMS]; - 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_ID_MASK(cmdCode), inBufs, outBufs, buf); -} - -u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) -{ - if(!buf) words = 0; - fb_assert(words <= IPC_MAX_PARAMS); - - while(REG_PXI_CNT9 & PXI_SEND_FIFO_FULL); - REG_PXI_SEND9 = cmd; - 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; - - while(REG_PXI_CNT9 & PXI_RECV_FIFO_EMPTY); - return REG_PXI_RECV9; -} diff --git a/source/hardware/pxi.c b/source/hardware/pxi.c new file mode 100644 index 0000000..81317a7 --- /dev/null +++ b/source/hardware/pxi.c @@ -0,0 +1,105 @@ +/* + * This file is part of fastboot 3DS + * Copyright (C) 2017 derrek, profi200 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "types.h" +#include "hardware/pxi.h" +#ifdef ARM9 + #include "arm9/hardware/interrupt.h" + #include "arm9/debug.h" +#elif ARM11 + #include "arm11/hardware/interrupt.h" +#endif +#include "fb_assert.h" +#include "ipc_handler.h" +#include "hardware/cache.h" + + +#ifdef ARM11 +// Temporary until we have a panic() function. +#define panic() *((vu32*)4) = 0xDEADBEEF +#endif + + + +static void pxiIrqHandler(UNUSED u32 id); + +void PXI_init(void) +{ + REG_PXI_SYNC = PXI_IRQ_ENABLE; + REG_PXI_CNT = PXI_FLUSH_SEND_FIFO | PXI_EMPTY_FULL_ERROR | PXI_ENABLE_SEND_RECV_FIFO; + +#ifdef ARM9 + REG_PXI_SYNC |= 9u<<8; + while(PXI_DATA_RECEIVED(REG_PXI_SYNC) != 11u); + + IRQ_registerHandler(IRQ_PXI_SYNC, pxiIrqHandler); +#elif ARM11 + while(PXI_DATA_RECEIVED(REG_PXI_SYNC) != 9u); + REG_PXI_SYNC |= 11u<<8; + + IRQ_registerHandler(IRQ_PXI_SYNC, 13, 0, true, pxiIrqHandler); +#endif +} + +static void pxiIrqHandler(UNUSED u32 id) +{ + const u32 cmdCode = REG_PXI_RECV; + 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 = ((u32)inBufs * 2) + ((u32)outBufs * 2) + params; + + if(cmdBufSize > IPC_MAX_PARAMS || cmdBufSize != PXI_DATA_RECEIVED(REG_PXI_SYNC)) + { + panic(); + } + + u32 buf[IPC_MAX_PARAMS]; + for(u32 i = 0; i < cmdBufSize; i++) buf[i] = REG_PXI_RECV; + if(REG_PXI_SYNC & PXI_EMPTY_FULL_ERROR) panic(); + + REG_PXI_SEND = IPC_handleCmd(IPC_CMD_ID_MASK(cmdCode), inBufs, outBufs, buf); +} + +u32 PXI_sendCmd(u32 cmd, const u32 *const buf, u8 words) +{ + if(!buf) words = 0; + fb_assert(words <= IPC_MAX_PARAMS); + + const u8 inBufs = IPC_CMD_IN_BUFS_MASK(cmd); + const u8 outBufs = IPC_CMD_OUT_BUFS_MASK(cmd); + for(u32 i = 0; i < inBufs; i++) + flushDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); + + for(u32 i = inBufs; i < inBufs + outBufs; i++) + invalidateDCacheRange((void*)buf[i * 2], buf[i * 2 + 1]); + + while(REG_PXI_CNT & PXI_SEND_FIFO_FULL); + REG_PXI_SEND = cmd; + for(u32 i = 0; i < words; i++) REG_PXI_SEND = buf[i]; + if(REG_PXI_SYNC & PXI_EMPTY_FULL_ERROR) panic(); + +#ifdef ARM9 + REG_PXI_SYNC = PXI_DATA_SENT(REG_PXI_SYNC, words) | PXI_NOTIFY_11; +#elif ARM11 + REG_PXI_SYNC = PXI_DATA_SENT(REG_PXI_SYNC, words) | PXI_NOTIFY_9; +#endif + + while(REG_PXI_CNT & PXI_RECV_FIFO_EMPTY); + return REG_PXI_RECV; +}