- properly align ARM11 stacks and buffers

- add very simple exception dumping for the ARM11
This commit is contained in:
Wolfvak 2019-09-25 19:35:01 -03:00 committed by d0k3
parent 3e25393284
commit fd5320b86f
11 changed files with 327 additions and 39 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <types.h>
#include <arm.h>
#include <vram.h>
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
};

View File

@ -16,31 +16,88 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This is almost the same as the ARM9 exception handler,
* but with a few extra register dumps (DFSR, IFSR and FAR)
*/
#include <arm.h>
.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

View File

@ -21,7 +21,7 @@
#include <arm.h>
#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)

View File

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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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__)