mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-11-29 12:49:58 +00:00
478 lines
9.2 KiB
ArmAsm
478 lines
9.2 KiB
ArmAsm
; sprg0 = old KDP/EWA/r1 ptr
|
|
; r3 = PA_NanoKernelCode
|
|
; r4 = physical base of our global area
|
|
; r5 = NoIdeaR23
|
|
; r6 = PA_EDP or zero?
|
|
; r7 = probably ROMHeader.ROMRelease ('rom vers', e.g. 0x10B5 is 1.0§5)
|
|
|
|
|
|
InitReplacement
|
|
|
|
crset cr5_eq
|
|
|
|
|
|
li r0, 0
|
|
|
|
|
|
|
|
; Position and initialise the kernel globals, IRP to KDP inclusive.
|
|
; (subset of builtin kernel)
|
|
|
|
; Zero from IRP (r4) to KDP (r4 + 10 pages)
|
|
|
|
lisori r12, kKDPfromIRP
|
|
mr r13, r4
|
|
@wipeloop
|
|
subic. r12, r12, 4
|
|
stwx r0, r13, r12
|
|
bgt @wipeloop
|
|
|
|
|
|
; Copy the old KDP to r4 + 10 pages.
|
|
; (r1 becomes our main ptr and r4 is discarded)
|
|
|
|
mfsprg r11, 0
|
|
lisori r1, kKDPfromIRP
|
|
add r1, r1, r4
|
|
|
|
li r12, 4096
|
|
@kdp_copyloop
|
|
subic. r12, r12, 4
|
|
lwzx r10, r11, r12
|
|
stwx r10, r1, r12
|
|
bgt @kdp_copyloop
|
|
|
|
|
|
; IRP goes at the base of the area we were given.
|
|
; Fill with repeating pattern and point EWA at it.
|
|
|
|
lisori r12, -kKDPfromIRP
|
|
add r12, r12, r1
|
|
stw r12, EWA.PA_IRP(r1)
|
|
bl InitIRP ; clobbers r10 and r12
|
|
|
|
|
|
|
|
; Play with some of the other values we were given
|
|
|
|
; Leave ROMRelease in r23.
|
|
|
|
mr r23, r7
|
|
|
|
; If no EDP (Emulator Data Page) pointer was provided,
|
|
; then put the EDP above our new KDP.
|
|
|
|
cmpwi r6, 0
|
|
stw r11, KDP.OldKDP(r1)
|
|
stw r9, 0x05a4(r1)
|
|
|
|
|
|
; discarded
|
|
|
|
bne @emulatordata_ptr_provided
|
|
addi r6, r1, 0x1000
|
|
@emulatordata_ptr_provided
|
|
|
|
|
|
|
|
; Save a few bits
|
|
|
|
stw r6, 0x05a8(r1)
|
|
stw r3, KDP.PA_NanoKernelCode(r1)
|
|
stw r5, PSA.NoIdeaR23(r1)
|
|
stw r1, EWA.PA_KDP(r1)
|
|
|
|
addi r12, r1, -0x340 ; get the base of the main CPU struct
|
|
li r10, -1
|
|
stw r10, CPU.ID(r12)
|
|
|
|
lwz r3, KDP.PA_ConfigInfo(r1)
|
|
|
|
bl LookupInterruptHandler
|
|
stw r7, KDP.PA_InterruptHandler(r1)
|
|
|
|
|
|
|
|
; Clearly changed our mind about where we might be.
|
|
|
|
bl @x
|
|
@x mflr r12
|
|
subi r12, r12, @x - NKTop
|
|
|
|
stw r12, KDP.PA_NanoKernelCode(r1)
|
|
|
|
|
|
; FDP
|
|
|
|
llabel r10, FDP
|
|
add r12, r10, r12
|
|
stw r12, KDP.PA_FDP(r1)
|
|
|
|
|
|
; Do something terrible with the CPU features
|
|
|
|
lwz r12, EWA.Flags(r1)
|
|
li r10, 0x00
|
|
rlwimi r10, r12, 0, 12, 15
|
|
rlwimi r10, r12, 0, 28, 30
|
|
stw r10, -0x0968(r1)
|
|
|
|
|
|
; Cook up a MSR:
|
|
; MSR_EE = 1
|
|
; MSR_PR = 1
|
|
; MSR_FP = 0
|
|
; MSR_ME = 0
|
|
; MSR_FE0 = 0
|
|
; MSR_SE = 0
|
|
; MSR_BE = 0
|
|
; MSR_FE1 = 0
|
|
; MSR_IP = preserved
|
|
; MSR_IR = 1
|
|
; MSR_DR = 1
|
|
; MSR_RI = 0
|
|
; MSR_LE = 0
|
|
|
|
mfmsr r12
|
|
andi. r12, r12, 0x0040
|
|
ori r12, r12, 0xd032
|
|
stw r12, PSA.UserModeMSR(r1)
|
|
|
|
|
|
|
|
; Set SPRG0 (for this CPU at least)
|
|
|
|
mtsprg 0, r1
|
|
|
|
|
|
; r11 still contains the OLD EWA ptr (which is also KDP/PSA ptr?)
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r11)
|
|
cmpwi r12, 0x0101
|
|
|
|
bgt @replaces_later_than_0101
|
|
|
|
;
|
|
lwz r12, KDP.PA_ECB_Old(r1)
|
|
stw r12, EWA.PA_ContextBlock(r1)
|
|
|
|
lwz r12, 0x660(r1)
|
|
oris r12, r12, 0x20
|
|
stw r12, EWA.Flags(r1)
|
|
|
|
lwz r12, 0x0664(r1)
|
|
stw r12, EWA.Enables(r1) ; boy, better figure out what this is
|
|
|
|
b @endif
|
|
@replaces_later_than_0101
|
|
|
|
; Obviously cannot replace a v2 NanoKernel like myself
|
|
cmpwi r12, 0x0200
|
|
bge CancelReplacement
|
|
|
|
lwz r12, EWA.PA_ContextBlock(r11)
|
|
stw r12, EWA.PA_ContextBlock(r1)
|
|
|
|
lwz r12, EWA.Flags(r11)
|
|
oris r12, r12, 0x20
|
|
stw r12, EWA.Flags(r1)
|
|
|
|
lwz r12, -0x000c(r11)
|
|
stw r12, EWA.Enables(r1)
|
|
|
|
@endif
|
|
|
|
|
|
|
|
lwz r12, 0x0340(r11)
|
|
lwz r10, KDP.LA_NCB(r11)
|
|
cmpw r12, r10
|
|
|
|
beq replace_old_kernel_0x198
|
|
stw r12, KDP.LA_NCB(r1)
|
|
stw r0, 0x06b4(r1)
|
|
lwz r10, 0x05b0(r11)
|
|
stw r10, 0x06c0(r1)
|
|
lwz r10, KDP.LA_NCB(r11)
|
|
stw r10, 0x06c4(r1)
|
|
lwz r10, 0x05b8(r11)
|
|
stw r10, 0x06c8(r1)
|
|
lwz r10, 0x05bc(r11)
|
|
stw r10, 0x06cc(r1)
|
|
stw r0, 0x06d0(r1)
|
|
stw r0, 0x06d4(r1)
|
|
stw r0, 0x06d8(r1)
|
|
stw r0, 0x06dc(r1)
|
|
stw r0, 0x06e0(r1)
|
|
stw r0, 0x06e4(r1)
|
|
stw r0, 0x06e8(r1)
|
|
stw r0, 0x06ec(r1)
|
|
stw r0, 0x06f0(r1)
|
|
stw r0, 0x06f4(r1)
|
|
stw r0, 0x06f8(r1)
|
|
stw r0, 0x06fc(r1)
|
|
replace_old_kernel_0x198
|
|
|
|
|
|
|
|
; Adjust a few KDP pointers to point into the new KDP
|
|
|
|
lwz r12, KDP.PA_PageMapStart(r1)
|
|
subf r12, r11, r12
|
|
add r12, r12, r1
|
|
stw r12, KDP.PA_PageMapStart(r1)
|
|
|
|
lwz r12, KDP.PA_PageMapEnd(r1)
|
|
subf r12, r11, r12
|
|
add r12, r12, r1
|
|
stw r12, KDP.PA_PageMapEnd(r1)
|
|
|
|
lwz r12, 0x05e8(r1)
|
|
subf r12, r11, r12
|
|
add r12, r12, r1
|
|
stw r12, 0x05e8(r1)
|
|
|
|
|
|
|
|
; Wipe KDP's NKInfo and ProcessorInfo
|
|
|
|
li r12, 0x200
|
|
addi r10, r1, KDP.NanoKernelInfo
|
|
|
|
@wipeloop
|
|
subic. r12, r12, 4
|
|
stwx r0, r10, r12
|
|
bgt @wipeloop
|
|
|
|
|
|
|
|
|
|
; r9 = physical base of kernel
|
|
li r12, 0
|
|
addi r10, r1, KDP.InfoRecord
|
|
|
|
bl MoveRecord ; (NanoKernelCode, NewKDPInfoRecord, OldKDP, 0)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.InfoRecordPtr(r1)
|
|
stw r0, KDP.InfoRecord + InfoRecord.Zero(r1)
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKProcessorStateLen(r1)
|
|
addi r10, r1, PSA.ProcessorState
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1)
|
|
|
|
bl MoveRecord ; (OldProcessorState, NewPSAProcessorState, OldKDP, ProcessorStateLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1)
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKHWInfoLen(r1)
|
|
lwz r10, EWA.PA_IRP(r1)
|
|
addi r10, r10, IRP.HWInfo
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1)
|
|
|
|
bl MoveRecord ; (OldHWInfo, NewIRPHWInfo, OldKDP, HWInfoLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1)
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1)
|
|
addi r10, r1, KDP.ProcessorInfo
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1)
|
|
|
|
bl MoveRecord ; (OldProcessorInfo, NewKDPProcessorInfo, OldKDP, ProcessorInfoLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1)
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr2(r1)
|
|
|
|
|
|
|
|
lhz r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1)
|
|
cmplwi r10, 0x0112
|
|
bge @ProcessorInfo_version_already_current
|
|
|
|
li r12, 160
|
|
li r10, 0x0112
|
|
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1)
|
|
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen2(r1)
|
|
sth r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1)
|
|
sth r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer2(r1)
|
|
@ProcessorInfo_version_already_current
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKDiagInfoLen(r1)
|
|
addi r10, r1, PSA.DiagInfo
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1)
|
|
|
|
bl MoveRecord ; (OldDiagInfo, NewPSADiagInfo, OldKDP, DiagInfoLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1)
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKSystemInfoLen(r1)
|
|
lwz r10, EWA.PA_IRP(r1)
|
|
addi r10, r10, IRP.SystemInfo
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1)
|
|
|
|
bl MoveRecord ; (OldSystemInfo, NewIRPSystemInfo, OldKDP, SystemInfoLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1)
|
|
|
|
|
|
|
|
lhz r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1)
|
|
addi r10, r1, KDP.NanoKernelInfo
|
|
lwz r9, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1)
|
|
|
|
bl MoveRecord ; (OldNanoKernelInfo, NewKDPNanoKernelInfo, OldKDP, NanoKernelInfoLen)
|
|
|
|
stw r10, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1)
|
|
|
|
|
|
|
|
li r12, 0x160
|
|
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1)
|
|
|
|
|
|
li r12, kNanoKernelVersion
|
|
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r1)
|
|
|
|
|
|
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.DecClockRateHz(r1)
|
|
stw r8, PSA.DecClockRateHzCopy(r1)
|
|
|
|
|
|
|
|
; Play with ConfigFlags
|
|
|
|
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
|
|
|
|
_bset r8, r8, 31 ; always set bit 31
|
|
|
|
if &TYPE('NKShowLog') != 'UNDEFINED'
|
|
_bset r8, r8, 28 ; see if someone can test this
|
|
endif
|
|
|
|
cmplwi r23, 0x27f3 ; set bit 27 on ROM 2.7f3 or later
|
|
blt @oldrom ; means later than PDM and Cordyceps
|
|
_bset r8, r8, 27
|
|
@oldrom
|
|
|
|
stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
|
|
|
|
|
|
|
|
; Say hello.
|
|
|
|
bl InitScreenConsole
|
|
|
|
_log 'Hello from the replacement multitasking NanoKernel. Version: '
|
|
|
|
mr r8, r12
|
|
bl printh
|
|
|
|
|
|
_log '^n Old KDP: '
|
|
|
|
mr r8, r11
|
|
bl printw
|
|
|
|
|
|
_log ' new KDP: '
|
|
|
|
mr r8, r1
|
|
bl printw
|
|
|
|
|
|
_log ' new irp: '
|
|
|
|
lwz r8, EWA.PA_IRP(r1)
|
|
mr r8, r8
|
|
bl printw
|
|
|
|
|
|
_log 'ROM vers: '
|
|
|
|
mr r8, r23
|
|
bl printh
|
|
|
|
_log '^n'
|
|
|
|
|
|
|
|
; Jump back into the common code path of Init.s
|
|
|
|
; The Emulator ContextBlock is expected in r6.
|
|
lwz r6, KDP.PA_ECB(r1)
|
|
|
|
b InitHighLevel
|
|
|
|
|
|
|
|
; MoveRecord
|
|
|
|
; r9 = base of kernel???
|
|
|
|
; Seems to be code to relocate some old structures.
|
|
|
|
MoveRecord ; OUTSIDE REFERER
|
|
|
|
; Check whether the old structure is in KDP
|
|
;
|
|
lwz r22, KDP.PA_ConfigInfo(r1)
|
|
lwz r22, NKConfigurationInfo.LA_InfoRecord(r22)
|
|
|
|
subf r9, r22, r9 ; r9 = offset of old address in irp
|
|
cmplwi r9, 0x1000
|
|
bge @kdp
|
|
|
|
add r21, r9, r11 ; r21 = the old address if it had been in KDP instead?
|
|
|
|
|
|
@0x18
|
|
|
|
; r9 = offset of old structure in old parent page
|
|
; r10 = destination
|
|
; r12 = length
|
|
|
|
|
|
;
|
|
@loop
|
|
subic. r12, r12, 4
|
|
blt @exit_loop
|
|
lwzx r9, r21, r12
|
|
stwx r9, r10, r12
|
|
bgt @loop
|
|
@exit_loop
|
|
|
|
lwz r22, KDP.PA_ConfigInfo(r1)
|
|
lwz r22, NKConfigurationInfo.LA_KernelData(r22)
|
|
|
|
subf r10, r1, r10
|
|
lisori r21, -9 * 4096
|
|
cmpw r10, r21 ; if dest is nearer than 9 pages below kdp...
|
|
blt @0x50
|
|
add r10, r10, r22
|
|
blr
|
|
@0x50
|
|
|
|
lwz r22, KDP.PA_ConfigInfo(r1)
|
|
lwz r22, NKConfigurationInfo.LA_InfoRecord(r22)
|
|
lwz r21, EWA.PA_IRP(r1)
|
|
add r10, r10, r1
|
|
subf r10, r21, r10
|
|
add r10, r10, r22
|
|
blr
|
|
|
|
@kdp
|
|
add r9, r9, r22
|
|
lwz r22, KDP.PA_ConfigInfo(r1)
|
|
lwz r22, NKConfigurationInfo.LA_KernelData(r22)
|
|
subf r9, r22, r9 ; r9 now equals an offset from old_kdp
|
|
add r21, r9, r11 ; r21 = address in new_kdp
|
|
b @0x18
|