mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2025-02-22 10:29:02 +00:00
Namely queues, semaphores, critical regions, event groups and "notifications". The MP calls implementing these services have been named after their MPLibrary wrapper functions. This convention will be followed in the future (no more NKCreateEvent).
480 lines
9.2 KiB
ArmAsm
480 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, 0x05b4(r11)
|
|
cmpw r12, r10
|
|
|
|
beq- replace_old_kernel_0x198
|
|
stw r12, 0x05b4(r1)
|
|
stw r0, 0x06b4(r1)
|
|
lwz r10, 0x05b0(r11)
|
|
stw r10, 0x06c0(r1)
|
|
lwz r10, 0x05b4(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
|
|
|
|
; Xrefs:
|
|
; replace_old_kernel
|
|
; 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
|