From dd4e2ef845d5493f3bed1e736201a09ed9f1b10b Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Sat, 31 Mar 2018 16:17:23 +0800 Subject: [PATCH] Reverse PPC-68k context switching (incomplete) --- Internal/EmulatorPublic.a | 4 +- Internal/NKOpaque.a | 18 +- Internal/NKPublic.a | 71 +-- NanoKernel/NKAddressSpaceMPCalls.s | 8 +- NanoKernel/NKInit.s | 51 +-- NanoKernel/NKInterrupts.s | 710 +++++++++++++++++------------ NanoKernel/NKMPCalls.s | 14 +- NanoKernel/NKMacros.s | 15 + NanoKernel/NKPaging.s | 14 +- NanoKernel/NKPrimaryIntHandlers.s | 4 +- NanoKernel/NKRTASCalls.s | 14 +- NanoKernel/NKReplacementInit.s | 6 +- NanoKernel/NKScheduler.s | 349 ++++++++------ NanoKernel/NKScreenConsole.s | 2 +- NanoKernel/NKSleep.s | 12 +- NanoKernel/NKSync.s | 14 +- NanoKernel/NKTasks.s | 46 +- NanoKernel/NKThud.s | 4 +- NanoKernel/NKTranslation.s | 2 +- NanoKernel/NKVMCalls.s | 8 +- 20 files changed, 767 insertions(+), 599 deletions(-) diff --git a/Internal/EmulatorPublic.a b/Internal/EmulatorPublic.a index 8d58b8a..980971d 100644 --- a/Internal/EmulatorPublic.a +++ b/Internal/EmulatorPublic.a @@ -30,7 +30,7 @@ DFC ds.l 1 ; 05c ds.l 1 ; 064 ds.l 1 ; 068 ds.l 1 ; 06c -INTM_L ds.l 1 ; 070 ; interrupt level or -1 +INTM_L ds.l 1 ; 070 ; interrupt level or -1 (halfword) DISP ds.l 1 ; 074 CODE ds.l 1 ; 078 SP ds.l 1 ; 07c @@ -92,8 +92,6 @@ PriorityShifty ds.l 1 ; 0cc ; if low nybble is empty, SchInit sets this to 2 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 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 diff --git a/Internal/NKOpaque.a b/Internal/NKOpaque.a index 8cd9e9a..104548c 100644 --- a/Internal/NKOpaque.a +++ b/Internal/NKOpaque.a @@ -139,16 +139,16 @@ kFlag17 equ 17 kFlag18 equ 18 kFlag19 equ 19 kFlag20 equ 20 -kFlagPMF equ 21 ; set by MPMarkPMFTask, means perf monitor -kFlag22 equ 22 +kFlagPerfMon equ 21 ; set by MPMarkPMFTask, means perf monitor +kFlagStopped equ 22 kFlag23 equ 23 kFlag24 equ 24 kFlag25 equ 25 ; set for idle1, idle2 -kFlag26 equ 26 ; set for blue -kFlag68kInterrupt equ 27 ; set on SWI (meaning 68k, or 68k interrupt?) +kFlag26 equ 26 ; set for blue, cleared when preempted, set when run +kFlagSchToInterruptEmu equ 27 ; set when scheduler should trigger a 68k interrupt in this task kFlag28 equ 28 ; set for blue kFlag29 equ 29 -kFlag30 equ 30 +kFlagAborted equ 30 kFlag31 equ 31 ds.l 1 ; 068 @@ -164,16 +164,16 @@ VectorSaveArea ds.l 1 ; 08c ds.l 1 ; 094 ds.l 1 ; 098 NotificationPtr ds.l 1 ; 09c -Semaphore ds.b 32 ; 0a0:0c0 ; Zero and One were fields +PageFaultSema ds.b 32 ; 0a0:0c0 ; task blocks on this fake sema, only to run when high-priority blue is done Zero1 ds.l 1 ; 0c0 Zero2 ds.l 1 ; 0c4 CreateTime1 ds.d 1 ; 0c8 CreateTime2 ds.d 1 ; 0d0 ds.l 1 ; 0d8 ds.l 1 ; 0dc -Zero3 ds.l 1 ; 0e0 -Zero4 ds.l 1 ; 0e4 -Zero5 ds.l 1 ; 0e8 +CodeFaultCtr ds.l 1 ; 0e0 ; these two only climb when VM is on +DataFaultCtr ds.l 1 ; 0e4 +PreemptCtr ds.l 1 ; 0e8 SomeLabelField ds.l 1 ; 0ec YellowVecTblPtr ds.l 1 ; 0f0 ExceptionHandlerID ds.l 1 ; 0f4 ; a queue diff --git a/Internal/NKPublic.a b/Internal/NKPublic.a index 3abfd63..f0476c9 100644 --- a/Internal/NKPublic.a +++ b/Internal/NKPublic.a @@ -131,13 +131,7 @@ NominalReadyQ ds.l 8 ; -9b0:-990 ; unblocked tasks with priority 2 IdleReadyQ ds.l 8 ; -990:-970 ; unblocked tasks with priority 3 PriorityFlags ds.l 1 ; -970 ; bit 0 is 0, bit 1 is 1, etc... ScrambledMPCallTime ds.l 1 ; -96c ; by MP call return -GlobalCPUFlags ds.l 1 ; -968 ; Init.s saves MQ (should be possible) here -MQFeatureBit equ 13 ; equals 0x00040000 -AVFeatureBit equ 12 ; equals 0x00080000 -; 8 0x00800000 -; 10 0x00200000 -;int vector checks 9 0x00400000 - +FlagsTemplate ds.l 1 ; -968 ; typically just EWA.kFlagVec UserModeMSR ds.l 1 ; -964 ThudBuffer ds.b 96 ; -960:-900 ; that's the kernel debugger NoIdeaR23 ds.l 1 ; -900 ; r23 copies here... replated to RTAS? @@ -160,7 +154,7 @@ DiagInfo ds.b 256 ; -5d0:-4d0 ProcessorState ds.b 128 ; -4d0:-450 ; interesting what this gets used by FreeList ds.l 4 ; -450:-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 +Pending68kInt ds.w 1 ; -43c ; used when Sch interrupts blue task (-1 means "none") ds.w 1 ; -43a DecClockRateHzCopy ds.l 1 ; -438 ; copied by Init.s OtherTimerQueuePtr ds.l 1 ; -434 ; unsigned timer queue in the pool, set by InitTMRQs @@ -311,7 +305,7 @@ SpacesSavedAreaBase ds.l 1 ; -270, cpu+0d0 SpacesDeferredAreaPtr ds.l 1 ; -26c, cpu+0d4 ds.l 1 ; -268, cpu+0d8 ds.l 1 ; -264, cpu+0dc - ds.l 1 ; -260, cpu+0e0 +SchSavedIncomingTask ds.l 1 ; -260, cpu+0e0 ds.l 1 ; -25c, cpu+0e4 TimerDispatchLR ds.l 1 ; -258, cpu+0e8 ds.l 1 ; -254, cpu+0ec @@ -408,7 +402,7 @@ WeMightClear ds.l 1 ; -114, cpu+22c ; still boots if not cleared ds.l 1 ; -0f0, cpu+250 ds.l 1 ; -0ec, cpu+254 ds.l 1 ; -0e8, cpu+258 -SpecialAreaPtr ds.l 1 ; -0e4, cpu+25c +SpecialAreaPtr ds.l 1 ; -0e4, cpu+25c ; will panic on page fault if this is not valid ds.l 1 ; -0e0, cpu+260 ds.l 1 ; -0dc, cpu+264 ds.l 1 ; -0d8, cpu+268 @@ -512,26 +506,32 @@ kFlag4 equ 4 kFlag5 equ 5 kFlag6 equ 6 kFlag7 equ 7 -kFlag8 equ 8 -kFlag9 equ 9 -kFlagBlue equ 10 ; could mean "currently in interrupt mode" -kFlag11 equ 11 -kFlag12 equ 12 -kFlag13 equ 13 -kFlag14 equ 14 -kFlag15 equ 15 -kFlag16 equ 16 + + ; PER-TASK FLAGS +kFlagEmu equ 8 ; emulator is running +kFlag9 equ 9 ; * = preserved on alt>sys switch +kFlagBlue equ 10 ; * +kFlag11 equ 11 ; * +kFlagVec equ 12 ; * +kFlagHasMQ equ 13 ; * +kFlag14 equ 14 ; * +kFlag15 equ 15 ; * +kFlagSIGP equ 16 ; * + + ; PER-CONTEXT FLAGS kFlag17 equ 17 kFlag18 equ 18 kFlag19 equ 19 -kFlag20 equ 20 -kFlag21 equ 21 -kFlag22 equ 22 -kFlag23 equ 23 + +kFlagFE0 equ 20 ; these correspond with MSR bits +kFlagSE equ 21 +kFlagBE equ 22 +kFlagFE1 equ 23 + kFlag24 equ 24 kFlag25 equ 25 -kFlag26 equ 26 -kFlag27 equ 27 +kFlag26 equ 26 ; can be copied from kFlagSE +kFlagLowSaves equ 27 kFlag28 equ 28 kFlag29 equ 29 kFlag30 equ 30 @@ -562,14 +562,17 @@ BATs ds.l 32 ; 280:300 ; GAP org 0x340 -MinusOne1 ds.l 1 ; 340 ; several longs set at once - ds.l 1 ; 344 -MinusOne2 ds.l 1 ; 348 - ds.l 1 ; 34c -MinusOne3 ds.l 1 ; 350 - ds.l 1 ; 354 -MinusOne4 ds.l 1 ; 358 - ds.l 1 ; 35c +NCBPointerCache +NCBCacheLA0 ds.l 1 ; 340 +NCBCachePA0 ds.l 1 ; 344 +NCBCacheLA1 ds.l 1 ; 348 +NCBCachePA1 ds.l 1 ; 34c +NCBCacheLA2 ds.l 1 ; 350 +NCBCachePA2 ds.l 1 ; 354 +NCBCacheLA3 ds.l 1 ; 358 +NCBCachePA3 ds.l 1 ; 35c +NCBPointerCacheEnd + YellowVecBase ds.l 48 ; 360:420 ; used to ignore illegal AltiVec insns by Init.s OrangeVecBase ds.l 48 ; 420:4e0 RedVecBase ds.l 48 ; 4e0:5a0 @@ -578,7 +581,7 @@ OtherFreeThing ds.l 1 ; 5a4 TopOfFreePages ds.l 1 ; 5a8 ; gotten from the old SPRG0 ds.l 1 ; 5ac PA_InterruptHandler ds.l 1 ; 5b0 - ds.l 1 ; 5b4 +LA_NCB ds.l 1 ; 5b4 ; most recent physical address found HiLevelPerfMonitorBits ds.l 1 ; 5b8 ds.l 1 ; 5bc PerfMonitorBits ds.l 1 ; 5c0 diff --git a/NanoKernel/NKAddressSpaceMPCalls.s b/NanoKernel/NKAddressSpaceMPCalls.s index af750e8..b6b5e24 100644 --- a/NanoKernel/NKAddressSpaceMPCalls.s +++ b/NanoKernel/NKAddressSpaceMPCalls.s @@ -3964,11 +3964,9 @@ MPCall_95_0x334 MPCall_95_0x348 ; OUTSIDE REFERER lwz r14, 0x0000(r30) - li r16, -0x01 - stw r16, 0x0340(r1) - stw r16, 0x0348(r1) - stw r16, 0x0350(r1) - stw r16, 0x0358(r1) + + _InvalNCBPointerCache scratch=r16 + lwz r16, 0x0e98(r1) rlwinm r14, r14, 0, 21, 19 addi r16, r16, 0x01 diff --git a/NanoKernel/NKInit.s b/NanoKernel/NKInit.s index 0875eed..28b99f7 100644 --- a/NanoKernel/NKInit.s +++ b/NanoKernel/NKInit.s @@ -209,14 +209,14 @@ FinishInitBuiltin ; Test MQ and save feature field - lis r8, 1 << (15 - PSA.MQFeatureBit) + lis r8, 1 << (15 - EWA.kFlagHasMQ) mtspr mq, r8 li r8, 0 mfspr r8, mq - stw r8, PSA.GlobalCPUFlags(r1) + stw r8, PSA.FlagsTemplate(r1) ; Add AV and save that in scratch field - oris r9, r8, 1 << (15 - PSA.AVFeatureBit) + _bset r9, r8, EWA.kFlagVec stw r9, EWA.r0(r1) ; Load from scratch field into a vector register @@ -230,11 +230,11 @@ FinishInitBuiltin stvewx v0, 0, r9 ; Scratch field now contains AltiVec and MQ flags. - ; Copy it to GlobalCPUFlags + ; Copy it to FlagsTemplate lwz r8, EWA.r0(r1) - stw r8, PSA.GlobalCPUFlags(r1) + stw r8, PSA.FlagsTemplate(r1) - ; current flags = tested flags | CPU flag 8 | CPU flag 9 + ; initial blue flags = global template + EWA.kFlagEmu + EWA.kFlag9 oris r7, r8, 0xa0 stw r7, EWA.Flags(r1) @@ -298,9 +298,8 @@ ResetBuiltinKernel ; r3 = 0 ; r4 = 0 ; r5 = SystemInfo -; r6 = PA_ECB -; r7 = AllCpuFeatures -; r8 = GlobalCPUFlags +; r6 = ECB +; r7 = Flags ; r9 = even more altivec crud ; r10 = LA_EmulatorKernelTrapTable ; r11 = MSR @@ -685,13 +684,9 @@ SetProcessorFlags @done -; These look like two-word structures. Not yet sure what they are. +; Init the NCB Pointer Cache - li r23, -1 - stw r23, KDP.MinusOne1(r1) ; kdp.0x340 - stw r23, KDP.MinusOne2(r1) ; kdp.0x348 - stw r23, KDP.MinusOne3(r1) ; kdp.0x350 - stw r23, KDP.MinusOne4(r1) ; kdp.0x358 + _InvalNCBPointerCache scratch=r23 @@ -1108,7 +1103,7 @@ SetProcessorFlags ; Create the Blue MacOS task - ; ARG GlobalCPUFlags r7, Process *r8 + ; ARG Flags r7, Process *r8 ; RET Task *r8 lwz r8, PSA.blueProcessPtr(r1) @@ -1124,7 +1119,7 @@ SetProcessorFlags ; Can equal -1 or a 68k interrupt number. PIHes touch it. li r8, -1 - sth r8, PSA.Int(r1) + sth r8, PSA.Pending68kInt(r1) ; stw r31, PSA.PA_BlueTask(r1) @@ -1206,20 +1201,20 @@ SetProcessorFlags ; Create the idle task for the first CPU - ; Unset the AV bit in GlobalCPUFlags so that + ; Unset EWA.kFlagVec so that ; idle task vector registers are not saved/restored ; (Leave the old value in r31) -av set PSA.AVFeatureBit - mr r31, r7 - rlwinm r7, r7, 0, av + 1, av - 1 - ; ARG GlobalCPUFlags r7, Process *r8 + mr r31, r7 + _bclr r7, r7, EWA.kFlagVec + + ; ARG Flags r7, Process *r8 ; RET Task *r8 lwz r8, PSA.blueProcessPtr(r1) bl CreateTask - ; Restore GlobalCPUFlags + ; Restore Flags mr r7, r31 ; Check @@ -1879,7 +1874,7 @@ finish_old_world bl ProbePerfMonitor lwz r27, 0x0630(r1) lwz r27, 0x0094(r27) - bl PagingFunc4 + bl PagingL2PWithoutBATs beq setup_0x1160 li r30, 0x00 stw r30, -0x0004(r29) @@ -1891,7 +1886,7 @@ setup_0x1160 bl PagingFunc1 lwz r27, 0x0630(r1) lwz r27, 0x009c(r27) - bl PagingFunc4 + bl PagingL2PWithoutBATs beq setup_0x1188 li r30, 0x00 stw r30, -0x0004(r29) @@ -1908,7 +1903,7 @@ setup_0x1188 subf r19, r19, r27 setup_0x11a0 - bl PagingFunc4 + bl PagingL2PWithoutBATs beq setup_0x11bc li r30, 0x00 stw r30, -0x0004(r29) @@ -1923,7 +1918,7 @@ setup_0x11bc bgt setup_0x11a0 lwz r27, 0x0630(r1) lwz r27, 0x00a4(r27) - bl PagingFunc4 + bl PagingL2PWithoutBATs beq setup_0x11f0 li r30, 0x00 stw r30, -0x0004(r29) @@ -1936,7 +1931,7 @@ setup_0x11f0 _log 'Nanokernel replaced. Returning to boot process^n' - addi r9, r1, 0x420 + addi r9, r1, KDP.OrangeVecBase mtsprg 3, r9 ; r1 = kdp diff --git a/NanoKernel/NKInterrupts.s b/NanoKernel/NKInterrupts.s index 93c6468..03ec3bf 100644 --- a/NanoKernel/NKInterrupts.s +++ b/NanoKernel/NKInterrupts.s @@ -10,7 +10,7 @@ ecInstInvalidAddress equ 10 ecInstHardwareFault equ 11 ecInstPageFault equ 12 ecInstSupAccessViolation equ 14 -ecDataInvalidAccess equ 18 +ecDataInvalidAddress equ 18 ecDataHardwareFault equ 19 ecDataPageFault equ 20 ecDataWriteViolation equ 21 @@ -38,19 +38,21 @@ major_0x02980 ; OUTSIDE REFERER lwz r9, EWA.Enables(r1) rlwinm r23, r17, 31, 27, 31 rlwnm. r9, r9, r8, 0x00, 0x00 - bsol cr3, major_0x02980_0x100 + bcl BO_IF, 15, major_0x02980_0x100 lwz r6, -0x0014(r1) ori r7, r16, 0x10 neg r23, r23 - mtcrf 0x3f, r7 + mtcrf 0x3f, r7 add r19, r19, r23 rlwimi r7, r8, 24, 0, 7 lwz r1, -0x0004(r1) - slwi r8, r8, 2 + + slwi r8, r8, 2 add r8, r8, r1 - lwz r9, 0x0dc0(r8) - addi r9, r9, 0x01 - stw r9, 0x0dc0(r8) + lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionCauseCounts(r8) + addi r9, r9, 1 + stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionCauseCounts(r8) + srwi r9, r7, 24 mfsprg r1, 0 lwz r8, 0x0000(r1) @@ -70,13 +72,16 @@ major_0x02980 ; OUTSIDE REFERER lwz r8, 0x0034(r1) stw r8, 0x016c(r6) cmpwi cr1, r9, 0x14 - blt cr4, major_0x04a20_0x18 - bne cr2, TaskApproachTwo - blt major_0x02980_0xa8 - bne cr1, major_0x02980_0x178 - b TaskApproachTwo + bc BO_IF, EWA.kFlagSIGP, _IntReturnFromSIGP + bc BO_IF_NOT, EWA.kFlagBlue, _RecoverableDataFault + blt ExceptionIsInEnables + bne cr1, _IntReturnToSystemContext + b _RecoverableDataFault + + + +ExceptionIsInEnables -major_0x02980_0xa8 mfsprg r1, 0 stw r10, 0x0084(r6) stw r12, 0x008c(r6) @@ -88,20 +93,26 @@ major_0x02980_0xa8 li r8, 0x00 lwz r10, 0x004c(r6) stw r8, EWA.Enables(r1) - lwz r1, -0x0004(r1) + lwz r1, EWA.PA_KDP(r1) lwz r4, 0x0054(r6) - lwz r3, 0x0654(r1) - blt cr2, major_0x02980_0xec - lwz r3, 0x05b4(r1) - _bclr r11, r11, 16 -major_0x02980_0xec - lwz r12, 0x0648(r1) - bsol cr6, PreferRegistersFromEWASavingContextBlock - rlwinm r7, r7, 0, 29, 16 - rlwimi r11, r7, 0, 20, 23 + lwz r3, KDP.LA_ECB(r1) + bc BO_IF, 8, @is_system_context + lwz r3, KDP.LA_NCB(r1) + _bclr r11, r11, MSR_EEbit +@is_system_context + + ; exception handler will return via trap in emulator code + lwz r12, KDP.LA_EmulatorKernelTrapTable + NanoKernelCallTable.ReturnFromException(r1) + + bcl BO_IF, EWA.kFlagLowSaves, PreferRegistersFromEWASavingContextBlock + rlwinm r7, r7, 0, 29, 16 ; unset 17-28 + rlwimi r11, r7, 0, 20, 23 ; threfore unset MSR[FE0/SE/BE/FE1] + b IntReturn + + major_0x02980_0x100 lwz r2, 0x0008(r1) lwz r3, 0x000c(r1) @@ -140,48 +151,68 @@ major_0x02980_0x134 ; OUTSIDE REFERER srwi r9, r7, 24 - bc BO_IF, EWA.kFlag16, major_0x04a20_0x18 - bc BO_IF_NOT, EWA.kFlagBlue, TaskApproachOne - cmpwi cr1, r9, ecInstPageFault - blt major_0x02980_0xa8 ; when Enables[cause] is set! - beq cr1, TaskApproachOne + bc BO_IF, EWA.kFlagSIGP, _IntReturnFromSIGP + bc BO_IF_NOT, EWA.kFlagBlue, _RecoverableCodeFault + + cmpwi cr1, r9, ecInstPageFault + blt ExceptionIsInEnables ; when Enables[cause] is set! + beq cr1, _RecoverableCodeFault + + +; fall through if blue, exception not "enabled" + +_IntReturnToSystemContext -major_0x02980_0x178 ; OUTSIDE REFERER lwz r1, EWA.PA_KDP(r1) lwz r9, KDP.PA_ECB(r1) + addi r8, r1, KDP.YellowVecBase mtsprg 3, r8 - bcl BO_IF, 8, SuspendBlueTask ; does not return + ; Exception came from emulator! Can't handle that with a 68k interrupt, can we? + bcl BO_IF, EWA.kFlagEmu, SuspendBlueTask + + + +; Swap the blue task between the system and alternate contexts + +; ARG old_context r6, new_context r9 + +_IntReturnToOppositeContext -major_0x02980_0x18c ; OUTSIDE REFERER mfsprg r1, 0 + lwz r8, EWA.Enables(r1) stw r7, ContextBlock.Flags(r6) stw r8, ContextBlock.Enables(r6) - bc BO_IF_NOT, 27, major_0x02980_0x1b8 + + bc BO_IF_NOT, EWA.kFlagLowSaves, @not_low_saves stw r17, 0x0024(r6) stw r20, 0x0028(r6) stw r21, 0x002c(r6) stw r19, 0x0034(r6) stw r18, 0x003c(r6) lmw r14, 0x0038(r1) +@not_low_saves + + + ; Save state to the old ContextBlock -major_0x02980_0x1b8 mfxer r8 - stw r13, 0x00dc(r6) - stw r8, 0x00d4(r6) - stw r12, 0x00ec(r6) + stw r13, ContextBlock.CR(r6) + stw r8, ContextBlock.XER(r6) + stw r12, ContextBlock.LR(r6) mfctr r8 - stw r10, 0x00fc(r6) - stw r8, 0x00f4(r6) - bc BO_IF_NOT, 13, major_0x02980_0x1e8 - lwz r8, 0x00c4(r9) + stw r10, ContextBlock.CodePtr(r6) + stw r8, ContextBlock.KernelCTR(r6) + + bc BO_IF_NOT, EWA.kFlagHasMQ, @no_mq + lwz r8, ContextBlock.MQ(r9) mfspr r12, mq mtspr mq, r8 - stw r12, 0x00c4(r6) + stw r12, ContextBlock.MQ(r6) +@no_mq -major_0x02980_0x1e8 lwz r8, 0x0004(r1) stw r8, 0x010c(r6) stw r2, 0x0114(r6) @@ -203,48 +234,62 @@ major_0x02980_0x1e8 stw r24, 0x01c4(r6) stw r25, 0x01cc(r6) stw r26, 0x01d4(r6) - andi. r8, r11, 0x2000 + _band. r8, r11, MSR_FPbit stw r27, 0x01dc(r6) stw r28, 0x01e4(r6) stw r29, 0x01ec(r6) stw r30, 0x01f4(r6) stw r31, 0x01fc(r6) - bnel major_0x03e18_0xb4 - bc BO_IF_NOT, 12, major_0x02980_0x260 + bnel bugger_around_with_floats + + bc BO_IF_NOT, EWA.kFlagVec, @no_vec bl Save_v0_v31 -major_0x02980_0x260 +@no_vec + + stw r11, ContextBlock.MSR(r6) + + + ; Load state from the new ContextBlock + + lwz r8, ContextBlock.Flags(r9) + + stw r9, EWA.PA_ContextBlock(r1) + + xoris r7, r7, 1 << (15 - EWA.kFlagEmu) ; toggle the emulator flag + + rlwimi r11, r8, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] - stw r11, 0x00a4(r6) - lwz r8, 0x0000(r9) - stw r9, -0x0014(r1) - xoris r7, r7, 0x80 - rlwimi r11, r8, 0, 20, 23 mr r6, r9 - rlwimi r7, r8, 0, 17, 31 - andi. r8, r11, 0x900 - lwz r8, 0x0004(r6) - lwz r13, 0x00dc(r6) + rlwimi r7, r8, 0, 17, 31 ; copy the flags that *do* differ between contexts + + andi. r8, r11, MSR_FE0 | MSR_FE1 + + lwz r8, ContextBlock.Enables(r6) + lwz r13, ContextBlock.CR(r6) stw r8, EWA.Enables(r1) - lwz r8, 0x00d4(r6) - lwz r12, 0x00ec(r6) + lwz r8, ContextBlock.XER(r6) + lwz r12, ContextBlock.LR(r6) mtxer r8 - lwz r8, 0x00f4(r6) - lwz r10, 0x00fc(r6) + lwz r8, ContextBlock.KernelCTR(r6) + lwz r10, ContextBlock.CodePtr(r6) mtctr r8 - bnel major_0x03e18_0x8 + + bnel IntHandleSpecialFPException + lwarx r8, 0, r1 sync stwcx. r8, 0, r1 - lwz r29, 0x00d8(r6) - lwz r8, 0x010c(r6) - cmpwi r29, 0x00 - stw r8, 0x0004(r1) - lwz r28, 0x0210(r29) - beq major_0x02980_0x2d0 - mtspr vrsave, r28 -major_0x02980_0x2d0 + lwz r29, ContextBlock.VectorSaveArea(r6) + lwz r8, ContextBlock.r1(r6) + cmpwi r29, 0 + stw r8, EWA.r1(r1) + lwz r28, 0x210(r29) + beq @no_vrsave + mtspr vrsave, r28 +@no_vrsave + lwz r2, 0x0114(r6) lwz r3, 0x011c(r6) lwz r4, 0x0124(r6) @@ -292,19 +337,19 @@ IntReturn ; OUTSIDE REFERER major_0x02ccc ; OUTSIDE REFERER - mtcrf 0x3f, r7 + mtcrf 0x3f, r7 - bc BO_IF_NOT, 27, @major_0x02ccc_0x18 - _bclr r7, r7, 27 + bc BO_IF_NOT, EWA.kFlagLowSaves, @major_0x02ccc_0x18 + _bclr r7, r7, EWA.kFlagLowSaves - bc BO_IF, 31, major_0x02ccc_0x30 - _bclr r7, r7, 26 + bc BO_IF, EWA.kFlag31, major_0x02ccc_0x30 + _bclr r7, r7, EWA.kFlag26 b @return @major_0x02ccc_0x18 - bc BO_IF_NOT, 26, @return - _bclr r7, r7, 26 + bc BO_IF_NOT, EWA.kFlag26, @return + _bclr r7, r7, EWA.kFlag26 stw r7, EWA.Flags(r1) li r8, ecInstTrace @@ -346,7 +391,7 @@ major_0x02ccc_0x30 lwz r21, 0x002c(r9) lwz r19, 0x0034(r9) lwz r18, 0x003c(r9) - _bclr r16, r7, 27 + _bclr r16, r7, EWA.kFlagLowSaves lwz r25, 0x0650(r8) rlwinm. r22, r17, 31, 27, 31 add r19, r19, r22 @@ -391,7 +436,7 @@ SuspendBlueTask _Lock PSA.SchLock, scratch1=r8, scratch2=r9 lwz r29, Task.Flags(r31) - _bset r29, r29, Task.kFlag22 + _bset r29, r29, Task.kFlagStopped _bset r29, r29, Task.kFlag19 stw r29, Task.Flags(r31) @@ -444,9 +489,17 @@ SuspendBlueTask -TaskApproachOne ; OUTSIDE REFERER +######## ### ###### ######## ######## ### ## ## ## ######## ###### +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## ## +######## ## ## ## #### ###### ###### ## ## ## ## ## ## ###### +## ######### ## ## ## ## ######### ## ## ## ## ## +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +## ## ## ###### ######## ## ## ## ####### ######## ## ###### - bcl BO_IF, 27, Local_Panic +_RecoverableCodeFault + + bcl BO_IF, EWA.kFlagLowSaves, Local_Panic bl SchSaveStartingAtR14 mr r30, r10 @@ -468,27 +521,27 @@ TaskApproachOne ; OUTSIDE REFERER srwi r8, r7, 24 rlwinm. r16, r16, 0, Task.kFlag9, Task.kFlag9 cmpwi cr1, r8, ecInstPageFault - bne TaskNotSuitableForWhatWeWantToDo - bne cr1, TaskNotSuitableForWhatWeWantToDo + bne _fault_throw_to_debugger + bne cr1, _fault_throw_to_debugger ; what is special about the upper 8 Flags? Are they Task-related? - lwz r8, Task.Zero3(r31) + lwz r8, Task.CodeFaultCtr(r31) addi r8, r8, 1 - stw r8, Task.Zero3(r31) + stw r8, Task.CodeFaultCtr(r31) - b CommonPathBetweenTaskIntFuncs + b _CommonFaultPath -TaskApproachTwo ; OUTSIDE REFERER +_RecoverableDataFault - bcl BO_IF_NOT, 27, Local_Panic + bcl BO_IF_NOT, EWA.kFlagLowSaves, Local_Panic bl PreferRegistersFromEWASavingContextBlock stw r10, ContextBlock.LA_EmulatorEntry(r6) - _bclr r7, r7, EWA.kFlag27 + _bclr r7, r7, EWA.kFlagLowSaves bl SchSaveStartingAtR14 @@ -510,23 +563,23 @@ TaskApproachTwo ; OUTSIDE REFERER srwi r8, r7, 24 rlwinm. r16, r16, 0, Task.kFlag9, Task.kFlag9 cmpwi cr1, r8, 0x14 - bne TaskNotSuitableForWhatWeWantToDo - bne cr1, TaskNotSuitableForWhatWeWantToDo + bne _fault_throw_to_debugger + bne cr1, _fault_throw_to_debugger - lwz r8, Task.Zero4(r31) + lwz r8, Task.DataFaultCtr(r31) addi r8, r8, 1 - stw r8, Task.Zero4(r31) + stw r8, Task.DataFaultCtr(r31) - -CommonPathBetweenTaskIntFuncs +_CommonFaultPath mfsprg r14, 0 _bclr r7, r7, EWA.kFlag26 _bclr r7, r7, EWA.kFlag31 + ; Panic if EWA.SpecialAreaPtr is invalid lwz r29, EWA.SpecialAreaPtr(r14) lisori r17, Area.kSignature lwz r16, Area.Signature(r29) @@ -544,21 +597,24 @@ CommonPathBetweenTaskIntFuncs cmpwi cr0, r9, ecInstPageFault cmpwi cr1, r16, 0 mr r26, r8 - bne cr0, CanSendMessage - beq cr1, CantSendMessage - beq cr2, CanSendMessage + bne cr0, @can_use_page_queue + beq cr1, @cannot_use_page_queue ; never seems to be taken (VMMaxVirtualPages never zero) + bc BO_IF, EWA.kFlagBlue, @can_use_page_queue + + + +@cannot_use_page_queue ; no, I'm wrong about this -- this code gets executed normally! -CantSendMessage lwz r16, Task.Flags(r31) addi r17, r31, Task.QueueMember - addi r18, r31, Task.Semaphore + addi r18, r31, Task.PageFaultSema stw r18, LLL.Freeform(r17) InsertAsPrev r17, r18, scratch=r19 li r17, 1 _bset r16, r16, Task.kFlag18 - stw r17, Task.Semaphore + Semaphore.Value(r31) + stw r17, Task.PageFaultSema + Semaphore.Value(r31) stw r16, Task.Flags(r31) rlwinm r30, r30, 0, 0, 19 @@ -575,44 +631,74 @@ CantSendMessage cmpwi r8, 0 beq IntLocalBlockMPCall ; jump if no error? -CanSendMessage + + + ; Block the task on its internal semaphore (the page fault semaphore) + +@can_use_page_queue + mfcr r28 li r8, Message.Size - beq cr2, major_0x02ccc_0x4a8 + bc BO_IF, EWA.kFlagBlue, @was_blues_fault + + + ; FAULT IN NON-BLUE TASK: send message to the page queue + bl PoolAlloc mr. r26, r8 - beq major_0x02ccc_PoolAllocFailed + beq @oom + + + ; Block the faulting NON-BLUE TASK on its own PageFaultSema, + ; put raise the semaphore, thus preparing it to unblock once + ; the latency-protected-priority blue task has served the fault addi r17, r31, Task.QueueMember - addi r18, r31, Task.Semaphore + addi r18, r31, Task.PageFaultSema stw r18, LLL.Freeform(r17) - InsertAsPrev r17, r18, scratch=r19 ; make this task wait on its own semaphore + InsertAsPrev r17, r18, scratch=r19 li r17, 1 - stw r17, Task.Semaphore + Semaphore.Value(r31) + stw r17, Task.PageFaultSema + Semaphore.Value(r31) + + + ; Via the Page Queue, tell the blue task what it needs to know - ; message = area ID, semaphore ID, address (page aligned?) lwz r27, Area.ID(r29) lisori r8, Message.kSignature - lwz r29, Task.Semaphore + Semaphore.BlockedTasks + LLL.Freeform(r31) - stw r27, Message.Word1(r26) - stw r29, Message.Word2(r26) + lwz r29, Task.PageFaultSema(r31) + stw r27, Message.Word1(r26) ; arg1 = area ID + stw r29, Message.Word2(r26) ; arg2 = sempahore ID in its BlockedTasks linked list stw r8, Message.LLL + LLL.Signature(r26) - stw r30, Message.Word3(r26) + stw r30, Message.Word3(r26) ; arg3 = page address mr r8, r26 addi r31, r1, PSA.PageQueue bl EnqueueMessage ; Message *r8, Queue *r31 - lwz r8, PSA.BlueSpinningOn(r1) + + + ; (Unconditionally) raise blue's priority to latency protection, and unblock it + + lwz r8, PSA.BlueSpinningOn(r1) ; this guarantees that blue will always be unblocked bl UnblockBlueIfCouldBePolling + + + ; Block the faulting task (this releases the scheduler lock) + b BlockMPCall -major_0x02ccc_0x4a8 + + + ; FAULT IN BLUE TASK: switch it over to the system context + +@was_blues_fault + mr r8, r31 bl SchRdyTaskNow _AssertAndRelease PSA.SchLock, scratch=r31 mtcr r28 - bns cr6, major_0x02ccc_0x504 + + bc BO_IF_NOT, EWA.kFlagLowSaves, @nolo lwz r8, 0x0064(r6) lwz r9, 0x0068(r6) stw r8, 0x0024(r6) @@ -623,14 +709,19 @@ major_0x02ccc_0x4a8 stw r9, 0x0034(r6) lwz r8, 0x007c(r6) stw r8, 0x003c(r6) - crclr EWA.kFlag27 + crclr EWA.kFlagLowSaves +@nolo -major_0x02ccc_0x504 ; r6 = ewa bl SchRestoreStartingAtR14 - b major_0x02980_0x178 + b _IntReturnToSystemContext + + +; We failed to service a page fault in a non-blue task, so just let it run +; Is this terrible? A don't-care? + +@oom -major_0x02ccc_PoolAllocFailed li r16, Task.kNominalPriority stb r16, Task.Priority(r31) mr r8, r31 @@ -638,8 +729,10 @@ major_0x02ccc_PoolAllocFailed bl FlagSchEval b BlockMPCall -TaskNotSuitableForWhatWeWantToDo - b FuncExportedFromTasks + + +_fault_throw_to_debugger + b ThrowTaskToDebugger @@ -777,7 +870,7 @@ major_0x03324_0x58 crclr cr5_so rlwimi r17, r26, 6, 26, 5 add r18, r18, r23 - blelr cr3 + bclr BO_IF_NOT, 13 neg r23, r23 add r18, r18, r23 blr @@ -916,7 +1009,7 @@ FDP_TableBase equ 0xa00 mtcr r26 rlwimi r17, r26, 6, 26, 5 crclr 23 ; unset bit 23 = cr5_so - bgelr cr3 ; jump now if bit 12 is off + bclr BO_IF_NOT, 12 ; jump now if bit 12 is off ; if bit 12 was on, turn on paging and fetch the offending insn ; and also activate the Red vector table @@ -1032,8 +1125,8 @@ IntDSIOtherOther_0xe0 IntDSIOtherOther_0x100 andis. r28, r31, 0x800 - addi r29, r1, 800 - bnel PagingFunc3 + addi r29, r1, KDP.BATs + 0xa0 + bnel PagingL2PWithBATs li r28, 0x43 and r28, r31, r28 cmpwi cr7, r28, 0x43 @@ -1093,7 +1186,7 @@ IntDSIOtherOther_0x1c8 mfsprg r28, 2 mtlr r28 beq IntDSIOtherOther_0x19c - li r8, ecDataInvalidAccess + li r8, ecDataInvalidAddress bge major_0x02980 li r8, ecDataPageFault b major_0x02980 @@ -1331,17 +1424,22 @@ IntDSIOther ; OUTSIDE REFERER rlwimi r7, r7, 27, 26, 26 kcReturnFromException ; OUTSIDE REFERER - ori r11, r11, 0x8000 - mtcrf 0x3f, r7 + + _bset r11, r11, MSR_EEbit + + mtcrf 0x3f, r7 cmplwi cr1, r3, 0x01 - blt cr4, major_0x04a20_0x18 + bc BO_IF, EWA.kFlagSIGP, _IntReturnFromSIGP + blt cr1, major_0x03be0_0x58 beq cr1, major_0x03be0_0x90 + + addi r8, r3, -0x20 - lwz r9, 0x0eac(r1) + lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionForcedCount(r1) cmplwi r8, 0xe0 - addi r9, r9, 0x01 - stw r9, 0x0eac(r1) + addi r9, r9, 1 + stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionForcedCount(r1) mfsprg r1, 0 rlwimi r7, r3, 24, 0, 7 blt major_0x03be0_0xe8 @@ -1354,7 +1452,7 @@ major_0x03be0_0x58 lwz r10, 0x0084(r6) rlwimi r7, r8, 0, 17, 7 lwz r8, 0x0044(r6) - rlwimi r11, r7, 0, 20, 23 + rlwimi r11, r7, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] stw r8, EWA.Enables(r1) andi. r8, r11, 0x900 lwz r12, 0x008c(r6) @@ -1365,16 +1463,16 @@ major_0x03be0_0x58 b IntReturn major_0x03be0_0x90 - lwz r9, 0x0ea8(r1) + lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionPropagateCount(r1) lwz r8, 0x0040(r6) - addi r9, r9, 0x01 - stw r9, 0x0ea8(r1) + addi r9, r9, 1 + stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.ExceptionPropagateCount(r1) mfsprg r1, 0 lwz r10, 0x0084(r6) rlwimi r7, r8, 0, 17, 7 lwz r8, 0x0044(r6) mtcrf 0x0f, r7 - rlwimi r11, r7, 0, 20, 23 + rlwimi r11, r7, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] stw r8, EWA.Enables(r1) lwz r12, 0x008c(r6) lwz r3, 0x0094(r6) @@ -1389,7 +1487,7 @@ major_0x03be0_0x90 lwz r18, 0x007c(r6) major_0x03be0_0xe8 - beq cr2, major_0x02980_0x178 + beq cr2, _IntReturnToSystemContext crclr cr6_so mfspr r10, srr0 li r8, ecTrapInstr @@ -1544,7 +1642,7 @@ major_0x03e18 ; OUTSIDE REFERER rlwinm. r8, r11, 0, 18, 18 bnelr -major_0x03e18_0x8 ; OUTSIDE REFERER +IntHandleSpecialFPException ; OUTSIDE REFERER lwz r8, 0x00e4(r6) rlwinm. r8, r8, 1, 0, 0 mfmsr r8 @@ -1595,7 +1693,7 @@ LoadFloatsFromContextBlock ; OUTSIDE REFERER -major_0x03e18_0xb4 ; OUTSIDE REFERER +bugger_around_with_floats ; OUTSIDE REFERER mfmsr r8 ori r8, r8, 0x2000 mtmsr r8 @@ -1807,114 +1905,162 @@ IntThermalEvent ; OUTSIDE REFERER +; We can assume that this is being called from the emulator + +; We accept a logical NCB ptr but the kernel needs a physical one. +; So we keep a four-entry cache in KDP, mapping logical NCB ptrs +; to physical ones. But when are there multiple alt contexts? + +; ARG flags? r3, mask r4 + align kIntAlign -kcRunAlternateContext ; OUTSIDE REFERER +kcRunAlternateContext mtcrf 0x3f, r7 - bcl BO_IF_NOT, 10, IntReturn + bcl BO_IF_NOT, EWA.kFlagBlue, IntReturn and. r8, r4, r13 - lwz r9, KDP.MinusOne1(r1) - rlwinm r8, r3, 0, 0, 25 + lwz r9, KDP.NCBCacheLA0(r1) + rlwinm r8, r3, 0, 0, 25 cmpw cr1, r8, r9 bne IntReturn - lwz r9, 0x0344(r1) - bne cr1, major_0x043a0_0x48 + lwz r9, KDP.NCBCachePA0(r1) + bne cr1, @search_cache -major_0x043a0_0x24 - addi r8, r1, 0x420 + +@found_physical_in_cache ; can come here from below after a more thorough search + + addi r8, r1, KDP.OrangeVecBase mtsprg 3, r8 - lwz r8, 0x0648(r1) - mtcrf 0x3f, r7 - mfsprg r1, 0 - clrlwi r7, r7, 0x08 - stw r8, 0x005c(r9) - stw r9, -0x0014(r1) - b major_0x02980_0x18c -major_0x043a0_0x48 - lwz r9, 0x0348(r1) - cmpw cr1, r8, r9 - beq cr1, major_0x043a0_0x130 - lwz r9, 0x0350(r1) - cmpw cr1, r8, r9 - beq cr1, major_0x043a0_0x110 - lwz r9, 0x0358(r1) - cmpw cr1, r8, r9 - beq cr1, major_0x043a0_0xf0 + lwz r8, KDP.LA_EmulatorKernelTrapTable(r1) + mtcrf 0x3f, r7 mfsprg r1, 0 - stmw r14, 0x0038(r1) - lwz r1, -0x0004(r1) + clrlwi r7, r7, 8 + stw r8, ContextBlock.LA_EmulatorKernelTrapTable(r9) + + stw r9, EWA.PA_ContextBlock(r1) + + b _IntReturnToOppositeContext + + +@search_cache + + lwz r9, KDP.NCBCacheLA1(r1) + cmpw cr1, r8, r9 + beq cr1, @found_in_slot_1 + + lwz r9, KDP.NCBCacheLA2(r1) + cmpw cr1, r8, r9 + beq cr1, @found_in_slot_2 + + lwz r9, KDP.NCBCacheLA3(r1) + cmpw cr1, r8, r9 + beq cr1, @found_in_slot_3 + + + ; No luck with the cache + + mfsprg r1, 0 + stmw r14, EWA.r14(r1) + lwz r1, EWA.PA_KDP(r1) + cmpw cr1, r8, r6 - beq cr1, major_0x043a0_0x154 + beq cr1, @fail + mr r27, r8 - addi r29, r1, 800 - bl PagingFunc3 - clrlwi r23, r8, 0x14 - beq major_0x043a0_0x154 - cmplwi r23, 0xd00 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs + clrlwi r23, r8, 20 + beq @fail + + cmplwi r23, 0x0d00 mr r9, r8 mr r8, r31 - ble major_0x043a0_0xc4 - addi r27, r27, 0x1000 - addi r29, r1, 800 - bl PagingFunc3 - beq major_0x043a0_0x154 - addi r31, r31, -0x1000 + ble @not_straddling_pages + + addi r27, r27, 0x1000 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs + beq @fail + + subi r31, r31, 0x1000 xor r23, r8, r31 - rlwinm. r23, r23, 0, 25, 22 - bne major_0x043a0_0x154 + rlwinm. r23, r23, 0, 25, 22 + bne @fail ; because physical pages are discontiguous +@not_straddling_pages + + clrlwi r23, r31, 30 + cmpwi r23, 3 + rlwimi r8, r9, 0, 20, 31 + beq @fail + + + ; Found a non-cached physical address for this NCB! + + lwz r23, KDP.NanoKernelInfo + NKNanoKernelInfo.NCBPtrCacheMissCount(r1) + addi r23, r23, 1 + stw r23, KDP.NanoKernelInfo + NKNanoKernelInfo.NCBPtrCacheMissCount(r1) + + + ; Stick it in cache slot 3 -major_0x043a0_0xc4 - clrlwi r23, r31, 0x1e - cmpwi r23, 0x03 - rlwimi r8, r9, 0, 20, 31 - beq major_0x043a0_0x154 - lwz r23, 0x0ea4(r1) - addi r23, r23, 0x01 - stw r23, 0x0ea4(r1) mfsprg r1, 0 - lmw r14, 0x0038(r1) - lwz r1, -0x0004(r1) - stw r8, 0x035c(r1) + lmw r14, EWA.r14(r1) + lwz r1, EWA.PA_KDP(r1) + stw r8, KDP.NCBCachePA3(r1) -major_0x043a0_0xf0 - lwz r8, 0x0350(r1) - stw r9, 0x0350(r1) - stw r8, 0x0358(r1) - lwz r9, 0x035c(r1) - lwz r8, 0x0354(r1) - stw r9, 0x0354(r1) - stw r8, 0x035c(r1) - lwz r9, 0x0350(r1) -major_0x043a0_0x110 - lwz r8, 0x0348(r1) - stw r9, 0x0348(r1) - stw r8, 0x0350(r1) - lwz r9, 0x0354(r1) - lwz r8, 0x034c(r1) - stw r9, 0x034c(r1) - stw r8, 0x0354(r1) - lwz r9, 0x0348(r1) +@found_in_slot_3 ; so promote to slot 2 -major_0x043a0_0x130 - lwz r8, 0x0340(r1) - stw r9, 0x0340(r1) - stw r9, 0x05b4(r1) - stw r8, 0x0348(r1) - lwz r9, 0x034c(r1) - lwz r8, 0x0344(r1) - stw r9, 0x0344(r1) - stw r8, 0x034c(r1) - b major_0x043a0_0x24 + lwz r8, KDP.NCBCacheLA2(r1) + stw r9, KDP.NCBCacheLA2(r1) + stw r8, KDP.NCBCacheLA3(r1) + + lwz r9, KDP.NCBCachePA3(r1) + lwz r8, KDP.NCBCachePA2(r1) + stw r9, KDP.NCBCachePA2(r1) + stw r8, KDP.NCBCachePA3(r1) + + lwz r9, KDP.NCBCacheLA2(r1) + + +@found_in_slot_2 ; so promote to slot 1 + + lwz r8, KDP.NCBCacheLA1(r1) + stw r9, KDP.NCBCacheLA1(r1) + stw r8, KDP.NCBCacheLA2(r1) + + lwz r9, KDP.NCBCachePA2(r1) + lwz r8, KDP.NCBCachePA1(r1) + stw r9, KDP.NCBCachePA1(r1) + stw r8, KDP.NCBCachePA2(r1) + + lwz r9, KDP.NCBCacheLA1(r1) + + +@found_in_slot_1 ; so promote to slot 0, save elsewhere, and push on + + lwz r8, KDP.NCBCacheLA0(r1) + stw r9, KDP.NCBCacheLA0(r1) + stw r9, KDP.LA_NCB(r1) + stw r8, KDP.NCBCacheLA1(r1) + + lwz r9, KDP.NCBCachePA1(r1) + lwz r8, KDP.NCBCachePA0(r1) + stw r9, KDP.NCBCachePA0(r1) + stw r8, KDP.NCBCachePA1(r1) + + b @found_physical_in_cache + + +@fail -major_0x043a0_0x154 mfsprg r1, 0 - lmw r14, 0x0038(r1) - lwz r1, -0x0004(r1) + lmw r14, EWA.r14(r1) + lwz r1, EWA.PA_KDP(r1) li r8, ecTrapInstr b major_0x02980_0x134 @@ -2104,25 +2250,15 @@ major_0x046d0 ; OUTSIDE REFERER +; For when the alternate context is running? + align kIntAlign -IntExternalOrange ; OUTSIDE REFERER -; r6 = saved at *(ewa + 0x18) -; sprg1 = saved at *(ewa + 4) -; rN (0,7,8,9,10,11,12,13, not r1) = saved at *(*(ewa - 0x14) + 0x104 + 8*N) - bl int_prepare -; r0 = 0 -; r1 = *(ewa - 4) -; r6 = kdp -; r7 = *(ewa - 0x10) # flags? -; r8 = ewa -; r10 = srr0 -; r11 = srr1 -; r12 = sprg2 -; r13 = cr +IntExternalOrange - mtcrf 0x3f, r7 - bnel cr2, Local_Panic + bl int_prepare + mtcrf 0x3f, r7 + bcl BO_IF_NOT, EWA.kFlagBlue, Local_Panic li r8, ecNoException b major_0x02980_0x134 @@ -2217,7 +2353,7 @@ IntProgram lwz r8, KDP.NanoKernelCallTable(r8) mtlr r8 addi r10, r10, 4 - rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlag22 into EWA.kFlag26 + rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlagBE into EWA.kFlag26 blr @nonemu_mpdispatch @@ -2231,7 +2367,7 @@ IntProgram ; Non-emu MPDispatch trap with r0 == -1: muck around a bit? addi r10, r10, 4 - rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlag22 into EWA.kFlag26 + rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlagBE into EWA.kFlag26 mfsprg r8, 0 rlwimi r13, r7, 8, 2, 2 lwz r9, EWA.PA_CurTask(r8) @@ -2282,27 +2418,17 @@ IntProgram bc BO_IF, 15, major_0x02980_0x134 ; if SRR0 points to subsequent instr addi r10, r10, 4 ; if SRR0 points to offending instr - rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlag22 into EWA.kFlag26 + rlwimi r7, r7, 27, 26, 26 ; copy EWA.kFlagBE into EWA.kFlag26 b major_0x02980_0x134 align kIntAlign -IntExternalYellow ; OUTSIDE REFERER +IntExternalYellow bl int_prepare - ; RET r0 = 0 - ; r1 = KernelData - ; r6 = ECB - ; r7 = AllCpuFeatures - ; r8 = EWA (pretend KDP) - ; r10 = SRR0 - ; r11 = SRR1 - ; r12 = LR from SPRG2 - ; r13 = CR - ; Sanity check @@ -2378,7 +2504,7 @@ SIGP lwz r16, EWA.PA_CurAddressSpace(r23) slwi r20, r3, 2 stw r16, EWA.SIGPSpacOnResume(r23) - bc BO_IF, 16, major_0x04a20_0x18 ; not sure about this + bc BO_IF, EWA.kFlagSIGP, _IntReturnFromSIGP ; not sure about this cmpwi cr2, r8, 0 lwz r18, EWA.SIGPSelector(r23) beq cr2, @args_in_registers @@ -2458,7 +2584,7 @@ SIGP srwi r3, r16, 2 ; Flags |= 0x8000 - ori r7, r7, 0x8000 + _bset r7, r7, EWA.kFlagSIGP mr r16, r6 stw r7, EWA.Flags(r23) @@ -2500,44 +2626,49 @@ major_0x04a20 ; OUTSIDE REFERER mfspr r10, srr0 mfspr r11, srr1 -major_0x04a20_0x18 ; OUTSIDE REFERER + + +_IntReturnFromSIGP + mfsprg r23, 0 - lwz r7, -0x02b0(r23) - andis. r8, r11, 0x02 + lwz r7, EWA.SIGPSavedR7(r23) + andis. r8, r11, 0x0002 ; MSR bit 14?? stw r7, -0x0010(r23) - bne major_0x04a20_0x30 - li r3, -0x7265 + bne @msr_14_set + li r3, -29285 +@msr_14_set -major_0x04a20_0x30 + ; Restore address space lwz r8, EWA.SIGPSpacOnResume(r23) - lwz r9, -0x001c(r23) + lwz r9, EWA.PA_CurAddressSpace(r23) cmpw r9, r8 - beq major_0x04a20_0x44 + beq @no_switch_space bl SchSwitchSpace +@no_switch_space -major_0x04a20_0x44 - lwz r10, -0x02d0(r23) - lwz r11, -0x02cc(r23) - lwz r12, -0x02c8(r23) - lwz r13, -0x02c4(r23) - lwz r8, -0x02c0(r23) - lwz r9, -0x02bc(r23) + lwz r10, EWA.SIGPSavedR10(r23) + lwz r11, EWA.SIGPSavedR11(r23) + lwz r12, EWA.SIGPSavedR12(r23) + lwz r13, EWA.SIGPSavedR13(r23) + lwz r8, EWA.SIGPSavedXER(r23) + lwz r9, EWA.SIGPSavedCTR(r23) mtxer r8 - lwz r8, -0x02b8(r23) - lwz r6, -0x02b4(r23) + lwz r8, EWA.SIGPSavedLR(r23) + lwz r6, EWA.SIGPSavedR6(r23) mtctr r9 - stw r6, -0x0014(r23) + stw r6, EWA.PA_ContextBlock(r23) mtlr r8 mr r8, r3 mr r9, r4 - lwz r16, 0x010c(r6) - lwz r2, 0x0114(r6) - lwz r3, 0x011c(r6) - lwz r4, 0x0124(r6) - lwz r5, 0x012c(r6) - lwz r17, 0x0134(r6) - stw r16, 0x0004(r23) - stw r17, 0x0018(r23) + lwz r16, ContextBlock.r1(r6) + lwz r2, ContextBlock.r2(r6) + lwz r3, ContextBlock.r3(r6) + lwz r4, ContextBlock.r4(r6) + lwz r5, ContextBlock.r5(r6) + lwz r17, ContextBlock.r6(r6) + stw r16, EWA.r1(r23) + stw r17, EWA.r6(r23) + blr @@ -2575,11 +2706,11 @@ IntSyscall ; OUTSIDE REFERER mfsprg r1, 0 bne @not_minus_1 - ; sc -1: mess around with flags + ; sc -1: quick-test whether "this task" is blue (cr0.eq if not blue) lwz r0, EWA.Flags(r1) mfsprg r1, 2 - rlwinm. r0, r0, 0, 10, 10 + rlwinm. r0, r0, 0, EWA.kFlagBlue, EWA.kFlagBlue mtlr r1 mfsprg r1, 1 rfi @@ -2605,23 +2736,6 @@ IntSyscall ; OUTSIDE REFERER bl int_prepare ; Save the usual suspects and get comfy -; Reg Contains Original saved in -; --------------------------------------------- -; r0 0 ContextBlock -; r1 KDP EWA -; r2 (itself) -; r3 (itself) -; r4 (itself) -; r5 (itself) -; r6 ContextBlock EWA -; r7 AllCpuFeatures ContextBlock -; r8 EWA ContextBlock -; r9 (itself) ContextBlock -; r10 SRR0 ContextBlock -; r11 SRR1 ContextBlock -; r12 LR ContextBlock -; r13 CR ContextBlock - lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.NanoKernelCallCounts + 32(r1) addi r9, r9, 1 stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.NanoKernelCallCounts + 8*4(r1) diff --git a/NanoKernel/NKMPCalls.s b/NanoKernel/NKMPCalls.s index 611afd1..6533efa 100644 --- a/NanoKernel/NKMPCalls.s +++ b/NanoKernel/NKMPCalls.s @@ -420,7 +420,7 @@ MPRegisterCpuPlugin ; r18 = physical address of plugin (assumes page-aligned) mr r27, r4 addi r29, r1, KDP.BATs + 0xa0 - bl PagingFunc3 + bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM rlwinm r18, r31, 0, 0, 19 @@ -428,7 +428,7 @@ MPRegisterCpuPlugin mr r27, r16 mr r19, r16 addi r29, r1, KDP.BATs + 0xa0 - bl PagingFunc3 + bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM rlwimi r19, r31, 0, 0, 19 @@ -448,7 +448,7 @@ MPRegisterCpuPlugin ; Get physical ptr to table of stack pointers (one per CPU) lwz r27, 0(r19) addi r29, r1, KDP.BATs + 0xa0 - bl PagingFunc3 + bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM rlwimi r27, r31, 0, 0, 19 stw r27, CoherenceGroup.PA_CpuPluginStackPtrs(r14) @@ -474,7 +474,7 @@ MPRegisterCpuPlugin @table_convert_loop lwzu r27, 4(r16) addi r29, r1, KDP.BATs + 0xa0 - bl PagingFunc3 + bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM subi r17, r17, 1 rlwimi r27, r31, 0, 0, 19 @@ -1285,7 +1285,7 @@ KCStartCPU ; OUTSIDE REFERER rlwinm r7, r7, 0, 13, 11 lwz r8, PSA.blueProcessPtr(r1) -; ARG GlobalCPUFlags r7, Process *r8 +; ARG Flags r7, Process *r8 bl CreateTask ; RET Task *r8 @@ -1456,7 +1456,7 @@ MPCpuPlugin DeclareMPCall 47, MPCall_47 MPCall_47 ; OUTSIDE REFERER - rlwinm. r8, r7, 0, 12, 12 + rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec lwz r15, 0x00d8(r6) beq ReturnMPCallOOM cmpwi r15, 0x00 @@ -1635,7 +1635,7 @@ KCMarkPMFTask ; OUTSIDE REFERER ; Insert bit 31 of r4 into bit 21 of these flags lwz r17, Task.Flags(r31) - rlwimi r17, r4, 10, Task.kFlagPMF, Task.kFlagPMF + rlwimi r17, r4, 10, Task.kFlagPerfMon, Task.kFlagPerfMon stw r17, Task.Flags(r31) diff --git a/NanoKernel/NKMacros.s b/NanoKernel/NKMacros.s index b3b0c73..f4fdbed 100644 --- a/NanoKernel/NKMacros.s +++ b/NanoKernel/NKMacros.s @@ -287,3 +287,18 @@ _bclr_lbit set 31 ENDIF ENDM + + + MACRO + _InvalNCBPointerCache &scratch==r0, &offset==0 + + IF &offset = 0 + li &scratch, -1 + ENDIF + + IF KDP.NCBPointerCache + &offset < KDP.NCBPointerCacheEnd + stw &scratch, KDP.NCBPointerCache + &offset(r1) + _InvalNCBPointerCache scratch=&scratch, offset=(&offset+8) + ENDIF + + ENDM diff --git a/NanoKernel/NKPaging.s b/NanoKernel/NKPaging.s index 69f4dd4..1c38401 100644 --- a/NanoKernel/NKPaging.s +++ b/NanoKernel/NKPaging.s @@ -356,11 +356,9 @@ PagingFunc1 ; OUTSIDE REFERER @_4b0 sync isync - li r8, -0x01 - stw r8, 0x0340(r1) - stw r8, 0x0348(r1) - stw r8, 0x0350(r1) - stw r8, 0x0358(r1) + + _InvalNCBPointerCache scratch=r8 + mfsprg r8, 0 mr r9, r28 lwz r8, -0x001c(r8) @@ -598,7 +596,7 @@ PagingFunc2AndAHalf -PagingFunc3 ; OUTSIDE REFERER +PagingL2PWithBATs ; OUTSIDE REFERER lwz r30, 0x0000(r29) li r28, -0x01 rlwimi r28, r30, 15, 0, 14 @@ -619,7 +617,7 @@ PagingFunc3 ; OUTSIDE REFERER rlwimi r28, r30, 15, 0, 14 xor r31, r27, r30 andc. r31, r31, r28 - bne PagingFunc4 + bne PagingL2PWithoutBATs @_54 andi. r31, r30, 0x01 @@ -631,7 +629,7 @@ PagingFunc3 ; OUTSIDE REFERER -PagingFunc4 ; OUTSIDE REFERER +PagingL2PWithoutBATs ; OUTSIDE REFERER mfsrin r31, r27 rlwinm r30, r27, 10, 26, 31 rlwimi r30, r31, 7, 1, 24 diff --git a/NanoKernel/NKPrimaryIntHandlers.s b/NanoKernel/NKPrimaryIntHandlers.s index 5569523..36a25f1 100644 --- a/NanoKernel/NKPrimaryIntHandlers.s +++ b/NanoKernel/NKPrimaryIntHandlers.s @@ -141,13 +141,13 @@ CommonPIHPath_0xc ; OUTSIDE REFERER or r31, r31, r30 stw r31, PSA.MCR(r1) - sth r28, PSA.Int(r1) + sth r28, PSA.Pending68kInt(r1) lwz r31, PSA.PA_BlueTask(r1) mfsprg r30, 0 lwz r28, Task.Flags(r31) lbz r29, Task.State(r31) - _bset r28, r28, Task.kFlag68kInterrupt + _bset r28, r28, Task.kFlagSchToInterruptEmu stw r28, Task.Flags(r31) cmpwi r29, 0 diff --git a/NanoKernel/NKRTASCalls.s b/NanoKernel/NKRTASCalls.s index 620af05..4b89a2c 100644 --- a/NanoKernel/NKRTASCalls.s +++ b/NanoKernel/NKRTASCalls.s @@ -25,7 +25,7 @@ rtas_is_available _Lock PSA.RTASLock, scratch1=r8, scratch2=r9 - mtcrf 0x3f, r7 + mtcrf 0x3f, r7 lwz r9, KDP.PA_ECB(r1) lwz r8, EWA.Enables(r1) stw r7, 0x0000(r6) @@ -80,11 +80,11 @@ kcRTASDispatch_0x8c stw r29, 0x01ec(r6) stw r30, 0x01f4(r6) stw r31, 0x01fc(r6) - bnel major_0x03e18_0xb4 + bnel bugger_around_with_floats stw r11, 0x00a4(r6) mr r27, r3 - addi r29, r1, 800 - bl PagingFunc3 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs beql Local_Panic rlwimi r3, r31, 0, 0, 19 lhz r8, 0x0004(r3) @@ -92,8 +92,8 @@ kcRTASDispatch_0x8c beq kcRTASDispatch_0x14c slwi r8, r8, 2 lwzx r27, r8, r3 - addi r29, r1, 800 - bl PagingFunc3 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs beql Local_Panic lwzx r9, r8, r3 rlwimi r9, r31, 0, 0, 19 @@ -142,7 +142,7 @@ kcRTASDispatch_0x190 lwz r8, 0x00f4(r6) lwz r10, 0x00fc(r6) mtctr r8 - bnel major_0x03e18_0x8 + bnel IntHandleSpecialFPException lwz r8, 0x010c(r6) stw r8, 0x0004(r1) lwz r2, 0x0114(r6) diff --git a/NanoKernel/NKReplacementInit.s b/NanoKernel/NKReplacementInit.s index 15fb42c..79fd99f 100644 --- a/NanoKernel/NKReplacementInit.s +++ b/NanoKernel/NKReplacementInit.s @@ -185,15 +185,15 @@ InitReplacement lwz r12, 0x0340(r11) - lwz r10, 0x05b4(r11) + lwz r10, KDP.LA_NCB(r11) cmpw r12, r10 beq replace_old_kernel_0x198 - stw r12, 0x05b4(r1) + stw r12, KDP.LA_NCB(r1) stw r0, 0x06b4(r1) lwz r10, 0x05b0(r11) stw r10, 0x06c0(r1) - lwz r10, 0x05b4(r11) + lwz r10, KDP.LA_NCB(r11) stw r10, 0x06c4(r1) lwz r10, 0x05b8(r11) stw r10, 0x06c8(r1) diff --git a/NanoKernel/NKScheduler.s b/NanoKernel/NKScheduler.s index 08a67f3..0b8d04b 100644 --- a/NanoKernel/NKScheduler.s +++ b/NanoKernel/NKScheduler.s @@ -850,7 +850,7 @@ SchSwitchSpace bne Local_Panic ; Intend to skip the dssall instruction if Altivec is... present? absent? - rlwinm. r16, r7, 0, 12, 12 ; seems to be leftover from Init.s Altivec testing + rlwinm. r16, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; seems to be leftover from Init.s Altivec testing ; Apply the address space to the segment registers isync @@ -1144,6 +1144,8 @@ SchReturn ; Either fallen through from SchReturn, or jumped to by ; TrulyCommonMPCallReturnPath when it wants to block the caller +; SchLock should be acquired before now! + SchEval mfsprg r14, 0 @@ -1240,6 +1242,7 @@ major_0x142dc_0xd8 ; OUTSIDE REFERER major_0x142dc_0x140 lwz r25, 0x0064(r30) li r26, 0x00 + rlwinm. r8, r25, 0, 21, 22 andc r27, r25, r8 beq+ major_0x142dc_0x184 @@ -1251,12 +1254,16 @@ major_0x142dc_0x140 stw r25, 0x0000(r26) InsertAsPrev r26, r25, scratch=r27 b major_0x142dc_0x58 - major_0x142dc_0x184 + cmpw cr3, r30, r31 rlwinm. r8, r25, 0, 27, 27 - bne cr3, major_0x14548 - bne major_0x14548 + bne cr3, _SchPreempt + bne _SchPreempt + + + ; Don't preempt, keep running the same task + bl GetTime bl major_0x148ec lwz r27, 0x0064(r31) @@ -1280,34 +1287,9 @@ major_0x142dc_0x1bc -######## ######## #### -## ## ## ## -## ## ## ## -######## ###### ## -## ## ## ## -## ## ## ## -## ## ## #### +; SchLock should be released before here -; SchExitInterrupt - -; All MPCalls get here? -; r0,7,8,9,10,11,12,13 restored from r6 area -; r1,6 restored from sprg0 area -; Apple used the "reserved" (not first three) bits of XER. -; If bit 27 of 0xedc(r1) is set: -; Bit 22 of XER is cleared -; Bit 10 of r7 is inserted into XER at bit 23 - -; > sprg0 = for r1 and r6 -; > r1 = kdp -; > r6 = register restore area -; > r7 = flag to insert into XER -; > r10 = new srr0 (return location) -; > r11 = new srr1 -; > r12 = lr restore -; > r13 = cr restore - -SchExitInterrupt ; OUTSIDE REFERER +SchExitInterrupt lwz r8, 0x0edc(r1) mfsprg r1, 0 mtlr r12 @@ -1338,157 +1320,231 @@ SchExitInterrupt_0x2c -major_0x14548 ; OUTSIDE REFERER - lwz r16, 0x0064(r31) - stw r30, -0x0260(r14) - rlwinm r16, r16, 0, 27, 25 - stw r6, 0x0088(r31) - mfsprg r8, 3 - stw r16, 0x0064(r31) - stw r8, 0x00f0(r31) - lwz r8, -0x000c(r14) - stw r7, 0x0000(r6) - stw r8, 0x0004(r6) - mfxer r8 - stw r13, 0x00dc(r6) - stw r8, 0x00d4(r6) - stw r12, 0x00ec(r6) - mfctr r8 - stw r10, 0x00fc(r6) - stw r8, 0x00f4(r6) - mfspr r8, pvr - rlwinm. r8, r8, 0, 0, 14 - bne major_0x14548_0x58 - mfspr r8, mq - stw r8, 0x00c4(r6) +; ARG outgoing_cb *r6, EWA *r14, incoming_task *r30, task_to_save_to *r31 -major_0x14548_0x58 - lwz r8, 0x0004(r14) - stw r8, 0x010c(r6) - stw r2, 0x0114(r6) - stw r3, 0x011c(r6) - andi. r8, r11, 0x2000 - stw r4, 0x0124(r6) - lwz r8, 0x0018(r14) - stw r5, 0x012c(r6) - stw r8, 0x0134(r6) +_SchPreempt + + ; Save info for the previous task + + lwz r16, Task.Flags(r31) + stw r30, EWA.SchSavedIncomingTask(r14) ; will clobber r30 + _bclr r16, r16, Task.kFlag26 + stw r6, Task.ContextBlockPtr(r31) + mfsprg r8, 3 + stw r16, Task.Flags(r31) + stw r8, Task.YellowVecTblPtr(r31) + + + ; Spam its context block + + lwz r8, EWA.Enables(r14) + stw r7, ContextBlock.Flags(r6) + stw r8, ContextBlock.Enables(r6) + mfxer r8 + stw r13, ContextBlock.CR(r6) + stw r8, ContextBlock.XER(r6) + stw r12, ContextBlock.LR(r6) + mfctr r8 + stw r10, ContextBlock.CodePtr(r6) + stw r8, ContextBlock.KernelCTR(r6) + + mfspr r8, pvr + rlwinm. r8, r8, 0, 0, 14 + bne @not_601 + mfspr r8, mq + stw r8, ContextBlock.MQ(r6) +@not_601 + + lwz r8, EWA.r1(r14) + stw r8, ContextBlock.r1(r6) + stw r2, ContextBlock.r2(r6) + stw r3, ContextBlock.r3(r6) + andi. r8, r11, MSR_FP + stw r4, ContextBlock.r4(r6) + lwz r8, EWA.r6(r14) + stw r5, ContextBlock.r5(r6) + stw r8, ContextBlock.r6(r6) bnel Save_f0_f31 - lwz r31, -0x0008(r14) - lwz r30, -0x0260(r14) - rlwinm. r8, r7, 0, 12, 12 + + lwz r31, EWA.PA_CurTask(r14) ; sly aside: r30 = new, r31 = current + lwz r30, EWA.SchSavedIncomingTask(r14) + + rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec bnel Save_v0_v31 - stw r11, 0x00a4(r6) - lwz r8, 0x00e8(r31) - addi r8, r8, 0x01 - stw r8, 0x00e8(r31) + stw r11, ContextBlock.MSR(r6) + + + ; Bump current task's preemption ctr + + lwz r8, Task.PreemptCtr(r31) + addi r8, r8, 1 + stw r8, Task.PreemptCtr(r31) + + + ; No clue + bl GetTime bl major_0x148ec + + + ; Update EWA global to match this task, and set task's state to 2 mfsprg r14, 0 - li r27, 0x02 - lbz r28, 0x0019(r30) - stb r27, 0x0018(r30) - stb r28, -0x0117(r14) + li r27, 2 + lbz r28, Task.Priority(r30) + stb r27, Task.State(r30) + stb r28, EWA.TaskPriority(r14) + + ; If incoming task is not already running, and running task is not in a queue, re-ready the running task cmplw r30, r31 - lwz r16, 0x0010(r31) - beq major_0x14548_0xd4 - cmpwi r16, 0x00 + lwz r16, Task.QueueMember + LLL.Next(r31) + beq @no + cmpwi r16, 0 mr r8, r31 beql SchRdyTaskNow -major_0x14548_0xd4 +@no + + + ; Play more with the incoming task mfsprg r19, 0 - li r8, 0x00 + + li r8, 0 stb r8, EWA.SchEvalFlag(r19) + lhz r8, EWA.CPUIndex(r19) - lwz r6, 0x0088(r30) - lwz r28, -0x0340(r19) - sth r8, 0x001a(r30) - stw r28, 0x0078(r30) - stw r30, -0x0008(r19) - stw r6, -0x0014(r19) - lwz r7, 0x0000(r6) - lwz r28, 0x0004(r6) - stw r7, -0x0010(r19) - stw r28, -0x000c(r19) - lwz r27, 0x0064(r30) - lwz r13, 0x00dc(r6) - ori r27, r27, 0x20 + lwz r6, Task.ContextBlockPtr(r30) + lwz r28, EWA.CPUBase + CPU.ID(r19) + sth r8, Task.CPUIndex(r30) + stw r28, Task.CpuID(r30) + + stw r30, EWA.PA_CurTask(r19) + + stw r6, EWA.PA_ContextBlock(r19) + + lwz r7, ContextBlock.Flags(r6) + lwz r28, ContextBlock.Enables(r6) + stw r7, EWA.Flags(r19) + stw r28, EWA.Enables(r19) + + lwz r27, Task.Flags(r30) + lwz r13, ContextBlock.CR(r6) + ori r27, r27, 1 << (31 - Task.kFlag26) lwz r11, 0x00a4(r6) lwz r8, 0x00f0(r30) rlwimi r11, r27, 24, 29, 29 rlwinm r27, r27, 0, 9, 7 mtsprg 3, r8 - stw r27, 0x0064(r30) - lwz r18, 0x0070(r30) - lwz r9, -0x001c(r19) + stw r27, Task.Flags(r30) + + + ; Switch address space if necessary + + lwz r18, Task.AddressSpacePtr(r30) + lwz r9, EWA.PA_CurAddressSpace(r19) cmpw r18, r9 - beq major_0x14548_0x148 + beq @same_space mr r8, r18 bl SchSwitchSpace +@same_space + -major_0x14548_0x148 mfsprg r19, 0 + + + ; Is this the blue task? If so, do we need to interrupt it? + mtcr r7 - lis r28, 0x00 - ori r28, r28, 0x10 - bne cr2, major_0x14548_0x20c + lisori r28, 1 << (31 - Task.kFlagSchToInterruptEmu) + bc BO_IF_NOT, EWA.kFlagBlue, @NO_BLUE_INTERRUPT and. r28, r28, r27 - li r8, 0x00 - beq major_0x14548_0x20c + li r8, 0 + beq @NO_BLUE_INTERRUPT + + + ; TRIGGER AN INTERRUPT IN THE BLUE TASK + andc r27, r27, r28 lwz r29, PSA.MCR(r1) - stw r27, 0x0064(r30) + stw r27, Task.Flags(r30) ; unset the task flag that got us here stw r8, PSA.MCR(r1) - blt cr2, major_0x14548_0x1cc - bsol cr6, Local_Panic - clrlwi r8, r7, 0x08 - stw r8, 0x0000(r6) + bc BO_IF, EWA.kFlagEmu, @already_in_system_context + bcl BO_IF, 27, Local_Panic + + + ; Need to switch blue task from alternate context to system context + + clrlwi r8, r7, 8 + stw r8, ContextBlock.Flags(r6) + lwz r6, KDP.PA_ECB(r1) - addi r26, r1, 0x360 + + addi r26, r1, KDP.YellowVecBase mtsprg 3, r26 - stw r26, 0x00f0(r30) - stw r6, -0x0014(r19) - stw r6, 0x0088(r30) - lwz r7, 0x0000(r6) - lwz r26, 0x0004(r6) + stw r26, Task.YellowVecTblPtr(r30) + + stw r6, EWA.PA_ContextBlock(r19) + stw r6, Task.ContextBlockPtr(r30) + + lwz r7, ContextBlock.Flags(r6) + lwz r26, ContextBlock.Enables(r6) mtcr r7 - stw r26, -0x000c(r19) - lwz r13, 0x00dc(r6) - lwz r11, 0x00a4(r6) - bsol cr6, Local_Panic - rlwimi r11, r7, 0, 20, 23 - rlwimi r7, r8, 0, 9, 16 - rlwimi r11, r27, 24, 29, 29 - stw r7, -0x0010(r19) + stw r26, EWA.Enables(r19) + + lwz r13, ContextBlock.CR(r6) + lwz r11, ContextBlock.MSR(r6) + + bcl BO_IF, 27, Local_Panic + + rlwimi r11, r7, 0, 20, 23 ; apply MSR[FE0/SE/BE/FE1] + rlwimi r7, r8, 0, 9, 16 ; keep flags 9-16 from alternate context + rlwimi r11, r27, 24, 29, 29 ; MSR[PMM] = Task.kFlagPerfMon + + stw r7, EWA.Flags(r19) +@already_in_system_context + + + ; Blue task now (or was already) in system context (i.e. 68k emulator is running) -major_0x14548_0x1cc lwz r17, ContextBlock.PriorityShifty(r6) - ori r17, r17, 0x100 + ori r17, r17, 0x100 stw r17, ContextBlock.PriorityShifty(r6) - lhz r17, -0x043c(r1) - lwz r18, 0x067c(r1) - cmplwi r17, 0xffff - lwz r26, KDP.PostIntMaskInit(r1) - beq major_0x14548_0x1f8 - sth r17, 0x0000(r18) - li r17, -0x01 - sth r17, -0x043c(r1) -major_0x14548_0x1f8 - cmpwi r29, 0x00 + + ; EDP.INTM_L = PSA.Pending68kInt (presumably the emulator polls this) + + lhz r17, PSA.Pending68kInt(r1) + lwz r18, KDP.PA_EmulatorIplValue(r1) + cmplwi r17, 0xffff ; i.e. (short)(-1) + lwz r26, KDP.PostIntMaskInit(r1) + beq @no_change_to_int_level ; would this ever happen? + + sth r17, 0(r18) + li r17, -1 + sth r17, PSA.Pending68kInt(r1) +@no_change_to_int_level + + + ; Fiddle with the emulator's Condition Register ("int mask") + + cmpwi r29, 0 or r13, r13, r29 - bne major_0x14548_0x20c + bne @did_set_bits_in_mask lwz r29, KDP.ClearIntMaskInit(r1) and r13, r13, r29 +@did_set_bits_in_mask + +@NO_BLUE_INTERRUPT + + + ; Back to the common path for preemption (pretty boring) -major_0x14548_0x20c lwz r29, 0x00d8(r6) cmpwi r29, 0x00 lwz r8, 0x0210(r29) - beq major_0x14548_0x220 + beq _SchPreempt_0x220 mtspr vrsave, r8 +_SchPreempt_0x220 -major_0x14548_0x220 lwz r8, 0x00d4(r6) lwz r12, 0x00ec(r6) mtxer r8 @@ -1497,11 +1553,11 @@ major_0x14548_0x220 mtctr r8 mfspr r8, pvr rlwinm. r8, r8, 0, 0, 14 - bne major_0x14548_0x24c + bne _SchPreempt_0x24c lwz r8, 0x00c4(r6) mtspr mq, r8 -major_0x14548_0x24c +_SchPreempt_0x24c li r9, 0x124 lwz r8, 0x010c(r6) dcbt r9, r6 @@ -1539,7 +1595,8 @@ major_0x14548_0x24c lwz r29, 0x01ec(r6) lwz r30, 0x01f4(r6) lwz r31, 0x01fc(r6) - beq major_0x14548_0x380 + + beq _SchPreempt_0x380 mfmsr r8 ori r8, r8, 0x2000 ori r11, r11, 0x2000 @@ -1579,18 +1636,10 @@ major_0x14548_0x24c lfd f29, 0x02e8(r6) lfd f30, 0x02f0(r6) lfd f31, 0x02f8(r6) +_SchPreempt_0x380 -major_0x14548_0x380 _AssertAndRelease PSA.SchLock, scratch=r8 -; sprg0 = for r1 and r6 -; r1 = kdp -; r6 = register restore area -; r7 = flag to insert into XER -; r10 = new srr0 (return location) -; r11 = new srr1 -; r12 = lr restore -; r13 = cr restore b SchExitInterrupt diff --git a/NanoKernel/NKScreenConsole.s b/NanoKernel/NKScreenConsole.s index 32ee9b1..42ae84e 100644 --- a/NanoKernel/NKScreenConsole.s +++ b/NanoKernel/NKScreenConsole.s @@ -196,7 +196,7 @@ major_0x18c08 ; OUTSIDE REFERER mfsrin r31, r27 cmpwi r31, 0x00 beqlr - b PagingFunc4 + b PagingL2PWithoutBATs diff --git a/NanoKernel/NKSleep.s b/NanoKernel/NKSleep.s index 52bd06d..9ba13ad 100644 --- a/NanoKernel/NKSleep.s +++ b/NanoKernel/NKSleep.s @@ -88,8 +88,8 @@ MPGetKernelState stw r5, ContextBlock.r5(r6) stw r8, ContextBlock.r6(r6) bnel Save_f0_f31 - rlwinm. r8, r7, 0, 12, 12 ; flags - bnel Save_v0_v31 + rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; flags + bnel+ Save_v0_v31 lwz r3, ContextBlock.r3(r6) lwz r4, ContextBlock.r4(r6) @@ -97,8 +97,8 @@ MPGetKernelState stw r11,ContextBlock.MSR(r6) mr r27, r5 - addi r29, r1, 800 - bl PagingFunc3 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs beq Local_ReturnInsufficientResourcesErrFromMPCall rlwimi r27, r31, 0, 0, 19 mr r17, r27 @@ -107,8 +107,8 @@ MPGetKernelState MPGetKernelState_0xc8 mr r27, r5 - addi r29, r1, 800 - bl PagingFunc3 + addi r29, r1, KDP.BATs + 0xa0 + bl PagingL2PWithBATs beq Local_ReturnInsufficientResourcesErrFromMPCall rlwimi r27, r31, 0, 0, 19 stwu r27, 0x0004(r15) diff --git a/NanoKernel/NKSync.s b/NanoKernel/NKSync.s index a346d3a..affc1ff 100644 --- a/NanoKernel/NKSync.s +++ b/NanoKernel/NKSync.s @@ -1608,7 +1608,7 @@ SetEvent lwz r16, Task.Flags(r26) lbz r19, Task.State(r26) - ori r16, r16, (1 << (31 - Task.kFlag68kInterrupt)) + ori r16, r16, (1 << (31 - Task.kFlagSchToInterruptEmu)) stw r16, Task.Flags(r26) ; But what *is* MCR? @@ -2595,23 +2595,23 @@ UnblockBlueIfCouldBePolling cmpwi r17, 0 addi r16, r19, Task.QueueMember - bne major_0x0dce8_0x70 + bne @blue_already_running RemoveFromList r16, scratch1=r17, scratch2=r18 lbz r17, Task.Timer + Timer.Byte3(r19) cmpwi r17, 1 - bne major_0x0dce8_0x60 + bne @no_timer_to_dequeue addi r8, r19, Task.Timer bl DequeueTimer lwz r19, PSA.PA_BlueTask(r1) -major_0x0dce8_0x60 +@no_timer_to_dequeue - li r16, 0x01 - stb r16, 0x0019(r19) + li r16, Task.kLatencyProtectPriority + stb r16, Task.Priority(r19) lwz r8, PSA.PA_BlueTask(r1) bl SchRdyTaskNow -major_0x0dce8_0x70 +@blue_already_running lwz r8, PSA.PA_BlueTask(r1) mtlr r24 diff --git a/NanoKernel/NKTasks.s b/NanoKernel/NKTasks.s index d8cca32..9a924bb 100644 --- a/NanoKernel/NKTasks.s +++ b/NanoKernel/NKTasks.s @@ -82,7 +82,7 @@ MPCall_7 ; OUTSIDE REFERER -; ARG GlobalCPUFlags r7, Process *r8 +; ARG Flags r7, Process *r8 ; RET Task *r8 CreateTask @@ -132,7 +132,7 @@ CreateTask ; Create a semaphore struct inside the task - addi r16, r28, Task.Semaphore + addi r16, r28, Task.PageFaultSema _lstart r17, Semaphore.kSignature stw r16, Semaphore.BlockedTasks + LLL.Next(r16) _lfinish @@ -140,23 +140,23 @@ CreateTask stw r17, Semaphore.BlockedTasks + LLL.Signature(r16) li r16, 1 - stw r16, Task.Semaphore + Semaphore.MaxValue(r28) + stw r16, Task.PageFaultSema + Semaphore.MaxValue(r28) li r16, 0 - stw r16, Task.Semaphore + Semaphore.Value(r28) + stw r16, Task.PageFaultSema + Semaphore.Value(r28) - addi r8, r28, Task.Semaphore + addi r8, r28, Task.PageFaultSema li r9, Semaphore.kIDClass bl MakeID cmpwi r8, 0 beq @fail_semq_no_id - stw r8, Task.Semaphore + Semaphore.BlockedTasks + LLL.Freeform(r28) + stw r8, Task.PageFaultSema + Semaphore.BlockedTasks + LLL.Freeform(r28) ; Allocate a vector (i.e. AltiVec) save area ; Conditionally, that is - rlwinm. r8, r7, 0, PSA.AVFeatureBit, PSA.AVFeatureBit + rlwinm. r8, r7, 0, 1 << (31 - EWA.kFlagVec) beq @non_altivec_task ; Allocate and check @@ -220,7 +220,7 @@ CreateTask addi r16, r28, Task.ContextBlock stw r16, Task.ContextBlockPtr(r28) ; overridden to real ECB on blue - lwz r16, PSA.GlobalCPUFlags(r1) + lwz r16, PSA.FlagsTemplate(r1) stw r16, Task.ContextBlock + ContextBlock.Flags(r28) lwz r16, PSA.UserModeMSR(r1) @@ -239,9 +239,9 @@ CreateTask li r16, 0 stw r16, Task.Zero1(r28) stw r16, Task.Zero2(r28) - stw r16, Task.Zero3(r28) - stw r16, Task.Zero4(r28) - stw r16, Task.Zero5(r28) + stw r16, Task.CodeFaultCtr(r28) + stw r16, Task.DataFaultCtr(r28) + stw r16, Task.PreemptCtr(r28) ; Who knows that these are for bl GetTime @@ -656,10 +656,10 @@ MPThrowException mtcr r16 li r3, kMPTaskAbortedErr - bc BO_IF, 30, ReleaseAndReturnMPCall + bc BO_IF, Task.kFlagAborted, ReleaseAndReturnMPCall li r3, kMPTaskStoppedErr - bc BO_IF, 22, ReleaseAndReturnMPCall + bc BO_IF, Task.kFlagStopped, ReleaseAndReturnMPCall bc BO_IF, 14, ReleaseAndReturnMPCallOOM @@ -777,7 +777,7 @@ MPCall_58_0xe0 -FuncExportedFromTasks ; OUTSIDE REFERER +ThrowTaskToDebugger ; OUTSIDE REFERER addi r16, r1, PSA.DbugQueue addi r17, r31, Task.QueueMember stw r16, LLL.Freeform(r17) @@ -785,13 +785,13 @@ FuncExportedFromTasks ; OUTSIDE REFERER li r8, 0x1c bl PoolAlloc lwz r29, Task.Flags(r31) - _bset r29, r29, 22 + _bset r29, r29, Task.kFlagStopped MPCall_58_0x114 mtcr r29 mr r28, r8 - bc BO_IF, 14, MPCall_58_0x13c - bc BO_IF, 20, MPCall_58_0x13c + bc BO_IF, Task.kFlag14, MPCall_58_0x13c + bc BO_IF, Task.kFlag20, MPCall_58_0x13c lwz r8, -0x08e8(r1) ; r8 = id @@ -799,10 +799,10 @@ MPCall_58_0x114 cmpwi r9, Queue.kIDClass mr r30, r8 - ori r29, r29, 0x800 + _bset r29, r29, Task.kFlag20 beq MPCall_58_0x184 - MPCall_58_0x13c + bc BO_IF, 19, MPCall_58_0x158 lwz r8, 0x00f4(r31) @@ -811,7 +811,7 @@ MPCall_58_0x13c cmpwi r9, Queue.kIDClass mr r30, r8 - ori r29, r29, 0x1000 + _bset r29, r29, Task.kFlag19 beq MPCall_58_0x184 MPCall_58_0x158 @@ -1001,7 +1001,7 @@ MPCall_60_0x144 MPCall_60_0x150 lwz r16, 0x0088(r31) - rlwinm. r8, r7, 0, 12, 12 + rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec lwz r16, 0x00d8(r16) beq ReleaseAndReturnMPCallOOM cmplwi cr3, r16, 0x00 @@ -1299,7 +1299,7 @@ MPCall_61_0xd8 MPCall_61_0xe8 lwz r16, 0x0088(r31) - rlwinm. r8, r7, 0, 12, 12 + rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec lwz r16, 0x00d8(r16) beq ReleaseAndReturnMPCallOOM cmplwi cr3, r16, 0x00 @@ -1399,7 +1399,7 @@ MPCall_61_0x1ec MPCall_61_0x1fc li r21, 0x04 lwz r18, 0x00a4(r16) - rlwimi r18, r17, 0, 20, 23 + rlwimi r18, r17, 0, 20, 23 ; MSR[FE0/SE/BE/FE1] rlwimi r18, r17, 0, 31, 31 stw r18, 0x00a4(r16) stw r21, 0x0154(r6) diff --git a/NanoKernel/NKThud.s b/NanoKernel/NKThud.s index 8c6c7c3..6f76826 100644 --- a/NanoKernel/NKThud.s +++ b/NanoKernel/NKThud.s @@ -951,7 +951,7 @@ print_memory_logical_0x48 b print_memory_logical_0x6c print_memory_logical_0x5c - bl PagingFunc4 + bl PagingL2PWithoutBATs rlwimi r31, r27, 0, 20, 31 lbz r8, 0x0000(r31) bl print_unknown @@ -977,7 +977,7 @@ print_memory_logical_0xac bl PagingFunc1 li r8, 0x20 bne print_memory_logical_0xdc - bl PagingFunc4 + bl PagingL2PWithoutBATs rlwimi r31, r27, 0, 20, 31 lbz r8, 0x0000(r31) cmpwi r8, 0xff diff --git a/NanoKernel/NKTranslation.s b/NanoKernel/NKTranslation.s index abb1e50..af7cd00 100644 --- a/NanoKernel/NKTranslation.s +++ b/NanoKernel/NKTranslation.s @@ -2310,7 +2310,7 @@ FDPEmulateInstruction rlwinm r17, r27, 13, 25, 29 rlwinm r18, r27, 18, 25, 29 beq cr6, FDP_1214_0x2b4 - mtcrf 0x3f, r21 + mtcrf 0x3f, r21 rlwinm r19, r27, 23, 25, 29 beq FDP_1bd0 bne cr1, FDP_1324 diff --git a/NanoKernel/NKVMCalls.s b/NanoKernel/NKVMCalls.s index 1fd5afc..e31fe29 100644 --- a/NanoKernel/NKVMCalls.s +++ b/NanoKernel/NKVMCalls.s @@ -1781,11 +1781,9 @@ RemovePTEFromHTAB ; OUTSIDE REFERER addi r8, r8, 0x01 stw r8, 0x0e98(r1) rlwimi r16, r9, 0, 0, 19 ;move page# back into PTE - li r8, -0x01 - stw r8, KDP. MinusOne1(r1) - stw r8, KDP. MinusOne2(r1) - stw r8, KDP. MinusOne3(r1) - stw r8, KDP. MinusOne4(r1) + + _InvalNCBPointerCache scratch=r8 + li r8, 0x00 ;0 upper HTAB word li r9, 0x00 ;0 lower HTAB word b EditPTEInHTAB ;update stored PTE and invalidate HTAB entry