Reverse power management functions

This is part of the work to get the mini running well. The
kcPowerDispatch and kcCacheDispatch entry points were explored. The dead
code implementing a Timer "Heartbeat" was also used to label some
structures better.
This commit is contained in:
Elliot Nunn 2018-03-09 19:46:39 +08:00
parent 7bee860e40
commit c7d4cdd367
19 changed files with 1378 additions and 887 deletions

View File

@ -39,18 +39,20 @@ MSR ds.l 1 ; 0a4 ; (SPAC) copied from kdp by CreateTask
org 0xc4
MQ ds.l 1 ; 0c4 ; 601 only
ds.l 1
EDPOffsetSWIRelated ds.l 1 ; 0c8
PriorityShifty ds.l 1 ; 0cc ; if low nybble is empty, InitRDYQs sets this to 2
org 0xd4
XER ds.l 1
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 0xe0
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
FE000000 ds.l 1 ; 0e8
Zero ds.l 1 ; 0ec
FE000000 ds.l 1 ; 0e8 ; also LR?
LR ds.l 1 ; 0ec
CTR ds.l 1 ; 0f0
KernelCTR ds.l 1 ; 0f4
org 0xfc
CodePtr ds.l 1 ; 0fc ; probably goes in SRR0?

View File

@ -322,7 +322,8 @@ LogFlagShift equ 3
LogFlagBit equ 31 - LogFlagShift
; bit 31 always set on replacement, bit 27 set on replacement with ROM 2.7f3 or later
org 0x128
AlertCount ds.l 1 ; 120, kdp+ee0 ; interprocessor alerts
SchEvalCount ds.l 1 ; 124, kdp+ee4
VMDispatchCountTblPtr ds.l 1 ; 128, kdp+ee8
ds.l 1
ds.l 1
@ -390,7 +391,7 @@ hasL2CR equ 0
hasPLRUL1 equ 1
hasTAU equ 2
hasVMX equ 3
unknownFlag equ 4
hasMSSregs equ 4
hasExtraBATs equ 5
ProcessorFlags ds.l 1 ; 048, kdp+f68 ; flags to specify processor features

View File

@ -109,7 +109,7 @@ kIdlePriority equ 3
ID ds.l 1 ; 000
Signature ds.l 1 ; 004
QueueMember ds.l 4 ; 008:018 ; a task is always a member of a queue, e.g. the RDYQ
MysteryByte1 ds.b 1 ; 018 ; CreateTask sets 0 by default (blue = 2)
State ds.b 1 ; 018 ; non-zero when running
Priority ds.b 1 ; 019 ; CreateTask sets 2 by default
CPUIndex ds.w 1 ; 01a
Weight ds.l 1 ; 01c ; default is 100, blue gets 200, idle gets 1
@ -145,7 +145,7 @@ kFlag23 equ 23
kFlag24 equ 24
kFlag25 equ 25 ; set for idle1, idle2
kFlag26 equ 26 ; set for blue
kFlag27 equ 27
kFlag27 equ 27 ; set on SWI
kFlag28 equ 28 ; set for blue
kFlag29 equ 29
kFlag30 equ 30
@ -470,7 +470,7 @@ kSignature equ 'EVNT'
LLL ds.l 4 ; 00:10 ; first field is ID
Flags ds.l 1 ; 10
ProcessID ds.l 1 ; 14
SWI ds.l 1 ; 18 ; contains 1-8 +/- 16
SWI ds.l 1 ; 18 ; contains 1-8 +/- 16 ; flag 27 (=16) means "is swi"
Counter ds.l 1 ; 1c
Size equ *

View File

@ -153,13 +153,13 @@ SevenFFFDead2 ds.l 1 ; -8dc
SevenFFFDead3 ds.l 1 ; -8d8
SevenFFFDead4 ds.l 1 ; -8d4
VioletVecBase ds.l 48 ; -8d0:-810
IndigoVecBase ds.l 48 ; -810:-750
IdleVecBase ds.l 48 ; -810:-750 ; to wake from DOZE/NAP/SLEEP state
BlueVecBase ds.l 48 ; -750:-690 ; gets enabled by PDM PIH
GreenVecBase ds.l 48 ; -690:-5d0
DiagInfo ds.b 256 ; -5d0:-4d0
ProcessorState ds.b 128 ; -4d0:-450 ; interesting what this gets used by
FreeList ds.l 4 ; -450:-440
ds.l 1 ; -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
ds.w 1 ; -43a
DecClockRateHzCopy ds.l 1 ; -438 ; copied by Init.s
@ -172,7 +172,7 @@ SystemAddressSpaceID ds.l 1 ; -424
blueProcessPtr ds.l 1 ; -41c ; physical ptr to first type-1 struct created
ThermalHandlerID ds.l 1 ; -418 ; is a Note struct
PMFHandlerID ds.l 1 ; -414 ; also a Note struct
BlueSpinningOn ds.l 1 ; -410 ; ID or 0 or -1
BlueSpinningOn ds.l 1 ; -410 ; ID or 0 or -1
ds.l 1 ; -40c
ds.l 1 ; -408
ds.l 1 ; -404

View File

@ -13,7 +13,7 @@ NKFiles =
{NKDir}NKVMCalls.s ¶
{NKDir}NKPowerCalls.s ¶
{NKDir}NKRTASCalls.s ¶
{NKDir}NKCacheCalls.s ¶
{NKDir}NKCache.s
{NKDir}NKMPCalls.s ¶
{NKDir}NKSync.s ¶
{NKDir}NKTasks.s ¶

529
NanoKernel/NKCache.s Normal file
View File

@ -0,0 +1,529 @@
###### ### ###### ## ## ######## ###### ### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ######### ###### ## ## ## ## ##
## ######### ## ## ## ## ## ######### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
###### ## ## ###### ## ## ######## ###### ## ## ######## ########
; Enable/disable/probe the L1/2 data/inst cache
; Probably called using an unknown 68k F-trap. Not usually called on my
; G4, but can be tested by hacking the MPCall table. Uses fancy new CPU
; features (MSSCR0), so probably not legacy code. For CPU accelerator
; cards? `FlushCache` needs to be nopped out to prevent a crash.
; ARGUMENT (r3)
; r3.hi = action flags
; enable specified caches $8000
; disable specified caches $4000
; report pre-change state $2000
; also enable (???) $1000
; enable/disable I-cache $0800
; enable/disable D-cache $0400
;
; r3.lo = which cache (L1/2)
; level 1 1
; level 2 2
;
; RETURN VALUE (r3)
; r3.hi = pre-change state flags (resemble action flags)
; both caches disabled $4000
; either cache enabled $8000
; I-cache enabled $0800
; D-cache enabled $0400
;
; r3.lo = return status
; success 0
; failure < 0
; checked L1 but did not set 1
; checked L2 but did not set 2
; DeclareMPCall 199, kcCacheDispatch ; DEBUG
kcCacheDispatch
_RegRangeToContextBlock r21, r23 ; get some breathing room
; _log 'kcCacheDispatch ' ; DEBUG
; mr r8, r3 ; DEBUG
; bl printw ; DEBUG
; _log '^n' ; DEBUG
clrlwi r8, r3, 16 ; bad selector
cmplwi r8, 2
bgt- @fail_bad_selector
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
andi. r8, r8, 1 << NKProcessorInfo.hasL2CR
beq- CacheCallFailNoL2 ; no L2CR => fail (what about 601?)
rlwinm. r9, r3, 0, 2, 2 ; if flagged, get cache state in r23
bnel- CacheCallGetInfoForReturnValue ; (otherwise, r23 is undefined)
srwi r8, r3, 30 ; cannot enable *and* disable
cmpwi r8, 3
beq- CacheCallFailBadFlags
clrlwi r8, r3, 16 ; go to main code for level 1/2 cache
cmplwi r8, 1
beq- CacheCallDispatchL1
cmplwi r8, 2
beq- CacheCallDispatchL2
@fail_bad_selector ; fall through => bad selector
lisori r3, -2
b CacheCallReturn
### ## ## ###
## ## #### ##
## ## ## ##
## ## ## ##
## ## ## ##
## ## ## ##
### ######## ###### ###
CacheCallDispatchL1
rlwinm. r9, r3, 0, 1, 1
bne- CacheCallL1DisableSelected
rlwinm. r9, r3, 0, 0, 0
bne- CacheCallL1EnableSelected
rlwinm. r9, r3, 0, 3, 3 ; ???
bl FlushCaches
b CacheCallReturn
CacheCallL1DisableSelected
bl FlushCaches
rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE]
srwi r22, r22, 12
mfspr r21, hid0
andc r21, r21, r22 ; HID0 &= ~mybits
sync
mtspr hid0, r21
li r3, 0
b CacheCallReturn
CacheCallL1EnableSelected
rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE]
srwi r22, r22, 12
mfspr r21, hid0
or r21, r21, r22 ; HID0 |= mybits
sync
mtspr hid0, r21
li r3, 0
b CacheCallReturn
### ## ####### ###
## ## ## ## ##
## ## ## ##
## ## ####### ##
## ## ## ##
## ## ## ##
### ######## ######### ###
CacheCallDispatchL2
rlwinm. r9, r3, 0, 1, 1
bne- CacheCallL2DisableSelected
rlwinm. r9, r3, 0, 0, 0
bne- CacheCallL2EnableSelected
rlwinm. r9, r3, 0, 3, 3
bne- CacheCallL2Flag3 ; goes to DisableSelected
rlwinm. r9, r3, 0, 2, 2
;bne removed?
bne- CacheCallReturn
CacheCallFailBadFlags
lisori r3, -4
b CacheCallReturn
CacheCallL2Flag3
bl CacheCallL2DisableSelected ; typo? should be `b`
CacheCallL2EnableSelected
mfspr r21, l2cr ; fail if L2CR[L2E] already set
sync
andis. r21, r21, 0x8000
bne- CacheCallReturn
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1)
and. r8, r8, r8
beq- CacheCallFailNoL2 ; fail if zero-sized cache reported
mfspr r21, hid0 ; save HID0
rlwinm r8, r21, 0, 12, 10 ; clear HID0[DPM] (dynamic power management)
mtspr hid0, r8 ; presumably to keep L2 working while we wait?
sync
addi r8, r1, PSA.ProcessorState
lwz r8, NKProcessorState.saveL2CR(r8)
and. r8, r8, r8
beq- CacheCallReturn ; fail if zero L2CR was saved?
sync
lis r9, 0x0020 ; set L2CR[GI] (global invalidate)
or r8, r8, r9
mtspr l2cr, r8
sync
@inval_loop
mfspr r8, l2cr ; check L2CR[IP] (invalidate progress)
sync
andi. r9, r8, 1
bne+ @inval_loop
lis r9, 0x0020 ; clear L2CR[GI]
andc r8, r8, r9
mtspr l2cr, r8
sync
lis r9, 0x8000 ; set L2CR[L2E] (L2 enable)
or r8, r8, r9
mtspr l2cr, r8
sync
mtspr hid0, r21 ; restore HID0
sync
li r3, 0 ; return successfully
b CacheCallReturn
CacheCallFailNoL2
li r3, -2
b CacheCallReturn
CacheCallL2DisableSelected
mfspr r22, l2cr ; return if already disabled per L2CR[L2E]
sync
andis. r22, r22, 0x8000
beq- CacheCallReturn
bl FlushCaches
mfspr r22, l2cr ; clear L2CR[L2E]
sync
clrlwi r22, r22, 1
mtspr l2cr, r22
sync
addi r8, r1, PSA.ProcessorState
stw r22, NKProcessorState.saveL2CR(r8) ; update saveL2CR
sync
rlwinm r22, r22, 0, 7, 3 ; clear L2CR[3/5/6] (all reserved)
oris r22, r22, 0x0010 ; set L2CR[13] (also reserved)
mtspr l2cr, r22
sync
;b CacheCallReturn ; fall through
### ######## ######## ######## ## ## ######## ## ## ###
## ## ## ## ## ## ## ## ## ### ## ##
## ## ## ## ## ## ## ## ## #### ## ##
## ######## ###### ## ## ## ######## ## ## ## ##
## ## ## ## ## ## ## ## ## ## #### ##
## ## ## ## ## ## ## ## ## ## ### ##
### ## ## ######## ## ####### ## ## ## ## ###
CacheCallReturn
ori r23, r23, 0xffff ; put the r23.hi from CacheCallGetInfoForReturnValue into r3.hi
oris r3, r3, 0xffff
and r3, r3, r23
CacheCallReturnWithoutFlags
_RegRangeFromContextBlock r21, r23
sync
; _log 'Return ' ; DEBUG
; mr r8, r3 ; DEBUG
; bl printw ; DEBUG
; _log '^n' ; DEBUG
b IntReturn
### ######## ######## ####### ######## ######## ###
## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ##
## ######## ######## ## ## ######## ###### ##
## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ##
### ## ## ## ####### ######## ######## ###
; RET r23.hi = flags describing state of specified cache (see top of file)
CacheCallGetInfoForReturnValue
clrlwi r8, r3, 16
cmplwi r8, 1
beq- @level1
cmplwi r8, 2
beq- @level2
lisori r3, -5
b CacheCallReturnWithoutFlags
@level1
mfspr r21, hid0
rlwinm. r21, r21, 12, 4, 5
beq- @all_off
oris r23, r21, 0x8000
blr
@level2
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1)
and. r8, r8, r8
beq+ CacheCallFailNoL2
mfspr r21, hid0 ; same bits as above
rlwinm r21, r21, 12, 4, 5
mfspr r22, l2cr ; L2-D is on if L1-D is on and L2CR[DO] is cleared
rlwinm r22, r22, 5, 4, 4
andc r21, r21, r22
mfspr r22, l2cr ; then again, both L2s are off if L2CR[L2E] is cleared
andis. r22, r22, 0x8000
beq- @all_off
or r23, r21, r22
blr
@all_off
lisori r23, 0x40000000
blr
######## ## ## ## ###### ## ## ######## ## ## ## ## ###### ######
## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## #### ## ## ##
###### ## ## ## ###### ######### ###### ## ## ## ## ## ## ######
## ## ## ## ## ## ## ## ## ## ## #### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ##
## ######## ####### ###### ## ## ## ####### ## ## ###### ######
; Flush L1 and L2 caches
; Also used by NKPowerCalls.s
; ARG KDP *r1, ContextBlock *r6
; CLOB r8, r9, cr
FlushCaches
; blr ; DEBUG
; Be cautious
mfctr r8
stw r25, ContextBlock.r25(r6)
stw r24, ContextBlock.r24(r6)
stw r8, ContextBlock.KernelCTR(r6)
; Flush level 1
lhz r25, KDP.ProcessorInfo + NKProcessorInfo.DataCacheLineSize(r1)
and. r25, r25, r25 ; r25 = L1-D line size
cntlzw r8, r25
beq- @return
subfic r9, r8, 31 ; r9 = logb(L1-D line size)
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.DataCacheTotalSize(r1)
and. r8, r8, r8 ; r8 = L1-D size
beq- @return
lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
mtcr r24
bc BO_IF, 31 - NKProcessorInfo.hasMSSregs, @use_SPRs_to_invalidate
; => go away to handle weird CPUs
bc BO_IF_NOT, 31 - NKProcessorInfo.hasPLRUL1, @no_pseudo_lru
slwi r24, r8, 1
add r8, r8, r24
srwi r8, r8, 1 ; be generous with pseudo-LRU caches
@no_pseudo_lru
srw r8, r8, r9
mtctr r8 ; loop counter = cache/line
lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM
lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8)
add r8, r8, r9
@loop_L1
lwzux r9, r8, r25
bdnz+ @loop_L1
; Flush level 2 (very similar to above)
lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
andi. r24, r24, 1 << NKProcessorInfo.hasL2CR
beq- @return ; return if L2CR unavailable
mfspr r24, l2cr
andis. r24, r24, 0x8000
beq- @return ; return if L2 off (per L2CR[L2E])
lhz r25, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DBlockSize(r1)
and. r25, r25, r25 ; r25 = L2-D line size
cntlzw r8, r25
beq- @return
subfic r9, r8, 31 ; r9 = logb(L2-D line size)
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1)
and. r8, r8, r8 ; r8 = L2-D size
beq- @return
srw r8, r8, r9
mtctr r8 ; loop counter = cache/line
mfspr r24, l2cr ; set L2CR[DO] (disables L2-I)
oris r24, r24, 0x0040
mtspr l2cr, r24
isync
lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM
lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8)
add r8, r8, r9
addis r8, r8, 0x19 ; start high in ROM and count backwards
neg r25, r25
@loop_L2
lwzux r9, r8, r25
bdnz+ @loop_L2
rlwinm r24, r24, 0, 10, 8
mtspr l2cr, r24 ; clear L2CR[DO] (reenables L2-I)
isync
; Done (this return path is also called from the sneaky code below)
@return
lwz r8, ContextBlock.KernelCTR(r6)
lwz r25, ContextBlock.r25(r6)
lwz r24, ContextBlock.r24(r6)
sync
mtctr r8
blr
; If "hasMSSregs" flag (my name) is set in ProcessorFlags, L1 and L2 can
; instead be flushed by clobbering reserved bits in MSSCR0 and L2CR
; respectively.
@use_SPRs_to_invalidate
; Flush level 1: set MSSCR0[8] and spin until it clears
dssall ; AltiVec needs to know
sync
mfspr r8, msscr0
oris r8, r8, 0x0080
mtspr msscr0, r8
sync
@loop_msscr0
mfspr r8, msscr0
sync
andis. r8, r8, 0x0080
bne+ @loop_msscr0
; Flush level 2: set L2CR[4] and spin until it clears
mfspr r8, l2cr
ori r8, r8, 0x0800
mtspr l2cr, r8
sync
@loop_l2cr
mfspr r8, l2cr
sync
andi. r8, r8, 0x0800
bne+ @loop_l2cr
; Jump back up to main code path to return
b @return
; Called when we cop a machine check with the "L1 data cache error"
; flag set in SRR1, followed by an interrupt return. Same trick as
; above.
; CLOB r8, cr
FlushL1CacheUsingMSSCR0
; Return if MSSCR0 unavailable
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
mtcr r8
bclr BO_IF_NOT, 31-NKProcessorInfo.hasMSSregs
; Flush level 1: set MSSCR0[8] and spin until it clears
dssall ; AltiVec needs to know
sync
mfspr r8, msscr0
oris r8, r8, 0x0080
mtspr msscr0, r8
sync
@loop_msscr0
mfspr r8, msscr0
sync
andis. r8, r8, 0x0080
bne+ @loop_msscr0
blr

View File

@ -1,300 +0,0 @@
kcCacheDispatch ; OUTSIDE REFERER
stw r21, 0x01ac(r6)
stw r22, 0x01b4(r6)
stw r23, 0x01bc(r6)
clrlwi r8, r3, 0x10
cmplwi r8, 0x02
bgt- kcCacheDispatch_0x4c
lwz r8, 0x0f68(r1)
andi. r8, r8, 0x01
beq- kcCacheDispatch_0x178
rlwinm. r9, r3, 0, 2, 2
bnel- kcCacheDispatch_0x1e4
srwi r8, r3, 30
cmpwi r8, 0x03
beq- kcCacheDispatch_0xd8
clrlwi r8, r3, 0x10
cmplwi r8, 0x01
beq- kcCacheDispatch_0x58
cmplwi r8, 0x02
beq- kcCacheDispatch_0xb8
kcCacheDispatch_0x4c
lis r3, -0x01
ori r3, r3, 0xfffe
b kcCacheDispatch_0x1c4
kcCacheDispatch_0x58
rlwinm. r9, r3, 0, 1, 1
bne- kcCacheDispatch_0x74
rlwinm. r9, r3, 0, 0, 0
bne- kcCacheDispatch_0x98
rlwinm. r9, r3, 0, 3, 3
bl kcCacheDispatch_0x258
b kcCacheDispatch_0x1c4
kcCacheDispatch_0x74
bl kcCacheDispatch_0x258
rlwinm r22, r3, 0, 4, 5
srwi r22, r22, 12
mfspr r21, hid0
andc r21, r21, r22
sync
mtspr hid0, r21
li r3, 0x00
b kcCacheDispatch_0x1c4
kcCacheDispatch_0x98
rlwinm r22, r3, 0, 4, 5
srwi r22, r22, 12
mfspr r21, hid0
or r21, r21, r22
sync
mtspr hid0, r21
li r3, 0x00
b kcCacheDispatch_0x1c4
kcCacheDispatch_0xb8
rlwinm. r9, r3, 0, 1, 1
bne- kcCacheDispatch_0x180
rlwinm. r9, r3, 0, 0, 0
bne- kcCacheDispatch_0xe8
rlwinm. r9, r3, 0, 3, 3
bne- kcCacheDispatch_0xe4
rlwinm. r9, r3, 0, 2, 2
bne- kcCacheDispatch_0x1c4
kcCacheDispatch_0xd8
lis r3, -0x01
ori r3, r3, 0xfffc
b kcCacheDispatch_0x1c4
kcCacheDispatch_0xe4
bl kcCacheDispatch_0x180
kcCacheDispatch_0xe8
mfspr r21, l2cr
sync
andis. r21, r21, 0x8000
bne- kcCacheDispatch_0x1c4
lwz r8, 0x0f54(r1)
and. r8, r8, r8
beq- kcCacheDispatch_0x178
mfspr r21, hid0
rlwinm r8, r21, 0, 12, 10
mtspr hid0, r8
sync
addi r8, r1, -0x4d0
lwz r8, 0x0050(r8)
and. r8, r8, r8
beq- kcCacheDispatch_0x1c4
sync
lis r9, 0x20
or r8, r8, r9
mtspr l2cr, r8
sync
kcCacheDispatch_0x138
mfspr r8, l2cr
sync
andi. r9, r8, 0x01
bne+ kcCacheDispatch_0x138
lis r9, 0x20
andc r8, r8, r9
mtspr l2cr, r8
sync
lis r9, -0x8000
or r8, r8, r9
mtspr l2cr, r8
sync
mtspr hid0, r21
sync
li r3, 0x00
b kcCacheDispatch_0x1c4
kcCacheDispatch_0x178
li r3, -0x02
b kcCacheDispatch_0x1c4
kcCacheDispatch_0x180
mfspr r22, l2cr
sync
andis. r22, r22, 0x8000
beq- kcCacheDispatch_0x1c4
bl kcCacheDispatch_0x258
mfspr r22, l2cr
sync
clrlwi r22, r22, 0x01
mtspr l2cr, r22
sync
addi r8, r1, -0x4d0
stw r22, 0x0050(r8)
sync
rlwinm r22, r22, 0, 7, 3
oris r22, r22, 0x10
mtspr l2cr, r22
sync
kcCacheDispatch_0x1c4
ori r23, r23, 0xffff
oris r3, r3, 0xffff
and r3, r3, r23
kcCacheDispatch_0x1d0
lwz r21, 0x01ac(r6)
lwz r22, 0x01b4(r6)
lwz r23, 0x01bc(r6)
sync
b IntReturn
kcCacheDispatch_0x1e4
clrlwi r8, r3, 0x10
cmplwi r8, 0x01
beq- kcCacheDispatch_0x204
cmplwi r8, 0x02
beq- kcCacheDispatch_0x218
lis r3, -0x01
ori r3, r3, 0xfffb
b kcCacheDispatch_0x1d0
kcCacheDispatch_0x204
mfspr r21, hid0
rlwinm. r21, r21, 12, 4, 5
beq- kcCacheDispatch_0x24c
oris r23, r21, 0x8000
blr
kcCacheDispatch_0x218
lwz r8, 0x0f54(r1)
and. r8, r8, r8
beq+ kcCacheDispatch_0x178
mfspr r21, hid0
rlwinm r21, r21, 12, 4, 5
mfspr r22, l2cr
rlwinm r22, r22, 5, 4, 4
andc r21, r21, r22
mfspr r22, l2cr
andis. r22, r22, 0x8000
beq- kcCacheDispatch_0x24c
or r23, r21, r22
blr
kcCacheDispatch_0x24c
lis r23, 0x4000
ori r23, r23, 0x00
blr
kcCacheDispatch_0x258 ; OUTSIDE REFERER
mfctr r8
stw r25, 0x01cc(r6)
stw r24, 0x01c4(r6)
stw r8, 0x00f4(r6)
lhz r25, 0x0f44(r1)
and. r25, r25, r25
cntlzw r8, r25
beq- kcCacheDispatch_0x338
subfic r9, r8, 0x1f
lwz r8, 0x0f34(r1)
and. r8, r8, r8
beq- kcCacheDispatch_0x338
lwz r24, 0x0f68(r1)
mtcr r24
bso- cr6, kcCacheDispatch_0x350
bne- cr7, kcCacheDispatch_0x2a4
slwi r24, r8, 1
add r8, r8, r24
srwi r8, r8, 1
kcCacheDispatch_0x2a4
srw r8, r8, r9
mtctr r8
lwz r8, 0x0630(r1)
lwz r9, 0x0028(r8)
add r8, r8, r9
kcCacheDispatch_0x2b8
lwzux r9, r8, r25
bdnz+ kcCacheDispatch_0x2b8
lwz r24, 0x0f68(r1)
andi. r24, r24, 0x01
beq- kcCacheDispatch_0x338
mfspr r24, l2cr
andis. r24, r24, 0x8000
beq- kcCacheDispatch_0x338
lhz r25, 0x0f60(r1)
and. r25, r25, r25
cntlzw r8, r25
beq- kcCacheDispatch_0x338
subfic r9, r8, 0x1f
lwz r8, 0x0f54(r1)
and. r8, r8, r8
beq- kcCacheDispatch_0x338
srw r8, r8, r9
mtctr r8
mfspr r24, l2cr
oris r24, r24, 0x40
mtspr l2cr, r24
isync
lwz r8, 0x0630(r1)
lwz r9, 0x0028(r8)
add r8, r8, r9
addis r8, r8, 0x19
neg r25, r25
kcCacheDispatch_0x324
lwzux r9, r8, r25
bdnz+ kcCacheDispatch_0x324
rlwinm r24, r24, 0, 10, 8
mtspr l2cr, r24
isync
kcCacheDispatch_0x338
lwz r8, 0x00f4(r6)
lwz r25, 0x01cc(r6)
lwz r24, 0x01c4(r6)
sync
mtctr r8
blr
kcCacheDispatch_0x350
dssall
sync
mfspr r8, 1014
oris r8, r8, 0x80
mtspr 1014, r8
sync
kcCacheDispatch_0x368
mfspr r8, 1014
sync
andis. r8, r8, 0x80
bne+ kcCacheDispatch_0x368
mfspr r8, l2cr
ori r8, r8, 0x800
mtspr l2cr, r8
sync
kcCacheDispatch_0x388
mfspr r8, l2cr
sync
andi. r8, r8, 0x800
bne+ kcCacheDispatch_0x388
b kcCacheDispatch_0x338
kcCacheDispatch_0x39c ; OUTSIDE REFERER
lwz r8, 0x0f68(r1)
mtcr r8
bnslr- cr6
dssall
sync
mfspr r8, 1014
oris r8, r8, 0x80
mtspr 1014, r8
sync
kcCacheDispatch_0x3c0
mfspr r8, 1014
sync
andis. r8, r8, 0x80
bne+ kcCacheDispatch_0x3c0
blr

View File

@ -63,5 +63,5 @@ 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
kGetProcessorTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name
kSIGP17 equ 17 ; r4 = target CPU idx?

View File

@ -541,12 +541,9 @@ InitHighLevel
; Fill Indigo (PSA). All panics, except for IntIndigo in:
; - SystemResetVector
; - ExternalIntVector
; - DecrementerVector
; For the PowerDispatch selector that governs idle modes
bl FillIndigo
bl InitIdleVecTable
@ -1138,7 +1135,7 @@ SetProcessorFlags
stw r8, Task.Name(r31)
li r8, 2
stb r8, Task.MysteryByte1(r31)
stb r8, Task.State(r31)
lisori r8, 0x30028 ; (Z>>Task.kFlag14) | (Z>>Task.kFlagBlue) | (Z>>Task.kFlag26) | (Z>>Task.kFlag28)
stw r8, Task.Flags(r31)

View File

@ -1302,11 +1302,13 @@ IntMachineCheck ; OUTSIDE REFERER
_log '^n'
rlwinm. r8, r11, 0, 2, 2
beq- IntMachineCheck_0xa4
bl kcCacheDispatch_0x39c
beq- @not_L1_data_cache_error
;L1 data cache error
bl FlushL1CacheUsingMSSCR0
b IntReturn
IntMachineCheck_0xa4
@not_L1_data_cache_error
li r8, 0x07
b major_0x02980_0x134

View File

@ -230,3 +230,50 @@ HalfLoadedReg set (&reg)
ENDM
MACRO
_RegRangeToContextBlock &first, &last
stw &first, $104+8*(&first)(r6)
IF &first != &last
_RegRangeToContextBlock &first+1, &last
ENDIF
ENDM
MACRO
_RegRangeFromContextBlock &first, &last
lwz &first, $104+8*(&first)(r6)
IF &first != &last
_RegRangeFromContextBlock &first+1, &last
ENDIF
ENDM
MACRO
_FloatRangeToContextBlock &first, &last
stfd &first, ContextBlock.FloatRegisters+8*(&first)(r6)
IF &first != &last
_FloatRangeToContextBlock &first+1, &last
ENDIF
ENDM
MACRO
_FloatRangeFromContextBlock &first, &last
lfd &first, ContextBlock.FloatRegisters+8*(&first)(r6)
IF &first != &last
_FloatRangeFromContextBlock &first+1, &last
ENDIF
ENDM

File diff suppressed because it is too large Load Diff

View File

@ -142,11 +142,11 @@ CommonPIHPath_0x14c
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
lwz r30, -0x0440(r1)
lwz r30, PSA.MCR(r1)
or r31, r31, r30
stw r31, -0x0440(r1)
stw r31, PSA.MCR(r1)
sth r28, -0x043c(r1)
lwz r31, -0x08f0(r1)
lwz r31, PSA.PA_BlueTask(r1)
mfsprg r30, 0
lwz r28, 0x0064(r31)
lbz r29, 0x0018(r31)

View File

@ -32,41 +32,51 @@ PflgTblCtr set PflgTblCtr + 1
with NKProcessorInfo
; CpuSpecificByte
; 1 2 ProcessorFlags CPU
; ---- - ------------------------------------------------------------------------ -----------------------
PflgTblEnt 0x03, 1, 0 ; 0**0
PflgTblEnt 0x00, 0, 0 ; 0**1 = 601
PflgTblEnt 0x03, 1, 0 ; 0**2
PflgTblEnt 0x1b, 2, 0 ; 0**3 = 603
PflgTblEnt 0x0a, 1, 0 ; 0**4 = 604
PflgTblEnt 0x1b, 2, 0 ; 0**5
PflgTblEnt 0x1b, 2, 0 ; 0**6 = 603e
PflgTblEnt 0x1b, 2, 0 ; 0**7 = 750FX
PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU ; 0**8 = 750
PflgTblEnt 0x0a, 1, 0 ; 0**9
PflgTblEnt 0x0a, 1, 0 ; 0**a
PflgTblEnt 0x03, 1, 0 ; 0**b
PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 0**c = 7400
PflgTblEnt 0x0b, 2, 0 ; 0**d
PflgTblEnt 0x03, 2, 0 ; 0**e
PflgTblEnt 0x03, 2, 0 ; 0**f
; CpuSpecificByte2:
HID0_NHR_only equ 1 ; Idle Power calls should set the HID0[NHR] bit
HID0_NHR_and_sleep equ 2 ; ...and the HID0 bit that potentiates MSR[POW]
HID0_neither equ 0
PflgTblEnt 0x03, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**0 = 7450
PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**1 = 7445/55
PflgTblEnt 0x03, 2, 0 ; 8**2 = 7447 (OS X only)
PflgTblEnt 0x03, 2, 0 ; 8**3
PflgTblEnt 0x03, 1, 0 ; 8**4
PflgTblEnt 0x03, 2, 0 ; 8**5
PflgTblEnt 0x03, 2, 0 ; 8**6
PflgTblEnt 0x03, 2, 0 ; 8**7
PflgTblEnt 0x03, 2, 0 ; 8**8
PflgTblEnt 0x03, 2, 0 ; 8**9
PflgTblEnt 0x03, 2, 0 ; 8**a
PflgTblEnt 0x03, 2, 0 ; 8**b
PflgTblEnt 0x1b, 2, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< unknownFlag ; 8**c = 7410
PflgTblEnt 0x03, 2, 0 ; 8**d
PflgTblEnt 0x03, 2, 0 ; 8**e
PflgTblEnt 0x03, 2, 0 ; 8**f
; See NKPowerCalls for info on CpuSpecificByte1. Its upper nybble specifies how to idle the CPU.
; CpuSpecificByte
; 1 2 ProcessorFlags CPU
; - - -------------- ---
PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**0
PflgTblEnt 0x00, HID0_neither, 0 ; 0**1 = 601
PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**2
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**3 = 603
PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**4 = 604
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**5
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**6 = 603e
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**7 = 750FX
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU ; 0**8 = 750
PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**9
PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**a
PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**b
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 0**c = 7400
PflgTblEnt 0x0b, HID0_NHR_and_sleep, 0 ; 0**d
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**e
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**f
PflgTblEnt 0x03, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**0 = 7450 (see note below)
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**1 = 7445/55
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**2 = 7447 (OS X only)
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**3
PflgTblEnt 0x03, HID0_NHR_only, 0 ; 8**4
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**5
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**6
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**7
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**8
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**9
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**a
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**b
PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**c = 7410
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**d
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**e
PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**f
; NB: PPC 7450 ("G4e") and its descendants (744x/745x) lack the HID0[DOZE] bit (they have HID0[HIGH_BAT_EN] instead).
; Therefore the upper nybble of CpuSpecificByte1 should be 0, or 2 for NAP (works), or 3 for SLEEP (freezes).
endwith

View File

@ -702,11 +702,11 @@ Save_v0_v31_0x1b8
TaskUnready
lwz r17, Task.QueueMember + LLL.Next( r8)
lbz r18, Task.MysteryByte1( r8)
lbz r18, Task.State( r8)
addi r16, r8, Task.QueueMember
; Panic if MysteryByte1==0, return early if this task is not enqueued (i.e. LLL.Next==0)
; Panic if State==0, return early if this task is not enqueued (i.e. LLL.Next==0)
cmpwi cr1, r18, 0
cmpwi r17, 0
beq+ cr1, Local_Panic
@ -740,7 +740,7 @@ TaskUnready
@return_early
li r16, 0
stb r16, Task.MysteryByte1(r8)
stb r16, Task.State(r8)
mfsprg r17, 0
li r16, 1
@ -821,7 +821,7 @@ TaskReadyCommonPath
li r16, 1
stb r16, Task.MysteryByte1(r8)
stb r16, Task.State(r8)
blr
@ -1167,9 +1167,11 @@ RescheduleAndReturn ; OUTSIDE REFERER
stb r8, EWA.SchEvalFlag(r14)
lwz r31, -0x0008(r14)
lwz r1, -0x0004(r14)
lwz r9, 0x0ee4(r1)
addi r9, r9, 0x01
stw r9, 0x0ee4(r1)
lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.SchEvalCount(r1)
addi r9, r9, 1
stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.SchEvalCount(r1)
bl major_0x14a98
lbz r27, 0x0019(r31)
blt- major_0x142dc_0x58
@ -1459,9 +1461,9 @@ major_0x14548_0x148
li r8, 0x00
beq- major_0x14548_0x20c
andc r27, r27, r28
lwz r29, -0x0440(r1)
lwz r29, PSA.MCR(r1)
stw r27, 0x0064(r30)
stw r8, -0x0440(r1)
stw r8, PSA.MCR(r1)
blt- cr2, major_0x14548_0x1cc
bsol+ cr6, Local_Panic
clrlwi r8, r7, 0x08
@ -1491,7 +1493,7 @@ major_0x14548_0x1cc
lhz r17, -0x043c(r1)
lwz r18, 0x067c(r1)
cmplwi r17, 0xffff
lwz r26, 0x0674(r1)
lwz r26, KDP.PostIntMaskInit(r1)
beq- major_0x14548_0x1f8
sth r17, 0x0000(r18)
li r17, -0x01
@ -1501,7 +1503,7 @@ major_0x14548_0x1f8
cmpwi r29, 0x00
or r13, r13, r29
bne- major_0x14548_0x20c
lwz r29, 0x0678(r1)
lwz r29, KDP.ClearIntMaskInit(r1)
and r13, r13, r29
major_0x14548_0x20c
@ -1823,7 +1825,8 @@ major_0x14a98 ; OUTSIDE REFERER
lwz r18, KDP.PA_ECB(r1)
nand. r8, r8, r8
lwz r17, ContextBlock.PriorityShifty(r18)
bltlr-
bltlr- ; return if flag 10 was unset
cmpwi r17, 0
rlwinm r9, r17, 0, 22, 22
blt- major_0x14a98_0x54
@ -1858,6 +1861,8 @@ major_0x14a98_0x54
## ## ## ## ## ## ## ## ## ## ## ##
## ######## ## ## ###### ######## ### ## ## ########
; ARG Task *r8
FlagSchEvaluationIfTaskRequires ; OUTSIDE REFERER
lwz r16, Task.Flags(r8)
mfsprg r15, 0
@ -1908,7 +1913,7 @@ FlagSchEvaluationIfTaskRequires ; OUTSIDE REFERER
lhz r17, EWA.CPUIndex(r15)
lhz r18, CPU.EWA + EWA.CPUIndex(r18)
cmpw r18, r17
bne- BEFOUR
bne- DoInterprocessorAlert
NINETYFOUR
li r16, 0x01
@ -1923,10 +1928,10 @@ major_0x14af8_0xa0
cmpw r17, r18
beq+ NINETYFOUR
BEFOUR
lwz r9, 0x0ee0(r1)
addi r9, r9, 0x01
stw r9, 0x0ee0(r1)
DoInterprocessorAlert
lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1)
addi r9, r9, 1
stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1)
li r16, kAlert
stw r16, EWA.SIGPSelector(r15)
@ -2009,8 +2014,8 @@ NewCpuEntryPoint
lwz r10, ContextBlock.CodePtr(r6)
lwz r11, ContextBlock.MSR(r6)
lwz r13, 0x00dc(r6)
lwz r12, 0x00ec(r6)
lwz r13, ContextBlock.CR(r6)
lwz r12, ContextBlock.LR(r6)
_log 'EWA '
mr r8, r14
@ -2033,7 +2038,7 @@ NewCpuEntryPoint
RemoveFromList r16, scratch1=r17, scratch2=r18
li r16, 2
stb r16, Task.MysteryByte1(r31)
stb r16, Task.State(r31)
lwz r16, Task.Flags(r31)
ori r16, r16, 0x20
@ -2135,17 +2140,20 @@ IdleCode
@make_calls
; KCCpuPlugin(12, 1)
li r3, 12
li r4, 1
li r0, 46
; Check that CPU plugin trusts this CPU
li r3, kGetProcessorTemp
li r4, 1 ; 2nd arg ignored
li r0, 46 ; KCCpuPlugin
sc
cmpwi r3, 0
beq- @startagain
li r3, 1
li r4, 0
twi 31, r31, 5 ; unconditional
twi 31, r31, 5 ; PowerCall(1)
cmpwi r3, 0
beq- @startagain
@ -2197,7 +2205,8 @@ StopProcessor_0x10c
lis r5, 0x7fff
ori r5, r5, 0xffff
mtdec r5
li r3, 0x06
li r4, 0x00
twi 31, r31, 0x05
li r3, 6
li r4, 0
twi 31, r31, 5
b StopProcessor_0x10c

View File

@ -1496,117 +1496,155 @@ MPSetEvent
## ## ## ## ## ## ##
### ######## ###### ######## ## ###
SetEvent ; OUTSIDE REFERER
lwz r16, 0x0010(r31)
or r16, r16, r8
stw r16, 0x0010(r31)
mflr r27
lwz r8, 0x0000(r31)
bl UnblockBlueIfCouldBePolling
lwz r16, 0x0008(r31)
cmpw r16, r31
addi r8, r16, -0x08
beq- SetEvent_0x90
lwz r17, 0x0088(r8)
lwz r18, 0x00fc(r17)
subi r18, r18, 4
stw r18, 0x00fc(r17)
lbz r17, 0x0037(r8)
cmpwi r17, 0x01
bne- SetEvent_0x4c
addi r8, r8, 0x20
bl DequeueTimer
; ARG Event *r31, flags r8
SetEvent_0x4c
lwz r16, 0x0008(r31)
SetEvent
lwz r16, EventGroup.Flags(r31)
or r16, r16, r8
stw r16, EventGroup.Flags(r31)
mflr r27
lwz r8, EventGroup.LLL + LLL.Freeform(r31)
bl UnblockBlueIfCouldBePolling
;
lwz r16, EventGroup.LLL + LLL.Next(r31)
cmpw r16, r31
subi r8, r16, Task.QueueMember
beq- @no_task_waiting
; CASE 1: task needs unblocking
; Rerun SC instruction in task context
lwz r17, Task.ContextBlockPtr(r8)
lwz r18, ContextBlock.CodePtr(r17)
subi r18, r18, 4
stw r18, ContextBlock.CodePtr(r17)
; Cancel timeout
lbz r17, Task.Timer + Timer.Byte3(r8)
cmpwi r17, 1
bne- @timer_not_armed
addi r8, r8, Task.Timer
bl DequeueTimer
@timer_not_armed
; Remove this task from my wait queue
lwz r16, EventGroup.LLL + LLL.Next(r31)
RemoveFromList r16, scratch1=r17, scratch2=r18
lwz r18, 0x001c(r31)
addi r18, r18, -0x01
stw r18, 0x001c(r31)
addi r8, r16, -0x08
li r17, 0x01
stb r17, 0x0019(r8)
lwz r18, EventGroup.Counter(r31)
subi r18, r18, 1
stw r18, EventGroup.Counter(r31)
; Latency protection priority
subi r8, r16, Task.QueueMember
li r17, Task.kLatencyProtectPriority
stb r17, Task.Priority(r8)
bl TaskReadyAsPrev
bl CalculateTimeslice
bl FlagSchEvaluationIfTaskRequires
SetEvent_0x90
lwz r16, 0x0018(r31)
rlwinm. r17, r16, 0, 27, 27
beq- SetEvent_0x1a0
lwz r17, KDP.PA_ECB(r1)
lwz r26, -0x08f0(r1)
lwz r18, 0x00c8(r17)
lwz r19, 0x00d0(r17)
cmpwi cr1, r18, 0x00
cmpwi r19, 0x00
bne- cr1, SetEvent_0xc8
bne- SetEvent_0x1a0
lwz r8, 0x0000(r31)
stw r8, 0x00d0(r17)
b SetEvent_0x118
SetEvent_0xc8
lwz r9, 0x0634(r1)
@no_task_waiting
lwz r16, EventGroup.SWI(r31)
rlwinm. r17, r16, 0, 27, 27
; CASE 2: no task waiting.
beq- @return
; CASE 3: SOFTWARE INTERRUPT
lwz r17, KDP.PA_ECB(r1)
lwz r26, PSA.PA_BlueTask(r1)
lwz r18, ContextBlock.EDPOffsetSWIRelated(r17)
lwz r19, ContextBlock.SWIEventGroupID(r17)
cmpwi cr1, r18, 0
cmpwi r19, 0
bne- cr1, @do_not_save_swi_event_id
bne- @return
lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; contains my ID
stw r8, ContextBlock.SWIEventGroupID(r17)
b @common_case
@do_not_save_swi_event_id
; There is an EDP table of SWI-EventGroup IDs... set ours, cancel if already set
lwz r9, KDP.PA_EmulatorData(r1)
rlwinm r16, r16, 2, 26, 29
add r18, r18, r9
lwzx r19, r16, r18
cmpwi r19, 0x00
bne- SetEvent_0x1a0
lwz r8, 0x0000(r31)
cmpwi r19, 0
bne- @return
; Set!
lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; my ID
stwx r8, r16, r18
li r19, 0x1c
li r9, 0x04
SetEvent_0xf0
; Find the highest interrupt level with a nonzero thing
li r19, 7*4
li r9, 4
@loop
lwzx r8, r19, r18
cmpwi r8, 0x00
bne- SetEvent_0x108
cmpwi r8, 0
bne- @exit_loop
subf. r19, r9, r19
bgt+ SetEvent_0xf0
bgt+ @loop
bl panic
@exit_loop
SetEvent_0x108
; Can I interrupt the current interrupt?
cmplw r16, r19
srwi r16, r16, 2
blt- SetEvent_0x1a0
stw r16, 0x00d0(r17)
srwi r16, r16, 2
blt- @return
stw r16, ContextBlock.SWIEventGroupID(r17)
@common_case
SetEvent_0x118
lwz r16, 0x0064(r26)
lbz r19, 0x0018(r26)
ori r16, r16, 0x10
stw r16, 0x0064(r26)
lwz r17, -0x0440(r1)
lwz r16, 0x0674(r1)
lwz r8, 0x0678(r1)
lwz r16, Task.Flags(r26)
lbz r19, Task.State(r26)
ori r16, r16, (1 << (31 - Task.kFlag27))
stw r16, Task.Flags(r26)
; But what *is* MCR?
lwz r17, PSA.MCR(r1)
lwz r16, KDP.PostIntMaskInit(r1)
lwz r8, KDP.ClearIntMaskInit(r1)
and r16, r16, r8
or r17, r17, r16
stw r17, -0x0440(r1)
cmpwi r19, 0x00
addi r16, r26, 0x08
bne- SetEvent_0x198
RemoveFromList r16, scratch1=r17, scratch2=r18
lbz r17, 0x0037(r26)
cmpwi r17, 0x01
bne- SetEvent_0x17c
addi r8, r26, 0x20
bl DequeueTimer
stw r17, PSA.MCR(r1)
SetEvent_0x17c
lwz r18, -0x08f0(r1)
li r16, 0x00
stb r16, 0x0019(r26)
cmpwi r19, 0
addi r16, r26, Task.QueueMember
bne- @task_already_running
; De-fang the blocking timeout
RemoveFromList r16, scratch1=r17, scratch2=r18
lbz r17, Task.Timer + Timer.Byte3(r26)
cmpwi r17, 1
bne- @timer_not_armed_2
addi r8, r26, Task.Timer
bl DequeueTimer
@timer_not_armed_2
lwz r18, PSA.PA_BlueTask(r1)
li r16, Task.kCriticalPriority
stb r16, Task.Priority(r26)
mr r8, r26
bl TaskReadyAsNext
mr r8, r26
bl CalculateTimeslice
@task_already_running
SetEvent_0x198
mr r8, r26
bl FlagSchEvaluationIfTaskRequires
SetEvent_0x1a0
@return
mtlr r27
blr
@ -2553,7 +2591,7 @@ UnblockBlueIfCouldBePolling
mflr r24
stw r9, PSA.BlueSpinningOn(r1)
lbz r17, Task.MysteryByte1(r19)
lbz r17, Task.State(r19)
cmpwi r17, 0
addi r16, r19, Task.QueueMember
@ -2566,12 +2604,12 @@ UnblockBlueIfCouldBePolling
bne- major_0x0dce8_0x60
addi r8, r19, Task.Timer
bl DequeueTimer
lwz r19, -0x08f0(r1)
lwz r19, PSA.PA_BlueTask(r1)
major_0x0dce8_0x60
li r16, 0x01
stb r16, 0x0019(r19)
lwz r8, -0x08f0(r1)
lwz r8, PSA.PA_BlueTask(r1)
bl TaskReadyAsPrev
major_0x0dce8_0x70

View File

@ -59,8 +59,8 @@ MPCall_7 ; OUTSIDE REFERER
stw r4, 0x0098(r31)
lwz r17, ContextBlock.r6(r6)
stw r17, 0x00ec(r31)
lwz r17, ContextBlock.r6(r6)
stw r17, ContextBlock.LR(r31)
lwz r16, Task.Flags(r28)
@ -206,7 +206,7 @@ CreateTask
li r16, 0
stb r16, Task.MysteryByte1(r28)
stb r16, Task.State(r28)
li r16, 9 ; (Z>>Task.kFlag28) | (Z>>Task.kFlag31)
stw r16, Task.Flags(r28)
@ -541,7 +541,7 @@ TasksFuncThatIsNotAMPCall
MPCall_11 ; OUTSIDE REFERER
mfsprg r16, 0
cmpwi r3, 0x00
lwz r17, -0x08f0(r1)
lwz r17, PSA.PA_BlueTask(r1)
lwz r18, -0x0008(r16)
lwz r19, 0x0000(r17)
bne- MPCall_11_0x1c

View File

@ -587,45 +587,53 @@ TimerFire5_0x8 ; OUTSIDE REFERER
; Dead code -- probably removed from TimerTable
_log 'Heartbeat: Ext '
lwz r16, 0x0e80(r1)
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1)
mr r8, r16
bl printd
_log 'Alerts '
lwz r16, 0x0ee0(r1)
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1)
mr r8, r16
bl printd
_log 'Blue cpu-'
lwz r17, -0x08f0(r1)
lhz r16, 0x001a(r17)
lwz r17, PSA.PA_BlueTask(r1)
lhz r16, Task.CPUIndex(r17)
mr r8, r16
bl printb
_log 'state-'
lbz r16, 0x0018(r17)
lbz r16, Task.State(r17)
mr r8, r16
bl printb
_log 'scr-'
lwz r16, KDP.PA_ECB(r1)
lwz r18, 0x0674(r1)
lwz r16, 0x00dc(r16)
lwz r18, KDP.PostIntMaskInit(r1)
lwz r16, ContextBlock.CR(r16)
and r16, r16, r18
mr r8, r16
bl printw
_log 'mcr-'
lwz r16, -0x0440(r1)
lwz r16, PSA.MCR(r1)
mr r8, r16
bl printw
_log 'IPL-'
lwz r16, 0x067c(r1)
lhz r16, 0x0000(r16)
lwz r16, KDP.PA_EmulatorIplValue(r1)
lhz r16, 0(r16)
mr r8, r16
bl printh
_log 'eSR-'
lwz r16, KDP.PA_ECB(r1)
lwz r16, 0x01cc(r16)
andi. r16, r16, 0x07
lwz r16, ContextBlock.r25(r16)
andi. r16, r16, 7
mr r8, r16
bl printb
_log '^n'
mfxer r19
lwz r16, 0x0038(r30)
lwz r17, 0x003c(r30)

View File

@ -24,7 +24,7 @@ NKTop
align 5
include 'NKRTASCalls.s'
align 5
include 'NKCacheCalls.s'
include 'NKCache.s'
; Mostly MP calls:
align 5