mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-11-18 13:12:45 +00:00
476 lines
12 KiB
ArmAsm
476 lines
12 KiB
ArmAsm
; AUTO-GENERATED SYMBOL LIST
|
|
|
|
########################################################################
|
|
|
|
ExceptionAfterRetry
|
|
mtsprg 3, r24
|
|
|
|
lwz r9, KDP.Enables(r1)
|
|
rlwinm r23, r17, (32-1), 27, 31
|
|
rlwnm. r9, r9, r8, 0, 0 ; BGE taken if exception disabled
|
|
|
|
bcl BO_IF, bitFlag15, major_0x02980_0x100
|
|
|
|
lwz r6, KDP.CurCBPtr(r1)
|
|
|
|
_bset r7, r16, 27
|
|
|
|
neg r23, r23
|
|
mtcrf 0x3f, r7
|
|
add r19, r19, r23
|
|
|
|
insrwi r7, r8, 8, 0 ; ec code -> high byte of flags
|
|
|
|
slwi r8, r8, 2 ; increment counter
|
|
add r8, r8, r1
|
|
lwz r9, KDP.NKInfo.ExceptionCauseCounts(r8)
|
|
addi r9, r9, 1
|
|
stw r9, KDP.NKInfo.ExceptionCauseCounts(r8)
|
|
|
|
; Move regs from KDP to ContextBlock
|
|
lwz r8, KDP.r7(r1)
|
|
stw r8, CB.r7(r6)
|
|
lwz r8, KDP.r8(r1)
|
|
stw r8, CB.r8(r6)
|
|
lwz r8, KDP.r9(r1)
|
|
stw r8, CB.r9(r6)
|
|
lwz r8, KDP.r10(r1)
|
|
stw r8, CB.r10(r6)
|
|
lwz r8, KDP.r11(r1)
|
|
stw r8, CB.r11(r6)
|
|
lwz r8, KDP.r12(r1)
|
|
stw r8, CB.r12(r6)
|
|
lwz r8, KDP.r13(r1)
|
|
stw r8, CB.r13(r6)
|
|
|
|
bge RunSystemContext ; Alt Context has left exception disabled => Sys Context
|
|
;fall through ; exception enabled => run userspace handler
|
|
|
|
########################################################################
|
|
|
|
RunExceptionHandler
|
|
stw r10, CB.ExceptionOriginAddr(r6) ; Save r10/SRR0, r12/LR, r3, r4
|
|
stw r12, CB.ExceptionOriginLR(r6)
|
|
stw r3, CB.ExceptionOriginR3(r6)
|
|
stw r4, CB.ExceptionOriginR4(r6)
|
|
|
|
lwz r8, KDP.Enables(r1) ; Save Enables & Flags
|
|
stw r7, CB.ExceptionOriginFlags(r6)
|
|
stw r8, CB.ExceptionOriginEnables(r6)
|
|
|
|
; Set up the Exception Handler context
|
|
li r8, 0 ; r8/Enables = 0 (handler must not throw exception)
|
|
lwz r10, CB.ExceptionHandler(r6) ; r10/SRR0 = handler addr
|
|
lwz r4, CB.ExceptionHandlerR4(r6) ; r4 = arbitrary second argument
|
|
lwz r3, KDP.ECBPtrLogical(r1) ; r3 = ContextBlock ptr
|
|
bc BO_IF, bitFlagEmu, @sys
|
|
lwz r3, KDP.NCBCacheLA0(r1)
|
|
@sys
|
|
lwz r12, KDP.EmuKCallTblPtrLogical(r1) ; r12/LR = address of KCallReturnFromException trap
|
|
|
|
bcl BO_IF, bitFlagLowSaves, PreferRegistersFromKDPSavingContextBlock ; ???
|
|
|
|
rlwinm r7, r7, 0, 29, 15 ; unset flags 16-28
|
|
stw r8, KDP.Enables(r1)
|
|
rlwimi r11, r7, 0, 20, 23 ; threfore unset MSR[FE0/SE/BE/FE1]
|
|
|
|
b IntReturn
|
|
|
|
########################################################################
|
|
|
|
major_0x02980_0x100
|
|
lwz r0, KDP.r0(r1)
|
|
lwz r2, KDP.r2(r1)
|
|
lwz r3, KDP.r3(r1)
|
|
lwz r4, KDP.r4(r1)
|
|
lwz r5, KDP.r5(r1)
|
|
blr
|
|
|
|
PreferRegistersFromKDPSavingContextBlock
|
|
stw r17, CB.PropagateR17(r6)
|
|
stw r20, CB.PropagateR20(r6)
|
|
stw r21, CB.PropagateR21(r6)
|
|
stw r19, CB.PropagateR19(r6)
|
|
stw r18, CB.PropagateR18(r6)
|
|
lmw r14, KDP.r14(r1)
|
|
blr
|
|
|
|
########################################################################
|
|
|
|
_alignToCacheBlock
|
|
KCallReturnFromExceptionFastPath
|
|
lwz r11, KDP.NKInfo.NanoKernelCallCounts(r1)
|
|
mr r10, r12
|
|
addi r11, r11, 1
|
|
stw r11, KDP.NKInfo.NanoKernelCallCounts(r1)
|
|
mfsrr1 r11
|
|
rlwimi r7, r7, 27, 26, 26 ; ?re-enable single stepping
|
|
|
|
KCallReturnFromException
|
|
cmplwi cr1, r3, 1 ; exception handler return value
|
|
blt cr1, @dispose
|
|
mtcrf 0x3f, r7
|
|
beq cr1, @propagate
|
|
|
|
;force to system context ; Handler returned >= 1
|
|
subi r8, r3, 32
|
|
lwz r9, KDP.NKInfo.ExceptionForcedCount(r1)
|
|
cmplwi r8, 256-32
|
|
addi r9, r9, 1
|
|
stw r9, KDP.NKInfo.ExceptionForcedCount(r1)
|
|
insrwi r7, r3, 8, 0
|
|
blt RunSystemContext ; Handler returned 1-255: force that exception number to System
|
|
li r8, ecTrapInstr
|
|
b Exception ; Handler returned >= 256: fail!
|
|
|
|
@dispose ; Handler returned 0: return to the code that threw the exception
|
|
lwz r8, CB.ExceptionOriginFlags(r6)
|
|
lwz r10, CB.ExceptionOriginAddr(r6)
|
|
rlwimi r7, r8, 0, 0xFF00FFFF ; restore most Flags to pre-exception state
|
|
lwz r8, CB.ExceptionOriginEnables(r6)
|
|
rlwimi r11, r7, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] <- Flags
|
|
stw r8, KDP.Enables(r1)
|
|
|
|
andi. r8, r11, MsrFE0 + MsrFE1 ; check: are floating-pt exceptions enabled?
|
|
|
|
lwz r12, CB.ExceptionOriginLR(r6) ; restore LR/r3/r4
|
|
lwz r3, CB.ExceptionOriginR3(r6)
|
|
lwz r4, CB.ExceptionOriginR4(r6)
|
|
|
|
bnel EnableFPU ; if FP exceptions are enabled, make sure the FPU is enabled
|
|
|
|
addi r9, r6, CB.ExceptionOriginFlags ; never gets used... points to exception part of ContextBlock?
|
|
|
|
b IntReturn
|
|
|
|
@propagate ; Handler returned 1: propagate exception
|
|
lwz r9, KDP.NKInfo.ExceptionPropagateCount(r1)
|
|
lwz r8, CB.ExceptionOriginFlags(r6)
|
|
addi r9, r9, 1
|
|
stw r9, KDP.NKInfo.ExceptionPropagateCount(r1)
|
|
lwz r10, CB.ExceptionOriginAddr(r6)
|
|
rlwimi r7, r8, 0, 0xFF00FFFF ; restore most Flags to pre-exception state
|
|
lwz r8, CB.ExceptionOriginEnables(r6)
|
|
mtcrf 0x0f, r7
|
|
rlwimi r11, r7, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] <- Flags
|
|
stw r8, KDP.Enables(r1)
|
|
|
|
lwz r12, CB.ExceptionOriginLR(r6) ; restore LR/r3/r4
|
|
lwz r3, CB.ExceptionOriginR3(r6)
|
|
lwz r4, CB.ExceptionOriginR4(r6)
|
|
|
|
bc BO_IF_NOT, bitFlagLowSaves, RunSystemContext
|
|
stmw r14, KDP.r14(r1)
|
|
lwz r17, CB.PropagateR17(r6)
|
|
lwz r20, CB.PropagateR20(r6)
|
|
lwz r21, CB.PropagateR21(r6)
|
|
lwz r19, CB.PropagateR19(r6)
|
|
lwz r18, CB.PropagateR18(r6)
|
|
b RunSystemContext
|
|
|
|
########################################################################
|
|
|
|
; BEFORE
|
|
; PowerPC exception vector saved r1/LR in SPRG1/2 and
|
|
; jumped where directed by the VecTbl pointed to by
|
|
; SPRG3. That function bl'ed here.
|
|
;
|
|
; AFTER
|
|
; Reg Contains Original saved in
|
|
; ---------------------------------------------
|
|
; r0 (itself)
|
|
; r1 KDP SPRG1
|
|
; r2 (itself)
|
|
; r3 (itself)
|
|
; r4 (itself)
|
|
; r5 (itself)
|
|
; r6 ContextBlock EWA
|
|
; r7 Flags ContextBlock
|
|
; r8 KDP ContextBlock
|
|
; r9 (scratch CB ptr) ContextBlock
|
|
; r10 SRR0 ContextBlock
|
|
; r11 SRR1 ContextBlock
|
|
; r12 LR ContextBlock
|
|
; r13 CR ContextBlock
|
|
|
|
LoadInterruptRegisters
|
|
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)
|
|
mfsrr0 r10
|
|
mfcr r13
|
|
lwz r7, KDP.Flags(r1)
|
|
mfsprg r12, 2
|
|
mfsrr1 r11
|
|
blr
|
|
|
|
########################################################################
|
|
|
|
Exception
|
|
lwz r9, KDP.Enables(r1)
|
|
mtcrf 0x3f, r7
|
|
|
|
rlwnm. r9, r9, r8, 0, 0 ; BLT taken if exception enabled
|
|
|
|
insrwi r7, r8, 8, 0 ; Exception code to hi byte of Flags
|
|
|
|
slwi r8, r8, 2 ; Increment counter, easy enough
|
|
add r8, r8, r1
|
|
lwz r9, KDP.NKInfo.ExceptionCauseCounts(r8)
|
|
addi r9, r9, 1
|
|
stw r9, KDP.NKInfo.ExceptionCauseCounts(r8)
|
|
|
|
blt RunExceptionHandler ; exception enabled => run userspace handler
|
|
;fall through ; Alt Context has left exception disabled => Sys Context
|
|
|
|
########################################################################
|
|
|
|
RunSystemContext
|
|
lwz r9, KDP.ECBPtr(r1) ; System ("Emulator") ContextBlock
|
|
|
|
addi r8, r1, KDP.VecTblSystem ; System VecTbl
|
|
mtsprg 3, r8
|
|
|
|
bcl BO_IF, bitFlagEmu, SystemCrash ; System Context already running!
|
|
|
|
; Fallthru (new CB in r9, old CB in r6)
|
|
|
|
########################################################################
|
|
|
|
SwitchContext ; OldCB *r6, NewCB *r9
|
|
; Run the System or Alternate Context
|
|
lwz r8, KDP.Enables(r1)
|
|
stw r7, CB.Flags(r6)
|
|
stw r8, CB.Enables(r6)
|
|
|
|
bc BO_IF_NOT, bitFlagLowSaves, @not_low_saves
|
|
stw r17, CB.LowSave17(r6)
|
|
stw r20, CB.LowSave20(r6)
|
|
stw r21, CB.LowSave21(r6)
|
|
stw r19, CB.LowSave19(r6)
|
|
stw r18, CB.LowSave18(r6)
|
|
lmw r14, KDP.r14(r1)
|
|
@not_low_saves
|
|
|
|
mfxer r8
|
|
stw r13, CB.CR(r6)
|
|
stw r8, CB.XER(r6)
|
|
stw r12, CB.LR(r6)
|
|
mfctr r8
|
|
stw r10, CB.SRR0(r6)
|
|
stw r8, CB.CTR(r6)
|
|
|
|
bc BO_IF_NOT, bitFlagHasMQ, @no_mq
|
|
lwz r8, CB.MQ(r9)
|
|
mfspr r12, mq
|
|
mtspr mq, r8
|
|
stw r12, CB.MQ(r6)
|
|
@no_mq
|
|
|
|
lwz r8, KDP.r1(r1)
|
|
stw r0, CB.r0(r6)
|
|
stw r8, 0x010c(r6)
|
|
stw r2, 0x0114(r6)
|
|
stw r3, 0x011c(r6)
|
|
stw r4, 0x0124(r6)
|
|
lwz r8, 0x0018(r1)
|
|
stw r5, 0x012c(r6)
|
|
stw r8, 0x0134(r6)
|
|
_band. r8, r11, bitMsrFP
|
|
stw r14, 0x0174(r6)
|
|
stw r15, 0x017c(r6)
|
|
stw r16, 0x0184(r6)
|
|
stw r17, 0x018c(r6)
|
|
stw r18, 0x0194(r6)
|
|
stw r19, 0x019c(r6)
|
|
stw r20, 0x01a4(r6)
|
|
stw r21, 0x01ac(r6)
|
|
stw r22, 0x01b4(r6)
|
|
stw r23, 0x01bc(r6)
|
|
stw r24, 0x01c4(r6)
|
|
stw r25, 0x01cc(r6)
|
|
stw r26, 0x01d4(r6)
|
|
stw r27, 0x01dc(r6)
|
|
stw r28, 0x01e4(r6)
|
|
stw r29, 0x01ec(r6)
|
|
stw r30, 0x01f4(r6)
|
|
stw r31, 0x01fc(r6)
|
|
bnel DisableFPU
|
|
|
|
lwz r8, KDP.OtherContextDEC(r1)
|
|
mfdec r31
|
|
cmpwi r8, 0
|
|
stw r31, KDP.OtherContextDEC(r1)
|
|
mtdec r8
|
|
blel ResetDEC ; to r8
|
|
|
|
lwz r8, CB.Flags(r9) ; r8 is the new Flags variable
|
|
stw r9, KDP.CurCBPtr(r1)
|
|
xoris r7, r7, 1 << (15 - bitFlagEmu) ; flip Emulator flag
|
|
rlwimi r11, r8, 0, 20, 23 ; "enact" MSR[FE0/SE/BE/FE1]
|
|
mr r6, r9 ; change the magic ContextBlock register
|
|
rlwimi r7, r8, 0, 0x0000FFFF ; change bottom half of flags only
|
|
|
|
andi. r8, r11, MsrFE0 + MsrFE1 ; FP exceptions enabled in new context?
|
|
|
|
lwz r8, CB.Enables(r6)
|
|
lwz r13, CB.CR(r6)
|
|
stw r8, KDP.Enables(r1)
|
|
lwz r8, CB.XER(r6)
|
|
lwz r12, CB.LR(r6)
|
|
mtxer r8
|
|
lwz r8, CB.CTR(r6)
|
|
lwz r10, CB.SRR0(r6)
|
|
mtctr r8
|
|
|
|
bnel ReloadFPU ; FP exceptions enabled, so load FPU
|
|
|
|
stwcx. r0, 0, r1
|
|
|
|
lwz r8, CB.r1(r6)
|
|
lwz r0, CB.r0(r6)
|
|
stw r8, KDP.r1(r1)
|
|
lwz r2, 0x0114(r6)
|
|
lwz r3, 0x011c(r6)
|
|
lwz r4, 0x0124(r6)
|
|
lwz r8, 0x0134(r6)
|
|
lwz r5, 0x012c(r6)
|
|
stw r8, 0x0018(r1)
|
|
lwz r14, 0x0174(r6)
|
|
lwz r15, 0x017c(r6)
|
|
lwz r16, 0x0184(r6)
|
|
lwz r17, 0x018c(r6)
|
|
lwz r18, 0x0194(r6)
|
|
lwz r19, 0x019c(r6)
|
|
lwz r20, 0x01a4(r6)
|
|
lwz r21, 0x01ac(r6)
|
|
lwz r22, 0x01b4(r6)
|
|
lwz r23, 0x01bc(r6)
|
|
lwz r24, 0x01c4(r6)
|
|
lwz r25, 0x01cc(r6)
|
|
lwz r26, 0x01d4(r6)
|
|
lwz r27, 0x01dc(r6)
|
|
lwz r28, 0x01e4(r6)
|
|
lwz r29, 0x01ec(r6)
|
|
lwz r30, 0x01f4(r6)
|
|
lwz r31, 0x01fc(r6)
|
|
|
|
########################################################################
|
|
|
|
IntReturn
|
|
andi. r8, r7, FlagTrace | FlagLowSaves
|
|
bnel @do_trace
|
|
|
|
stw r7, KDP.Flags(r1) ; Save kernel flags for next interrupt
|
|
mtlr r12 ; Restore user SPRs from kernel GPRs
|
|
mtsrr0 r10
|
|
mtsrr1 r11
|
|
mtcr r13
|
|
lwz r10, CB.r10(r6) ; Restore user GPRs from ContextBlock
|
|
lwz r11, CB.r11(r6)
|
|
lwz r12, CB.r12(r6)
|
|
lwz r13, CB.r13(r6)
|
|
lwz r7, CB.r7(r6)
|
|
lwz r8, CB.r8(r6)
|
|
lwz r9, CB.r9(r6)
|
|
lwz r6, KDP.r6(r1) ; Restore last two registers from EWA
|
|
lwz r1, KDP.r1(r1)
|
|
|
|
rfi ; Return from interrupt
|
|
|
|
|
|
@do_trace
|
|
mtcrf 0x3f, r7
|
|
|
|
bc BO_IF_NOT, bitFlagLowSaves, @no_low_saves
|
|
|
|
_bclr r7, r7, bitFlagLowSaves ; LowSaves set with flag 31 -> unset and do some emulation
|
|
bc BO_IF, bitFlag31, @last_minute_memretry
|
|
|
|
_bclr r7, r7, bitFlagTrace ; But if flag 31 is unset, disable tracing and go home
|
|
b @return
|
|
|
|
@no_low_saves
|
|
bc BO_IF_NOT, bitFlagTrace, @return
|
|
|
|
_bclr r7, r7, bitFlagTrace ; Trace flag set with no LowSaves -> unset that flag, and do Trace Exception
|
|
stw r7, KDP.Flags(r1)
|
|
li r8, ecInstTrace
|
|
b Exception
|
|
|
|
@return
|
|
blr
|
|
|
|
@last_minute_memretry
|
|
stw r7, KDP.Flags(r1)
|
|
stw r0, 0x0000(r1)
|
|
stw r2, 0x0008(r1)
|
|
stw r3, 0x000c(r1)
|
|
stw r4, 0x0010(r1)
|
|
stw r5, 0x0014(r1)
|
|
lwz r8, 0x013c(r6)
|
|
stw r8, 0x001c(r1)
|
|
lwz r8, 0x0144(r6)
|
|
stw r8, 0x0020(r1)
|
|
lwz r8, 0x014c(r6)
|
|
stw r8, 0x0024(r1)
|
|
lwz r8, 0x0154(r6)
|
|
stw r8, 0x0028(r1)
|
|
lwz r8, 0x015c(r6)
|
|
stw r8, 0x002c(r1)
|
|
lwz r8, 0x0164(r6)
|
|
stw r8, 0x0030(r1)
|
|
lwz r8, 0x016c(r6)
|
|
stw r8, 0x0034(r1)
|
|
|
|
stmw r14, KDP.r14(r1)
|
|
|
|
lwz r17, CB.LowSave17(r9) ; LowSave means "MemRetry in ContextBlock"
|
|
lwz r20, CB.LowSave20(r9)
|
|
lwz r21, CB.LowSave21(r9)
|
|
lwz r19, CB.LowSave19(r9)
|
|
lwz r18, CB.LowSave18(r9)
|
|
_bclr r16, r7, bitFlagLowSaves
|
|
|
|
lwz r25, KDP.MRBase(r1) ; MRUnknown is indexed by the first arg of MROptab?
|
|
extrwi. r22, r17, 4, 27 ;
|
|
add r19, r19, r22 ; Correct r19 (EA) by adding byteCount from r17
|
|
rlwimi r25, r17, 7, 25, 30 ; The top of MRUnknown is... mysterious!
|
|
lhz r26, MRUnknown-MRBase(r25) ; leaving this incorrect as a reminder!
|
|
|
|
insrwi r25, r19, 3, 28 ; Set Memtab alignment modulus
|
|
stw r16, KDP.Flags(r1)
|
|
rlwimi r26, r26, 8, 8, 15 ; First byte of MRUnknown is for cr3/cr4
|
|
insrwi r25, r17, 4, 24 ; byteCount and load/store from second arg of MROptab?
|
|
mtcrf 0x10, r26 ; Set CR3
|
|
lha r22, MRMemtab-MRBase(r25) ; Jump to MRMemtab...
|
|
|
|
addi r23, r1, KDP.VecTblMemRetry
|
|
add r22, r22, r25
|
|
mfsprg r24, 3
|
|
mtlr r22
|
|
mtsprg 3, r23
|
|
mfmsr r14
|
|
_bset r15, r14, bitMsrDR
|
|
mtmsr r15
|
|
rlwimi r25, r26, 2, 22, 29 ; Second byte of MRUnknown is
|
|
bnelr
|
|
b MRDoSecondary
|
|
|
|
########################################################################
|
|
|
|
ResetDEC ; to r8
|
|
lis r31, 0x7FFF
|
|
mtdec r31
|
|
mtdec r8
|
|
blr
|