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
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

View File

@ -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)

View File

@ -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?

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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