Reverse PPC-68k context switching (incomplete)

This commit is contained in:
Elliot Nunn 2018-03-31 16:17:23 +08:00
parent 4c0e5221f1
commit dd4e2ef845
20 changed files with 767 additions and 599 deletions

View File

@ -30,7 +30,7 @@ DFC ds.l 1 ; 05c
ds.l 1 ; 064
ds.l 1 ; 068
ds.l 1 ; 06c
INTM_L ds.l 1 ; 070 ; interrupt level or -1
INTM_L ds.l 1 ; 070 ; interrupt level or -1 (halfword)
DISP ds.l 1 ; 074
CODE ds.l 1 ; 078
SP ds.l 1 ; 07c
@ -92,8 +92,6 @@ PriorityShifty ds.l 1 ; 0cc ; if low nybble is empty, SchInit sets this to 2
SWIEventGroupID ds.l 1 ; 0d0 ; what?
XER ds.l 1 ; 0d4
VectorSaveArea ds.l 1 ; 0d8 ; AltiVec hack: vector registers don't fit in CB!
org 0xdc
CR ds.l 1 ; 0dc ; from heartbeat code, unsure of meaning (ANDed with PostIntMaskInit) r13
PageInSystemHeap ds.l 1 ; 0e0 ; these are set by StartInit.a:FiddleWithEmulator
OtherPageInSystemHeap ds.l 1 ; 0e4

View File

@ -139,16 +139,16 @@ kFlag17 equ 17
kFlag18 equ 18
kFlag19 equ 19
kFlag20 equ 20
kFlagPMF equ 21 ; set by MPMarkPMFTask, means perf monitor
kFlag22 equ 22
kFlagPerfMon equ 21 ; set by MPMarkPMFTask, means perf monitor
kFlagStopped equ 22
kFlag23 equ 23
kFlag24 equ 24
kFlag25 equ 25 ; set for idle1, idle2
kFlag26 equ 26 ; set for blue
kFlag68kInterrupt equ 27 ; set on SWI (meaning 68k, or 68k interrupt?)
kFlag26 equ 26 ; set for blue, cleared when preempted, set when run
kFlagSchToInterruptEmu equ 27 ; set when scheduler should trigger a 68k interrupt in this task
kFlag28 equ 28 ; set for blue
kFlag29 equ 29
kFlag30 equ 30
kFlagAborted equ 30
kFlag31 equ 31
ds.l 1 ; 068
@ -164,16 +164,16 @@ VectorSaveArea ds.l 1 ; 08c
ds.l 1 ; 094
ds.l 1 ; 098
NotificationPtr ds.l 1 ; 09c
Semaphore ds.b 32 ; 0a0:0c0 ; Zero and One were fields
PageFaultSema ds.b 32 ; 0a0:0c0 ; task blocks on this fake sema, only to run when high-priority blue is done
Zero1 ds.l 1 ; 0c0
Zero2 ds.l 1 ; 0c4
CreateTime1 ds.d 1 ; 0c8
CreateTime2 ds.d 1 ; 0d0
ds.l 1 ; 0d8
ds.l 1 ; 0dc
Zero3 ds.l 1 ; 0e0
Zero4 ds.l 1 ; 0e4
Zero5 ds.l 1 ; 0e8
CodeFaultCtr ds.l 1 ; 0e0 ; these two only climb when VM is on
DataFaultCtr ds.l 1 ; 0e4
PreemptCtr ds.l 1 ; 0e8
SomeLabelField ds.l 1 ; 0ec
YellowVecTblPtr ds.l 1 ; 0f0
ExceptionHandlerID ds.l 1 ; 0f4 ; a queue

View File

@ -131,13 +131,7 @@ NominalReadyQ ds.l 8 ; -9b0:-990 ; unblocked tasks with priority 2
IdleReadyQ ds.l 8 ; -990:-970 ; unblocked tasks with priority 3
PriorityFlags ds.l 1 ; -970 ; bit 0 is 0, bit 1 is 1, etc...
ScrambledMPCallTime ds.l 1 ; -96c ; by MP call return
GlobalCPUFlags ds.l 1 ; -968 ; Init.s saves MQ (should be possible) here
MQFeatureBit equ 13 ; equals 0x00040000
AVFeatureBit equ 12 ; equals 0x00080000
; 8 0x00800000
; 10 0x00200000
;int vector checks 9 0x00400000
FlagsTemplate ds.l 1 ; -968 ; typically just EWA.kFlagVec
UserModeMSR ds.l 1 ; -964
ThudBuffer ds.b 96 ; -960:-900 ; that's the kernel debugger
NoIdeaR23 ds.l 1 ; -900 ; r23 copies here... replated to RTAS?
@ -160,7 +154,7 @@ DiagInfo ds.b 256 ; -5d0:-4d0
ProcessorState ds.b 128 ; -4d0:-450 ; interesting what this gets used by
FreeList ds.l 4 ; -450:-440
MCR ds.l 1 ; -440 ; reported by heartbeat code
Int ds.w 1 ; -43c ; set by CommonPIHPath: a one-byte 68k int ID or -1
Pending68kInt ds.w 1 ; -43c ; used when Sch interrupts blue task (-1 means "none")
ds.w 1 ; -43a
DecClockRateHzCopy ds.l 1 ; -438 ; copied by Init.s
OtherTimerQueuePtr ds.l 1 ; -434 ; unsigned timer queue in the pool, set by InitTMRQs
@ -311,7 +305,7 @@ SpacesSavedAreaBase ds.l 1 ; -270, cpu+0d0
SpacesDeferredAreaPtr ds.l 1 ; -26c, cpu+0d4
ds.l 1 ; -268, cpu+0d8
ds.l 1 ; -264, cpu+0dc
ds.l 1 ; -260, cpu+0e0
SchSavedIncomingTask ds.l 1 ; -260, cpu+0e0
ds.l 1 ; -25c, cpu+0e4
TimerDispatchLR ds.l 1 ; -258, cpu+0e8
ds.l 1 ; -254, cpu+0ec
@ -408,7 +402,7 @@ WeMightClear ds.l 1 ; -114, cpu+22c ; still boots if not cleared
ds.l 1 ; -0f0, cpu+250
ds.l 1 ; -0ec, cpu+254
ds.l 1 ; -0e8, cpu+258
SpecialAreaPtr ds.l 1 ; -0e4, cpu+25c
SpecialAreaPtr ds.l 1 ; -0e4, cpu+25c ; will panic on page fault if this is not valid
ds.l 1 ; -0e0, cpu+260
ds.l 1 ; -0dc, cpu+264
ds.l 1 ; -0d8, cpu+268
@ -512,26 +506,32 @@ kFlag4 equ 4
kFlag5 equ 5
kFlag6 equ 6
kFlag7 equ 7
kFlag8 equ 8
kFlag9 equ 9
kFlagBlue equ 10 ; could mean "currently in interrupt mode"
kFlag11 equ 11
kFlag12 equ 12
kFlag13 equ 13
kFlag14 equ 14
kFlag15 equ 15
kFlag16 equ 16
; PER-TASK FLAGS
kFlagEmu equ 8 ; emulator is running
kFlag9 equ 9 ; * = preserved on alt>sys switch
kFlagBlue equ 10 ; *
kFlag11 equ 11 ; *
kFlagVec equ 12 ; *
kFlagHasMQ equ 13 ; *
kFlag14 equ 14 ; *
kFlag15 equ 15 ; *
kFlagSIGP equ 16 ; *
; PER-CONTEXT FLAGS
kFlag17 equ 17
kFlag18 equ 18
kFlag19 equ 19
kFlag20 equ 20
kFlag21 equ 21
kFlag22 equ 22
kFlag23 equ 23
kFlagFE0 equ 20 ; these correspond with MSR bits
kFlagSE equ 21
kFlagBE equ 22
kFlagFE1 equ 23
kFlag24 equ 24
kFlag25 equ 25
kFlag26 equ 26
kFlag27 equ 27
kFlag26 equ 26 ; can be copied from kFlagSE
kFlagLowSaves equ 27
kFlag28 equ 28
kFlag29 equ 29
kFlag30 equ 30
@ -562,14 +562,17 @@ BATs ds.l 32 ; 280:300
; GAP
org 0x340
MinusOne1 ds.l 1 ; 340 ; several longs set at once
ds.l 1 ; 344
MinusOne2 ds.l 1 ; 348
ds.l 1 ; 34c
MinusOne3 ds.l 1 ; 350
ds.l 1 ; 354
MinusOne4 ds.l 1 ; 358
ds.l 1 ; 35c
NCBPointerCache
NCBCacheLA0 ds.l 1 ; 340
NCBCachePA0 ds.l 1 ; 344
NCBCacheLA1 ds.l 1 ; 348
NCBCachePA1 ds.l 1 ; 34c
NCBCacheLA2 ds.l 1 ; 350
NCBCachePA2 ds.l 1 ; 354
NCBCacheLA3 ds.l 1 ; 358
NCBCachePA3 ds.l 1 ; 35c
NCBPointerCacheEnd
YellowVecBase ds.l 48 ; 360:420 ; used to ignore illegal AltiVec insns by Init.s
OrangeVecBase ds.l 48 ; 420:4e0
RedVecBase ds.l 48 ; 4e0:5a0
@ -578,7 +581,7 @@ OtherFreeThing ds.l 1 ; 5a4
TopOfFreePages ds.l 1 ; 5a8 ; gotten from the old SPRG0
ds.l 1 ; 5ac
PA_InterruptHandler ds.l 1 ; 5b0
ds.l 1 ; 5b4
LA_NCB ds.l 1 ; 5b4 ; most recent physical address found
HiLevelPerfMonitorBits ds.l 1 ; 5b8
ds.l 1 ; 5bc
PerfMonitorBits ds.l 1 ; 5c0

View File

@ -3964,11 +3964,9 @@ MPCall_95_0x334
MPCall_95_0x348 ; OUTSIDE REFERER
lwz r14, 0x0000(r30)
li r16, -0x01
stw r16, 0x0340(r1)
stw r16, 0x0348(r1)
stw r16, 0x0350(r1)
stw r16, 0x0358(r1)
_InvalNCBPointerCache scratch=r16
lwz r16, 0x0e98(r1)
rlwinm r14, r14, 0, 21, 19
addi r16, r16, 0x01

View File

@ -209,14 +209,14 @@ FinishInitBuiltin
; Test MQ and save feature field
lis r8, 1 << (15 - PSA.MQFeatureBit)
lis r8, 1 << (15 - EWA.kFlagHasMQ)
mtspr mq, r8
li r8, 0
mfspr r8, mq
stw r8, PSA.GlobalCPUFlags(r1)
stw r8, PSA.FlagsTemplate(r1)
; Add AV and save that in scratch field
oris r9, r8, 1 << (15 - PSA.AVFeatureBit)
_bset r9, r8, EWA.kFlagVec
stw r9, EWA.r0(r1)
; Load from scratch field into a vector register
@ -230,11 +230,11 @@ FinishInitBuiltin
stvewx v0, 0, r9
; Scratch field now contains AltiVec and MQ flags.
; Copy it to GlobalCPUFlags
; Copy it to FlagsTemplate
lwz r8, EWA.r0(r1)
stw r8, PSA.GlobalCPUFlags(r1)
stw r8, PSA.FlagsTemplate(r1)
; current flags = tested flags | CPU flag 8 | CPU flag 9
; initial blue flags = global template + EWA.kFlagEmu + EWA.kFlag9
oris r7, r8, 0xa0
stw r7, EWA.Flags(r1)
@ -298,9 +298,8 @@ ResetBuiltinKernel
; r3 = 0
; r4 = 0
; r5 = SystemInfo
; r6 = PA_ECB
; r7 = AllCpuFeatures
; r8 = GlobalCPUFlags
; r6 = ECB
; r7 = Flags
; r9 = even more altivec crud
; r10 = LA_EmulatorKernelTrapTable
; r11 = MSR
@ -685,13 +684,9 @@ SetProcessorFlags
@done
; These look like two-word structures. Not yet sure what they are.
; Init the NCB Pointer Cache
li r23, -1
stw r23, KDP.MinusOne1(r1) ; kdp.0x340
stw r23, KDP.MinusOne2(r1) ; kdp.0x348
stw r23, KDP.MinusOne3(r1) ; kdp.0x350
stw r23, KDP.MinusOne4(r1) ; kdp.0x358
_InvalNCBPointerCache scratch=r23
@ -1108,7 +1103,7 @@ SetProcessorFlags
; Create the Blue MacOS task
; ARG GlobalCPUFlags r7, Process *r8
; ARG Flags r7, Process *r8
; RET Task *r8
lwz r8, PSA.blueProcessPtr(r1)
@ -1124,7 +1119,7 @@ SetProcessorFlags
; Can equal -1 or a 68k interrupt number. PIHes touch it.
li r8, -1
sth r8, PSA.Int(r1)
sth r8, PSA.Pending68kInt(r1)
;
stw r31, PSA.PA_BlueTask(r1)
@ -1206,20 +1201,20 @@ SetProcessorFlags
; Create the idle task for the first CPU
; Unset the AV bit in GlobalCPUFlags so that
; Unset EWA.kFlagVec so that
; idle task vector registers are not saved/restored
; (Leave the old value in r31)
av set PSA.AVFeatureBit
mr r31, r7
rlwinm r7, r7, 0, av + 1, av - 1
; ARG GlobalCPUFlags r7, Process *r8
mr r31, r7
_bclr r7, r7, EWA.kFlagVec
; ARG Flags r7, Process *r8
; RET Task *r8
lwz r8, PSA.blueProcessPtr(r1)
bl CreateTask
; Restore GlobalCPUFlags
; Restore Flags
mr r7, r31
; Check
@ -1879,7 +1874,7 @@ finish_old_world
bl ProbePerfMonitor
lwz r27, 0x0630(r1)
lwz r27, 0x0094(r27)
bl PagingFunc4
bl PagingL2PWithoutBATs
beq setup_0x1160
li r30, 0x00
stw r30, -0x0004(r29)
@ -1891,7 +1886,7 @@ setup_0x1160
bl PagingFunc1
lwz r27, 0x0630(r1)
lwz r27, 0x009c(r27)
bl PagingFunc4
bl PagingL2PWithoutBATs
beq setup_0x1188
li r30, 0x00
stw r30, -0x0004(r29)
@ -1908,7 +1903,7 @@ setup_0x1188
subf r19, r19, r27
setup_0x11a0
bl PagingFunc4
bl PagingL2PWithoutBATs
beq setup_0x11bc
li r30, 0x00
stw r30, -0x0004(r29)
@ -1923,7 +1918,7 @@ setup_0x11bc
bgt setup_0x11a0
lwz r27, 0x0630(r1)
lwz r27, 0x00a4(r27)
bl PagingFunc4
bl PagingL2PWithoutBATs
beq setup_0x11f0
li r30, 0x00
stw r30, -0x0004(r29)
@ -1936,7 +1931,7 @@ setup_0x11f0
_log 'Nanokernel replaced. Returning to boot process^n'
addi r9, r1, 0x420
addi r9, r1, KDP.OrangeVecBase
mtsprg 3, r9
; r1 = kdp

File diff suppressed because it is too large Load Diff

View File

@ -420,7 +420,7 @@ MPRegisterCpuPlugin
; r18 = physical address of plugin (assumes page-aligned)
mr r27, r4
addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3
bl PagingL2PWithBATs
beq ReleaseAndReturnMPCallOOM
rlwinm r18, r31, 0, 0, 19
@ -428,7 +428,7 @@ MPRegisterCpuPlugin
mr r27, r16
mr r19, r16
addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3
bl PagingL2PWithBATs
beq ReleaseAndReturnMPCallOOM
rlwimi r19, r31, 0, 0, 19
@ -448,7 +448,7 @@ MPRegisterCpuPlugin
; Get physical ptr to table of stack pointers (one per CPU)
lwz r27, 0(r19)
addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3
bl PagingL2PWithBATs
beq ReleaseAndReturnMPCallOOM
rlwimi r27, r31, 0, 0, 19
stw r27, CoherenceGroup.PA_CpuPluginStackPtrs(r14)
@ -474,7 +474,7 @@ MPRegisterCpuPlugin
@table_convert_loop
lwzu r27, 4(r16)
addi r29, r1, KDP.BATs + 0xa0
bl PagingFunc3
bl PagingL2PWithBATs
beq ReleaseAndReturnMPCallOOM
subi r17, r17, 1
rlwimi r27, r31, 0, 0, 19
@ -1285,7 +1285,7 @@ KCStartCPU ; OUTSIDE REFERER
rlwinm r7, r7, 0, 13, 11
lwz r8, PSA.blueProcessPtr(r1)
; ARG GlobalCPUFlags r7, Process *r8
; ARG Flags r7, Process *r8
bl CreateTask
; RET Task *r8
@ -1456,7 +1456,7 @@ MPCpuPlugin
DeclareMPCall 47, MPCall_47
MPCall_47 ; OUTSIDE REFERER
rlwinm. r8, r7, 0, 12, 12
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec
lwz r15, 0x00d8(r6)
beq ReturnMPCallOOM
cmpwi r15, 0x00
@ -1635,7 +1635,7 @@ KCMarkPMFTask ; OUTSIDE REFERER
; Insert bit 31 of r4 into bit 21 of these flags
lwz r17, Task.Flags(r31)
rlwimi r17, r4, 10, Task.kFlagPMF, Task.kFlagPMF
rlwimi r17, r4, 10, Task.kFlagPerfMon, Task.kFlagPerfMon
stw r17, Task.Flags(r31)

View File

@ -287,3 +287,18 @@ _bclr_lbit set 31
ENDIF
ENDM
MACRO
_InvalNCBPointerCache &scratch==r0, &offset==0
IF &offset = 0
li &scratch, -1
ENDIF
IF KDP.NCBPointerCache + &offset < KDP.NCBPointerCacheEnd
stw &scratch, KDP.NCBPointerCache + &offset(r1)
_InvalNCBPointerCache scratch=&scratch, offset=(&offset+8)
ENDIF
ENDM

View File

@ -356,11 +356,9 @@ PagingFunc1 ; OUTSIDE REFERER
@_4b0
sync
isync
li r8, -0x01
stw r8, 0x0340(r1)
stw r8, 0x0348(r1)
stw r8, 0x0350(r1)
stw r8, 0x0358(r1)
_InvalNCBPointerCache scratch=r8
mfsprg r8, 0
mr r9, r28
lwz r8, -0x001c(r8)
@ -598,7 +596,7 @@ PagingFunc2AndAHalf
PagingFunc3 ; OUTSIDE REFERER
PagingL2PWithBATs ; OUTSIDE REFERER
lwz r30, 0x0000(r29)
li r28, -0x01
rlwimi r28, r30, 15, 0, 14
@ -619,7 +617,7 @@ PagingFunc3 ; OUTSIDE REFERER
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
bne PagingFunc4
bne PagingL2PWithoutBATs
@_54
andi. r31, r30, 0x01
@ -631,7 +629,7 @@ PagingFunc3 ; OUTSIDE REFERER
PagingFunc4 ; OUTSIDE REFERER
PagingL2PWithoutBATs ; OUTSIDE REFERER
mfsrin r31, r27
rlwinm r30, r27, 10, 26, 31
rlwimi r30, r31, 7, 1, 24

View File

@ -141,13 +141,13 @@ CommonPIHPath_0xc ; OUTSIDE REFERER
or r31, r31, r30
stw r31, PSA.MCR(r1)
sth r28, PSA.Int(r1)
sth r28, PSA.Pending68kInt(r1)
lwz r31, PSA.PA_BlueTask(r1)
mfsprg r30, 0
lwz r28, Task.Flags(r31)
lbz r29, Task.State(r31)
_bset r28, r28, Task.kFlag68kInterrupt
_bset r28, r28, Task.kFlagSchToInterruptEmu
stw r28, Task.Flags(r31)
cmpwi r29, 0

View File

@ -25,7 +25,7 @@ rtas_is_available
_Lock PSA.RTASLock, scratch1=r8, scratch2=r9
mtcrf 0x3f, r7
mtcrf 0x3f, r7
lwz r9, KDP.PA_ECB(r1)
lwz r8, EWA.Enables(r1)
stw r7, 0x0000(r6)
@ -80,11 +80,11 @@ kcRTASDispatch_0x8c
stw r29, 0x01ec(r6)
stw r30, 0x01f4(r6)
stw r31, 0x01fc(r6)
bnel major_0x03e18_0xb4
bnel bugger_around_with_floats
stw r11, 0x00a4(r6)
mr r27, r3
addi r29, r1, 800
bl PagingFunc3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beql Local_Panic
rlwimi r3, r31, 0, 0, 19
lhz r8, 0x0004(r3)
@ -92,8 +92,8 @@ kcRTASDispatch_0x8c
beq kcRTASDispatch_0x14c
slwi r8, r8, 2
lwzx r27, r8, r3
addi r29, r1, 800
bl PagingFunc3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beql Local_Panic
lwzx r9, r8, r3
rlwimi r9, r31, 0, 0, 19
@ -142,7 +142,7 @@ kcRTASDispatch_0x190
lwz r8, 0x00f4(r6)
lwz r10, 0x00fc(r6)
mtctr r8
bnel major_0x03e18_0x8
bnel IntHandleSpecialFPException
lwz r8, 0x010c(r6)
stw r8, 0x0004(r1)
lwz r2, 0x0114(r6)

View File

@ -185,15 +185,15 @@ InitReplacement
lwz r12, 0x0340(r11)
lwz r10, 0x05b4(r11)
lwz r10, KDP.LA_NCB(r11)
cmpw r12, r10
beq replace_old_kernel_0x198
stw r12, 0x05b4(r1)
stw r12, KDP.LA_NCB(r1)
stw r0, 0x06b4(r1)
lwz r10, 0x05b0(r11)
stw r10, 0x06c0(r1)
lwz r10, 0x05b4(r11)
lwz r10, KDP.LA_NCB(r11)
stw r10, 0x06c4(r1)
lwz r10, 0x05b8(r11)
stw r10, 0x06c8(r1)

View File

@ -850,7 +850,7 @@ SchSwitchSpace
bne Local_Panic
; Intend to skip the dssall instruction if Altivec is... present? absent?
rlwinm. r16, r7, 0, 12, 12 ; seems to be leftover from Init.s Altivec testing
rlwinm. r16, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; seems to be leftover from Init.s Altivec testing
; Apply the address space to the segment registers
isync
@ -1144,6 +1144,8 @@ SchReturn
; Either fallen through from SchReturn, or jumped to by
; TrulyCommonMPCallReturnPath when it wants to block the caller
; SchLock should be acquired before now!
SchEval
mfsprg r14, 0
@ -1240,6 +1242,7 @@ major_0x142dc_0xd8 ; OUTSIDE REFERER
major_0x142dc_0x140
lwz r25, 0x0064(r30)
li r26, 0x00
rlwinm. r8, r25, 0, 21, 22
andc r27, r25, r8
beq+ major_0x142dc_0x184
@ -1251,12 +1254,16 @@ major_0x142dc_0x140
stw r25, 0x0000(r26)
InsertAsPrev r26, r25, scratch=r27
b major_0x142dc_0x58
major_0x142dc_0x184
cmpw cr3, r30, r31
rlwinm. r8, r25, 0, 27, 27
bne cr3, major_0x14548
bne major_0x14548
bne cr3, _SchPreempt
bne _SchPreempt
; Don't preempt, keep running the same task
bl GetTime
bl major_0x148ec
lwz r27, 0x0064(r31)
@ -1280,34 +1287,9 @@ major_0x142dc_0x1bc
######## ######## ####
## ## ## ##
## ## ## ##
######## ###### ##
## ## ## ##
## ## ## ##
## ## ## ####
; SchLock should be released before here
; SchExitInterrupt
; All MPCalls get here?
; r0,7,8,9,10,11,12,13 restored from r6 area
; r1,6 restored from sprg0 area
; Apple used the "reserved" (not first three) bits of XER.
; If bit 27 of 0xedc(r1) is set:
; Bit 22 of XER is cleared
; Bit 10 of r7 is inserted into XER at bit 23
; > sprg0 = for r1 and r6
; > r1 = kdp
; > r6 = register restore area
; > r7 = flag to insert into XER
; > r10 = new srr0 (return location)
; > r11 = new srr1
; > r12 = lr restore
; > r13 = cr restore
SchExitInterrupt ; OUTSIDE REFERER
SchExitInterrupt
lwz r8, 0x0edc(r1)
mfsprg r1, 0
mtlr r12
@ -1338,157 +1320,231 @@ SchExitInterrupt_0x2c
major_0x14548 ; OUTSIDE REFERER
lwz r16, 0x0064(r31)
stw r30, -0x0260(r14)
rlwinm r16, r16, 0, 27, 25
stw r6, 0x0088(r31)
mfsprg r8, 3
stw r16, 0x0064(r31)
stw r8, 0x00f0(r31)
lwz r8, -0x000c(r14)
stw r7, 0x0000(r6)
stw r8, 0x0004(r6)
mfxer r8
stw r13, 0x00dc(r6)
stw r8, 0x00d4(r6)
stw r12, 0x00ec(r6)
mfctr r8
stw r10, 0x00fc(r6)
stw r8, 0x00f4(r6)
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
bne major_0x14548_0x58
mfspr r8, mq
stw r8, 0x00c4(r6)
; ARG outgoing_cb *r6, EWA *r14, incoming_task *r30, task_to_save_to *r31
major_0x14548_0x58
lwz r8, 0x0004(r14)
stw r8, 0x010c(r6)
stw r2, 0x0114(r6)
stw r3, 0x011c(r6)
andi. r8, r11, 0x2000
stw r4, 0x0124(r6)
lwz r8, 0x0018(r14)
stw r5, 0x012c(r6)
stw r8, 0x0134(r6)
_SchPreempt
; Save info for the previous task
lwz r16, Task.Flags(r31)
stw r30, EWA.SchSavedIncomingTask(r14) ; will clobber r30
_bclr r16, r16, Task.kFlag26
stw r6, Task.ContextBlockPtr(r31)
mfsprg r8, 3
stw r16, Task.Flags(r31)
stw r8, Task.YellowVecTblPtr(r31)
; Spam its context block
lwz r8, EWA.Enables(r14)
stw r7, ContextBlock.Flags(r6)
stw r8, ContextBlock.Enables(r6)
mfxer r8
stw r13, ContextBlock.CR(r6)
stw r8, ContextBlock.XER(r6)
stw r12, ContextBlock.LR(r6)
mfctr r8
stw r10, ContextBlock.CodePtr(r6)
stw r8, ContextBlock.KernelCTR(r6)
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
bne @not_601
mfspr r8, mq
stw r8, ContextBlock.MQ(r6)
@not_601
lwz r8, EWA.r1(r14)
stw r8, ContextBlock.r1(r6)
stw r2, ContextBlock.r2(r6)
stw r3, ContextBlock.r3(r6)
andi. r8, r11, MSR_FP
stw r4, ContextBlock.r4(r6)
lwz r8, EWA.r6(r14)
stw r5, ContextBlock.r5(r6)
stw r8, ContextBlock.r6(r6)
bnel Save_f0_f31
lwz r31, -0x0008(r14)
lwz r30, -0x0260(r14)
rlwinm. r8, r7, 0, 12, 12
lwz r31, EWA.PA_CurTask(r14) ; sly aside: r30 = new, r31 = current
lwz r30, EWA.SchSavedIncomingTask(r14)
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec
bnel Save_v0_v31
stw r11, 0x00a4(r6)
lwz r8, 0x00e8(r31)
addi r8, r8, 0x01
stw r8, 0x00e8(r31)
stw r11, ContextBlock.MSR(r6)
; Bump current task's preemption ctr
lwz r8, Task.PreemptCtr(r31)
addi r8, r8, 1
stw r8, Task.PreemptCtr(r31)
; No clue
bl GetTime
bl major_0x148ec
; Update EWA global to match this task, and set task's state to 2
mfsprg r14, 0
li r27, 0x02
lbz r28, 0x0019(r30)
stb r27, 0x0018(r30)
stb r28, -0x0117(r14)
li r27, 2
lbz r28, Task.Priority(r30)
stb r27, Task.State(r30)
stb r28, EWA.TaskPriority(r14)
; If incoming task is not already running, and running task is not in a queue, re-ready the running task
cmplw r30, r31
lwz r16, 0x0010(r31)
beq major_0x14548_0xd4
cmpwi r16, 0x00
lwz r16, Task.QueueMember + LLL.Next(r31)
beq @no
cmpwi r16, 0
mr r8, r31
beql SchRdyTaskNow
major_0x14548_0xd4
@no
; Play more with the incoming task
mfsprg r19, 0
li r8, 0x00
li r8, 0
stb r8, EWA.SchEvalFlag(r19)
lhz r8, EWA.CPUIndex(r19)
lwz r6, 0x0088(r30)
lwz r28, -0x0340(r19)
sth r8, 0x001a(r30)
stw r28, 0x0078(r30)
stw r30, -0x0008(r19)
stw r6, -0x0014(r19)
lwz r7, 0x0000(r6)
lwz r28, 0x0004(r6)
stw r7, -0x0010(r19)
stw r28, -0x000c(r19)
lwz r27, 0x0064(r30)
lwz r13, 0x00dc(r6)
ori r27, r27, 0x20
lwz r6, Task.ContextBlockPtr(r30)
lwz r28, EWA.CPUBase + CPU.ID(r19)
sth r8, Task.CPUIndex(r30)
stw r28, Task.CpuID(r30)
stw r30, EWA.PA_CurTask(r19)
stw r6, EWA.PA_ContextBlock(r19)
lwz r7, ContextBlock.Flags(r6)
lwz r28, ContextBlock.Enables(r6)
stw r7, EWA.Flags(r19)
stw r28, EWA.Enables(r19)
lwz r27, Task.Flags(r30)
lwz r13, ContextBlock.CR(r6)
ori r27, r27, 1 << (31 - Task.kFlag26)
lwz r11, 0x00a4(r6)
lwz r8, 0x00f0(r30)
rlwimi r11, r27, 24, 29, 29
rlwinm r27, r27, 0, 9, 7
mtsprg 3, r8
stw r27, 0x0064(r30)
lwz r18, 0x0070(r30)
lwz r9, -0x001c(r19)
stw r27, Task.Flags(r30)
; Switch address space if necessary
lwz r18, Task.AddressSpacePtr(r30)
lwz r9, EWA.PA_CurAddressSpace(r19)
cmpw r18, r9
beq major_0x14548_0x148
beq @same_space
mr r8, r18
bl SchSwitchSpace
@same_space
major_0x14548_0x148
mfsprg r19, 0
; Is this the blue task? If so, do we need to interrupt it?
mtcr r7
lis r28, 0x00
ori r28, r28, 0x10
bne cr2, major_0x14548_0x20c
lisori r28, 1 << (31 - Task.kFlagSchToInterruptEmu)
bc BO_IF_NOT, EWA.kFlagBlue, @NO_BLUE_INTERRUPT
and. r28, r28, r27
li r8, 0x00
beq major_0x14548_0x20c
li r8, 0
beq @NO_BLUE_INTERRUPT
; TRIGGER AN INTERRUPT IN THE BLUE TASK
andc r27, r27, r28
lwz r29, PSA.MCR(r1)
stw r27, 0x0064(r30)
stw r27, Task.Flags(r30) ; unset the task flag that got us here
stw r8, PSA.MCR(r1)
blt cr2, major_0x14548_0x1cc
bsol cr6, Local_Panic
clrlwi r8, r7, 0x08
stw r8, 0x0000(r6)
bc BO_IF, EWA.kFlagEmu, @already_in_system_context
bcl BO_IF, 27, Local_Panic
; Need to switch blue task from alternate context to system context
clrlwi r8, r7, 8
stw r8, ContextBlock.Flags(r6)
lwz r6, KDP.PA_ECB(r1)
addi r26, r1, 0x360
addi r26, r1, KDP.YellowVecBase
mtsprg 3, r26
stw r26, 0x00f0(r30)
stw r6, -0x0014(r19)
stw r6, 0x0088(r30)
lwz r7, 0x0000(r6)
lwz r26, 0x0004(r6)
stw r26, Task.YellowVecTblPtr(r30)
stw r6, EWA.PA_ContextBlock(r19)
stw r6, Task.ContextBlockPtr(r30)
lwz r7, ContextBlock.Flags(r6)
lwz r26, ContextBlock.Enables(r6)
mtcr r7
stw r26, -0x000c(r19)
lwz r13, 0x00dc(r6)
lwz r11, 0x00a4(r6)
bsol cr6, Local_Panic
rlwimi r11, r7, 0, 20, 23
rlwimi r7, r8, 0, 9, 16
rlwimi r11, r27, 24, 29, 29
stw r7, -0x0010(r19)
stw r26, EWA.Enables(r19)
lwz r13, ContextBlock.CR(r6)
lwz r11, ContextBlock.MSR(r6)
bcl BO_IF, 27, Local_Panic
rlwimi r11, r7, 0, 20, 23 ; apply MSR[FE0/SE/BE/FE1]
rlwimi r7, r8, 0, 9, 16 ; keep flags 9-16 from alternate context
rlwimi r11, r27, 24, 29, 29 ; MSR[PMM] = Task.kFlagPerfMon
stw r7, EWA.Flags(r19)
@already_in_system_context
; Blue task now (or was already) in system context (i.e. 68k emulator is running)
major_0x14548_0x1cc
lwz r17, ContextBlock.PriorityShifty(r6)
ori r17, r17, 0x100
ori r17, r17, 0x100
stw r17, ContextBlock.PriorityShifty(r6)
lhz r17, -0x043c(r1)
lwz r18, 0x067c(r1)
cmplwi r17, 0xffff
lwz r26, KDP.PostIntMaskInit(r1)
beq major_0x14548_0x1f8
sth r17, 0x0000(r18)
li r17, -0x01
sth r17, -0x043c(r1)
major_0x14548_0x1f8
cmpwi r29, 0x00
; EDP.INTM_L = PSA.Pending68kInt (presumably the emulator polls this)
lhz r17, PSA.Pending68kInt(r1)
lwz r18, KDP.PA_EmulatorIplValue(r1)
cmplwi r17, 0xffff ; i.e. (short)(-1)
lwz r26, KDP.PostIntMaskInit(r1)
beq @no_change_to_int_level ; would this ever happen?
sth r17, 0(r18)
li r17, -1
sth r17, PSA.Pending68kInt(r1)
@no_change_to_int_level
; Fiddle with the emulator's Condition Register ("int mask")
cmpwi r29, 0
or r13, r13, r29
bne major_0x14548_0x20c
bne @did_set_bits_in_mask
lwz r29, KDP.ClearIntMaskInit(r1)
and r13, r13, r29
@did_set_bits_in_mask
@NO_BLUE_INTERRUPT
; Back to the common path for preemption (pretty boring)
major_0x14548_0x20c
lwz r29, 0x00d8(r6)
cmpwi r29, 0x00
lwz r8, 0x0210(r29)
beq major_0x14548_0x220
beq _SchPreempt_0x220
mtspr vrsave, r8
_SchPreempt_0x220
major_0x14548_0x220
lwz r8, 0x00d4(r6)
lwz r12, 0x00ec(r6)
mtxer r8
@ -1497,11 +1553,11 @@ major_0x14548_0x220
mtctr r8
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
bne major_0x14548_0x24c
bne _SchPreempt_0x24c
lwz r8, 0x00c4(r6)
mtspr mq, r8
major_0x14548_0x24c
_SchPreempt_0x24c
li r9, 0x124
lwz r8, 0x010c(r6)
dcbt r9, r6
@ -1539,7 +1595,8 @@ major_0x14548_0x24c
lwz r29, 0x01ec(r6)
lwz r30, 0x01f4(r6)
lwz r31, 0x01fc(r6)
beq major_0x14548_0x380
beq _SchPreempt_0x380
mfmsr r8
ori r8, r8, 0x2000
ori r11, r11, 0x2000
@ -1579,18 +1636,10 @@ major_0x14548_0x24c
lfd f29, 0x02e8(r6)
lfd f30, 0x02f0(r6)
lfd f31, 0x02f8(r6)
_SchPreempt_0x380
major_0x14548_0x380
_AssertAndRelease PSA.SchLock, scratch=r8
; sprg0 = for r1 and r6
; r1 = kdp
; r6 = register restore area
; r7 = flag to insert into XER
; r10 = new srr0 (return location)
; r11 = new srr1
; r12 = lr restore
; r13 = cr restore
b SchExitInterrupt

View File

@ -196,7 +196,7 @@ major_0x18c08 ; OUTSIDE REFERER
mfsrin r31, r27
cmpwi r31, 0x00
beqlr
b PagingFunc4
b PagingL2PWithoutBATs

View File

@ -88,8 +88,8 @@ MPGetKernelState
stw r5, ContextBlock.r5(r6)
stw r8, ContextBlock.r6(r6)
bnel Save_f0_f31
rlwinm. r8, r7, 0, 12, 12 ; flags
bnel Save_v0_v31
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; flags
bnel+ Save_v0_v31
lwz r3, ContextBlock.r3(r6)
lwz r4, ContextBlock.r4(r6)
@ -97,8 +97,8 @@ MPGetKernelState
stw r11,ContextBlock.MSR(r6)
mr r27, r5
addi r29, r1, 800
bl PagingFunc3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beq Local_ReturnInsufficientResourcesErrFromMPCall
rlwimi r27, r31, 0, 0, 19
mr r17, r27
@ -107,8 +107,8 @@ MPGetKernelState
MPGetKernelState_0xc8
mr r27, r5
addi r29, r1, 800
bl PagingFunc3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beq Local_ReturnInsufficientResourcesErrFromMPCall
rlwimi r27, r31, 0, 0, 19
stwu r27, 0x0004(r15)

View File

@ -1608,7 +1608,7 @@ SetEvent
lwz r16, Task.Flags(r26)
lbz r19, Task.State(r26)
ori r16, r16, (1 << (31 - Task.kFlag68kInterrupt))
ori r16, r16, (1 << (31 - Task.kFlagSchToInterruptEmu))
stw r16, Task.Flags(r26)
; But what *is* MCR?
@ -2595,23 +2595,23 @@ UnblockBlueIfCouldBePolling
cmpwi r17, 0
addi r16, r19, Task.QueueMember
bne major_0x0dce8_0x70
bne @blue_already_running
RemoveFromList r16, scratch1=r17, scratch2=r18
lbz r17, Task.Timer + Timer.Byte3(r19)
cmpwi r17, 1
bne major_0x0dce8_0x60
bne @no_timer_to_dequeue
addi r8, r19, Task.Timer
bl DequeueTimer
lwz r19, PSA.PA_BlueTask(r1)
major_0x0dce8_0x60
@no_timer_to_dequeue
li r16, 0x01
stb r16, 0x0019(r19)
li r16, Task.kLatencyProtectPriority
stb r16, Task.Priority(r19)
lwz r8, PSA.PA_BlueTask(r1)
bl SchRdyTaskNow
major_0x0dce8_0x70
@blue_already_running
lwz r8, PSA.PA_BlueTask(r1)
mtlr r24

View File

@ -82,7 +82,7 @@ MPCall_7 ; OUTSIDE REFERER
; ARG GlobalCPUFlags r7, Process *r8
; ARG Flags r7, Process *r8
; RET Task *r8
CreateTask
@ -132,7 +132,7 @@ CreateTask
; Create a semaphore struct inside the task
addi r16, r28, Task.Semaphore
addi r16, r28, Task.PageFaultSema
_lstart r17, Semaphore.kSignature
stw r16, Semaphore.BlockedTasks + LLL.Next(r16)
_lfinish
@ -140,23 +140,23 @@ CreateTask
stw r17, Semaphore.BlockedTasks + LLL.Signature(r16)
li r16, 1
stw r16, Task.Semaphore + Semaphore.MaxValue(r28)
stw r16, Task.PageFaultSema + Semaphore.MaxValue(r28)
li r16, 0
stw r16, Task.Semaphore + Semaphore.Value(r28)
stw r16, Task.PageFaultSema + Semaphore.Value(r28)
addi r8, r28, Task.Semaphore
addi r8, r28, Task.PageFaultSema
li r9, Semaphore.kIDClass
bl MakeID
cmpwi r8, 0
beq @fail_semq_no_id
stw r8, Task.Semaphore + Semaphore.BlockedTasks + LLL.Freeform(r28)
stw r8, Task.PageFaultSema + Semaphore.BlockedTasks + LLL.Freeform(r28)
; Allocate a vector (i.e. AltiVec) save area
; Conditionally, that is
rlwinm. r8, r7, 0, PSA.AVFeatureBit, PSA.AVFeatureBit
rlwinm. r8, r7, 0, 1 << (31 - EWA.kFlagVec)
beq @non_altivec_task
; Allocate and check
@ -220,7 +220,7 @@ CreateTask
addi r16, r28, Task.ContextBlock
stw r16, Task.ContextBlockPtr(r28) ; overridden to real ECB on blue
lwz r16, PSA.GlobalCPUFlags(r1)
lwz r16, PSA.FlagsTemplate(r1)
stw r16, Task.ContextBlock + ContextBlock.Flags(r28)
lwz r16, PSA.UserModeMSR(r1)
@ -239,9 +239,9 @@ CreateTask
li r16, 0
stw r16, Task.Zero1(r28)
stw r16, Task.Zero2(r28)
stw r16, Task.Zero3(r28)
stw r16, Task.Zero4(r28)
stw r16, Task.Zero5(r28)
stw r16, Task.CodeFaultCtr(r28)
stw r16, Task.DataFaultCtr(r28)
stw r16, Task.PreemptCtr(r28)
; Who knows that these are for
bl GetTime
@ -656,10 +656,10 @@ MPThrowException
mtcr r16
li r3, kMPTaskAbortedErr
bc BO_IF, 30, ReleaseAndReturnMPCall
bc BO_IF, Task.kFlagAborted, ReleaseAndReturnMPCall
li r3, kMPTaskStoppedErr
bc BO_IF, 22, ReleaseAndReturnMPCall
bc BO_IF, Task.kFlagStopped, ReleaseAndReturnMPCall
bc BO_IF, 14, ReleaseAndReturnMPCallOOM
@ -777,7 +777,7 @@ MPCall_58_0xe0
FuncExportedFromTasks ; OUTSIDE REFERER
ThrowTaskToDebugger ; OUTSIDE REFERER
addi r16, r1, PSA.DbugQueue
addi r17, r31, Task.QueueMember
stw r16, LLL.Freeform(r17)
@ -785,13 +785,13 @@ FuncExportedFromTasks ; OUTSIDE REFERER
li r8, 0x1c
bl PoolAlloc
lwz r29, Task.Flags(r31)
_bset r29, r29, 22
_bset r29, r29, Task.kFlagStopped
MPCall_58_0x114
mtcr r29
mr r28, r8
bc BO_IF, 14, MPCall_58_0x13c
bc BO_IF, 20, MPCall_58_0x13c
bc BO_IF, Task.kFlag14, MPCall_58_0x13c
bc BO_IF, Task.kFlag20, MPCall_58_0x13c
lwz r8, -0x08e8(r1)
; r8 = id
@ -799,10 +799,10 @@ MPCall_58_0x114
cmpwi r9, Queue.kIDClass
mr r30, r8
ori r29, r29, 0x800
_bset r29, r29, Task.kFlag20
beq MPCall_58_0x184
MPCall_58_0x13c
bc BO_IF, 19, MPCall_58_0x158
lwz r8, 0x00f4(r31)
@ -811,7 +811,7 @@ MPCall_58_0x13c
cmpwi r9, Queue.kIDClass
mr r30, r8
ori r29, r29, 0x1000
_bset r29, r29, Task.kFlag19
beq MPCall_58_0x184
MPCall_58_0x158
@ -1001,7 +1001,7 @@ MPCall_60_0x144
MPCall_60_0x150
lwz r16, 0x0088(r31)
rlwinm. r8, r7, 0, 12, 12
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec
lwz r16, 0x00d8(r16)
beq ReleaseAndReturnMPCallOOM
cmplwi cr3, r16, 0x00
@ -1299,7 +1299,7 @@ MPCall_61_0xd8
MPCall_61_0xe8
lwz r16, 0x0088(r31)
rlwinm. r8, r7, 0, 12, 12
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec
lwz r16, 0x00d8(r16)
beq ReleaseAndReturnMPCallOOM
cmplwi cr3, r16, 0x00
@ -1399,7 +1399,7 @@ MPCall_61_0x1ec
MPCall_61_0x1fc
li r21, 0x04
lwz r18, 0x00a4(r16)
rlwimi r18, r17, 0, 20, 23
rlwimi r18, r17, 0, 20, 23 ; MSR[FE0/SE/BE/FE1]
rlwimi r18, r17, 0, 31, 31
stw r18, 0x00a4(r16)
stw r21, 0x0154(r6)

View File

@ -951,7 +951,7 @@ print_memory_logical_0x48
b print_memory_logical_0x6c
print_memory_logical_0x5c
bl PagingFunc4
bl PagingL2PWithoutBATs
rlwimi r31, r27, 0, 20, 31
lbz r8, 0x0000(r31)
bl print_unknown
@ -977,7 +977,7 @@ print_memory_logical_0xac
bl PagingFunc1
li r8, 0x20
bne print_memory_logical_0xdc
bl PagingFunc4
bl PagingL2PWithoutBATs
rlwimi r31, r27, 0, 20, 31
lbz r8, 0x0000(r31)
cmpwi r8, 0xff

View File

@ -2310,7 +2310,7 @@ FDPEmulateInstruction
rlwinm r17, r27, 13, 25, 29
rlwinm r18, r27, 18, 25, 29
beq cr6, FDP_1214_0x2b4
mtcrf 0x3f, r21
mtcrf 0x3f, r21
rlwinm r19, r27, 23, 25, 29
beq FDP_1bd0
bne cr1, FDP_1324

View File

@ -1781,11 +1781,9 @@ RemovePTEFromHTAB ; OUTSIDE REFERER
addi r8, r8, 0x01
stw r8, 0x0e98(r1)
rlwimi r16, r9, 0, 0, 19 ;move page# back into PTE
li r8, -0x01
stw r8, KDP. MinusOne1(r1)
stw r8, KDP. MinusOne2(r1)
stw r8, KDP. MinusOne3(r1)
stw r8, KDP. MinusOne4(r1)
_InvalNCBPointerCache scratch=r8
li r8, 0x00 ;0 upper HTAB word
li r9, 0x00 ;0 lower HTAB word
b EditPTEInHTAB ;update stored PTE and invalidate HTAB entry