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;
+}