Do the same for arm9 exceptions

This commit is contained in:
TuxSH
2018-05-22 20:26:14 +02:00
parent 55bd62d7a9
commit c0bd69309a
15 changed files with 99 additions and 105 deletions

View File

@@ -0,0 +1,91 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
*
* 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 <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "arm9_exception_handlers.h"
#include "i2c.h"
#include "screen.h"
#define FINAL_BUFFER 0x25000000
#define REG_DUMP_SIZE 4 * 17
#define CODE_DUMP_SIZE 48
void __attribute__((noreturn)) arm9ExceptionHandlerMain(u32 *registerDump, u32 type)
{
ExceptionDumpHeader dumpHeader;
u8 codeDump[CODE_DUMP_SIZE];
dumpHeader.magic[0] = 0xDEADC0DE;
dumpHeader.magic[1] = 0xDEADCAFE;
dumpHeader.versionMajor = 1;
dumpHeader.versionMinor = 2;
dumpHeader.processor = 9;
dumpHeader.core = 0;
dumpHeader.type = type;
dumpHeader.registerDumpSize = REG_DUMP_SIZE;
dumpHeader.codeDumpSize = CODE_DUMP_SIZE;
dumpHeader.additionalDataSize = 0;
u32 cpsr = registerDump[16];
u32 pc = registerDump[15] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
registerDump[15] = pc;
//Dump code
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //wouldn't work well on 32-bit Thumb instructions, but it isn't much of a problem
dumpHeader.codeDumpSize = ((u32)instr & (((cpsr & 0x20) != 0) ? 1 : 3)) != 0 ? 0 : safecpy(codeDump, instr, dumpHeader.codeDumpSize);
//Copy register dump and code dump
u8 *final = (u8 *)(FINAL_BUFFER + sizeof(ExceptionDumpHeader));
final += safecpy(final, registerDump, dumpHeader.registerDumpSize);
final += safecpy(final, codeDump, dumpHeader.codeDumpSize);
//Dump stack in place
dumpHeader.stackDumpSize = safecpy(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF));
dumpHeader.totalSize = sizeof(ExceptionDumpHeader) + dumpHeader.registerDumpSize + dumpHeader.codeDumpSize + dumpHeader.stackDumpSize + dumpHeader.additionalDataSize;
//Copy header (actually optimized by the compiler)
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
<<<<<<< HEAD:exceptions/arm9/source/mainHandler.c
if(ARESCREENSINITIALIZED) I2C_writeReg(I2C_DEV_MCU, 0x22, 1 << 0); //Shutdown LCD
((void (*)())0xFFFF0830)(); //Ensure that all memory transfers have completed and that the data cache has been flushed
I2C_writeReg(I2C_DEV_MCU, 0x20, 1 << 2); //Reboot
=======
if(ARESCREENSINITIALIZED) i2cWriteRegisterNoWait(I2C_DEV_MCU, 0x22, 1 << 0); //Shutdown LCD
((void (*)())0xFFFF0830)(); //Ensure that all memory transfers have completed and that the data cache has been flushed
i2cWriteRegisterNoWait(I2C_DEV_MCU, 0x20, 1 << 2); //Reboot
>>>>>>> Do the same for arm9 exceptions:source/arm9_exception_handlers.c
while(true);
}

View File

@@ -0,0 +1,48 @@
/*
* This file is part of Luma3DS
* Copyright (C) 2016-2019 Aurora Wright, TuxSH
*
* 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 <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "types.h"
extern const u32 arm9ExceptionHandlerAddressTable[6];
extern u32 arm9ExceptionHandlerSvcBreakAddress;
<<<<<<< HEAD:exceptions/arm9/source/types.h
//Common data types
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
#define PDN_GPU_CNT (*(vu32 *)0x10141200)
#define ARESCREENSINITIALIZED ((PDN_GPU_CNT & 0xFF) != 1)
=======
u32 safecpy(void *dst, const void *src, u32 len);
>>>>>>> Do the same for arm9 exceptions:source/arm9_exception_handlers.h

View File

@@ -0,0 +1,168 @@
@ This file is part of Luma3DS
@ Copyright (C) 2016-2019 Aurora Wright, TuxSH
@
@ 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 <http://www.gnu.org/licenses/>.
@
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
@ * Requiring preservation of specified reasonable legal notices or
@ author attributions in that material or in the Appropriate Legal
@ Notices displayed by works containing it.
@ * Prohibiting misrepresentation of the origin of that material,
@ or requiring that modified versions of such material be marked in
@ reasonable ways as different from the original version.
.macro GEN_USUAL_HANDLER name, index
\name\()Handler:
ldr sp, =_regs
stmia sp, {r0-r7}
mov r0, #\index
b _arm9ExceptionHandlerCommon
.endm
.section .arm9_exception_handlers.text, "ax", %progbits
.arm
.align 4
.global _arm9ExceptionHandlerCommon
.type _arm9ExceptionHandlerCommon, %function
_arm9ExceptionHandlerCommon:
mov r1, r0
mov r0, sp
mrs r2, spsr
mrs r3, cpsr
add r6, r0, #(8 * 4)
orr r3, #0xc0 @ mask interrupts
msr cpsr_cx, r3
ands r4, r2, #0xf @ get the mode that triggered the exception
moveq r4, #0xf @ usr => sys
bic r5, r3, #0xf
orr r5, r4
msr cpsr_c, r5 @ change processor mode
stmia r6!, {r8-lr}
msr cpsr_c, r3 @ restore processor mode
str lr, [r6], #4
str r2, [r6]
msr cpsr_cxsf, #0xdf @ finally, switch to system mode, mask interrupts and clear flags (in case of double faults)
ldr sp, =0x02000000
b arm9ExceptionHandlerMain
.global FIQHandler
.type FIQHandler, %function
GEN_USUAL_HANDLER FIQ, 0
.global undefinedInstructionHandler
.type undefinedInstructionHandler, %function
GEN_USUAL_HANDLER undefinedInstruction, 1
.global prefetchAbortHandler
.type prefetchAbortHandler, %function
prefetchAbortHandler:
msr cpsr_cx, #0xd7 @ mask interrupts (abort mode)
mrs sp, spsr
and sp, #0x3f
cmp sp, #0x13
bne _prefetchAbortNormalHandler
ldr sp, =arm9ExceptionHandlerSvcBreakAddress
ldr sp, [sp]
cmp sp, #0
beq _prefetchAbortNormalHandler
add sp, #(1*4 + 4)
cmp lr, sp
bne _prefetchAbortNormalHandler
mov sp, r8
pop {r8-r11}
ldr lr, [sp, #8]!
ldr sp, [sp, #4]
msr spsr_cxsf, sp
tst sp, #0x20
addne lr, #2 @ adjust address for later
GEN_USUAL_HANDLER _prefetchAbortNormal, 2
.global dataAbortHandler
.type dataAbortHandler, %function
dataAbortHandler:
msr cpsr_cx, #0xd7 @ mask interrupts (abort mode)
mrs sp, spsr
and sp, #0x3f
cmp sp, #0x1f
bne _dataAbortNormalHandler
sub lr, #8
adr sp, safecpy
cmp lr, sp
blo _j_dataAbortNormalHandler
adr sp, _safecpy_end
cmp lr, sp
bhs _j_dataAbortNormalHandler
msr spsr_f, #(1 << 30)
mov r12, #0
adds pc, lr, #4
_j_dataAbortNormalHandler:
add lr, #8
GEN_USUAL_HANDLER _dataAbortNormal, 3
.global safecpy
.type safecpy, %function
safecpy:
push {r4, lr}
mov r3, #0
movs r12, #1
_safecpy_loop:
ldrb r4, [r1, r3]
cmp r12, #0
beq _safecpy_loop_end
strb r4, [r0, r3]
add r3, #1
cmp r3, r2
blo _safecpy_loop
_safecpy_loop_end:
mov r0, r3
pop {r4, pc}
_safecpy_end:
.section .arm9_exception_handlers.rodata, "a", %progbits
.align 4
.global arm9ExceptionHandlerAddressTable
arm9ExceptionHandlerAddressTable:
.word 0 @ IRQ
.word FIQHandler @ FIQ
.word 0 @ SVC
.word undefinedInstructionHandler @ Undefined instruction
.word prefetchAbortHandler @ Prefetch abort
.word dataAbortHandler @ Data abort
.section .arm9_exception_handlers.bss, "w", %nobits
.align 4
.global arm9ExceptionHandlerSvcBreakAddress
arm9ExceptionHandlerSvcBreakAddress:
.word 0
_regs: .skip (4 * 17)

View File

@@ -33,24 +33,20 @@
#include "utils.h"
#include "fmt.h"
#include "buttons.h"
#include "../build/bundled.h"
#include "arm9_exception_handlers.h"
void installArm9Handlers(void)
{
memcpy((void *)0x01FF8000, arm9_exceptions_bin, arm9_exceptions_bin_size);
vu32 *dstVeneers = (vu32 *)0x08000000;
/* IRQHandler is at 0x08000000, but we won't handle it for some reasons
svcHandler is at 0x08000010, but we won't handle svc either */
static const u32 offsets[] = {0x08, 0x18, 0x20, 0x28};
for(u32 i = 0; i < 4; i++)
for(u32 i = 0; i < 6; i++)
{
*(vu32 *)(0x08000000 + offsets[i]) = 0xE51FF004;
*(vu32 *)(0x08000000 + offsets[i] + 4) = *(vu32 *)(0x01FF8008 + 4 * i);
if(arm9ExceptionHandlerAddressTable[i] != 0)
{
dstVeneers[2 * i] = 0xE51FF004;
dstVeneers[2 * i + 1] = arm9ExceptionHandlerAddressTable[i];
}
}
*(vu32 *)0x01FF8004 = 0; //BreakPtr
}
void detectAndProcessExceptionDumps(void)

View File

@@ -180,7 +180,11 @@ bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
return true;
}
<<<<<<< HEAD
bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
=======
bool i2cWriteRegisterNoWait(u8 dev_id, u8 reg, u8 data)
>>>>>>> Do the same for arm9 exceptions
{
const u8 busId = i2cDevTable[devId].busId;
I2cRegs *const regs = i2cGetBusRegsBase(busId);
@@ -200,6 +204,7 @@ bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
}
}
<<<<<<< HEAD
regs->REG_I2C_DATA = *in;
regs->REG_I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE | I2C_STOP;
i2cWaitBusy(regs);
@@ -218,6 +223,15 @@ u8 I2C_readReg(I2cDevice devId, u8 regAddr)
if(!I2C_readRegBuf(devId, regAddr, &data, 1)) return 0xFF;
return data;
}
=======
return ret;
}
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data)
{
bool ret = i2cWriteRegisterNoWait(dev_id, reg, data);
wait(3ULL);
>>>>>>> Do the same for arm9 exceptions
bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data)
{

View File

@@ -90,6 +90,7 @@ bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size);
*/
u8 I2C_readReg(I2cDevice devId, u8 regAddr);
<<<<<<< HEAD
/**
* @brief Writes a byte to a I2C register.
*
@@ -100,3 +101,8 @@ u8 I2C_readReg(I2cDevice devId, u8 regAddr);
* @return Returns true on success and false on failure.
*/
bool I2C_writeReg(I2cDevice devId, u8 regAddr, u8 data);
=======
u8 i2cReadRegister(u8 dev_id, u8 reg);
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
bool i2cWriteRegisterNoWait(u8 dev_id, u8 reg, u8 data);
>>>>>>> Do the same for arm9 exceptions

View File

@@ -39,6 +39,7 @@
#include "memory.h"
#include "config.h"
#include "utils.h"
#include "arm9_exception_handlers.h"
#include "../build/bundled.h"
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
@@ -501,7 +502,7 @@ u32 patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address)
addr[0] = 0xE1A0800D;
addr[1] = 0xE12FFF7F;
*(vu32 *)0x01FF8004 = arm9SvcTable[0x3C]; //BreakPtr
arm9ExceptionHandlerSvcBreakAddress = arm9SvcTable[0x3C]; //BreakPtr
return 0;
}

View File

@@ -134,6 +134,7 @@ _start:
mov r1, r10
mov r2, r11
b main
.pool
.section .chainloader.text.start, "ax", %progbits
.align 4
@@ -142,6 +143,7 @@ _start:
chainload:
ldr sp, =__itcm_stack_top__
b chainloader_main
.pool
.global disableMpuAndJumpToEntrypoints
.type disableMpuAndJumpToEntrypoints, %function
@@ -173,3 +175,5 @@ disableMpuAndJumpToEntrypoints:
mov r1, r5
ldr r2, =0x3BEEF
bx r6
.pool