powermac-rom/NanoKernel/NKBuiltinInit.s

1380 lines
28 KiB
ArmAsm

; When we receive control:
; r3 = ConfigInfo
; r4 = ProcessorInfo
; r5 = SystemInfo
; r6 = DiagInfo
; r7 = RTAS_flag ('RTAS' or 0)
; r8 = RTAS_proc
; r9 = HWInfo
InitBuiltin
; Leave zero in r0 (it is rather a silly place).
li r0, 0
; Initialize segment registers (understand these better!)
isync
lis r12, 0x2000
mtsr 0, r12
mtsr 1, r0
mtsr 2, r0
mtsr 3, r0
mtsr 4, r0
mtsr 5, r0
mtsr 6, r0
mtsr 7, r0
mtsr 8, r0
mtsr 9, r0
mtsr 10, r0
mtsr 11, r0
mtsr 12, r0
mtsr 13, r0
mtsr 14, r0
mtsr 15, r0
isync
; Zero out the timebase (rtc on 601) and upper BAT registers
; (this is best practice for invalidating BATs)
; (Interestingly, SheepShaver also uses r12 for this PVR access.)
mfspr r12, pvr
rlwinm. r12, r12, 0, 0, 14
bne- @not601
mtspr rtcl, r0
mtspr rtcu, r0
mtspr ibat0l, r0
mtspr ibat1l, r0
mtspr ibat2l, r0
mtspr ibat3l, r0
b @endif601
@not601
mtspr tbl, r0
mtspr tbu, r0
mtspr ibat0u, r0
mtspr ibat1u, r0
mtspr ibat2u, r0
mtspr ibat3u, r0
mtspr dbat0u, r0
mtspr dbat1u, r0
mtspr dbat2u, r0
mtspr dbat3u, r0
@endif601
; The Trampoline instructs us to put the base of the blue area at
; this physical address, which seems always to be the base of the
; first RAM bank reported by the trampoline. (The kernel is also
; expected to initialise MacOS LowMemory from a key/valye list.)
lwz r12, NKConfigurationInfo.PA_RelocatedLowMemInit(r3)
; Search SysInfo for the first nonzero size RAM bank.
addi r10, r5, NKSystemInfo.Bank0Start - 4
@rambank_loop
lwzu r11, 8(r10) ; Bank0Size, Bank1Size...
cmpwi r11, 0
beq+ @rambank_loop
; r10 points to BankXSize, r11 contains BankXSize
; DeltaMemory = PA_RelocatedLowMemInit if fits in bank, else 0.
subf r11, r12, r11
srawi r11, r11, 31 ; f... if PA_ > BankSize else 0...
andc r12, r12, r11 ; zero DeltaMemory if PA_ > BankSize
; BankSize -= DeltaMemory
lwz r11, 0(r10)
subf r11, r12, r11
stw r11, 0(r10)
; BankStart += DeltaMemory
lwz r11, -4(r10)
add r11, r11, r12
stw r11, -4(r10)
; PhysicalMemorySize -= DeltaMemory (+ another page if there is close to 2GB)
lwz r11, NKSystemInfo.PhysicalMemorySize(r5)
addis r15, r11, 1
cmpwi r15, 0
bgt- @skip_reducing_ram
addi r11, r11, -4096
@skip_reducing_ram
subf r11, r12, r11
stw r11, 0(r5)
; Load PhysicalMemorySize - 1 into r15.
;
; Create the HTABMASK for eventual insertion in lo half of SDR1:
; - Is number of bits used from hash func to index PTEGs in HTAB.
; - Arch allows 10..19 bits.
; - Bits 0-9 assumed by architecture.
; - Bits 10-18 in the low field of SDR1.
; - Bits 19-31 also in low field, but must be zeroed.
; - Our r14 "mask" = (future low half of SDR1) || 0xffff.
; - Therefore has an extra six ones.
; - Therefore equals HTAB size - 1.
; - Computed from PhysicalMemorySize as follows:
;
; ---------------------------------------------------------------------
; Phys RAM r14 HTABMASK bits PTEGs in HTAB HTAB size
; (MB) (10-19 allowed)
; ---------------------------------------------------------------------
; <= 8 0000ffff 10 1k 64k
; <= 16 0001ffff 11 2k 128k
; <= 32 0003ffff 12 4k 256k
; <= 64 0007ffff 13 8k 512k
; <= 128 000fffff 14 16k 1024k
; <= 256 001fffff 15 32k 2048k
; > 256 003fffff 16 64k 4096k
lwz r15, NKSystemInfo.PhysicalMemorySize(r5)
addi r15, r15, -1
cntlzw r12, r15
lis r14, 0x01ff
srw r14, r14, r12
ori r14, r14, 0xffff
clrlwi r14, r14, 10
; Based on PhysicalMemorySize, guess how much memory the
; kernel needs, including the HTAB. Leave it in r15.
;
; -----------------------------
; Phys RAM r15 Kern
; (MB) pages
; -----------------------------
; >= 4 0001d000 29
; >= 8 0001e000 30
; >= 16 00030000 48
; >= 32 00054000 84
; >= 64 0009c000 156
; >= 128 0012c000 300
; >= 256 0024c000 588
; >= 512 0048c000 1164
; >=1024 0050c000 1292
; >=2048 0060c000 1548
addis r15, r15, 0x40
rlwinm r15, r15, 22, 10, 19
add r15, r15, r14
lisori r10, 0x0000c001
add r15, r15, r10
; Search SysInfo backwards for a RAM bank that can fit:
; - A HTAB aligned to a multiple of its own length
; - An r15-size area immediately below that
;
; Kernel structures (HTAB at top) will butt up against
; BankEnd % HTABSIZE. Leave bottom in r13 and top in r12.
addi r10, r5, NKSystemInfo.EndOfBanks
@try_another_bank
lwz r11, -4(r10) ; size
lwzu r12, -8(r10) ; start
add r11, r12, r11 ; end
andc r13, r11, r14 ; end % HTABSIZE
subf r13, r15, r13 ; end % HTABSIZE - r15
cmplw r13, r12
blt+ @try_another_bank
cmplw r13, r11
bgt+ @try_another_bank
add r12, r13, r15
; Populate SDR1 with HTABORG || HTABMASK:
; - HTABORG = top_of_bank % HTABSIZE (only top half)
; - HTABMASK = top half of r14 (which equals HTABSIZE-1)
;
; Leave SDR1 in r12 and HTABORG (a full address) in r11.
subf r12, r14, r12
rlwimi r12, r14, 16, 16, 31
mtspr sdr1, r12
rlwinm r11, r12, 0, 0, 15
; Recap: (matches SheepShaver notes on NKv1)
; r11 HTABORG
; r12 SDR1
; r13 base of "reserved" kernel area
; r14 HTABSIZE - 1
; r15 size of "reserved" kernel area
; Place the kernel data page (KDP) 8k below the HTAB,
; and point SPRG0 at it. r1 almost always points to KDP.
;
; Page above KDP becomes emulator data page (EDP).
; Page below KDP becomes private v2 kernel globals.
lisori r1, -0x2000
add r1, r1, r11
mtsprg 0, r1
; Init the reserved area to zero, up to the HTAB.
;
; But if the machine has Thudded and dumped all its registers
; (as evidenced by a saved SDR1) then don't zero that dump.
lwz r11, KDP.ThudSavedSDR1(r1)
cmpw r12, r11
lis r11, 0x7fff
bne- @did_not_panic
subf r11, r13, r1
addi r11, r11, KDP.StartOfPanicArea
@did_not_panic
subf r12, r14, r15
addi r12, r12, -0x01
@eraseloop
addic. r12, r12, -4
subf r10, r11, r12
cmplwi cr7, r10, KDP.EndOfPanicArea - KDP.StartOfPanicArea - 4
ble- cr7, @skipwrite
stwx r0, r13, r12
@skipwrite
bne+ @eraseloop
; Put r1 pointer (for indexing PSA/KDP) in CPU-0 EWA
stw r1, EWA.PA_KDP(r1)
; Set up the interrupt response page (IRP) at KDP - (10 pages).
;
; (Point CPU-0 EWA to it and fill it with 0x68f168f1.)
lisori r12, IRPOffset
add r12, r12, r1
stw r12, EWA.PA_IRP(r1)
bl InitIRP
; Set up runtime abstraction services (RTAS).
;
; Kernel argument r7 is either 'RTAS' or zero. If 'RTAS':
; - Arg r8 points to RTAS dispatch proc.
; - Arg r9 points to HWInfo points to RTAS private data
; - Copy HWInfo into IRP
;
; TODO: neaten, use records!
lisori r12, 'RTAS'
cmpw r7, r12
bne- @RTAS_absent
stw r8, KDP.RTAS_Proc(r1)
lwz r7, NKHWInfo.RTAS_PrivDataArea(r9)
stw r7, KDP.RTAS_PrivDataArea(r1)
lwz r11, EWA.PA_IRP(r1)
addi r11, r11, IRP.HWInfo
li r10, 0xc0
@RTAS_copyloop
addic. r10, r10, -4
lwzx r12, r9, r10
stwx r12, r11, r10
bgt+ @RTAS_copyloop
stw r23, PSA.NoIdeaR23(r1)
b @RTAS_done
@RTAS_absent
stw r0, KDP.RTAS_Proc(r1)
stw r0, KDP.RTAS_PrivDataArea(r1)
@RTAS_done
; Copy 160 bytes of ProcessorInfo into KDP
; (Way longer than anything I know about!)
addi r11, r1, KDP.ProcessorInfo
li r10, 160
@ProcessorInfo_copyloop
addic. r10, r10, -4
lwzx r12, r4, r10
stwx r12, r11, r10
bgt+ @ProcessorInfo_copyloop
; Copy 320 bytes of SystemInfo into IRP
lwz r11, EWA.PA_IRP(r1)
addi r11, r11, IRP.SystemInfo
li r10, 320
@SystemInfo_copyloop
addic. r10, r10, -4
lwzx r12, r5, r10
stwx r12, r11, r10
bgt+ @SystemInfo_copyloop
; If DiagnosticInfo != 0, copy it to PSA
cmpwi r6, 0
beq- @DiagInfo_skipcopy
addi r11, r1, PSA.DiagInfo
li r10, 256; NKDiagInfo.Size
@DiagInfo_copyloop
addic. r10, r10, -4
lwzx r12, r6, r10
stwx r12, r11, r10
bgt+ @DiagInfo_copyloop
@DiagInfo_skipcopy
; Store a ConfigInfo pointer in KDP
stw r3, KDP.PA_ConfigInfo(r1)
; Add to (presumably empty) ConfigFlags
lwz r9, KDP.PA_ConfigInfo(r1)
lhz r8, NKConfigurationInfo.Debug(r9)
; If CI.Debug >= 257 && CI.DebugFlags & 2 ...
cmplwi r8, NKConfigurationInfo.DebugThreshold
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
if &TYPE('NKShowLog') = 'UNDEFINED'
blt- @no_screen_log
lwz r8, NKConfigurationInfo.DebugFlags(r9)
rlwinm. r8, r8, 0, NKConfigurationInfo.LogFlagBit, NKConfigurationInfo.LogFlagBit
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
beq- @no_screen_log
endif
; Enable the screen log
ori r8, r8, 1<< 3
@no_screen_log
; Switch on two other flags
ori r8, r8, 1<< 0 ; not sure
ori r8, r8, 1<< 4 ; to do with interrupts
stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
; Turns out that there was a CPU struct hiding between PSA and KDP,
; which contains our main CPU ewa
addi r9, r1, EWA.CPUBase
li r8, -1
stw r8, CPU.ID(r9)
; Say hello.
bl InitScreenConsole
_log 'Hello from the builtin multitasking NanoKernel. Version: '
li r8, kNanoKernelVersion
mr r8, r8
bl Printh
_log '^n'
; Save a pointer to the kernel memory area in KDP
; (will get upped by pool extends?)
stw r13, KDP.KernelMemoryBase(r1)
; PA_NanoKernelCode is uninitialized, but this loaded value gets
; clobbered straight away anyway. Compiler!
lwz r12, KDP.PA_NanoKernelCode(r1)
; Choose a primary interrupt handler (PIH)
;
; ARG NKConfigurationInfo *r3
bl LookupInterruptHandler
; RET InterruptHandler *r7
; CLOB r12
stw r7, KDP.PA_InterruptHandler(r1)
; Store HTABSIZE in the IRP
lwz r11, EWA.PA_IRP(r1)
addi r12, r14, 1
stw r12, IRP.SystemInfo + NKSystemInfo.HashTableSize(r11)
; Populate KDP...
; Place EDP pointer (and leave it in r8).
addi r8, r1, 0x1000
stw r8, KDP.PA_EmulatorData(r1)
; Place pointer to top of reserved kernel area.
; (= ptr to top of HTAB)
add r12, r13, r15
stw r12, KDP.KernelMemoryEnd(r1)
; Place PA_RelocatedLowMemInit from ConfigInfo in KDP.
; (See note above.)
lwz r12, NKConfigurationInfo.PA_RelocatedLowMemInit(r3)
stw r12, KDP.PA_RelocatedLowMemInit(r1)
; Place something from ConfigInfo in KDP.
; This address seems to contain 0x40820160.
; Trampoline ns old SharedMemoryAddr, which was 0 anyway.
lwz r12, NKConfigurationInfo.SharedMemoryAddr(r3)
stw r12, KDP.SharedMemoryAddr(r1)
; Place (LA_EmulatorCode + KernelTrapTableOffset) from ConfigInfo in KDP.
; (Call this LA_EmulatorKernelTrapTable?)
lwz r12, NKConfigurationInfo.LA_EmulatorCode(r3)
lwz r11, NKConfigurationInfo.KernelTrapTableOffset(r3)
add r12, r12, r11
stw r12, KDP.LA_EmulatorKernelTrapTable(r1)
; Place "PA_NanoKernelCode" in KDP and leave it in r12.
bl * + 4
mflr r12
addi r12, r12, 4 - *
stw r12, KDP.PA_NanoKernelCode(r1)
; FDP. Got its name from an embarrassing mistake by me. Needs a better one.
; Probably written by Gary, it emulates bad PowerPC instructions.
llabel r11, FDP
add r12, r11, r12
stw r12, KDP.PA_FDP(r1)
; Place "LA_ECB" and "PA_ECB" (twice) from ConfigInfo in KDP.
; (This gets called the System Context.)
lwz r12, NKConfigurationInfo.LA_EmulatorData(r3)
lwz r11, NKConfigurationInfo.ECBOffset(r3)
add r12, r12, r11
stw r12, KDP.LA_ECB(r1)
add r12, r8, r11 ; PA_EmulatorData + ECBOffset
stw r12, KDP.PA_ECB(r1)
stw r12, EWA.PA_ContextBlock(r1)
; Place init vals for rupt masks from ConfigInfo in KDP.
lwz r12, NKConfigurationInfo.TestIntMaskInit(r3)
stw r12, KDP.TestIntMaskInit(r1)
lwz r12, NKConfigurationInfo.ClearIntMaskInit(r3)
stw r12, KDP.ClearIntMaskInit(r1)
lwz r12, NKConfigurationInfo.PostIntMaskInit(r3)
stw r12, KDP.PostIntMaskInit(r1)
; Place "PA_EmulatorIplValue" from ConfigInfo in KDP.
lwz r12, NKConfigurationInfo.IplValueOffset(r3)
add r12, r8, r12
stw r12, KDP.PA_EmulatorIplValue(r1)
; Copy this value from ConfigInfo to KDP *again* (see above).
; But this time, add 0x7c to get 0x408201DC.
lwz r12, NKConfigurationInfo.SharedMemoryAddr(r3)
addi r12, r12, 0x7c
stw r12, KDP.SharedMemoryAddrPlus(r1)
; Place PageAttributeInit from ConfigInfo in KDP.
lwz r12, NKConfigurationInfo.PageAttributeInit(r3)
stw r12, KDP.PageAttributeInit(r1)
; Make space at KDP + 0x920 for PageMap,
; according to ConfigInfo.PageMapInitSize.
; 0x1b8 might be a typical value
addi r13, r1, KDP.PageMap
lwz r12, NKConfigurationInfo.PageMapInitSize(r3)
stw r13, KDP.PA_PageMapStart(r1)
add r13, r13, r12
stw r13, KDP.PA_PageMapEnd(r1)
; Zero out a word in KDP a bit below &PA_PageMap.
; Only NewWorld and Unknown PIHes touch this.
stw r0, KDP.ZeroWord(r1)
; The InfoRecord contains metadata about the Power Mac structures
; described in PPCInfoRecordsPriv.
; It lives in the top 64b of the InfoRecord (nee Interrupt Response) Page,
; which on PCI machines is mapped to 5fffe000 (just under 1.5GB). Here we
; populate it at the top of our KDP, and later we copy it to our IRP.
; Logical self-pointer to the copy of InfoRecord in KDP
; (Will this be altered when the InfoRecord is copied to IRP?)
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, KDP.InfoRecord
stw r12, KDP.InfoRecord + InfoRecord.InfoRecordPtr(r1)
; Constant
stw r0, KDP.InfoRecord + InfoRecord.Zero(r1)
; NKProcessorState (created by kernel, lives in PSA)
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, PSA.ProcessorState
stw r12, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1)
li r12, 0x0100
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorStateVer(r1)
li r12, 128
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorStateLen(r1)
; NKHWInfo (created by bootloader, copied to IRP)
lwz r11, NKConfigurationInfo.LA_InfoRecord(r3)
addi r12, r11, IRP.HWInfo
stw r12, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1)
li r12, 0x0108
sth r12, KDP.InfoRecord + InfoRecord.NKHWInfoVer(r1)
li r12, 192
sth r12, KDP.InfoRecord + InfoRecord.NKHWInfoLen(r1)
; NKProcessorInfo (created by bootloader, copied to KDP)
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, KDP.ProcessorInfo
stw r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1)
li r12, 0x0112
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1)
li r12, 160
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1)
; NKNanoKernelInfo (created by kernel, lives in KDP)
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, KDP.NanoKernelInfo
stw r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1)
li r12, kNanoKernelVersion
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r1)
li r12, 352
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1)
; NKDiagInfo (created by bootloader, copied to PSA)
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, PSA.DiagInfo
stw r12, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1)
li r12, 0x0100
sth r12, KDP.InfoRecord + InfoRecord.NKDiagInfoVer(r1)
li r12, 256
sth r12, KDP.InfoRecord + InfoRecord.NKDiagInfoLen(r1)
; NKSystemInfo (created by bootloader, copied to IRP)
lwz r11, NKConfigurationInfo.LA_InfoRecord(r3)
addi r12, r11, IRP.SystemInfo
stw r12, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1)
li r12, 0x0107
sth r12, KDP.InfoRecord + InfoRecord.NKSystemInfoVer(r1)
li r12, 320
sth r12, KDP.InfoRecord + InfoRecord.NKSystemInfoLen(r1)
; NKProcessorInfo... again!
lwz r11, NKConfigurationInfo.LA_KernelData(r3)
addi r12, r11, KDP.ProcessorInfo
stw r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr2(r1)
li r12, 0x0112
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer2(r1)
li r12, 160
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen2(r1)
; Populate emulator data page (EDP).
; Copy 16-byte BootstrapVersion string from ConfigInfo
lwz r11, NKConfigurationInfo.BootVersionOffset(r3)
lwz r12, NKConfigurationInfo.BootstrapVersion(r3)
stwux r12, r11, r8
lwz r12, NKConfigurationInfo.BootstrapVersion + 4(r3)
stw r12, 4(r11)
lwz r12, NKConfigurationInfo.BootstrapVersion + 8(r3)
stw r12, 8(r11)
lwz r12, NKConfigurationInfo.BootstrapVersion + 12(r3)
stw r12, 12(r11)
; Place logical pointer to emulator entry point in ContextBlock.
; Leave pointer to ECB in r11.
lwz r12, NKConfigurationInfo.LA_EmulatorCode(r3)
lwz r11, NKConfigurationInfo.EmulatorEntryOffset(r3)
add r12, r11, r12
lwz r11, NKConfigurationInfo.ECBOffset(r3)
add r11, r11, r8
stw r12, ContextBlock.LA_EmulatorEntry(r11)
; Place LA_EmulatorData from ConfigInfo in ContextBlock.
lwz r12, NKConfigurationInfo.LA_EmulatorData(r3)
stw r12, ContextBlock.LA_EmulatorData(r11)
; Place LA_DispatchTable from ConfigInfo in ContextBlock.
lwz r12, NKConfigurationInfo.LA_DispatchTable(r3)
stw r12, ContextBlock.LA_DispatchTable(r11)
; Place LA_EmulatorKernelTrapTable from KDP in ContextBlock.
lwz r12, KDP.LA_EmulatorKernelTrapTable(r1)
stw r12, ContextBlock.LA_EmulatorKernelTrapTable(r11)
; Initialize MacOS LowMem globals at PA_RelocatedLowMemInit
; Zero out 8k
lwz r10, KDP.PA_RelocatedLowMemInit(r1)
li r9, 0x2000
@LowMem_zeroloop
addic. r9, r9, -4
stwx r0, r10, r9
bne+ @LowMem_zeroloop
; Populate from LowMemInit "key-value" table.
lwz r11, NKConfigurationInfo.MacLowMemInitOffset(r3)
lwz r10, KDP.PA_RelocatedLowMemInit(r1)
lwzux r9, r11, r3 ; get first word and point r11 at it
@LowMem_setloop
mr. r9, r9
beq- @LowMem_done
lwzu r12, 4(r11)
stwx r12, r10, r9
lwzu r9, 4(r11)
b @LowMem_setloop
@LowMem_done
; We expect a 'Hnfo' signature (from Trampoline) in HWInfo.
;
; If HWInfo IS signed, great -- we can move on with the init process,
; and skip all the nasty cache-probing, table-consulting madness that
; follows. Just ignore the rest of this file.
;
; But if HWInfo is unsigned, then this is going to hurt.
lwz r11, EWA.PA_IRP(r1)
lwz r11, IRP.HWInfo + NKHWInfo.Signature(r11)
lisori r12, 'Hnfo'
cmplw r12, r11
beq- FinishInitBuiltin
; Darn. All right, see if we can copy ProcessorInfo from
; ProcessorInfoTable.s
mfpvr r12
stw r12, KDP.ProcessorInfo + NKProcessorInfo.ProcessorVersionReg(r1)
srwi r12, r12, 16
lwz r11, KDP.PA_NanoKernelCode(r1)
addi r10, r1, KDP.ProcessorInfo + NKProcessorInfo.Ovr
li r9, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
; check for several (some unknown) pre-7410 CPUs, and load their info
cmpwi r12, 0x0001 ; 601
addi r11, r11, ProcessorInfoTable - NKTop
beq- OverrideProcessorInfo
cmpwi r12, 0x0003 ; 603
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x0004 ; 604
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x0006 ; 603e
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x0007 ; 750FX
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x0008 ; 750
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x0009 ; ???
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x000a ; ???
beq- OverrideProcessorInfo
cmpwi r12, 0x000c ; 7400
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
cmpwi r12, 0x000d ; ???
addi r11, r11, NKProcessorInfo.OvrEnd - NKProcessorInfo.Ovr
beq- OverrideProcessorInfo
; Now things get crazy. Have barely touched this...
; get base of page table (why?)
mfsdr1 r22
; r21 = SDR1 & 0xffff0000
rlwinm r21, r22, 0, 0, 15
; r22 = (SDR1 << 16) & 0x007F0000
rlwinm r22, r22, 16, 9, 15
addis r22, r22, 0x01
li r15, 0x00
li r12, 0x1a
mtctr r12
lwz r12, -0x0020(r1)
addi r10, r12, 0xec0
new_world_0x60c
lwz r11, -0x0004(r10)
lwzu r12, -0x0008(r10)
subf r9, r12, r21
cmplw r9, r11
bge- new_world_0x624
mr r11, r9
new_world_0x624
cmplw r11, r15
ble- new_world_0x634
mr r13, r12
mr r15, r11
new_world_0x634
bdnz+ new_world_0x60c
addi r12, r22, -0x01
neg r11, r13
and r12, r11, r12
add r13, r13, r12
subf r15, r12, r15
rlwinm r15, r15, 0, 0, 21
li r11, 0x1000
stw r11, 0x0f30(r1)
li r11, -0x01
li r10, 0x400
new_world_0x660
subic. r10, r10, 4
stwx r11, r21, r10
bne+ new_world_0x660
dcbz 0, r21
new_world_0x670
addi r10, r10, 0x01
lbzx r11, r21, r10
cmpwi r11, 0x00
beq+ new_world_0x670
sth r10, 0x0f3c(r1)
sth r10, 0x0f3e(r1)
sth r10, 0x0f46(r1)
sth r10, 0x0f48(r1)
sth r10, 0x0f4a(r1)
lis r12, -0x8000
add r11, r21, r22
addi r11, r11, -0xe6e
addis r10, r21, 0x01
new_world_0x6a4
stwu r11, -0x0004(r10)
rlwimi r12, r10, 29, 29, 31
stwu r12, -0x0004(r10)
cmpw r10, r21
rlwinm r9, r10, 9, 7, 19
tlbie r9
bne+ new_world_0x6a4
sync
isync
lwz r11, 0x064c(r1)
li r12, (copied_code_1_end - copied_code_1) / 4
mtctr r12
add r20, r21, r22
addi r11, r11, copied_code_1_end - NKTop
new_world_0x6dc
lwzu r12, -0x0004(r11)
stwu r12, -0x0004(r20)
dcbst 0, r20
sync
icbi 0, r20
bdnz+ new_world_0x6dc
sync
isync
stw r0, 0x0f34(r1)
li r17, 0x00
li r18, 0x200
li r19, 0x00
li r16, -0x01
b new_world_0x720
new_world_0x714
addi r17, r17, 0x200
cmplw r17, r15
bge- new_world_0x734
new_world_0x720
mtlr r20
blrl
ble+ new_world_0x714
addi r12, r17, -0x200
stw r12, 0x0f34(r1)
new_world_0x734
li r12, 0x01
sth r12, 0x0f4e(r1)
lwz r18, 0x0f34(r1)
mr r17, r18
li r19, 0x00
li r16, -0x01
b new_world_0x75c
new_world_0x750
add r17, r17, r18
cmplw r17, r15
bge- new_world_0x774
new_world_0x75c
mtlr r20
blrl
ble+ new_world_0x750
subf r17, r18, r17
divwu r12, r17, r18
sth r12, 0x0f4e(r1)
new_world_0x774
lwz r17, 0x0f34(r1)
lhz r18, 0x0f4e(r1)
slwi r17, r17, 1
divwu r18, r17, r18
srwi r19, r18, 1
li r14, 0x200
add r19, r19, r14
li r16, -0x01
b new_world_0x7ac
new_world_0x798
lhz r12, 0x0f4a(r1)
cmplw r14, r12
ble- new_world_0x7bc
srwi r14, r14, 1
subf r19, r14, r19
new_world_0x7ac
mtlr r20
blrl
ble+ new_world_0x798
slwi r12, r14, 1
new_world_0x7bc
sth r12, 0x0f44(r1)
mtsdr1 r21
mr r14, r13
li r13, 0xff0
sth r0, 0x0f50(r1)
li r17, 0x00
lwz r18, 0x0f30(r1)
li r19, 0x00
li r16, -0x01
b new_world_0x7f4
new_world_0x7e4
add r17, r17, r18
lis r12, 0x3f
cmplw r17, r12
bge- new_world_0x82c
new_world_0x7f4
mtlr r20
mfmsr r12
ori r12, r12, 0x10
mtmsr r12
isync
blrl
mfmsr r12
rlwinm r12, r12, 0, 28, 26
mtmsr r12
isync
ble+ new_world_0x7e4
subf r17, r18, r17
divwu r12, r17, r18
sth r12, 0x0f50(r1)
new_world_0x82c
li r12, 0x01
sth r12, 0x0f52(r1)
li r17, 0x00
lis r18, 0x40
li r19, 0x00
li r16, -0x01
b new_world_0x858
new_world_0x848
add r17, r17, r18
lis r12, 0x200
cmplw r17, r12
bge- new_world_0x890
new_world_0x858
mtlr r20
mfmsr r12
ori r12, r12, 0x10
mtmsr r12
isync
blrl
mfmsr r12
rlwinm r12, r12, 0, 28, 26
mtmsr r12
isync
ble+ new_world_0x848
subf r17, r18, r17
divwu r12, r17, r18
sth r12, 0x0f52(r1)
new_world_0x890
mr r13, r14
addi r12, r22, -0x01
srwi r12, r12, 16
or r12, r12, r21
mtsdr1 r12
lwz r12, 0x0f34(r1)
stw r12, 0x0f38(r1)
lhz r12, 0x0f4e(r1)
sth r12, 0x0f4c(r1)
lhz r12, 0x0f44(r1)
sth r12, 0x0f42(r1)
lis r11, 0x3960
stw r11, 0x0000(r21)
lis r11, 0x4e80
ori r11, r11, 0x20
stw r11, 0x0004(r21)
dcbst 0, r21
sync
icbi 0, r21
sync
isync
mtlr r21
blrl
li r11, 0x01
sth r11, 0x0002(r21)
sync
isync
mtlr r21
blrl
sth r11, 0x0f40(r1)
cmpwi r11, 0x01
beq- skip_cache_hackery_never
lwz r11, 0x064c(r1)
li r12, (copied_code_2_end - copied_code_2) / 4
mtctr r12
add r20, r21, r22
addi r11, r11, copied_code_2_end - NKTop
new_world_0x924
lwzu r12, -0x0004(r11)
stwu r12, -0x0004(r20)
dcbst 0, r20
sync
icbi 0, r20
bdnz+ new_world_0x924
sync
isync
subf r12, r21, r20
mulli r12, r12, 0x80
cmplw r12, r15
bge- new_world_0x958
mr r15, r12
new_world_0x958
add r12, r13, r15
mr r11, r20
lis r10, 0x4e80
ori r10, r10, 0x20
new_world_0x968
lwzu r9, -0x0200(r12)
stw r10, 0x0000(r12)
cmpw r12, r13
stwu r9, -0x0004(r11)
dcbst 0, r12
sync
icbi 0, r12
bne+ new_world_0x968
sync
isync
stw r0, 0x0f38(r1)
li r17, 0x00
li r18, 0x200
li r19, 0x00
li r16, -0x01
b new_world_0x9b4
new_world_0x9a8
addi r17, r17, 0x200
cmplw r17, r15
bge- new_world_0x9c8
new_world_0x9b4
mtlr r20
blrl
ble+ new_world_0x9a8
addi r12, r17, -0x200
stw r12, 0x0f38(r1)
new_world_0x9c8
li r12, 0x01
sth r12, 0x0f4c(r1)
lwz r18, 0x0f38(r1)
mr r17, r18
li r19, 0x00
li r16, -0x01
b new_world_0x9f0
new_world_0x9e4
add r17, r17, r18
cmplw r17, r15
bge- new_world_0xa08
new_world_0x9f0
mtlr r20
blrl
ble+ new_world_0x9e4
subf r17, r18, r17
divwu r12, r17, r18
sth r12, 0x0f4c(r1)
new_world_0xa08
add r12, r13, r15
mr r11, r20
new_world_0xa10
lwzu r9, -0x0004(r11)
stwu r9, -0x0200(r12)
cmpw r12, r13
dcbst 0, r12
sync
icbi 0, r12
bne+ new_world_0xa10
sync
isync
lwz r17, 0x0f38(r1)
lhz r18, 0x0f4c(r1)
divwu r18, r17, r18
slwi r17, r17, 1
add r12, r13, r17
subi r11, r21, 4
new_world_0xa4c
subf r12, r18, r12
li r14, 0x400
new_world_0xa54
rlwinm. r14, r14, 31, 0, 28
lwzx r9, r12, r14
lis r10, 0x4e80
ori r10, r10, 0x20
stwx r10, r12, r14
stwu r9, 0x0004(r11)
dcbst r12, r14
sync
icbi r12, r14
addi r14, r14, 0x04
lwzx r9, r12, r14
lis r10, 0x4bff
ori r10, r10, 0xfffc
stwx r10, r12, r14
stwu r9, 0x0004(r11)
dcbst r12, r14
sync
icbi r12, r14
bne+ new_world_0xa54
cmpw r12, r13
bne+ new_world_0xa4c
sync
isync
mr r19, r18
slwi r18, r18, 1
li r14, 0x200
add r19, r19, r14
li r16, -0x01
b new_world_0xadc
new_world_0xac8
li r12, 0x08
cmplw r14, r12
ble- new_world_0xaec
srwi r14, r14, 1
subf r19, r14, r19
new_world_0xadc
mtlr r20
blrl
ble+ new_world_0xac8
slwi r12, r14, 1
new_world_0xaec
sth r12, 0x0f42(r1)
srwi r18, r18, 1
add r12, r13, r17
subi r11, r21, 4
new_world_0xafc
subf r12, r18, r12
li r14, 0x400
new_world_0xb04
rlwinm. r14, r14, 31, 0, 28
lwzu r9, 0x0004(r11)
stwx r9, r12, r14
addi r14, r14, 0x04
lwzu r9, 0x0004(r11)
stwx r9, r12, r14
bne+ new_world_0xb04
cmpw r12, r13
bne+ new_world_0xafc
skip_cache_hackery_never
; Clearly can't just fall through
b FinishInitBuiltin
; copied_code_1
; Xrefs:
; new_world
copied_code_1 ; OUTSIDE REFERER
li r10, 0x03
copied_code_1_0x4
li r12, 0x800
mtctr r12
add r19, r19, r13
li r11, 0x00
mtdec r11
copied_code_1_0x18
subf r12, r17, r11
srawi r12, r12, 31
and r11, r11, r12
lbzx r12, r13, r11
add r12, r12, r12
lbzx r12, r19, r11
add r12, r12, r12
add r11, r11, r18
bdnz+ copied_code_1_0x18
subf r19, r13, r19
mfdec r12
neg r12, r12
cmplw r12, r16
bgt- copied_code_1_0x54
mr r16, r12
copied_code_1_0x54
srwi r11, r12, 7
subf r12, r11, r12
cmpw r12, r16
blelr-
addic. r10, r10, -0x01
bgt+ copied_code_1_0x4
cmpw r12, r16
blr
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
copied_code_1_end ; OUTSIDE REFERER
; copied_code_2
; Xrefs:
; new_world
copied_code_2 ; OUTSIDE REFERER
li r10, 0x03
mflr r9
copied_code_2_0x8
li r12, 0x800
mtctr r12
add r19, r19, r13
li r11, 0x00
mtdec r11
copied_code_2_0x1c
subf r12, r17, r11
srawi r12, r12, 31
and r11, r11, r12
add r12, r13, r11
mtlr r12
blrl
add r12, r19, r11
mtlr r12
blrl
add r11, r11, r18
bdnz+ copied_code_2_0x1c
subf r19, r13, r19
mfdec r12
neg r12, r12
cmplw r12, r16
bgt- copied_code_2_0x60
mr r16, r12
copied_code_2_0x60
srwi r11, r12, 7
subf r12, r11, r12
cmpw r12, r16
mtlr r9
blelr-
addic. r10, r10, -0x01
bgt+ copied_code_2_0x8
cmpw r12, r16
blr
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
isync
copied_code_2_end ; OUTSIDE REFERER