230 lines
No EOL
6.1 KiB
ArmAsm
230 lines
No EOL
6.1 KiB
ArmAsm
#include "regnames.h"
|
|
|
|
|
|
|
|
.extern _decrementer_exception_fn
|
|
|
|
#define ISTATE_OFFSET_SP_FRAME 0x00
|
|
#define ISTATE_OFFSET_LR_FRAME 0x04
|
|
#define ISTATE_OFFSET_R0 0x08
|
|
#define ISTATE_OFFSET_R2 0x0c
|
|
#define ISTATE_OFFSET_R3 0x10
|
|
#define ISTATE_OFFSET_R4 0x14
|
|
#define ISTATE_OFFSET_R5 0x18
|
|
#define ISTATE_OFFSET_R6 0x1c
|
|
#define ISTATE_OFFSET_R7 0x20
|
|
#define ISTATE_OFFSET_R8 0x24
|
|
#define ISTATE_OFFSET_R9 0x28
|
|
#define ISTATE_OFFSET_R10 0x2c
|
|
#define ISTATE_OFFSET_R11 0x30
|
|
#define ISTATE_OFFSET_R13 0x34
|
|
#define ISTATE_OFFSET_R14 0x38
|
|
#define ISTATE_OFFSET_R15 0x3c
|
|
#define ISTATE_OFFSET_R16 0x40
|
|
#define ISTATE_OFFSET_R17 0x44
|
|
#define ISTATE_OFFSET_R18 0x48
|
|
#define ISTATE_OFFSET_R19 0x4c
|
|
#define ISTATE_OFFSET_R20 0x50
|
|
#define ISTATE_OFFSET_R21 0x54
|
|
#define ISTATE_OFFSET_R22 0x58
|
|
#define ISTATE_OFFSET_R23 0x5c
|
|
#define ISTATE_OFFSET_R24 0x60
|
|
#define ISTATE_OFFSET_R25 0x64
|
|
#define ISTATE_OFFSET_R26 0x68
|
|
#define ISTATE_OFFSET_R27 0x6c
|
|
#define ISTATE_OFFSET_R28 0x70
|
|
#define ISTATE_OFFSET_R29 0x74
|
|
#define ISTATE_OFFSET_R30 0x78
|
|
#define ISTATE_OFFSET_R31 0x7c
|
|
#define ISTATE_OFFSET_CR 0x80
|
|
#define ISTATE_OFFSET_PC 0x84
|
|
#define ISTATE_OFFSET_SRR1 0x88
|
|
#define ISTATE_OFFSET_LR 0x8c
|
|
#define ISTATE_OFFSET_CTR 0x90
|
|
#define ISTATE_OFFSET_XER 0x94
|
|
#define ISTATE_OFFSET_DAR 0x98
|
|
#define ISTATE_OFFSET_R12 0x9c
|
|
#define ISTATE_OFFSET_SP 0xa0
|
|
#define ISTATE_SIZE 0xa4
|
|
|
|
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
|
|
|
|
.section V_TEXT_GENESIS, "ax"
|
|
|
|
.macro CTX_SAVE
|
|
// honestly i'm going insane looking at powerpc assembly documentation
|
|
// so a lot of this will be based heavily on helenos's exception.S
|
|
// also their code is much nicer to look at than apple's hw_exception.s
|
|
// https://github.com/HelenOS/helenos/blob/master/kernel/arch/ppc32/src/exception.S
|
|
// i do not claim ownership of this
|
|
|
|
mtspr 1,r12
|
|
mfcr r12
|
|
mtspr 2,sp
|
|
|
|
subi sp, sp, ALIGN_UP(ISTATE_SIZE, 16)
|
|
stw r0, ISTATE_OFFSET_R0(sp)
|
|
stw r2, ISTATE_OFFSET_R2(sp)
|
|
stw r3, ISTATE_OFFSET_R3(sp)
|
|
stw r4, ISTATE_OFFSET_R4(sp)
|
|
stw r5, ISTATE_OFFSET_R5(sp)
|
|
stw r6, ISTATE_OFFSET_R6(sp)
|
|
stw r7, ISTATE_OFFSET_R7(sp)
|
|
stw r8, ISTATE_OFFSET_R8(sp)
|
|
stw r9, ISTATE_OFFSET_R9(sp)
|
|
stw r10, ISTATE_OFFSET_R10(sp)
|
|
stw r11, ISTATE_OFFSET_R11(sp)
|
|
stw r13, ISTATE_OFFSET_R13(sp)
|
|
stw r14, ISTATE_OFFSET_R14(sp)
|
|
stw r15, ISTATE_OFFSET_R15(sp)
|
|
stw r16, ISTATE_OFFSET_R16(sp)
|
|
stw r17, ISTATE_OFFSET_R17(sp)
|
|
stw r18, ISTATE_OFFSET_R18(sp)
|
|
stw r19, ISTATE_OFFSET_R19(sp)
|
|
stw r20, ISTATE_OFFSET_R20(sp)
|
|
stw r21, ISTATE_OFFSET_R21(sp)
|
|
stw r22, ISTATE_OFFSET_R22(sp)
|
|
stw r23, ISTATE_OFFSET_R23(sp)
|
|
stw r24, ISTATE_OFFSET_R24(sp)
|
|
stw r25, ISTATE_OFFSET_R25(sp)
|
|
stw r26, ISTATE_OFFSET_R26(sp)
|
|
stw r27, ISTATE_OFFSET_R27(sp)
|
|
stw r28, ISTATE_OFFSET_R28(sp)
|
|
stw r29, ISTATE_OFFSET_R29(sp)
|
|
stw r30, ISTATE_OFFSET_R30(sp)
|
|
stw r31, ISTATE_OFFSET_R31(sp)
|
|
|
|
stw r12, ISTATE_OFFSET_CR(sp)
|
|
|
|
mfsrr0 r12
|
|
stw r12, ISTATE_OFFSET_PC(sp)
|
|
|
|
mfsrr1 r12
|
|
stw r12, ISTATE_OFFSET_SRR1(sp)
|
|
|
|
mflr r12
|
|
stw r12, ISTATE_OFFSET_LR(sp)
|
|
|
|
mfctr r12
|
|
stw r12, ISTATE_OFFSET_CTR(sp)
|
|
|
|
mfxer r12
|
|
stw r12, ISTATE_OFFSET_XER(sp)
|
|
|
|
mfdar r12
|
|
stw r12, ISTATE_OFFSET_DAR(sp)
|
|
|
|
mfsprg1 r12
|
|
stw r12, ISTATE_OFFSET_R12(sp)
|
|
|
|
mfsprg2 r12
|
|
stw r12, ISTATE_OFFSET_SP(sp)
|
|
|
|
li r12, 0
|
|
stw r12, ISTATE_OFFSET_LR_FRAME(sp)
|
|
stw r12, ISTATE_OFFSET_SP_FRAME(sp)
|
|
.endm
|
|
|
|
// assumes that the stack pointer is already set to the correct value (it should be saved after using CTX_SAVE, and restored before using CTX_LOAD)
|
|
.macro CTX_LOAD
|
|
lwz r0, ISTATE_OFFSET_R0(sp)
|
|
lwz r2, ISTATE_OFFSET_R2(sp)
|
|
lwz r3, ISTATE_OFFSET_R3(sp)
|
|
lwz r4, ISTATE_OFFSET_R4(sp)
|
|
lwz r5, ISTATE_OFFSET_R5(sp)
|
|
lwz r6, ISTATE_OFFSET_R6(sp)
|
|
lwz r7, ISTATE_OFFSET_R7(sp)
|
|
lwz r8, ISTATE_OFFSET_R8(sp)
|
|
lwz r9, ISTATE_OFFSET_R9(sp)
|
|
lwz r10, ISTATE_OFFSET_R10(sp)
|
|
lwz r11, ISTATE_OFFSET_R11(sp)
|
|
lwz r13, ISTATE_OFFSET_R13(sp)
|
|
lwz r14, ISTATE_OFFSET_R14(sp)
|
|
lwz r15, ISTATE_OFFSET_R15(sp)
|
|
lwz r16, ISTATE_OFFSET_R16(sp)
|
|
lwz r17, ISTATE_OFFSET_R17(sp)
|
|
lwz r18, ISTATE_OFFSET_R18(sp)
|
|
lwz r19, ISTATE_OFFSET_R19(sp)
|
|
lwz r20, ISTATE_OFFSET_R20(sp)
|
|
lwz r21, ISTATE_OFFSET_R21(sp)
|
|
lwz r22, ISTATE_OFFSET_R22(sp)
|
|
lwz r23, ISTATE_OFFSET_R23(sp)
|
|
lwz r24, ISTATE_OFFSET_R24(sp)
|
|
lwz r25, ISTATE_OFFSET_R25(sp)
|
|
lwz r26, ISTATE_OFFSET_R26(sp)
|
|
lwz r27, ISTATE_OFFSET_R27(sp)
|
|
lwz r28, ISTATE_OFFSET_R28(sp)
|
|
lwz r29, ISTATE_OFFSET_R29(sp)
|
|
lwz r30, ISTATE_OFFSET_R30(sp)
|
|
lwz r31, ISTATE_OFFSET_R31(sp)
|
|
lwz r12, ISTATE_OFFSET_CR(sp)
|
|
|
|
li r12, 0
|
|
lwz r12, ISTATE_OFFSET_LR_FRAME(sp) // do we need to do this?
|
|
lwz r12, ISTATE_OFFSET_SP_FRAME(sp)
|
|
|
|
lwz r12, ISTATE_OFFSET_SP(sp)
|
|
mtsprg 2,r12
|
|
|
|
lwz r12, ISTATE_OFFSET_R12(sp)
|
|
mtsprg 1,r12
|
|
|
|
lwz r12, ISTATE_OFFSET_DAR(sp)
|
|
mtdar r12
|
|
|
|
lwz r12, ISTATE_OFFSET_XER(sp)
|
|
mtxer r12
|
|
|
|
lwz r12, ISTATE_OFFSET_CTR(sp)
|
|
mtctr r12
|
|
|
|
lwz r12, ISTATE_OFFSET_LR(sp)
|
|
mtlr r12
|
|
|
|
lwz r12, ISTATE_OFFSET_SRR1(sp)
|
|
mtsrr1 r12
|
|
|
|
lwz r12, ISTATE_OFFSET_PC(sp)
|
|
mtsrr0 r12
|
|
|
|
|
|
|
|
mfspr 2,sp
|
|
mtcr r12
|
|
mfspr 1,r12
|
|
.endm
|
|
|
|
#define ABSOLUTE(x) ((x) - 0x100)
|
|
|
|
// _decrementer_exception_wrapper
|
|
// called when the decrementer exception occurs (i.e. when it reaches 0)
|
|
.org ABSOLUTE(0x900)
|
|
.global _decrementer_exception_wrapper
|
|
_decrementer_exception_wrapper:
|
|
rfi
|
|
CTX_SAVE
|
|
|
|
// save the current stack pointer
|
|
mtspr 2,sp
|
|
|
|
// move the stack pointer to our stack (0x8000)
|
|
addis sp, sp, 0x8000@h
|
|
|
|
// load the address of the decrementer exception handler
|
|
lis r12, _decrementer_exception_fn@h
|
|
addi r12, r12, _decrementer_exception_fn@l
|
|
|
|
// call the decrementer exception handler
|
|
mtctr r12
|
|
bctrl
|
|
|
|
// restore the stack pointer
|
|
mfspr 2,sp
|
|
|
|
// restore the context
|
|
CTX_LOAD
|
|
|
|
// return
|
|
rfi
|
|
|
|
.org ABSOLUTE(0x8000) |