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.
This commit is contained in:
Elliot Nunn 2018-03-05 19:00:11 +08:00
parent a323be3c8b
commit 7bee860e40
7 changed files with 330 additions and 250 deletions

View File

@ -386,7 +386,7 @@ kSignature equ 'CPU '
ID ds.l 1 ; 00 ID ds.l 1 ; 00
Signature ds.l 1 ; 04 Signature ds.l 1 ; 04
LLL ds.l 4 ; 08:18 ; member of CGRP 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 IdleTaskPtr ds.l 1 ; 1c
EWABase ds.b 800 ; negative-indexed parts of EWA 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 LLL ds.l 4 ; 10:20 ; member of global CGRP list
CpuCount ds.l 1 ; 20 CpuCount ds.l 1 ; 20
ScheduledCpuCount ds.l 1 ; 24 ScheduledCpuCount ds.l 1 ; 24
ds.l 1 ; 28 LA_CpuPlugin ds.l 1 ; 28 ; page-aligned
ds.l 1 ; 2c PA_CpuPlugin ds.l 1 ; 2c ; page-aligned
ds.l 1 ; 30 CpuPluginSize ds.l 1 ; 30 ; page-aligned size
ds.l 1 ; 34 LA_CpuPluginDesc ds.l 1 ; 34 ; non-page-aligned ; [1c] = count, [20...] = entry table
ds.l 1 ; 38 PA_CpuPluginDesc ds.l 1 ; 38 ; non-page-aligned
ds.l 1 ; 3c PA_CpuPluginTOC ds.l 1 ; 3c ; "table of contents": a TVector pointer for each selector
ds.l 1 ; 40 PA_CpuPluginStackPtrs ds.l 1 ; 40 ; array of stack pointers (one per CPU)
ds.l 1 ; 44 CpuPluginSelectorCount ds.l 1 ; 44 ; max of 64
Incrementer ds.l 1 ; 48 ; number of NKCreateAddressSpaceSub calls % 1M 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 ; 50
ds.l 1 ; 54 ds.l 1 ; 54

View File

@ -283,16 +283,16 @@ ThudSavedR29 ds.l 1 ; -2e0, cpu+060
ThudSavedR30 ds.l 1 ; -2dc, cpu+064 ThudSavedR30 ds.l 1 ; -2dc, cpu+064
ThudSavedR31 ds.l 1 ; -2d8, cpu+068 ThudSavedR31 ds.l 1 ; -2d8, cpu+068
ds.l 1 ; -2d4, cpu+06c ds.l 1 ; -2d4, cpu+06c
ds.l 1 ; -2d0, cpu+070 SIGPSavedR10 ds.l 1 ; -2d0, cpu+070
ds.l 1 ; -2cc, cpu+074 SIGPSavedR11 ds.l 1 ; -2cc, cpu+074
ds.l 1 ; -2c8, cpu+078 SIGPSavedR12 ds.l 1 ; -2c8, cpu+078
ds.l 1 ; -2c4, cpu+07c SIGPSavedR13 ds.l 1 ; -2c4, cpu+07c
ds.l 1 ; -2c0, cpu+080 SIGPSavedXER ds.l 1 ; -2c0, cpu+080
ds.l 1 ; -2bc, cpu+084 SIGPSavedCTR ds.l 1 ; -2bc, cpu+084
ds.l 1 ; -2b8, cpu+088 SIGPSavedLR ds.l 1 ; -2b8, cpu+088
ds.l 1 ; -2b4, cpu+08c SIGPSavedR6 ds.l 1 ; -2b4, cpu+08c
ds.l 1 ; -2b0, cpu+090 SIGPSavedR7 ds.l 1 ; -2b0, cpu+090
ds.l 1 ; -2ac, cpu+094 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 ; -2a8, cpu+098
ds.l 1 ; -2a4, cpu+09c ds.l 1 ; -2a4, cpu+09c
ds.l 1 ; -2a0, cpu+0a0 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 ; -244, cpu+0fc
ds.l 1 ; -240, cpu+100 ds.l 1 ; -240, cpu+100
ds.l 1 ; -23c, cpu+104 ds.l 1 ; -23c, cpu+104
ds.l 1 ; -238, cpu+108 SIGPSelector ds.l 1 ; -238, cpu+108
ds.l 1 ; -234, cpu+10c SIGPCallR4 ds.l 1 ; -234, cpu+10c
ds.l 1 ; -230, cpu+110 SIGPCallR5 ds.l 1 ; -230, cpu+110
ds.l 1 ; -22c, cpu+114 SIGPCallR6 ds.l 1 ; -22c, cpu+114
ds.l 1 ; -228, cpu+118 SIGPCallR7 ds.l 1 ; -228, cpu+118
ds.l 1 ; -224, cpu+11c SIGPCallR8 ds.l 1 ; -224, cpu+11c
ds.l 1 ; -220, cpu+120 SIGPCallR9 ds.l 1 ; -220, cpu+120
ds.l 1 ; -21c, cpu+124 SIGPCallR10 ds.l 1 ; -21c, cpu+124
ds.l 1 ; -218, cpu+128 ds.l 1 ; -218, cpu+128
ds.l 1 ; -214, cpu+12c ds.l 1 ; -214, cpu+12c
ds.l 1 ; -210, cpu+130 ds.l 1 ; -210, cpu+130
@ -668,7 +668,7 @@ ThudSavedSR12 ds.l 1 ; 7f0
ThudSavedSR13 ds.l 1 ; 7f4 ThudSavedSR13 ds.l 1 ; 7f4
ThudSavedSR14 ds.l 1 ; 7f8 ThudSavedSR14 ds.l 1 ; 7f8
ThudSavedSR15 ds.l 1 ; 7fc ThudSavedSR15 ds.l 1 ; 7fc
ThudSavedF0 ds.d 1 ; 800 ThudSavedF0 ds.d 1 ; KDP.BATs + 0xa0
ThudSavedF1 ds.d 1 ; 808 ThudSavedF1 ds.d 1 ; 808
ThudSavedF2 ds.d 1 ; 810 ThudSavedF2 ds.d 1 ; 810
ThudSavedF3 ds.d 1 ; 818 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) ExternalIntVector ds.l 1 ; 14 ; called by IVT+500 (external interrupt)
AlignmentIntVector ds.l 1 ; 18 ; called by IVT+600 (alignment) AlignmentIntVector ds.l 1 ; 18 ; called by IVT+600 (alignment)
ProgramIntVector ds.l 1 ; 1c ; called by IVT+700 (program) 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) DecrementerVector ds.l 1 ; 24 ; called by IVT+900 (decrementer)
ReservedVector1 ds.l 1 ; 28 ; called by IVT+a00 (reserved) ReservedVector1 ds.l 1 ; 28 ; called by IVT+a00 (reserved)
ReservedVector2 ds.l 1 ; 2c ; called by IVT+b00 (reserved) ReservedVector2 ds.l 1 ; 2c ; called by IVT+b00 (reserved)

View File

@ -52,3 +52,16 @@ BO_IF equ 12
BO_IF_NOT equ 4 BO_IF_NOT equ 4
Z equ 0x80000000 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?

View File

@ -2420,10 +2420,10 @@ IntExternalYellow ; OUTSIDE REFERER
bl Save_r14_r31 bl Save_r14_r31
li r9, 9 li r9, kSIGP9
stw r9, -0x0238(r8) stw r9, EWA.SIGPSelector(r8)
li r8, 1 li r8, 1 ; args in EWA
bl SIGP bl SIGP
bl Restore_r14_r31 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: ; if r8 == 0, i.e. userspace MPCpuPlugin call:
; IntExternalYellow ; r3 => routine selector
; MPCall_43 ; executing CPU index => r3
; KCStartCPU ; r4-10 => r4-10
; KCCpuPlugin
; FlagSchEvaluationIfTaskRequires
; MPCall_103
; > r7 = flags ; if r8 != 0, i.e. internal NanoKernel call:
; > r8 = usually 2? ; 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 align 5
SIGP ; OUTSIDE REFERER SIGP
mfsprg r23, 0 mfsprg r23, 0
mtcr r7 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 ; r20 = offset into CPU plugin dispatch table = routine number * 4
lwz r22, -0x0338(r23) ;
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 li r8, -0x7266
lwz r17, 0x0038(r22) lwz r17, CoherenceGroup.PA_CpuPluginDesc(r22)
lwz r16, 0x0044(r22) lwz r16, CoherenceGroup.CpuPluginSelectorCount(r22)
mr. r17, r17 mr. r17, r17
beqlr- beqlr-
slwi r16, r16, 2 slwi r16, r16, 2
li r8, -0x7267 li r8, -0x7267
cmplw r20, r16 cmplw r20, r16
bgelr- bgelr-
stw r10, -0x02d0(r23)
stw r11, -0x02cc(r23) ; Save some registers in advance of this unusual "upcall".
stw r12, -0x02c8(r23) stw r10, EWA.SIGPSavedR10(r23)
stw r13, -0x02c4(r23) stw r11, EWA.SIGPSavedR11(r23)
stw r12, EWA.SIGPSavedR12(r23)
stw r13, EWA.SIGPSavedR13(r23)
mfxer r16 mfxer r16
mfctr r17 mfctr r17
stw r16, -0x02c0(r23) stw r16, EWA.SIGPSavedXER(r23)
mflr r16 mflr r16
stw r17, -0x02bc(r23) stw r17, EWA.SIGPSavedCTR(r23)
stw r16, -0x02b8(r23) stw r16, EWA.SIGPSavedLR(r23) ; obviously this is getting revisited somewhere
stw r6, -0x02b4(r23) stw r6, EWA.SIGPSavedR6(r23)
stw r7, -0x02b0(r23) stw r7, EWA.SIGPSavedR7(r23)
lwz r9, -0x001c(r23)
lwz r8, 0x004c(r22)
cmpw r9, r8
beq- SIGP_0x94
bl SetSpaceSRsAndBATs
SIGP_0x94 ; Change to the CPU plugin's preferred address space.
lwz r16, 0x0004(r23) lwz r9, EWA.PA_CurAddressSpace(r23)
lwz r17, 0x0018(r23) lwz r8, CoherenceGroup.CpuPluginSpacePtr(r22)
stw r16, 0x010c(r6) cmpw r9, r8
stw r2, 0x0114(r6) beq- @noNeedToSwitchSpace
stw r3, 0x011c(r6) bl SetSpaceSRsAndBATs
stw r4, 0x0124(r6) @noNeedToSwitchSpace
stw r5, 0x012c(r6)
stw r17, 0x0134(r6) ; Save user registers to ContextBlock (odd way to do this).
lwz r17, 0x0648(r1) 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) lhz r16, EWA.CPUIndex(r23)
lwz r19, -0x0964(r1)
slwi r16, r16, 2 ; MSR for CPU plugin with EE (external ints) and PR (problem state) switched off
rlwinm r19, r19, 0, 18, 15 lwz r19, PSA.UserModeMSR(r1)
lwz r8, 0x003c(r22) slwi r16, r16, 2
lwz r9, 0x0040(r22) 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 lwzx r20, r8, r20
lwz r18, 0x0000(r20) lwz r18, 0(r20)
mtlr r17 mtlr r17
mtspr srr0, r18 mtspr srr0, r18
mtspr srr1, r19 mtspr srr1, r19
lwzx r1, r9, r16 lwzx r1, r9, r16
lwz r2, 0x0004(r20) lwz r2, 4(r20)
srwi r3, r16, 2
; r3 (first arg) = CPU index
srwi r3, r16, 2
; Flags |= 0x8000
ori r7, r7, 0x8000 ori r7, r7, 0x8000
mr r16, r6 mr r16, r6
stw r7, -0x0010(r23) stw r7, EWA.Flags(r23)
; Not sure where this ContextBlock comes from?
addi r6, r23, -0x318 addi r6, r23, -0x318
stw r6, -0x0014(r23) stw r6, EWA.PA_ContextBlock(r23)
beq- cr2, SIGP_0x128
lwz r4, -0x0234(r23) beq- cr2, @args_in_registers_2
lwz r5, -0x0230(r23)
lwz r6, -0x022c(r23) ;args not in registers
lwz r7, -0x0228(r23) lwz r4, EWA.SIGPCallR4(r23)
lwz r8, -0x0224(r23) lwz r5, EWA.SIGPCallR5(r23)
lwz r9, -0x0220(r23) lwz r6, EWA.SIGPCallR6(r23)
lwz r10, -0x021c(r23) lwz r7, EWA.SIGPCallR7(r23)
lwz r8, EWA.SIGPCallR8(r23)
lwz r9, EWA.SIGPCallR9(r23)
lwz r10, EWA.SIGPCallR10(r23)
; Go.
rfi rfi
SIGP_0x128 @args_in_registers_2
lwz r6, 0x0134(r16) lwz r6, ContextBlock.r6(r16)
lwz r7, 0x013c(r16) lwz r7, ContextBlock.r7(r16)
lwz r8, 0x0144(r16) lwz r8, ContextBlock.r8(r16)
lwz r9, 0x014c(r16) lwz r9, ContextBlock.r9(r16)
lwz r10, 0x0154(r16) lwz r10, ContextBlock.r10(r16)
; Go.
rfi rfi
@ -2576,7 +2612,7 @@ major_0x04a20_0x18 ; OUTSIDE REFERER
li r3, -0x7265 li r3, -0x7265
major_0x04a20_0x30 major_0x04a20_0x30
lwz r8, -0x02ac(r23) lwz r8, EWA.SIGPSpacOnResume(r23)
lwz r9, -0x001c(r23) lwz r9, -0x001c(r23)
cmpw r9, r8 cmpw r9, r8
beq- major_0x04a20_0x44 beq- major_0x04a20_0x44

View File

@ -770,97 +770,138 @@ MPCall_1 ; OUTSIDE REFERER
; KCRegisterCpuPlugin ; 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 mfsprg r14, 0
lwz r15, EWA.PA_CurTask(r14) lwz r15, EWA.PA_CurTask(r14)
lwz r16, ContextBlock.r6(r6) 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 bne+ ReturnMPCallOOM
andi. r8, r5, 0xfff
andi. r8, r5, 0xfff ; r5 page aligned and nonzero?
cmpwi cr1, r5, 0 cmpwi cr1, r5, 0
bne+ ReturnMPCallOOM bne+ ReturnMPCallOOM
beq+ cr1, ReturnMPCallOOM beq+ cr1, ReturnMPCallOOM
_Lock PSA.SchLock, scratch1=r18, scratch2=r19 _Lock PSA.SchLock, scratch1=r18, scratch2=r19
; r14 = coherence group ptr (motherpboard CGRP if not specified in first argument)
mr. r8, r3 mr. r8, r3
bne- KCRegisterCpuPlugin_0x50 bne- @use_specified_cgrp
mfsprg r15, 0 mfsprg r15, 0
lwz r14, -0x0338(r15) lwz r14, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15)
b KCRegisterCpuPlugin_0x60 b @cgrp_done
@use_specified_cgrp
KCRegisterCpuPlugin_0x50
; r8 = id
bl LookupID bl LookupID
cmpwi r9, CoherenceGroup.kIDClass cmpwi r9, CoherenceGroup.kIDClass
mr r14, r8 mr r14, r8
bne+ ReturnMPCallInvalidIDErr bne+ ReturnMPCallInvalidIDErr
@cgrp_done
KCRegisterCpuPlugin_0x60 ; Fail if no CPU plugin descriptor is passed in fourth argument
cmpwi r16, 0x00 cmpwi r16, 0
bne- KCRegisterCpuPlugin_0x74 bne- @no_table_ptr
stw r16, 0x0038(r14) stw r16, CoherenceGroup.PA_CpuPluginDesc(r14)
stw r16, 0x0034(r14) stw r16, CoherenceGroup.LA_CpuPluginDesc(r14)
b ReleaseAndReturnMPCallInvalidIDErr b ReleaseAndReturnMPCallInvalidIDErr
@no_table_ptr
KCRegisterCpuPlugin_0x74 ; Fail if CPU plugin descriptor lies within CPU plugin
add r17, r4, r5 add r17, r4, r5
cmplw r16, r4 cmplw r16, r4
cmplw cr1, r16, r17 cmplw cr1, r16, r17
blt+ ReleaseAndReturnMPCallOOM blt+ ReleaseAndReturnMPCallOOM
bge+ cr1, 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 mr. r19, r19
bne+ ReleaseAndReturnMPCallInvalidIDErr bne+ ReleaseAndReturnMPCallInvalidIDErr
; r18 = physical address of plugin (assumes page-aligned)
mr r27, r4 mr r27, r4
addi r29, r1, 800 addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3 bl PagingFunc3
beq+ ReleaseAndReturnMPCallOOM 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 r27, r16
mr r19, r16 mr r19, r16
addi r29, r1, 800 addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3 bl PagingFunc3
beq+ ReleaseAndReturnMPCallOOM beq+ ReleaseAndReturnMPCallOOM
rlwimi r19, r31, 0, 0, 19 rlwimi r19, r31, 0, 0, 19
stw r4, 0x0028(r14)
stw r18, 0x002c(r14) ; Populate the coherence group structure.
stw r5, 0x0030(r14)
stw r16, 0x0034(r14) ; Save (page-aligned) address of main plugin (second argument)
stw r19, 0x0038(r14) stw r4, CoherenceGroup.LA_CpuPlugin(r14)
lwz r27, 0x0000(r19) stw r18, CoherenceGroup.PA_CpuPlugin(r14)
addi r29, r1, 800
; 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 bl PagingFunc3
beq+ ReleaseAndReturnMPCallOOM beq+ ReleaseAndReturnMPCallOOM
rlwimi r27, r31, 0, 0, 19 rlwimi r27, r31, 0, 0, 19
stw r27, 0x0040(r14) stw r27, CoherenceGroup.PA_CpuPluginStackPtrs(r14)
mfsprg r16, 0 mfsprg r16, 0
lwz r17, -0x001c(r16)
stw r17, 0x004c(r14) ; The cpup should operate in the caller's address space
addi r16, r19, 0x20 lwz r17, EWA.PA_CurAddressSpace(r16)
stw r16, 0x003c(r14) stw r17, CoherenceGroup.CpuPluginSpacePtr(r14)
subi r16, r16, 4
lwz r17, 0x001c(r19) ; Get ptr to dispatch table at descriptor + 32
cmplwi r17, 0x40 addi r16, r19, 0x20
stw r17, 0x0044(r14) 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 bgt+ ReleaseAndReturnMPCallOOM
KCRegisterCpuPlugin_0x114 ; Convert those entries to physical addresses
lwzu r27, 0x0004(r16) @table_convert_loop
addi r29, r1, 800 lwzu r27, 4(r16)
addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3 bl PagingFunc3
beq+ ReleaseAndReturnMPCallOOM beq+ ReleaseAndReturnMPCallOOM
addi r17, r17, -0x01 subi r17, r17, 1
rlwimi r27, r31, 0, 0, 19 rlwimi r27, r31, 0, 0, 19
cmpwi r17, 0x00 cmpwi r17, 0
stw r27, 0x0000(r16) stw r27, 0(r16)
bgt+ KCRegisterCpuPlugin_0x114 bgt+ @table_convert_loop
_log 'CPU plugin registered^n' _log 'CPU plugin registered^n'
; r1 = kdp ; r1 = kdp
@ -1426,7 +1467,7 @@ MPCall_62 ; OUTSIDE REFERER
mr. r8, r3 mr. r8, r3
bne- MPCall_62_0x18 bne- MPCall_62_0x18
mfsprg r15, 0 mfsprg r15, 0
lwz r31, -0x0338(r15) lwz r31, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15)
lwz r3, 0x0000(r31) lwz r3, 0x0000(r31)
b MPCall_62_0x24 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 _Lock PSA.SchLock, scratch1=r16, scratch2=r17
mr r8, r3 mr r8, r3
; r8 = id
bl LookupID bl LookupID
cmpwi r9, CPU.kIDClass cmpwi r9, CPU.kIDClass
mr r31, r8 mr r31, r8
bne+ ReleaseAndReturnMPCallInvalidIDErr bne+ ReleaseAndReturnMPCallInvalidIDErr
lwz r16, 0x0018(r31)
lis r17, 0x00 lwz r16, CPU.Eff(r31)
ori r17, r17, 0x09 lisori r17, 9
and. r17, r17, r16 and. r17, r17, r16
bne+ ReleaseAndReturnMPCallOOM 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 mfsprg r15, 0
; r8 = usually 2?
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 bl SIGP
lwz r17, 0x0008(r31) lwz r17, 0x0008(r31)
addi r16, r31, 0x08 addi r16, r31, 0x08
@ -1631,16 +1671,16 @@ KCStartCPU ; OUTSIDE REFERER
bne+ ReleaseAndReturnZeroFromMPCall bne+ ReleaseAndReturnZeroFromMPCall
mfsprg r15, 0 mfsprg r15, 0
li r16, 0x04 li r16, kResetProcessor
stw r16, -0x0238(r15) stw r16, EWA.SIGPSelector(r15)
lhz r16, CPU.EWA + EWA.CPUIndex(r30) lhz r16, CPU.EWA + EWA.CPUIndex(r30)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
; Put the boots in? ; Put the boots in?
_log 'SIGP kResetProcessor^n' _log 'SIGP kResetProcessor^n'
li r8, 2 li r8, 2 ; args in EWA
bl SIGP bl SIGP
cmpwi r8, -0x7264 cmpwi r8, -0x7264
cmpwi cr1, r8, 0 cmpwi cr1, r8, 0
@ -1700,19 +1740,17 @@ KCStartCPU ; OUTSIDE REFERER
_AssertAndRelease PSA.SchLock, scratch=r16 _AssertAndRelease PSA.SchLock, scratch=r16
; Some EWA/KDP stuff I do not understand
mfsprg r15, 0 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) lhz r16, CPU.EWA + EWA.CPUIndex(r30)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
MPCall_44_0x15c MPCall_44_0x15c
_log 'SIGP kSynchClock^n' _log 'SIGP kSynchClock^n'
li r8, 0x02 li r8, 2 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
cmpwi r8, -0x7264 cmpwi r8, -0x7264
cmpwi cr1, r8, 0x00 cmpwi cr1, r8, 0x00
@ -1720,29 +1758,34 @@ MPCall_44_0x15c
bne- cr1, MPCall_Panic bne- cr1, MPCall_Panic
mfsprg r15, 0 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) lhz r16, CPU.EWA + EWA.CPUIndex(r30)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
lwz r16, 0x064c(r1)
llabel r17, major_0x14bcc lwz r16, KDP.PA_NanoKernelCode(r1)
llabel r17, NewCpuEntryPoint
add r16, r16, r17 add r16, r16, r17
stw r16, -0x0230(r15) stw r16, EWA.SIGPCallR5(r15)
stw r30, -0x022c(r15)
MPCall_44_0x1c0 stw r30, EWA.SIGPCallR6(r15) ; cpu struct
@retry
_log 'SIGP kStartProcessor^n' _log 'SIGP kStartProcessor^n'
li r8, 0x04 li r8, 4 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
cmpwi r8, -0x7264 cmpwi r8, -0x7264
cmpwi cr1, r8, 0x00 cmpwi cr1, r8, 0
beq+ MPCall_44_0x1c0 beq+ @retry
bne- cr1, MPCall_Panic bne- cr1, MPCall_Panic
_log 'Processor scheduled^n' _log 'Processor scheduled^n'
b ReturnZeroFromMPCall 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 MPCpuPlugin
li r8, 0x00
; r7 = flags ; Arguments in registers
; r8 = usually 2? li r8, 0
; Hopefully returns via kcReturnFromInterrupt? Geez...
bl SIGP bl SIGP
mr r3, r8 mr r3, r8
mr r4, r9 mr r4, r9 ; r4 not accessible calling MPLibrary func from C
b CommonMPCallReturnPath b CommonMPCallReturnPath
@ -2121,7 +2169,7 @@ MPCall_108 ; OUTSIDE REFERER
NKSetClockStep ; OUTSIDE REFERER NKSetClockStep ; OUTSIDE REFERER
mfsprg r9, 0 mfsprg r9, 0
lwz r8, -0x0338(r9) lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9)
lwz r9, 0x0024(r8) lwz r9, 0x0024(r8)
cmpwi r9, 0x01 cmpwi r9, 0x01
bgt+ ReturnMPCallOOM bgt+ ReturnMPCallOOM
@ -2199,7 +2247,7 @@ NKSetClockDriftCorrection ; OUTSIDE REFERER
mfsprg r9, 0 mfsprg r9, 0
cmpwi r31, 0x00 cmpwi r31, 0x00
beq+ ReturnMPCallOOM beq+ ReturnMPCallOOM
lwz r8, -0x0338(r9) lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9)
lwz r9, 0x0024(r8) lwz r9, 0x0024(r8)
cmpwi r9, 0x01 cmpwi r9, 0x01
bgt+ ReturnMPCallOOM bgt+ ReturnMPCallOOM

View File

@ -1927,24 +1927,17 @@ BEFOUR
lwz r9, 0x0ee0(r1) lwz r9, 0x0ee0(r1)
addi r9, r9, 0x01 addi r9, r9, 0x01
stw r9, 0x0ee0(r1) stw r9, 0x0ee0(r1)
li r16, 0x05
stw r16, -0x0238(r15)
stw r18, -0x0234(r15)
li r8, 0x02
; r7 = flags li r16, kAlert
; r8 = usually 2? stw r16, EWA.SIGPSelector(r15)
stw r18, EWA.SIGPCallR4(r15)
li r8, 2
b SIGP b SIGP
; major_0x14bcc NewCpuEntryPoint
; Xrefs:
; "EvenMore"
; "SecondCpuCodeViaPtr"
major_0x14bcc
; This func gets passed its CPU struct in r3, ; This func gets passed its CPU struct in r3,
; which lets us find its real EWA pointer. ; which lets us find its real EWA pointer.
@ -2192,10 +2185,12 @@ StopProcessor
bl TasksFuncThatIsNotAMPCall bl TasksFuncThatIsNotAMPCall
_AssertAndRelease PSA.SchLock, scratch=r16 _AssertAndRelease PSA.SchLock, scratch=r16
_log 'SIGP kStopProcessor^n' _log 'SIGP kStopProcessor^n'
li r3, 0x03 li r3, kStopProcessor
lhz r4, CPU.EWA + EWA.CPUIndex(r31) 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' _log 'Stop didn''t work - going to sleep.^n'
StopProcessor_0x10c StopProcessor_0x10c

View File

@ -120,14 +120,11 @@ MPCall_103_0x10c
stw r8, -0x0278(r15) stw r8, -0x0278(r15)
stw r9, -0x0274(r15) stw r9, -0x0274(r15)
mr r29, r17 mr r29, r17
li r16, 0x06 li r16, kSIGP6
stw r16, -0x0238(r15) stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15) lhz r16, EWA.CPUIndex(r15)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
li r8, 0x02 li r8, 2 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
mr r17, r29 mr r17, r29
mfsdr1 r8 mfsdr1 r8
@ -257,14 +254,11 @@ MPCall_103_0x270
li r8, 0x00 li r8, 0x00
stw r8, 0x0004(r17) stw r8, 0x0004(r17)
mfsprg r15, 0 mfsprg r15, 0
li r16, 0x11 li r16, kSIGP17
stw r16, -0x0238(r15) stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15) lhz r16, EWA.CPUIndex(r15)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
li r8, 0x02 li r8, 2 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
li r3, 0x00 li r3, 0x00
b Local_CommonMPCallReturnPath b Local_CommonMPCallReturnPath
@ -362,24 +356,18 @@ RestoreKernelState_0x144
bl SetSpaceSRsAndBATs bl SetSpaceSRsAndBATs
isync isync
mfsprg r15, 0 mfsprg r15, 0
li r16, 0x07 li r16, kSIGP7
stw r16, -0x0238(r15) stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15) lhz r16, EWA.CPUIndex(r15)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
li r8, 0x02 li r8, 2 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
mfsprg r15, 0 mfsprg r15, 0
li r16, 0x11 li r16, kSIGP17
stw r16, -0x0238(r15) stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15) lhz r16, EWA.CPUIndex(r15)
stw r16, -0x0234(r15) stw r16, EWA.SIGPCallR4(r15)
li r8, 0x02 li r8, 2 ; args in EWA
; r7 = flags
; r8 = usually 2?
bl SIGP bl SIGP
li r3, 0x00 li r3, 0x00
b Local_CommonMPCallReturnPath b Local_CommonMPCallReturnPath