From c7d4cdd367d07f78fe046a918624f2ed8932d31d Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Fri, 9 Mar 2018 19:46:39 +0800 Subject: [PATCH] Reverse power management functions This is part of the work to get the mini running well. The kcPowerDispatch and kcCacheDispatch entry points were explored. The dead code implementing a Timer "Heartbeat" was also used to label some structures better. --- Internal/EmulatorPublic.a | 16 +- Internal/InfoRecords.a | 5 +- Internal/NKOpaque.a | 6 +- Internal/NKPublic.a | 6 +- NanoKernel/InnerMakeFile | 2 +- NanoKernel/NKCache.s | 529 +++++++++++++++++ NanoKernel/NKCacheCalls.s | 300 ---------- NanoKernel/NKEquates.s | 2 +- NanoKernel/NKInit.s | 9 +- NanoKernel/NKInterrupts.s | 8 +- NanoKernel/NKMacros.s | 47 ++ NanoKernel/NKPowerCalls.s | 934 +++++++++++++++++------------- NanoKernel/NKPrimaryIntHandlers.s | 6 +- NanoKernel/NKProcFlagsTbl.s | 80 +-- NanoKernel/NKScheduler.s | 65 ++- NanoKernel/NKSync.s | 208 ++++--- NanoKernel/NKTasks.s | 8 +- NanoKernel/NKTimers.s | 32 +- NanoKernel/NanoKernel.s | 2 +- 19 files changed, 1378 insertions(+), 887 deletions(-) create mode 100644 NanoKernel/NKCache.s delete mode 100644 NanoKernel/NKCacheCalls.s diff --git a/Internal/EmulatorPublic.a b/Internal/EmulatorPublic.a index 8d48d25..be5ea29 100644 --- a/Internal/EmulatorPublic.a +++ b/Internal/EmulatorPublic.a @@ -39,18 +39,20 @@ MSR ds.l 1 ; 0a4 ; (SPAC) copied from kdp by CreateTask org 0xc4 MQ ds.l 1 ; 0c4 ; 601 only - ds.l 1 +EDPOffsetSWIRelated ds.l 1 ; 0c8 PriorityShifty ds.l 1 ; 0cc ; if low nybble is empty, InitRDYQs sets this to 2 - - org 0xd4 -XER ds.l 1 +SWIEventGroupID ds.l 1 ; 0d0 ; what? +XER ds.l 1 ; 0d4 VectorSaveArea ds.l 1 ; 0d8 ; AltiVec hack: vector registers don't fit in CB! - org 0xe0 + org 0xdc +CR ds.l 1 ; 0dc ; from heartbeat code, unsure of meaning (ANDed with PostIntMaskInit) r13 PageInSystemHeap ds.l 1 ; 0e0 ; these are set by StartInit.a:FiddleWithEmulator OtherPageInSystemHeap ds.l 1 ; 0e4 -FE000000 ds.l 1 ; 0e8 -Zero ds.l 1 ; 0ec +FE000000 ds.l 1 ; 0e8 ; also LR? +LR ds.l 1 ; 0ec +CTR ds.l 1 ; 0f0 +KernelCTR ds.l 1 ; 0f4 org 0xfc CodePtr ds.l 1 ; 0fc ; probably goes in SRR0? diff --git a/Internal/InfoRecords.a b/Internal/InfoRecords.a index 01b39ef..8644f07 100644 --- a/Internal/InfoRecords.a +++ b/Internal/InfoRecords.a @@ -322,7 +322,8 @@ LogFlagShift equ 3 LogFlagBit equ 31 - LogFlagShift ; bit 31 always set on replacement, bit 27 set on replacement with ROM 2.7f3 or later - org 0x128 +AlertCount ds.l 1 ; 120, kdp+ee0 ; interprocessor alerts +SchEvalCount ds.l 1 ; 124, kdp+ee4 VMDispatchCountTblPtr ds.l 1 ; 128, kdp+ee8 ds.l 1 ds.l 1 @@ -390,7 +391,7 @@ hasL2CR equ 0 hasPLRUL1 equ 1 hasTAU equ 2 hasVMX equ 3 -unknownFlag equ 4 +hasMSSregs equ 4 hasExtraBATs equ 5 ProcessorFlags ds.l 1 ; 048, kdp+f68 ; flags to specify processor features diff --git a/Internal/NKOpaque.a b/Internal/NKOpaque.a index 770a1af..91b0a07 100644 --- a/Internal/NKOpaque.a +++ b/Internal/NKOpaque.a @@ -109,7 +109,7 @@ kIdlePriority equ 3 ID ds.l 1 ; 000 Signature ds.l 1 ; 004 QueueMember ds.l 4 ; 008:018 ; a task is always a member of a queue, e.g. the RDYQ -MysteryByte1 ds.b 1 ; 018 ; CreateTask sets 0 by default (blue = 2) +State ds.b 1 ; 018 ; non-zero when running Priority ds.b 1 ; 019 ; CreateTask sets 2 by default CPUIndex ds.w 1 ; 01a Weight ds.l 1 ; 01c ; default is 100, blue gets 200, idle gets 1 @@ -145,7 +145,7 @@ kFlag23 equ 23 kFlag24 equ 24 kFlag25 equ 25 ; set for idle1, idle2 kFlag26 equ 26 ; set for blue -kFlag27 equ 27 +kFlag27 equ 27 ; set on SWI kFlag28 equ 28 ; set for blue kFlag29 equ 29 kFlag30 equ 30 @@ -470,7 +470,7 @@ kSignature equ 'EVNT' LLL ds.l 4 ; 00:10 ; first field is ID Flags ds.l 1 ; 10 ProcessID ds.l 1 ; 14 -SWI ds.l 1 ; 18 ; contains 1-8 +/- 16 +SWI ds.l 1 ; 18 ; contains 1-8 +/- 16 ; flag 27 (=16) means "is swi" Counter ds.l 1 ; 1c Size equ * diff --git a/Internal/NKPublic.a b/Internal/NKPublic.a index e7bbf09..4cdd5f6 100644 --- a/Internal/NKPublic.a +++ b/Internal/NKPublic.a @@ -153,13 +153,13 @@ SevenFFFDead2 ds.l 1 ; -8dc SevenFFFDead3 ds.l 1 ; -8d8 SevenFFFDead4 ds.l 1 ; -8d4 VioletVecBase ds.l 48 ; -8d0:-810 -IndigoVecBase ds.l 48 ; -810:-750 +IdleVecBase ds.l 48 ; -810:-750 ; to wake from DOZE/NAP/SLEEP state BlueVecBase ds.l 48 ; -750:-690 ; gets enabled by PDM PIH GreenVecBase ds.l 48 ; -690:-5d0 DiagInfo ds.b 256 ; -5d0:-4d0 ProcessorState ds.b 128 ; -4d0:-450 ; interesting what this gets used by FreeList ds.l 4 ; -450:-440 - ds.l 1 ; -440 +MCR ds.l 1 ; -440 ; reported by heartbeat code Int ds.w 1 ; -43c ; set by CommonPIHPath: a one-byte 68k int ID or -1 ds.w 1 ; -43a DecClockRateHzCopy ds.l 1 ; -438 ; copied by Init.s @@ -172,7 +172,7 @@ SystemAddressSpaceID ds.l 1 ; -424 blueProcessPtr ds.l 1 ; -41c ; physical ptr to first type-1 struct created ThermalHandlerID ds.l 1 ; -418 ; is a Note struct PMFHandlerID ds.l 1 ; -414 ; also a Note struct -BlueSpinningOn ds.l 1 ; -410 ; ID or 0 or -1 +BlueSpinningOn ds.l 1 ; -410 ; ID or 0 or -1 ds.l 1 ; -40c ds.l 1 ; -408 ds.l 1 ; -404 diff --git a/NanoKernel/InnerMakeFile b/NanoKernel/InnerMakeFile index c4f2df2..1a7e92e 100644 --- a/NanoKernel/InnerMakeFile +++ b/NanoKernel/InnerMakeFile @@ -13,7 +13,7 @@ NKFiles = {NKDir}NKVMCalls.s ¶ {NKDir}NKPowerCalls.s ¶ {NKDir}NKRTASCalls.s ¶ - {NKDir}NKCacheCalls.s ¶ + {NKDir}NKCache.s ¶ {NKDir}NKMPCalls.s ¶ {NKDir}NKSync.s ¶ {NKDir}NKTasks.s ¶ diff --git a/NanoKernel/NKCache.s b/NanoKernel/NKCache.s new file mode 100644 index 0000000..26ccd39 --- /dev/null +++ b/NanoKernel/NKCache.s @@ -0,0 +1,529 @@ + ###### ### ###### ## ## ######## ###### ### ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ######### ###### ## ## ## ## ## +## ######### ## ## ## ## ## ######### ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + ###### ## ## ###### ## ## ######## ###### ## ## ######## ######## + +; Enable/disable/probe the L1/2 data/inst cache + +; Probably called using an unknown 68k F-trap. Not usually called on my +; G4, but can be tested by hacking the MPCall table. Uses fancy new CPU +; features (MSSCR0), so probably not legacy code. For CPU accelerator +; cards? `FlushCache` needs to be nopped out to prevent a crash. + +; ARGUMENT (r3) +; r3.hi = action flags +; enable specified caches $8000 +; disable specified caches $4000 +; report pre-change state $2000 +; also enable (???) $1000 +; enable/disable I-cache $0800 +; enable/disable D-cache $0400 +; +; r3.lo = which cache (L1/2) +; level 1 1 +; level 2 2 +; +; RETURN VALUE (r3) +; r3.hi = pre-change state flags (resemble action flags) +; both caches disabled $4000 +; either cache enabled $8000 +; I-cache enabled $0800 +; D-cache enabled $0400 +; +; r3.lo = return status +; success 0 +; failure < 0 +; checked L1 but did not set 1 +; checked L2 but did not set 2 + +; DeclareMPCall 199, kcCacheDispatch ; DEBUG + +kcCacheDispatch + + _RegRangeToContextBlock r21, r23 ; get some breathing room + +; _log 'kcCacheDispatch ' ; DEBUG +; mr r8, r3 ; DEBUG +; bl printw ; DEBUG +; _log '^n' ; DEBUG + + clrlwi r8, r3, 16 ; bad selector + cmplwi r8, 2 + bgt- @fail_bad_selector + + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + andi. r8, r8, 1 << NKProcessorInfo.hasL2CR + beq- CacheCallFailNoL2 ; no L2CR => fail (what about 601?) + + rlwinm. r9, r3, 0, 2, 2 ; if flagged, get cache state in r23 + bnel- CacheCallGetInfoForReturnValue ; (otherwise, r23 is undefined) + + srwi r8, r3, 30 ; cannot enable *and* disable + cmpwi r8, 3 + beq- CacheCallFailBadFlags + + clrlwi r8, r3, 16 ; go to main code for level 1/2 cache + cmplwi r8, 1 + beq- CacheCallDispatchL1 + cmplwi r8, 2 + beq- CacheCallDispatchL2 + +@fail_bad_selector ; fall through => bad selector + lisori r3, -2 + b CacheCallReturn + + + + ### ## ## ### + ## ## #### ## +## ## ## ## +## ## ## ## +## ## ## ## + ## ## ## ## + ### ######## ###### ### + +CacheCallDispatchL1 + + rlwinm. r9, r3, 0, 1, 1 + bne- CacheCallL1DisableSelected + + rlwinm. r9, r3, 0, 0, 0 + bne- CacheCallL1EnableSelected + + rlwinm. r9, r3, 0, 3, 3 ; ??? + + bl FlushCaches + + b CacheCallReturn + + + +CacheCallL1DisableSelected + + bl FlushCaches + + rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE] + srwi r22, r22, 12 + mfspr r21, hid0 + andc r21, r21, r22 ; HID0 &= ~mybits + sync + mtspr hid0, r21 + + li r3, 0 + b CacheCallReturn + + + +CacheCallL1EnableSelected + + rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE] + srwi r22, r22, 12 + mfspr r21, hid0 + or r21, r21, r22 ; HID0 |= mybits + sync + mtspr hid0, r21 + + li r3, 0 + b CacheCallReturn + + + + ### ## ####### ### + ## ## ## ## ## +## ## ## ## +## ## ####### ## +## ## ## ## + ## ## ## ## + ### ######## ######### ### + +CacheCallDispatchL2 + + rlwinm. r9, r3, 0, 1, 1 + bne- CacheCallL2DisableSelected + + rlwinm. r9, r3, 0, 0, 0 + bne- CacheCallL2EnableSelected + + rlwinm. r9, r3, 0, 3, 3 + bne- CacheCallL2Flag3 ; goes to DisableSelected + + rlwinm. r9, r3, 0, 2, 2 + ;bne removed? + + bne- CacheCallReturn + + + +CacheCallFailBadFlags + + lisori r3, -4 + b CacheCallReturn + + + +CacheCallL2Flag3 + + bl CacheCallL2DisableSelected ; typo? should be `b` + + + +CacheCallL2EnableSelected + + mfspr r21, l2cr ; fail if L2CR[L2E] already set + sync + andis. r21, r21, 0x8000 + bne- CacheCallReturn + + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) + and. r8, r8, r8 + beq- CacheCallFailNoL2 ; fail if zero-sized cache reported + + mfspr r21, hid0 ; save HID0 + + rlwinm r8, r21, 0, 12, 10 ; clear HID0[DPM] (dynamic power management) + mtspr hid0, r8 ; presumably to keep L2 working while we wait? + sync + + addi r8, r1, PSA.ProcessorState + lwz r8, NKProcessorState.saveL2CR(r8) + and. r8, r8, r8 + beq- CacheCallReturn ; fail if zero L2CR was saved? + sync + + lis r9, 0x0020 ; set L2CR[GI] (global invalidate) + or r8, r8, r9 + mtspr l2cr, r8 + sync +@inval_loop + mfspr r8, l2cr ; check L2CR[IP] (invalidate progress) + sync + andi. r9, r8, 1 + bne+ @inval_loop + + lis r9, 0x0020 ; clear L2CR[GI] + andc r8, r8, r9 + mtspr l2cr, r8 + sync + + lis r9, 0x8000 ; set L2CR[L2E] (L2 enable) + or r8, r8, r9 + mtspr l2cr, r8 + sync + + mtspr hid0, r21 ; restore HID0 + sync + + li r3, 0 ; return successfully + b CacheCallReturn + + + +CacheCallFailNoL2 + + li r3, -2 + b CacheCallReturn + + + +CacheCallL2DisableSelected + + mfspr r22, l2cr ; return if already disabled per L2CR[L2E] + sync + andis. r22, r22, 0x8000 + beq- CacheCallReturn + + bl FlushCaches + + mfspr r22, l2cr ; clear L2CR[L2E] + sync + clrlwi r22, r22, 1 + mtspr l2cr, r22 + sync + + addi r8, r1, PSA.ProcessorState + stw r22, NKProcessorState.saveL2CR(r8) ; update saveL2CR + sync + + rlwinm r22, r22, 0, 7, 3 ; clear L2CR[3/5/6] (all reserved) + oris r22, r22, 0x0010 ; set L2CR[13] (also reserved) + mtspr l2cr, r22 + sync + + ;b CacheCallReturn ; fall through + + + + ### ######## ######## ######## ## ## ######## ## ## ### + ## ## ## ## ## ## ## ## ## ### ## ## +## ## ## ## ## ## ## ## ## #### ## ## +## ######## ###### ## ## ## ######## ## ## ## ## +## ## ## ## ## ## ## ## ## ## #### ## + ## ## ## ## ## ## ## ## ## ## ### ## + ### ## ## ######## ## ####### ## ## ## ## ### + +CacheCallReturn + + ori r23, r23, 0xffff ; put the r23.hi from CacheCallGetInfoForReturnValue into r3.hi + oris r3, r3, 0xffff + and r3, r3, r23 + +CacheCallReturnWithoutFlags + _RegRangeFromContextBlock r21, r23 + sync + +; _log 'Return ' ; DEBUG +; mr r8, r3 ; DEBUG +; bl printw ; DEBUG +; _log '^n' ; DEBUG + + b IntReturn + + + + ### ######## ######## ####### ######## ######## ### + ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## +## ######## ######## ## ## ######## ###### ## +## ## ## ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ## ## ## + ### ## ## ## ####### ######## ######## ### + +; RET r23.hi = flags describing state of specified cache (see top of file) + +CacheCallGetInfoForReturnValue + + clrlwi r8, r3, 16 + + cmplwi r8, 1 + beq- @level1 + cmplwi r8, 2 + beq- @level2 + + lisori r3, -5 + b CacheCallReturnWithoutFlags + +@level1 + mfspr r21, hid0 + rlwinm. r21, r21, 12, 4, 5 + beq- @all_off + + oris r23, r21, 0x8000 + blr + +@level2 + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) + and. r8, r8, r8 + beq+ CacheCallFailNoL2 + + mfspr r21, hid0 ; same bits as above + rlwinm r21, r21, 12, 4, 5 + + mfspr r22, l2cr ; L2-D is on if L1-D is on and L2CR[DO] is cleared + rlwinm r22, r22, 5, 4, 4 + andc r21, r21, r22 + + mfspr r22, l2cr ; then again, both L2s are off if L2CR[L2E] is cleared + andis. r22, r22, 0x8000 + beq- @all_off + + or r23, r21, r22 + blr + +@all_off + lisori r23, 0x40000000 + blr + + + +######## ## ## ## ###### ## ## ######## ## ## ## ## ###### ###### +## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## #### ## ## ## +###### ## ## ## ###### ######### ###### ## ## ## ## ## ## ###### +## ## ## ## ## ## ## ## ## ## ## #### ## ## +## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## +## ######## ####### ###### ## ## ## ####### ## ## ###### ###### + +; Flush L1 and L2 caches +; Also used by NKPowerCalls.s + +; ARG KDP *r1, ContextBlock *r6 +; CLOB r8, r9, cr + +FlushCaches + +; blr ; DEBUG + + ; Be cautious + + mfctr r8 + stw r25, ContextBlock.r25(r6) + stw r24, ContextBlock.r24(r6) + stw r8, ContextBlock.KernelCTR(r6) + + + ; Flush level 1 + + lhz r25, KDP.ProcessorInfo + NKProcessorInfo.DataCacheLineSize(r1) + and. r25, r25, r25 ; r25 = L1-D line size + cntlzw r8, r25 + beq- @return + subfic r9, r8, 31 ; r9 = logb(L1-D line size) + + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.DataCacheTotalSize(r1) + and. r8, r8, r8 ; r8 = L1-D size + beq- @return + + lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + mtcr r24 + + bc BO_IF, 31 - NKProcessorInfo.hasMSSregs, @use_SPRs_to_invalidate + ; => go away to handle weird CPUs + + bc BO_IF_NOT, 31 - NKProcessorInfo.hasPLRUL1, @no_pseudo_lru + slwi r24, r8, 1 + add r8, r8, r24 + srwi r8, r8, 1 ; be generous with pseudo-LRU caches +@no_pseudo_lru + + srw r8, r8, r9 + mtctr r8 ; loop counter = cache/line + + lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM + lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8) + add r8, r8, r9 + +@loop_L1 + lwzux r9, r8, r25 + bdnz+ @loop_L1 + + + ; Flush level 2 (very similar to above) + + lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + andi. r24, r24, 1 << NKProcessorInfo.hasL2CR + beq- @return ; return if L2CR unavailable + + mfspr r24, l2cr + andis. r24, r24, 0x8000 + beq- @return ; return if L2 off (per L2CR[L2E]) + + lhz r25, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DBlockSize(r1) + and. r25, r25, r25 ; r25 = L2-D line size + cntlzw r8, r25 + beq- @return + subfic r9, r8, 31 ; r9 = logb(L2-D line size) + + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) + and. r8, r8, r8 ; r8 = L2-D size + beq- @return + + srw r8, r8, r9 + mtctr r8 ; loop counter = cache/line + + mfspr r24, l2cr ; set L2CR[DO] (disables L2-I) + oris r24, r24, 0x0040 + mtspr l2cr, r24 + isync + + lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM + lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8) + add r8, r8, r9 + + addis r8, r8, 0x19 ; start high in ROM and count backwards + neg r25, r25 + +@loop_L2 + lwzux r9, r8, r25 + bdnz+ @loop_L2 + + rlwinm r24, r24, 0, 10, 8 + mtspr l2cr, r24 ; clear L2CR[DO] (reenables L2-I) + isync + + + ; Done (this return path is also called from the sneaky code below) + +@return + lwz r8, ContextBlock.KernelCTR(r6) + lwz r25, ContextBlock.r25(r6) + lwz r24, ContextBlock.r24(r6) + sync + mtctr r8 + blr + + +; If "hasMSSregs" flag (my name) is set in ProcessorFlags, L1 and L2 can +; instead be flushed by clobbering reserved bits in MSSCR0 and L2CR +; respectively. + +@use_SPRs_to_invalidate + + ; Flush level 1: set MSSCR0[8] and spin until it clears + + dssall ; AltiVec needs to know + + sync + mfspr r8, msscr0 + oris r8, r8, 0x0080 + mtspr msscr0, r8 + sync +@loop_msscr0 + mfspr r8, msscr0 + sync + andis. r8, r8, 0x0080 + bne+ @loop_msscr0 + + + ; Flush level 2: set L2CR[4] and spin until it clears + + mfspr r8, l2cr + ori r8, r8, 0x0800 + mtspr l2cr, r8 + sync +@loop_l2cr + mfspr r8, l2cr + sync + andi. r8, r8, 0x0800 + bne+ @loop_l2cr + + + ; Jump back up to main code path to return + + b @return + + + +; Called when we cop a machine check with the "L1 data cache error" +; flag set in SRR1, followed by an interrupt return. Same trick as +; above. + +; CLOB r8, cr + +FlushL1CacheUsingMSSCR0 + + ; Return if MSSCR0 unavailable + + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + mtcr r8 + bclr BO_IF_NOT, 31-NKProcessorInfo.hasMSSregs + + + ; Flush level 1: set MSSCR0[8] and spin until it clears + + dssall ; AltiVec needs to know + + sync + mfspr r8, msscr0 + oris r8, r8, 0x0080 + mtspr msscr0, r8 + sync +@loop_msscr0 + mfspr r8, msscr0 + sync + andis. r8, r8, 0x0080 + bne+ @loop_msscr0 + + blr diff --git a/NanoKernel/NKCacheCalls.s b/NanoKernel/NKCacheCalls.s deleted file mode 100644 index f28095d..0000000 --- a/NanoKernel/NKCacheCalls.s +++ /dev/null @@ -1,300 +0,0 @@ -kcCacheDispatch ; OUTSIDE REFERER - stw r21, 0x01ac(r6) - stw r22, 0x01b4(r6) - stw r23, 0x01bc(r6) - clrlwi r8, r3, 0x10 - cmplwi r8, 0x02 - bgt- kcCacheDispatch_0x4c - lwz r8, 0x0f68(r1) - andi. r8, r8, 0x01 - beq- kcCacheDispatch_0x178 - rlwinm. r9, r3, 0, 2, 2 - bnel- kcCacheDispatch_0x1e4 - srwi r8, r3, 30 - cmpwi r8, 0x03 - beq- kcCacheDispatch_0xd8 - clrlwi r8, r3, 0x10 - cmplwi r8, 0x01 - beq- kcCacheDispatch_0x58 - cmplwi r8, 0x02 - beq- kcCacheDispatch_0xb8 - -kcCacheDispatch_0x4c - lis r3, -0x01 - ori r3, r3, 0xfffe - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0x58 - rlwinm. r9, r3, 0, 1, 1 - bne- kcCacheDispatch_0x74 - rlwinm. r9, r3, 0, 0, 0 - bne- kcCacheDispatch_0x98 - rlwinm. r9, r3, 0, 3, 3 - bl kcCacheDispatch_0x258 - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0x74 - bl kcCacheDispatch_0x258 - rlwinm r22, r3, 0, 4, 5 - srwi r22, r22, 12 - mfspr r21, hid0 - andc r21, r21, r22 - sync - mtspr hid0, r21 - li r3, 0x00 - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0x98 - rlwinm r22, r3, 0, 4, 5 - srwi r22, r22, 12 - mfspr r21, hid0 - or r21, r21, r22 - sync - mtspr hid0, r21 - li r3, 0x00 - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0xb8 - rlwinm. r9, r3, 0, 1, 1 - bne- kcCacheDispatch_0x180 - rlwinm. r9, r3, 0, 0, 0 - bne- kcCacheDispatch_0xe8 - rlwinm. r9, r3, 0, 3, 3 - bne- kcCacheDispatch_0xe4 - rlwinm. r9, r3, 0, 2, 2 - bne- kcCacheDispatch_0x1c4 - -kcCacheDispatch_0xd8 - lis r3, -0x01 - ori r3, r3, 0xfffc - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0xe4 - bl kcCacheDispatch_0x180 - -kcCacheDispatch_0xe8 - mfspr r21, l2cr - sync - andis. r21, r21, 0x8000 - bne- kcCacheDispatch_0x1c4 - lwz r8, 0x0f54(r1) - and. r8, r8, r8 - beq- kcCacheDispatch_0x178 - mfspr r21, hid0 - rlwinm r8, r21, 0, 12, 10 - mtspr hid0, r8 - sync - addi r8, r1, -0x4d0 - lwz r8, 0x0050(r8) - and. r8, r8, r8 - beq- kcCacheDispatch_0x1c4 - sync - lis r9, 0x20 - or r8, r8, r9 - mtspr l2cr, r8 - sync - -kcCacheDispatch_0x138 - mfspr r8, l2cr - sync - andi. r9, r8, 0x01 - bne+ kcCacheDispatch_0x138 - lis r9, 0x20 - andc r8, r8, r9 - mtspr l2cr, r8 - sync - lis r9, -0x8000 - or r8, r8, r9 - mtspr l2cr, r8 - sync - mtspr hid0, r21 - sync - li r3, 0x00 - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0x178 - li r3, -0x02 - b kcCacheDispatch_0x1c4 - -kcCacheDispatch_0x180 - mfspr r22, l2cr - sync - andis. r22, r22, 0x8000 - beq- kcCacheDispatch_0x1c4 - bl kcCacheDispatch_0x258 - mfspr r22, l2cr - sync - clrlwi r22, r22, 0x01 - mtspr l2cr, r22 - sync - addi r8, r1, -0x4d0 - stw r22, 0x0050(r8) - sync - rlwinm r22, r22, 0, 7, 3 - oris r22, r22, 0x10 - mtspr l2cr, r22 - sync - -kcCacheDispatch_0x1c4 - ori r23, r23, 0xffff - oris r3, r3, 0xffff - and r3, r3, r23 - -kcCacheDispatch_0x1d0 - lwz r21, 0x01ac(r6) - lwz r22, 0x01b4(r6) - lwz r23, 0x01bc(r6) - sync - b IntReturn - -kcCacheDispatch_0x1e4 - clrlwi r8, r3, 0x10 - cmplwi r8, 0x01 - beq- kcCacheDispatch_0x204 - cmplwi r8, 0x02 - beq- kcCacheDispatch_0x218 - lis r3, -0x01 - ori r3, r3, 0xfffb - b kcCacheDispatch_0x1d0 - -kcCacheDispatch_0x204 - mfspr r21, hid0 - rlwinm. r21, r21, 12, 4, 5 - beq- kcCacheDispatch_0x24c - oris r23, r21, 0x8000 - blr - -kcCacheDispatch_0x218 - lwz r8, 0x0f54(r1) - and. r8, r8, r8 - beq+ kcCacheDispatch_0x178 - mfspr r21, hid0 - rlwinm r21, r21, 12, 4, 5 - mfspr r22, l2cr - rlwinm r22, r22, 5, 4, 4 - andc r21, r21, r22 - mfspr r22, l2cr - andis. r22, r22, 0x8000 - beq- kcCacheDispatch_0x24c - or r23, r21, r22 - blr - -kcCacheDispatch_0x24c - lis r23, 0x4000 - ori r23, r23, 0x00 - blr - -kcCacheDispatch_0x258 ; OUTSIDE REFERER - mfctr r8 - stw r25, 0x01cc(r6) - stw r24, 0x01c4(r6) - stw r8, 0x00f4(r6) - lhz r25, 0x0f44(r1) - and. r25, r25, r25 - cntlzw r8, r25 - beq- kcCacheDispatch_0x338 - subfic r9, r8, 0x1f - lwz r8, 0x0f34(r1) - and. r8, r8, r8 - beq- kcCacheDispatch_0x338 - lwz r24, 0x0f68(r1) - mtcr r24 - bso- cr6, kcCacheDispatch_0x350 - bne- cr7, kcCacheDispatch_0x2a4 - slwi r24, r8, 1 - add r8, r8, r24 - srwi r8, r8, 1 - -kcCacheDispatch_0x2a4 - srw r8, r8, r9 - mtctr r8 - lwz r8, 0x0630(r1) - lwz r9, 0x0028(r8) - add r8, r8, r9 - -kcCacheDispatch_0x2b8 - lwzux r9, r8, r25 - bdnz+ kcCacheDispatch_0x2b8 - lwz r24, 0x0f68(r1) - andi. r24, r24, 0x01 - beq- kcCacheDispatch_0x338 - mfspr r24, l2cr - andis. r24, r24, 0x8000 - beq- kcCacheDispatch_0x338 - lhz r25, 0x0f60(r1) - and. r25, r25, r25 - cntlzw r8, r25 - beq- kcCacheDispatch_0x338 - subfic r9, r8, 0x1f - lwz r8, 0x0f54(r1) - and. r8, r8, r8 - beq- kcCacheDispatch_0x338 - srw r8, r8, r9 - mtctr r8 - mfspr r24, l2cr - oris r24, r24, 0x40 - mtspr l2cr, r24 - isync - lwz r8, 0x0630(r1) - lwz r9, 0x0028(r8) - add r8, r8, r9 - addis r8, r8, 0x19 - neg r25, r25 - -kcCacheDispatch_0x324 - lwzux r9, r8, r25 - bdnz+ kcCacheDispatch_0x324 - rlwinm r24, r24, 0, 10, 8 - mtspr l2cr, r24 - isync - -kcCacheDispatch_0x338 - lwz r8, 0x00f4(r6) - lwz r25, 0x01cc(r6) - lwz r24, 0x01c4(r6) - sync - mtctr r8 - blr - -kcCacheDispatch_0x350 - dssall - sync - mfspr r8, 1014 - oris r8, r8, 0x80 - mtspr 1014, r8 - sync - -kcCacheDispatch_0x368 - mfspr r8, 1014 - sync - andis. r8, r8, 0x80 - bne+ kcCacheDispatch_0x368 - mfspr r8, l2cr - ori r8, r8, 0x800 - mtspr l2cr, r8 - sync - -kcCacheDispatch_0x388 - mfspr r8, l2cr - sync - andi. r8, r8, 0x800 - bne+ kcCacheDispatch_0x388 - b kcCacheDispatch_0x338 - -kcCacheDispatch_0x39c ; OUTSIDE REFERER - lwz r8, 0x0f68(r1) - mtcr r8 - bnslr- cr6 - dssall - sync - mfspr r8, 1014 - oris r8, r8, 0x80 - mtspr 1014, r8 - sync - -kcCacheDispatch_0x3c0 - mfspr r8, 1014 - sync - andis. r8, r8, 0x80 - bne+ kcCacheDispatch_0x3c0 - blr diff --git a/NanoKernel/NKEquates.s b/NanoKernel/NKEquates.s index f790b11..99c4d0b 100644 --- a/NanoKernel/NKEquates.s +++ b/NanoKernel/NKEquates.s @@ -63,5 +63,5 @@ kSIGP6 equ 6 ; r4 = target CPU idx? kSIGP7 equ 7 ; r4 = target CPU idx? kSynchClock equ 8 ; r4 = target CPU idx, kSIGP9 equ 9 ; no args? -kSIGPGetTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name +kGetProcessorTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name kSIGP17 equ 17 ; r4 = target CPU idx? diff --git a/NanoKernel/NKInit.s b/NanoKernel/NKInit.s index 0dff14f..6b9f410 100644 --- a/NanoKernel/NKInit.s +++ b/NanoKernel/NKInit.s @@ -541,12 +541,9 @@ InitHighLevel -; Fill Indigo (PSA). All panics, except for IntIndigo in: -; - SystemResetVector -; - ExternalIntVector -; - DecrementerVector +; For the PowerDispatch selector that governs idle modes - bl FillIndigo + bl InitIdleVecTable @@ -1138,7 +1135,7 @@ SetProcessorFlags stw r8, Task.Name(r31) li r8, 2 - stb r8, Task.MysteryByte1(r31) + stb r8, Task.State(r31) lisori r8, 0x30028 ; (Z>>Task.kFlag14) | (Z>>Task.kFlagBlue) | (Z>>Task.kFlag26) | (Z>>Task.kFlag28) stw r8, Task.Flags(r31) diff --git a/NanoKernel/NKInterrupts.s b/NanoKernel/NKInterrupts.s index eddb735..7e62eed 100644 --- a/NanoKernel/NKInterrupts.s +++ b/NanoKernel/NKInterrupts.s @@ -1302,11 +1302,13 @@ IntMachineCheck ; OUTSIDE REFERER _log '^n' rlwinm. r8, r11, 0, 2, 2 - beq- IntMachineCheck_0xa4 - bl kcCacheDispatch_0x39c + beq- @not_L1_data_cache_error + +;L1 data cache error + bl FlushL1CacheUsingMSSCR0 b IntReturn -IntMachineCheck_0xa4 +@not_L1_data_cache_error li r8, 0x07 b major_0x02980_0x134 diff --git a/NanoKernel/NKMacros.s b/NanoKernel/NKMacros.s index dc4630b..d5f575f 100644 --- a/NanoKernel/NKMacros.s +++ b/NanoKernel/NKMacros.s @@ -230,3 +230,50 @@ HalfLoadedReg set (®) ENDM + + MACRO + _RegRangeToContextBlock &first, &last + + stw &first, $104+8*(&first)(r6) + + IF &first != &last + _RegRangeToContextBlock &first+1, &last + ENDIF + + ENDM + + + MACRO + _RegRangeFromContextBlock &first, &last + + lwz &first, $104+8*(&first)(r6) + + IF &first != &last + _RegRangeFromContextBlock &first+1, &last + ENDIF + + ENDM + + + MACRO + _FloatRangeToContextBlock &first, &last + + stfd &first, ContextBlock.FloatRegisters+8*(&first)(r6) + + IF &first != &last + _FloatRangeToContextBlock &first+1, &last + ENDIF + + ENDM + + + MACRO + _FloatRangeFromContextBlock &first, &last + + lfd &first, ContextBlock.FloatRegisters+8*(&first)(r6) + + IF &first != &last + _FloatRangeFromContextBlock &first+1, &last + ENDIF + + ENDM diff --git a/NanoKernel/NKPowerCalls.s b/NanoKernel/NKPowerCalls.s index 40228b6..9384ee7 100644 --- a/NanoKernel/NKPowerCalls.s +++ b/NanoKernel/NKPowerCalls.s @@ -1,19 +1,28 @@ -; FillIndigo +#### ## ## #### ######## ## ## ######## ###### ######## ######## ## + ## ### ## ## ## ## ## ## ## ## ## ## ## ## + ## #### ## ## ## ## ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ## ###### ## ## ######## ## + ## ## #### ## ## ## ## ## ## ## ## ## ## + ## ## ### ## ## ## ## ## ## ## ## ## ## ## +#### ## ## #### ## ### ######## ###### ## ######## ######## -; Xrefs: -; setup +; When we are asked via a PowerDispatch call to put a CPU into a non-full- +; on pwrmgt state, we will point its SPRG3 to this table. Any of these +; three interrupts will return the CPU to full-on mode, and we will return +; from the PowerDispatch call. Called at NK init time. align kIntAlign -FillIndigo ; EXPORTED +InitIdleVecTable + mflr r9 llabel r23, panic add r23, r23, r25 - addi r8, r1, PSA.IndigoVecBase - li r22, 192 ;VecTable.Size + addi r8, r1, PSA.IdleVecBase + li r22, VecTable.Size bl wordfill mtlr r9 - llabel r23, IntIndigo + llabel r23, IntReturnToFullOn add r23, r23, r25 stw r23, VecTable.SystemResetVector(r8) stw r23, VecTable.ExternalIntVector(r8) @@ -21,559 +30,698 @@ FillIndigo ; EXPORTED blr +######## #### ###### ######## ### ######## ###### ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ###### ######## ## ## ## ## ######### +## ## ## ## ## ######### ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## +######## #### ###### ## ## ## ## ###### ## ## -; kcPowerDispatch +; Called using 68k `$FE0F` or PPC `twi ... 5` -; NB: I was probably wrong about this. -; Contains a (very rare) mtsprg0 instruction. - -; Xrefs: -; "sup" +; ARG selector r3 (0-11), ... align kIntAlign -kcPowerDispatch ; EXPORTED ; OUTSIDE REFERER +kcPowerDispatch + mtcr r7 - lwz r4, 0x0670(r1) - cmplwi cr7, r3, 0x0b + lwz r4, KDP.TestIntMaskInit(r1) + cmplwi cr7, r3, 11 mr r9, r13 - blt- cr2, kcPowerDispatch_0x18 - lwz r9, -0x0440(r1) + bc BO_IF, 8, @use_provided_mcr + lwz r9, PSA.MCR(r1) +@use_provided_mcr -kcPowerDispatch_0x18 and. r8, r4, r9 - bgt- cr7, major_0x09e28_0x34 - bne- major_0x09e28_0x2c - cmplwi cr7, r3, 0x0b - beq- cr7, major_0x0a600_0x1c - cmplwi cr7, r3, 0x08 - beq- cr7, major_0x09e28_0x3c - cmplwi cr7, r3, 0x09 - beq- cr7, major_0x0a600_0x10 - stw r26, 0x01d4(r6) - stw r27, 0x01dc(r6) - stw r28, 0x01e4(r6) - stw r29, 0x01ec(r6) - stw r30, 0x01f4(r6) - stw r31, 0x01fc(r6) - mfsprg r31, 3 - addi r8, r1, -0x810 + bgt- cr7, PowerEarlyReturnError ; invalid selector + bne- PowerEarlyReturnSuccess + + cmplwi cr7, r3, 11 + beq- cr7, PwrInfiniteLoop + + cmplwi cr7, r3, 8 + beq- cr7, PwrSuspendSystem + + cmplwi cr7, r3, 9 + beq- cr7, PwrSetICTC + + ; Fall through to 0-7: PwrIdle + + + + ##### ######## #### ######## ## ######## + ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## +## ## ####### ## ## ## ## ## ###### +## ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ## + ##### ## #### ######## ######## ######## + +; Selector 0-7 + +; Set the CPU static pwrmgt state to doze, idle or sleep, then return to +; full-on when we get an interrupt. + +; ARG r3 & 1: which of the two pre-programmed pwrmgt states to invoke (see NKProcFlagsTbl.s) +; r3 & 4: whether to flush L1 and L2 caches + +; Different 603+ chips have static power management states named "doze", +; "nap" and "sleep". A state is selected by setting the corresponding bit +; in HID0. The state is then invoked by setting MSR[POW]. The state is +; ended by a decrementer interrupt (doze/nap only) or external interrupt. +; This is a short term CPU-specific state, *not* system-wide "sleep". + +; Because the NK timer code sets the decrementer, we can be sure that we +; will not miss a timer firing. + +PwrIdle + + ; Get us some breathing room + + _RegRangeToContextBlock r26, r31 + + + ; Activate the interrupt table that will rouse the CPU + + mfsprg r31, 3 ; will restore r31 => SPRG3 after state exited + addi r8, r1, PSA.IdleVecBase mtsprg 3, r8 - rlwinm r26, r3, 0, 29, 29 - clrlwi r3, r3, 0x1e - lbz r8, 0x06b8(r1) - slwi r3, r3, 1 - addi r3, r3, 0x1a - rlwnm r3, r8, r3, 0x1e, 0x1f - cmpwi r3, 0x00 - beq- major_0x09e28_0x24 - lbz r9, 0x06b9(r1) - cmpwi r9, 0x00 - beq- kcPowerDispatch_0xb0 - mfspr r27, hid0 + + + ; Save argument & 4 (run-cache-code flag) + + rlwinm r26, r3, 0, 29, 29 + + + ; Choose from the NK's two pre-programmed pwrmgt states for this CPU. + ; Fail if we find zero (e.g. on the 601). + + ; arg pwrmgt state selector => r3 + ; r3 & 1 0=fail 1=DOZE 2=NAP 3=SLEEP + ; ------ --------------------------- + ; 0 (CpuSpecificByte1 >> 6) & 3 + ; 1 (CpuSpecificByte1 >> 4) & 3 + + clrlwi r3, r3, 30 + lbz r8, KDP.CpuSpecificByte1(r1) + slwi r3, r3, 1 + addi r3, r3, 26 + rlwnm r3, r8, r3, 30, 31 + cmpwi r3, 0 + beq- PowerEarlyRestoreReturnError + + + ; Depending on pre-programmed flags, set: + ; HID0[NHR] ("not hard reset" flag) + ; HID0[ptrmgt state selected above] + + lbz r9, KDP.CpuSpecificByte2(r1) + cmpwi r9, 0 + beq- @set_neither + + mfspr r27, hid0 ; will restore r27 => HID0 when system wakes below mr r8, r27 - cmpwi r9, 0x01 - beq- kcPowerDispatch_0xa8 - oris r9, r3, 0x100 - srw r9, r9, r9 - rlwimi r8, r9, 0, 8, 10 + cmpwi r9, 1 + beq- @set_only_nhr -kcPowerDispatch_0xa8 - oris r8, r8, 0x01 + oris r9, r3, 0x0100 ; set bit 7 + srw r9, r9, r9 ; shift right by 0-3 + rlwimi r8, r9, 0, 8, 10 ; keep bits 8/9/10 +@set_only_nhr + + oris r8, r8, 1 ; also set NHR mtspr hid0, r8 +@set_neither + + + ; Flush L1 and L2 caches if argument & 4 + + cmplwi r26, 4 + beql- FlushCaches + + + ; Set MSR bits to enter the selected pwrmgt state -kcPowerDispatch_0xb0 - cmplwi r26, 0x04 - beql- kcCacheDispatch_0x258 mfmsr r8 - ori r8, r8, 0x8002 - cmplwi r3, 0x00 - beq- kcPowerDispatch_0xcc - oris r8, r8, 0x04 - -kcPowerDispatch_0xcc - sync + ori r8, r8, 0x8002 ; Always set MSR[EE] and MSR[RI] so we can wake! + cmplwi r3, 0 ; If using HID0[pwrmgt state], set MSR[POW] so it takes effect + beq- @no_pow + oris r8, r8, 4 +@no_pow + sync ; Apply MSR! mtmsr r8 isync -kcPowerDispatch_0xd8 - b kcPowerDispatch_0xd8 + + ; Loop while the state takes effect, then jump 4 bytes forward when we cop an interrupt + + b * +IntReturnToFullOn + ; Restore HID0 from r27, assuming that we mangled it -; IntIndigo - -; Odd that this is unaligned - -IntIndigo - lbz r8, 0x06b9(r1) - cmpwi r8, 0x00 - beq- IntIndigo_0x10 + lbz r8, KDP.CpuSpecificByte2(r1) + cmpwi r8, 0 + beq- @hid_was_not_changed mtspr hid0, r27 +@hid_was_not_changed + + + ; Restore registers and return successfully to caller. + ; Not sure about the decrementer stuff. -IntIndigo_0x10 mfsprg r1, 2 mtlr r1 mfsprg r1, 1 - lis r9, 0x7fff + + lis r9, 0x7fff mfspr r8, dec mtspr dec, r9 mtspr dec, r8 + li r3, 0 +PowerCallRestoreReturn -; major_0x09e28 + mtsprg 3, r31 ; saved SPRG3 above -; Xrefs: -; kcPowerDispatch -; IntIndigo + _RegRangeFromContextBlock r26, r31 - li r3, 0x00 - -major_0x09e28_0x4 - mtsprg 3, r31 - lwz r26, 0x01d4(r6) - lwz r27, 0x01dc(r6) - lwz r28, 0x01e4(r6) - lwz r29, 0x01ec(r6) - lwz r30, 0x01f4(r6) - lwz r31, 0x01fc(r6) b IntReturn -major_0x09e28_0x24 ; OUTSIDE REFERER + + +; Return islands for other calls + +PowerEarlyRestoreReturnError li r3, -0x7267 - b major_0x09e28_0x4 + b PowerCallRestoreReturn -major_0x09e28_0x2c ; OUTSIDE REFERER - li r3, 0x00 +PowerEarlyReturnSuccess + li r3, 0 b IntReturn -major_0x09e28_0x34 ; OUTSIDE REFERER - li r3, -0x01 +PowerEarlyReturnError + li r3, -1 b IntReturn -major_0x09e28_0x3c ; OUTSIDE REFERER + + + ####### ###### ## ## ###### ######## ######## ## ## ######## +## ## ## ## ## ## ## ## ## ## ## ### ## ## ## +## ## ## ## ## ## ## ## ## #### ## ## ## + ####### ###### ## ## ###### ######## ###### ## ## ## ## ## +## ## ## ## ## ## ## ## ## #### ## ## +## ## ## ## ## ## ## ## ## ## ## ### ## ## + ####### ###### ####### ###### ## ######## ## ## ######## + +; Selector 8 + +; Put this, the last scheduled CPU, into SLEEP mode. +; Save state. Call ActuallySuspend. Restore state. Return. + +PwrSuspendSystem + + ; Cannot sleep if multiple CPUs are scheduled + mfsprg r9, 0 - lwz r8, -0x0338(r9) - lwz r9, 0x0024(r8) - cmpwi r9, 0x01 + lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) + lwz r9, CoherenceGroup.ScheduledCpuCount(r8) + cmpwi r9, 1 li r3, -0x7267 bgt+ IntReturn - stw r26, 0x01d4(r6) - stw r27, 0x01dc(r6) - stw r28, 0x01e4(r6) - stw r29, 0x01ec(r6) - stw r30, 0x01f4(r6) - stw r31, 0x01fc(r6) - bl kcCacheDispatch_0x258 + + + ; Some breathing room + + _RegRangeToContextBlock r26, r31 + + + bl FlushCaches + + + ; Disable both L1 caches (via HID0) + mfspr r9, hid0 - rlwinm r9, r9, 0, 18, 16 - rlwinm r9, r9, 0, 17, 15 + rlwinm r9, r9, 0, 18, 16 ; unset HID0[DCE] (data cache enable) + rlwinm r9, r9, 0, 17, 15 ; unset HID0[ICE] (inst cache enable) mtspr hid0, r9 sync isync - lwz r26, 0x0f68(r1) - andi. r26, r26, 0x01 - beq- major_0x09e28_0xb0 + + + ; Disable L2 cache (via L2CR, if present) + + lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + andi. r26, r26, 1 << NKProcessorInfo.hasL2CR + beq- @no_need_to_deactivate_l2 mfspr r9, l2cr - clrlwi r9, r9, 0x01 + clrlwi r9, r9, 1 ; unset L2CR[L2E] mtspr l2cr, r9 sync isync - addi r8, r1, -0x4d0 - stw r9, 0x0050(r8) + addi r8, r1, PSA.ProcessorState + stw r9, NKProcessorState.saveL2CR(r8) +@no_need_to_deactivate_l2 -major_0x09e28_0xb0 - stw r7, 0x0000(r6) - stw r2, 0x0114(r6) - stw r3, 0x011c(r6) - stw r4, 0x0124(r6) - stw r5, 0x012c(r6) - 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 r13, 0x00dc(r6) - andi. r8, r11, 0x2000 - beq- major_0x09e28_0x198 + + ; Save some GPRs + + stw r7, ContextBlock.Flags(r6) + _RegRangeToContextBlock r2, r5 + _RegRangeToContextBlock r14, r25 + stw r13, ContextBlock.CR(r6) + + + ; Save floats + + andi. r8, r11, 0x2000 ; MSR[FP] + beq- @no_save_float mfmsr r8 - ori r8, r8, 0x2000 + ori r8, r8, 0x2000 ; ensure that MSR bit is set? mtmsr r8 isync - stfd f0, 0x0200(r6) - stfd f1, 0x0208(r6) - stfd f2, 0x0210(r6) - stfd f3, 0x0218(r6) - stfd f4, 0x0220(r6) - stfd f5, 0x0228(r6) - stfd f6, 0x0230(r6) - stfd f7, 0x0238(r6) - stfd f8, 0x0240(r6) - stfd f9, 0x0248(r6) - stfd f10, 0x0250(r6) - stfd f11, 0x0258(r6) - stfd f12, 0x0260(r6) - stfd f13, 0x0268(r6) - stfd f14, 0x0270(r6) - stfd f15, 0x0278(r6) - stfd f16, 0x0280(r6) + _FloatRangeToContextBlock f0, f16 mffs f0 - stfd f17, 0x0288(r6) - stfd f18, 0x0290(r6) - stfd f19, 0x0298(r6) - stfd f20, 0x02a0(r6) - stfd f21, 0x02a8(r6) - stfd f22, 0x02b0(r6) - stfd f23, 0x02b8(r6) - stfd f24, 0x02c0(r6) - stfd f25, 0x02c8(r6) - stfd f26, 0x02d0(r6) - stfd f27, 0x02d8(r6) - stfd f28, 0x02e0(r6) - stfd f29, 0x02e8(r6) - stfd f30, 0x02f0(r6) - stfd f31, 0x02f8(r6) - stfd f0, 0x00e0(r6) + _FloatRangeToContextBlock f17, f31 + stfd f0, ContextBlock.PageInSystemHeap(r6) ; ??? +@no_save_float + + + ; Save misc SPRs -major_0x09e28_0x198 mfxer r9 - addi r16, r1, -0x4d0 - stw r9, 0x00d4(r6) + addi r16, r1, PSA.ProcessorState + stw r9, ContextBlock.XER(r6) mfctr r9 - stw r9, 0x00f0(r6) - stw r12, 0x00e8(r6) - stw r10, 0x0054(r16) - stw r11, 0x0058(r16) + stw r9, ContextBlock.CTR(r6) + stw r12, ContextBlock.FE000000(r6) + stw r10, NKProcessorState.saveSRR0(r16) + stw r11, NKProcessorState.saveSRR1(r16) mfspr r9, hid0 - stw r9, 0x0064(r16) + stw r9, NKProcessorState.saveHID0(r16) -major_0x09e28_0x1c0 + + ; Save timebase + +@tb_retry mftbu r9 - stw r9, 0x005c(r16) + stw r9, NKProcessorState.saveTBU(r16) mftb r9 - stw r9, 0x0060(r16) + stw r9, NKProcessorState.saveTBL(r16) mftbu r8 - lwz r9, 0x005c(r16) + lwz r9, NKProcessorState.saveTBU(r16) cmpw r8, r9 - bne+ major_0x09e28_0x1c0 - mfmsr r9 - stw r9, 0x006c(r16) - mfspr r9, sdr1 - stw r9, 0x0070(r16) - mfspr r9, dbat0u - stw r9, 0x0000(r16) - mfspr r9, dbat0l - stw r9, 0x0004(r16) - mfspr r9, dbat1u - stw r9, 0x0008(r16) - mfspr r9, dbat1l - stw r9, 0x000c(r16) - mfspr r9, dbat2u - stw r9, 0x0010(r16) - mfspr r9, dbat2l - stw r9, 0x0014(r16) - mfspr r9, dbat3u - stw r9, 0x0018(r16) - mfspr r9, dbat3l - stw r9, 0x001c(r16) - mfspr r9, ibat0u - stw r9, 0x0020(r16) - mfspr r9, ibat0l - stw r9, 0x0024(r16) - mfspr r9, ibat1u - stw r9, 0x0028(r16) - mfspr r9, ibat1l - stw r9, 0x002c(r16) - mfspr r9, ibat2u - stw r9, 0x0030(r16) - mfspr r9, ibat2l - stw r9, 0x0034(r16) - mfspr r9, ibat3u - stw r9, 0x0038(r16) - mfspr r9, ibat3l - stw r9, 0x003c(r16) - mfsprg r9, 0 - stw r9, 0x0040(r16) - mfsprg r9, 1 - stw r9, 0x0044(r16) - mfsprg r9, 2 - stw r9, 0x0048(r16) - mfsprg r9, 3 - stw r9, 0x004c(r16) - stw r6, 0x007c(r16) - bl major_0x09e28_0x59c - lwz r1, 0x0004(r1) - addi r16, r1, -0x4d0 - lis r8, 0x100 - ori r8, r8, 0x00 - lis r9, 0x00 + bne+ @tb_retry -major_0x09e28_0x2ac - addis r9, r9, -0x1000 + + ; Save MSR + + mfmsr r9 + stw r9, NKProcessorState.saveMSR(r16) + + + ; Save SDR1 + + mfspr r9, sdr1 + stw r9, NKProcessorState.saveSDR1(r16) + + + ; Save BAT registers + + mfspr r9, dbat0u + stw r9, NKProcessorState.saveDBAT0u(r16) + mfspr r9, dbat0l + stw r9, NKProcessorState.saveDBAT0l(r16) + mfspr r9, dbat1u + stw r9, NKProcessorState.saveDBAT1u(r16) + mfspr r9, dbat1l + stw r9, NKProcessorState.saveDBAT1l(r16) + mfspr r9, dbat2u + stw r9, NKProcessorState.saveDBAT2u(r16) + mfspr r9, dbat2l + stw r9, NKProcessorState.saveDBAT2l(r16) + mfspr r9, dbat3u + stw r9, NKProcessorState.saveDBAT3u(r16) + mfspr r9, dbat3l + stw r9, NKProcessorState.saveDBAT3l(r16) + mfspr r9, ibat0u + stw r9, NKProcessorState.saveIBAT0u(r16) + mfspr r9, ibat0l + stw r9, NKProcessorState.saveIBAT0l(r16) + mfspr r9, ibat1u + stw r9, NKProcessorState.saveIBAT1u(r16) + mfspr r9, ibat1l + stw r9, NKProcessorState.saveIBAT1l(r16) + mfspr r9, ibat2u + stw r9, NKProcessorState.saveIBAT2u(r16) + mfspr r9, ibat2l + stw r9, NKProcessorState.saveIBAT2l(r16) + mfspr r9, ibat3u + stw r9, NKProcessorState.saveIBAT3u(r16) + mfspr r9, ibat3l + stw r9, NKProcessorState.saveIBAT3l(r16) + + + ; Save SPRGs + + mfsprg r9, 0 + stw r9, NKProcessorState.saveSPRG0(r16) + mfsprg r9, 1 + stw r9, NKProcessorState.saveSPRG1(r16) + mfsprg r9, 2 + stw r9, NKProcessorState.saveSPRG2(r16) + mfsprg r9, 3 + stw r9, NKProcessorState.saveSPRG3(r16) + + + ; Save ContextBlock ptr + + stw r6, NKProcessorState.saveContextPtr(r16) + + + ; Do the thing. The BL gives us a useful restore address. + + bl ActuallySuspend + + + lwz r1, EWA.r1(r1) + addi r16, r1, PSA.ProcessorState + + + ; Do something evil to the segment registers? + + lisori r8, 0x1000000 + lis r9, 0 +@srin_loop + subis r9, r9, 0x1000 addis r8, r8, -0x10 mr. r9, r9 mtsrin r8, r9 - bne+ major_0x09e28_0x2ac + bne+ @srin_loop isync + + + ; Reactivate L1 cache + mfspr r9, hid0 - li r8, 0x800 - ori r8, r8, 0x200 + li r8, 0x800 ; HID0[ICFI] invalidate icache + ori r8, r8, 0x200 ; HID0[SPD] disable spec cache accesses or r9, r9, r8 mtspr hid0, r9 isync - andc r9, r9, r8 + andc r9, r9, r8 ; now undo that? mtspr hid0, r9 isync - ori r9, r9, 0x8000 - ori r9, r9, 0x4000 + ori r9, r9, 0x8000 ; set HID0[ICE] + ori r9, r9, 0x4000 ; set HID0[DCE] mtspr hid0, r9 isync - lwz r26, 0x0f68(r1) - andi. r26, r26, 0x01 - beq- major_0x09e28_0x38c - lwz r8, 0x0f54(r1) + + + ; Reactivate L2 cache + + lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) + andi. r26, r26, 1 << NKProcessorInfo.hasL2CR + beq- @no_need_to_reactivate_l2 + lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) mr. r8, r8 - beq- major_0x09e28_0x38c + beq- @no_need_to_reactivate_l2 + mfspr r9, hid0 rlwinm r9, r9, 0, 12, 10 mtspr hid0, r9 isync - lwz r9, 0x0050(r16) + + lwz r9, NKProcessorState.saveL2CR(r16) mtspr l2cr, r9 sync isync - lis r8, 0x20 + lis r8, 0x20 ; set L2CR[L2I] to invalidate L2 cache or r8, r9, r8 mtspr l2cr, r8 sync isync -major_0x09e28_0x344 + ; spin while bottom bit (reserved) is set??? +@l2_reactivate_loop mfspr r8, l2cr rlwinm. r8, r8, 31, 0, 0 - bne+ major_0x09e28_0x344 + bne+ @l2_reactivate_loop + + mfspr r8, l2cr - lis r9, -0x21 - ori r9, r9, 0xffff + lisori r9, 0xffdfffff ; unset bit 6 (reserved?) and r8, r8, r9 mtspr l2cr, r8 sync + + mfspr r8, hid0 - oris r8, r8, 0x10 + oris r8, r8, 0x0010 ; set HID0[HIGH_BAT_EN] (was HID0[DOZE]) mtspr hid0, r8 isync + + mfspr r8, l2cr - oris r8, r8, 0x8000 + oris r8, r8, 0x8000 ; set L2CR[L2E] mtspr l2cr, r8 sync isync +@no_need_to_reactivate_l2 -major_0x09e28_0x38c - lwz r6, 0x007c(r16) - lwz r7, 0x0000(r6) - lwz r13, 0x00dc(r6) - lwz r9, 0x00f0(r6) + + ; Still working on this... + + lwz r6, NKProcessorState.saveContextPtr(r16) + lwz r7, ContextBlock.Flags(r6) + lwz r13, ContextBlock.CR(r6) + lwz r9, ContextBlock.CTR(r6) mtctr r9 - lwz r12, 0x00e8(r6) - lwz r9, 0x00d4(r6) + lwz r12, ContextBlock.FE000000(r6) + lwz r9, ContextBlock.XER(r6) mtxer r9 - lwz r10, 0x0054(r16) - lwz r11, 0x0058(r16) - lwz r2, 0x0114(r6) - lwz r3, 0x011c(r6) - lwz r4, 0x0124(r6) - lwz r5, 0x012c(r6) - lwz r14, 0x0174(r6) - lwz r15, 0x017c(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) - andi. r8, r11, 0x2000 - beq- major_0x09e28_0x4a8 + lwz r10, NKProcessorState.saveSRR0(r16) + lwz r11, NKProcessorState.saveSRR1(r16) + + + ; Load some GPRs + + _RegRangeFromContextBlock r2, r5 + _RegRangeFromContextBlock r14, r15 + _RegRangeFromContextBlock r17, r31 + + + ; Load floats + + andi. r8, r11, 0x2000 ; MSR[FP] + beq- @no_restore_float mfmsr r8 - ori r8, r8, 0x2000 + ori r8, r8, 0x2000 ; ensure that MSR bit is set? mtmsr r8 isync - lfd f31, 0x00e0(r6) - lfd f0, 0x0200(r6) - lfd f1, 0x0208(r6) - lfd f2, 0x0210(r6) - lfd f3, 0x0218(r6) - lfd f4, 0x0220(r6) - lfd f5, 0x0228(r6) - lfd f6, 0x0230(r6) - lfd f7, 0x0238(r6) - lfd f8, 0x0240(r6) - mtfsf 0xff, f31 - lfd f9, 0x0248(r6) - lfd f10, 0x0250(r6) - lfd f11, 0x0258(r6) - lfd f12, 0x0260(r6) - lfd f13, 0x0268(r6) - lfd f14, 0x0270(r6) - lfd f15, 0x0278(r6) - lfd f16, 0x0280(r6) - lfd f17, 0x0288(r6) - lfd f18, 0x0290(r6) - lfd f19, 0x0298(r6) - lfd f20, 0x02a0(r6) - lfd f21, 0x02a8(r6) - lfd f22, 0x02b0(r6) - lfd f23, 0x02b8(r6) - lfd f24, 0x02c0(r6) - lfd f25, 0x02c8(r6) - lfd f26, 0x02d0(r6) - lfd f27, 0x02d8(r6) - lfd f28, 0x02e0(r6) - lfd f29, 0x02e8(r6) - lfd f30, 0x02f0(r6) - lfd f31, 0x02f8(r6) + lfd f31, ContextBlock.PageInSystemHeap(r6) ; bit odd + _FloatRangeFromContextBlock f0, f8 + mtfsf 0xff, f31 + _FloatRangeFromContextBlock f9, f31 +@no_restore_float -major_0x09e28_0x4a8 - lwz r9, 0x0064(r16) + + ; Load HID0, plus ICE and DCE bits + + lwz r9, NKProcessorState.saveHID0(r16) ori r9, r9, 0x8000 ori r9, r9, 0x4000 mtspr hid0, r9 sync isync - lwz r9, 0x005c(r16) + + + ; Load timebase + + lwz r9, NKProcessorState.saveTBU(r16) mtspr tbu, r9 - lwz r9, 0x0060(r16) + lwz r9, NKProcessorState.saveTBL(r16) mtspr tbl, r9 - li r9, 0x01 + + + ; Set decrementer quite low? + + li r9, 1 mtspr dec, r9 - lwz r9, 0x006c(r16) + + + ; Load MSR + + lwz r9, NKProcessorState.saveMSR(r16) mtmsr r9 sync isync - lwz r9, 0x0070(r16) + + + ; Load SDR1 + + lwz r9, NKProcessorState.saveSDR1(r16) mtspr sdr1, r9 - lwz r9, 0x0040(r16) + + + ; Load SPRGs + + lwz r9, NKProcessorState.saveSPRG0(r16) mtsprg 0, r9 - lwz r9, 0x0044(r16) + lwz r9, NKProcessorState.saveSPRG1(r16) mtsprg 1, r9 - lwz r9, 0x0048(r16) + lwz r9, NKProcessorState.saveSPRG2(r16) mtsprg 2, r9 - lwz r9, 0x004c(r16) + lwz r9, NKProcessorState.saveSPRG3(r16) mtsprg 3, r9 - lwz r9, 0x0000(r16) + + + ; Load BAT registers + + lwz r9, NKProcessorState.saveDBAT0u(r16) mtspr dbat0u, r9 - lwz r9, 0x0004(r16) + lwz r9, NKProcessorState.saveDBAT0l(r16) mtspr dbat0l, r9 - lwz r9, 0x0008(r16) + lwz r9, NKProcessorState.saveDBAT1u(r16) mtspr dbat1u, r9 - lwz r9, 0x000c(r16) + lwz r9, NKProcessorState.saveDBAT1l(r16) mtspr dbat1l, r9 - lwz r9, 0x0010(r16) + lwz r9, NKProcessorState.saveDBAT2u(r16) mtspr dbat2u, r9 - lwz r9, 0x0014(r16) + lwz r9, NKProcessorState.saveDBAT2l(r16) mtspr dbat2l, r9 - lwz r9, 0x0018(r16) + lwz r9, NKProcessorState.saveDBAT3u(r16) mtspr dbat3u, r9 - lwz r9, 0x001c(r16) + lwz r9, NKProcessorState.saveDBAT3l(r16) mtspr dbat3l, r9 - lwz r9, 0x0020(r16) + lwz r9, NKProcessorState.saveIBAT0u(r16) mtspr ibat0u, r9 - lwz r9, 0x0024(r16) + lwz r9, NKProcessorState.saveIBAT0l(r16) mtspr ibat0l, r9 - lwz r9, 0x0028(r16) + lwz r9, NKProcessorState.saveIBAT1u(r16) mtspr ibat1u, r9 - lwz r9, 0x002c(r16) + lwz r9, NKProcessorState.saveIBAT1l(r16) mtspr ibat1l, r9 - lwz r9, 0x0030(r16) + lwz r9, NKProcessorState.saveIBAT2u(r16) mtspr ibat2u, r9 - lwz r9, 0x0034(r16) + lwz r9, NKProcessorState.saveIBAT2l(r16) mtspr ibat2l, r9 - lwz r9, 0x0038(r16) + lwz r9, NKProcessorState.saveIBAT3u(r16) mtspr ibat3u, r9 - lwz r9, 0x003c(r16) + lwz r9, NKProcessorState.saveIBAT3l(r16) mtspr ibat3l, r9 - lwz r16, 0x0184(r6) - li r3, 0x00 + + + ; And reclaim the register we were using for ProcessorState + + _RegRangeFromContextBlock r16, r16 + + + ; Hooray! We're back! + + li r3, 0 b IntReturn -major_0x09e28_0x59c + + + ### ###### ## ## ###### ######## ######## ## ## ######## ### + ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## +## ## ## ## ## ## ## ## #### ## ## ## ## +## ###### ## ## ###### ######## ###### ## ## ## ## ## ## +## ## ## ## ## ## ## ## #### ## ## ## + ## ## ## ## ## ## ## ## ## ## ### ## ## ## + ### ###### ####### ###### ## ######## ## ## ######## ### + +ActuallySuspend mflr r9 - stw r9, 0x0074(r16) - stw r1, 0x0078(r16) - addi r9, r16, 0x74 - li r0, 0x00 - stw r9, 0x0000(0) - lis r9, 0x4c61 - ori r9, r9, 0x7273 - stw r9, 0x0004(0) + stw r9, NKProcessorState.saveReturnAddr(r16) + stw r1, NKProcessorState.saveKernelDataPtr(r16) + addi r9, r16, NKProcessorState.saveKernelDataPtr - 4 ; so that 4(r9) goes to r1? + li r0, 0 + stw r9, 0(0) + lisori r9, 'Lars' + stw r9, 4(0) + + mfspr r9, hid0 - andis. r9, r9, 0x20 + andis. r9, r9, 0x0020 ; mask: only HID0[SLEEP] mtspr hid0, r9 + + mfmsr r8 - oris r8, r8, 0x04 + oris r8, r8, 0x0004 ; set MSR[POW] (but not yet) + + mfspr r9, hid0 - ori r9, r9, 0x8000 + ori r9, r9, 0x8000 ; set HID0[ICE] mtspr hid0, r9 - bl * + 4 - mflr r9 - addi r9, r9, major_0x0a600 - (* - 4) + + + ; Get address of this table => r9 + bl @l +@l mflr r9 + addi r9, r9, @table_of_sixteen_zeros - @l + + lisori r1, 0xcafebabe - b major_0x0a500 + b @evil_aligned_sleep_loop align 8 - - -; major_0x0a500 - -; Xrefs: -; major_0x09e28 - -major_0x0a500 ; OUTSIDE REFERER +@evil_aligned_sleep_loop sync - mtmsr r8 + mtmsr r8 ; sleep now isync - cmpwi r1, 0x00 - beq+ major_0x0a500 - lwz r0, 0x0000(r9) - andi. r1, r1, 0x00 - b major_0x0a500 + cmpwi r1, 0 + beq+ @evil_aligned_sleep_loop ; re-sleep until the world is sane? + lwz r0, 0(r9) + andi. r1, r1, 0 + b @evil_aligned_sleep_loop ; actually, there is no escape align 8 +@table_of_sixteen_zeros + dcb.b 16, 0 -; major_0x0a600 -; Xrefs: -; kcPowerDispatch + ####### ###### ######## ######## #### ###### ######## ###### +## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## + ######## ###### ###### ## ## ## ## ## + ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## + ####### ###### ######## ## #### ###### ## ###### -major_0x0a600 ; OUTSIDE REFERER - dc.l 0 - dc.l 0 - dc.l 0 - dc.l 0 +; Selector 9 + +; Set ICTC (Instruction Cache Throttling Control) register +; (used to reduce temp without adjusting clock) + +; ARG value r5 + +PwrSetICTC -major_0x0a600_0x10 ; OUTSIDE REFERER mtspr 1019, r5 - li r3, 0x00 + li r3, 0 b IntReturn -major_0x0a600_0x1c ; OUTSIDE REFERER - b major_0x0a600_0x1c + + + ## ## ## ####### ####### ######## + #### #### ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ######## + ## ## ## ## ## ## ## ## + ## ## ## ## ## ## ## ## + ###### ###### ######## ####### ####### ## + +; Selector 11 + +PwrInfiniteLoop + + b * diff --git a/NanoKernel/NKPrimaryIntHandlers.s b/NanoKernel/NKPrimaryIntHandlers.s index 020ff48..029d0cf 100644 --- a/NanoKernel/NKPrimaryIntHandlers.s +++ b/NanoKernel/NKPrimaryIntHandlers.s @@ -142,11 +142,11 @@ CommonPIHPath_0x14c _Lock PSA.SchLock, scratch1=r16, scratch2=r17 - lwz r30, -0x0440(r1) + lwz r30, PSA.MCR(r1) or r31, r31, r30 - stw r31, -0x0440(r1) + stw r31, PSA.MCR(r1) sth r28, -0x043c(r1) - lwz r31, -0x08f0(r1) + lwz r31, PSA.PA_BlueTask(r1) mfsprg r30, 0 lwz r28, 0x0064(r31) lbz r29, 0x0018(r31) diff --git a/NanoKernel/NKProcFlagsTbl.s b/NanoKernel/NKProcFlagsTbl.s index df6e201..e3c31f0 100644 --- a/NanoKernel/NKProcFlagsTbl.s +++ b/NanoKernel/NKProcFlagsTbl.s @@ -32,41 +32,51 @@ PflgTblCtr set PflgTblCtr + 1 with NKProcessorInfo - ; CpuSpecificByte - ; 1 2 ProcessorFlags CPU - ; ---- - ------------------------------------------------------------------------ ----------------------- - PflgTblEnt 0x03, 1, 0 ; 0**0 - PflgTblEnt 0x00, 0, 0 ; 0**1 = 601 - PflgTblEnt 0x03, 1, 0 ; 0**2 - PflgTblEnt 0x1b, 2, 0 ; 0**3 = 603 - PflgTblEnt 0x0a, 1, 0 ; 0**4 = 604 - PflgTblEnt 0x1b, 2, 0 ; 0**5 - PflgTblEnt 0x1b, 2, 0 ; 0**6 = 603e - PflgTblEnt 0x1b, 2, 0 ; 0**7 = 750FX - PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU ; 0**8 = 750 - PflgTblEnt 0x0a, 1, 0 ; 0**9 - PflgTblEnt 0x0a, 1, 0 ; 0**a - PflgTblEnt 0x03, 1, 0 ; 0**b - PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 0**c = 7400 - PflgTblEnt 0x0b, 2, 0 ; 0**d - PflgTblEnt 0x03, 2, 0 ; 0**e - PflgTblEnt 0x03, 2, 0 ; 0**f +; CpuSpecificByte2: +HID0_NHR_only equ 1 ; Idle Power calls should set the HID0[NHR] bit +HID0_NHR_and_sleep equ 2 ; ...and the HID0 bit that potentiates MSR[POW] +HID0_neither equ 0 - PflgTblEnt 0x03, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**0 = 7450 - PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**1 = 7445/55 - PflgTblEnt 0x03, 2, 0 ; 8**2 = 7447 (OS X only) - PflgTblEnt 0x03, 2, 0 ; 8**3 - PflgTblEnt 0x03, 1, 0 ; 8**4 - PflgTblEnt 0x03, 2, 0 ; 8**5 - PflgTblEnt 0x03, 2, 0 ; 8**6 - PflgTblEnt 0x03, 2, 0 ; 8**7 - PflgTblEnt 0x03, 2, 0 ; 8**8 - PflgTblEnt 0x03, 2, 0 ; 8**9 - PflgTblEnt 0x03, 2, 0 ; 8**a - PflgTblEnt 0x03, 2, 0 ; 8**b - PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**c = 7410 - PflgTblEnt 0x03, 2, 0 ; 8**d - PflgTblEnt 0x03, 2, 0 ; 8**e - PflgTblEnt 0x03, 2, 0 ; 8**f +; See NKPowerCalls for info on CpuSpecificByte1. Its upper nybble specifies how to idle the CPU. + + ; CpuSpecificByte + ; 1 2 ProcessorFlags CPU + ; - - -------------- --- + PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**0 + PflgTblEnt 0x00, HID0_neither, 0 ; 0**1 = 601 + PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**2 + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**3 = 603 + PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**4 = 604 + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**5 + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**6 = 603e + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**7 = 750FX + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU ; 0**8 = 750 + PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**9 + PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**a + PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**b + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 0**c = 7400 + PflgTblEnt 0x0b, HID0_NHR_and_sleep, 0 ; 0**d + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**e + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**f + + PflgTblEnt 0x03, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**0 = 7450 (see note below) + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**1 = 7445/55 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**2 = 7447 (OS X only) + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**3 + PflgTblEnt 0x03, HID0_NHR_only, 0 ; 8**4 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**5 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**6 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**7 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**8 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**9 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**a + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**b + PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**c = 7410 + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**d + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**e + PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**f + +; NB: PPC 7450 ("G4e") and its descendants (744x/745x) lack the HID0[DOZE] bit (they have HID0[HIGH_BAT_EN] instead). +; Therefore the upper nybble of CpuSpecificByte1 should be 0, or 2 for NAP (works), or 3 for SLEEP (freezes). endwith diff --git a/NanoKernel/NKScheduler.s b/NanoKernel/NKScheduler.s index 18bf2c3..1a12324 100644 --- a/NanoKernel/NKScheduler.s +++ b/NanoKernel/NKScheduler.s @@ -702,11 +702,11 @@ Save_v0_v31_0x1b8 TaskUnready lwz r17, Task.QueueMember + LLL.Next( r8) - lbz r18, Task.MysteryByte1( r8) + lbz r18, Task.State( r8) addi r16, r8, Task.QueueMember - ; Panic if MysteryByte1==0, return early if this task is not enqueued (i.e. LLL.Next==0) + ; Panic if State==0, return early if this task is not enqueued (i.e. LLL.Next==0) cmpwi cr1, r18, 0 cmpwi r17, 0 beq+ cr1, Local_Panic @@ -740,7 +740,7 @@ TaskUnready @return_early li r16, 0 - stb r16, Task.MysteryByte1(r8) + stb r16, Task.State(r8) mfsprg r17, 0 li r16, 1 @@ -821,7 +821,7 @@ TaskReadyCommonPath li r16, 1 - stb r16, Task.MysteryByte1(r8) + stb r16, Task.State(r8) blr @@ -1167,9 +1167,11 @@ RescheduleAndReturn ; OUTSIDE REFERER stb r8, EWA.SchEvalFlag(r14) lwz r31, -0x0008(r14) lwz r1, -0x0004(r14) - lwz r9, 0x0ee4(r1) - addi r9, r9, 0x01 - stw r9, 0x0ee4(r1) + + lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.SchEvalCount(r1) + addi r9, r9, 1 + stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.SchEvalCount(r1) + bl major_0x14a98 lbz r27, 0x0019(r31) blt- major_0x142dc_0x58 @@ -1459,9 +1461,9 @@ major_0x14548_0x148 li r8, 0x00 beq- major_0x14548_0x20c andc r27, r27, r28 - lwz r29, -0x0440(r1) + lwz r29, PSA.MCR(r1) stw r27, 0x0064(r30) - stw r8, -0x0440(r1) + stw r8, PSA.MCR(r1) blt- cr2, major_0x14548_0x1cc bsol+ cr6, Local_Panic clrlwi r8, r7, 0x08 @@ -1491,7 +1493,7 @@ major_0x14548_0x1cc lhz r17, -0x043c(r1) lwz r18, 0x067c(r1) cmplwi r17, 0xffff - lwz r26, 0x0674(r1) + lwz r26, KDP.PostIntMaskInit(r1) beq- major_0x14548_0x1f8 sth r17, 0x0000(r18) li r17, -0x01 @@ -1501,7 +1503,7 @@ major_0x14548_0x1f8 cmpwi r29, 0x00 or r13, r13, r29 bne- major_0x14548_0x20c - lwz r29, 0x0678(r1) + lwz r29, KDP.ClearIntMaskInit(r1) and r13, r13, r29 major_0x14548_0x20c @@ -1823,7 +1825,8 @@ major_0x14a98 ; OUTSIDE REFERER lwz r18, KDP.PA_ECB(r1) nand. r8, r8, r8 lwz r17, ContextBlock.PriorityShifty(r18) - bltlr- + bltlr- ; return if flag 10 was unset + cmpwi r17, 0 rlwinm r9, r17, 0, 22, 22 blt- major_0x14a98_0x54 @@ -1858,6 +1861,8 @@ major_0x14a98_0x54 ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ## ## ###### ######## ### ## ## ######## +; ARG Task *r8 + FlagSchEvaluationIfTaskRequires ; OUTSIDE REFERER lwz r16, Task.Flags(r8) mfsprg r15, 0 @@ -1908,7 +1913,7 @@ FlagSchEvaluationIfTaskRequires ; OUTSIDE REFERER lhz r17, EWA.CPUIndex(r15) lhz r18, CPU.EWA + EWA.CPUIndex(r18) cmpw r18, r17 - bne- BEFOUR + bne- DoInterprocessorAlert NINETYFOUR li r16, 0x01 @@ -1923,10 +1928,10 @@ major_0x14af8_0xa0 cmpw r17, r18 beq+ NINETYFOUR -BEFOUR - lwz r9, 0x0ee0(r1) - addi r9, r9, 0x01 - stw r9, 0x0ee0(r1) +DoInterprocessorAlert + lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1) + addi r9, r9, 1 + stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1) li r16, kAlert stw r16, EWA.SIGPSelector(r15) @@ -2009,8 +2014,8 @@ NewCpuEntryPoint lwz r10, ContextBlock.CodePtr(r6) lwz r11, ContextBlock.MSR(r6) - lwz r13, 0x00dc(r6) - lwz r12, 0x00ec(r6) + lwz r13, ContextBlock.CR(r6) + lwz r12, ContextBlock.LR(r6) _log 'EWA ' mr r8, r14 @@ -2033,7 +2038,7 @@ NewCpuEntryPoint RemoveFromList r16, scratch1=r17, scratch2=r18 li r16, 2 - stb r16, Task.MysteryByte1(r31) + stb r16, Task.State(r31) lwz r16, Task.Flags(r31) ori r16, r16, 0x20 @@ -2135,17 +2140,20 @@ IdleCode @make_calls - ; KCCpuPlugin(12, 1) - li r3, 12 - li r4, 1 - li r0, 46 + + ; Check that CPU plugin trusts this CPU + + li r3, kGetProcessorTemp + li r4, 1 ; 2nd arg ignored + li r0, 46 ; KCCpuPlugin sc cmpwi r3, 0 beq- @startagain + li r3, 1 li r4, 0 - twi 31, r31, 5 ; unconditional + twi 31, r31, 5 ; PowerCall(1) cmpwi r3, 0 beq- @startagain @@ -2197,7 +2205,8 @@ StopProcessor_0x10c lis r5, 0x7fff ori r5, r5, 0xffff mtdec r5 - li r3, 0x06 - li r4, 0x00 - twi 31, r31, 0x05 + + li r3, 6 + li r4, 0 + twi 31, r31, 5 b StopProcessor_0x10c \ No newline at end of file diff --git a/NanoKernel/NKSync.s b/NanoKernel/NKSync.s index 1c6689d..5cd0754 100644 --- a/NanoKernel/NKSync.s +++ b/NanoKernel/NKSync.s @@ -1496,117 +1496,155 @@ MPSetEvent ## ## ## ## ## ## ## ### ######## ###### ######## ## ### -SetEvent ; OUTSIDE REFERER - lwz r16, 0x0010(r31) - or r16, r16, r8 - stw r16, 0x0010(r31) - mflr r27 - lwz r8, 0x0000(r31) - bl UnblockBlueIfCouldBePolling - lwz r16, 0x0008(r31) - cmpw r16, r31 - addi r8, r16, -0x08 - beq- SetEvent_0x90 - lwz r17, 0x0088(r8) - lwz r18, 0x00fc(r17) - subi r18, r18, 4 - stw r18, 0x00fc(r17) - lbz r17, 0x0037(r8) - cmpwi r17, 0x01 - bne- SetEvent_0x4c - addi r8, r8, 0x20 - bl DequeueTimer +; ARG Event *r31, flags r8 -SetEvent_0x4c - lwz r16, 0x0008(r31) +SetEvent + lwz r16, EventGroup.Flags(r31) + or r16, r16, r8 + stw r16, EventGroup.Flags(r31) + + mflr r27 + + lwz r8, EventGroup.LLL + LLL.Freeform(r31) + bl UnblockBlueIfCouldBePolling + + ; + lwz r16, EventGroup.LLL + LLL.Next(r31) + cmpw r16, r31 + subi r8, r16, Task.QueueMember + beq- @no_task_waiting + + + ; CASE 1: task needs unblocking + + ; Rerun SC instruction in task context + lwz r17, Task.ContextBlockPtr(r8) + lwz r18, ContextBlock.CodePtr(r17) + subi r18, r18, 4 + stw r18, ContextBlock.CodePtr(r17) + + ; Cancel timeout + lbz r17, Task.Timer + Timer.Byte3(r8) + cmpwi r17, 1 + bne- @timer_not_armed + addi r8, r8, Task.Timer + bl DequeueTimer +@timer_not_armed + + ; Remove this task from my wait queue + lwz r16, EventGroup.LLL + LLL.Next(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 - lwz r18, 0x001c(r31) - addi r18, r18, -0x01 - stw r18, 0x001c(r31) - addi r8, r16, -0x08 - li r17, 0x01 - stb r17, 0x0019(r8) + lwz r18, EventGroup.Counter(r31) + subi r18, r18, 1 + stw r18, EventGroup.Counter(r31) + + ; Latency protection priority + subi r8, r16, Task.QueueMember + li r17, Task.kLatencyProtectPriority + stb r17, Task.Priority(r8) + bl TaskReadyAsPrev bl CalculateTimeslice bl FlagSchEvaluationIfTaskRequires -SetEvent_0x90 - lwz r16, 0x0018(r31) - rlwinm. r17, r16, 0, 27, 27 - beq- SetEvent_0x1a0 - lwz r17, KDP.PA_ECB(r1) - lwz r26, -0x08f0(r1) - lwz r18, 0x00c8(r17) - lwz r19, 0x00d0(r17) - cmpwi cr1, r18, 0x00 - cmpwi r19, 0x00 - bne- cr1, SetEvent_0xc8 - bne- SetEvent_0x1a0 - lwz r8, 0x0000(r31) - stw r8, 0x00d0(r17) - b SetEvent_0x118 -SetEvent_0xc8 - lwz r9, 0x0634(r1) +@no_task_waiting + lwz r16, EventGroup.SWI(r31) + rlwinm. r17, r16, 0, 27, 27 + + + ; CASE 2: no task waiting. + + beq- @return + + + ; CASE 3: SOFTWARE INTERRUPT + + lwz r17, KDP.PA_ECB(r1) + lwz r26, PSA.PA_BlueTask(r1) + lwz r18, ContextBlock.EDPOffsetSWIRelated(r17) + lwz r19, ContextBlock.SWIEventGroupID(r17) + cmpwi cr1, r18, 0 + cmpwi r19, 0 + bne- cr1, @do_not_save_swi_event_id + bne- @return + + lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; contains my ID + stw r8, ContextBlock.SWIEventGroupID(r17) + b @common_case +@do_not_save_swi_event_id + + ; There is an EDP table of SWI-EventGroup IDs... set ours, cancel if already set + lwz r9, KDP.PA_EmulatorData(r1) rlwinm r16, r16, 2, 26, 29 add r18, r18, r9 lwzx r19, r16, r18 - cmpwi r19, 0x00 - bne- SetEvent_0x1a0 - lwz r8, 0x0000(r31) + cmpwi r19, 0 + bne- @return + + ; Set! + lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; my ID stwx r8, r16, r18 - li r19, 0x1c - li r9, 0x04 -SetEvent_0xf0 + ; Find the highest interrupt level with a nonzero thing + li r19, 7*4 + li r9, 4 +@loop lwzx r8, r19, r18 - cmpwi r8, 0x00 - bne- SetEvent_0x108 + cmpwi r8, 0 + bne- @exit_loop subf. r19, r9, r19 - bgt+ SetEvent_0xf0 + bgt+ @loop bl panic +@exit_loop -SetEvent_0x108 + ; Can I interrupt the current interrupt? cmplw r16, r19 - srwi r16, r16, 2 - blt- SetEvent_0x1a0 - stw r16, 0x00d0(r17) + srwi r16, r16, 2 + blt- @return + stw r16, ContextBlock.SWIEventGroupID(r17) +@common_case -SetEvent_0x118 - lwz r16, 0x0064(r26) - lbz r19, 0x0018(r26) - ori r16, r16, 0x10 - stw r16, 0x0064(r26) - lwz r17, -0x0440(r1) - lwz r16, 0x0674(r1) - lwz r8, 0x0678(r1) + + lwz r16, Task.Flags(r26) + lbz r19, Task.State(r26) + ori r16, r16, (1 << (31 - Task.kFlag27)) + stw r16, Task.Flags(r26) + + ; But what *is* MCR? + lwz r17, PSA.MCR(r1) + lwz r16, KDP.PostIntMaskInit(r1) + lwz r8, KDP.ClearIntMaskInit(r1) and r16, r16, r8 or r17, r17, r16 - stw r17, -0x0440(r1) - cmpwi r19, 0x00 - addi r16, r26, 0x08 - bne- SetEvent_0x198 - RemoveFromList r16, scratch1=r17, scratch2=r18 - lbz r17, 0x0037(r26) - cmpwi r17, 0x01 - bne- SetEvent_0x17c - addi r8, r26, 0x20 - bl DequeueTimer + stw r17, PSA.MCR(r1) -SetEvent_0x17c - lwz r18, -0x08f0(r1) - li r16, 0x00 - stb r16, 0x0019(r26) + cmpwi r19, 0 + addi r16, r26, Task.QueueMember + bne- @task_already_running + + ; De-fang the blocking timeout + RemoveFromList r16, scratch1=r17, scratch2=r18 + lbz r17, Task.Timer + Timer.Byte3(r26) + cmpwi r17, 1 + bne- @timer_not_armed_2 + addi r8, r26, Task.Timer + bl DequeueTimer +@timer_not_armed_2 + + lwz r18, PSA.PA_BlueTask(r1) + li r16, Task.kCriticalPriority + stb r16, Task.Priority(r26) mr r8, r26 bl TaskReadyAsNext mr r8, r26 bl CalculateTimeslice +@task_already_running -SetEvent_0x198 mr r8, r26 bl FlagSchEvaluationIfTaskRequires -SetEvent_0x1a0 +@return mtlr r27 blr @@ -2553,7 +2591,7 @@ UnblockBlueIfCouldBePolling mflr r24 stw r9, PSA.BlueSpinningOn(r1) - lbz r17, Task.MysteryByte1(r19) + lbz r17, Task.State(r19) cmpwi r17, 0 addi r16, r19, Task.QueueMember @@ -2566,12 +2604,12 @@ UnblockBlueIfCouldBePolling bne- major_0x0dce8_0x60 addi r8, r19, Task.Timer bl DequeueTimer - lwz r19, -0x08f0(r1) + lwz r19, PSA.PA_BlueTask(r1) major_0x0dce8_0x60 li r16, 0x01 stb r16, 0x0019(r19) - lwz r8, -0x08f0(r1) + lwz r8, PSA.PA_BlueTask(r1) bl TaskReadyAsPrev major_0x0dce8_0x70 diff --git a/NanoKernel/NKTasks.s b/NanoKernel/NKTasks.s index 3c9811a..7a90ea6 100644 --- a/NanoKernel/NKTasks.s +++ b/NanoKernel/NKTasks.s @@ -59,8 +59,8 @@ MPCall_7 ; OUTSIDE REFERER stw r4, 0x0098(r31) - lwz r17, ContextBlock.r6(r6) - stw r17, 0x00ec(r31) + lwz r17, ContextBlock.r6(r6) + stw r17, ContextBlock.LR(r31) lwz r16, Task.Flags(r28) @@ -206,7 +206,7 @@ CreateTask li r16, 0 - stb r16, Task.MysteryByte1(r28) + stb r16, Task.State(r28) li r16, 9 ; (Z>>Task.kFlag28) | (Z>>Task.kFlag31) stw r16, Task.Flags(r28) @@ -541,7 +541,7 @@ TasksFuncThatIsNotAMPCall MPCall_11 ; OUTSIDE REFERER mfsprg r16, 0 cmpwi r3, 0x00 - lwz r17, -0x08f0(r1) + lwz r17, PSA.PA_BlueTask(r1) lwz r18, -0x0008(r16) lwz r19, 0x0000(r17) bne- MPCall_11_0x1c diff --git a/NanoKernel/NKTimers.s b/NanoKernel/NKTimers.s index 276fb1e..034fc10 100644 --- a/NanoKernel/NKTimers.s +++ b/NanoKernel/NKTimers.s @@ -587,45 +587,53 @@ TimerFire5_0x8 ; OUTSIDE REFERER ; Dead code -- probably removed from TimerTable _log 'Heartbeat: Ext ' - lwz r16, 0x0e80(r1) + lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1) mr r8, r16 bl printd + _log 'Alerts ' - lwz r16, 0x0ee0(r1) + lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1) mr r8, r16 bl printd + _log 'Blue cpu-' - lwz r17, -0x08f0(r1) - lhz r16, 0x001a(r17) + lwz r17, PSA.PA_BlueTask(r1) + lhz r16, Task.CPUIndex(r17) mr r8, r16 bl printb + _log 'state-' - lbz r16, 0x0018(r17) + lbz r16, Task.State(r17) mr r8, r16 bl printb + _log 'scr-' lwz r16, KDP.PA_ECB(r1) - lwz r18, 0x0674(r1) - lwz r16, 0x00dc(r16) + lwz r18, KDP.PostIntMaskInit(r1) + lwz r16, ContextBlock.CR(r16) and r16, r16, r18 mr r8, r16 bl printw + _log 'mcr-' - lwz r16, -0x0440(r1) + lwz r16, PSA.MCR(r1) mr r8, r16 bl printw + _log 'IPL-' - lwz r16, 0x067c(r1) - lhz r16, 0x0000(r16) + lwz r16, KDP.PA_EmulatorIplValue(r1) + lhz r16, 0(r16) mr r8, r16 bl printh + _log 'eSR-' lwz r16, KDP.PA_ECB(r1) - lwz r16, 0x01cc(r16) - andi. r16, r16, 0x07 + lwz r16, ContextBlock.r25(r16) + andi. r16, r16, 7 mr r8, r16 bl printb _log '^n' + mfxer r19 lwz r16, 0x0038(r30) lwz r17, 0x003c(r30) diff --git a/NanoKernel/NanoKernel.s b/NanoKernel/NanoKernel.s index 9044cb2..f9afeb8 100644 --- a/NanoKernel/NanoKernel.s +++ b/NanoKernel/NanoKernel.s @@ -24,7 +24,7 @@ NKTop align 5 include 'NKRTASCalls.s' align 5 - include 'NKCacheCalls.s' + include 'NKCache.s' ; Mostly MP calls: align 5