mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-10-19 03:24:43 +00:00
438 lines
9.6 KiB
ArmAsm
438 lines
9.6 KiB
ArmAsm
; AUTO-GENERATED SYMBOL LIST
|
|
|
|
########################################################################
|
|
|
|
IllegalInstruction
|
|
mfmsr r9
|
|
_bset r8, r9, bitMsrDR
|
|
mtmsr r8
|
|
lwz r8, 0(r10)
|
|
mtmsr r9
|
|
|
|
stw r0, KDP.r0(r1)
|
|
stw r2, KDP.r2(r1)
|
|
stw r3, KDP.r3(r1)
|
|
stw r4, KDP.r4(r1)
|
|
stw r5, KDP.r5(r1)
|
|
lwz r9, CB.r7(r6)
|
|
stw r9, KDP.r7(r1)
|
|
lwz r9, CB.r8(r6)
|
|
stw r9, KDP.r8(r1)
|
|
lwz r9, CB.r9(r6)
|
|
stw r9, KDP.r9(r1)
|
|
lwz r9, CB.r10(r6)
|
|
stw r9, KDP.r10(r1)
|
|
lwz r9, CB.r11(r6)
|
|
stw r9, KDP.r11(r1)
|
|
lwz r9, CB.r12(r6)
|
|
stw r9, KDP.r12(r1)
|
|
lwz r9, CB.r13(r6)
|
|
stw r9, KDP.r13(r1)
|
|
stmw r14, KDP.r14(r1)
|
|
|
|
rlwinm r9, r8, 6, 15, 31
|
|
cmplwi r9, 0xB99F
|
|
beq @MFTB
|
|
|
|
rlwinm r9, r8, 17, 15, 20
|
|
insrwi r9, r8, 11, 21
|
|
cmplwi r9, 0xFFAE
|
|
beq @STFIWX
|
|
|
|
|
|
@FAIL
|
|
li r8, ecInvalidInstr
|
|
b Exception
|
|
|
|
|
|
@MFTB
|
|
extrwi r9, r8, 10, 11 ; r9 = tbr field
|
|
cmplwi cr7, r9, 0x188 ; TBL=268, mangled
|
|
cmplwi cr6, r9, 0x1A8 ; TBU=269, mangled
|
|
cror 15, cr6_eq, cr7_eq
|
|
bc BO_IF_NOT, 15, @FAIL
|
|
|
|
@retry_rtc
|
|
mfspr r20, rtcu
|
|
mfspr r21, rtcl
|
|
mfspr r23, rtcu
|
|
xor. r23, r23, r20
|
|
lis r23, 1000000000 >> 16
|
|
rlwinm r28, r8, 13, 25, 29 ; r28 = dest register number * 4
|
|
ori r23, r23, 1000000000 & 0xFFFF
|
|
bne @retry_rtc
|
|
|
|
mullw r8, r20, r23
|
|
mulhwu r20, r20, r23
|
|
mfxer r23
|
|
addc r21, r21, r8
|
|
addze r20, r20
|
|
mtxer r23
|
|
lwz r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
|
|
rlwimi r7, r7, 27, 26, 26
|
|
addi r23, r23, 1
|
|
stw r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
|
|
|
|
stwx r21, r1, r28 ; save register into EWA
|
|
mr r16, r7
|
|
beq cr7, loc_D50 ; TBL
|
|
stwx r20, r1, r28
|
|
b loc_D50 ; TBU
|
|
|
|
|
|
@STFIWX
|
|
lwz r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
|
|
mr r27, r8
|
|
addi r23, r23, 1
|
|
stw r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
|
|
mfmsr r14
|
|
_bset r15, r14, bitMsrDR
|
|
b loc_A38
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
KCallRunAlternateContext
|
|
; ARG ContextBlock *r3, flags r4
|
|
|
|
; We accept a logical NCB ptr but the kernel needs a physical one.
|
|
; So we keep a four-entry cache in KDP, mapping logical NCB ptrs
|
|
; to physical ones. Never seen multiple contexts used before though.
|
|
|
|
and. r8, r4, r13
|
|
lwz r9, KDP.NCBCacheLA0(r1)
|
|
rlwinm r8, r3, 0, 0, 25
|
|
cmpw cr1, r8, r9
|
|
bne IntReturn
|
|
lwz r9, KDP.NCBCachePA0(r1)
|
|
bne cr1, @search_cache
|
|
|
|
|
|
@found_physical_in_cache ; can come here from below after a more thorough search
|
|
|
|
addi r8, r1, KDP.VecTblAlternate ; the only use of this vector table?
|
|
mtsprg 3, r8
|
|
|
|
lwz r8, KDP.LA_EmuKCallTbl(r1)
|
|
mtcrf 0x3f, r7
|
|
clrlwi r7, r7, 8
|
|
stw r8, CB.ExceptionHandlerRetAddr(r9)
|
|
|
|
stw r9, KDP.CurCBPtr(r1)
|
|
|
|
b SwitchContext ; OldCB *r6, NewCB *r9
|
|
|
|
|
|
@search_cache
|
|
|
|
lwz r9, KDP.NCBCacheLA1(r1)
|
|
cmpw cr1, r8, r9
|
|
beq cr1, @found_in_slot_1
|
|
|
|
lwz r9, KDP.NCBCacheLA2(r1)
|
|
cmpw cr1, r8, r9
|
|
beq cr1, @found_in_slot_2
|
|
|
|
lwz r9, KDP.NCBCacheLA3(r1)
|
|
cmpw cr1, r8, r9
|
|
beq cr1, @found_in_slot_3
|
|
|
|
|
|
; No luck with the cache
|
|
|
|
stmw r14, KDP.r14(r1)
|
|
|
|
cmpw cr1, r8, r6
|
|
beq cr1, @fail
|
|
|
|
mr r27, r8
|
|
addi r29, r1, KDP.BATs + 0xa0
|
|
bl GetPhysicalAddr
|
|
clrlwi r23, r8, 20
|
|
beq @fail
|
|
|
|
cmplwi r23, 0x0d00
|
|
mr r9, r8
|
|
mr r8, r31
|
|
ble @not_straddling_pages
|
|
|
|
addi r27, r27, 0x1000
|
|
addi r29, r1, KDP.BATs + 0xa0
|
|
bl GetPhysicalAddr
|
|
beq @fail
|
|
|
|
subi r31, r31, 0x1000
|
|
xor r23, r8, r31
|
|
rlwinm. r23, r23, 0, 25, 22
|
|
bne @fail ; because physical pages are discontiguous
|
|
@not_straddling_pages
|
|
|
|
clrlwi r23, r31, 30
|
|
cmpwi r23, 3
|
|
rlwimi r8, r9, 0, 20, 31
|
|
beq @fail
|
|
|
|
|
|
; Found a non-cached physical address for this NCB!
|
|
|
|
lwz r23, KDP.NKInfo.NCBPtrCacheMissCount(r1)
|
|
addi r23, r23, 1
|
|
stw r23, KDP.NKInfo.NCBPtrCacheMissCount(r1)
|
|
|
|
|
|
; Stick it in cache slot 3
|
|
|
|
lmw r14, KDP.r14(r1)
|
|
stw r8, KDP.NCBCachePA3(r1)
|
|
|
|
|
|
@found_in_slot_3 ; so promote to slot 2
|
|
|
|
lwz r8, KDP.NCBCacheLA2(r1)
|
|
stw r9, KDP.NCBCacheLA2(r1)
|
|
stw r8, KDP.NCBCacheLA3(r1)
|
|
|
|
lwz r9, KDP.NCBCachePA3(r1)
|
|
lwz r8, KDP.NCBCachePA2(r1)
|
|
stw r9, KDP.NCBCachePA2(r1)
|
|
stw r8, KDP.NCBCachePA3(r1)
|
|
|
|
lwz r9, KDP.NCBCacheLA2(r1)
|
|
|
|
|
|
@found_in_slot_2 ; so promote to slot 1
|
|
|
|
lwz r8, KDP.NCBCacheLA1(r1)
|
|
stw r9, KDP.NCBCacheLA1(r1)
|
|
stw r8, KDP.NCBCacheLA2(r1)
|
|
|
|
lwz r9, KDP.NCBCachePA2(r1)
|
|
lwz r8, KDP.NCBCachePA1(r1)
|
|
stw r9, KDP.NCBCachePA1(r1)
|
|
stw r8, KDP.NCBCachePA2(r1)
|
|
|
|
lwz r9, KDP.NCBCacheLA1(r1)
|
|
|
|
|
|
@found_in_slot_1 ; so promote to slot 0, save elsewhere, and push on
|
|
|
|
lwz r8, KDP.NCBCacheLA0(r1)
|
|
stw r9, KDP.NCBCacheLA0(r1)
|
|
; stw r9, KDP.LA_NCB(r1)
|
|
stw r8, KDP.NCBCacheLA1(r1)
|
|
|
|
lwz r9, KDP.NCBCachePA1(r1)
|
|
lwz r8, KDP.NCBCachePA0(r1)
|
|
stw r9, KDP.NCBCachePA0(r1)
|
|
stw r8, KDP.NCBCachePA1(r1)
|
|
|
|
b @found_physical_in_cache
|
|
|
|
|
|
@fail
|
|
|
|
lmw r14, KDP.r14(r1)
|
|
li r8, ecTrapInstr
|
|
b Exception
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
KCallResetSystem
|
|
; PPC trap 1, or indirectly, 68k RESET
|
|
|
|
stmw r14, KDP.r14(r1)
|
|
|
|
xoris r8, r3, 'Ga'
|
|
cmplwi r8, 'ry'
|
|
bne Reset
|
|
xoris r8, r4, 0x0505
|
|
cmplwi r8, 0x1956
|
|
bne Reset
|
|
|
|
; Gary Davidian skeleton key: r5/D0 = MSR bits to unset, r7/D2 = MSR bits to set
|
|
andc r11, r11, r5
|
|
lwz r8, CB.r7(r6)
|
|
or r11, r11, r8
|
|
b IntReturn
|
|
|
|
Reset
|
|
include 'NKReset.s'
|
|
|
|
lmw r14, KDP.r14(r1)
|
|
b KCallPrioritizeInterrupts
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
KCallPrioritizeInterrupts
|
|
; Left side: roll back the interrupt preparation before the int handler repeats is
|
|
; Right side: jump to the external interrupt handler (PIH or IntProgram)
|
|
mtsprg 2, r12
|
|
mtsrr0 r10
|
|
mtsrr1 r11
|
|
mtcr r13
|
|
lwz r10, CB.r10(r6)
|
|
lwz r11, CB.r11(r6)
|
|
lwz r12, CB.r12(r6)
|
|
lwz r13, CB.r13(r6)
|
|
lwz r7, CB.r7(r6)
|
|
lwz r8, KDP.r1(r1)
|
|
mfsprg r9, 3
|
|
lwz r9, VecTbl.External(r9)
|
|
mtsprg 1, r8
|
|
mtlr r9
|
|
lwz r8, CB.r8(r6)
|
|
lwz r9, CB.r9(r6)
|
|
lwz r6, KDP.r6(r1)
|
|
blrl ; (could this ever fall though to KCallSystemCrash?)
|
|
|
|
########################################################################
|
|
|
|
KCallSystemCrash
|
|
stw r0, KDP.r0(r1)
|
|
stw r2, KDP.r2(r1)
|
|
stw r3, KDP.r3(r1)
|
|
stw r4, KDP.r4(r1)
|
|
stw r5, KDP.r5(r1)
|
|
|
|
lwz r8, CB.r7(r6)
|
|
lwz r9, CB.r8(r6)
|
|
stw r8, KDP.r7(r1)
|
|
stw r9, KDP.r8(r1)
|
|
|
|
lwz r8, CB.r9(r6)
|
|
lwz r9, CB.r10(r6)
|
|
stw r8, KDP.r9(r1)
|
|
stw r9, KDP.r10(r1)
|
|
|
|
lwz r8, CB.r11(r6)
|
|
lwz r9, CB.r12(r6)
|
|
stw r8, KDP.r11(r1)
|
|
stw r9, KDP.r12(r1)
|
|
|
|
lwz r8, CB.r13(r6)
|
|
stw r8, KDP.r13(r1)
|
|
|
|
stmw r14, KDP.r14(r1)
|
|
|
|
bl SystemCrash
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
IntProgram
|
|
; (also called when the Alternate Context gets an External Int => Exception)
|
|
|
|
; Standard interrupt palaver
|
|
mfsprg r1, 0
|
|
stw r6, KDP.r6(r1)
|
|
mfsprg r6, 1
|
|
stw r6, KDP.r1(r1)
|
|
lwz r6, KDP.CurCBPtr(r1)
|
|
stw r7, CB.r7(r6)
|
|
stw r8, CB.r8(r6)
|
|
stw r9, CB.r9(r6)
|
|
stw r10, CB.r10(r6)
|
|
stw r11, CB.r11(r6)
|
|
stw r12, CB.r12(r6)
|
|
stw r13, CB.r13(r6)
|
|
|
|
; Compare SRR0 with address of Emulator's KCall trap table
|
|
lwz r8, KDP.LA_EmuKCallTbl(r1)
|
|
mfsrr0 r10
|
|
mfcr r13
|
|
xor. r8, r10, r8
|
|
lwz r7, KDP.Flags(r1)
|
|
mfsprg r12, 2
|
|
beq KCallReturnFromExceptionFastPath ; KCall in Emulator table => fast path
|
|
rlwimi. r7, r7, bitFlagEmu, 0, 0
|
|
cmplwi cr7, r8, 16 * 4
|
|
bge cr0, @fromAltContext ; Alt Context cannot make KCalls; this might be an External Int
|
|
bge cr7, @notFromEmulatorTrapTable ; from Emulator but not from its KCall table => do more checks
|
|
|
|
; SUCCESSFUL TRAP from emulator KCall table
|
|
; => Service call then return to link register
|
|
add r8, r8, r1
|
|
lwz r11, KDP.NKInfo.NanoKernelCallCounts(r8)
|
|
lwz r10, KDP.KCallTbl(r8)
|
|
addi r11, r11, 1
|
|
stw r11, KDP.NKInfo.NanoKernelCallCounts(r8)
|
|
mtlr r10
|
|
mr r10, r12 ; ret addr: LR was saved to SPRG2, SPRG2 to r12 above, r12 to r10 now, r10 to SRR0 to program ctr later
|
|
mfsrr1 r11
|
|
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
|
|
blr
|
|
|
|
@notFromEmulatorTrapTable ; so check if it is even a trap...
|
|
mfsrr1 r11
|
|
mtcrf 0x70, r11
|
|
bc BO_IF_NOT, 14, @notTrap
|
|
|
|
mfmsr r9 ; fetch the instruction to get the "trap number"
|
|
_bset r8, r9, bitMsrDR
|
|
mtmsr r8
|
|
lwz r8, 0(r10)
|
|
mtmsr r9
|
|
xoris r8, r8, 0xfff
|
|
cmplwi cr7, r8, 16 ; only traps 0-15 are allowed
|
|
slwi r8, r8, 2 ; (for "success" case below)
|
|
bge cr7, @illegalTrap
|
|
|
|
; SUCCESSFUL TRAP from outside emulator KCall table
|
|
; => Service call then return to following instruction
|
|
add r8, r8, r1
|
|
lwz r10, KDP.NKInfo.NanoKernelCallCounts(r8)
|
|
addi r10, r10, 1
|
|
stw r10, KDP.NKInfo.NanoKernelCallCounts(r8)
|
|
lwz r8, KDP.KCallTbl(r8)
|
|
mtlr r8
|
|
addi r10, r10, 4 ; continue executing the next instruction
|
|
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
|
|
blr
|
|
|
|
; Cannot service with a KCall => throw Exception
|
|
@fromAltContext ; external interrupt, or a (forbidden) KCall attempt
|
|
mfsrr1 r11
|
|
mtcrf 0x70, r11
|
|
@notTrap ; then it was some other software exception
|
|
bc BO_IF, 12, IllegalInstruction
|
|
bc BO_IF, 11, @floatingPointException
|
|
@illegalTrap ; because we only allow traps 0-15
|
|
rlwinm r8, r11, 17, 28, 29
|
|
addi r8, r8, 0x4b3
|
|
rlwnm r8, r8, r8, 28, 31
|
|
b Exception ; CLEVER BIT HACKING described below
|
|
|
|
; SRR1[13] SRR[14] Exception
|
|
; 0 0 ecNoException
|
|
; 0 1 ecTrapInstr
|
|
; 1 0 ecPrivilegedInstr
|
|
; 1 1 9 (floating-point?)
|
|
|
|
@floatingPointException
|
|
li r8, ecFloatException
|
|
bc BO_IF, 15, Exception ; SRR1[15] set => handler can retry
|
|
addi r10, r10, 4
|
|
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
|
|
b Exception ; SRR1[15] unset => can't retry
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
IntSyscall
|
|
bl LoadInterruptRegisters
|
|
mfmsr r8
|
|
subi r10, r10, 4
|
|
rlwimi r11, r8, 0, 0xFFFF0000
|
|
li r8, ecSystemCall
|
|
b Exception
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
IntTrace
|
|
bl LoadInterruptRegisters
|
|
li r8, ecInstTrace
|
|
b Exception
|