mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2025-01-24 02:29:48 +00:00
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:
parent
a323be3c8b
commit
7bee860e40
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user