; Important note: If you want more than r3-r5, get them from ECB!!! ; Unimplemented MPCalls from MPLibrary: ; NKSetPrInfoPageSize 109 ; NKSetPrInfoILockSizes 110 ; NKSetPrInfoTransCache 111 ; NKSetPrInfoL1Cache 112 ; NKSetPrInfoL2Cache 113 ; AUTO-GENERATED SYMBOL LIST ; IMPORTS: ; NKAddressSpaces ; SpaceL2PIgnoringBATs ; SpaceL2PUsingBATs ; NKConsoleLog ; printb ; printd ; printh ; prints ; printw ; NKIndex ; DeleteID ; GetNextIDOfClass ; LookupID ; MakeID ; NKInterrupts ; IntReturn ; SIGP ; NKPaging ; PagingL2PWithBATs ; NKPoolAllocator ; ExtendPool ; PoolAllocClear ; PoolFree ; NKScheduler ; CalculateTimeslice ; FlagSchEval ; FlagSchEvaluationIfTaskRequires ; NewCpuEntryPoint ; Save_v0_v31 ; SchEval ; SchIdleTask ; SchIdleTaskStopper ; SchRdyTaskLater ; SchRdyTaskNow ; SchRestoreStartingAtR14 ; SchSaveStartingAtR14 ; SchTaskUnrdy ; NKScreenConsole ; ScreenConsole_redraw ; NKTasks ; CreateTask ; NKThud ; panic ; NKTimers ; DequeueTimer ; EnqueueTimer ; GetTime ; NKVMCalls ; EditPTEInHTAB ; GetPARPageInfo ; RemovePageFromTLB ; VMSecondLastExportedFunc ; EXPORTS: ; BlockMPCall (=> NKInterrupts, NKSync) ; CommonMPCallReturnPath (=> NKAddressSpaces, NKSleep, NKTasks) ; MPCall_6_0x78 (=> NKTasks) ; ReleaseAndMPCallWasBad (=> NKAddressSpaces) ; ReleaseAndReturnMPCall (=> NKAddressSpaces, NKSync, NKTasks) ; ReleaseAndReturnMPCallBlueBlocking (=> NKSync) ; ReleaseAndReturnMPCallInvalidIDErr (=> NKAddressSpaces, NKSync, NKTasks) ; ReleaseAndReturnMPCallOOM (=> NKAddressSpaces, NKSync, NKTasks) ; ReleaseAndReturnMPCallPrivilegedErr (=> NKAddressSpaces) ; ReleaseAndReturnMPCallTaskAborted (=> NKSync) ; ReleaseAndReturnParamErrFromMPCall (=> NKAddressSpaces, NKSync) ; ReleaseAndReturnZeroFromMPCall (=> NKAddressSpaces, NKSync, NKTasks) ; ReleaseAndScrambleMPCall (=> NKAddressSpaces, NKSync, NKTasks) ; ReleaseAndTimeoutMPCall (=> NKSync) ; ReturnMPCallInvalidIDErr (=> NKAddressSpaces, NKTasks) ; ReturnMPCallOOM (=> NKAddressSpaces, NKPrimaryIntHandlers, NKSleep, NKSync, NKTasks) ; ReturnParamErrFromMPCall (=> NKAddressSpaces, NKPrimaryIntHandlers, NKSleep) ; ReturnZeroFromMPCall (=> NKAddressSpaces, NKSleep, NKSync) ; ScrambleMPCall (=> NKSync) ; kcMPDispatch (=> NKInit, NKInterrupts) ; major_0x0b0cc (=> NKAddressSpaces) ;MPCall_Panic set MPCall_Panic if &TYPE('NKDebugShim') != 'UNDEFINED' MaxMPCallCount equ 300 else MaxMPCallCount equ 134 endif MACRO DeclareMPCall &n, &code @h org MPCallTable + 4*&n dc.l &code - NKTop - 4*&n org @h ENDM ; Creates a blank table without overflowing PPCAsm's default ; macro stack size :) MACRO CreateMPCallTbl &n if &n >= 1 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 2 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 3 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 4 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 5 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 6 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 7 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 8 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 9 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 10 dc.l (MPCallBad - NKTop) - (* - MPCallTable) endif if &n >= 11 CreateMPCallTbl (&n) - 10 endif ENDM kcMPDispatch ; reached by `sc`, or `twi *, *, 8` bl SchSaveStartingAtR14 lwz r8, EWA.r6(r8) ; clobbers our EWA pointer :( lwz r14, KDP.PA_NanoKernelCode(r1) ; but r14... lwz r15, ContextBlock.r0(r6) ; ...and r15 were saved stw r8, ContextBlock.r6(r6) ; why move r6 from EWA to ContextBlock? b MPCallTableEnd MPCallTable CreateMPCallTbl MaxMPCallCount MPCallTableEnd ; Not sure where this counter table is? lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.MPDispatchCountTblPtr(r1) rlwinm r17, r15, 2, 20, 29 cmplwi r16, 0 beq @no_count lwzx r18, r16, r17 addi r18, r18, 1 stwx r18, r16, r17 @no_count cmplwi r15, MaxMPCallCount rlwimi r14, r15, 2, 21, 29 llabel r16, MPCallTable lwzx r15, r16, r14 add r15, r15, r14 mtlr r15 bltlr ; Handler for out-of-range or unimplemented (debug) ; MPCalls. MPCallBad ; OUTSIDE REFERER li r3, -4 b CommonMPCallReturnPath ReleaseAndMPCallWasBad ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 b MPCallBad ; > r1 = kdp ReleaseAndReturnZeroFromMPCall ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 ReturnZeroFromMPCall ; OUTSIDE REFERER li r3, 0x00 b CommonMPCallReturnPath ReleaseAndScrambleMPCall ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 ; I'd really live a name for this. ScrambleMPCall ; OUTSIDE REFERER mfspr r16, pvr rlwinm. r16, r16, 0, 0, 14 beq @is_601 mftb r4 b @not_601 @is_601 mfspr r4, rtcl @not_601 xori r16, r4, 0x1007 xoris r16, r16, 0x1950 stw r16, PSA.ScrambledMPCallTime(r1) li r3, -29294 b CommonMPCallReturnPath ; dead code? li r3, kMPDeletedErr b CommonMPCallReturnPath ReleaseAndTimeoutMPCall ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 li r3, kMPTimeOutErr b CommonMPCallReturnPath ReleaseAndReturnMPCallTaskAborted ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 li r3, kMPTaskAbortedErr b CommonMPCallReturnPath ReleaseAndReturnMPCallOOM ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 ReturnMPCallOOM ; OUTSIDE REFERER li r3, kMPInsufficientResourcesErr b CommonMPCallReturnPath ReleaseAndReturnMPCallBlueBlocking ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 ReturnMPCallBlueBlocking ; OUTSIDE REFERER li r3, kMPBlueBlockingErr b CommonMPCallReturnPath ReleaseAndReturnParamErrFromMPCall ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 ReturnParamErrFromMPCall ; OUTSIDE REFERER li r3, -0x32 b CommonMPCallReturnPath ReleaseAndReturnMPCallPrivilegedErr ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 li r3, kMPPrivilegedErr b CommonMPCallReturnPath ReleaseAndReturnMPCallInvalidIDErr ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 ReturnMPCallInvalidIDErr ; OUTSIDE REFERER li r3, kMPInvalidIDErr b CommonMPCallReturnPath major_0x0b0cc ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 li r3, -0x725a b CommonMPCallReturnPath ReturnZeroFromMPCall_again ; OUTSIDE REFERER li r3, 0x00 b CommonMPCallReturnPath BlockMPCall ; OUTSIDE REFERER crclr 10 b TrulyCommonMPCallReturnPath ReleaseAndReturnMPCall ; OUTSIDE REFERER _AssertAndRelease PSA.SchLock, scratch=r16 CommonMPCallReturnPath ; OUTSIDE REFERER crset 10 TrulyCommonMPCallReturnPath ; OUTSIDE REFERER mfsprg r8, 0 lwz r9, 0x0134(r6) stw r9, 0x0018(r8) bc BO_IF_NOT, 10, @block ;return immediately bl SchRestoreStartingAtR14 b IntReturn @block b SchEval ; Called after MPLibrary creates a new structure DeclareMPCall 0, MPCall_0 MPCall_0 ; OUTSIDE REFERER andi. r16, r3, 0xfff mr r30, r7 mr r29, r6 bne ReturnMPCallOOM ; Fail if this page is outside of the PAR rlwinm. r4, r3, 20, 12, 31 lwz r9, KDP.VMLogicalPages(r1) beq ReturnMPCallOOM cmplw r4, r9 bge ReturnMPCallOOM _Lock PSA.HTABLock, scratch1=r17, scratch2=r18 bl GetPARPageInfo bge cr4, MPCall_0_0xd8 bgt cr5, MPCall_0_0xd8 bns cr7, MPCall_0_0xd8 bgt cr7, MPCall_0_0xd8 bltl cr5, RemovePageFromTLB bgel cr5, VMSecondLastExportedFunc ori r16, r16, 0x404 li r31, 0x03 rlwimi r9, r31, 0, 30, 31 bl EditPTEInHTAB mr r7, r30 mr r6, r29 _AssertAndRelease PSA.HTABLock, scratch=r16 _Lock PSA.PoolLock, scratch1=r16, scratch2=r17 rlwinm r8, r9, 0, 0, 19 mr r9, r3 ; r1 = kdp ; r8 = anywhere in new page (phys) ; r9 = page_virt bl ExtendPool _AssertAndRelease PSA.PoolLock, scratch=r16 b ReturnZeroFromMPCall MPCall_0_0xd8 mr r7, r30 mr r6, r29 _AssertAndRelease PSA.HTABLock, scratch=r16 b ReturnMPCallOOM ; MPCall_1 DeclareMPCall 1, MPCall_1 MPCall_1 ; OUTSIDE REFERER b ReturnZeroFromMPCall_again ; ARG MPCoherenceGroupID r3, CpuPluginPtr r4, CpuPluginSize r5, CpuPluginDesc r6 ; RET OSStatus r3 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' mfsprg r14, 0 lwz r15, EWA.PA_CurTask(r14) lwz r16, ContextBlock.r6(r6) ; 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 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 @use_specified_cgrp mfsprg r15, 0 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 ; 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 ; 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 ; 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, KDP.BATs + 0xa0 bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM 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, KDP.BATs + 0xa0 bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM 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 PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM rlwimi r27, r31, 0, 0, 19 stw r27, CoherenceGroup.PA_CpuPluginStackPtrs(r14) mfsprg r16, 0 ; 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 ; Convert those entries to physical addresses @table_convert_loop lwzu r27, 4(r16) addi r29, r1, KDP.BATs + 0xa0 bl PagingL2PWithBATs beq ReleaseAndReturnMPCallOOM 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 b ReleaseAndReturnZeroFromMPCall ; Called by MPProcessors and MPProcessorsScheduled ; ARG bool r3 scheduled_only ; RET int r3 DeclareMPCall 3, MPProcessors MPProcessors mfsprg r15, 0 lwz r14, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15) mr. r8, r3 lwz r3, CoherenceGroup.CpuCount(r14) beq CommonMPCallReturnPath lwz r3, CoherenceGroup.ScheduledCpuCount(r14) b CommonMPCallReturnPath ; ARG AddressSpaceID r3 ; RET AddressSpaceID r3, ??? r4, ProcessStructID r5 DeclareMPCall 4, MPCreateProcess MPCreateProcess _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr. r8, r3 bne @spac_id_supplied lwz r3, PSA.SystemAddressSpaceID(r1) mr r8, r3 @spac_id_supplied bl LookupID ; r8 = something not sure what ; r9 = 0:inval, 1:proc, 2:task, 3:timer, 4:q, 5:sema, 6:cr, 7:cpu, 8:addrspc, 9:evtg, 10:cohg, 11:area, 12:not, 13:log cmpwi r9, AddressSpace.kIDClass mr r30, r8 bne ReleaseAndReturnMPCallInvalidIDErr li r8, 0x20 ;Process.Size bl PoolAllocClear mr. r31, r8 beq ReleaseAndScrambleMPCall li r9, Process.kIDClass bl MakeID cmpwi r8, 0x00 bne @did_not_fail mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @did_not_fail stw r8, Process.ID(r31) lisori r16, Process.kSignature stw r16, Process.Signature(r31) stw r3, Process.SystemAddressSpaceID(r31) ; NOT SYSTEM -- fix struct stw r30, Process.SystemAddressSpacePtr(r31) lwz r17, Process.AddressSpaceCount(r31) addi r17, r17, 1 stw r17, Process.AddressSpaceCount(r31) mr r5, r8 ; r1 = kdp b ReleaseAndReturnZeroFromMPCall DeclareMPCall 5, MPTerminateProcess MPTerminateProcess _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, Process.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, 0x0008(r31) rlwinm. r17, r16, 0, 30, 30 bne ReleaseAndReturnMPCallOOM ori r16, r16, 0x02 stw r16, 0x0008(r31) mr r8, r3 ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ; ARG ProcessID r3 ; RET OSStatus r3 DeclareMPCall 6, MPDeleteProcess MPDeleteProcess _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Process.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, Process.Flags(r31) lwz r17, Process.TaskCount(r31) rlwinm. r8, r16, 0, Process.kFlag30, Process.kFlag30 cmpwi cr1, r17, 0 beq ReleaseAndReturnMPCallOOM bne cr1, ReleaseAndReturnMPCallOOM mr r8, r3 bl DeleteID _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 mr r8, r31 bl PoolFree b ReturnZeroFromMPCall MPCall_6_0x78 ; OUTSIDE REFERER _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mfsprg r16, 0 rlwinm. r8, r7, 0, 10, 10 lwz r17, KDP.PA_ECB(r1) lwz r31, EWA.PA_CurTask(r16) beq MPCall_6_0xb4 lwz r8, ContextBlock.PriorityShifty(r17) rlwinm r8, r8, 0, 24, 21 oris r8, r8, 0x8000 stw r8, ContextBlock.PriorityShifty(r17) MPCall_6_0xb4 mr r8, r31 bl SchTaskUnrdy li r16, Task.kNominalPriority stb r16, Task.Priority(r31) bl SchRdyTaskNow mr r8, r31 bl FlagSchEvaluationIfTaskRequires _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 b CommonMPCallReturnPath ; Implements MPYield (null argument) ; Caller gets its priority set to nominal ; ARG TaskID r3 (null for MPYield) ; RET OSStatus r3 DeclareMPCall 13, MPYieldWithHint MPYieldWithHint _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mfsprg r16, 0 rlwinm. r8, r7, 0, 10, 10 lwz r17, KDP.PA_ECB(r1) lwz r31, EWA.PA_CurTask(r16) beq @i_am_important ; not 68k mode? clrlwi. r8, r3, 31 lwz r8, ContextBlock.PriorityShifty(r17) rlwinm r8, r8, 0, 24, 21 oris r8, r8, 0x8000 stw r8, ContextBlock.PriorityShifty(r17) beq @i_am_important ; MPYield call ; If this task is lbz r16, Task.Priority(r31) cmpwi r16, Task.kNominalPriority bge @return mr r8, r31 bl SchTaskUnrdy li r16, Task.kNominalPriority stb r16, Task.Priority(r31) bl SchRdyTaskLater b @return @i_am_important mr r8, r31 bl SchTaskUnrdy li r16, Task.kNominalPriority stb r16, Task.Priority(r31) bl SchRdyTaskNow @return mr r8, r31 bl FlagSchEvaluationIfTaskRequires _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 b CommonMPCallReturnPath ; ARG AbsoluteTime r3/r4 ; RET OSStatus r3 DeclareMPCall 33, MPDelayUntil MPDelayUntil rlwinm. r8, r7, 0, EWA.kFlagBlue, EWA.kFlagBlue bne ReturnMPCallBlueBlocking _Lock PSA.SchLock, scratch1=r16, scratch2=r17 b _MPDelayUntilCommon ; This version is allowed while the blue task is running ; ARG AbsoluteTime r3/r4 ; RET OSStatus r3 DeclareMPCall 55, MPDelayUntilSys MPDelayUntilSys rlwinm. r8, r7, 0, EWA.kFlagBlue, EWA.kFlagBlue lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1) beq _MPDelayUntilCommon ; Why the hell are we counting interrupts? lwz r17, PSA.OtherSystemContextPtr(r1) lwz r18, KDP.PA_ECB(r1) cmpw r16, r17 stw r16, PSA.OtherSystemContextPtr(r1) bne ReturnZeroFromMPCall lwz r8, ContextBlock.PriorityShifty(r18) rlwinm r8, r8, 0, 24, 21 oris r8, r8, 0x8000 stw r8, ContextBlock.PriorityShifty(r18) _Lock PSA.SchLock, scratch1=r16, scratch2=r17 lwz r16, PSA.BlueSpinningOn(r1) cmpwi r16, -1 li r16, 0 bne _MPDelayUntilCommon stw r16, PSA.BlueSpinningOn(r1) b ReleaseAndReturnZeroFromMPCall _MPDelayUntilCommon mfsprg r16, 0 li r17, 1 lwz r31, EWA.PA_CurTask(r16) addi r16, r31, Task.Timer stb r17, Timer.Kind(r16) ; High bit is possibly suspect? Or a flag? clrlwi r3, r3, 1 stw r3, Timer.Time(r16) stw r4, Timer.Time+4(r16) stw r31, Timer.ParentTaskPtr(r16) mr r8, r16 bl EnqueueTimer mr r8, r31 bl SchTaskUnrdy addi r16, r1, PSA.DelayQueue addi r17, r31, Timer.QueueLLL stw r16, LLL.Freeform(r17) InsertAsPrev r17, r16, scratch=r18 li r3, 0 b BlockMPCall DeclareMPCall 34, MPCall_34 MPCall_34 ; OUTSIDE REFERER mr r8, r3 mr r9, r4 ; r1 = kdp ; r9 = kind bl MakeID cmpwi r8, 0x00 beq ScrambleMPCall mr r5, r8 b ReturnZeroFromMPCall DeclareMPCall 35, MPCall_35 MPCall_35 ; OUTSIDE REFERER mr r8, r3 bl DeleteID cmpwi r8, 0x01 beq ReturnZeroFromMPCall b ReturnMPCallInvalidIDErr DeclareMPCall 36, MPCall_36 MPCall_36 ; OUTSIDE REFERER mr r8, r3 ; r8 = id bl LookupID cmpwi r9, 0 ; invalid mr r4, r9 mr r5, r8 bne ReturnZeroFromMPCall b ReturnMPCallInvalidIDErr ; Replace the provided process/coherence/console ID with ; the "next" one. IDs were opaque but were only longs. ; Wrapped by MPGetNext*ID, which indirects the opaque ID ; structure. ; From MP docs: A coherence group is the set of processors ; and other bus controllers that have cache-coherent ; access to memory. Mac OS 9 defines only one coherence ; group, which is all the processors that can access ; internal memory (RAM). Other coherence groups are ; possible; for example, a PCI card with its own memory ; and processors can comprise a coherence group. ; > r3 = kind (process=1,coherence=10,console=13) ; > r4 = prev_id ; < r3 = MP result code ; < r4 = next_id DeclareMPCall 37, MPGetNextID MPGetNextID mr r8, r4 mr r9, r3 bl GetNextIDOfClass cmpwi r8, 0x00 mr r4, r8 bne ReturnZeroFromMPCall b ReturnMPCallInvalidIDErr ; Replace the provided address ; space/task/queue/semaphore/critical ; region/timer/event/notification ID with the "next" one. ; IDs were opaque but were only longs. Wrapped by ; MPGetNext*ID, which indirects the opaque ID structure. ; Differs from KCGetNextID because it deals in ; objects owned by a particular process. ; Useful info about some poorly understood structures ; ARG ProcessID r3, IDClass r4, ID r5 ; RET MPErr r3, IDClass r4, ID r5 DeclareMPCall 116, MPGetNextIDOwnedByProcess MPGetNextIDOwnedByProcess ; Confirm that owner ID in r3 is a Process mr r8, r3 bl LookupID cmpwi r9, Process.kIDClass bne ReturnMPCallInvalidIDErr ; Loop over IDs (and resolve them) until one is owned by the Process @try_another_id mr r8, r5 mr r9, r4 ; ARG ID r8, IDClass r9 bl GetNextIDOfClass ; RET ID r8 mr. r5, r8 beq ReturnMPCallInvalidIDErr ; ARG ID r8 bl LookupID ; RET Ptr r8, IDClass r9 cmpwi r4, Task.kIDClass cmpwi cr1, r4, Timer.kIDClass beq @task beq cr1, @timer cmpwi r4, Queue.kIDClass cmpwi cr1, r4, Semaphore.kIDClass beq @queue beq cr1, @semaphore cmpwi r4, CriticalRegion.kIDClass cmpwi cr1, r4, AddressSpace.kIDClass beq @critical_region beq cr1, @address_space cmpwi r4, EventGroup.kIDClass cmpwi cr1, r4, Area.kIDClass beq @event_group beq cr1, @area cmpwi r4, Notification.kIDClass cmpwi cr1, r4, ConsoleLog.kIDClass beq @notification beq cr1, @console_log b ReturnParamErrFromMPCall @task lwz r17, Task.Flags(r8) lwz r9, Task.ProcessID(r8) rlwinm. r17, r17, 0, 15, 15 beq @not_owned_by_blue_process lwz r9, PSA.blueProcessPtr(r1) lwz r9, Task.ID(r9) @not_owned_by_blue_process cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @timer lwz r9, Timer.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @queue lwz r9, Queue.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @semaphore lwz r9, Semaphore.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @critical_region lwz r9, CriticalRegion.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @address_space lwz r9, AddressSpace.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @event_group lwz r9, EventGroup.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @area lwz r9, Area.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @notification lwz r9, Notification.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall @console_log lwz r9, ConsoleLog.ProcessID(r8) cmpw r9, r3 bne @try_another_id b ReturnZeroFromMPCall DeclareMPCall 38, MPCall_38 MPCall_38 ; OUTSIDE REFERER mr r8, r3 ; r8 = id bl LookupID cmpwi r9, Process.kIDClass bne ReturnMPCallInvalidIDErr mr r31, r8 MPCall_38_0x14 mr r8, r4 li r9, 0x02 bl GetNextIDOfClass cmpwi r8, 0x00 beq ReturnMPCallInvalidIDErr mr r4, r8 ; r8 = id bl LookupID ; r8 = something not sure what ; r9 = 0:inval, 1:proc, 2:task, 3:timer, 4:q, 5:sema, 6:cr, 7:cpu, 8:addrspc, 9:evtg, 10:cohg, 11:area, 12:not, 13:log lwz r17, 0x0064(r8) lwz r16, 0x0060(r8) rlwinm. r17, r17, 0, 15, 15 beq MPCall_38_0x48 lwz r16, PSA.blueProcessPtr(r1) lwz r16, 0x0000(r16) MPCall_38_0x48 cmpw r16, r3 beq ReturnZeroFromMPCall b MPCall_38_0x14 DeclareMPCall 62, MPGetNextCpuID MPGetNextCpuID mr. r8, r3 bne @r3_nonzero ;r3 zero mfsprg r15, 0 lwz r31, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15) lwz r3, 0(r31) b @endif @r3_nonzero bl LookupID cmpwi r9, CoherenceGroup.kIDClass bne ReturnMPCallInvalidIDErr @endif @loop mr r8, r4 li r9, CPU.kIDClass bl GetNextIDOfClass cmpwi r8, 0 beq ReturnMPCallInvalidIDErr mr r4, r8 bl LookupID lwz r16, CPU.LLL + LLL.Freeform(r8) lwz r17, CPU.ID(r16) cmpw r17, r3 bne @loop b ReturnZeroFromMPCall DeclareMPCall 42, MPCreateProcessor MPCreateProcessor mr. r8, r3 bne @cgrpProvided mfsprg r15, 0 lwz r30, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15) b @gotCgrp @cgrpProvided bl LookupID cmpwi r9, CoherenceGroup.kIDClass mr r30, r8 bne ReturnMPCallInvalidIDErr @gotCgrp li r8, CPU.Size bl PoolAllocClear mr. r31, r8 beq ScrambleMPCall _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, CPU.kIDClass bl MakeID cmpwi r8, 0 bne+ @success mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @success stw r8, CPU.ID(r31) lisori r16, CPU.kSignature stw r8, ContextBlock.r6(r6) ; return ID in r6 stw r16, CPU.Signature(r31) lwz r17, 0x0020(r30) addi r17, r17, 0x01 stw r17, 0x0020(r30) addi r16, r31, 0x08 stw r30, 0x0000(r16) InsertAsPrev r16, r30, scratch=r17 lisori r8, 11 lisori r8, 6 stw r8, CPU.Flags(r31) addi r30, r31, CPU.EWABase addi r8, r1, PSA.Base stw r8, EWA.PA_PSA - EWA.Base(r30) stw r1, EWA.PA_KDP - EWA.Base(r30) li r8, 0 stw r8, EWA.PA_CurTask - EWA.Base(r30) ; Matches code in Init.s quite closely li r8, -0x01 sth r4, 0x020a(r30) stb r8, 0x0209(r30) ; interesting... lwz r8, EWA.PA_IRP(r1) stw r8, EWA.PA_IRP - EWA.Base(r30) lisori r8, 'time' stw r8, EWA.TimeList - EWA.Base + LLL.Signature(r30) li r8, 0x04 stb r8, 0x0014(r30) li r8, 0x01 stb r8, 0x0016(r30) li r8, 0x00 stb r8, 0x0017(r30) lisori r8, 0x7fffffff stw r8, 0x0038(r30) oris r8, r8, 0xffff stw r8, 0x003c(r30) b ReleaseAndReturnZeroFromMPCall ; Simple MPLibrary wrapper DeclareMPCall 43, MPDeleteProcessor MPDeleteProcessor _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, CPU.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lwz r16, CPU.Flags(r31) lisori r17, 9 and. r17, r17, r16 bne ReleaseAndReturnMPCallOOM 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 lwz r18, 0x0020(r17) addi r18, r18, -0x01 stw r18, 0x0020(r17) RemoveFromList r16, scratch1=r17, scratch2=r18 mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID ; r1 = kdp b ReleaseAndReturnZeroFromMPCall DeclareMPCall 44, MPStartScheduling ; ARG CpuID r3 MPStartScheduling _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, CPU.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r30, r8 lwz r16, CPU.Flags(r30) rlwinm. r8, r16, 0, 28, 28 bne ReleaseAndReturnZeroFromMPCall mfsprg r15, 0 li r16, kResetProcessor stw r16, EWA.SIGPSelector(r15) lhz r16, CPU.EWA + EWA.CPUIndex(r30) stw r16, EWA.SIGPCallR4(r15) ; Put the boots in? _log 'SIGP kResetProcessor^n' li r8, 2 ; args in EWA bl SIGP cmpwi r8, -0x7264 cmpwi cr1, r8, 0 beq ReleaseAndReturnMPCallOOM bne cr1, ReleaseAndReturnMPCallOOM ; Every CPU gets an idle task _log 'Creating idle task^n' mr r31, r7 rlwinm r7, r7, 0, 13, 11 lwz r8, PSA.blueProcessPtr(r1) ; ARG Flags r7, Process *r8 bl CreateTask ; RET Task *r8 mr r7, r31 mr. r31, r8 beq ReleaseAndScrambleMPCall stw r31, CPU.IdleTaskPtr(r30) lisori r8, 'idle' stw r8, Task.Name(r31) lisori r8, 0x80040 ; (Z>>Task.kFlag12)| (Z>>Task.kFlag25) stw r8, Task.Flags(r31) li r8, 1 stw r8, Task.Weight(r31) li r8, Task.kIdlePriority stb r8, Task.Priority(r31) ; whoa -- cpu structs arent this big? lhz r8, CPU.EWA + EWA.CPUIndex(r30) sth r8, Task.CPUIndex(r31) lwz r8, Task.ContextBlock + ContextBlock.Flags(r31) _bset r8, r8, 9 stw r8, Task.ContextBlock + ContextBlock.Flags(r31) lwz r8, KDP.PA_NanoKernelCode(r1) llabel r26, SchIdleTask add r8, r8, r26 stw r8, Task.ContextBlock + ContextBlock.CodePtr(r31) ; better compare this with init code idle task lwz r8, Task.ContextBlock + ContextBlock.MSR(r31) andi. r8, r8, 0xbfcf stw r8, Task.ContextBlock + ContextBlock.MSR(r31) _AssertAndRelease PSA.SchLock, scratch=r16 mfsprg r15, 0 li r16, kSynchClock stw r16, EWA.SIGPSelector(r15) lhz r16, CPU.EWA + EWA.CPUIndex(r30) stw r16, EWA.SIGPCallR4(r15) MPCall_44_0x15c _log 'SIGP kSynchClock^n' li r8, 2 ; args in EWA bl SIGP cmpwi r8, -0x7264 cmpwi cr1, r8, 0x00 beq MPCall_44_0x15c bne cr1, MPCall_Panic mfsprg r15, 0 li r16, kStartProcessor stw r16, EWA.SIGPSelector(r15) lhz r16, CPU.EWA + EWA.CPUIndex(r30) stw r16, EWA.SIGPCallR4(r15) lwz r16, KDP.PA_NanoKernelCode(r1) llabel r17, NewCpuEntryPoint add r16, r16, r17 stw r16, EWA.SIGPCallR5(r15) stw r30, EWA.SIGPCallR6(r15) ; cpu struct @retry _log 'SIGP kStartProcessor^n' li r8, 4 ; args in EWA bl SIGP cmpwi r8, -0x7264 cmpwi cr1, r8, 0 beq @retry bne cr1, MPCall_Panic _log 'Processor scheduled^n' b ReturnZeroFromMPCall DeclareMPCall 45, MPStopScheduling MPStopScheduling _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, CPU.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r30, r8 lwz r16, CPU.Flags(r30) rlwinm. r8, r16, 0, CPU.kFlagScheduled, CPU.kFlagScheduled beq ReleaseAndReturnZeroFromMPCall lwz r31, CPU.IdleTaskPtr(r30) rlwinm. r8, r16, 0, CPU.kFlag31, CPU.kFlag31 bne ReleaseAndReturnMPCallOOM lbz r17, Task.Priority(r31) cmpwi r17, Task.kCriticalPriority beq @running_critical_task lwz r17, Task.Flags(r31) _bset r17, r17, Task.kFlag8 stw r17, Task.Flags(r31) mr r8, r31 bl SchTaskUnrdy li r17, Task.kCriticalPriority stb r17, Task.Priority(r31) mr r8, r31 bl SchRdyTaskLater bl CalculateTimeslice mr r8, r31 bl FlagSchEval lwz r8, KDP.PA_NanoKernelCode(r1) llabel r9, SchIdleTaskStopper add r8, r8, r9 stw r8, Task.ContextBlock + ContextBlock.CodePtr(r31) @running_critical_task _AssertAndRelease PSA.SchLock + Lock.Count, scratch=r16 b MPCall_6_0x78 ; Directly wrapped by MPLibrary ; ARG selector r3, arbitrary args r4... ; RET arbitrary DeclareMPCall 46, MPCpuPlugin MPCpuPlugin ; Arguments in registers li r8, 0 ; Hopefully returns via kcSchExitInterrupt? Geez... bl SIGP mr r3, r8 mr r4, r9 ; r4 not accessible calling MPLibrary func from C b CommonMPCallReturnPath DeclareMPCall 47, MPCall_47 MPCall_47 ; OUTSIDE REFERER rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec lwz r15, 0x00d8(r6) beq ReturnMPCallOOM cmpwi r15, 0x00 mr r16, r2 beq ReturnMPCallOOM mr r17, r3 mr r18, r4 mr r19, r5 bl Save_v0_v31 mr r2, r16 mr r3, r17 mr r4, r18 mr r5, r19 b ReturnZeroFromMPCall ; MPCall_48_Bad DeclareMPCall 48, MPCall_48_Bad MPCall_48_Bad ; OUTSIDE REFERER b MPCallBad ; MPDebugPutString DeclareMPCall 96, MPDebugPutString MPDebugPutString ; OUTSIDE REFERER rlwinm. r9, r11, 0, 27, 27 mr r8, r3 beq MPDebugPutString_0x1c li r9, 0x00 bl SpaceL2PUsingBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17 beq MPDebugPutString_0x24 rlwimi r8, r17, 0, 0, 19 MPDebugPutString_0x1c bl PrintS b ReturnZeroFromMPCall MPDebugPutString_0x24 _log 'NKxprintf (V->P translation error)^n' b ReturnMPCallOOM ; ARG long r3, int r4 size (1:byte, 2:half, else:word) DeclareMPCall 97, MPDebugPutHex MPDebugPutHex mr r8, r3 cmpwi r4, 1 cmpwi cr1, r4, 2 beq @byte beq cr1, @half bl Printw b CommonMPCallReturnPath @half bl Printh b CommonMPCallReturnPath @byte bl Printb b CommonMPCallReturnPath DeclareMPCall 124, MPDebugPutDec MPDebugPutDec mr r8, r3 bl Printd b CommonMPCallReturnPath DeclareMPCall 99, MPSetBlueProcessID MPSetBlueProcessID mfsprg r16, 0 rlwinm. r8, r7, 0, EWA.kFlagBlue, EWA.kFlagBlue lwz r31, EWA.PA_CurTask(r16) beq ReturnMPCallOOM ; not in blue -> fail mr r8, r3 bl LookupID cmpwi r9, Process.kIDClass bne ReturnMPCallInvalidIDErr stw r3, Task.ProcessID(r31) stw r4, Task.SomeLabelField(r31) b ReturnZeroFromMPCall DeclareMPCall 104, MPRegisterThermalHandler MPRegisterThermalHandler _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr. r8, r3 beq @is_zero bl LookupID cmpwi r9, Notification.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr @is_zero stw r3, PSA.ThermalHandlerID(r1) b ReleaseAndReturnZeroFromMPCall DeclareMPCall 105, MPRegisterPMFHandler MPRegisterPMFHandler _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr. r8, r3 beq @is_zero bl LookupID cmpwi r9, Notification.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr @is_zero stw r3, PSA.PMFHandlerID(r1) b ReleaseAndReturnZeroFromMPCall DeclareMPCall 106, MPMarkPMFTask MPMarkPMFTask _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mfsprg r30, 0 mr. r8, r3 lwz r31, EWA.PA_CurTask(r30) beq @use_this_task_instead bl LookupID cmpwi r9, Task.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr @use_this_task_instead ; Insert bit 31 of r4 into bit 21 of these flags lwz r17, Task.Flags(r31) rlwimi r17, r4, 10, Task.kFlagPerfMon, Task.kFlagPerfMon stw r17, Task.Flags(r31) ; Don't know what this does! mr r8, r31 bl FlagSchEval b ReleaseAndReturnZeroFromMPCall ; ARG int r6: ; 2: SystemInfo ; 3: DiagInfo ; 4: NanoKernelInfo ; 5: ProcessorInfo ; 6: HWInfo ; 7: ProcessorState ; RET Ptr r4, short r5 ver, short r6 len DeclareMPCall 107, NKLocateInfoRecord NKLocateInfoRecord cmpwi r3, 5 cmpwi cr1, r3, 2 beq @ProcessorInfo beq cr1, @SystemInfo cmpwi r3, 3 cmpwi cr1, r3, 4 beq @DiagInfo beq cr1, @NanoKernelInfo cmpwi r3, 7 cmpwi cr1, r3, 6 beq @ProcessorState bne cr1, ReturnParamErrFromMPCall lwz r4, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKHWInfoLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKHWInfoVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall @ProcessorState lwz r4, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKProcessorStateLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKProcessorStateVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall @ProcessorInfo lwz r4, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall @NanoKernelInfo lwz r4, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall @DiagInfo lwz r4, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKDiagInfoLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKDiagInfoVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall @SystemInfo lwz r4, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1) lhz r16, KDP.InfoRecord + InfoRecord.NKSystemInfoLen(r1) lhz r5, KDP.InfoRecord + InfoRecord.NKSystemInfoVer(r1) stw r16, ContextBlock.r6(r6) b ReturnZeroFromMPCall ; ARG int r3 stop ; long r4 CpuClockRateHz ; long r5 BusClockRateHz ; long r6 DecClockRateHz ; RET OSStatus r3 DeclareMPCall 108, NKSetPrInfoClockRates NKSetPrInfoClockRates cmplwi r3, 2 bge ReturnParamErrFromMPCall mulli r17, r3, 16 addi r18, r1, KDP.ProcessorInfo + NKProcessorInfo.ClockRates add r18, r17, r18 lwz r16, ContextBlock.r6(r6) stw r4, 0(r18) stw r5, 4(r18) stw r16, 8(r18) _log 'Clock rates for step ' mr r8, r3 bl Printd _log '- Cpu ' mr r8, r4 bl Printd _log '- Bus ' mr r8, r5 bl Printd _log '- Dec ' mr r8, r16 bl Printd _log 'Hz^n' b ReturnZeroFromMPCall ; NKSetClockStep ; Debug string matches MPLibrary! ; 0xf7e(r1) = clock_step (half-word) ; > r3 = new_clock_step # (half-word) DeclareMPCall 131, NKSetClockStep NKSetClockStep ; OUTSIDE REFERER mfsprg r9, 0 lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) lwz r9, 0x0024(r8) cmpwi r9, 0x01 bgt ReturnMPCallOOM lhz r19, 0x0f7e(r1) _log 'NKSetClockStep - current ' mr r8, r19 bl Printd _log ' new ' mr r8, r3 bl Printd _log '^n' cmplwi r3, 0x02 cmpw cr1, r3, r19 bge ReturnParamErrFromMPCall beq cr1, ReturnMPCallOOM mulli r17, r3, 0x10 addi r18, r1, 0xf80 sth r17, 0x0f7e(r1) add r18, r17, r18 lwz r16, 0x0000(r18) lwz r17, 0x0004(r18) stw r16, 0x0f24(r1) stw r17, 0x0f28(r1) lwz r16, 0x0f88(r1) stw r16, 0x0f2c(r1) _Lock PSA.SchLock, scratch1=r16, scratch2=r17 lwz r16, 0x0008(r18) stw r16, PSA.DecClockRateHzCopy(r1) bgt cr1, NKSetClockStep_0xec lwz r31, PSA.OtherTimerQueuePtr(r1) lbz r18, 0x0017(r31) cmpwi r18, 0x00 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall mr r8, r31 bl DequeueTimer ; r1 = kdp b ReleaseAndReturnZeroFromMPCall NKSetClockStep_0xec lwz r31, PSA.OtherTimerQueuePtr(r1) lbz r18, 0x0017(r31) cmpwi r18, 0x01 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall bl GetTime stw r8, 0x0038(r31) stw r9, 0x003c(r31) mr r8, r31 bl EnqueueTimer ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ; NKSetClockDriftCorrection ; There's a one-billion constant in here, for fractional ; expression. ; PSA._36c(r1) = tb_drift_numerator ; PSA._368(r1) = tb_drift_denominator ; > r3 = to DeclareMPCall 132, NKSetClockDriftCorrection NKSetClockDriftCorrection ; OUTSIDE REFERER lwz r31, PSA._364(r1) mfsprg r9, 0 cmpwi r31, 0x00 beq ReturnMPCallOOM lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) lwz r9, 0x0024(r8) cmpwi r9, 0x01 bgt ReturnMPCallOOM lwz r19, 0x0fa0(r1) cmpwi r3, 0x00 cmpw cr1, r3, r19 stw r3, 0x0fa0(r1) beq NKSetClockDriftCorrection_0x12c beq cr1, ReturnZeroFromMPCall lis r16, 0x3b9a ori r16, r16, 0xca00 lwz r17, 0x0f88(r1) srwi r17, r17, 7 divw r18, r16, r3 cmpw r18, r17 bge NKSetClockDriftCorrection_0x64 divw r16, r16, r17 mr r18, r17 divw r17, r3, r16 b NKSetClockDriftCorrection_0x6c NKSetClockDriftCorrection_0x64 rlwinm r17, r3, 2, 30, 30 addi r17, r17, 0x01 NKSetClockDriftCorrection_0x6c stw r17, PSA._36c(r1) stw r18, PSA._368(r1) _log 'TB drift adjusted to ' mr r8, r3 bl Printd _log ' ppb ( ' mr r8, r17 bl Printd _log '/ ' mr r8, r18 bl Printd _log ')^n' _Lock PSA.SchLock, scratch1=r16, scratch2=r17 lwz r31, PSA._364(r1) lbz r18, 0x0017(r31) cmpwi r18, 0x01 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall bl GetTime stw r8, 0x0038(r31) stw r9, 0x003c(r31) mr r8, r31 bl EnqueueTimer ; r1 = kdp b ReleaseAndReturnZeroFromMPCall NKSetClockDriftCorrection_0x12c _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r17, 0x00 stw r17, PSA._36c(r1) stw r17, PSA._368(r1) lwz r31, PSA._364(r1) lbz r18, 0x0017(r31) cmpwi r18, 0x00 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall mr r8, r31 bl DequeueTimer ; r1 = kdp b ReleaseAndReturnZeroFromMPCall DeclareMPCall 115, MPCall_115 MPCall_115 ; OUTSIDE REFERER _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, ConsoleLog.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lwz r30, 0x000c(r31) cmpwi r30, 0x00 bne MPCall_115_0x94 _Lock PSA.DbugLock, scratch1=r16, scratch2=r17 lwz r30, PSA._404(r1) MPCall_115_0x54 addi r30, r30, 0x01 andi. r29, r30, 0xfff bne MPCall_115_0x64 lwz r30, -0x1000(r30) MPCall_115_0x64 lbz r16, 0x0000(r30) cmpwi r16, 0x00 beq MPCall_115_0x54 stw r30, 0x000c(r31) _AssertAndRelease PSA.DbugLock, scratch=r16 MPCall_115_0x94 cmpwi r5, 0x00 ble ReleaseAndReturnMPCallOOM rlwinm. r9, r11, 0, 27, 27 mr r8, r4 crmove 30, 2 beq MPCall_115_0xd0 li r9, 0x00 bl SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17 beq ReleaseAndReturnMPCallOOM add r8, r4, r5 li r9, 0x00 addi r8, r8, -0x01 mr r30, r8 bl SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17 beq ReleaseAndReturnMPCallOOM MPCall_115_0xd0 lwz r28, PSA._404(r1) lwz r29, 0x000c(r31) li r5, 0x00 not r27, r4 MPCall_115_0xe0 cmpw r28, r29 cmplw cr1, r4, r30 beq MPCall_115_0x144 bgt cr1, MPCall_115_0x144 rlwinm r16, r4, 0, 0, 19 mr r8, r4 beq cr7, MPCall_115_0x11c cmpw r16, r27 mr r17, r26 beq MPCall_115_0x11c mr r27, r16 li r9, 0x00 bl SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17 beq ReleaseAndReturnMPCallOOM mr r26, r17 MPCall_115_0x11c rlwimi r17, r4, 0, 20, 31 lbz r8, 0x0000(r29) addi r29, r29, 0x01 andi. r16, r29, 0xfff bne+ MPCall_115_0x134 lwz r29, -0x1000(r29) MPCall_115_0x134 stb r8, 0x0000(r17) addi r5, r5, 0x01 addi r4, r4, 0x01 b MPCall_115_0xe0 MPCall_115_0x144 stw r29, 0x000c(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ; Point external interrupts (thing PIHes) towards this notification DeclareMPCall 121, MPRegisterExternalHandler MPRegisterExternalHandler _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr. r8, r3 beq @zero bl LookupID cmpwi r9, Notification.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr @zero stw r3, PSA.ExternalHandlerID(r1) b ReleaseAndReturnZeroFromMPCall DeclareMPCall 133, MPCall_133 MPCall_133 ; OUTSIDE REFERER _Lock PSA.SchLock, scratch1=r16, scratch2=r17 cmpw r3, r0 lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1) li r17, 0x0b blt MPCall_133_0x34 and r3, r3, r17 or r16, r16, r3 b MPCall_133_0x3c MPCall_133_0x34 orc r3, r3, r17 and r16, r16, r3 MPCall_133_0x3c stw r16, 0x0edc(r1) srawi r16, r4, 16 extsh r17, r4 cmpwi r16, -0x01 cmpwi cr1, r17, -0x01 beq MPCall_133_0x60 bgt MPCall_133_0x5c li r16, 0x00 MPCall_133_0x5c sth r16, PSA._360(r1) MPCall_133_0x60 beq cr1, MPCall_133_0x70 bgt cr1, MPCall_133_0x6c li r17, 0x00 MPCall_133_0x6c sth r17, PSA._35e(r1) MPCall_133_0x70 srawi r16, r5, 16 extsh r17, r5 cmpwi r16, -0x01 cmpwi cr1, r17, -0x01 beq MPCall_133_0x90 bgt MPCall_133_0x8c li r16, 0x00 MPCall_133_0x8c sth r16, PSA._35c(r1) MPCall_133_0x90 beq cr1, MPCall_133_0xa0 bgt cr1, MPCall_133_0x9c li r17, 0x00 MPCall_133_0x9c sth r17, PSA._35a(r1) MPCall_133_0xa0 ; r1 = kdp bl ScreenConsole_redraw ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_Panic b panic