From 7bee860e40b93e2ea19fe18877cc01e6759aab36 Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Mon, 5 Mar 2018 19:00:11 +0800 Subject: [PATCH] Reverse the CPU plugin mechanism CPU plugins are code fragment resources that allow the NanoKernel to perform CPU-specific functions, such as starting or stopping a processor core or getting core temperature. They live in the Apple CPU Plugins file. The Power Manager selects a plugin at boot (or doesn't), prepares and holds it in memory, and registers it with the NanoKernel using MPRegisterCpuPlugin(). The NanoKernel can then call any of the plugin's entry points synchronously using its SIGP() function, which is also exposed via the MPCpuPlugin() call. The plugin return path is tricky, but involved the ReturnFromInterrupt trap instruction in the emulator ROM code. The CPU plugin calling convention is described in the SIGP comments. CPU plugins operate in the blue address space, but with interrupts disabled and supervisor mode on. This code was reversed to get the Mac mini working. It is not clear how the Power Manager determines CPU temperature when there are no CPU registers to do this. --- Internal/NKOpaque.a | 20 +-- Internal/NKPublic.a | 40 +++--- NanoKernel/NKEquates.s | 13 ++ NanoKernel/NKInterrupts.s | 188 +++++++++++++++++------------ NanoKernel/NKMPCalls.s | 248 +++++++++++++++++++++++--------------- NanoKernel/NKScheduler.s | 27 ++--- NanoKernel/NKSleep.s | 44 +++---- 7 files changed, 330 insertions(+), 250 deletions(-) diff --git a/Internal/NKOpaque.a b/Internal/NKOpaque.a index 16a20aa..770a1af 100644 --- a/Internal/NKOpaque.a +++ b/Internal/NKOpaque.a @@ -386,7 +386,7 @@ kSignature equ 'CPU ' ID ds.l 1 ; 00 Signature ds.l 1 ; 04 LLL ds.l 4 ; 08:18 ; member of CGRP -Eff ds.l 1 ; 18 ; contains 0x0000000f +Eff ds.l 1 ; 18 ; contains 0x0000000f ; cannot delete if this field & 9 IdleTaskPtr ds.l 1 ; 1c EWABase ds.b 800 ; negative-indexed parts of EWA @@ -499,16 +499,16 @@ CPUList ds.l 4 ; 00:10 ; CPUs on this "motherboard" LLL ds.l 4 ; 10:20 ; member of global CGRP list CpuCount ds.l 1 ; 20 ScheduledCpuCount ds.l 1 ; 24 - ds.l 1 ; 28 - ds.l 1 ; 2c - ds.l 1 ; 30 - ds.l 1 ; 34 - ds.l 1 ; 38 - ds.l 1 ; 3c - ds.l 1 ; 40 - ds.l 1 ; 44 +LA_CpuPlugin ds.l 1 ; 28 ; page-aligned +PA_CpuPlugin ds.l 1 ; 2c ; page-aligned +CpuPluginSize ds.l 1 ; 30 ; page-aligned size +LA_CpuPluginDesc ds.l 1 ; 34 ; non-page-aligned ; [1c] = count, [20...] = entry table +PA_CpuPluginDesc ds.l 1 ; 38 ; non-page-aligned +PA_CpuPluginTOC ds.l 1 ; 3c ; "table of contents": a TVector pointer for each selector +PA_CpuPluginStackPtrs ds.l 1 ; 40 ; array of stack pointers (one per CPU) +CpuPluginSelectorCount ds.l 1 ; 44 ; max of 64 Incrementer ds.l 1 ; 48 ; number of NKCreateAddressSpaceSub calls % 1M - ds.l 1 ; 4c +CpuPluginSpacePtr ds.l 1 ; 4c ; space that cpup runs in ds.l 1 ; 50 ds.l 1 ; 54 diff --git a/Internal/NKPublic.a b/Internal/NKPublic.a index 0443682..e7bbf09 100644 --- a/Internal/NKPublic.a +++ b/Internal/NKPublic.a @@ -283,16 +283,16 @@ ThudSavedR29 ds.l 1 ; -2e0, cpu+060 ThudSavedR30 ds.l 1 ; -2dc, cpu+064 ThudSavedR31 ds.l 1 ; -2d8, cpu+068 ds.l 1 ; -2d4, cpu+06c - ds.l 1 ; -2d0, cpu+070 - ds.l 1 ; -2cc, cpu+074 - ds.l 1 ; -2c8, cpu+078 - ds.l 1 ; -2c4, cpu+07c - ds.l 1 ; -2c0, cpu+080 - ds.l 1 ; -2bc, cpu+084 - ds.l 1 ; -2b8, cpu+088 - ds.l 1 ; -2b4, cpu+08c - ds.l 1 ; -2b0, cpu+090 - ds.l 1 ; -2ac, cpu+094 +SIGPSavedR10 ds.l 1 ; -2d0, cpu+070 +SIGPSavedR11 ds.l 1 ; -2cc, cpu+074 +SIGPSavedR12 ds.l 1 ; -2c8, cpu+078 +SIGPSavedR13 ds.l 1 ; -2c4, cpu+07c +SIGPSavedXER ds.l 1 ; -2c0, cpu+080 +SIGPSavedCTR ds.l 1 ; -2bc, cpu+084 +SIGPSavedLR ds.l 1 ; -2b8, cpu+088 +SIGPSavedR6 ds.l 1 ; -2b4, cpu+08c +SIGPSavedR7 ds.l 1 ; -2b0, cpu+090 +SIGPSpacOnResume ds.l 1 ; -2ac, cpu+094 ; address space ptr to switch to when plug has executed ds.l 1 ; -2a8, cpu+098 ds.l 1 ; -2a4, cpu+09c ds.l 1 ; -2a0, cpu+0a0 @@ -321,14 +321,14 @@ TimerDispatchLR ds.l 1 ; -258, cpu+0e8 ds.l 1 ; -244, cpu+0fc ds.l 1 ; -240, cpu+100 ds.l 1 ; -23c, cpu+104 - ds.l 1 ; -238, cpu+108 - ds.l 1 ; -234, cpu+10c - ds.l 1 ; -230, cpu+110 - ds.l 1 ; -22c, cpu+114 - ds.l 1 ; -228, cpu+118 - ds.l 1 ; -224, cpu+11c - ds.l 1 ; -220, cpu+120 - ds.l 1 ; -21c, cpu+124 +SIGPSelector ds.l 1 ; -238, cpu+108 +SIGPCallR4 ds.l 1 ; -234, cpu+10c +SIGPCallR5 ds.l 1 ; -230, cpu+110 +SIGPCallR6 ds.l 1 ; -22c, cpu+114 +SIGPCallR7 ds.l 1 ; -228, cpu+118 +SIGPCallR8 ds.l 1 ; -224, cpu+11c +SIGPCallR9 ds.l 1 ; -220, cpu+120 +SIGPCallR10 ds.l 1 ; -21c, cpu+124 ds.l 1 ; -218, cpu+128 ds.l 1 ; -214, cpu+12c ds.l 1 ; -210, cpu+130 @@ -668,7 +668,7 @@ ThudSavedSR12 ds.l 1 ; 7f0 ThudSavedSR13 ds.l 1 ; 7f4 ThudSavedSR14 ds.l 1 ; 7f8 ThudSavedSR15 ds.l 1 ; 7fc -ThudSavedF0 ds.d 1 ; 800 +ThudSavedF0 ds.d 1 ; KDP.BATs + 0xa0 ThudSavedF1 ds.d 1 ; 808 ThudSavedF2 ds.d 1 ; 810 ThudSavedF3 ds.d 1 ; 818 @@ -745,7 +745,7 @@ ISIVector ds.l 1 ; 10 ; called by IVT+400 (ISI) ExternalIntVector ds.l 1 ; 14 ; called by IVT+500 (external interrupt) AlignmentIntVector ds.l 1 ; 18 ; called by IVT+600 (alignment) ProgramIntVector ds.l 1 ; 1c ; called by IVT+700 (program) -FPUnavailVector ds.l 1 ; 20 ; called by IVT+800 (FP unavail) +FPUnavailVector ds.l 1 ; 20 ; called by IVT+KDP.BATs + 0xa0 (FP unavail) DecrementerVector ds.l 1 ; 24 ; called by IVT+900 (decrementer) ReservedVector1 ds.l 1 ; 28 ; called by IVT+a00 (reserved) ReservedVector2 ds.l 1 ; 2c ; called by IVT+b00 (reserved) diff --git a/NanoKernel/NKEquates.s b/NanoKernel/NKEquates.s index de11928..f790b11 100644 --- a/NanoKernel/NKEquates.s +++ b/NanoKernel/NKEquates.s @@ -52,3 +52,16 @@ BO_IF equ 12 BO_IF_NOT equ 4 Z equ 0x80000000 + + +; SIGP (SIGnal Plugin) selectors used by the kernel: +kStartProcessor equ 1 ; r4 = target CPU idx, r5 = cpu's entry point, r6 = entry point's r3 (CPU struct ptr) +kStopProcessor equ 3 ; r4 = target CPU idx +kResetProcessor equ 4 ; r4 = target CPU idx +kAlert equ 5 ; r4 = target CPU idx? ; my name, has something to do with timers +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 +kSIGP17 equ 17 ; r4 = target CPU idx? diff --git a/NanoKernel/NKInterrupts.s b/NanoKernel/NKInterrupts.s index f561ec6..eddb735 100644 --- a/NanoKernel/NKInterrupts.s +++ b/NanoKernel/NKInterrupts.s @@ -2420,10 +2420,10 @@ IntExternalYellow ; OUTSIDE REFERER bl Save_r14_r31 - li r9, 9 - stw r9, -0x0238(r8) + li r9, kSIGP9 + stw r9, EWA.SIGPSelector(r8) - li r8, 1 + li r8, 1 ; args in EWA bl SIGP bl Restore_r14_r31 @@ -2444,109 +2444,145 @@ IntExternalYellow ; OUTSIDE REFERER -; SIGP +; "SIGnal Plugin": Call the CPU plugin PEF bundle synchronously. +; (blue address space but in supervisor mode without interrupts) -; Really need to figure out what this does... +; ARG: -; Xrefs: -; IntExternalYellow -; MPCall_43 -; KCStartCPU -; KCCpuPlugin -; FlagSchEvaluationIfTaskRequires -; MPCall_103 +; if r8 == 0, i.e. userspace MPCpuPlugin call: +; r3 => routine selector +; executing CPU index => r3 +; r4-10 => r4-10 -; > r7 = flags -; > r8 = usually 2? +; if r8 != 0, i.e. internal NanoKernel call: +; EWA.SIGPSelector => routine selector +; executing CPU index => r3 +; PlugCallR4-10 => r4-10 + +; For most NK SIGPs, r4 contains the index of the CPU being operated on align 5 -SIGP ; OUTSIDE REFERER +SIGP + mfsprg r23, 0 mtcr r7 - lwz r16, -0x001c(r23) - slwi r20, r3, 2 - stw r16, -0x02ac(r23) - blt- cr4, major_0x04a20_0x18 - cmpwi cr2, r8, 0x00 - lwz r18, -0x0238(r23) - beq- cr2, SIGP_0x28 - slwi r20, r18, 2 -SIGP_0x28 - lwz r22, -0x0338(r23) + ; r20 = offset into CPU plugin dispatch table = routine number * 4 + ; + 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 + cmpwi cr2, r8, 0 + lwz r18, EWA.SIGPSelector(r23) + beq- cr2, @args_in_registers + slwi r20, r18, 2 +@args_in_registers + + ; Check that a CPU plugin is installed and that the + ; plugin dispatch table includes this command number. + lwz r22, EWA.CPUBase + CPU.LLL + LLL.Freeform(r23) li r8, -0x7266 - lwz r17, 0x0038(r22) - lwz r16, 0x0044(r22) + lwz r17, CoherenceGroup.PA_CpuPluginDesc(r22) + lwz r16, CoherenceGroup.CpuPluginSelectorCount(r22) mr. r17, r17 beqlr- slwi r16, r16, 2 li r8, -0x7267 cmplw r20, r16 bgelr- - stw r10, -0x02d0(r23) - stw r11, -0x02cc(r23) - stw r12, -0x02c8(r23) - stw r13, -0x02c4(r23) + + ; Save some registers in advance of this unusual "upcall". + stw r10, EWA.SIGPSavedR10(r23) + stw r11, EWA.SIGPSavedR11(r23) + stw r12, EWA.SIGPSavedR12(r23) + stw r13, EWA.SIGPSavedR13(r23) mfxer r16 mfctr r17 - stw r16, -0x02c0(r23) + stw r16, EWA.SIGPSavedXER(r23) mflr r16 - stw r17, -0x02bc(r23) - stw r16, -0x02b8(r23) - stw r6, -0x02b4(r23) - stw r7, -0x02b0(r23) - lwz r9, -0x001c(r23) - lwz r8, 0x004c(r22) - cmpw r9, r8 - beq- SIGP_0x94 - bl SetSpaceSRsAndBATs + stw r17, EWA.SIGPSavedCTR(r23) + stw r16, EWA.SIGPSavedLR(r23) ; obviously this is getting revisited somewhere + stw r6, EWA.SIGPSavedR6(r23) + stw r7, EWA.SIGPSavedR7(r23) -SIGP_0x94 - lwz r16, 0x0004(r23) - lwz r17, 0x0018(r23) - stw r16, 0x010c(r6) - stw r2, 0x0114(r6) - stw r3, 0x011c(r6) - stw r4, 0x0124(r6) - stw r5, 0x012c(r6) - stw r17, 0x0134(r6) - lwz r17, 0x0648(r1) + ; Change to the CPU plugin's preferred address space. + lwz r9, EWA.PA_CurAddressSpace(r23) + lwz r8, CoherenceGroup.CpuPluginSpacePtr(r22) + cmpw r9, r8 + beq- @noNeedToSwitchSpace + bl SetSpaceSRsAndBATs +@noNeedToSwitchSpace + + ; Save user registers to ContextBlock (odd way to do this). + lwz r16, EWA.r1(r23) + lwz r17, EWA.r6(r23) + stw r16, ContextBlock.r1(r6) + stw r2, ContextBlock.r2(r6) + stw r3, ContextBlock.r3(r6) + stw r4, ContextBlock.r4(r6) + stw r5, ContextBlock.r5(r6) + stw r17, ContextBlock.r6(r6) + + ; Return address for CPU plugin code (=> twi 31, r31, 0 => kcReturnFromException) + lwz r17, KDP.LA_EmulatorKernelTrapTable + NanoKernelCallTable.ReturnFromException(r1) + + ; Need CPU index to look up the CPU plugin stack pointer in a table lhz r16, EWA.CPUIndex(r23) - lwz r19, -0x0964(r1) - slwi r16, r16, 2 - rlwinm r19, r19, 0, 18, 15 - lwz r8, 0x003c(r22) - lwz r9, 0x0040(r22) + + ; MSR for CPU plugin with EE (external ints) and PR (problem state) switched off + lwz r19, PSA.UserModeMSR(r1) + slwi r16, r16, 2 + rlwinm r19, r19, 0, 18, 15 + + ; SRR0 (=> program counter) = TOC[routine_idx][first long] + ; r1 (stack ptr) = stackPtrs[cpu_idx] + ; r2 (RTOC) = TOC[routine_idx][second long] + lwz r8, CoherenceGroup.PA_CpuPluginTOC(r22) + lwz r9, CoherenceGroup.PA_CpuPluginStackPtrs(r22) lwzx r20, r8, r20 - lwz r18, 0x0000(r20) + lwz r18, 0(r20) mtlr r17 mtspr srr0, r18 mtspr srr1, r19 lwzx r1, r9, r16 - lwz r2, 0x0004(r20) - srwi r3, r16, 2 + lwz r2, 4(r20) + + ; r3 (first arg) = CPU index + srwi r3, r16, 2 + + ; Flags |= 0x8000 ori r7, r7, 0x8000 mr r16, r6 - stw r7, -0x0010(r23) + stw r7, EWA.Flags(r23) + + ; Not sure where this ContextBlock comes from? addi r6, r23, -0x318 - stw r6, -0x0014(r23) - beq- cr2, SIGP_0x128 - lwz r4, -0x0234(r23) - lwz r5, -0x0230(r23) - lwz r6, -0x022c(r23) - lwz r7, -0x0228(r23) - lwz r8, -0x0224(r23) - lwz r9, -0x0220(r23) - lwz r10, -0x021c(r23) + stw r6, EWA.PA_ContextBlock(r23) + + beq- cr2, @args_in_registers_2 + +;args not in registers + lwz r4, EWA.SIGPCallR4(r23) + lwz r5, EWA.SIGPCallR5(r23) + lwz r6, EWA.SIGPCallR6(r23) + lwz r7, EWA.SIGPCallR7(r23) + lwz r8, EWA.SIGPCallR8(r23) + lwz r9, EWA.SIGPCallR9(r23) + lwz r10, EWA.SIGPCallR10(r23) + + ; Go. rfi -SIGP_0x128 - lwz r6, 0x0134(r16) - lwz r7, 0x013c(r16) - lwz r8, 0x0144(r16) - lwz r9, 0x014c(r16) - lwz r10, 0x0154(r16) +@args_in_registers_2 + lwz r6, ContextBlock.r6(r16) + lwz r7, ContextBlock.r7(r16) + lwz r8, ContextBlock.r8(r16) + lwz r9, ContextBlock.r9(r16) + lwz r10, ContextBlock.r10(r16) + + ; Go. rfi @@ -2576,7 +2612,7 @@ major_0x04a20_0x18 ; OUTSIDE REFERER li r3, -0x7265 major_0x04a20_0x30 - lwz r8, -0x02ac(r23) + lwz r8, EWA.SIGPSpacOnResume(r23) lwz r9, -0x001c(r23) cmpw r9, r8 beq- major_0x04a20_0x44 diff --git a/NanoKernel/NKMPCalls.s b/NanoKernel/NKMPCalls.s index 5477077..d7016fd 100644 --- a/NanoKernel/NKMPCalls.s +++ b/NanoKernel/NKMPCalls.s @@ -770,97 +770,138 @@ MPCall_1 ; OUTSIDE REFERER ; KCRegisterCpuPlugin +; ARG MPCoherenceGroupID r3, CpuPluginPtr r4, CpuPluginSize r5, CpuPluginDesc r6 +; RET OSStatus r3 - DeclareMPCall 2, KCRegisterCpuPlugin + DeclareMPCall 2, MPRegisterCpuPlugin + +MPRegisterCpuPlugin +; _log 'MPRegisterCpuPlugin ' +; mr r8, r3 +; bl Printw +; mr r8, r4 +; bl Printw +; mr r8, r5 +; bl Printw +; mr r8, r6 +; bl Printw +; _log '^n' -KCRegisterCpuPlugin ; OUTSIDE REFERER mfsprg r14, 0 lwz r15, EWA.PA_CurTask(r14) lwz r16, ContextBlock.r6(r6) - andi. r8, r4, 0xfff ; page alignment? + ; Check that address of CPU plugin is page-aligned, + ; and that CPU plugin size if page-aligned and nonzero. + andi. r8, r4, 0xfff bne+ ReturnMPCallOOM - - andi. r8, r5, 0xfff ; r5 page aligned and nonzero? + andi. r8, r5, 0xfff cmpwi cr1, r5, 0 bne+ ReturnMPCallOOM beq+ cr1, ReturnMPCallOOM _Lock PSA.SchLock, scratch1=r18, scratch2=r19 + ; r14 = coherence group ptr (motherpboard CGRP if not specified in first argument) mr. r8, r3 - bne- KCRegisterCpuPlugin_0x50 + bne- @use_specified_cgrp mfsprg r15, 0 - lwz r14, -0x0338(r15) - b KCRegisterCpuPlugin_0x60 - -KCRegisterCpuPlugin_0x50 -; r8 = id + lwz r14, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15) + b @cgrp_done +@use_specified_cgrp bl LookupID cmpwi r9, CoherenceGroup.kIDClass - mr r14, r8 bne+ ReturnMPCallInvalidIDErr +@cgrp_done -KCRegisterCpuPlugin_0x60 - cmpwi r16, 0x00 - bne- KCRegisterCpuPlugin_0x74 - stw r16, 0x0038(r14) - stw r16, 0x0034(r14) + ; Fail if no CPU plugin descriptor is passed in fourth argument + cmpwi r16, 0 + bne- @no_table_ptr + stw r16, CoherenceGroup.PA_CpuPluginDesc(r14) + stw r16, CoherenceGroup.LA_CpuPluginDesc(r14) b ReleaseAndReturnMPCallInvalidIDErr +@no_table_ptr -KCRegisterCpuPlugin_0x74 + ; Fail if CPU plugin descriptor lies within CPU plugin add r17, r4, r5 cmplw r16, r4 cmplw cr1, r16, r17 blt+ ReleaseAndReturnMPCallOOM bge+ cr1, ReleaseAndReturnMPCallOOM - lwz r19, 0x0038(r14) + + ; What the hell? Wouldn't this always fail? + lwz r19, CoherenceGroup.PA_CpuPluginDesc(r14) mr. r19, r19 bne+ ReleaseAndReturnMPCallInvalidIDErr + + ; r18 = physical address of plugin (assumes page-aligned) mr r27, r4 - addi r29, r1, 800 + addi r29, r1, KDP.BATs + 0xa0 bl PagingFunc3 beq+ ReleaseAndReturnMPCallOOM - rlwinm r18, r31, 0, 0, 19 + rlwinm r18, r31, 0, 0, 19 + + ; r18 = physical address of descriptor (does not assume page-aligned) mr r27, r16 mr r19, r16 - addi r29, r1, 800 + addi r29, r1, KDP.BATs + 0xa0 bl PagingFunc3 beq+ ReleaseAndReturnMPCallOOM - rlwimi r19, r31, 0, 0, 19 - stw r4, 0x0028(r14) - stw r18, 0x002c(r14) - stw r5, 0x0030(r14) - stw r16, 0x0034(r14) - stw r19, 0x0038(r14) - lwz r27, 0x0000(r19) - addi r29, r1, 800 + rlwimi r19, r31, 0, 0, 19 + + ; Populate the coherence group structure. + + ; Save (page-aligned) address of main plugin (second argument) + stw r4, CoherenceGroup.LA_CpuPlugin(r14) + stw r18, CoherenceGroup.PA_CpuPlugin(r14) + + ; Save size of main plugin (third argument) + stw r5, CoherenceGroup.CpuPluginSize(r14) + + ; Save (non-page-aligned) address of descriptor (fourth argument) + stw r16, CoherenceGroup.LA_CpuPluginDesc(r14) + stw r19, CoherenceGroup.PA_CpuPluginDesc(r14) + + ; Get physical ptr to table of stack pointers (one per CPU) + lwz r27, 0(r19) + addi r29, r1, KDP.BATs + 0xa0 bl PagingFunc3 beq+ ReleaseAndReturnMPCallOOM - rlwimi r27, r31, 0, 0, 19 - stw r27, 0x0040(r14) + rlwimi r27, r31, 0, 0, 19 + stw r27, CoherenceGroup.PA_CpuPluginStackPtrs(r14) + mfsprg r16, 0 - lwz r17, -0x001c(r16) - stw r17, 0x004c(r14) - addi r16, r19, 0x20 - stw r16, 0x003c(r14) - subi r16, r16, 4 - lwz r17, 0x001c(r19) - cmplwi r17, 0x40 - stw r17, 0x0044(r14) + + ; The cpup should operate in the caller's address space + lwz r17, EWA.PA_CurAddressSpace(r16) + stw r17, CoherenceGroup.CpuPluginSpacePtr(r14) + + ; Get ptr to dispatch table at descriptor + 32 + addi r16, r19, 0x20 + stw r16, CoherenceGroup.PA_CpuPluginTOC(r14) + subi r16, r16, 4 ; prepare for loop below + + ; Get number of entries in the dispatch table + lwz r17, 0x1c(r19) + cmplwi r17, 64 + stw r17, CoherenceGroup.CpuPluginSelectorCount(r14) bgt+ ReleaseAndReturnMPCallOOM -KCRegisterCpuPlugin_0x114 - lwzu r27, 0x0004(r16) - addi r29, r1, 800 + ; Convert those entries to physical addresses +@table_convert_loop + lwzu r27, 4(r16) + addi r29, r1, KDP.BATs + 0xa0 bl PagingFunc3 beq+ ReleaseAndReturnMPCallOOM - addi r17, r17, -0x01 - rlwimi r27, r31, 0, 0, 19 - cmpwi r17, 0x00 - stw r27, 0x0000(r16) - bgt+ KCRegisterCpuPlugin_0x114 + subi r17, r17, 1 + rlwimi r27, r31, 0, 0, 19 + cmpwi r17, 0 + stw r27, 0(r16) + bgt+ @table_convert_loop + + + _log 'CPU plugin registered^n' ; r1 = kdp @@ -1426,7 +1467,7 @@ MPCall_62 ; OUTSIDE REFERER mr. r8, r3 bne- MPCall_62_0x18 mfsprg r15, 0 - lwz r31, -0x0338(r15) + lwz r31, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15) lwz r3, 0x0000(r31) b MPCall_62_0x24 @@ -1567,34 +1608,33 @@ KCCreateCpuStruct_0x68 - DeclareMPCall 43, MPCall_43 +; Simple MPLibrary wrapper -MPCall_43 ; OUTSIDE REFERER + DeclareMPCall 43, MPDeleteProcessor + +MPDeleteProcessor _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 - -; r8 = id bl LookupID cmpwi r9, CPU.kIDClass - mr r31, r8 bne+ ReleaseAndReturnMPCallInvalidIDErr - lwz r16, 0x0018(r31) - lis r17, 0x00 - ori r17, r17, 0x09 + + lwz r16, CPU.Eff(r31) + lisori r17, 9 and. r17, r17, r16 bne+ ReleaseAndReturnMPCallOOM - mfsprg r15, 0 - li r16, 0x04 - stw r16, -0x0238(r15) - lhz r16, CPU.EWA + EWA.CPUIndex(r31) - stw r16, -0x0234(r15) - li r8, 0x02 -; r7 = flags -; r8 = usually 2? + mfsprg r15, 0 + + li r16, kResetProcessor + stw r16, EWA.SIGPSelector(r15) + + lhz r16, CPU.EWA + EWA.CPUIndex(r31) + stw r16, EWA.SIGPCallR4(r15) + li r8, 2 ; args in EWA bl SIGP lwz r17, 0x0008(r31) addi r16, r31, 0x08 @@ -1631,16 +1671,16 @@ KCStartCPU ; OUTSIDE REFERER bne+ ReleaseAndReturnZeroFromMPCall mfsprg r15, 0 - li r16, 0x04 - stw r16, -0x0238(r15) + li r16, kResetProcessor + stw r16, EWA.SIGPSelector(r15) lhz r16, CPU.EWA + EWA.CPUIndex(r30) - stw r16, -0x0234(r15) + stw r16, EWA.SIGPCallR4(r15) ; Put the boots in? _log 'SIGP kResetProcessor^n' - li r8, 2 + li r8, 2 ; args in EWA bl SIGP cmpwi r8, -0x7264 cmpwi cr1, r8, 0 @@ -1700,19 +1740,17 @@ KCStartCPU ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 - ; Some EWA/KDP stuff I do not understand mfsprg r15, 0 - li r16, 0x08 - stw r16, -0x0238(r15) + + + li r16, kSynchClock + stw r16, EWA.SIGPSelector(r15) lhz r16, CPU.EWA + EWA.CPUIndex(r30) - stw r16, -0x0234(r15) + stw r16, EWA.SIGPCallR4(r15) MPCall_44_0x15c _log 'SIGP kSynchClock^n' - li r8, 0x02 - -; r7 = flags -; r8 = usually 2? + li r8, 2 ; args in EWA bl SIGP cmpwi r8, -0x7264 cmpwi cr1, r8, 0x00 @@ -1720,29 +1758,34 @@ MPCall_44_0x15c bne- cr1, MPCall_Panic + mfsprg r15, 0 - li r16, 0x01 - stw r16, -0x0238(r15) + + li r16, kStartProcessor + stw r16, EWA.SIGPSelector(r15) + lhz r16, CPU.EWA + EWA.CPUIndex(r30) - stw r16, -0x0234(r15) - lwz r16, 0x064c(r1) - llabel r17, major_0x14bcc + stw r16, EWA.SIGPCallR4(r15) + + lwz r16, KDP.PA_NanoKernelCode(r1) + llabel r17, NewCpuEntryPoint add r16, r16, r17 - stw r16, -0x0230(r15) - stw r30, -0x022c(r15) + stw r16, EWA.SIGPCallR5(r15) -MPCall_44_0x1c0 + stw r30, EWA.SIGPCallR6(r15) ; cpu struct + +@retry _log 'SIGP kStartProcessor^n' - li r8, 0x04 - -; r7 = flags -; r8 = usually 2? + li r8, 4 ; args in EWA bl SIGP + cmpwi r8, -0x7264 - cmpwi cr1, r8, 0x00 - beq+ MPCall_44_0x1c0 + cmpwi cr1, r8, 0 + beq+ @retry bne- cr1, MPCall_Panic + _log 'Processor scheduled^n' + b ReturnZeroFromMPCall @@ -1798,19 +1841,24 @@ KCStopScheduling_0x94 -; KCCpuPlugin +; Directly wrapped by MPLibrary +; ARG selector r3, arbitrary args r4... +; RET arbitrary - DeclareMPCall 46, KCCpuPlugin + DeclareMPCall 46, MPCpuPlugin -KCCpuPlugin ; OUTSIDE REFERER - li r8, 0x00 +MPCpuPlugin -; r7 = flags -; r8 = usually 2? + ; Arguments in registers + li r8, 0 + + ; Hopefully returns via kcReturnFromInterrupt? Geez... bl SIGP + mr r3, r8 - mr r4, r9 + mr r4, r9 ; r4 not accessible calling MPLibrary func from C + b CommonMPCallReturnPath @@ -2121,7 +2169,7 @@ MPCall_108 ; OUTSIDE REFERER NKSetClockStep ; OUTSIDE REFERER mfsprg r9, 0 - lwz r8, -0x0338(r9) + lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) lwz r9, 0x0024(r8) cmpwi r9, 0x01 bgt+ ReturnMPCallOOM @@ -2199,7 +2247,7 @@ NKSetClockDriftCorrection ; OUTSIDE REFERER mfsprg r9, 0 cmpwi r31, 0x00 beq+ ReturnMPCallOOM - lwz r8, -0x0338(r9) + lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) lwz r9, 0x0024(r8) cmpwi r9, 0x01 bgt+ ReturnMPCallOOM diff --git a/NanoKernel/NKScheduler.s b/NanoKernel/NKScheduler.s index 2359b61..18bf2c3 100644 --- a/NanoKernel/NKScheduler.s +++ b/NanoKernel/NKScheduler.s @@ -1927,24 +1927,17 @@ BEFOUR lwz r9, 0x0ee0(r1) addi r9, r9, 0x01 stw r9, 0x0ee0(r1) - li r16, 0x05 - stw r16, -0x0238(r15) - stw r18, -0x0234(r15) - li r8, 0x02 -; r7 = flags -; r8 = usually 2? + li r16, kAlert + stw r16, EWA.SIGPSelector(r15) + stw r18, EWA.SIGPCallR4(r15) + + li r8, 2 b SIGP -; major_0x14bcc - -; Xrefs: -; "EvenMore" -; "SecondCpuCodeViaPtr" - -major_0x14bcc +NewCpuEntryPoint ; This func gets passed its CPU struct in r3, ; which lets us find its real EWA pointer. @@ -2192,10 +2185,12 @@ StopProcessor bl TasksFuncThatIsNotAMPCall _AssertAndRelease PSA.SchLock, scratch=r16 _log 'SIGP kStopProcessor^n' - li r3, 0x03 + li r3, kStopProcessor lhz r4, CPU.EWA + EWA.CPUIndex(r31) - li r0, 0x2e - twi 31, r31, 0x08 + + ; Use twi to call MPCpuPlugin(3, myCpuID) + li r0, 46 + twi 31, r31, 8 _log 'Stop didn''t work - going to sleep.^n' StopProcessor_0x10c diff --git a/NanoKernel/NKSleep.s b/NanoKernel/NKSleep.s index c542341..98ff4c7 100644 --- a/NanoKernel/NKSleep.s +++ b/NanoKernel/NKSleep.s @@ -120,14 +120,11 @@ MPCall_103_0x10c stw r8, -0x0278(r15) stw r9, -0x0274(r15) mr r29, r17 - li r16, 0x06 - stw r16, -0x0238(r15) + li r16, kSIGP6 + stw r16, EWA.SIGPSelector(r15) lhz r16, EWA.CPUIndex(r15) - stw r16, -0x0234(r15) - li r8, 0x02 - -; r7 = flags -; r8 = usually 2? + stw r16, EWA.SIGPCallR4(r15) + li r8, 2 ; args in EWA bl SIGP mr r17, r29 mfsdr1 r8 @@ -257,14 +254,11 @@ MPCall_103_0x270 li r8, 0x00 stw r8, 0x0004(r17) mfsprg r15, 0 - li r16, 0x11 - stw r16, -0x0238(r15) + li r16, kSIGP17 + stw r16, EWA.SIGPSelector(r15) lhz r16, EWA.CPUIndex(r15) - stw r16, -0x0234(r15) - li r8, 0x02 - -; r7 = flags -; r8 = usually 2? + stw r16, EWA.SIGPCallR4(r15) + li r8, 2 ; args in EWA bl SIGP li r3, 0x00 b Local_CommonMPCallReturnPath @@ -362,24 +356,18 @@ RestoreKernelState_0x144 bl SetSpaceSRsAndBATs isync mfsprg r15, 0 - li r16, 0x07 - stw r16, -0x0238(r15) + li r16, kSIGP7 + stw r16, EWA.SIGPSelector(r15) lhz r16, EWA.CPUIndex(r15) - stw r16, -0x0234(r15) - li r8, 0x02 - -; r7 = flags -; r8 = usually 2? + stw r16, EWA.SIGPCallR4(r15) + li r8, 2 ; args in EWA bl SIGP mfsprg r15, 0 - li r16, 0x11 - stw r16, -0x0238(r15) + li r16, kSIGP17 + stw r16, EWA.SIGPSelector(r15) lhz r16, EWA.CPUIndex(r15) - stw r16, -0x0234(r15) - li r8, 0x02 - -; r7 = flags -; r8 = usually 2? + stw r16, EWA.SIGPCallR4(r15) + li r8, 2 ; args in EWA bl SIGP li r3, 0x00 b Local_CommonMPCallReturnPath