diff --git a/Makefile b/Makefile
index 99e2dee..0ff2da0 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ export INCLUDE := -I"$(shell pwd)/common"
export ASFLAGS := -g -x assembler-with-cpp $(INCLUDE)
export CFLAGS := -DDBUILTS="\"$(DBUILTS)\"" -DDBUILTL="\"$(DBUILTL)\"" -DVERSION="\"$(VERSION)\"" -DFLAVOR="\"$(FLAVOR)\"" \
- -g -Os -Wall -Wextra -Wpedantic -Wcast-align -Wformat=2 -Wno-main \
+ -g -Os -Wall -Wextra -Wcast-align -Wformat=2 -Wno-main \
-fomit-frame-pointer -ffast-math -std=gnu11 -MMD -MP \
-Wno-unused-function -Wno-format-truncation $(INCLUDE) -ffunction-sections -fdata-sections
export LDFLAGS := -Tlink.ld -nostartfiles -Wl,--gc-sections,-z,max-page-size=512
diff --git a/arm11/Makefile b/arm11/Makefile
index 09dde18..2f321a1 100644
--- a/arm11/Makefile
+++ b/arm11/Makefile
@@ -10,8 +10,8 @@ INCDIRS := source
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
ASFLAGS += $(SUBARCH) $(INCLUDE)
-CFLAGS += $(SUBARCH) $(INCLUDE)
-LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map
+CFLAGS += $(SUBARCH) $(INCLUDE) -flto
+LDFLAGS += $(SUBARCH) -Wl,-Map,$(TARGET).map -flto
include ../Makefile.common
include ../Makefile.build
diff --git a/arm11/source/arm/exception.c b/arm11/source/arm/exception.c
new file mode 100644
index 0000000..86df02e
--- /dev/null
+++ b/arm11/source/arm/exception.c
@@ -0,0 +1,217 @@
+/*
+ * This file is part of GodMode9
+ * Copyright (C) 2019 Wolfvak
+ *
+ * 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 2 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
+#include
+
+#include
+
+static const u8 num_font[16*8];
+
+#define SCREEN ((u16*)(VRAM_TOP_LA))
+
+void draw_char(u16 *fb, int c, int x, int y)
+{
+ for (int _y = 0; _y < 8; _y++) {
+ for (int _x = 0; _x < 8; _x++) {
+ u16 *fbpos = fb + (240 - (y + _y)) + (240 * (x + _x));
+
+ u8 mask = (num_font[(c * 8) + _y] >> (8 - _x)) & 1;
+
+ if (mask)
+ *fbpos = ~0;
+ else
+ *fbpos = 0;
+ }
+ }
+}
+
+void draw_hex(u16 *fb, u32 num, int x, int y)
+{
+ x += 7*8;
+ for (int i = 0; i < 8; i++) {
+ draw_char(fb, num & 0xf, x, y);
+ num >>= 4;
+ x -= 8;
+ }
+}
+
+void do_exception(u32 type, u32 *regs)
+{
+ for (int i = 0; i < 400*240; i++)
+ SCREEN[i] = 0;
+
+ draw_hex(SCREEN, type, 8, 16);
+
+ for (int i = 0; i < 20; i += 2) {
+ draw_hex(SCREEN, i, 8, 32 + (i * 4));
+ draw_hex(SCREEN, regs[i], 80, 32 + (i * 4));
+
+ draw_hex(SCREEN, i + 1, 208, 32 + (i * 4));
+ draw_hex(SCREEN, regs[i + 1], 280, 32 + (i * 4));
+ }
+
+ while(1)
+ ARM_WFI();
+}
+
+static const u8 num_font[] = {
+ 0b00000000,
+ 0b00011000,
+ 0b00100100,
+ 0b00101100,
+ 0b00110100,
+ 0b00100100,
+ 0b00011000,
+ 0b00000000, // 0
+
+ 0b00000000,
+ 0b00011000,
+ 0b00101000,
+ 0b00001000,
+ 0b00001000,
+ 0b00001000,
+ 0b00111100,
+ 0b00000000, // 1
+
+ 0b00000000,
+ 0b00011000,
+ 0b00100100,
+ 0b00000100,
+ 0b00001000,
+ 0b00010000,
+ 0b00111100,
+ 0b00000000, // 2
+
+ 0b00000000,
+ 0b00111000,
+ 0b00000100,
+ 0b00011000,
+ 0b00000100,
+ 0b00000100,
+ 0b00111000,
+ 0b00000000, // 3
+
+ 0b00000000,
+ 0b00100100,
+ 0b00100100,
+ 0b00111100,
+ 0b00000100,
+ 0b00000100,
+ 0b00000100,
+ 0b00000000, // 4
+
+ 0b00000000,
+ 0b00111100,
+ 0b00100000,
+ 0b00111000,
+ 0b00000100,
+ 0b00000100,
+ 0b00111000,
+ 0b00000000, // 5
+
+ 0b00000000,
+ 0b00011100,
+ 0b00100000,
+ 0b00111000,
+ 0b00100100,
+ 0b00100100,
+ 0b00011000,
+ 0b00000000, // 6
+
+ 0b00000000,
+ 0b00111100,
+ 0b00000100,
+ 0b00000100,
+ 0b00001000,
+ 0b00010000,
+ 0b00010000,
+ 0b00000000, // 7
+
+ 0b00000000,
+ 0b00011000,
+ 0b00100100,
+ 0b00011000,
+ 0b00100100,
+ 0b00100100,
+ 0b00011000,
+ 0b00000000, // 8
+
+ 0b00000000,
+ 0b00011000,
+ 0b00100100,
+ 0b00011100,
+ 0b00000100,
+ 0b00000100,
+ 0b00111000,
+ 0b00000000, // 9
+
+ 0b00000000,
+ 0b00011000,
+ 0b00100100,
+ 0b00111100,
+ 0b00100100,
+ 0b00100100,
+ 0b00100100,
+ 0b00000000, // A
+
+ 0b00000000,
+ 0b00111000,
+ 0b00100100,
+ 0b00111000,
+ 0b00100100,
+ 0b00100100,
+ 0b00111000,
+ 0b00000000, // B
+
+ 0b00000000,
+ 0b00011100,
+ 0b00100000,
+ 0b00100000,
+ 0b00100000,
+ 0b00100000,
+ 0b00011100,
+ 0b00000000, // C
+
+ 0b00000000,
+ 0b00110000,
+ 0b00101000,
+ 0b00100100,
+ 0b00100100,
+ 0b00101000,
+ 0b00110000,
+ 0b00000000, // C
+
+ 0b00000000,
+ 0b00111100,
+ 0b00100000,
+ 0b00111100,
+ 0b00100000,
+ 0b00100000,
+ 0b00111100,
+ 0b00000000, // E
+
+ 0b00000000,
+ 0b00111100,
+ 0b00100000,
+ 0b00111100,
+ 0b00100000,
+ 0b00100000,
+ 0b00100000,
+ 0b00000000, // F
+};
diff --git a/arm11/source/arm/vectors.s b/arm11/source/arm/vectors.s
index 6536ea0..3043516 100644
--- a/arm11/source/arm/vectors.s
+++ b/arm11/source/arm/vectors.s
@@ -16,31 +16,88 @@
* along with this program. If not, see .
*/
+/*
+ * This is almost the same as the ARM9 exception handler,
+ * but with a few extra register dumps (DFSR, IFSR and FAR)
+ */
+
#include
.arm
.align 3
+.macro TRAP_ENTRY xrq
+ msr cpsr_f, #(\xrq << 29)
+ b XRQ_Main
+.endm
+
.section .vector, "ax"
vectors:
- b XRQ_Reset @ RESET
- b XRQ_Reset @ UNDEFINED
- b XRQ_Reset @ SVC
- b XRQ_Reset @ PREFETCH ABORT
- b XRQ_Reset @ DATA ABORT
- b XRQ_Reset @ RESERVED
- b XRQ_IRQ @ IRQ
- b XRQ_Reset @ FIQ
+ b XRQ_Reset
+ b XRQ_Undefined
+ b XRQ_SVC
+ b XRQ_PrefetchAbt
+ b XRQ_DataAbt
+ b XRQ_Reserved
+ b XRQ_IRQ
+ b XRQ_FIQ
XRQ_Reset:
- mov r0, #0x18000000
- add r1, r0, #(6 << 20)
- mov r2, #0xFFFFFFFF
- 1:
- cmp r0, r1
- strne r2, [r0], #4
- moveq r0, #0x18000000
- b 1b
+ TRAP_ENTRY 0
+
+XRQ_Undefined:
+ TRAP_ENTRY 1
+
+XRQ_SVC:
+ TRAP_ENTRY 2
+
+XRQ_PrefetchAbt:
+ TRAP_ENTRY 3
+
+XRQ_DataAbt:
+ TRAP_ENTRY 4
+
+XRQ_Reserved:
+ TRAP_ENTRY 5
+
+XRQ_FIQ:
+ TRAP_ENTRY 7
+
+XRQ_Main:
+ ldr sp, =(exception_stack_top - 32*4)
+ stmia sp, {r0-r7}
+
+ cpsid aif
+
+ mrs r1, cpsr
+ lsr r0, r1, #29
+
+ mrs r2, spsr
+ str lr, [sp, #15*4]
+ str r2, [sp, #16*4]
+
+ ands r2, r2, #SR_PMODE_MASK
+ orreq r2, r2, #SR_SYS_MODE
+ orr r2, r2, #(0x10 | SR_NOINT)
+
+ add r3, sp, #8*4
+ msr cpsr_c, r2
+ nop
+ nop
+ stmia r3!, {r8-r14}
+ nop
+ nop
+ msr cpsr_c, r1
+
+ mrc p15, 0, r4, c5, c0, 0 @ data fault status register
+ mrc p15, 0, r5, c5, c0, 1 @ instruction fault status register
+ mrc p15, 0, r6, c6, c0, 0 @ data fault address
+ add r3, r3, #2*4 @ skip saved PC and CPSR
+ stmia r3!, {r4, r5, r6}
+
+ mov r1, sp
+ bl do_exception
+
XRQ_IRQ:
sub lr, lr, #4 @ Fix return address
@@ -58,3 +115,10 @@ XRQ_IRQ:
pop {r0-r4, r12, lr}
rfeia sp! @ Return from exception
+
+.section .bss.xrq_stk
+.align 12
+exception_stack: @ reserve a single aligned page for the exception stack
+ .space 4096
+exception_stack_top:
+.global exception_stack_top
diff --git a/arm11/source/boot.s b/arm11/source/boot.s
index 4cb35d2..9e7deef 100644
--- a/arm11/source/boot.s
+++ b/arm11/source/boot.s
@@ -21,7 +21,7 @@
#include
-#define STACK_SZ (16384)
+#define STACK_SZ (8192)
.global __boot
__boot:
@@ -95,9 +95,11 @@ corezero_start:
coresmp_start:
bl SYS_CoreInit
- b MainLoop
+ ldr lr, =MainLoop
+ bx lr
.section .bss.stack
-.align 3
+.align 12 @ make sure stack is aligned to a page boundary
+.global _stack_base
_stack_base:
.space (MAX_CPU * STACK_SZ)
diff --git a/arm11/source/hw/spi.c b/arm11/source/hw/spi.c
index 358f546..32560f7 100755
--- a/arm11/source/hw/spi.c
+++ b/arm11/source/hw/spi.c
@@ -122,8 +122,7 @@ int SPI_DoXfer(u32 dev, const SPI_XferInfo *xfers, u32 xfer_cnt)
void SPI_Init(void)
{
- // This cuts off access from the old SPI
- // interface used during the NDS days
+ // This cuts off access to the old NDS SPI interface
*REG_CFG_SPI_CNT = 7;
}
diff --git a/arm11/source/system/xalloc.c b/arm11/source/system/xalloc.c
index 3850ea8..02a7921 100755
--- a/arm11/source/system/xalloc.c
+++ b/arm11/source/system/xalloc.c
@@ -21,7 +21,7 @@
#include "system/xalloc.h"
-static char xalloc_buf[XALLOC_BUF_SIZE];
+static char ALIGN(4096) xalloc_buf[XALLOC_BUF_SIZE];
static size_t mark = 0;
void *XAlloc(size_t size)
diff --git a/arm9/source/system/i2c.c b/arm9/source/system/i2c.c
index d9a3586..6ee1fd4 100755
--- a/arm9/source/system/i2c.c
+++ b/arm9/source/system/i2c.c
@@ -15,6 +15,7 @@ static bool I2C_AllocBuffer(void)
return false;
i2c_xfer_buf = (char*)xbuf;
}
+
return true;
}
@@ -41,11 +42,12 @@ bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
{
int ret;
+ u32 *args;
if (!I2C_AllocBuffer())
return false;
- u32 args[] = {devId, regAddr, (u32)i2c_xfer_buf, size};
+ args = (u32[]){devId, regAddr, (u32)i2c_xfer_buf, size};
memcpy(i2c_xfer_buf, in, size);
ARM_WbDC_Range(i2c_xfer_buf, size);
diff --git a/arm9/source/system/spiflash.c b/arm9/source/system/spiflash.c
index 4dbb830..00bc1a8 100755
--- a/arm9/source/system/spiflash.c
+++ b/arm9/source/system/spiflash.c
@@ -4,7 +4,7 @@
#define SPIFLASH_CHUNK_SIZE (0x1000)
-static char *spiflash_xalloc_buf = NULL;
+static char *spiflash_xfer_buf = NULL;
bool spiflash_get_status(void)
{
@@ -15,29 +15,29 @@ bool spiflash_read(u32 offset, u32 size, u8 *buf)
{
u32 args[3];
- if (!spiflash_xalloc_buf) {
+ if (!spiflash_xfer_buf) {
u32 xbuf = PXI_DoCMD(PXI_XALLOC, (u32[]){SPIFLASH_CHUNK_SIZE}, 1);
if (xbuf == 0 || xbuf == 0xFFFFFFFF)
return false;
- spiflash_xalloc_buf = (char*)xbuf;
+ spiflash_xfer_buf = (char*)xbuf;
}
- args[1] = (u32)spiflash_xalloc_buf;
+ args[1] = (u32)spiflash_xfer_buf;
while(size > 0) {
- u32 rem = min(size, SPIFLASH_CHUNK_SIZE);
+ u32 blksz = min(size, SPIFLASH_CHUNK_SIZE);
args[0] = offset;
- args[2] = rem;
+ args[2] = blksz;
ARM_DSB();
PXI_DoCMD(PXI_NVRAM_READ, args, 3);
- ARM_InvDC_Range(spiflash_xalloc_buf, rem);
- memcpy(buf, spiflash_xalloc_buf, rem);
+ ARM_InvDC_Range(spiflash_xfer_buf, blksz);
+ memcpy(buf, spiflash_xfer_buf, blksz);
- buf += rem;
- size -= rem;
- offset += rem;
+ buf += blksz;
+ size -= blksz;
+ offset += blksz;
}
return true;
diff --git a/common/arm.h b/common/arm.h
index 28fc084..53843ed 100644
--- a/common/arm.h
+++ b/common/arm.h
@@ -10,7 +10,7 @@
#define SR_ABT_MODE (0x17)
#define SR_UND_MODE (0x1B)
#define SR_SYS_MODE (0x1F)
-#define SR_PMODE_MASK (0x1F)
+#define SR_PMODE_MASK (0x0F)
#define SR_THUMB BIT(5)
#define SR_NOFIQ BIT(6)
diff --git a/common/common.h b/common/common.h
index 5e81eeb..2fadb31 100755
--- a/common/common.h
+++ b/common/common.h
@@ -56,7 +56,11 @@
(sizeof(x) / sizeof(*(x)))
#define bkpt \
- asm volatile("bkpt\n\t")
+ __builtin_trap()
+
+#define assert(x) \
+ (!!(x) ? (void)0 : __builtin_trap())
+
#define STATIC_ASSERT(...) \
_Static_assert((__VA_ARGS__), #__VA_ARGS__)