Everything on PDM

This commit is contained in:
Elliot Nunn 2018-07-04 19:26:33 +08:00
parent b1d95b5928
commit 3bac275cc5
54 changed files with 6780 additions and 39184 deletions

View File

@ -74,6 +74,9 @@ Reg12 ds.l 1 ; 770
Reg13 ds.l 1 ; 774
Reg14 ds.l 1 ; 778
org 0x800
FuncPtrs ds.l 120 ; 800:9e0
org 0xf00
BootstrapVersion ds.b 16 ; f00:f10 ; Bootstrap loader version info, from ConfigInfo
@ -83,124 +86,6 @@ BootstrapVersion ds.b 16 ; f00:f10 ; Bootstrap loader version info, from Config
; Lives in EDP. Keeping a separate record to EDP makes the code nicer.
; Gets called the "system context"
ContextBlock record 0,INCR
; Move this!
Flags ds.l 1 ; 000 ; (SPAC) copied from kdp by CreateTask
Enables ds.l 1 ; 004
org 0x40
SavedFlags ds.l 1 ; 040 ; from before exception
org 0x44
SavedEnables ds.l 1 ; 044 ; from before exception
org 0x4c
ExceptionHandler ds.l 1 ; 04c
org 0x5c
LA_EmulatorKernelTrapTable ds.l 1
org 0x74
SRR0 ds.l 1 ; 074
org 0x84
LA_EmulatorEntry ds.l 1 ; 084 ; Entry pt of emulator; set by NK Init.s
org 0x94
LA_EmulatorData ds.l 1
org 0x9c
LA_DispatchTable ds.l 1
org 0xa4
MSR ds.l 1 ; 0a4 ; (SPAC) copied from kdp by CreateTask
org 0xc4
MQ ds.l 1 ; 0c4 ; 601 only
EDPOffsetSWIRelated ds.l 1 ; 0c8
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!
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 ; 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?
org 0x100
ds.l 1
r0 ds.l 1 ; 104
ds.l 1
r1 ds.l 1 ; 10c
ds.l 1
r2 ds.l 1 ; 114
ds.l 1
r3 ds.l 1 ; 11c
ds.l 1
r4 ds.l 1 ; 124
ds.l 1
r5 ds.l 1 ; 12c
ds.l 1
r6 ds.l 1 ; 134
ds.l 1
r7 ds.l 1 ; 13c
ds.l 1
r8 ds.l 1 ; 144
ds.l 1
r9 ds.l 1 ; 14c
ds.l 1
r10 ds.l 1 ; 154
ds.l 1
r11 ds.l 1 ; 15c
ds.l 1
r12 ds.l 1 ; 164
ds.l 1
r13 ds.l 1 ; 16c
ds.l 1
r14 ds.l 1 ; 174
ds.l 1
r15 ds.l 1 ; 17c
ds.l 1
r16 ds.l 1 ; 184
ds.l 1
r17 ds.l 1 ; 18c
ds.l 1
r18 ds.l 1 ; 194
ds.l 1
r19 ds.l 1 ; 19c
ds.l 1
r20 ds.l 1 ; 1a4
ds.l 1
r21 ds.l 1 ; 1ac
ds.l 1
r22 ds.l 1 ; 1b4
ds.l 1
r23 ds.l 1 ; 1bc
ds.l 1
r24 ds.l 1 ; 1c4
ds.l 1
r25 ds.l 1 ; 1cc
ds.l 1
r26 ds.l 1 ; 1d4
ds.l 1
r27 ds.l 1 ; 1dc
ds.l 1
r28 ds.l 1 ; 1e4
ds.l 1
r29 ds.l 1 ; 1ec
ds.l 1
r30 ds.l 1 ; 1f4
ds.l 1
r31 ds.l 1 ; 1fc
FloatRegisters ds.d 32 ; 200:300
endr

View File

@ -97,7 +97,7 @@ NanodbgrFlagBit equ 31 - NanodbgrFlagShift
LogFlagShift equ 1
LogFlagBit equ 31 - LogFlagShift
Size equ *
endr
@ -167,50 +167,10 @@ Bank14Start ds.l 1 ; 0a0, irp+e60 ; Starting address of RAM bank 14
Bank14Size ds.l 1 ; 0a4, irp+e64 ; Number of bytes in RAM bank 14
Bank15Start ds.l 1 ; 0a8, irp+e68 ; Starting address of RAM bank 15
Bank15Size ds.l 1 ; 0ac, irp+e6c ; Number of bytes in RAM bank 15
Bank16Start ds.l 1 ; 0b0, irp+e70 ; Starting address of RAM bank 16
Bank16Size ds.l 1 ; 0b4, irp+e74 ; Number of bytes in RAM bank 16
Bank17Start ds.l 1 ; 0b8, irp+e78 ; Starting address of RAM bank 17
Bank17Size ds.l 1 ; 0bc, irp+e7c ; Number of bytes in RAM bank 17
Bank18Start ds.l 1 ; 0c0, irp+e80 ; Starting address of RAM bank 18
Bank18Size ds.l 1 ; 0c4, irp+e84 ; Number of bytes in RAM bank 18
Bank19Start ds.l 1 ; 0c8, irp+e88 ; Starting address of RAM bank 19
Bank19Size ds.l 1 ; 0cc, irp+e8c ; Number of bytes in RAM bank 19
Bank20Start ds.l 1 ; 0d0, irp+e90 ; Starting address of RAM bank 20
Bank20Size ds.l 1 ; 0d4, irp+e94 ; Number of bytes in RAM bank 20
Bank21Start ds.l 1 ; 0d8, irp+e98 ; Starting address of RAM bank 21
Bank21Size ds.l 1 ; 0dc, irp+e9c ; Number of bytes in RAM bank 21
Bank22Start ds.l 1 ; 0e0, irp+ea0 ; Starting address of RAM bank 22
Bank22Size ds.l 1 ; 0e4, irp+ea4 ; Number of bytes in RAM bank 22
Bank23Start ds.l 1 ; 0e8, irp+ea8 ; Starting address of RAM bank 23
Bank23Size ds.l 1 ; 0ec, irp+eac ; Number of bytes in RAM bank 23
Bank24Start ds.l 1 ; 0f0, irp+eb0 ; Starting address of RAM bank 24
Bank24Size ds.l 1 ; 0f4, irp+eb4 ; Number of bytes in RAM bank 24
Bank25Start ds.l 1 ; 0f8, irp+eb8 ; Starting address of RAM bank 25
Bank25Size ds.l 1 ; 0fc, irp+ebc ; Number of bytes in RAM bank 25
EndOfBanks
MaxBanks equ 26 ; Pads out to old struct len (cache block), more to come...
; Interrupt Support Data
IntCntrBaseAddr ds.l 1 ; 100, irp+ec0 ; Interrupt Controller Base Address (variable is used since this is a PCI Dev and address is relocatable)
IntPendingReg ds.l 2 ; 104, irp+ec4 ; Data of current interrupts pending register
; These fields were added to report information about tightly-coupled L2 caches.
; The inline L2 information should be used in situations where there is a CPU
; card L2 cache that can coexist with a motherboard L2.
InlineL2DSize ds.l 1 ; 10c, irp+ecc ; Size of in-line L2 Dcache
InlineL2ISize ds.l 1 ; 110, irp+ed0 ; Size of in-line L2 Icache
InlineL2Combined ds.w 1 ; 114, irp+ed4 ; 1 <- combined or no cache, 0 <- split cache
InlineL2IBlockSize ds.w 1 ; 116, irp+ed6 ; Block size of in-line I L2 cache
InlineL2DBlockSize ds.w 1 ; 118, irp+ed8 ; Block size of in-line D L2 cache
InlineL2IAssoc ds.w 1 ; 11a, irp+eda ; Associativity of L2 I
InlineL2DAssoc ds.w 1 ; 11c, irp+edc ; Associativity of L2 D
ds.w 1 ; 11e, irp+ede ; pad
; More Interrupt Support Data
IntsCompleted ds.l 2 ; 120, irp+ee0 ; completed interrupts
align 5 ; pad to nice cache block alignment
MaxBanks equ 16 ; Pads out to old struct len (cache block), more to come...
Size equ *
endr
@ -268,6 +228,7 @@ DiagLongBootSig ds.l 1 ; 0f4 ; Burn in restart flag
DiagWarmStartHigh ds.l 1 ; 0f8 ; First long of native warm start (WLSC) <SM44>
DiagWarmStartLow ds.l 1 ; 0fc ; Second long of native warm start (SamB) <SM44>
align 5 ; pad to nice cache block alignment
Size equ *
endr
@ -301,37 +262,7 @@ ExceptionPropagateCount ds.l 1 ; 0e8, kdp+ea8 ; count of Exceptions propagated
ExceptionForcedCount ds.l 1 ; 0ec, kdp+eac ; count of Exceptions forced to system
SysContextCpuTime ds.l 2 ; 0f0, kdp+eb0 ; CPU Time used by System Context
AltContextCpuTime ds.l 2 ; 0f8, kdp+eb4 ; CPU Time used by Alternate Context
; This stuff is new (starts at 0x100)
blueProcessID ds.l 1 ; 100, kdp+ec0 ; ID of the blue process.
blueTaskID ds.l 1 ; 104, kdp+ec4 ; ID of the blue task.
pageQueueID ds.l 1 ; 108, kdp+ec8 ; ID of the page fault queue.
TaskCount ds.l 1 ; 10c, kdp+ecc ; Number of tasks.
FreePoolExtendCount ds.l 1 ; 110, kdp+ed0 ; Number of pages given to the nanokernel.
;rsrv1 ds.l 3 ; 114, kdp+ed4 ; reserved???
; My additions
org 0x11c
ConfigFlags ds.l 1 ; 11c, kdp+edc ; includes ScreenConsole ... TODO put flag equs here
NanodbgrFlagShift equ 1
NanodbgrFlagBit equ 31 - NanodbgrFlagShift
LogFlagShift equ 3
LogFlagBit equ 31 - LogFlagShift
; bit 31 always set on replacement, bit 27 set on replacement with ROM 2.7f3 or later
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
MPDispatchCountTblPtr ds.l 1 ; 134, kdp+ef4 ; ???????
AddrSpcSetCtr ds.l 1 ; 138, kdp+ef8 ; incremented by SchSwitchSpace
IDCtr ds.l 1 ; 13c, kdp+efc
org 0x160
Size equ *
endr
@ -372,35 +303,8 @@ DataCacheAssociativity ds.w 1 ; 02e, kdp+f4e ; Associativity of the Data Cache
TransCacheTotalSize ds.w 1 ; 030, kdp+f50 ; number of entries in the Translation Cache
TransCacheAssociativity ds.w 1 ; 032, kdp+f52 ; Associativity of the Translation Cache
OvrEnd
; These fields were added to report information about back-side L2 caches
ProcessorL2DSize ds.l 1 ; 034, kdp+f54 ; Size of back-side L2 Dcache
ProcessorL2ISize ds.l 1 ; 038, kdp+f58 ; Size of back-side L2 Icache
ProcessorL2Combined ds.w 1 ; 03c, kdp+f5c ; 1 <- combined or no cache, 0 <- split cache
ProcessorL2IBlockSize ds.w 1 ; 03e, kdp+f5e ; Block size of back-side I L2 cache
ProcessorL2DBlockSize ds.w 1 ; 040, kdp+f60 ; Block size of back-side D L2 cache
ProcessorL2IAssoc ds.w 1 ; 042, kdp+f62 ; Associativity of L2 I
ProcessorL2DAssoc ds.w 1 ; 044, kdp+f64 ; Associativity of L2 D
filler1 ds.w 1 ; 046, kdp+f66 ; align to long
; ProcessorFlags - Definitions for the processor flags field. These are bit positions,
; as in 1 << hasVMX, and not masks.
hasL2CR equ 0
hasPLRUL1 equ 1
hasTAU equ 2
hasVMX equ 3
hasMSSregs equ 4
hasExtraBATs equ 5
ProcessorFlags ds.l 1 ; 048, kdp+f68 ; flags to specify processor features
align 5 ; pad to nice cache block alignment
org 0x05e
SetToZero ds.w 1 ; 05e, kdp+f7e ; by same code that sets below
ClockRates ds.b 16*4 ; 060:0a0, kdp:f80:fc0 ; 16b blks of cpu/bus/dec/?? speeds (Hz)
org 0x40
Size equ *
endr
@ -493,6 +397,7 @@ HardwareInfoFlags ds.l 1 ; 094, irp+f94 ; 32 bits of flags (see enum above)
RTAS_Get_PowerOn_Time ds.l 1 ; 098, irp+f98 ; token for RTAS getting time for system startup
align 5 ; pad to nice cache block alignment (did i get this right?)
Size equ *
endr
@ -549,4 +454,5 @@ saveSDR1 ds.l 1 ; 070 ; place to store SDR1
saveReturnAddr ds.l 1 ; 074 ; place to store the addr to jump to.
saveKernelDataPtr ds.l 1 ; 078 ; place to store the KernelDataPtr
saveContextPtr ds.l 1 ; 07c ; place to store the ContextPtr
Size equ *
endr

View File

@ -1,678 +0,0 @@
; Opaque NanoKernel structures:
; - stored in the NanoKernel pool (not always)
; - associated with a class number and opaque ID (not always)
; - referenced by opaque ID (for MPLibrary's benefit)
;_______________________________________________________________________
; ID CLASS 1: PROCESS
; (size: 32b, thud command: id -p)
;
; The NanoKernel's internal representation of a cooperative process
; within the blue environment. Processes and tasks have a many-to-one
; relationship.
;
; There is a special 'blue' process that owns the blue task and all
; the CPU idle tasks.
;_______________________________________________________________________
Process record 0,INCR
kIDClass equ 1
kFirstID equ 0x00010001
kSignature equ 'PROC'
;_______________________
; Fields
;_______________________
ID ds.l 1 ; 00
Signature ds.l 1 ; 04 ; 'PROC'
Flags ds.l 1 ; 08 ; MPCall_5 does something here
kFlag0 equ 0
kFlag1 equ 1
kFlag2 equ 2
kFlag3 equ 3
kFlag4 equ 4
kFlag5 equ 5
kFlag6 equ 6
kFlag7 equ 7
kFlag8 equ 8
kFlag9 equ 9
kFlag10 equ 10
kFlag11 equ 11
kFlag12 equ 12
kFlag13 equ 13
kFlag14 equ 14
kFlag15 equ 15
kFlag16 equ 16
kFlag17 equ 17
kFlag18 equ 18
kFlag19 equ 19
kFlag20 equ 20
kFlag21 equ 21
kFlag22 equ 22
kFlag23 equ 23
kFlag24 equ 24
kFlag25 equ 25
kFlag26 equ 26
kFlag27 equ 27
kFlag28 equ 28
kFlag29 equ 29
kFlag30 equ 30
kFlag31 equ 31
SystemAddressSpaceID ds.l 1 ; 0c ; set by Init.s after addrspc creation
TaskCount ds.l 1 ; 10 ; incremented by CreateTask
SystemAddressSpacePtr ds.l 1 ; 14
AddressSpaceCount ds.l 1 ; 18 ; incremented by NKCreateAddressSpaceSub
ds.l 1 ; 1c
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 2: TASK
; (size: 1k, thud command: id -t)
;
; What the MPLibrary and NanoKernel call the unit of multitasking.
; (Remember that 'Thread' and 'Process' were taken.)
;
; Contains space for a ContextBlock in the style of the ECB, but
; blue's ContextBlockPtr is redirected to the ECB.
;_______________________________________________________________________
Task record 0,INCR
kIDClass equ 2
kFirstID equ 0x00020001
kSignature equ 'TASK'
;_______________________
; Task priorities
;_______________________
kCriticalPriority equ 0
kLatencyProtectPriority equ 1
kNominalPriority equ 2
kIdlePriority equ 3
;_______________________
; Fields
;_______________________
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
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
Timer ds.b 64 ; 020:060
ProcessID ds.l 1 ; 060
Flags ds.l 1 ; 064 ; IntAlignment is interested in bit 9, MPCalls 52/116 in bit 15
kFlag0 equ 0
kFlag1 equ 1
kFlag2 equ 2
kFlag3 equ 3
kFlag4 equ 4
kFlag5 equ 5
kFlag6 equ 6
kFlag7 equ 7
kFlag8 equ 8
kFlagTakesAllExceptions equ 9
kFlag10 equ 10
kFlag11 equ 11
kFlag12 equ 12 ; set for idle1, idle2
kFlag13 equ 13
kFlagNotDebuggable equ 14 ; set for blue, idle1
kFlagBlue equ 15
kFlag16 equ 16
kFlag17 equ 17
kFlagPageFaulted equ 18
kFlag19 equ 19
kFlag20 equ 20
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, 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
kFlagAborted equ 30
kFlag31 equ 31
ds.l 1 ; 068
OwningProcessPtr ds.l 1 ; 06c
AddressSpacePtr ds.l 1 ; 070 ; borrowed from PROC argument to CreateTask
Name ds.l 1 ; 074 ; 'blue', creator of owning cooperative process, etc
CpuID ds.l 1 ; 078
ds.l 1 ; 07c
CreateTime3 ds.d 1 ; 080
ContextBlockPtr ds.l 1 ; 088 ; points internally by default, and to EDP.ECB in blue
VectorSaveArea ds.l 1 ; 08c
ds.l 1 ; 090
ds.l 1 ; 094
ds.l 1 ; 098
NotificationPtr ds.l 1 ; 09c
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
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
VecBase ds.l 1 ; 0f0
ExceptionHandlerID ds.l 1 ; 0f4 ; a queue
ErrToReturnIfIDie ds.l 1 ; 0f8
ds.l 1 ; 0fc
ContextBlock ds.b 768 ; 100:400 ; like the EDP's Emulator Context Block -- unsure of size
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 3: TIMER
; (size: 64b, thud command: id -tm)
;
; "Prev" is actually the next timer to fire!
;_______________________________________________________________________
Timer record 0,INCR
kIDClass equ 3
kFirstID equ 0x00030001
kSignature equ 'TIME'
;_______________________
; Fields
;_______________________
ID ds.l 1 ; 00 ; task+20
Signature ds.l 1 ; 04 ; task+24
QueueLLL ds.l 1 ; 08 ; task+28 ; overlaps with the below bytefields, as a union?
ds.l 1 ; 0c ; task+2c
ProcessID ds.l 1 ; 10 ; task+30
Kind ds.b 1 ; 14 ; task+34 ; InitTMRQs sets to 6, MPCall 55 to 1, MPCall 52 to 2
kKind1 equ 1
kKind2 equ 2
kKind3 equ 3
kKind4 equ 4
kKind5 equ 5
kKind6 equ 6
kKind7 equ 7
Byte1 ds.b 1 ; 15 ; task+35
KeepAfterFiring ds.b 1 ; 16 ; task+36 ; InitTMRQs sets to 1
Byte3 ds.b 1 ; 17 ; task+37 ; called_by_init_tmrqs sets to 1
MessageQueueID
ParentTaskPtr ds.l 1 ; 18 ; task+38 ; task to be unblocked when timer fires
ReservedMessage ds.l 1 ; 1c ; task+3c ; 'note' allocated when timer armed
Message1 ds.l 1 ; 20 ; task+40 ; if I hit a message queue
Message2 ds.l 1 ; 24 ; task+44
Message3 ds.l 1 ; 28 ; task+48
EventGroupID ds.l 1 ; 2c ; task+4c ; if I hit an event group
EventGroupFlags ds.l 1 ; 30 ; task+50
SemaphoreID ds.l 1 ; 34 ; task+54
Time ds.l 2 ; 38 ; task+58 ; set from first two args to MPCall 55
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 4: QUEUE
; (size: 52b, thud command: id -q)
;
;_______________________________________________________________________
Queue record 0,INCR
kIDClass equ 4
kFirstID equ 0x00040001
;_______________________
; Fields
;_______________________
BlockedTasks ds.l 4 ; 00:10 ; titled MSGQ ; waiting for messages
Messages ds.l 4 ; 10:20 ; titled NOTQ ; waiting for tasks
ProcessID ds.l 1 ; 20 ; why associate a queue with a process?
ReserveCount ds.l 1 ; 24 ; as number of messages, from MPSetQueueReserve
ReservePtr ds.l 1 ; 28 ; ptr to first element of
BlockedTaskCount ds.l 1 ; 2c
MessageCount ds.l 1 ; 30
Size equ *
endr
ReadyQueue record 0,INCR
LLL ds.l 4 ; 00:10 ; nothing fancy, freeform contains priority flag
Counter ds.l 1 ; 10 ; SchInit sets, SchRdyTaskLater bumps, major_0x13e4c decs
TotalWeight ds.l 1 ; 14 ; divide available time by these
Timecake ds.d 1 ; 18 ; period of ~1ms, 8ms, 64ms, 512ms
org 0x20
; Constants
kSignature equ 'RDYQ'
endr
Message record 0,INCR
kSignature equ 'note'
kReservedSignature equ 'notr'
LLL ds.l 4 ; 00:10 ; singly linked (next ptrs) only
Word1 ds.l 1 ; 10
Word2 ds.l 1 ; 14
Word3 ds.l 1 ; 18
Size equ *
endr
kTimerQueueSignature equ 'TMRQ'
kDelayQueueSignature equ 'DLYQ'
kDbugQueueSignature equ 'DBUG'
kPageQueueSignature equ 'PAGQ'
kNotQueueSignature equ 'NOTQ'
kSemaQueueSignature equ 'SEMQ'
;_______________________________________________________________________
; ID CLASS 5: SEMAPHORE
; (size: 32b, thud command: id -s)
;
;_______________________________________________________________________
Semaphore record 0,INCR
kIDClass equ 5
kFirstID equ 0x00050001
kSignature equ 'SEMA'
;_______________________
; Fields
;_______________________
BlockedTasks ds.l 4 ; 00:10 ; blocked tasks
Value ds.l 1 ; 10 ; negative if tasks are blocked???
MaxValue ds.l 1 ; 14
ProcessID ds.l 1 ; 18
BlockedTaskCount ds.l 1 ; 1c ; starts as 0
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 6: CRITICAL REGION
; (size: 36b, thud command: id -r)
;
;_______________________________________________________________________
CriticalRegion record 0,INCR
kIDClass equ 6
kFirstID equ 0x00060001
kSignature equ 'CRGN'
;_______________________
; Fields
;_______________________
LLL ds.l 4 ; 00:10
ProcessID ds.l 4 ; 10:20 ; lll.freeform is the field?
ds.l 1 ; 20
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 7: CPU
; (size: 32+800+128 = 960b, thud command: id -c)
;
;_______________________________________________________________________
CPU record 0,INCR
kIDClass equ 7
kFirstID equ 0x00070001
kSignature equ 'CPU '
;_______________________
; Fields
;_______________________
ID ds.l 1 ; 00
Signature ds.l 1 ; 04
LLL ds.l 4 ; 08:18 ; member of CGRP
Flags ds.l 1 ; 18 ; contains 0x0000000f ; cannot delete if this field & 9
IdleTaskPtr ds.l 1 ; 1c
EWABase ds.b 800 ; negative-indexed parts of EWA
EWA ds.b 128 ; positive-indexed parts of EWA
kFlag0 equ 0
kFlag1 equ 1
kFlag2 equ 2
kFlag3 equ 3
kFlag4 equ 4
kFlag5 equ 5
kFlag6 equ 6
kFlag7 equ 7
kFlag8 equ 8
kFlag9 equ 9
kFlag10 equ 10
kFlag11 equ 11
kFlag12 equ 12
kFlag13 equ 13
kFlag14 equ 14
kFlag15 equ 15
kFlag16 equ 16
kFlag17 equ 17
kFlag18 equ 18
kFlag19 equ 19
kFlag20 equ 20
kFlag21 equ 21
kFlag22 equ 22
kFlag23 equ 23
kFlag24 equ 24
kFlag25 equ 25
kFlag26 equ 26
kFlag27 equ 27
kFlagScheduled equ 28
kFlag29 equ 29
kFlag30 equ 30
kFlag31 equ 31
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 8: ADDRESS SPACE
; (size: 192b, thud command: id -sp)
;
;_______________________________________________________________________
AddressSpace record 0,INCR
kIDClass equ 8
kFirstID equ 0x00080001
kSignature equ 'SPAC'
;_______________________
; Fields
;_______________________
ID ds.l 1 ; 00
Signature ds.l 1 ; 04
Flags ds.l 1 ; 08
kFlag30 equ 30
TaskCount ds.l 1 ; 0c ; incremented by CreateTask
RsrvList ds.l 4 ; 10:20 ; LLL
AreaList ds.l 4 ; 20:30 ; LLL
SRs ds.l 16 ; 30:70 ; segment register values
ParentCoherenceSpecialPtr ds.l 1 ; 70 ; SpecialPtr of owning cgrp (in list owned by Cpu)
ProcessID ds.l 1 ; 74 ; ID of owning PROC
ds.l 1 ; 78
ds.l 1 ; 7c
BATs
BAT0U ds.l 1 ; 80
BAT0L ds.l 1 ; 84
BAT1U ds.l 1 ; 88
BAT1L ds.l 1 ; 8c
BAT2U ds.l 1 ; 90
BAT2L ds.l 1 ; 94
BAT3U ds.l 1 ; 98
BAT3L ds.l 1 ; 9c
ExtraBATs ; the flag that enables these is never set?
ExtraBAT0U ds.l 1 ; a0
ExtraBAT0L ds.l 1 ; a4
ExtraBAT1U ds.l 1 ; a8
ExtraBAT1L ds.l 1 ; ac
ExtraBAT2U ds.l 1 ; b0
ExtraBAT2L ds.l 1 ; b4
ExtraBAT3U ds.l 1 ; b8
ExtraBAT3L ds.l 1 ; bc
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 9: EVENT GROUP
; (size: 32b, thud command: id -e)
;
;_______________________________________________________________________
EventGroup record 0,INCR
kIDClass equ 9
kFirstID equ 0x00090001
kSignature equ 'EVNT'
;_______________________
; Fields
;_______________________
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 ; flag 27 (=16) means "is swi"
Counter ds.l 1 ; 1c
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 10: COHERENCE GROUP
; (size: 88b, thud command: id -cg)
;
;_______________________________________________________________________
CoherenceGroup record 0,INCR
kIDClass equ 10
kFirstID equ 0x000a0001
kSignature equ 'CGRP'
;_______________________
; Fields
;_______________________
CPUList ds.l 4 ; 00:10 ; CPUs on this "motherboard"
LLL ds.l 4 ; 10:20 ; member of global CGRP list
CpuCount ds.l 1 ; 20
ScheduledCpuCount ds.l 1 ; 24
LA_CpuPlugin ds.l 1 ; 28 ; page-aligned
PA_CpuPlugin ds.l 1 ; 2c ; page-aligned
CpuPluginSize ds.l 1 ; 30 ; page-aligned size
LA_CpuPluginDesc ds.l 1 ; 34 ; non-page-aligned ; [1c] = count, [20...] = entry table
PA_CpuPluginDesc ds.l 1 ; 38 ; non-page-aligned
PA_CpuPluginTOC ds.l 1 ; 3c ; "table of contents": a TVector pointer for each selector
PA_CpuPluginStackPtrs ds.l 1 ; 40 ; array of stack pointers (one per CPU)
CpuPluginSelectorCount ds.l 1 ; 44 ; max of 64
Incrementer ds.l 1 ; 48 ; number of NKCreateAddressSpaceSub calls % 1M
CpuPluginSpacePtr ds.l 1 ; 4c ; space that cpup runs in
ds.l 1 ; 50
ds.l 1 ; 54
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 11: AREA
; (size: 160b, thud command: id -a)
;
; A contiguous region of effective addresses with similar properties.
;_______________________________________________________________________
Area record 0,INCR
kIDClass equ 11
kFirstID equ 0x000b0001
kSignature equ 'AREA'
kPLEFlagIsInHTAB equ 20 ; bits 0-19 = HTAB offset if set, else physical page
kPLEFlagHasPhysPage equ 31
;_______________________
; Fields
;_______________________
ID ds.l 1 ; 00
Signature ds.l 1 ; 04
Flags ds.l 1 ; 08
kDontOwnPageMapArray equ 25
kPageMapArrayIs2D equ 26
kPageMapArrayInPool equ 27
kAliasFlag equ 28
kPrivilegedFlag equ 29
kFaultCtrArrayIs2D equ 30
kFaultCtrArrayInPool equ 31
ProcessID ds.l 1 ; 0c
AddressSpaceID ds.l 1 ; 10
ParentAreaID ds.l 1 ; 14 ; if alias
BackingProviderID ds.l 1 ; 18 ; notification ID
PTEConfig ds.l 1 ; 1c
FlagsAndMinAlign ds.l 1 ; 20 ; detailed description to come
LogicalBase ds.l 1 ; 24
LogicalEnd ds.l 1 ; 28 ; the last valid address in the area
Length ds.l 1 ; 2c ; in actual bytes!
LogicalSeparation ds.l 1 ; 30 ; min logical distance to any other area
Counter ds.l 1 ; 34
BytesMapped ds.l 1 ; 38 ; total size of pages actually mapped to me
FaultCtrArrayPtr ds.l 1 ; 3c ; in paged areas, tracks how many times pages are added to HTAB
PageMapArrayPtr ds.l 1 ; 40 ; in paged areas, stores PTE template for each page
AliasLLL ds.l 4 ; 44:54
LLL ds.l 4 ; 54:64 ; member of address space
ds.l 1 ; 64
PageSize ds.l 1 ; 68 ; always 4k, the size of a PPC page
AddressSpacePtr ds.l 1 ; 6c
ContigPTETemplate ds.l 1 ; 70 ; in contig areas, acts as PTE template for every page (whole Area is same page)
PagedPTETemplate ds.l 1 ; 74 ; when paged area is created this fills PageMapArray
AlignmentMask ds.l 1 ; 78 ; bit mask that LogicalBase is aligned to
DefaultAlignmentMask ds.l 1 ; 7c ; always 0xFFFFF000 (page alignment)
ds.l 1 ; 80
BackingProviderMisc ds.l 1 ; 84 ; seems to be arbitrary (third arg to MPSetAreaBackingProvider)
ds.l 1 ; 88
ds.l 1 ; 8c
FenceLLL ds.l 4 ; 90:a0 ; function unknown, id is 'fenc'
Size equ *
endr
; Page List Entry bits:
;_______________________________________________________________________
; ID CLASS 12: NOTIFICATION
; (size: 40b, thud command: id -n)
;
;_______________________________________________________________________
Notification record 0,INCR
kIDClass equ 12
kFirstID equ 0x000c0001
kSignature equ 'KNOT'
;_______________________
; Fields
;_______________________
TaskPtr ds.l 1 ; 00 ; (set on init)
Signature ds.l 1 ; 04 ; (set on init)
ProcessID ds.l 1 ; 08 ; (set on init)
QueueID ds.l 1 ; 0c ; message queue
MsgWord1 ds.l 1 ; 10
MsgWord2 ds.l 1 ; 14
MsgWord3 ds.l 1 ; 18
EventGroupID ds.l 1 ; 1c
EventFlags ds.l 1 ; 20
SemaphoreID ds.l 1 ; 24
Size equ *
endr
;_______________________________________________________________________
; ID CLASS 13: CONSOLE LOG
; (size: 16b, thud command: id -nc)
;
; Never seen one in the wild -- must have been in debug builds.
;_______________________________________________________________________
ConsoleLog record 0,INCR
kIDClass equ 13
kFirstID equ 0x000d0001
;_______________________
; Fields
;_______________________
ds.l 1 ; 00
ds.l 1 ; 04
ProcessID ds.l 1 ; 08
ds.l 1 ; 0c
Size equ *
endr

File diff suppressed because it is too large Load Diff

View File

@ -86,7 +86,7 @@ End
Echo ------------------------------
Echo "Running PPCLink..."
PPCLink -xm library -codestart 0 -warn -o "{DEST_X}" {LinkList}
PPCLink -xm library -dead off -codestart 0 -warn -o "{DEST_X}" {LinkList}
Echo "Dumping temp xcoff to DEST..."
"{CTOOL}" fromx "{DEST_X}" "{DEST}"

View File

@ -36,7 +36,7 @@ NKDir = :NanoKernel:
NKIncDir = :Internal:
NKBin = {ResultDir}NanoKernel.x
NKOpts =
#include "{NKDir}InnerMakeFile"
#include "{NKDir}NKMakeFile"

View File

@ -1,42 +0,0 @@
# I expect these variables to be set already:
# NKDir, NKIncDir, NKBin
NKFiles = ¶
{NKDir}NKInit.s ¶
{NKDir}NKReplacementInit.s ¶
{NKDir}NKBuiltinInit.s ¶
{NKDir}NKProcFlagsTbl.s ¶
{NKDir}NKProcInfoTbl.s ¶
{NKDir}NKInterrupts.s ¶
{NKDir}NKPaging.s ¶
{NKDir}NKTranslation.s ¶
{NKDir}NKVMCalls.s ¶
{NKDir}NKPowerCalls.s ¶
{NKDir}NKRTASCalls.s ¶
{NKDir}NKCache.s ¶
{NKDir}NKMPCalls.s ¶
{NKDir}NKSync.s ¶
{NKDir}NKTasks.s ¶
{NKDir}NKAddressSpaces.s ¶
{NKDir}NKPoolAllocator.s ¶
{NKDir}NKTimers.s ¶
{NKDir}NKScheduler.s ¶
{NKDir}NKIndex.s ¶
{NKDir}NKPrimaryIntHandlers.s ¶
{NKDir}NKConsoleLog.s ¶
{NKDir}NKSleep.s ¶
{NKDir}NKThud.s ¶
{NKDir}NKScreenConsole.s ¶
{NKDir}NKAdditions.s ¶
NKIncludes = ¶
{NKDir}NKMacros.s ¶
{NKDir}NKEquates.s ¶
{NKIncDir}InfoRecords.a ¶
{NKIncDir}EmulatorPublic.a ¶
{NKIncDir}NKPublic.a ¶
{NKIncDir}NKOpaque.a ¶
# We get warning 3202 from ALIGN directives -- kill it
{NKBin} Ä {NKDir}NanoKernel.s {NKFiles} {NKIncludes}
PPCAsm -o {Targ} -w 3202 -i {NKIncDir} -i "{AIncludes}" {NKDir}NanoKernel.s

101
NanoKernel/MRInterrupts.s Executable file
View File

@ -0,0 +1,101 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKExceptions
; Exception
; MRException
; NKMemory
; GetPhysical
; PutPTE
; NKSystemCrash
; SystemCrash
; EXPORTS:
; MRDataStorageInt (=> NKReset)
; MRMachineCheckInt (=> NKReset)
; Special MR registers to investigate: r19 (inst addr), r26 (error)
########################################################################
MRDataStorageInt ; Consult DSISR and the page table to decide what to do
mfdsisr r31 ; Check DSISR for simple HTAB miss
andis. r28, r31, 0xC030 ; (bits 0/1/10/11)
mfsprg r1, 1
mfdar r27
bne @possible_htab_miss
andis. r28, r31, 0x0800 ; Illegal data access (else crash!)
addi r29, r1, KDP.CurDBAT0
bnel GetPhysical ; Get LBAT or lower PTE
li r28, 0x43 ; Filter Writethru and Protection bits
and r28, r31, r28
cmpwi cr7, r28, 0x43
beql SystemCrash ; Not illegal data access => Crash
mfsprg r28, 2
mtlr r28
bne cr7, @access_exception ; Any filtered bit unset => Exception
mfsrr0 r28 ; Writethru and Protection bits set => ROM write nop
addi r28, r28, 4
lwz r26, KDP.NKInfo.QuietWriteCount(r1)
mtsrr0 r28
addi r26, r26, 1
stw r26, KDP.NKInfo.QuietWriteCount(r1)
@return
extrwi r26, r25, 8, 22 ; Signal to some MemRetry code?
rfi
@access_exception
andi. r28, r31, 3
li r8, ecDataSupAccessViolation
beq MRException
cmpwi r28, 3
li r8, ecDataWriteViolation
beq MRException ; Nobody allowed to write => Exception
li r8, ecDataSupWriteViolation
b MRException ; Supervisor allowed to write => Exception
@possible_htab_miss
andis. r28, r31, 0x8010 ; Check for DataAccess Interrupt or ec[io]wx
bne MRHardwareFault ; Either of those => big trouble
bl PutPTE ; HTAB miss => fill HTAB
mfsprg r28, 2 ; (restore lr)
mtlr r28
beq @return ; HTAB success => RFI
li r8, ecDataPageFault
blt MRException ; Fault => Exception
li r8, ecDataInvalidAddress
b MRException ; Bad address => Exception
MRMachineCheckInt ; Always gives HW fault
mfsprg r1, 1
lwz r27, KDP.HtabLastEA(r1)
subf r28, r19, r27 ; Delete last HTAB entry if suspicious
cmpwi r28, -16 ; (i.e. within 16b of MemRetried EA)
blt @no_htab_del
cmpwi r28, 16
bgt @no_htab_del
lwz r28, KDP.NKInfo.HashTableDeleteCount(r1)
lwz r29, KDP.ApproxCurrentPTEG(r1)
addi r28, r28, 1
stw r28, KDP.NKInfo.HashTableDeleteCount(r1)
li r28, 0
stw r28, 0(r29)
sync
tlbie r27
sync
@no_htab_del
MRHardwareFault ; Can come from a DSI or a Machine Check
cmplw r10, r19
li r8, ecDataHardwareFault
bne MRException
mtsprg 3, r24
lmw r14, KDP.r14(r1)
li r8, ecInstHardwareFault
b Exception

213
NanoKernel/MRMemtab.s Executable file
View File

@ -0,0 +1,213 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MRMemtabCode
; MRLoad1
; MRLoad11
; MRLoad12
; MRLoad121
; MRLoad122
; MRLoad1221
; MRLoad124
; MRLoad1241
; MRLoad14
; MRLoad141
; MRLoad142
; MRLoad1421
; MRLoad21
; MRLoad221
; MRLoad24
; MRLoad241
; MRLoad242
; MRLoad4
; MRLoad41
; MRLoad42
; MRLoad421
; MRLoad44
; MRLoad8
; MRStore1
; MRStore11
; MRStore12
; MRStore121
; MRStore122
; MRStore1221
; MRStore124
; MRStore1241
; MRStore14
; MRStore141
; MRStore142
; MRStore1421
; MRStore2
; MRStore21
; MRStore221
; MRStore24
; MRStore241
; MRStore242
; MRStore4
; MRStore41
; MRStore42
; MRStore421
; MRStore44
; MRStore8
; MROptabCode
; MRLoad2
; MRLoad22
; MRStore22
; EXPORTS:
; MRMemtab (=> MROptabCode, NKExceptions)
; Indexing this table:
; bits 0-23 MRCode
; bits 24-26 number of bytes to access minus one
; bit 27 one for load, zero for store
; bits 28-30 bottom three bits of adjusted EA
; bit 31 zero (entries are 2b)
; "adjusted EA": address of the byte immediately to the right of the "string"
; Interpreting this table:
; Entries refer to routines in MRMemtabCode, all
; of which eventually jump to MRDoSecondary.
########################################################################
MACRO
memtabRow &label
DC.W (&label-MRBase) - (*-MRMemtab)
ENDM
MRMemtab
memtabRow MRStore8 ; 8-byte stores
memtabRow MRStore1241 ; mod 1
memtabRow MRStore242 ; mod 2
memtabRow MRStore1421 ; mod 3
memtabRow MRStore44 ; mod 4
memtabRow MRStore1241 ; mod 5
memtabRow MRStore242 ; mod 6
memtabRow MRStore1421 ; mod 7
memtabRow MRLoad8 ; 8-byte loads
memtabRow MRLoad1241 ; mod 1
memtabRow MRLoad242 ; mod 2
memtabRow MRLoad1421 ; mod 3
memtabRow MRLoad44 ; mod 4
memtabRow MRLoad1241 ; mod 5
memtabRow MRLoad242 ; mod 6
memtabRow MRLoad1421 ; mod 7
memtabRow MRStore1 ; 1-byte stores
memtabRow MRStore1 ; mod 1
memtabRow MRStore1 ; mod 2
memtabRow MRStore1 ; mod 3
memtabRow MRStore1 ; mod 4
memtabRow MRStore1 ; mod 5
memtabRow MRStore1 ; mod 6
memtabRow MRStore1 ; mod 7
memtabRow MRLoad1 ; 1-byte loads
memtabRow MRLoad1 ; mod 1
memtabRow MRLoad1 ; mod 2
memtabRow MRLoad1 ; mod 3
memtabRow MRLoad1 ; mod 4
memtabRow MRLoad1 ; mod 5
memtabRow MRLoad1 ; mod 6
memtabRow MRLoad1 ; mod 7
memtabRow MRStore2 ; 2-byte stores
memtabRow MRStore11 ; mod 1
memtabRow MRStore2 ; mod 2
memtabRow MRStore11 ; mod 3
memtabRow MRStore2 ; mod 4
memtabRow MRStore11 ; mod 5
memtabRow MRStore2 ; mod 6
memtabRow MRStore11 ; mod 7
memtabRow MRLoad2 ; 2-byte loads
memtabRow MRLoad11 ; mod 1
memtabRow MRLoad2 ; mod 2
memtabRow MRLoad11 ; mod 3
memtabRow MRLoad2 ; mod 4
memtabRow MRLoad11 ; mod 5
memtabRow MRLoad2 ; mod 6
memtabRow MRLoad11 ; mod 7
memtabRow MRStore12 ; 3-byte stores
memtabRow MRStore21 ; mod 1
memtabRow MRStore12 ; mod 2
memtabRow MRStore21 ; mod 3
memtabRow MRStore12 ; mod 4
memtabRow MRStore21 ; mod 5
memtabRow MRStore12 ; mod 6
memtabRow MRStore21 ; mod 7
memtabRow MRLoad12 ; 3-byte loads
memtabRow MRLoad21 ; mod 1
memtabRow MRLoad12 ; mod 2
memtabRow MRLoad21 ; mod 3
memtabRow MRLoad12 ; mod 4
memtabRow MRLoad21 ; mod 5
memtabRow MRLoad12 ; mod 6
memtabRow MRLoad21 ; mod 7
memtabRow MRStore4 ; 4-byte stores
memtabRow MRStore121 ; mod 1
memtabRow MRStore22 ; mod 2
memtabRow MRStore121 ; mod 3
memtabRow MRStore4 ; mod 4
memtabRow MRStore121 ; mod 5
memtabRow MRStore22 ; mod 6
memtabRow MRStore121 ; mod 7
memtabRow MRLoad4 ; 4-byte loads
memtabRow MRLoad121 ; mod 1
memtabRow MRLoad22 ; mod 2
memtabRow MRLoad121 ; mod 3
memtabRow MRLoad4 ; mod 4
memtabRow MRLoad121 ; mod 5
memtabRow MRLoad22 ; mod 6
memtabRow MRLoad121 ; mod 7
memtabRow MRStore14 ; 5-byte stores
memtabRow MRStore41 ; mod 1
memtabRow MRStore122 ; mod 2
memtabRow MRStore221 ; mod 3
memtabRow MRStore14 ; mod 4
memtabRow MRStore41 ; mod 5
memtabRow MRStore122 ; mod 6
memtabRow MRStore221 ; mod 7
memtabRow MRLoad14 ; 5-byte loads
memtabRow MRLoad41 ; mod 1
memtabRow MRLoad122 ; mod 2
memtabRow MRLoad221 ; mod 3
memtabRow MRLoad14 ; mod 4
memtabRow MRLoad41 ; mod 5
memtabRow MRLoad122 ; mod 6
memtabRow MRLoad221 ; mod 7
memtabRow MRStore24 ; 6-byte stores
memtabRow MRStore141 ; mod 1
memtabRow MRStore42 ; mod 2
memtabRow MRStore1221 ; mod 3
memtabRow MRStore24 ; mod 4
memtabRow MRStore141 ; mod 5
memtabRow MRStore42 ; mod 6
memtabRow MRStore1221 ; mod 7
memtabRow MRLoad24 ; 6-byte loads
memtabRow MRLoad141 ; mod 1
memtabRow MRLoad42 ; mod 2
memtabRow MRLoad1221 ; mod 3
memtabRow MRLoad24 ; mod 4
memtabRow MRLoad141 ; mod 5
memtabRow MRLoad42 ; mod 6
memtabRow MRLoad1221 ; mod 7
memtabRow MRStore124 ; 7-byte stores
memtabRow MRStore241 ; mod 1
memtabRow MRStore142 ; mod 2
memtabRow MRStore421 ; mod 3
memtabRow MRStore124 ; mod 4
memtabRow MRStore241 ; mod 5
memtabRow MRStore142 ; mod 6
memtabRow MRStore421 ; mod 7
memtabRow MRLoad124 ; 7-byte loads
memtabRow MRLoad241 ; mod 1
memtabRow MRLoad142 ; mod 2
memtabRow MRLoad421 ; mod 3
memtabRow MRLoad124 ; mod 4
memtabRow MRLoad241 ; mod 5
memtabRow MRLoad142 ; mod 6
memtabRow MRLoad421 ; mod 7

331
NanoKernel/MRMemtabCode.s Executable file
View File

@ -0,0 +1,331 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptabCode
; MRDoSecondary
; MRLoad2
; MRLoad22
; MRStore22
; EXPORTS:
; MRLoad1 (=> MRMemtab)
; MRLoad11 (=> MRMemtab)
; MRLoad12 (=> MRMemtab)
; MRLoad121 (=> MRMemtab)
; MRLoad122 (=> MRMemtab)
; MRLoad1221 (=> MRMemtab)
; MRLoad124 (=> MRMemtab)
; MRLoad1241 (=> MRMemtab)
; MRLoad14 (=> MRMemtab)
; MRLoad141 (=> MRMemtab)
; MRLoad142 (=> MRMemtab)
; MRLoad1421 (=> MRMemtab)
; MRLoad21 (=> MRMemtab)
; MRLoad221 (=> MRMemtab)
; MRLoad24 (=> MRMemtab)
; MRLoad241 (=> MRMemtab)
; MRLoad242 (=> MRMemtab)
; MRLoad4 (=> MRMemtab)
; MRLoad41 (=> MRMemtab)
; MRLoad42 (=> MRMemtab)
; MRLoad421 (=> MRMemtab)
; MRLoad44 (=> MRMemtab)
; MRLoad8 (=> MRMemtab)
; MRStore1 (=> MRMemtab)
; MRStore11 (=> MRMemtab)
; MRStore12 (=> MRMemtab)
; MRStore121 (=> MRMemtab)
; MRStore122 (=> MRMemtab)
; MRStore1221 (=> MRMemtab)
; MRStore124 (=> MRMemtab)
; MRStore1241 (=> MRMemtab)
; MRStore14 (=> MRMemtab)
; MRStore141 (=> MRMemtab)
; MRStore142 (=> MRMemtab)
; MRStore1421 (=> MRMemtab)
; MRStore2 (=> MRMemtab)
; MRStore21 (=> MRMemtab)
; MRStore221 (=> MRMemtab)
; MRStore24 (=> MRMemtab)
; MRStore241 (=> MRMemtab)
; MRStore242 (=> MRMemtab)
; MRStore4 (=> MRMemtab)
; MRStore41 (=> MRMemtab)
; MRStore42 (=> MRMemtab)
; MRStore421 (=> MRMemtab)
; MRStore44 (=> MRMemtab)
; MRStore8 (=> MRMemtab)
; Each routine accepts:
; r17 = pretend inst with accessLen (range 1-8) in bits 27-30 (will be decremented)
; r19 = address of byte to the right of the string to be loaded/saved
; r23 as a scratch register
; r20/r21 = right-justified data (stores only)
; Before jumping to MRDoSecondary or one of the MRFast paths, each routine sets:
; r20/r21 = right-justified data (loads only)
; r17 has len field decremented
; r23 = junk, not to be trusted
########################################################################
MRLoad1241
lbz r23, -8(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 0
MRLoad241
lhz r23, -7(r19)
subi r17, r17, 4
insrwi r20, r23, 16, 8
b MRLoad41
MRLoad141
lbz r23, -6(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 16
MRLoad41
lwz r23, -5(r19)
subi r17, r17, 8
inslwi r20, r23, 8, 24
insrwi r21, r23, 24, 0
b MRLoad1
MRLoad1421
lbz r23, -8(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 0
MRLoad421
lwz r23, -7(r19)
subi r17, r17, 8
inslwi r20, r23, 24, 8
insrwi r21, r23, 8, 0
b MRLoad21
MRLoad1221
lbz r23, -6(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 16
MRLoad221
lhz r23, -5(r19)
subi r17, r17, 4
rlwimi r20, r23, 24, 24, 31
insrwi r21, r23, 8, 0
b MRLoad21
MRLoad121
lbz r23, -4(r19)
subi r17, r17, 2
insrwi r21, r23, 8, 0
MRLoad21
lhz r23, -3(r19)
subi r17, r17, 4
insrwi r21, r23, 16, 8
b MRLoad1
MRLoad11
lbz r23, -2(r19)
subi r17, r17, 2
insrwi r21, r23, 8, 16
MRLoad1
lbz r23, -1(r19)
insrwi r21, r23, 8, 24
b MRDoSecondary
MRLoad242
lhz r23, -8(r19)
subi r17, r17, 4
insrwi r20, r23, 16, 0
b MRLoad42
MRLoad142
lbz r23, -7(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 8
MRLoad42
lwz r23, -6(r19)
subi r17, r17, 8
inslwi r20, r23, 16, 16
insrwi r21, r23, 16, 0
b MRLoad2
MRLoad122
lbz r23, -5(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 24
b MRLoad22
MRLoad12
lbz r23, -3(r19)
subi r17, r17, 2
insrwi r21, r23, 8, 8
b MRLoad2
MRLoad44
lwz r20, -8(r19)
subi r17, r17, 8
lwz r21, -4(r19)
b MRDoSecondary
MRLoad124
lbz r23, -7(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 8
MRLoad24
lhz r23, -6(r19)
subi r17, r17, 4
insrwi r20, r23, 16, 16
lwz r21, -4(r19)
b MRDoSecondary
MRLoad14
lbz r23, -5(r19)
subi r17, r17, 2
insrwi r20, r23, 8, 24
MRLoad4
lwz r21, -4(r19)
b MRDoSecondary
MRLoad8
lwz r20, -8(r19)
lwz r21, -4(r19)
b MRDoSecondary
########################################################################
MRStore1241
srwi r23, r20, 24
stb r23, -8(r19)
subi r17, r17, 2
MRStore241
srwi r23, r20, 8
sth r23, -7(r19)
subi r17, r17, 4
b MRStore41
MRStore141
srwi r23, r20, 8
stb r23, -6(r19)
subi r17, r17, 2
MRStore41
srwi r23, r21, 8
insrwi r23, r20, 8, 0
stw r23, -5(r19)
subi r17, r17, 8
stb r21, -1(r19)
b MRDoSecondary
MRStore1421
srwi r23, r20, 24
stb r23, -8(r19)
subi r17, r17, 2
MRStore421
srwi r23, r21, 24
insrwi r23, r20, 24, 0
stw r23, -7(r19)
subi r17, r17, 8
b MRStore21
MRStore1221
srwi r23, r20, 8
stb r23, -6(r19)
subi r17, r17, 2
MRStore221
srwi r23, r21, 24
insrwi r23, r20, 8, 16
sth r23, -5(r19)
subi r17, r17, 4
b MRStore21
MRStore121
srwi r23, r21, 24
stb r23, -4(r19)
subi r17, r17, 2
MRStore21
srwi r23, r21, 8
sth r23, -3(r19)
subi r17, r17, 4
stb r21, -1(r19)
b MRDoSecondary
MRStore11
srwi r23, r21, 8
stb r23, -2(r19)
subi r17, r17, 2
MRStore1
stb r21, -1(r19)
b MRDoSecondary
MRStore242
srwi r23, r20, 16
sth r23, -8(r19)
subi r17, r17, 4
b MRStore42
MRStore142
srwi r23, r20, 16
stb r23, -7(r19)
subi r17, r17, 2
MRStore42
srwi r23, r21, 16
insrwi r23, r20, 16, 0
stw r23, -6(r19)
subi r17, r17, 8
sth r21, -2(r19)
b MRDoSecondary
MRStore122
stb r20, -5(r19)
subi r17, r17, 2
b MRStore22
MRStore12
srwi r23, r21, 16
stb r23, -3(r19)
subi r17, r17, 2
MRStore2
sth r21, -2(r19)
b MRDoSecondary
MRStore44
stw r20, -8(r19)
subi r17, r17, 8
stw r21, -4(r19)
b MRDoSecondary
MRStore124
srwi r23, r20, 16
stb r23, -7(r19)
subi r17, r17, 2
MRStore24
sth r20, -6(r19)
subi r17, r17, 4
stw r21, -4(r19)
b MRDoSecondary
MRStore14
stb r20, -5(r19)
subi r17, r17, 2
MRStore4
stw r21, -4(r19)
b MRDoSecondary
MRStore8
stw r20, -8(r19)
stw r21, -4(r19)
b MRDoSecondary

229
NanoKernel/MROptab.s Executable file
View File

@ -0,0 +1,229 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptabCode
; MRPriCrash
; MRPriDCBZ
; MRPriLSCBX
; MRPriLSWI
; MRPriLSWX
; MRPriPlainLoad
; MRPriPlainStore
; MRPriSTFDUx
; MRPriSTFDx
; MRPriSTFSUx
; MRPriSTFSx
; MRPriSTHBRX
; MRPriSTSWI
; MRPriSTSWX
; MRPriSTWBRX
; MRPriUpdLoad
; MRPriUpdStore
; MRSecDCBZ
; MRSecDone
; MRSecException
; MRSecException2
; MRSecLFDu
; MRSecLFSu
; MRSecLHBRX
; MRSecLMW
; MRSecLSCBX
; MRSecLSWix
; MRSecLWARX
; MRSecLWBRX
; MRSecLoad
; MRSecLoadExt
; MRSecRedoNoTrace
; MRSecSTMW
; MRSecSTWCX
; MRSecStrStore
; MRRestab
; MRResBlank
; MRResDCBZ
; MRResLBZux
; MRResLDARX
; MRResLDux
; MRResLFDux
; MRResLFSux
; MRResLHAux
; MRResLHBRX
; MRResLHZux
; MRResLMW
; MRResLSCBX
; MRResLSWix
; MRResLWARX
; MRResLWAux
; MRResLWBRX
; MRResLWZux
; MRResRedoNoTrace
; MRResST1ux
; MRResST2ux
; MRResST4ux
; MRResST8ux
; MRResSTDCX
; MRResSTMW
; MRResSTSWix
; MRResSTWCX
; MRResX1012
; MRResX884
; MRRestab
; EXPORTS:
; MROptabD (=> NKHotInts)
; MROptabX (=> NKHotInts)
########################################################################
MACRO
optabRow &myAccLen, &myLoadStore, &resLabel, &myFlags, &primLabel, &secLabel
_L set 1
_S set 0
DC.W (&myAccLen << 11) | (&myLoadStore << 10) | (((&resLabel - MRResTab) >> 1) << 4) | &myFlags
DC.B (&primLabel-MRBase) >> 2
DC.B (&secLabel-MRBase) >> 2
ENDM
; LEGEND .... access size (r17 bits 27-30) and 0=Store/1=Load (r17 bit 31)
; ................ MRRestab entry (r17 bits 0-5)
;
; . mrOpflag1 }
; . mrOpflag2 } cr3 flags
; . mrOpflag3 }
; . mrFlagDidLoad }
;
; primary routine secondary routine X-form extended opcode D-form opcode
; ................ ................ ....................... .................
MACRO
optabNone
optabRow 0,_L, MRResBlank, %0000, MRPriCrash, MRSecException ; defaults for blank rows
ENDM
MROptabX
optabRow 4,_L, MRResLWARX, %0000, MRPriPlainLoad, MRSecLWARX ; 00000(101)00=020=LWARX
optabRow 8,_L, MRResLDARX, %0000, MRPriCrash, MRSecException ; 00010(101)00=084=LDARX
optabNone ; 00100(101)00=148
optabNone ; 00110(101)00=212
optabNone ; 01000(101)00=276
optabNone ; 01010(101)00=340
optabNone ; 01100(101)00=404
optabNone ; 01110(101)00=468
optabNone ; 10000(101)00=532
optabNone ; 10010(101)00=596
optabNone ; 10100(101)00=660
optabNone ; 10110(101)00=724
optabRow 8,_L, MRResLDux, %0000, MRPriPlainLoad, MRSecLoad ; 11000(101)00=788
optabRow 4,_L, MRResLWAux, %0000, MRPriPlainLoad, MRSecLoad ; 11010(101)00=852
optabRow 8,_S, MRResST8ux, %0000, MRPriPlainStore, MRSecDone ; 11100(101)00=916
optabNone ; 11110(101)00=980
optabNone ; 00001(101)00=052
optabNone ; 00011(101)00=116
optabNone ; 00101(101)00=180
optabNone ; 00111(101)00=244
optabNone ; 01001(101)00=308
optabNone ; 01011(101)00=372
optabNone ; 01101(101)00=436
optabNone ; 01111(101)00=500
optabNone ; 10001(101)00=564
optabNone ; 10011(101)00=628
optabNone ; 10101(101)00=692
optabNone ; 10111(101)00=756
optabRow 8,_L, MRResLDux, %0000, MRPriUpdLoad, MRSecLoad ; 11001(101)00=820
optabRow 8,_L, MRResX884, %0011, MRPriCrash, MRSecException ; 11011(101)00=884
optabRow 8,_S, MRResST8ux, %0000, MRPriUpdStore, MRSecDone ; 11101(101)00=948
optabRow 8,_S, MRResX1012, %0010, MRPriCrash, MRSecException ; 11111(101)00=1012
optabRow 8,_L, MRResLDux, %0000, MRPriPlainLoad, MRSecLoad ; 00000(101)01=021=LDX
optabNone ; 00010(101)01=085
optabRow 8,_S, MRResST8ux, %0000, MRPriPlainStore, MRSecDone ; 00100(101)01=149=STDX
optabNone ; 00110(101)01=213
optabRow 4,_L, MRResLSCBX, %1011, MRPriLSCBX, MRSecLSCBX ; 01000(101)01=277=LSCBX (POWER)
optabRow 4,_L, MRResLWAux, %0000, MRPriPlainLoad, MRSecLoad ; 01010(101)01=341=LWAX
optabNone ; 01100(101)01=405
optabNone ; 01110(101)01=469
optabRow 4,_L, MRResLSWix, %1011, MRPriLSWX, MRSecLSWix ; 10000(101)01=533=LSWX
optabRow 4,_L, MRResLSWix, %1111, MRPriLSWI, MRSecLSWix ; 10010(101)01=597=LSWI
optabRow 4,_S, MRResSTSWix, %0010, MRPriSTSWX, MRSecStrStore ; 10100(101)01=661=STSWX
optabRow 4,_S, MRResSTSWix, %1110, MRPriSTSWI, MRSecStrStore ; 10110(101)01=725=STSWI
optabNone ; 11000(101)01=789
optabNone ; 11010(101)01=853
optabNone ; 11100(101)01=917
optabNone ; 11110(101)01=981
optabRow 8,_L, MRResLDux, %0000, MRPriUpdLoad, MRSecLoad ; 00001(101)01=053=LDUX
optabNone ; 00011(101)01=117
optabRow 8,_S, MRResST8ux, %0000, MRPriUpdStore, MRSecDone ; 00101(101)01=181=STDUX
optabNone ; 00111(101)01=245
optabNone ; 01001(101)01=309
optabRow 4,_L, MRResLWAux, %0000, MRPriUpdLoad, MRSecDone ; 01011(101)01=373=LWAUX
optabNone ; 01101(101)01=437
optabNone ; 01111(101)01=501
optabNone ; 10001(101)01=565
optabNone ; 10011(101)01=629
optabNone ; 10101(101)01=693
optabNone ; 10111(101)01=757
optabNone ; 11001(101)01=821
optabNone ; 11011(101)01=885
optabNone ; 11101(101)01=949
optabNone ; 11111(101)01=1013
optabNone ; 00000(101)10=022
optabRow 1,_L, MRResRedoNoTrace, %0010, MRPriUpdLoad, MRSecRedoNoTrace ; 00010(101)10=086
optabRow 4,_L, MRResSTWCX, %0000, MRPriPlainStore, MRSecSTWCX ; 00100(101)10=150=STWCX.
optabRow 8,_S, MRResSTDCX, %0000, MRPriCrash, MRSecException ; 00110(101)10=214=STDCX.
optabRow 1,_L, MRResRedoNoTrace, %0010, MRPriUpdLoad, MRSecRedoNoTrace ; 01000(101)10=278=DCBT
optabNone ; 01010(101)10=342
optabNone ; 01100(101)10=406
optabNone ; 01110(101)10=470
optabRow 4,_L, MRResLWBRX, %0010, MRPriUpdLoad, MRSecLWBRX ; 10000(101)10=534=LWBRX
optabNone ; 10010(101)10=598
optabRow 4,_S, MRResST4ux, %0000, MRPriSTWBRX, MRSecDone ; 10100(101)10=662=STWBRX
optabNone ; 10110(101)10=726
optabRow 2,_L, MRResLHBRX, %0010, MRPriUpdLoad, MRSecLHBRX ; 11000(101)10=790=LHBRX
optabNone ; 11010(101)10=854
optabRow 2,_S, MRResST2ux, %0000, MRPriSTHBRX, MRSecDone ; 11100(101)10=918=STHBRX
optabRow 1,_L, MRResRedoNoTrace, %0010, MRPriUpdLoad, MRSecRedoNoTrace ; 11110(101)10=982=ICBI
optabRow 1,_L, MRResRedoNoTrace, %0010, MRPriUpdLoad, MRSecRedoNoTrace ; 00001(101)10=054=DCBST
optabNone ; 00011(101)10=118
optabNone ; 00101(101)10=182
optabRow 1,_L, MRResRedoNoTrace, %0010, MRPriUpdLoad, MRSecRedoNoTrace ; 00111(101)10=246=DCBTST
optabRow 0,_L, MRResBlank, %0000, MRPriPlainLoad, MRSecException2 ; 01001(101)10=310=ECIWX
optabNone ; 01011(101)10=374
optabRow 0,_S, MRResBlank, %0000, MRPriPlainStore, MRSecException2 ; 01101(101)10=438=ECOWX
optabNone ; 01111(101)10=502
optabNone ; 10001(101)10=566
optabNone ; 10011(101)10=630
optabNone ; 10101(101)10=694
optabNone ; 10111(101)10=758
optabNone ; 11001(101)10=822
optabNone ; 11011(101)10=886
optabNone ; 11101(101)10=950
optabRow 8,_S, MRResDCBZ, %0010, MRPriDCBZ, MRSecDCBZ ; 11111(101)10=1014=DCBZ
MROptabD ; X-form opcodes ending with 0b11 correspond with D-form opcodes, so these tables can overlap
optabRow 4,_L, MRResLWZux, %0000, MRPriPlainLoad, MRSecLoad ; 00000(101)11=023=LWZX (1)00000=32=LWZ
optabRow 1,_L, MRResLBZux, %0000, MRPriPlainLoad, MRSecLoad ; 00010(101)11=087=LBZX (1)00010=34=LBZ
optabRow 4,_S, MRResST4ux, %0000, MRPriPlainStore, MRSecDone ; 00100(101)11=151=STWX (1)00100=36=STW
optabRow 1,_S, MRResST1ux, %0000, MRPriPlainStore, MRSecDone ; 00110(101)11=215=STBX (1)00110=38=STB
optabRow 2,_L, MRResLHZux, %0000, MRPriPlainLoad, MRSecLoad ; 01000(101)11=279=LHZX (1)01000=40=LHZ
optabRow 2,_L, MRResLHAux, %0000, MRPriPlainLoad, MRSecLoadExt ; 01010(101)11=343=LHAX (1)01010=42=LHA
optabRow 2,_S, MRResST2ux, %0000, MRPriPlainStore, MRSecDone ; 01100(101)11=407=STHX (1)01100=44=STH
optabRow 4,_L, MRResLMW, %0011, MRPriUpdLoad, MRSecLMW ; 01110(101)11=471 (1)01110=46=LMW
optabRow 4,_L, MRResLFSux, %0000, MRPriPlainLoad, MRSecLFSu ; 10000(101)11=535=LFSX (1)10000=48=LFS
optabRow 8,_L, MRResLFDux, %0000, MRPriPlainLoad, MRSecLFDu ; 10010(101)11=599=LFDX (1)10010=50=LFD
optabRow 4,_S, MRResST4ux, %0000, MRPriSTFSx, MRSecDone ; 10100(101)11=663=STFSX (1)10100=52=STFS
optabRow 8,_S, MRResST8ux, %0000, MRPriSTFDx, MRSecDone ; 10110(101)11=727=STFDX (1)10110=54=STFD
optabNone ; 11000(101)11=791 (1)11000=56
optabNone ; 11010(101)11=855 (1)11010=58
optabNone ; 11100(101)11=919 (1)11100=60
optabRow 4,_S, MRResST4ux, %0000, MRPriSTFDx, MRSecDone ; 11110(101)11=983=STFIWX (1)11110=62
optabRow 4,_L, MRResLWZux, %0000, MRPriUpdLoad, MRSecLoad ; 00001(101)11=055=LWZUX (1)00001=33=LWZU
optabRow 1,_L, MRResLBZux, %0000, MRPriUpdLoad, MRSecLoad ; 00011(101)11=119=LBZUX (1)00011=35=LBZU
optabRow 4,_S, MRResST4ux, %0000, MRPriUpdStore, MRSecDone ; 00101(101)11=183=STWUX (1)00101=37=STWU
optabRow 1,_S, MRResST1ux, %0000, MRPriUpdStore, MRSecDone ; 00111(101)11=247=STBUX (1)00111=39=STBU
optabRow 2,_L, MRResLHZux, %0000, MRPriUpdLoad, MRSecLoad ; 01001(101)11=311=LHZUX (1)01001=41=LHZU
optabRow 2,_L, MRResLHAux, %0000, MRPriUpdLoad, MRSecLoadExt ; 01011(101)11=375=LHAUX (1)01011=43=LHAU
optabRow 2,_S, MRResST2ux, %0000, MRPriUpdStore, MRSecDone ; 01101(101)11=439=STHUX (1)01101=45=STHU
optabRow 4,_S, MRResSTMW, %0010, MRPriUpdStore, MRSecSTMW ; 01111(101)11=503 (1)01111=47=STMW
optabRow 4,_L, MRResLFSux, %0000, MRPriUpdLoad, MRSecLFSu ; 10001(101)11=567=LFSUX (1)10001=49=LFSU
optabRow 8,_L, MRResLFDux, %0000, MRPriUpdLoad, MRSecLFDu ; 10011(101)11=631=LFDUX (1)10011=51=LFDU
optabRow 4,_S, MRResST4ux, %0000, MRPriSTFSUx, MRSecDone ; 10101(101)11=695=STFSUX (1)10101=53=STFSU
optabRow 8,_S, MRResST8ux, %0000, MRPriSTFDUx, MRSecDone ; 10111(101)11=759=STFDUX (1)10111=55=STFDU
optabNone ; 11001(101)11=823 (1)11001=57
optabNone ; 11011(101)11=887 (1)11011=59
optabNone ; 11101(101)11=951 (1)11101=61
optabNone ; 11111(101)11=1015 (1)11111=63

549
NanoKernel/MROptabCode.s Executable file
View File

@ -0,0 +1,549 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MRMemtab
; MRMemtab
; NKExceptions
; MRException
; NKFloatingPt
; LFDTable
; STFDTable
; NKSystemCrash
; SystemCrash
; EXPORTS:
; MRDoSecondary (=> MRMemtabCode, NKExceptions)
; MRDoneTableSTFD (=> NKFloatingPt)
; MRLoad2 (=> MRMemtab, MRMemtabCode)
; MRLoad22 (=> MRMemtab, MRMemtabCode)
; MRPriCrash (=> MROptab)
; MRPriDCBZ (=> MROptab)
; MRPriLSCBX (=> MROptab)
; MRPriLSWI (=> MROptab)
; MRPriLSWX (=> MROptab)
; MRPriPlainLoad (=> MROptab)
; MRPriPlainStore (=> MROptab)
; MRPriSTFDUx (=> MROptab)
; MRPriSTFDx (=> MROptab)
; MRPriSTFSUx (=> MROptab)
; MRPriSTFSx (=> MROptab)
; MRPriSTHBRX (=> MROptab)
; MRPriSTSWI (=> MROptab)
; MRPriSTSWX (=> MROptab)
; MRPriSTWBRX (=> MROptab)
; MRPriUpdLoad (=> MROptab)
; MRPriUpdStore (=> MROptab)
; MRSecDCBZ (=> MROptab, MRRestab)
; MRSecDone (=> MROptab, MRRestab, NKFloatingPt, NKSoftInts)
; MRSecException (=> MROptab, MRRestab)
; MRSecException2 (=> MROptab, MRRestab)
; MRSecLFDu (=> MROptab, MRRestab)
; MRSecLFSu (=> MROptab, MRRestab)
; MRSecLHBRX (=> MROptab, MRRestab)
; MRSecLMW (=> MROptab, MRRestab)
; MRSecLSCBX (=> MROptab, MRRestab)
; MRSecLSWix (=> MROptab, MRRestab)
; MRSecLWARX (=> MROptab, MRRestab)
; MRSecLWBRX (=> MROptab, MRRestab)
; MRSecLoad (=> MROptab, MRRestab)
; MRSecLoadExt (=> MROptab, MRRestab)
; MRSecRedoNoTrace (=> MROptab, MRRestab)
; MRSecSTMW (=> MROptab, MRRestab)
; MRSecSTWCX (=> MROptab, MRRestab)
; MRSecStrStore (=> MROptab, MRRestab)
; MRStore22 (=> MRMemtab, MRMemtabCode)
########################################################################
MRPriCrash
bl SystemCrash
MRSecException
b MRSecException2
########################################################################
MRPriSTFSx
rlwinm r17, r17, 0,16,10
MRPriSTFSUx
crclr cr7_so
b MRDoTableSTFD
MRPriSTFDx
rlwinm r17, r17, 0,16,10
MRPriSTFDUx
crset cr7_so
MRDoTableSTFD
; This table is of the form:
; stfd <reg>, KDP.FloatScratch(r1)
; b MRDoneTableSTFD
clrrwi r19, r25, 10
rlwimi r19, r17, 14,24,28
addi r19, r19, STFDTable-MRBase
mtlr r19
rlwimi r14, r11, 0,18,18
mtmsr r14
blr
MRDoneTableSTFD
ori r11, r11, 0x2000
lwz r20, KDP.FloatScratch(r1)
lwz r21, KDP.FloatScratch+4(r1)
bso cr7, MRPriUpdLoad
extrwi r23, r20, 11,1
cmpwi r23, 0x380
insrwi r20, r20, 27,2
inslwi r20, r21, 3,29
mr r21, r20
bgt MRPriUpdLoad
cmpwi r23, 0x36A
clrrwi r21, r20, 31
blt MRPriUpdLoad
oris r20, r20, 0x80
neg r23, r23
clrlwi r20, r20, 8
srw r20, r20, r23
rlwimi r21, r20, 31,9,31
b MRPriUpdLoad
########################################################################
MRPriSTWBRX
rlwinm r28, r17, 13,25,29
lwbrx r21, r1, r28
b MRPriPlainLoad
MRPriSTHBRX
rlwinm r28, r17, 13,25,29
addi r21, r1, 2
lhbrx r21, r21, r28
b MRPriPlainLoad
########################################################################
MRPriUpdStore
rlwinm r28, r17, 13,25,29
lwzx r21, r1, r28
b MRPriUpdLoad
MRPriPlainStore
rlwinm r28, r17, 13,25,29
lwzx r21, r1, r28
MRPriPlainLoad
rlwinm r17, r17, 0,16,10
MRPriUpdLoad
extrwi. r22, r17, 4,27
add r19, r18, r22
########################################################################
MRPriDone
clrrwi r25, r25, 10
insrwi r25, r19, 3,28
insrwi r25, r17, 4,24
lha r22, MRMemtab-MRBase(r25)
addi r23, r1, KDP.VecTblMemRetry
add r22, r22, r25
mtlr r22
mtsprg 3, r23
mtmsr r15
insrwi r25, r26, 8,22
bnelr
b MRDoSecondary
########################################################################
MRStore22 ; Fast return paths from MemAccess code
srwi r23, r21, 16
sth r23, -4(r19)
addi r17, r17, -4
sth r21, -2(r19)
b MRDoSecondary
MRLoad22
lhz r23, -4(r19)
addi r17, r17, -4
insrwi r21, r23, 16,0
MRLoad2
lhz r23, -2(r19)
insrwi r21, r23, 16,16
MRDoSecondary
sync
rlwinm. r28, r17, 18,25,29
mtlr r25
cror cr0_eq, cr0_eq, mrOpflag3
mtmsr r14
mtsprg 3, r24
beqlr
crset mrFlagDidLoad
stwx r18, r1, r28
blr
########################################################################
MRSecLoadExt
extsh r21, r21
MRSecLoad
rlwinm r28, r17, 13,25,29
crset mrFlagDidLoad
stwx r21, r1, r28
########################################################################
MRSecDone
andi. r23, r16, ContextFlagTraceWhenDone ; Time to return from interrupt
addi r10, r10, 4
mtsrr0 r10
mtsrr1 r11
bne @trace ; Is a Trace flagged?
mtlr r12
bc BO_IF_NOT, mrFlagDidLoad, @load_ewa_registers
mtcr r13
lmw r2, KDP.r2(r1)
lwz r0, KDP.r0(r1)
lwz r1, KDP.r1(r1)
rfi
@load_ewa_registers ; Only load changed registers
mtcr r13
lmw r10, KDP.r10(r1)
lwz r1, KDP.r1(r1)
rfi
@trace ; Jump to Trace int handler
mfsprg r24, 3
mtsprg 2, r12
_clear r16, r16, bitContextFlagTraceWhenDone
lwz r12, VecTbl.Trace(r24)
stw r16, KDP.Flags(r1)
mtcr r13
mtlr r12
lmw r2, KDP.r2(r1)
lwz r0, KDP.r0(r1)
lwz r1, KDP.r1(r1)
mtsprg 1, r1
blrl
########################################################################
MRSecLHBRX
slwi r21, r21, 16
MRSecLWBRX
rlwinm r28, r17, 13,25,29
crset mrFlagDidLoad
stwbrx r21, r1, r28
b MRSecDone
########################################################################
MRSecLFSu
clrrwi r20, r21, 31
xor. r21, r20, r21
beq MRSecLFDu
rlwinm. r23, r21, 16,17,24
addi r23, r23, 0x80
rlwimi r20, r21, 29,5,31
extsh r23, r23
rlwimi r20, r21, 0,1,1
slwi r21, r21, 29
addi r23, r23, -0x4080
rlwimi r20, r23, 0,2,4
bne MRSecLFDu
srwi r21, r21, 20
insrwi r21, r20, 20,0
cntlzw r23, r21
slw r21, r21, r23
neg r23, r23
rlwimi r20, r21, 21,12,31
addi r23, r23, 0x380
slwi r21, r21, 21
insrwi r20, r23, 11,1
MRSecLFDu
; This table is of the form:
; lfd <reg>, KDP.FloatScratch(r1)
; b MRSecDone
clrrwi r23, r25, 10
rlwimi r23, r17, 14,24,28
addi r23, r23, LFDTable-MRBase
mtlr r23
stw r20, KDP.FloatScratch(r1)
stw r21, KDP.FloatScratch+4(r1)
rlwimi r14, r11, 0,18,18
mtmsr r14
ori r11, r11, 0x2000
blr
########################################################################
MRSecLMW
rlwinm. r28, r17, 13,25,29
rlwinm r23, r17, 18,25,29
cmpw cr7, r28, r23
addis r17, r17, 0x20
beq loc_E68
beq cr7, loc_E6C
loc_E68
stwx r21, r1, r28
loc_E6C
cmpwi r28, 0x7C
li r22, 9
insrwi r17, r22, 6,26
addi r19, r19, 4
bne MRPriDone
b MRSecDone
MRSecSTMW
addis r17, r17, 0x20
rlwinm. r28, r17, 13,25,29
beq MRSecDone
lwzx r21, r1, r28
li r22, 8
insrwi r17, r22, 6,26
addi r19, r19, 4
b MRPriDone
########################################################################
MRPriDCBZ ; Zero four 8b chunks of the cache blk
clrrwi r19, r18, 5 ; r19 = address of chunk to zero
b MRComDCBZ ; (for use by this code only)
MRSecDCBZ
andi. r22, r19, 0x18
clrrwi r19, r19, 3 ; MemAccess code decrements this reg
beq MRSecDone ; Zeroed all foun chunks -> done!
MRComDCBZ
li r22, 0x10 ; Set 8 bytes (? set bit 27)
insrwi. r17, r22, 6,26
addi r19, r19, 8 ; Align ptr to right hand size of chunk
li r20, 0 ; Contents = zeros
li r21, 0
b MRPriDone ; Go, then come back to MRSecDCBZ
########################################################################
MRSecLWARX
rlwinm r28, r17, 13,25,29
crset mrFlagDidLoad
stwx r21, r1, r28
stwcx. r21, r1, r28
b MRSecDone
MRSecSTWCX
stwcx. r0, 0, r1
mfcr r23
rlwinm r23, r23, 0,3,1
rlwimi r13, r23, 0,0,3
b MRSecDone
########################################################################
MRSecRedoNoTrace ; Rerun the (cache) instruction, but not its Trace Exception
rlwinm r16, r16, 0, ~(ContextFlagTraceWhenDone | ContextFlagMemRetryErr)
subi r10, r10, 4
stw r16, KDP.Flags(r1)
b MRSecDone
########################################################################
MRSecException2
li r8, ecDataInvalidAddress
b MRException
########################################################################
MRPriSTSWI
addi r22, r27, -0x800
extrwi r22, r22, 5,16
b loc_F2C
MRPriSTSWX
mfxer r22
andi. r22, r22, 0x7F
addi r22, r22, -1
beq MRSecDone
loc_F2C
rlwimi r17, r22, 4,21,25
not r22, r22
insrwi r17, r22, 2,4
mr r19, r18
b loc_1008
MRSecStrStore
andi. r22, r17, 0x7C0
addis r28, r17, 0x20
rlwimi r17, r28, 0,6,10
addi r17, r17, -0x40
bne loc_1008
b MRSecDone
########################################################################
MRPriLSWI
addi r22, r27, -0x800
extrwi r22, r22, 5,16
addis r28, r27, 0x3E0
rlwimi r17, r28, 22,16,20
b loc_F80
MRPriLSWX
mfxer r22
andi. r22, r22, 0x7F
rlwimi r17, r27, 0,16,20
addi r22, r22, -1
beq MRSecDone
loc_F80
andis. r23, r17, 0x1F
rlwimi r17, r22, 4,21,25
not r22, r22
insrwi r17, r22, 2,4
mr r19, r18
bne loc_1070
rlwimi r17, r17, 5,11,15
b loc_1070
MRSecLSWix
andi. r22, r17, 0x7C0
rlwinm r28, r17, 13,25,29
bne loc_1044
rlwinm r22, r17, 9,27,28
slw r21, r21, r22
b loc_1044
########################################################################
MRPriLSCBX
mfxer r22
andi. r22, r22, 0x7F
rlwimi r17, r27, 0,16,20
insrwi r17, r27, 1,3
addi r22, r22, -1
beq MRSecDone
andis. r23, r17, 0x1F
rlwimi r17, r22, 4,21,25
not r22, r22
insrwi r17, r22, 2,4
mr r19, r18
bne loc_10C8
rlwimi r17, r17, 5,11,15
b loc_10C8
MRSecLSCBX
rlwinm. r22, r17, 28,25,29
rlwinm r28, r17, 13,25,29
bne loc_109C
rlwinm r23, r17, 9,27,28
slw r21, r21, r23
b loc_109C
########################################################################
loc_1008
andi. r23, r17, 0x7C0
rlwinm r28, r17, 13,25,29
lwzx r21, r1, r28
li r22, 8
insrwi r17, r22, 6,26
addi r19, r19, 4
bne MRPriDone
rlwinm r22, r17, 9,27,28
srw r21, r21, r22
extrwi r22, r17, 2,4
neg r22, r22
add r19, r19, r22
addi r22, r22, 4
insrwi. r17, r22, 5,26
b MRPriDone
loc_1044
rlwinm r23, r17, 18,25,29
cmpw cr7, r28, r23
rlwinm r23, r17, 23,25,29
cmpw cr6, r28, r23
beq cr7, loc_1060
beq cr6, loc_1060
stwx r21, r1, r28
loc_1060
addis r28, r17, 0x20
rlwimi r17, r28, 0,6,10
addi r17, r17, -0x40
beq MRSecDone
loc_1070
andi. r23, r17, 0x7C0
li r22, 9
insrwi r17, r22, 6,26
addi r19, r19, 4
bne MRPriDone
extrwi r22, r17, 2,4
neg r22, r22
add r19, r19, r22
addi r22, r22, 4
insrwi. r17, r22, 5,26
b MRPriDone
loc_109C
rlwinm r23, r17, 18,25,29
cmpw cr7, r28, r23
rlwinm r23, r17, 23,25,29
cmpw cr6, r28, r23
beq cr7, loc_10B8
beq cr6, loc_10B8
stwx r21, r1, r28
loc_10B8
addis r28, r17, 0x20
rlwimi r17, r28, 0,6,10
addi r17, r17, -0x40
beq MRSecDone
loc_10C8
not r22, r22
rlwimi r22, r17, 6,30,31
li r28, 1
mfxer r23
extrwi r23, r23, 8,16
srwi r20, r21, 24
cmpw cr7, r20, r23
add. r22, r22, r28
beq cr7, loc_112C
beq loc_112C
extrwi r20, r21, 8,8
cmpw cr7, r20, r23
add. r22, r22, r28
beq cr7, loc_112C
beq loc_112C
extrwi r20, r21, 8,16
cmpw cr7, r20, r23
add. r22, r22, r28
beq cr7, loc_112C
beq loc_112C
clrlwi r20, r21, 24
cmpw cr7, r20, r23
add. r22, r22, r28
beq cr7, loc_112C
bne loc_1070
loc_112C
rlwinm. r28, r17, 0,3,3
mfxer r23
add r22, r22, r23
insrwi r23, r22, 7,25
mtxer r23
beq MRSecDone
mfcr r23
clrlwi r23, r23, 30
insrwi r13, r23, 4,0
b MRSecDone

138
NanoKernel/MRRestab.s Executable file
View File

@ -0,0 +1,138 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptabCode
; MRSecDCBZ
; MRSecDone
; MRSecException
; MRSecException2
; MRSecLFDu
; MRSecLFSu
; MRSecLHBRX
; MRSecLMW
; MRSecLSCBX
; MRSecLSWix
; MRSecLWARX
; MRSecLWBRX
; MRSecLoad
; MRSecLoadExt
; MRSecRedoNoTrace
; MRSecSTMW
; MRSecSTWCX
; MRSecStrStore
; EXPORTS:
; MRResBlank (=> MROptab)
; MRResDCBZ (=> MROptab)
; MRResLBZux (=> MROptab)
; MRResLDARX (=> MROptab)
; MRResLDux (=> MROptab)
; MRResLFDux (=> MROptab)
; MRResLFSux (=> MROptab)
; MRResLHAux (=> MROptab)
; MRResLHBRX (=> MROptab)
; MRResLHZux (=> MROptab)
; MRResLMW (=> MROptab)
; MRResLSCBX (=> MROptab)
; MRResLSWix (=> MROptab)
; MRResLWARX (=> MROptab)
; MRResLWAux (=> MROptab)
; MRResLWBRX (=> MROptab)
; MRResLWZux (=> MROptab)
; MRResRedoNoTrace (=> MROptab)
; MRResST1ux (=> MROptab)
; MRResST2ux (=> MROptab)
; MRResST4ux (=> MROptab)
; MRResST8ux (=> MROptab)
; MRResSTDCX (=> MROptab)
; MRResSTMW (=> MROptab)
; MRResSTSWix (=> MROptab)
; MRResSTWCX (=> MROptab)
; MRResX1012 (=> MROptab)
; MRResX884 (=> MROptab)
; MRRestab (=> MROptab, NKExceptions)
########################################################################
MACRO
restabLine &myFlags, &secLabel
DC.B &myFlags
DC.B (&secLabel-MRBase) >> 2
ENDM
MRRestab
MRResLBZux restabLine %0001, MRSecLoad ; 0 ; LBZ(U)(X)
MRResLHZux restabLine %0001, MRSecLoad ; 1 ; LHZ(U)(X)
MRResLWZux restabLine %0001, MRSecLoad ; 2 ; LWZ(U)(X)
MRResLDux restabLine %0001, MRSecLoad ; 3 ; LD(U)X + X-788 + X-820
restabLine %0001, MRSecException ; 4
MRResLHAux restabLine %0001, MRSecLoadExt ; 5 ; LHA(U)(X)
MRResLWAux restabLine %0001, MRSecLoad ; 6 ; LWA(U)X
restabLine %0001, MRSecException ; 7
restabLine %0001, MRSecException ; 8
MRResLHBRX restabLine %0011, MRSecLHBRX ; 9 ; LHBRX
MRResLWBRX restabLine %0011, MRSecLWBRX ; 10 ; LWBRX
restabLine %0001, MRSecException ; 11
restabLine %0001, MRSecException ; 12
restabLine %0001, MRSecException ; 13
MRResLFSux restabLine %0001, MRSecLFSu ; 14 ; LFS(U)(X)
MRResLFDux restabLine %0001, MRSecLFDu ; 15 ; LFD(U)(X)
MRResST1ux restabLine %0001, MRSecDone ; 16 ; STB(U)(X)
MRResST2ux restabLine %0001, MRSecDone ; 17 ; STH(U)(X) + STHBRX
MRResST4ux restabLine %0001, MRSecDone ; 18 ; STW(U)(X) + STFS(U)(X) + STWBRX + STFIWX
MRResST8ux restabLine %0001, MRSecDone ; 19 ; STFD(U)(X) + STDUX
MRResLWARX restabLine %0001, MRSecLWARX ; 20 ; LWARX
MRResLDARX restabLine %0001, MRSecException ; 21 ; LDARX
MRResSTWCX restabLine %0001, MRSecSTWCX ; 22 ; STWCX.
MRResSTDCX restabLine %0001, MRSecException ; 23 ; STDCX.
restabLine %0001, MRSecException ; 24
restabLine %0001, MRSecException ; 25
MRResLMW restabLine %0011, MRSecLMW ; 26 ; LMW
MRResX884 restabLine %0011, MRSecException ; 27 ; X-884
restabLine %0001, MRSecException ; 28
restabLine %0001, MRSecException ; 29
MRResSTMW restabLine %0011, MRSecSTMW ; 30 ; STMW
MRResX1012 restabLine %0011, MRSecException ; 31 ; -1012
MRResLSWix restabLine %0011, MRSecLSWix ; 32 ; LSW(I|X)
restabLine %0011, MRSecLSWix ; 33
restabLine %0011, MRSecLSWix ; 34
restabLine %0011, MRSecLSWix ; 35
MRResSTSWix restabLine %0011, MRSecStrStore ; 36 ; STSW(I|X)
restabLine %0011, MRSecStrStore ; 37
restabLine %0011, MRSecStrStore ; 38
restabLine %0011, MRSecStrStore ; 39
MRResLSCBX restabLine %0011, MRSecLSCBX ; 40 ; LSCBX
restabLine %0011, MRSecLSCBX ; 41
restabLine %0011, MRSecLSCBX ; 42
restabLine %0011, MRSecLSCBX ; 43
restabLine %0011, MRSecLSCBX ; 44
restabLine %0011, MRSecLSCBX ; 45
restabLine %0011, MRSecLSCBX ; 46
restabLine %0011, MRSecLSCBX ; 47
MRResDCBZ restabLine %0011, MRSecDCBZ ; 48 ; DCBZ
restabLine %0001, MRSecException ; 49
restabLine %0001, MRSecException ; 50
restabLine %0001, MRSecException ; 51
restabLine %0001, MRSecException ; 52 ; A little birdie told me these will change in later versions
restabLine %0001, MRSecException ; 53
restabLine %0001, MRSecException ; 54
restabLine %0001, MRSecException ; 55
restabLine %0001, MRSecException ; 56
restabLine %0001, MRSecException ; 57
restabLine %0001, MRSecException ; 58
restabLine %0001, MRSecException ; 59
restabLine %0001, MRSecException ; 60
restabLine %0001, MRSecException ; 61
MRResRedoNoTrace restabLine %0011, MRSecRedoNoTrace ; 62 ; DCBT + ICBI + DCBST + DCBTST + X-86
MRResBlank restabLine %0001, MRSecException2 ; 63

View File

@ -1,9 +0,0 @@
# Lets you just run Make in this directory,
# while ignoring the rest of the build system
NKDir = :
NKIncDir = {NKDir}:Internal:
NKBin = {NKDir}NanoKernel.s.x
NKOpts =
#include "{NKDir}InnerMakeFile"

View File

@ -1,61 +0,0 @@
;_______________________________________________________________________
; My additions to the NanoKernel, to go at the end of the code image
;_______________________________________________________________________
if &TYPE('NKDebugShim') != 'UNDEFINED'
DeclareMPCall 200, NKDebug
NKDebug
; Lifted from NKxprintf:
; Put the physical address of the r3 arg in r8
rlwinm. r9, r11, 0, MSR_DRbit, MSR_DRbit ; IntSyscall sets this
mr r8, r3
beq @already_physical
li r9, 0
bl SpaceL2PUsingBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17
beq @fail
rlwimi r8, r17, 0, 0, 19
@already_physical
; Copy the command into the KDP buffer reserved for this purpose:
; r8 = src
; r29 = dest
; r30 = ctr
; r31 = val
mfsprg r1, 0
lwz r1, EWA.PA_KDP(r1)
li r30, 0
addi r29, r1, PSA.ThudBuffer
@cmdloop
lbzx r31, r8, r30
stbx r31, r29, r30
addi r30, r30, 1
cmpwi r31, 0
bne @cmdloop
lwz r31, PSA._404(r1)
stw r8, PSA._404(r1)
bl panic
lwz r8, PSA._404(r1)
li r0, 0
stw r0, 0(r8)
stw r31, PSA._404(r1)
b ReturnZeroFromMPCall
@fail
b ReturnMPCallOOM
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,538 +0,0 @@
###### ### ###### ## ## ######## ###### ### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ######### ###### ## ## ## ## ##
## ######### ## ## ## ## ## ######### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
###### ## ## ###### ## ## ######## ###### ## ## ######## ########
; 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
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKInterrupts
; IntReturn
; EXPORTS:
; FlushCaches (=> NKPowerCalls)
; FlushL1CacheUsingMSSCR0 (=> NKInterrupts)
; kcCacheDispatch (=> NKInit)
; 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

59
NanoKernel/NKColdInts.s Executable file
View File

@ -0,0 +1,59 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKExceptions
; Exception
; LoadInterruptRegisters
; ReturnFromInt
; NKMemory
; PutPTE
; EXPORTS:
; InstStorageInt (=> NKReset)
; MachineCheckInt (=> NKReset)
########################################################################
InstStorageInt
bl LoadInterruptRegisters
andis. r8, r11, 0x4020 ; Not in HTAB || Bad seg reg
beq @already_in_htab
stmw r14, KDP.r14(r1)
mr r27, r10
bl PutPTE
bne @illegal_address ; Could not find in SegMap
mfsprg r24, 3
mfmsr r14
_set r15, r14, bitMsrDR
addi r23, r1, KDP.VecTblMemRetry
mtsprg 3, r23
mr r19, r10
mtmsr r15
lbz r23, 0(r19)
sync
mtmsr r14
mtsprg 3, r24
lmw r14, KDP.r14(r1)
b ReturnFromInt
@illegal_address
lmw r14, KDP.r14(r1)
li r8, ecInstPageFault
blt Exception
li r8, ecInstInvalidAddress
b Exception
@already_in_htab
andis. r8, r11, 0x800 ; Illegal access to legal EA?
li r8, ecInstSupAccessViolation
bne Exception
li r8, ecInstHardwareFault
b Exception
########################################################################
MachineCheckInt
bl LoadInterruptRegisters
li r8, ecMachineCheck
b Exception

View File

@ -1,662 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKScreenConsole
; ScreenConsole_putchar
; ScreenConsole_redraw
; EXPORTS:
; getchar (=> NKThud, NKTimers)
; print_unknown (=> NKThud)
; printb (=> NKInit, NKMPCalls, NKTimers)
; printc (=> NKInit, NKPoolAllocator, NKThud)
; printd (=> NKInit, NKMPCalls, NKPoolAllocator, NKTimers)
; printh (=> NKBuiltinInit, NKMPCalls, NKReplacementInit, NKScheduler, NKThud, NKTimers)
; prints (=> NKMPCalls, NKThud)
; printw (=> NKAddressSpaces, NKInit, NKInterrupts, NKMPCalls, NKPaging, NKPoolAllocator, NKReplacementInit, NKScheduler, NKThud, NKTimers, NKVMCalls)
; prints
; _log null-terminated string with a few special escapes.
; Not done figuring this out, with the serial and stuff.
prints ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
lwz r1, -0x0004(r1)
lwz r28, PSA.NoIdeaR23(r1)
lwz r29, 0x0edc(r1)
_Lock PSA.DbugLock, scratch1=r30, scratch2=r31
cmpwi cr7, r28, 0x00
andi. r29, r29, 0x02
beq cr7, prints_skip_serial
crmove 30, 2
beq PrintS_skip_serial
mfmsr r31
bl serial_io
bl serial_flush
prints_skip_serial
addi r8, r8, -0x01
prints_next_char
bl serial_busywait
lbzu r29, 0x0001(r8)
cmpwi r29, 0x00
beq print_common
cmpwi r29, 10
beq PrintS_newline
cmpwi r29, 13
beq PrintS_newline
cmpwi r29, '\\'
beq PrintS_escape_code
cmpwi r29, '^'
bne PrintS_normal_char
prints_escape_code
lbzu r29, 0x0001(r8)
cmpwi r29, 'n'
beq PrintS_newline
cmpwi r29, 'r'
beq PrintS_newline
cmpwi r29, 'b'
bne PrintS_literal_backslash_or_caret
li r29, 0x07
b PrintS_normal_char
prints_literal_backslash_or_caret
lbzu r29, -0x0001(r8)
addi r8, r8, 0x01
prints_normal_char
mr r24, r29
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, prints_0xe4
ori r30, r31, 0x10
mtmsr r30
isync
stb r24, 0x0006(r28)
eieio
mtmsr r31
isync
prints_0xe4
b PrintS_next_char
prints_newline
li r29, 0x0d
; r1 = kdp
bl ScreenConsole_putchar
li r29, 0x0a
; r1 = kdp
bl ScreenConsole_putchar
; r1 = kdp
bl ScreenConsole_redraw
beq cr7, prints_0x13c
ori r30, r31, 0x10
mtmsr r30
isync
li r29, 0x0d
stb r29, 0x0006(r28)
eieio
prints_0x118
lbz r29, 0x0002(r28)
eieio
andi. r29, r29, 0x04
beq PrintS_0x118
li r29, 0x0a
stb r29, 0x0006(r28)
eieio
mtmsr r31
isync
prints_0x13c
b PrintS_next_char
print_common ; OUTSIDE REFERER
beq cr7, print_common_0x8c
mtmsr r31
isync
lwz r29, PSA.DecClockRateHzCopy(r1)
srwi r29, r29, 8
mfspr r30, dec
subf r29, r29, r30
ori r30, r31, 0x10
mtmsr r30
isync
print_common_0x28
mfspr r30, dec
subf. r30, r29, r30
ble print_common_0x50
li r30, 0x01
stb r30, 0x0002(r28)
eieio
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x01
beq print_common_0x28
print_common_0x50
sync
mtmsr r31
isync
mfspr r30, pvr
rlwinm. r30, r30, 0, 0, 14
li r31, 0x00
beq print_common_0x78
mtspr dbat3u, r31
mtspr dbat3l, r31
b print_common_0x80
print_common_0x78
mtspr ibat3l, r31
mtspr ibat3u, r31
print_common_0x80
isync
mtspr srr0, r26
mtspr srr1, r27
print_common_0x8c
_AssertAndRelease PSA.DbugLock, scratch=r30
; print_return
; Restores registers from EWA and returns.
print_return ; OUTSIDE REFERER
mfsprg r1, 0
lwz r24, -0x0110(r1)
lwz r25, -0x010c(r1)
mtlr r24
mtcr r25
lmw r24, -0x0108(r1)
lwz r1, -0x0004(r1)
blr
; printd
; _log decimal
printd ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
lwz r1, -0x0004(r1)
lwz r28, PSA.NoIdeaR23(r1)
lwz r29, 0x0edc(r1)
_Lock PSA.DbugLock, scratch1=r30, scratch2=r31
cmpwi cr7, r28, 0x00
andi. r29, r29, 0x02
beq cr7, printd_0x58
crmove 30, 2
beq Printd_0x58
bl serial_io
bl serial_flush
printd_0x58
cmpwi r8, 0x00
li r25, 0x2d
blt Printd_0x9c
printd_0x64
mr. r24, r8
li r25, 0x30
beq Printd_0x9c
lis r24, 0x3b9a
ori r24, r24, 0xca00
printd_0x78
divw. r25, r8, r24
bne Printd_0x8c
li r25, 0x0a
divw r24, r24, r25
b Printd_0x78
printd_0x8c
divw r29, r8, r24
addi r25, r29, 0x30
mullw r29, r29, r24
subf r8, r29, r8
printd_0x9c
bl serial_busywait
mr r29, r25
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, printd_0xc8
ori r30, r31, 0x10
mtmsr r30
isync
stb r25, 0x0006(r28)
eieio
mtmsr r31
isync
printd_0xc8
cmpwi r8, 0x00
bge Printd_0xd8
neg r8, r8
b Printd_0x64
printd_0xd8
li r25, 0x0a
divw. r24, r24, r25
bne Printd_0x8c
li r29, 0x20
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, printd_0x120
ori r30, r31, 0x10
mtmsr r30
isync
printd_0xfc
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x04
beq Printd_0xfc
li r29, 0x20
stb r29, 0x0006(r28)
eieio
mtmsr r31
isync
printd_0x120
b print_common
; printw
; _log word (hex) then a space
printw ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
li r24, 0x08
crset cr6_eq
b print_digity_common
; printh
; _log halfword (hex) then a space
printh ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
li r24, 0x04
rotlwi r8, r8, 0x10
crset cr6_eq
b print_digity_common
; printb
; _log byte (hex) then a space
printb ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
li r24, 0x02
rotlwi r8, r8, 0x18
crset cr6_eq
b print_digity_common
print_unknown ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
li r24, 0x02
rotlwi r8, r8, 0x18
crclr cr6_eq
b print_digity_common
print_digity_common ; OUTSIDE REFERER
lwz r1, -0x0004(r1)
lwz r28, PSA.NoIdeaR23(r1)
lwz r29, 0x0edc(r1)
_Lock PSA.DbugLock, scratch1=r30, scratch2=r31
cmpwi cr7, r28, 0x00
andi. r29, r29, 0x02
beq cr7, print_digity_common_0x40
crmove 30, 2
beq print_digity_common_0x40
bl serial_io
bl serial_flush
print_digity_common_0x40
bl serial_busywait
li r25, 0x30
rlwimi r25, r8, 4, 28, 31
rotlwi r8, r8, 0x04
cmpwi r25, 0x39
ble print_digity_common_0x5c
addi r25, r25, 0x27
print_digity_common_0x5c
mr r29, r25
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, print_digity_common_0x84
ori r30, r31, 0x10
mtmsr r30
isync
stb r25, 0x0006(r28)
eieio
mtmsr r31
isync
print_digity_common_0x84
addi r24, r24, -0x01
mr. r24, r24
bne print_digity_common_0x40
bne cr6, print_digity_common_0xd0
li r29, 0x20
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, print_digity_common_0xd0
ori r30, r31, 0x10
mtmsr r30
isync
print_digity_common_0xac
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x04
beq print_digity_common_0xac
li r29, 0x20
stb r29, 0x0006(r28)
eieio
mtmsr r31
isync
print_digity_common_0xd0
b print_common
getchar ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
lwz r1, EWA.PA_KDP(r1)
lwz r28, PSA.NoIdeaR23(r1)
cmpwi cr7, r28, 0x00
li r8, -0x01
beq cr7, print_return
_Lock PSA.DbugLock, scratch1=r30, scratch2=r31
bl serial_io
ori r30, r31, 0x10
mtmsr r30
isync
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x01
beq print_common
lbz r8, 0x0006(r28)
b print_common
; printc
; _log char
printc ; OUTSIDE REFERER
mfsprg r1, 0
stmw r24, -0x0108(r1)
mflr r24
mfcr r25
stw r24, -0x0110(r1)
stw r25, -0x010c(r1)
lwz r1, -0x0004(r1)
lwz r28, PSA.NoIdeaR23(r1)
lwz r29, 0x0edc(r1)
_Lock PSA.DbugLock, scratch1=r30, scratch2=r31
cmpwi cr7, r28, 0x00
andi. r29, r29, 0x02
beq cr7, printc_0x58
crmove 30, 2
beq Printc_0x58
bl serial_io
bl serial_flush
printc_0x58
mr r29, r8
; r1 = kdp
bl ScreenConsole_putchar
beq cr7, printc_0x90
ori r30, r31, 0x10
mtmsr r30
isync
printc_0x70
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x04
beq Printc_0x70
stb r8, 0x0006(r28)
eieio
mtmsr r31
isync
printc_0x90
b print_common
; serial_flush
; This and the following func are a bit speculative, but
; whatever.
; Whoa. Turns on data but not code paging. Crikey.
serial_flush ; OUTSIDE REFERER
ori r30, r31, MSR_DR
mtmsr r30
isync
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x09
stb r29, 0x0002(r28);set register pointer to 9 (next write goes to WR9)
eieio
li r29, 0x80;load code for channel A (also disables interrupts)
stb r29, 0x0002(r28);reset channel A
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x04
stb r29, 0x0002(r28);set register pointer to 4 (next write goes to WR4)
eieio
li r29, 0x48;X16 clock, 8-bit sync, 1.5 stop bits, parity off
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x03
stb r29, 0x0002(r28);set reg pointer to 3 (next write to WR3)
eieio
li r29, 0xc0;recieve 8 bits per character (but recieve off)
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x05
stb r29, 0x0002(r28);set reg pointer to 5 (next write to WR5)
eieio
li r29, 0x60;transmit 8 bits per char (but transmit off)
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x09
stb r29, 0x0002(r28);set reg pointer to 9 (next write to WR9)
eieio
li r29, 0x00
stb r29, 0x0002(r28);stop channel A reset?
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x0a
stb r29, 0x0002(r28);set reg pointer to 10 (next write to WR10)
eieio
li r29, 0x00;8-bit sync, NRZ encoding
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x0b
stb r29, 0x0002(r28);set reg pointer to 11 (next write to WR11)
eieio
li r29, 0x50;rx and tx using BR Generator
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x0c
stb r29, 0x0002(r28);set reg pointer to 12 (next write to WR12)
eieio
li r29, 0x00;0 time constant low byte
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x0d
stb r29, 0x0002(r28);set reg pointer to 13 (next write to WR13)
eieio
li r29, 0x00;0 time constant high byte
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x0e
stb r29, 0x0002(r28);set reg pointer to 14 (next write to WR14)
eieio
li r29, 0x01;enable Baud Rate generator
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x03
stb r29, 0x0002(r28);set reg pointer to 3 (next write to WR3)
eieio
li r29, 0xc1;enable reciever
stb r29, 0x0002(r28)
eieio
lbz r29, 0x0002(r28);make sure next write goes to command register
li r29, 0x05
stb r29, 0x0002(r28);set reg pointer to 5 (next write to WR5)
eieio
li r29, 0xea;assert DTR and RTS, set 8 bit characters, and enable transmitter
stb r29, 0x0002(r28)
eieio
mtmsr r31 ;restore previous MSR
isync
blr
; serial_io
;appears to set BAT 3 so the scc can be accessed from logical memory space.
serial_io ; OUTSIDE REFERER
mfspr r26, srr0
mfspr r27, srr1
isync
mfspr r30, pvr
rlwinm. r30, r30, 0, 0, 14
rlwinm r29, r28, 0, 0, 14
beq serial_io_0x38
li r30, 0x03
or r30, r30, r29
li r31, 0x3a
or r31, r31, r29
mtspr dbat3l, r31
mtspr dbat3u, r30
b serial_io_0x50
serial_io_0x38
li r30, 0x32
or r30, r30, r29
li r31, 0x40
or r31, r31, r29
mtspr ibat3u, r30
mtspr ibat3l, r31
serial_io_0x50
isync
mfmsr r31
blr
; serial_busywait
; See disclaimer above.
serial_busywait ; OUTSIDE
beqlr cr7
ori r30, r31, 0x10
mtmsr r30
isync
serial_busywait_0x10
lbz r30, 0x0002(r28)
eieio
andi. r30, r30, 0x04
beq serial_busywait_0x10
mtmsr r31
isync
blr

View File

@ -1,69 +1,138 @@
;_______________________________________________________________________
; Equates for the whole NanoKernel
; Equates for the whole NanoKernel
;_______________________________________________________________________
kNanoKernelVersion equ $0228
; PowerPC Machine Status Register (MSR) bits
; (borrowing the _bitEqu macro from NKInfoRecordsPriv.s)
_bitEqu MSR_POW, 13
_bitEqu MSR_ILE, 15
_bitEqu MSR_EE, 16
_bitEqu MSR_PR, 17
_bitEqu MSR_FP, 18
_bitEqu MSR_ME, 19
_bitEqu MSR_FE0, 20
_bitEqu MSR_SE, 21
_bitEqu MSR_BE, 22
_bitEqu MSR_FE1, 23
_bitEqu MSR_IP, 25
_bitEqu MSR_IR, 26
_bitEqu MSR_DR, 27
_bitEqu MSR_RI, 30
_bitEqu MSR_LE, 31
; Special Purpose Registers (SPRs) not understood by MPW
l2cr equ 1017
; Alignment for NanoKernel interrupt routines (mostly Interrupts.s)
kIntAlign equ 5
; Helps with making equates
; X = 0x00008000, Xbit=16, Xshift=15
macro
_bitEqu &bit, &name
&name equ 1 << (31-&bit)
bit&name equ &bit
shift&name equ 31 - &bit
endm
; Junk
kNanoKernelVersion equ $0101
; IRP is 10 pages below KDP (measured start to start)
; This should be neatened up to describe the kernel global area
IRPOffset equ (-10) * 4096
kKDPfromIRP equ 10 * 4096
kPoolOffsetFromGlobals equ (-7) * 4096 ; goes all the way up to 24 bytes short of PSA
; PowerPC Machine Status Register (MSR) bits
; (borrowing the _bitEqu macro from NKInfoRecordsPriv.s)
_bitEqu 13, MsrPOW
_bitEqu 15, MsrILE
_bitEqu 16, MsrEE
_bitEqu 17, MsrPR
_bitEqu 18, MsrFP
_bitEqu 19, MsrME
_bitEqu 20, MsrFE0
_bitEqu 21, MsrSE
_bitEqu 22, MsrBE
_bitEqu 23, MsrFE1
_bitEqu 25, MsrIP
_bitEqu 26, MsrIR
_bitEqu 27, MsrDR
_bitEqu 30, MsrRI
_bitEqu 31, MsrLE
; Special Purpose Registers (SPRs) not understood by MPW
l2cr equ 1017
; Alignment for NanoKernel interrupt routines (mostly Interrupts.s)
kIntAlign equ 5
; Branch instruction BO fields
; (disregarding static prediction :)
BO_IF equ 12
BO_IF_NOT equ 4
Z equ 0x80000000
; Junk
; SIGP (SIGnal Plugin) selectors used by the kernel:
kStartProcessor equ 1 ; r4 = target CPU idx, r5 = cpu's entry point, r6 = entry point's r3 (CPU struct ptr)
kStopProcessor equ 3 ; r4 = target CPU idx
kResetProcessor equ 4 ; r4 = target CPU idx
kAlert equ 5 ; r4 = target CPU idx? ; my name, has something to do with timers
kSIGP6 equ 6 ; r4 = target CPU idx?
kSIGP7 equ 7 ; r4 = target CPU idx?
kSynchClock equ 8 ; r4 = target CPU idx,
kSIGP9 equ 9 ; no args?
kGetProcessorTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name
kSIGP17 equ 17 ; r4 = target CPU idx?
; IRP is 10 pages below KDP (measured start to start)
; This should be neatened up to describe the kernel global area
IRPOffset equ (-10) * 4096
kKDPfromIRP equ 10 * 4096
kPoolOffsetFromGlobals equ (-7) * 4096 ; goes all the way up to 24 bytes short of PSA
; Branch instruction BO fields
; (disregarding static prediction :)
BO_IF equ 12
BO_IF_NOT equ 4
Z equ 0x80000000
; SIGP (SIGnal Plugin) selectors used by the kernel:
kStartProcessor equ 1 ; r4 = target CPU idx, r5 = cpu's entry point, r6 = entry point's r3 (CPU struct ptr)
kStopProcessor equ 3 ; r4 = target CPU idx
kResetProcessor equ 4 ; r4 = target CPU idx
kAlert equ 5 ; r4 = target CPU idx? ; my name, has something to do with timers
kSIGP6 equ 6 ; r4 = target CPU idx?
kSIGP7 equ 7 ; r4 = target CPU idx?
kSynchClock equ 8 ; r4 = target CPU idx,
kSIGP9 equ 9 ; no args?
kGetProcessorTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name
kSIGP17 equ 17 ; r4 = target CPU idx?
; Exception cause equates
; System = FFFFFFFF, Alt = 7DF2F700 (ecInstPageFault and ecDataPageFault disabled), same +/- VM
ecNoException equ 0
ecSystemCall equ 1
ecTrapInstr equ 2
ecFloatException equ 3
ecInvalidInstr equ 4
ecPrivilegedInstr equ 5
ecMachineCheck equ 7
ecInstTrace equ 8
ecInstInvalidAddress equ 10
ecInstHardwareFault equ 11
ecInstPageFault equ 12
ecInstSupAccessViolation equ 14
ecDataInvalidAddress equ 18
ecDataHardwareFault equ 19
ecDataPageFault equ 20
ecDataWriteViolation equ 21
ecDataSupAccessViolation equ 22
ecDataSupWriteViolation equ 23
ecUnknown24 equ 24
; FLAGS r7/cr
crMaskAll equ %11111111
; Bits 0-7 (CR0-CR1): Exception Cause Number (see equates)
crMaskExceptionNum equ %11000000
maskExceptionNum equ 0xFF000000
crMaskFlags equ %00111111
maskFlags equ 0x00FFFFFF
; Bits 8-15 (CR2-CR3) Global Flags
crMaskGlobalFlags equ %00110000
maskGlobalFlags equ 0x00FF0000
_bitEqu 8, GlobalFlagSystem ; raised when System (Emulator) Context is running
_bitEqu 13, GlobalFlagMQReg ; raised when POWER "Multiply-Quotient" register is present
; Bits 24-31 (CR6-CR7) Context Flags
crMaskContextFlags equ %00001111
maskContextFlags equ 0x0000FFFF
; Bits 20-23 (CR5) MSR Flags FE0/SE/BE/FE1:
crMaskMsrFlags equ %00000100
maskMsrFlags equ 0x00000F00
; Bits 24-31 (CR6-CR7) Other Context Flags:
_bitEqu 26, ContextFlagTraceWhenDone ; raised when MSR[SE] is up but we get an unrelated interrupt
_bitEqu 27, ContextFlagMemRetryErr ; raised when an exception is raised during MemRetry
_bitEqu 31, ContextFlagResumeMemRetry ; allows MemRetry to be resumed (raised by userspace?)
mrOpflag1 equ cr3_lt
mrOpflag2 equ cr3_gt
mrOpflag3 equ cr3_eq
mrFlagDidLoad equ cr3_so

492
NanoKernel/NKExceptions.s Normal file
View File

@ -0,0 +1,492 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MRMemtab
; MRMemtab
; MROptabCode
; MRDoSecondary
; MRRestab
; MRRestab
; NKFloatingPt
; DisableFPU
; EnableFPU
; ReloadFPU
; NKSystemCrash
; SystemCrash
; EXPORTS:
; Exception (=> MRInterrupts, NKColdInts, NKSoftInts)
; KCallReturnFromException (=> NKReset)
; KCallReturnFromExceptionFastPath (=> NKSoftInts)
; LoadInterruptRegisters (=> NKColdInts, NKSoftInts)
; MRException (=> MRInterrupts, MROptabCode)
; ReturnFromInt (=> NKColdInts, NKLegacyVM, NKSoftInts)
; SwitchContext (=> NKSoftInts)
########################################################################
; MemRetry error
MRException
mtsprg 3, r24
lwz r9, KDP.Enables(r1)
extrwi r23, r17, 5, 26 ; extract accessLen field
rlwnm. r9, r9, r8, 0, 0 ; BGE taken if exception disabled
bcl BO_IF, mrFlagDidLoad, LoadExtraMRRegs
lwz r6, KDP.ContextPtr(r1)
_set r7, r16, bitContextFlagMemRetryErr
neg r23, r23
mtcrf crMaskFlags, r7
add r19, r19, r23 ; convert r19 from end address back to start address??
insrwi r7, r8, 8, 0 ; ec code -> high byte of flags
slwi r8, r8, 2 ; increment counter
add r8, r8, r1
lwz r9, KDP.NKInfo.ExceptionCauseCounts(r8)
addi r9, r9, 1
stw r9, KDP.NKInfo.ExceptionCauseCounts(r8)
; Move regs from KDP to ContextBlock
lwz r8, KDP.r7(r1)
stw r8, CB.r7+4(r6)
lwz r8, KDP.r8(r1)
stw r8, CB.r8+4(r6)
lwz r8, KDP.r9(r1)
stw r8, CB.r9+4(r6)
lwz r8, KDP.r10(r1)
stw r8, CB.r10+4(r6)
lwz r8, KDP.r11(r1)
stw r8, CB.r11+4(r6)
lwz r8, KDP.r12(r1)
stw r8, CB.r12+4(r6)
lwz r8, KDP.r13(r1)
stw r8, CB.r13+4(r6)
bge RunSystemContext ; Alt Context has left exception disabled => Sys Context
;fall through ; exception enabled => run userspace handler
########################################################################
; Exception or MRException that is Enabled (i.e. not being auto-forced to System)
ExceptionCommon
stw r10, CB.FaultSrcPC+4(r6) ; Save r10/SRR0, r12/LR, r3, r4
stw r12, CB.FaultSrcLR+4(r6)
stw r3, CB.FaultSrcR3+4(r6)
stw r4, CB.FaultSrcR4+4(r6)
lwz r8, KDP.Enables(r1) ; Save Enables & Flags, inc ContextFlagMemRetryErr
stw r7, CB.IntraState.Flags(r6)
stw r8, CB.IntraState.Enables(r6)
; Use IntraState because context handles its own error
li r8, 0 ; Enables=0 (any exceptions in handler go to System)
lwz r10, CB.IntraState.Handler+4(r6) ; SRR0 = handler addr
lwz r4, CB.IntraState.HandlerArg+4(r6) ; r4 = arbitrary second argument
lwz r3, KDP.ECBPtrLogical(r1) ; r3 = ContextBlock ptr
bc BO_IF, bitGlobalFlagSystem, @sys
lwz r3, KDP.NCBCacheLA0(r1)
@sys
lwz r12, KDP.EmuKCallTblPtrLogical(r1) ; r12/LR = address of KCallReturnFromException trap
bcl BO_IF, bitContextFlagMemRetryErr, SaveFailingMemRetryState
rlwinm r7, r7, 0, 29, 15 ; unset flags 16-28
stw r8, KDP.Enables(r1)
rlwimi r11, r7, 0, 20, 23 ; threfore unset MSR[FE0/SE/BE/FE1]
b ReturnFromInt
########################################################################
LoadExtraMRRegs
lwz r0, KDP.r0(r1)
lwz r2, KDP.r2(r1)
lwz r3, KDP.r3(r1)
lwz r4, KDP.r4(r1)
lwz r5, KDP.r5(r1)
blr
SaveFailingMemRetryState
stw r17, CB.IntraState.MemRet17+4(r6)
stw r20, CB.IntraState.MemRetData(r6)
stw r21, CB.IntraState.MemRetData+4(r6)
stw r19, CB.IntraState.MemRet19+4(r6)
stw r18, CB.IntraState.MemRet18+4(r6)
lmw r14, KDP.r14(r1)
blr
########################################################################
_alignToCacheBlock
KCallReturnFromExceptionFastPath
lwz r11, KDP.NKInfo.NanoKernelCallCounts(r1)
mr r10, r12
addi r11, r11, 1
stw r11, KDP.NKInfo.NanoKernelCallCounts(r1)
mfsrr1 r11
rlwimi r7, r7, 32+bitMsrSE-bitContextFlagTraceWhenDone, ContextFlagTraceWhenDone
KCallReturnFromException
cmplwi cr1, r3, 1 ; exception handler return value
blt cr1, @dispose
mtcrf crMaskFlags, r7
beq cr1, @propagate
; If handler returns an exception cause code 2-255, "force" this exception to the System Context.
subi r8, r3, 32
lwz r9, KDP.NKInfo.ExceptionForcedCount(r1)
cmplwi r8, 256-32
addi r9, r9, 1
stw r9, KDP.NKInfo.ExceptionForcedCount(r1)
insrwi r7, r3, 8, 0
blt RunSystemContext
li r8, ecTrapInstr
b Exception ; (error if number is > max exception number)
; If handler returns 0 (System Context must always do this), return to userspace.
@dispose
lwz r8, CB.IntraState.Flags(r6) ; Restore Context flags (inc exception number?)
lwz r10, CB.FaultSrcPC+4(r6)
rlwimi r7, r8, 0, maskExceptionNum | maskContextFlags ; preserve global flags
lwz r8, CB.IntraState.Enables(r6)
rlwimi r11, r7, 0, maskMsrFlags
stw r8, KDP.Enables(r1)
andi. r8, r11, MsrFE0 + MsrFE1 ; check: are floating-pt exceptions enabled?
lwz r12, CB.FaultSrcLR+4(r6) ; restore LR/r3/r4
lwz r3, CB.FaultSrcR3+4(r6)
lwz r4, CB.FaultSrcR4+4(r6)
bnel EnableFPU
addi r9, r6, CB.IntraState ; If MemRetry was interrupted, resume it.
b ReturnFromInt
; If handler returns 1, "propagate" this exception to the System Context
; (When we get back to the Alternate Context, it will be as if the exception was disposed.)
@propagate
lwz r9, KDP.NKInfo.ExceptionPropagateCount(r1)
lwz r8, CB.IntraState.Flags(r6)
addi r9, r9, 1
stw r9, KDP.NKInfo.ExceptionPropagateCount(r1)
lwz r10, CB.FaultSrcPC+4(r6)
rlwimi r7, r8, 0, maskExceptionNum | maskContextFlags ; preserve global flags
lwz r8, CB.IntraState.Enables(r6)
mtcrf crMaskContextFlags, r7
rlwimi r11, r7, 0, maskMsrFlags
stw r8, KDP.Enables(r1)
lwz r12, CB.FaultSrcLR+4(r6) ; restore LR/r3/r4
lwz r3, CB.FaultSrcR3+4(r6)
lwz r4, CB.FaultSrcR4+4(r6)
bc BO_IF_NOT, bitContextFlagMemRetryErr, RunSystemContext
stmw r14, KDP.r14(r1) ; When we *do* get back to this context,
lwz r17, CB.IntraState.MemRet17+4(r6) ; make sure MemRetry state can be resumed
lwz r20, CB.IntraState.MemRetData(r6) ; from InterState
lwz r21, CB.IntraState.MemRetData+4(r6)
lwz r19, CB.IntraState.MemRet19+4(r6)
lwz r18, CB.IntraState.MemRet18+4(r6)
b RunSystemContext
########################################################################
; BEFORE
; PowerPC exception vector saved r1/LR in SPRG1/2 and
; jumped where directed by the VecTbl pointed to by
; SPRG3. That function bl'ed here.
;
; AFTER
; Reg Contains Original saved in
; ---------------------------------------------
; r0 (itself)
; r1 KDP SPRG1
; r2 (itself)
; r3 (itself)
; r4 (itself)
; r5 (itself)
; r6 ContextBlock EWA
; r7 Flags ContextBlock
; r8 KDP ContextBlock
; r9 (scratch CB ptr) ContextBlock
; r10 SRR0 ContextBlock
; r11 SRR1 ContextBlock
; r12 LR ContextBlock
; r13 CR ContextBlock
LoadInterruptRegisters
mfsprg r1, 0
stw r6, KDP.r6(r1)
mfsprg r6, 1
stw r6, KDP.r1(r1)
lwz r6, KDP.ContextPtr(r1)
stw r7, CB.r7+4(r6)
stw r8, CB.r8+4(r6)
stw r9, CB.r9+4(r6)
stw r10, CB.r10+4(r6)
stw r11, CB.r11+4(r6)
stw r12, CB.r12+4(r6)
stw r13, CB.r13+4(r6)
mfsrr0 r10
mfcr r13
lwz r7, KDP.Flags(r1)
mfsprg r12, 2
mfsrr1 r11
blr
########################################################################
Exception
lwz r9, KDP.Enables(r1)
mtcrf crMaskFlags, r7
rlwnm. r9, r9, r8, 0, 0 ; BLT taken if exception enabled
insrwi r7, r8, 8, 0 ; Exception code to hi byte of Flags
slwi r8, r8, 2 ; Increment counter, easy enough
add r8, r8, r1
lwz r9, KDP.NKInfo.ExceptionCauseCounts(r8)
addi r9, r9, 1
stw r9, KDP.NKInfo.ExceptionCauseCounts(r8)
blt ExceptionCommon ; exception enabled => run userspace handler
;fall through ; Alt Context has left exception disabled => Sys Context
########################################################################
RunSystemContext
lwz r9, KDP.ECBPtr(r1) ; System ("Emulator") ContextBlock
addi r8, r1, KDP.VecTblSystem ; System VecTbl
mtsprg 3, r8
bcl BO_IF, bitGlobalFlagSystem, SystemCrash ; System Context already running!
; Fallthru (new CB in r9, old CB in r6)
########################################################################
SwitchContext ; OldCB *r6, NewCB *r9
; Run the System or Alternate Context
lwz r8, KDP.Enables(r1)
stw r7, CB.InterState.Flags(r6)
stw r8, CB.InterState.Enables(r6)
bc BO_IF_NOT, bitContextFlagMemRetryErr, @can_dispose_mr_state
stw r17, CB.InterState.MemRet17+4(r6)
stw r20, CB.InterState.MemRetData(r6)
stw r21, CB.InterState.MemRetData+4(r6)
stw r19, CB.InterState.MemRet19+4(r6)
stw r18, CB.InterState.MemRet18+4(r6)
lmw r14, KDP.r14(r1)
@can_dispose_mr_state
mfxer r8
stw r13, CB.CR+4(r6)
stw r8, CB.XER+4(r6)
stw r12, CB.LR+4(r6)
mfctr r8
stw r10, CB.PC+4(r6)
stw r8, CB.CTR+4(r6)
bc BO_IF_NOT, bitGlobalFlagMQReg, @no_mq
lwz r8, CB.MQ+4(r9)
mfspr r12, mq
mtspr mq, r8
stw r12, CB.MQ+4(r6)
@no_mq
lwz r8, KDP.r1(r1)
stw r0, CB.r0+4(r6)
stw r8, CB.r1+4(r6)
stw r2, CB.r2+4(r6)
stw r3, CB.r3+4(r6)
stw r4, CB.r4+4(r6)
lwz r8, KDP.r6(r1)
stw r5, CB.r5+4(r6)
stw r8, CB.r6+4(r6)
_band. r8, r11, bitMsrFP
stw r14, CB.r14+4(r6)
stw r15, CB.r15+4(r6)
stw r16, CB.r16+4(r6)
stw r17, CB.r17+4(r6)
stw r18, CB.r18+4(r6)
stw r19, CB.r19+4(r6)
stw r20, CB.r20+4(r6)
stw r21, CB.r21+4(r6)
stw r22, CB.r22+4(r6)
stw r23, CB.r23+4(r6)
stw r24, CB.r24+4(r6)
stw r25, CB.r25+4(r6)
stw r26, CB.r26+4(r6)
stw r27, CB.r27+4(r6)
stw r28, CB.r28+4(r6)
stw r29, CB.r29+4(r6)
stw r30, CB.r30+4(r6)
stw r31, CB.r31+4(r6)
bnel DisableFPU
lwz r8, KDP.OtherContextDEC(r1)
mfdec r31
cmpwi r8, 0
stw r31, KDP.OtherContextDEC(r1)
mtdec r8
blel ResetDEC ; to r8
lwz r8, CB.InterState.Flags(r9) ; r8 is the new Flags variable
stw r9, KDP.ContextPtr(r1)
xoris r7, r7, GlobalFlagSystem >> 16 ; flip Emulator flag
rlwimi r11, r8, 0, maskMsrFlags
mr r6, r9 ; change the magic ContextBlock register
rlwimi r7, r8, 0, maskContextFlags ; change bottom half of flags only
andi. r8, r11, MsrFE0 + MsrFE1 ; FP exceptions enabled in new context?
lwz r8, CB.InterState.Enables(r6)
lwz r13, CB.CR+4(r6)
stw r8, KDP.Enables(r1)
lwz r8, CB.XER+4(r6)
lwz r12, CB.LR+4(r6)
mtxer r8
lwz r8, CB.CTR+4(r6)
lwz r10, CB.PC+4(r6)
mtctr r8
bnel ReloadFPU ; FP exceptions enabled, so load FPU
stwcx. r0, 0, r1
lwz r8, CB.r1+4(r6)
lwz r0, CB.r0+4(r6)
stw r8, KDP.r1(r1)
lwz r2, CB.r2+4(r6)
lwz r3, CB.r3+4(r6)
lwz r4, CB.r4+4(r6)
lwz r8, CB.r6+4(r6)
lwz r5, CB.r5+4(r6)
stw r8, KDP.r6(r1)
lwz r14, CB.r14+4(r6)
lwz r15, CB.r15+4(r6)
lwz r16, CB.r16+4(r6)
lwz r17, CB.r17+4(r6)
lwz r18, CB.r18+4(r6)
lwz r19, CB.r19+4(r6)
lwz r20, CB.r20+4(r6)
lwz r21, CB.r21+4(r6)
lwz r22, CB.r22+4(r6)
lwz r23, CB.r23+4(r6)
lwz r24, CB.r24+4(r6)
lwz r25, CB.r25+4(r6)
lwz r26, CB.r26+4(r6)
lwz r27, CB.r27+4(r6)
lwz r28, CB.r28+4(r6)
lwz r29, CB.r29+4(r6)
lwz r30, CB.r30+4(r6)
lwz r31, CB.r31+4(r6)
########################################################################
ReturnFromInt ; If ContextFlagMemRetryErr && ContextFlagResumeMemRetry, please pass KernelState ptr in r9
andi. r8, r7, ContextFlagTraceWhenDone | ContextFlagMemRetryErr
bnel @special_cases ; Keep rare cases out of the hot path
stw r7, KDP.Flags(r1) ; Save kernel flags for next interrupt
mtlr r12 ; Restore user SPRs from kernel GPRs
mtsrr0 r10
mtsrr1 r11
mtcr r13
lwz r10, CB.r10+4(r6) ; Restore user GPRs from ContextBlock
lwz r11, CB.r11+4(r6)
lwz r12, CB.r12+4(r6)
lwz r13, CB.r13+4(r6)
lwz r7, CB.r7+4(r6)
lwz r8, CB.r8+4(r6)
lwz r9, CB.r9+4(r6)
lwz r6, KDP.r6(r1) ; Restore last two registers from EWA
lwz r1, KDP.r1(r1)
rfi ; Go
@special_cases
mtcrf crMaskFlags, r7
bc BO_IF_NOT, bitContextFlagMemRetryErr, @no_memretry ; If MemRetry had to be paused for an exception
_clear r7, r7, bitContextFlagMemRetryErr ; which is now finished, finish MemRetry.
bc BO_IF, bitContextFlagResumeMemRetry, @resume_memretry
_clear r7, r7, bitContextFlagTraceWhenDone
b @justreturn
@no_memretry
bc BO_IF_NOT, bitContextFlagTraceWhenDone, @justreturn ; If this current interrupt was raised when
_clear r7, r7, bitContextFlagTraceWhenDone ; every instruction should be followed by a
stw r7, KDP.Flags(r1) ; Trace exception, then raise one.
li r8, ecInstTrace
b Exception
@justreturn
blr
@resume_memretry ; Pick up where an MRException left off, now that the Exception has been disposed.
stw r7, KDP.Flags(r1)
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
stw r3, KDP.r3(r1)
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
lwz r8, CB.r7+4(r6)
stw r8, KDP.r7(r1)
lwz r8, CB.r8+4(r6)
stw r8, KDP.r8(r1)
lwz r8, CB.r9+4(r6)
stw r8, KDP.r9(r1)
lwz r8, CB.r10+4(r6)
stw r8, KDP.r10(r1)
lwz r8, CB.r11+4(r6)
stw r8, KDP.r11(r1)
lwz r8, CB.r12+4(r6)
stw r8, KDP.r12(r1)
lwz r8, CB.r13+4(r6)
stw r8, KDP.r13(r1)
stmw r14, KDP.r14(r1)
lwz r17, KernelState.MemRet17+4(r9) ; Get the MR state from IntraState (if context was never switched)
lwz r20, KernelState.MemRetData(r9) ; or InterState (if exception was propagated to System Context and
lwz r21, KernelState.MemRetData+4(r9) ; we are now switching back to Alternate Context).
lwz r19, KernelState.MemRet19+4(r9)
lwz r18, KernelState.MemRet18+4(r9)
_clear r16, r7, bitContextFlagMemRetryErr
lwz r25, KDP.MRBase(r1) ; MRRestab is indexed by the first arg of MROptab?
extrwi. r22, r17, 4, 27 ;
add r19, r19, r22 ; Correct r19 (EA) by adding len from r17
rlwimi r25, r17, 7, 25, 30
lhz r26, MRRestab-MRBase(r25)
insrwi r25, r19, 3, 28 ; Set Memtab alignment modulus
stw r16, KDP.Flags(r1)
rlwimi r26, r26, 8, 8, 15 ; First byte of MRRestab is for cr3/cr4
insrwi r25, r17, 4, 24 ; len and load/store from second arg of MROptab?
mtcrf 0x10, r26 ; Set CR3
lha r22, MRMemtab-MRBase(r25) ; Jump to MRMemtab...
addi r23, r1, KDP.VecTblMemRetry
add r22, r22, r25
mfsprg r24, 3
mtlr r22
mtsprg 3, r23
mfmsr r14
_set r15, r14, bitMsrDR
mtmsr r15
rlwimi r25, r26, 2, 22, 29 ; Second byte of MRRestab is a secondary routine
bnelr
b MRDoSecondary
########################################################################
ResetDEC ; to r8
lis r31, 0x7FFF
mtdec r31
mtdec r8
blr

166
NanoKernel/NKFloatingPt.s Normal file
View File

@ -0,0 +1,166 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptabCode
; MRDoneTableSTFD
; MRSecDone
; EXPORTS:
; DisableFPU (=> NKExceptions)
; EnableFPU (=> NKExceptions)
; FPUnavailInt (=> NKReset)
; LFDTable (=> MROptabCode)
; ReloadFPU (=> NKExceptions)
; STFDTable (=> MROptabCode)
########################################################################
_alignToCacheBlock
FPUnavailInt
; Reload the FPU
mfsprg r1, 0
stw r11, KDP.FloatingPtTemp1(r1)
lwz r11, KDP.NKInfo.FPUReloadCount(r1)
stw r6, KDP.FloatingPtTemp2(r1)
addi r11, r11, 1
stw r11, KDP.NKInfo.FPUReloadCount(r1)
mfsrr1 r11
_set r11, r11, bitMsrFP
mtsrr1 r11
mfmsr r11 ; need this to access float registers
_set r11, r11, bitMsrFP
lwz r6, KDP.ContextPtr(r1)
mtmsr r11
bl LoadFloats
lwz r11, KDP.FloatingPtTemp1(r1)
lwz r6, KDP.FloatingPtTemp2(r1)
mfsprg r1, 2
mtlr r1
mfsprg r1, 1
rfi
########################################################################
EnableFPU
rlwinm. r8, r11, 0, 18, 18
bnelr
ReloadFPU
lwz r8, CB.FPSCR+4(r6)
rlwinm. r8, r8, 1, 0, 0
mfmsr r8
_set r8, r8, bitMsrFP
beqlr
mtmsr r8
_set r11, r11, bitMsrFP
########################################################################
LoadFloats
lfd f31, CB.FPSCR(r6)
lfd f0, CB.f0(r6)
lfd f1, CB.f1(r6)
lfd f2, CB.f2(r6)
lfd f3, CB.f3(r6)
lfd f4, CB.f4(r6)
lfd f5, CB.f5(r6)
lfd f6, CB.f6(r6)
lfd f7, CB.f7(r6)
mtfs f31
lfd f8, CB.f8(r6)
lfd f9, CB.f9(r6)
lfd f10, CB.f10(r6)
lfd f11, CB.f11(r6)
lfd f12, CB.f12(r6)
lfd f13, CB.f13(r6)
lfd f14, CB.f14(r6)
lfd f15, CB.f15(r6)
lfd f16, CB.f16(r6)
lfd f17, CB.f17(r6)
lfd f18, CB.f18(r6)
lfd f19, CB.f19(r6)
lfd f20, CB.f20(r6)
lfd f21, CB.f21(r6)
lfd f22, CB.f22(r6)
lfd f23, CB.f23(r6)
lfd f24, CB.f24(r6)
lfd f25, CB.f25(r6)
lfd f26, CB.f26(r6)
lfd f27, CB.f27(r6)
lfd f28, CB.f28(r6)
lfd f29, CB.f29(r6)
lfd f30, CB.f30(r6)
lfd f31, CB.f31(r6)
blr
########################################################################
DisableFPU
mfmsr r8
_set r8, r8, bitMsrFP
mtmsr r8
_clear r11, r11, bitMsrFP
stfd f0, CB.f0(r6)
stfd f1, CB.f1(r6)
stfd f2, CB.f2(r6)
stfd f3, CB.f3(r6)
stfd f4, CB.f4(r6)
stfd f5, CB.f5(r6)
stfd f6, CB.f6(r6)
stfd f7, CB.f7(r6)
stfd f8, CB.f8(r6)
stfd f9, CB.f9(r6)
stfd f10, CB.f10(r6)
stfd f11, CB.f11(r6)
stfd f12, CB.f12(r6)
stfd f13, CB.f13(r6)
stfd f14, CB.f14(r6)
stfd f15, CB.f15(r6)
stfd f16, CB.f16(r6)
stfd f17, CB.f17(r6)
stfd f18, CB.f18(r6)
stfd f19, CB.f19(r6)
stfd f20, CB.f20(r6)
stfd f21, CB.f21(r6)
stfd f22, CB.f22(r6)
stfd f23, CB.f23(r6)
mffs f0
stfd f24, CB.f24(r6)
stfd f25, CB.f25(r6)
stfd f26, CB.f26(r6)
stfd f27, CB.f27(r6)
stfd f28, CB.f28(r6)
stfd f29, CB.f29(r6)
stfd f30, CB.f30(r6)
stfd f31, CB.f31(r6)
stfd f0, CB.FPSCR(r6)
blr
########################################################################
; This is used by MemRetry
MACRO
MakeFloatJumpTable &OPCODE, &DEST, &highest==31
if &highest > 0
MakeFloatJumpTable &OPCODE, &DEST, highest = (&highest) - 1
endif
&OPCODE &highest, KDP.FloatScratch(r1)
b &DEST
ENDM
LFDTable
MakeFloatJumpTable lfd, MRSecDone
STFDTable
MakeFloatJumpTable stfd, MRDoneTableSTFD

392
NanoKernel/NKHotInts.s Normal file
View File

@ -0,0 +1,392 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptab
; MROptabD
; MROptabX
; EXPORTS:
; AlignmentInt (=> NKReset)
; DataStorageInt (=> NKReset)
; DecrementerIntAlt (=> NKReset)
; DecrementerIntSys (=> NKReset)
; EmulateDataAccess (=> NKSoftInts)
; ExternalInt0 (=> NKReset)
; ExternalInt1 (=> NKReset)
; ExternalInt2 (=> NKReset)
########################################################################
_align 6
ExternalInt0
mfsprg r1, 0 ; Init regs and increment ctr
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
lwz r2, KDP.NKInfo.ExternalIntCount(r1)
stw r3, KDP.r3(r1)
addi r2, r2, 1
stw r2, KDP.NKInfo.ExternalIntCount(r1)
mfmsr r2 ; Save a self-ptr to FF880000... why?
lis r3, 0xFF88
_set r0, r2, bitMsrDR
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
mfsrr0 r4
mfsrr1 r5
mtmsr r0
stw r3, 0(r3)
mtmsr r2
mtsrr0 r4
mtsrr1 r5
lwz r4, KDP.r4(r1)
lwz r5, KDP.r5(r1)
lwz r2, KDP.DebugIntPtr(r1) ; Query the shared mem (debug?) for int num
mfcr r0
lha r2, 0(r2)
lwz r3, KDP.EmuIntLevelPtr(r1)
rlwinm. r2, r2, 0, 0x80000007
ori r2, r2, 0x8000
sth r2, 0(r3)
mfsprg r2, 2
lwz r3, KDP.r3(r1)
mtlr r2
beq @clear ; 0 -> clear interrupt
bgt @return ; negative -> no interrupt flag
; positive -> post interrupt
lwz r2, KDP.PostIntMaskInit(r1) ; Post an interrupt via Cond Reg
or r0, r0, r2
@return
mtcr r0 ; Set CR and return
lwz r0, KDP.r0(r1)
lwz r2, KDP.r2(r1)
mfsprg r1, 1
rfi
@clear
lwz r2, KDP.ClearIntMaskInit(r1) ; Clear an interrupt via Cond Reg
and r0, r0, r2
b @return
########################################################################
_align 6
IntLookupTable
dc.b 0, 1, 2, 2, 4, 4, 4, 4
dc.b 3, 3, 3, 3, 4, 4, 4, 4
dc.b 4, 4, 4, 4, 4, 4, 4, 4
dc.b 4, 4, 4, 4, 4, 4, 4, 4
dc.b 7, 7, 7, 7, 7, 7, 7, 7
dc.b 7, 7, 7, 7, 7, 7, 7, 7
dc.b 7, 7, 7, 7, 7, 7, 7, 7
dc.b 7, 7, 7, 7, 7, 7, 7, 7
_align 6
ExternalInt1
mfsprg r1, 0 ; Init regs and increment ctr
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
lwz r2, KDP.NKInfo.ExternalIntCount(r1)
stw r3, KDP.r3(r1)
addi r2, r2, 1
stw r2, KDP.NKInfo.ExternalIntCount(r1)
lis r2, 0x50F3 ; Query OpenPIC at 50F2A000
mfmsr r3
_set r0, r3, bitMsrDR
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
mfsrr0 r4
mfsrr1 r5
mtmsr r0
li r0, 0xC0
stb r0, -0x6000(r2)
eieio
lbz r0, -0x6000(r2)
mtmsr r3
mtsrr0 r4
mtsrr1 r5
lwz r4, KDP.r4(r1)
lwz r5, KDP.r5(r1)
lwz r3, KDP.CodeBase(r1) ; Loop that number up in the table
rlwimi r3, r0, 0, 0x0000003F
lbz r2, IntLookupTable-CodeBase(r3)
mfcr r0
lwz r3, KDP.EmuIntLevelPtr(r1)
clrlwi. r2, r2, 29
sth r2, 0(r3)
mfsprg r2, 2
lwz r3, KDP.r3(r1)
mtlr r2
beq @clear ; 0 -> clear interrupt
; nonzero -> post interrupt
lwz r2, KDP.PostIntMaskInit(r1) ; Post an interrupt via Cond Reg
or r0, r0, r2
@return
mtcr r0 ; Set CR and return
lwz r0, KDP.r0(r1)
lwz r2, KDP.r2(r1)
mfsprg r1, 1
rfi
@clear
lwz r2, KDP.ClearIntMaskInit(r1) ; Clear an interrupt via Cond Reg
and r0, r0, r2
b @return
########################################################################
_align 6
ExternalInt2
mfsprg r1, 0 ; Init regs and increment ctr
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
lwz r2, KDP.NKInfo.ExternalIntCount(r1)
stw r3, KDP.r3(r1)
addi r2, r2, 1
stw r2, KDP.NKInfo.ExternalIntCount(r1)
lis r2, 0xF300 ; Query OpenPIC at F3000028/C
mfmsr r0
_set r3, r0, bitMsrDR
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
mfsrr0 r4
mfsrr1 r5
mtmsr r3
lis r3, 0x8000
stw r3, 0x28(r2)
eieio
lwz r3, 0x2C(r2)
mtmsr r0
mtsrr0 r4
mtsrr1 r5
lwz r4, KDP.r4(r1)
lwz r5, KDP.r5(r1)
mfcr r0
; Interpret OpenPic result:
rlwinm. r2, r3, 0, 11, 11 ; bit 11 -> 7
li r2, 7
bne @gotnum
rlwinm r2, r3, 0, 15, 16 ; bit 15-16/21/31 -> 4
rlwimi. r2, r3, 0, 21, 31
li r2, 4
bne @gotnum
rlwinm. r2, r3, 0, 18, 18 ; bit 18 -> 3
li r2, 3
bne @gotnum
andis. r2, r3, 0x7FEA ; bit 1-10/12/14/19-20 -> 2
rlwimi. r2, r3, 0, 19, 20
li r2, 2
bne @gotnum
extrwi. r2, r3, 1, 13 ; bit 13 -> 1
; else -> 0
@gotnum
lwz r3, KDP.EmuIntLevelPtr(r1)
sth r2, 0(r3)
mfsprg r2, 2
lwz r3, KDP.r3(r1)
mtlr r2
beq @clear ; 0 -> clear interrupt
; nonzero -> post interrupt
lwz r2, KDP.PostIntMaskInit(r1) ; Post an interrupt via Cond Reg
or r0, r0, r2
@return
mtcr r0 ; Set CR and return
lwz r0, KDP.r0(r1)
lwz r2, KDP.r2(r1)
mfsprg r1, 1
rfi
@clear
lwz r2, KDP.ClearIntMaskInit(r1) ; Clear an interrupt via Cond Reg
and r0, r0, r2
b @return
########################################################################
; Increment the Sys/Alt CPU clocks, and the Dec-int counter
_align 6
DecrementerIntSys
mfsprg r1, 0
stmw r2, KDP.r2(r1)
mfdec r31
lwz r30, KDP.OtherContextDEC(r1)
DecCommon ; DEC for Alternate=r30, System=r31
mfxer r29 ; we will do carries
lwz r28, KDP.ProcInfo.DecClockRateHz(r1)
stw r28, KDP.OtherContextDEC(r1)
mtdec r28 ; reset Sys and Alt decrementers
subf r31, r31, r28 ; System ticks actually elapsed
subf r30, r30, r28 ; Alternate ticks actually elapsed
lwz r28, KDP.NKInfo.SysContextCpuTime+4(r1)
lwz r27, KDP.NKInfo.SysContextCpuTime(r1)
addc r28, r28, r31
addze r27, r27
stw r28, KDP.NKInfo.SysContextCpuTime+4(r1)
stw r27, KDP.NKInfo.SysContextCpuTime(r1)
lwz r28, KDP.NKInfo.AltContextCpuTime+4(r1)
lwz r27, KDP.NKInfo.AltContextCpuTime(r1)
addc r28, r28, r30
addze r27, r27
stw r28, KDP.NKInfo.AltContextCpuTime+4(r1)
stw r27, KDP.NKInfo.AltContextCpuTime(r1)
mtxer r29
stw r0, KDP.r0(r1)
mfsprg r31, 1
stw r31, KDP.r1(r1)
lwz r31, KDP.NKInfo.DecrementerIntCount(r1)
addi r31, r31, 1
stw r31, KDP.NKInfo.DecrementerIntCount(r1)
lmw r27, KDP.r27(r1)
mfsprg r1, 2
mtlr r1
mfsprg r1, 1
rfi
DecrementerIntAlt
mfsprg r1, 0
stmw r2, KDP.r2(r1)
lwz r31, KDP.OtherContextDEC(r1)
mfdec r30
b DecCommon
########################################################################
_align 6
DataStorageInt
mfsprg r1, 0
stmw r2, KDP.r2(r1)
mfsprg r11, 1
stw r0, KDP.r0(r1)
stw r11, KDP.r1(r1)
mfsrr0 r10
mfsrr1 r11
mfsprg r12, 2
mfcr r13
mfmsr r14
_set r15, r14, bitMsrDR
mtmsr r15
lwz r27, 0(r10) ; r27 = INSTRUCTION
mtmsr r14
EmulateDataAccess
rlwinm. r18, r27, 18, 25, 29 ; r16 = 4 * rA (r0 wired to 0)
lwz r25, KDP.MRBase(r1)
li r21, 0
beq @r0
lwzx r18, r1, r18 ; r16 = contents of rA
@r0
andis. r26, r27, 0xec00 ; intended to extract the major opcode? seems wrong though!
lwz r16, KDP.Flags(r1)
mfsprg r24, 3
rlwinm r17, r27, 0, 6, 15 ; r17 = rS/D and rA fields
rlwimi r16, r16, 27, 26, 26 ; ContextFlagTraceWhenDone = MsrSE
bge @xform
;dform
rlwimi r25, r27, 7, 26, 29
rlwimi r25, r27, 12, 25, 25
lwz r26, MROptabD-MRBase(r25) ; table of 4b elements, index = major opcode bits 51234 (this is the last quarter of MROptabX)
extsh r23, r27 ; r23 = register offset field, sign-extended
rlwimi r25, r26, 26, 22, 29
mtlr r25 ; dest = r25 = first of two function ptrs in table entry
mtcr r26 ; using the flags in the arbitrary upper 16 bits of the table entry?
add r18, r18, r23 ; r18 = effective address attempted by instruction
rlwimi r17, r26, 6, 26, 5 ; r17 = pretend X-form inst with: maj opcode (from tbl), rS/D and RA (from inst), min opcode (from tbl)
blr
@xform
rlwimi r25, r27, 27, 26, 29
rlwimi r25, r27, 0, 25, 25
rlwimi r25, r27, 6, 23, 24
lwz r26, MROptabX-MRBase(r25) ; table of 4b elements, index = minor (x-form) opcode bits 8940123
rlwinm r23, r27, 23, 25, 29 ; r23 = 4 * rB
rlwimi r25, r26, 26, 22, 29
mtlr r25 ; dest = r25 = first of two function ptrs in table entry
mtcr r26
lwzx r23, r1, r23 ; get rB from saved registers
rlwimi r17, r26, 6, 26, 5 ; r17 = pretend X-form inst with: maj opcode (from tbl), rS/D and RA (from inst), min opcode (from tbl)
add r18, r18, r23 ; r18 = effective address attempted by instruction
bclr BO_IF_NOT, mrOpflag2
neg r23, r23
add r18, r18, r23
blr
########################################################################
_align 6
AlignmentInt
mfsprg r1, 0
stmw r2, KDP.r2(r1)
lwz r11, KDP.NKInfo.MisalignmentCount(r1)
addi r11, r11, 1
stw r11, KDP.NKInfo.MisalignmentCount(r1)
mfsprg r11, 1
stw r0, KDP.r0(r1)
stw r11, KDP.r1(r1)
mfsrr0 r10
mfsrr1 r11
mfsprg r12, 2
mfcr r13
mfsprg r24, 3
mfdsisr r27
mfdar r18
extrwi. r21, r27, 2, 15 ; evaluate hi two bits of XO (or 0 for d-form?)
lwz r25, KDP.MRBase(r1)
rlwinm r17, r27, 16, 0x03FF0000
lwz r16, KDP.Flags(r1)
rlwimi r25, r27, 24, 23, 29 ; add constant fields from dsisr (*4) to FDP
rlwimi r16, r16, 27, 26, 26 ; ContextFlagTraceWhenDone = MsrSE
bne @xform
;dform
lwz r26, MROptabD-MRBase(r25) ; use upper quarter of table
mfmsr r14
rlwimi r25, r26, 26, 22, 29 ; third byte of lookup value is a /4 code offset in FDP
mtlr r25 ; so get ready to go there
_set r15, r14, bitMsrDR
mtcr r26
rlwimi r17, r26, 6, 26, 5 ; wrap some shite around the register values
blr
@xform
lwz r26, MROptabX-MRBase(r25)
mfmsr r14
rlwimi r25, r26, 26, 22, 29
mtlr r25
_set r15, r14, bitMsrDR
mtcr r26
rlwimi r17, r26, 6, 26, 5
bclr BO_IF_NOT, mrOpflag1
mtmsr r15
lwz r27, 0(r10)
mtmsr r14
blr

View File

@ -1,311 +0,0 @@
;_______________________________________________________________________
; NanoKernel Opaque ID Index
;
; Creates opaque structure IDs and stores them in the Pool. An opaque
; ID maps back to the (type, pointer) pair passed to MakeID.
;
; This abstraction is very important to the Multiprocessing Services.
;
; Rene on comp.sys.mac.programmer.help, 26 Oct 01:
;
; Total opaque IDs - The number of IDs currently in use. All MP
; objects: address spaces, areas, processors, memory coherence groups,
; queues, semaphores, critical regions, event groups, timers,
; notifications, etc. are assigned an ID when created, and they are
; accessed by way of this ID. The kernel presently handles 65,000
; simultaneous IDs with a bit pattern reuse probability of 1 in 4
; billion.
;
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKPoolAllocator
; PoolAllocClear
; NKThud
; panic
; EXPORTS:
; DeleteID (=> NKAddressSpaces, NKMPCalls, NKSync, NKTasks, NKTimers)
; GetNextIDOfClass (=> NKAddressSpaces, NKMPCalls, NKThud)
; InitIDIndex (=> NKInit)
; LookupID (=> NKAddressSpaces, NKInterrupts, NKMPCalls, NKPrimaryIntHandlers, NKSync, NKTasks, NKThud, NKTimers)
; MakeID (=> NKAddressSpaces, NKInit, NKMPCalls, NKSync, NKTasks)
;_______________________________________________________________________
Local_Panic set *
b panic
; ARG KDP *r1
InitIDIndex
mflr r23
li r8, Index.Size
bl PoolAllocClear
mr. r22, r8
stw r8, PSA.IndexPtr(r1)
beq Local_Panic
li r9, 0
stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1)
sth r9, Index.HalfOne(r22)
sth r9, Index.HalfTwo(r22)
lisori r9, Index.kSignature
stw r9, Index.Signature(r22)
; Then what the hell is this?
li r8, 0xfd8
bl PoolAllocClear
cmpwi r8, 0
stw r8, Index.IDsPtr(r22)
beq Local_Panic
mtlr r23
li r9, 0x00
sth r9, 0x0000(r8)
li r9, 0x1fa
sth r9, 0x0002(r8)
lisori r9, 'IDs '
stw r9, 0x0004(r8)
blr
; ARG void *r8, IDClass r9
; RET ID r8
MakeID
lwz r18, PSA.IndexPtr(r1)
lhz r19, 0x0000(r18)
mr r21, r19
@_c
lwz r18, PSA.IndexPtr(r1)
rlwinm r20, r19, 25, 23, 29
addi r20, r20, 0x08
clrlwi. r19, r19, 0x17
lwzx r18, r18, r20
slwi r22, r19, 3
addi r20, r18, 0x08
cmpwi r18, 0x00
add r22, r22, r20
bne @_48
li r19, 0x00
b @_c
@_3c
add r20, r20, r19
cmpw r20, r21
beq @_70
@_48
lbz r23, 0x0000(r22)
cmpwi r23, 0x00
beq @_f0
addi r19, r19, 0x01
cmpwi cr1, r19, 0x1fa
addi r22, r22, 0x08
lhz r20, 0x0000(r18)
blt cr1, @_3c
addi r19, r20, 0x200
b @_c
@_70
lwz r18, PSA.IndexPtr(r1)
mr r21, r8
lhz r19, 0x0002(r18)
mr r22, r9
addi r19, r19, 0x200
rlwinm. r20, r19, 25, 23, 29
li r8, 0x00
beqlr
mflr r23
li r8, 0xfd8
; r1 = kdp
; r8 = size
bl PoolAllocClear
; r8 = ptr
mr. r18, r8
mtlr r23
li r8, 0x00
beqlr
lwz r17, PSA.IndexPtr(r1)
lhz r19, 0x0002(r17)
addi r19, r19, 0x200
rlwinm r20, r19, 25, 23, 29
addi r20, r20, 0x08
sth r19, 0x0002(r17)
stwx r18, r20, r17
sth r19, 0x0000(r18)
li r9, 0x1fa
sth r9, 0x0002(r18)
lis r9, 0x4944
ori r9, r9, 0x7320
stw r9, 0x0004(r18)
li r19, 0x00
mr r8, r21
mr r9, r22
addi r22, r18, 0x08
@_f0
stw r8, 0x0004(r22)
stb r9, 0x0000(r22)
lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1)
addi r9, r9, 0x01
stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1)
lhz r20, 0x0000(r18)
lhz r8, 0x0002(r22)
lwz r21, PSA.IndexPtr(r1)
add r19, r19, r20
addi r8, r8, 0x01
lhz r20, 0x0002(r18)
sth r8, 0x0002(r22)
addi r20, r20, -0x01
rlwimi. r8, r19, 16, 0, 15
sth r20, 0x0002(r18)
sth r19, 0x0000(r21)
bnelr+
lhz r8, 0x0002(r22)
addi r8, r8, 0x01
sth r8, 0x0002(r22)
rlwimi r8, r19, 16, 0, 15
blr
; ARG ID r8
align 5
DeleteID
rlwinm r20, r8, 9, 23, 29
lwz r18, PSA.IndexPtr(r1)
addi r20, r20, 0x08
rlwinm. r19, r8, 16, 23, 31
lwzx r18, r18, r20
cmplwi cr1, r19, 0x1fa
cmpwi r18, 0x00
addi r20, r18, 0x08
slwi r22, r19, 3
add r22, r22, r20
clrlwi r20, r8, 0x10
li r8, 0x00
bgelr cr1
beqlr
lbz r19, 0x0000(r22)
lhz r23, 0x0002(r22)
cmpwi r19, 0x00
cmpw cr1, r23, r20
beqlr
bnelr cr1
lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1)
addi r9, r9, -0x01
stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1)
lhz r20, 0x0002(r18)
stb r8, 0x0000(r22)
addi r20, r20, 0x01
li r8, 0x01
sth r20, 0x0002(r18)
blr
; ARG ID r8
; RET Ptr r8, IDClass r9
align 5
LookupID
rlwinm r20, r8, 9, 23, 29
lwz r18, PSA.IndexPtr(r1)
addi r20, r20, 0x08
rlwinm. r19, r8, 16, 23, 31
lwzx r18, r18, r20
cmplwi cr1, r19, 0x1fa
cmpwi r18, 0x00
addi r20, r18, 0x08
slwi r22, r19, 3
add r22, r22, r20
clrlwi r20, r8, 0x10
li r8, 0x00
li r9, 0x00
bgelr cr1
beqlr
lbz r19, 0x0000(r22)
lhz r23, 0x0002(r22)
cmpwi r19, 0x00
cmpw cr1, r23, r20
beqlr
bnelr cr1
lwz r8, 0x0004(r22)
mr r9, r19
blr
; ARG ID r8, IDClass r9
; RET ID r8
align 5
GetNextIDOfClass
rlwinm r20, r8, 9, 23, 29
lwz r18, PSA.IndexPtr(r1)
addi r20, r20, 0x08
rlwinm. r19, r8, 16, 23, 31
lwzx r18, r18, r20
cmplwi cr1, r19, 0x1fa
cmpwi r18, 0x00
cmpwi cr2, r8, 0x00
addi r20, r18, 0x08
slwi r22, r19, 3
li r8, 0x00
bgelr cr1
beqlr
add r22, r22, r20
bne cr2, @_48
@_3c
lbz r23, 0x0000(r22)
cmpwi r23, 0x00
bne @_8c
@_48
addi r19, r19, 0x01
cmpwi r19, 0x1fa
addi r22, r22, 0x08
blt @_3c
lhz r20, 0x0000(r18)
addi r20, r20, 0x200
rlwinm. r20, r20, 25, 23, 29
lwz r18, PSA.IndexPtr(r1)
beqlr
addi r20, r20, 0x08
li r19, 0x00
lwzx r18, r18, r20
cmpwi r18, 0x00
addi r22, r18, 0x08
bne @_3c
li r8, 0x00
blr
@_8c
cmpwi r9, 0x00
cmpw cr1, r9, r23
beq @_9c
bne cr1, @_48
@_9c
lhz r20, 0x0000(r18)
lhz r8, 0x0002(r22)
add r19, r19, r20
rlwimi r8, r19, 16, 0, 15
blr

2604
NanoKernel/NKInit.s Normal file → Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1162
NanoKernel/NKLegacyVM.s Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,304 +1,337 @@
MACRO
_log &s
BL @paststring
STRING AsIs
DC.B &s, 0, 0
ALIGN 2
MACRO
_log &s
BL @paststring
STRING AsIs
DC.B &s, 0, 0
ALIGN 2
@paststring
mflr r8
BL PrintS
ENDM
mflr r8
BL PrintS
ENDM
; Cool macro for one-line debug calls
MACRO
_wlog &s1, &reg, &s2, &scratch==r8
; Cool macro for one-line debug calls
MACRO
_wlog &s1, &reg, &s2, &scratch==r8
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
mr &scratch, r8
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
mr &scratch, r8
_log &s1
_log '[ '
_log &s1
_log '[ '
mr r8, &reg
bl PrintW
mr r8, &reg
bl PrintW
_log ']'
_log &s2
_log ']'
_log &s2
mr r8, &scratch
endif
mr r8, &scratch
endif
ENDM
ENDM
MACRO
_wlogh &s1, &reg, &s2, &scratch==r8
MACRO
_wlogh &s1, &reg, &s2, &scratch==r8
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
mr &scratch, r8
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
mr &scratch, r8
_log &s1
_log '[ '
_log &s1
_log '[ '
mr r8, &reg
bl PrintH
mr r8, &reg
bl PrintH
_log ']'
_log &s2
_log ']'
_log &s2
mr r8, &scratch
endif
mr r8, &scratch
endif
ENDM
ENDM
MACRO
_clog &s
MACRO
_clog &s
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
_log &s
endif
if &TYPE('ExtraNKLogging') != 'UNDEFINED'
_log &s
endif
ENDM
ENDM
MACRO
LHHI &reg, &val
lis (&reg), ((&val) >> 16) & 0xffff
ENDM
MACRO
LHHI &reg, &val
lis (&reg), ((&val) >> 16) & 0xffff
ENDM
MACRO
LLHI &reg, &val
ori (&reg), (&reg), (&val) & 0xffff
ENDM
MACRO
LLHI &reg, &val
ori (&reg), (&reg), (&val) & 0xffff
ENDM
MACRO
lisori &reg, &val
lis &reg, ((&val) >> 16) & 0xffff
ori &reg, &reg, (&val) & 0xffff
ENDM
MACRO
lisori &reg, &val
lis &reg, ((&val) >> 16) & 0xffff
ori &reg, &reg, (&val) & 0xffff
ENDM
MACRO
llabel &reg, &val
lisori &reg, &val - NKTop
ENDM
MACRO
llabel &reg, &val
lisori &reg, &val - CodeBase
ENDM
MACRO
_lstart &reg, &val
LHHI (&reg), (&val)
HalfLoadedWord set (&val)
HalfLoadedReg set (&reg)
ENDM
MACRO
_lstart &reg, &val
LHHI (&reg), (&val)
HalfLoadedWord set (&val)
HalfLoadedReg set (&reg)
ENDM
MACRO
_lfinish
LLHI HalfLoadedReg, HalfLoadedWord
ENDM
MACRO
_lfinish
LLHI HalfLoadedReg, HalfLoadedWord
ENDM
MACRO
InitList &ptr, &sig, &scratch==r8
_lstart &scratch, &sig
stw &ptr, LLL.Next(&ptr)
_lfinish
stw &ptr, LLL.Prev(&ptr)
stw &scratch, LLL.Signature(&ptr)
ENDM
MACRO
InitList &ptr, &sig, &scratch==r8
_lstart &scratch, &sig
stw &ptr, LLL.Next(&ptr)
_lfinish
stw &ptr, LLL.Prev(&ptr)
stw &scratch, LLL.Signature(&ptr)
ENDM
; Next is 8, Prev is C
; Next is 8, Prev is C
MACRO
InsertAsPrev &el, &next, &scratch==r18
MACRO
InsertAsPrev &el, &next, &scratch==r18
stw &next, LLL.Next(&el)
lwz &scratch, LLL.Prev(&next)
stw &scratch, LLL.Prev(&el)
stw &el, LLL.Next(&scratch)
stw &el, LLL.Prev(&next)
stw &next, LLL.Next(&el)
lwz &scratch, LLL.Prev(&next)
stw &scratch, LLL.Prev(&el)
stw &el, LLL.Next(&scratch)
stw &el, LLL.Prev(&next)
ENDM
ENDM
MACRO
InsertAsNext &el, &prev, &scratch==r18
MACRO
InsertAsNext &el, &prev, &scratch==r18
stw &prev, LLL.Prev(&el)
lwz &scratch, LLL.Next(&prev)
stw &scratch, LLL.Next(&el)
stw &el, LLL.Prev(&scratch)
stw &el, LLL.Next(&prev)
stw &prev, LLL.Prev(&el)
lwz &scratch, LLL.Next(&prev)
stw &scratch, LLL.Next(&el)
stw &el, LLL.Prev(&scratch)
stw &el, LLL.Next(&prev)
ENDM
ENDM
MACRO
RemoveFromList &el, &scratch1==r17, &scratch2==r18
MACRO
RemoveFromList &el, &scratch1==r17, &scratch2==r18
; Point neighbours of el up and down at each other
lwz &scratch1, 8(&el)
lwz &scratch2, 12(&el)
stw &scratch1, 8(&scratch2)
stw &scratch2, 12(&scratch1)
; Point neighbours of el up and down at each other
lwz &scratch1, 8(&el)
lwz &scratch2, 12(&el)
stw &scratch1, 8(&scratch2)
stw &scratch2, 12(&scratch1)
; Zero out the pointers in el
li &scratch1, 0
stw &scratch1, 8(&el)
stw &scratch1, 12(&el)
; Zero out the pointers in el
li &scratch1, 0
stw &scratch1, 8(&el)
stw &scratch1, 12(&el)
ENDM
ENDM
MACRO
_Lock &lockoffset, &scratch1==r17, &scratch2==r18
mr &scratch1, r8
mr &scratch2, r9
addi r8, r1, &lockoffset
bl AcquireLock
mr r8, &scratch1
mr r9, &scratch2
ENDM
MACRO
_Lock &lockoffset, &scratch1==r17, &scratch2==r18
mr &scratch1, r8
mr &scratch2, r9
addi r8, r1, &lockoffset
bl AcquireLock
mr r8, &scratch1
mr r9, &scratch2
ENDM
MACRO
_AssertAndRelease &lockoffset, &scratch==r18
sync
lwz &scratch, &lockoffset(r1)
cmpwi cr1, &scratch, 0
li &scratch, 0
bne+ cr1, @okay
mflr &scratch
bl panic
MACRO
_AssertAndRelease &lockoffset, &scratch==r18
sync
lwz &scratch, &lockoffset(r1)
cmpwi cr1, &scratch, 0
li &scratch, 0
bne+ cr1, @okay
mflr &scratch
bl panic
@okay stw &scratch, &lockoffset(r1)
ENDM
@okay stw &scratch, &lockoffset(r1)
ENDM
MACRO
_bset &dest, &src, &bit
MACRO
_set &dest, &src, &bit
IF &bit < 16
oris&dot &dest, &src, 1 << (15 - (&bit))
ELSE
ori&dot &dest, &src, 1 << (31 - (&bit))
ENDIF
IF &bit < 16
oris&dot &dest, &src, 1 << (15 - (&bit))
ELSE
ori&dot &dest, &src, 1 << (31 - (&bit))
ENDIF
ENDM
ENDM
MACRO
_bclr &dest, &src, &bit
MACRO
_clear &dest, &src, &bit
_bclr_rbit set &bit+1
if _bclr_rbit > 31
_bclr_rbit set 0
endif
_clear_rbit set &bit+1
if _clear_rbit > 31
_clear_rbit set 0
endif
_bclr_lbit set &bit-1
if _bclr_lbit < 0
_bclr_lbit set 31
endif
_clear_lbit set &bit-1
if _clear_lbit < 0
_clear_lbit set 31
endif
rlwinm&dot &dest, &src, 0, _bclr_rbit, _bclr_lbit
rlwinm&dot &dest, &src, 0, _clear_rbit, _clear_lbit
ENDM
ENDM
MACRO
_band &dest, &src, &bit
MACRO
_band &dest, &src, &bit
IF &bit < 16
andis&dot &dest, &src, 1 << (15 - (&bit))
ELSE
andi&dot &dest, &src, 1 << (31 - (&bit))
ENDIF
IF &bit < 16
andis&dot &dest, &src, 1 << (15 - (&bit))
ELSE
andi&dot &dest, &src, 1 << (31 - (&bit))
ENDIF
ENDM
ENDM
MACRO
_b_if_time_gt &lhi, &rhi, &targ
MACRO
_b_if_time_gt &lhi, &rhi, &targ
cmpw &lhi, &rhi
cmplw cr1, &lhi + 1, &rhi + 1
bgt &targ
blt @fallthru
bgt cr1, &targ
cmpw &lhi, &rhi
cmplw cr1, &lhi + 1, &rhi + 1
bgt &targ
blt @fallthru
bgt cr1, &targ
@fallthru
ENDM
ENDM
MACRO
_b_if_time_le &lhi, &rhi, &targ
MACRO
_b_if_time_le &lhi, &rhi, &targ
cmpw &lhi, &rhi
cmplw cr1, &lhi + 1, &rhi + 1
blt &targ
bgt @fallthru
ble cr1, &targ
cmpw &lhi, &rhi
cmplw cr1, &lhi + 1, &rhi + 1
blt &targ
bgt @fallthru
ble cr1, &targ
@fallthru
ENDM
ENDM
MACRO
_RegRangeToContextBlock &first, &last
MACRO
_RegRangeToContextBlock &first, &last
stw &first, $104+8*(&first)(r6)
stw &first, $104+8*(&first)(r6)
IF &first != &last
_RegRangeToContextBlock &first+1, &last
ENDIF
IF &first != &last
_RegRangeToContextBlock &first+1, &last
ENDIF
ENDM
ENDM
MACRO
_RegRangeFromContextBlock &first, &last
MACRO
_RegRangeFromContextBlock &first, &last
lwz &first, $104+8*(&first)(r6)
lwz &first, $104+8*(&first)(r6)
IF &first != &last
_RegRangeFromContextBlock &first+1, &last
ENDIF
IF &first != &last
_RegRangeFromContextBlock &first+1, &last
ENDIF
ENDM
ENDM
MACRO
_FloatRangeToContextBlock &first, &last
MACRO
_FloatRangeToContextBlock &first, &last
stfd &first, ContextBlock.FloatRegisters+8*(&first)(r6)
stfd &first, CB.FloatRegisters+8*(&first)(r6)
IF &first != &last
_FloatRangeToContextBlock &first+1, &last
ENDIF
IF &first != &last
_FloatRangeToContextBlock &first+1, &last
ENDIF
ENDM
ENDM
MACRO
_FloatRangeFromContextBlock &first, &last
MACRO
_FloatRangeFromContextBlock &first, &last
lfd &first, ContextBlock.FloatRegisters+8*(&first)(r6)
lfd &first, CB.FloatRegisters+8*(&first)(r6)
IF &first != &last
_FloatRangeFromContextBlock &first+1, &last
ENDIF
IF &first != &last
_FloatRangeFromContextBlock &first+1, &last
ENDIF
ENDM
ENDM
MACRO
_InvalNCBPointerCache &scratch==r0, &offset==0
MACRO
_InvalNCBPointerCache &scratch==r0, &offset==0
IF &offset = 0
li &scratch, -1
ENDIF
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
IF KDP.NCBPointerCache + &offset < KDP.NCBPointerCacheEnd
stw &scratch, KDP.NCBPointerCache + &offset(r1)
_InvalNCBPointerCache scratch=&scratch, offset=(&offset+8)
ENDIF
ENDM
ENDM
MACRO
_kaddr &rd, &rs, &label
addi &rd, &rs, (&label-CodeBase)
ENDM
MACRO
_alignToCacheBlock
IF (*-CodeBase) & 0x1f
b * + 4
_alignToCacheBlock
ENDIF
ENDM
MACRO
_align &arg
my_align set 1 << (&arg)
my_mask set my_align - 1
my_offset set * - CodeBase
my_pad set (my_align - (my_offset & my_mask)) & my_mask
IF my_pad
dcb.l my_pad>>2, 0x48000004
ENDIF
ENDM

28
NanoKernel/NKMakeFile Normal file
View File

@ -0,0 +1,28 @@
# I expect these variables to be set already:
# NKDir, NKIncDir, NKBin
NKFiles = ¶
{NKDir}NanoKernel.s ¶
{NKDir}NKStructs.s ¶
{NKDir}NKEquates.s ¶
{NKDir}NKMacros.s ¶
{NKDir}NKInit.s ¶
{NKDir}NKSystemCrash.s ¶
{NKDir}NKHotInts.s ¶
{NKDir}NKColdInts.s ¶
{NKDir}MROptabCode.s ¶
{NKDir}MRMemtabCode.s ¶
{NKDir}MRInterrupts.s ¶
{NKDir}MROptab.s ¶
{NKDir}MRMemtab.s ¶
{NKDir}MRRestab.s ¶
{NKDir}NKMemory.s ¶
{NKDir}NKExceptions.s ¶
{NKDir}NKFloatingPt.s ¶
{NKDir}NKSoftInts.s ¶
{NKDir}NKReset.s ¶
{NKDir}NKLegacyVM.s ¶
# We get warning 3202 from ALIGN directives -- kill it
{NKBin} Ä {NKDir}NanoKernel.s {NKFiles}
PPCAsm -o {Targ} -w 3202 -i {NKIncDir} -i "{AIncludes}" {NKDir}NanoKernel.s

549
NanoKernel/NKMemory.s Normal file
View File

@ -0,0 +1,549 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKSystemCrash
; SystemCrash
; EXPORTS:
; FlushTLB (=> NKReset)
; GetPhysical (=> MRInterrupts, NKSoftInts)
; PutPTE (=> MRInterrupts, NKColdInts, NKLegacyVM, NKReset)
; SetMap (=> NKReset)
########################################################################
########################################################################
PutPTE ; EA r27 // PTE r30/r31, EQ=Success, GT=Invalid, LT=Fault
lwz r29, KDP.CurMap.SegMapPtr(r1)
rlwinm r28, r27, 7, 0x0000000F << 3 ; convert segment of passed ptr to offset into SegMap
lwzx r29, r29, r28 ; r29 = ptr to start of segment in PageMap
rlwinm r28, r27, 20, 0x0000FFFF ; r27 = page index within SegMap
lhz r30, PME.LBase(r29)
b @find_pme
@try_next_pme ; Point r29 to the PageMapEntry that concerns this page
lhzu r30, 8(r29) ; get another PME.LBase
@find_pme
lhz r31, PME.PageCount(r29)
subf r30, r30, r28 ; r30 = page index within area
cmplw cr7, r30, r31
bgt cr7, @try_next_pme
lwz r28, KDP.HtabTempEntryPtr(r1) ; (remove temp PTE if present)
lwz r31, PME.PBaseAndFlags(r29)
cmpwi cr7, r28, 0 ; (remove temp PTE if present)
extlwi. r26, r31, 2, 20 ; DaddyFlag and CountingFlag in top bits
bne cr7, @remove_temp_pte ; (remove temp PTE if present)
blt @daddy_flag ; >>>>> DaddyFlag = 1
@return_remove_temp_pte ; (optimized: if LT then to jumps to @daddy_flag)
bgt @create_temp_pte ; >>>>> DaddyFlag = 0, CountingFlag = 1
; fallthru ; >>>>> DaddyFlag = 0, CountingFlag = 0
########################################################################
; CODE TO CREATE A PAGE TABLE ENTRY
; <<<<< Fallthru from main entry point (top two flags of PME are zero)
slwi r28, r30, 12
add r31, r31, r28 ; r31 = physical page ptr plus 12 bits of PageMapEntry flags
@return_daddy_flag ; <<<<< @daddy_flag comes here
@return_create_temp_pte ; <<<<< @create_temp_pte comes here (r31=pageptr, r26=0x5A5A)
mfsrin r30, r27 ; HASH FUNCTION: get address of PTEG
rlwinm r28, r27, 26, 10, 25 ; r28 = (1st arg of XOR) * 64b
rlwinm r30, r30, 6, 7, 25 ; r30 = (2nd arg of XOR) * 64b
xor r28, r28, r30 ; r28 (hash output * 64b) = r28 ^ r30
lwz r30, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r30
or. r29, r29, r28 ; result (PTEG address) into r29
@retry_other_pteg ; <<<<< @no_blanks_in_pteg can return here after doing sec'dary hash
lwz r30, 0(r29) ; Take address of PTEG in r29, find empty/"invalid" PTE within (optimized!)
lwz r28, 8(r29)
cmpwi cr6, r30, 0
lwz r30, 16(r29)
cmpwi cr7, r28, 0
lwzu r28, 24(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
lwzu r30, 8(r29)
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
lwzu r28, 8(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
lwzu r30, 8(r29)
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
lwzu r28, 8(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
addi r29, r29, 8
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
addi r29, r29, 8
bge cr6, @found_blank_pte
rlwinm r28, r31, 0, 26, 26 ; wImg bit in PTE???
addi r29, r29, 8 ; Leave PTE + 24 in r29
blt cr7, @no_blanks_in_pteg ; >>>>> This might cause PutPTE to return an error (BNE)
@found_blank_pte ; Take PTE address (plus 24) in r29, draft PTE[lo] in r31
cmpwi r26, 0 ; NOTE: top bit of r31 will be set if sec'dary hash func was used
mfsrin r28, r27
extrwi r30, r27, 6, 4 ; PTE[API/26-31] taken from upper 6 bits of offset-within-segment
stw r27, KDP.HtabLastEA(r1)
ori r31, r31, 0x100 ; set PTE[R(eference)]
rlwimi r30, r31, 27, 25, 25 ; set PTE[H(ash func ID)] to cheeky topmost bit of the phys addr in r31
rlwinm r31, r31, 0, 21, 19 ; unset upper reserved bit in PTE[lo]
insrwi r30, r28, 24, 1 ; get PTE[VSID] from segment register
stw r31, -20(r29) ; PTE[lo] = r31
oris r30, r30, 0x8000 ; set PTE[V(alid)]
sync ; because we just wanged the page table
stwu r30, -24(r29) ; PTE[hi] = r30
lwz r28, KDP.NKInfo.HashTableCreateCount(r1)
stw r29, KDP.ApproxCurrentPTEG(r1)
addi r28, r28, 1
stw r28, KDP.NKInfo.HashTableCreateCount(r1)
beqlr ; >>>>> RETURN "BEQ" if we got to "Case 1" directly
cmpwi r26, 0x5A5A ; Special value set so that we take note of this new temporary PTE?
bne @notemp
stw r29, KDP.HtabTempEntryPtr(r1)
cmpw r29, r29 ; >>>>> RETURN "BEQ" if we got to "Case 1" via @create_temp_pte
blr
@notemp
lwz r28, 0(r26) ; Otherwise, we got here via @daddy_flag? Looks nonsensical.
lwz r30, KDP.HTABORG(r1)
ori r28, r28, 0x801
subf r30, r30, r29
cmpw r29, r29
rlwimi r28, r30, 9, 0, 19
stw r28, 0(r26)
blr ; >>>>> RETURN "BEQ" otherwise
########################################################################
; Helpful code that jumps back to roughly where it started
@remove_temp_pte
lwz r28, KDP.NKInfo.HashTableDeleteCount(r1)
lwz r29, KDP.HtabTempEntryPtr(r1)
addi r28, r28, 1
stw r28, KDP.NKInfo.HashTableDeleteCount(r1)
li r28, 0
stw r28, 0(r29)
lwz r29, KDP.HtabTempPage(r1)
stw r28, KDP.HtabTempPage(r1)
stw r28, KDP.HtabTempEntryPtr(r1)
sync
tlbie r29
sync
bge @return_remove_temp_pte ; Optimization: would otherwise branch to a "blt @daddy_flag"
########################################################################
; r30 = page index within area, r31 = PBaseAndFlags
@daddy_flag
extlwi. r28, r31, 2, 21 ; top bits of r28 = CountingFlag, PhysicalIsRelativeFlag
bge @return_via_pf2 ; if !CountingFlag: return (if !PIRFlag: via PF2)
rlwinm r28, r30, 2, 0xFFFFFFFC ; r28 = pageIdxInArea * 4
rlwinm r26, r31, 22, 0xFFFFFFFC ; r26 = PIRFlag << 31 | BtmBit << 22 | physBase * 4
lwzux r28, r26, r28 ; this makes no sense!!
lwz r31, KDP.PageAttributeInit(r1)
andi. r30, r28, 0x881
rlwimi r31, r28, 0, 0xFFFFF000
cmplwi r30, 1
cmplwi cr7, r30, 0x81
ori r31, r31, 0x100
rlwimi r31, r28, 3, 24, 24
rlwimi r31, r28, 31, 26, 26
rlwimi r31, r28, 1, 25, 25
xori r31, r31, 0x40
rlwimi r31, r28, 30, 31, 31
beq @return_daddy_flag
bltlr cr7
bl SystemCrash
########################################################################
; Helpful code that jumps back to roughly where it started
@create_temp_pte ; Make "temp" PageMapEntry, when flags look like 0x800
ori r28, r27, 0xfff ; r27 = passed ptr, r31 = PBaseAndFlags
stw r28, KDP.HtabTempPage(r1)
rlwinm r31, r31, 0, 22, 19 ; clear CountingFlag in r31
li r26, 0x5A5A ; set magic number in r26 so that KDP.HtabTempEntryPtr gets set
b @return_create_temp_pte
########################################################################
; Helpful return code for @daddy_flag
@return_via_pf2
bgtlr
addi r29, r1, KDP.SupervisorMap
b SetMap
########################################################################
; So try the secondary hashing function, if we haven't already
@no_blanks_in_pteg
cmplw cr6, r28, r26
subi r29, r29, 64 + 16
ble cr6, @search_for_matching_pte
crnot cr0_eq, cr0_eq
lwz r30, KDP.PTEGMask(r1)
xori r31, r31, 0x800
xor r29, r29, r30
beq @retry_other_pteg
########################################################################
@search_for_matching_pte ; r29 = full PTEG
lwz r26, KDP.OverflowingPTEG(r1) ; this could be zero
crclr cr6_eq ; prepare to return "failure"
rlwimi r26, r29, 0, -64
addi r29, r26, 8
b @first_pte
@rethink_pte_search
bne cr6, @next_pte
mr r26, r29
@next_pte
cmpw cr6, r29, r26
addi r29, r29, 8
@first_pte
rlwimi r29, r26, 0, 0, 25
lwz r31, 4(r29)
lwz r30, 0(r29)
beq cr6, @got_pte
rlwinm r28, r31, 30, 25, 25
andc. r28, r28, r30 ; R && !H (i.e. page has been read and is not in "secondary hash" PTEG)
bne @next_pte ; if so,
@got_pte
########################################################################
clrlwi r28, r31, 30
cmpwi cr7, r28, 0
clrrwi r28, r31, 12
cmpw r28, r1
lwz r30, KDP.ContextPtr(r1)
beq cr7, @rethink_pte_search
addi r31, r30, 768-1
beq @rethink_pte_search
rlwinm r30, r30, 0, 0xFFFFF000
cmpwi cr7, r28, 30
lwz r30, 0(r29)
rlwinm r31, r31, 0, 0xFFFFF000
cmpwi r28, 31
rlwinm r31, r30, 0, 0x00000040
beq cr7, @rethink_pte_search
extlwi r28, r30, 4, 1
beq @rethink_pte_search
neg r31, r31
insrwi r28, r30, 6, 4
xor r31, r31, r29
rlwimi r28, r30, 5, 10, 19
rlwinm r31, r31, 6, 10, 19
xor r28, r28, r31
lwz r26, KDP.CurMap.SegMapPtr(r1)
rlwinm r30, r28, (32-25), 0x00000078
lwzx r26, r26, r30 ; r26 pts into PageMap @ current segment
@tinyloop ; find the last non-blank PME in the segment
lhz r30, PME.LBase(r26)
rlwinm r31, r28, 20, 0x0000FFFF
subf r30, r30, r31
lhz r31, PME.PageCount(r26)
addi r26, r26, 8
cmplw cr7, r30, r31
lwz r31, PME.PBaseAndFlags - 8(r26)
andi. r31, r31, 0xe01
cmpwi r31, 0xa01
bgt cr7, @tinyloop
beq @tinyloop
lwz r26, PME.PBaseAndFlags - 8(r26) ; got that PME (26)
slwi r30, r30, 2
extrwi r31, r26, 2, 20
cmpwi cr7, r31, 3 ; not a DaddyFlag + CountingFlag? Try again!
lwz r31, KDP.NKInfo.HashTableOverflowCount(r1)
stw r29, KDP.OverflowingPTEG(r1)
addi r31, r31, 1
stw r31, KDP.NKInfo.HashTableOverflowCount(r1)
lwz r31, KDP.NKInfo.HashTableDeleteCount(r1)
stw r30, 0(r29)
addi r31, r31, 1
stw r31, KDP.NKInfo.HashTableDeleteCount(r1)
sync
tlbie r28
sync
_InvalNCBPointerCache scratch=r28
bne cr7, PutPTE ; not a DaddyFlag + CountingFlag? Retriable...
rlwinm r26, r26, 22, 0xFFFFFFFC ; PIRFlag << 31 | BtmBit << 22 | physBase * 4
lwzux r28, r26, r30
lwz r31, 4(r29)
andi. r30, r28, 0x800
rlwinm r30, r28, (32-9), 0x007FFFF8
xor r30, r30, r29
beq SystemCrash
andi. r30, r30, 0xffff
xori r28, r28, 0x800
bne SystemCrash
rlwimi r28, r31, 0, 0, 19 ; r28 = EA of victim of overflow
rlwimi r28, r31, 29, 27, 27
rlwimi r28, r31, 27, 28, 28
stw r28, 0(r26)
b PutPTE
########################################################################
########################################################################
SetMap ; MemMap r29
lwz r28, MemMap.SegMapPtr(r29)
stw r28, KDP.CurMap.SegMapPtr(r1)
addi r28, r28, 16*8 + 4
lis r31, 0
@next_seg ; SEGMENT REGISTERS
lwzu r30, -8(r28)
subis r31, r31, 0x1000
mr. r31, r31
mtsrin r30, r31
bne @next_seg
mfpvr r31
lwz r28, MemMap.BatMap(r29)
andis. r31, r31, 0xFFFE
addi r29, r1, 0
stw r28, KDP.CurMap.BatMap(r1)
beq @601
rlwimi r29, r28, 7, 0x00000078 ; BATS, non-601
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat0u, r30
mtspr ibat0l, r31
stw r30, KDP.CurIBAT0.U(r1)
stw r31, KDP.CurIBAT0.L(r1)
rlwimi r29, r28, 11, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat1u, r30
mtspr ibat1l, r31
stw r30, KDP.CurIBAT1.U(r1)
stw r31, KDP.CurIBAT1.L(r1)
rlwimi r29, r28, 15, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat2u, r30
mtspr ibat2l, r31
stw r30, KDP.CurIBAT2.U(r1)
stw r31, KDP.CurIBAT2.L(r1)
rlwimi r29, r28, 19, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat3u, r30
mtspr ibat3l, r31
stw r30, KDP.CurIBAT3.U(r1)
stw r31, KDP.CurIBAT3.L(r1)
rlwimi r29, r28, 23, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat0u, r30
mtspr dbat0l, r31
stw r30, KDP.CurDBAT0.U(r1)
stw r31, KDP.CurDBAT0.L(r1)
rlwimi r29, r28, 27, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat1u, r30
mtspr dbat1l, r31
stw r30, KDP.CurDBAT1.U(r1)
stw r31, KDP.CurDBAT1.L(r1)
rlwimi r29, r28, 31, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat2u, r30
mtspr dbat2l, r31
stw r30, KDP.CurDBAT2.U(r1)
stw r31, KDP.CurDBAT2.L(r1)
rlwimi r29, r28, 3, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat3u, r30
mtspr dbat3l, r31
stw r30, KDP.CurDBAT3.U(r1)
stw r31, KDP.CurDBAT3.L(r1)
cmpw r29, r29
blr
@601
rlwimi r29, r28, 7, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0300(r1)
stw r31, 0x0304(r1)
stw r30, 0x0320(r1)
stw r31, 0x0324(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat0u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat0l, r31
rlwimi r29, r28, 11, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0308(r1)
stw r31, 0x030c(r1)
stw r30, 0x0328(r1)
stw r31, 0x032c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat1u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat1l, r31
rlwimi r29, r28, 15, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0310(r1)
stw r31, 0x0314(r1)
stw r30, 0x0330(r1)
stw r31, 0x0334(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat2u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat2l, r31
rlwimi r29, r28, 19, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0318(r1)
stw r31, 0x031c(r1)
stw r30, 0x0338(r1)
stw r31, 0x033c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat3u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat3l, r31
cmpw r29, r29
blr
########################################################################
########################################################################
GetPhysical ; EA r27, batPtr r29 // PA r31, EQ=Fail
lwz r30, 0(r29)
li r28, -1
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
bne GetPhysicalFromHTAB
@_54
andi. r31, r30, 1
rlwinm r28, r28, 0, 8, 19
lwzu r31, 4(r29)
and r28, r27, r28
or r31, r31, r28
bnelr
GetPhysicalFromHTAB ; EA r27 // PA r31, EQ=Fail
mfsrin r31, r27
rlwinm r30, r27, 10, 26, 31
rlwimi r30, r31, 7, 1, 24
rlwinm r28, r27, 26, 10, 25
oris r30, r30, 0x8000
rlwinm r31, r31, 6, 7, 25
xor r28, r28, r31
lwz r31, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r31
or. r29, r29, r28
@_2c
lwz r31, 0(r29)
lwz r28, 8(r29)
cmpw cr6, r30, r31
lwz r31, 16(r29)
cmpw cr7, r30, r28
lwzu r28, 24(r29)
bne cr6, @_50
@_48
lwzu r31, -0x0014(r29)
blr
@_50
cmpw cr6, r30, r31
lwzu r31, 8(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 8(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, 8(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 8(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, -0x000c(r29)
beqlr cr7
cmpw cr7, r30, r28
lwzu r31, 8(r29)
beqlr cr6
lwzu r31, 8(r29)
beqlr cr7
lwz r31, KDP.PTEGMask(r1)
xori r30, r30, 0x40
andi. r28, r30, 0x40
addi r29, r29, -0x3c
xor r29, r29, r31
bne @_2c
blr
########################################################################
########################################################################
FlushTLB
lhz r29, KDP.ProcInfo.TransCacheTotalSize(r1)
slwi r29, r29, 11
@loop
subi r29, r29, 4096
cmpwi r29, 0
tlbie r29
bgt @loop
sync
blr

View File

@ -1,743 +0,0 @@
Local_Panic set *
b panic
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKAddressSpaces
; FindAreaAbove
; MPCall_95_0x254
; SpaceGetPagePLE
; NKConsoleLog
; printw
; NKThud
; panic
; EXPORTS:
; PagingFlushTLB (=> NKInit, NKScheduler, NKSleep)
; PagingFunc1 (=> NKInit, NKInterrupts, NKThud, NKVMCalls)
; PagingFunc2 (=> NKInit)
; PagingFunc2AndAHalf (=> NKSleep)
; PagingL2PWithBATs (=> NKInterrupts, NKMPCalls, NKRTASCalls, NKSleep)
; PagingL2PWithoutBATs (=> NKInit, NKScreenConsole, NKThud)
align 5
PagingFunc1 ; OUTSIDE REFERER
mfsprg r29, 0
mflr r28
stw r8, -0x00dc(r29)
mfcr r8
stw r9, -0x00d8(r29)
stw r8, -0x00a4(r29)
stw r14, -0x00d4(r29)
stw r15, -0x00d0(r29)
stw r16, -0x00cc(r29)
stw r17, -0x00c8(r29)
stw r18, -0x00c4(r29)
stw r19, -0x00c0(r29)
stw r20, -0x00bc(r29)
stw r21, -0x00b8(r29)
stw r22, -0x00b4(r29)
stw r28, -0x00e0(r29)
b @_88
@_44
mfsprg r29, 0
lwz r8, -0x00a4(r29)
lwz r28, -0x00e0(r29)
mtcrf 0x7f, r8
lwz r8, -0x00dc(r29)
mtlr r28
lwz r9, -0x00d8(r29)
lwz r14, -0x00d4(r29)
lwz r15, -0x00d0(r29)
lwz r16, -0x00cc(r29)
lwz r17, -0x00c8(r29)
lwz r18, -0x00c4(r29)
lwz r19, -0x00c0(r29)
lwz r20, -0x00bc(r29)
lwz r21, -0x00b8(r29)
lwz r22, -0x00b4(r29)
blr
@_88
mfsprg r30, 0
mr r9, r27
lwz r8, -0x001c(r30)
bl FindAreaAbove
mr r31, r8
stw r8, EWA.SpecialAreaPtr(r30)
stw r27, -0x00e8(r30)
lwz r16, 0x0024(r31)
lwz r17, 0x0020(r31)
cmplw r16, r27
lwz r18, 0x007c(r31)
bgt @_1a0
bgt @_44
and r28, r27, r18
rlwinm. r26, r17, 0, 16, 16
lwz r17, 0x0038(r31)
beq @_fc
lwz r18, 0x0070(r31)
subf r19, r16, r28
clrlwi r31, r18, 0x1e
cmpwi cr7, r17, -0x01
cmpwi cr6, r31, 0x00
beq cr7, @_1a0
beq cr6, @_44
cmpwi r17, 0x01
add r31, r18, r19
blt @_44
li r26, 0x00
b @_208
@_fc
mr r8, r27
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
lwz r28, 0x0000(r30)
mr r26, r30
mr r8, r27
bl MPCall_95_0x254
beq @_12c
lhz r16, 0x0000(r30)
rlwinm. r8, r16, 0, 16, 16
bne @_12c
srwi r16, r16, 1
sth r16, 0x0000(r30)
@_12c
lwz r8, 0x0024(r31)
lwz r9, 0x06b4(r1)
cmpwi r8, 0x00
cmpwi cr6, r9, 0x00
li r8, 0x801
li r9, 0x01
bne @_154
beq cr6, @_154
li r8, 0x881
li r9, 0x81
@_154
lwz r31, 0x0688(r1)
and. r30, r28, r8
rlwimi r31, r28, 0, 0, 19
cmplwi cr6, r30, 0x800
cmplwi r30, 0x01
bge cr6, @_2ec
cmplw cr7, r30, r9
ori r31, r31, 0x100
rlwimi r31, r28, 28, 28, 28
rlwimi r31, r28, 3, 24, 24
rlwimi r31, r28, 31, 26, 26
rlwimi r31, r28, 1, 25, 25
xori r31, r31, 0x40
rlwimi r31, r28, 30, 31, 31
rlwimi r31, r28, 0, 30, 30
xori r31, r31, 0x02
beq @_208
blt cr7, @_44
bl Local_Panic
@_1a0
lwz r29, 0x05e8(r1)
rlwinm r28, r27, 7, 25, 28
lwzx r29, r29, r28
rlwinm r28, r27, 20, 16, 31
lhz r30, 0x0000(r29)
b @_1bc
@_1b8
lhzu r30, 0x0008(r29)
@_1bc
lhz r31, 0x0002(r29)
subf r30, r30, r28
cmplw cr7, r30, r31
bgt cr7, @_1b8
lwz r28, 0x0690(r1)
lwz r31, 0x0004(r29)
cmpwi cr7, r28, 0x00
bnel cr7, @_314
rlwinm. r26, r31, 23, 29, 30
cmplwi cr7, r26, 0x06
beq @_200
cmplwi cr6, r26, 0x02
beq cr7, @_368
beq cr6, @_3b8
b @_44
; Dead code:
blt @_360
bgt @_3b8
@_200
slwi r28, r30, 12
add r31, r31, r28
@_208
mfsrin r30, r27
rlwinm r28, r27, 26, 10, 25
rlwinm r30, r30, 6, 7, 25
xor r28, r28, r30
lwz r30, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r30
or. r29, r29, r28
@_228
lwz r30, 0x0000(r29)
lwz r28, 0x0008(r29)
cmpwi cr6, r30, 0x00
lwz r30, 0x0010(r29)
cmpwi cr7, r28, 0x00
lwzu r28, 0x0018(r29)
bge cr6, @_298
cmpwi cr6, r30, 0x00
lwzu r30, 0x0008(r29)
bge cr7, @_298
cmpwi cr7, r28, 0x00
lwzu r28, 0x0008(r29)
bge cr6, @_298
cmpwi cr6, r30, 0x00
lwzu r30, 0x0008(r29)
bge cr7, @_298
cmpwi cr7, r28, 0x00
lwzu r28, 0x0008(r29)
bge cr6, @_298
cmpwi cr6, r30, 0x00
addi r29, r29, 0x08
bge cr7, @_298
cmpwi cr7, r28, 0x00
addi r29, r29, 0x08
bge cr6, @_298
rlwinm r28, r31, 0, 26, 26
addi r29, r29, 0x08
blt cr7, @_3e0
@_298
cmpwi r26, 0x00
mfsrin r28, r27
rlwinm r30, r27, 10, 26, 31
stw r27, 0x0694(r1)
oris r30, r30, 0x8000
ori r31, r31, 0x100
rlwimi r30, r31, 27, 25, 25
rlwinm r31, r31, 0, 21, 19
rlwimi r30, r28, 7, 1, 24
stw r31, -0x0014(r29)
eieio
stwu r30, -0x0018(r29)
sync
lwz r28, 0x0e94(r1)
stw r29, 0x0698(r1)
addi r28, r28, 0x01
stw r28, 0x0e94(r1)
beq @_44
cmpwi r26, 0x5a5a
bne @_2f4
stw r29, 0x0690(r1)
@_2ec
cmpw r29, r29
b @_44
@_2f4
lwz r28, 0x0000(r26)
lwz r30, KDP.HTABORG(r1)
ori r28, r28, 0x800
subf r30, r30, r29
cmpw r29, r29
rlwimi r28, r30, 9, 0, 19
stw r28, 0x0000(r26)
b @_44
@_314
lwz r28, 0x0e98(r1)
lwz r29, 0x0690(r1)
addi r28, r28, 0x01
stw r28, 0x0e98(r1)
li r28, 0x00
stw r28, 0x0000(r29)
lwz r29, 0x068c(r1)
stw r28, 0x068c(r1)
stw r28, 0x0690(r1)
mfspr r28, pvr
rlwinm. r28, r28, 0, 0, 14
sync
tlbie r29
beq @_354
sync
tlbsync
@_354
sync
isync
blr
; Dead code:
@_360
rlwinm. r28, r31, 21, 0, 1
bge @_3cc
@_368
slwi r28, r30, 2
rlwinm r26, r31, 22, 0, 29
lwzux r28, r26, r28
lwz r31, 0x0688(r1)
andi. r30, r28, 0x881
rlwimi r31, r28, 0, 0, 19
cmplwi cr6, r30, 0x800
cmplwi cr7, r30, 0x81
cmplwi r30, 0x01
bge cr6, @_2ec
cmplwi cr7, r30, 0x81
ori r31, r31, 0x100
rlwimi r31, r28, 3, 24, 24
rlwimi r31, r28, 31, 26, 26
rlwimi r31, r28, 1, 25, 25
xori r31, r31, 0x40
rlwimi r31, r28, 30, 31, 31
beq @_208
blt cr7, @_44
bl Local_Panic
@_3b8
ori r28, r27, 0xfff
stw r28, 0x068c(r1)
rlwinm r31, r31, 0, 22, 19
li r26, 0x5a5a
b @_208
; Dead code:
@_3cc
bgt @_44
bl Local_Panic
addi r29, r1, KDP.SegMap32SupInitPtr
bl PagingFunc2
b @_44
@_3e0
cmplw cr6, r28, r26
addi r29, r29, -0x50
ble cr6, @_400
crnot 2, 2
lwz r30, KDP.PTEGMask(r1)
xori r31, r31, 0x800
xor r29, r29, r30
beq @_228
@_400
lwz r26, 0x069c(r1)
crclr cr6_eq
rlwimi r26, r29, 0, 0, 25
li r9, 0x08
addi r29, r26, 0x08
b @_428
; Dead code:
@_418
bne cr6, @_420
mr r26, r29
@_420
cmpw cr6, r29, r26
addi r29, r29, 0x08
@_428
rlwimi r29, r26, 0, 0, 25
lwz r31, 0x0004(r29)
lwz r30, 0x0000(r29)
beq cr6, @_444
rlwinm r28, r31, 30, 25, 25
andc. r28, r28, r30
bne @_420
@_444
addi r9, r9, -0x01
cmpwi cr7, r9, 0x00
rlwinm r31, r30, 0, 25, 25
blel cr7, Local_Panic
rlwinm r28, r30, 1, 0, 3
neg r31, r31
rlwimi r28, r30, 22, 4, 9
xor r31, r31, r29
rlwimi r28, r30, 5, 10, 19
rlwinm r31, r31, 6, 10, 19
xor r28, r28, r31
xoris r30, r30, 0x8000
lwz r31, 0x0e9c(r1)
stw r29, 0x069c(r1)
addi r31, r31, 0x01
stw r31, 0x0e9c(r1)
lwz r31, 0x0e98(r1)
stw r30, 0x0000(r29)
addi r31, r31, 0x01
stw r31, 0x0e98(r1)
sync
mfspr r31, pvr
rlwinm. r31, r31, 0, 0, 14
tlbie r28
beq @_4b0
sync
tlbsync
@_4b0
sync
isync
_InvalNCBPointerCache scratch=r8
mfsprg r8, 0
mr r9, r28
lwz r8, -0x001c(r8)
bl FindAreaAbove
lwz r16, 0x0024(r8)
mr r31, r8
cmplw r16, r28
mr r8, r28
bgt @_600
bgt Local_Panic
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
mr r26, r30
beql @_88
@_500
lwz r28, 0x0000(r26)
lwz r31, 0x0004(r29)
andi. r30, r28, 0x800
rlwinm r30, r28, 23, 9, 28
xor r30, r30, r29
beq Local_Panic
andi. r30, r30, 0xffff
xori r28, r28, 0x800
bne Local_Panic
rlwimi r28, r31, 0, 0, 19
rlwimi r28, r31, 29, 27, 27
rlwimi r28, r31, 27, 28, 28
stw r28, 0x0000(r26)
bl @_88
_log 'PTEG overflow: EA '
mr r8, r27
bl Printw
_log 'Victim EA: '
mr r8, r28
bl Printw
_log 'MapInfo: '
mr r8, r29
bl Printw
lwz r16, 0x0000(r26)
mr r8, r26
bl Printw
mr r8, r16
bl Printw
_log ' PTE: '
lwz r16, 0x0000(r29)
lwz r17, 0x0004(r29)
mr r8, r29
bl Printw
mr r8, r16
bl Printw
mr r8, r17
bl Printw
_log '^n'
bl @_88
@_600
lwz r26, 0x05e8(r1)
rlwinm r30, r28, 7, 25, 28
lwzx r26, r26, r30
@_60c
lhz r30, 0x0000(r26)
rlwinm r31, r28, 20, 16, 31
subf r30, r30, r31
lhz r31, 0x0002(r26)
addi r26, r26, 0x08
cmplw cr7, r30, r31
lwz r31, -0x0004(r26)
andi. r31, r31, 0xe01
cmpwi r31, 0xa01
bgt cr7, @_60c
beq @_60c
lwz r26, -0x0004(r26)
slwi r30, r30, 2
rlwinm r31, r26, 22, 30, 31
cmpwi cr7, r31, 0x03
rlwinm r26, r26, 22, 0, 29
add r26, r26, r30
bnel cr7, @_88
b @_500
PagingFunc2 ; OUTSIDE REFERER
sync
isync
lwz r28, 0x0000(r29)
stw r28, 0x05e8(r1)
addi r28, r28, 0x84
lis r31, 0x00
@_18
lwzu r30, -0x0008(r28)
addis r31, r31, -0x1000
mr. r31, r31
mtsrin r30, r31
bne @_18
isync
PagingFunc2AndAHalf
lwz r28, 0x0004(r29)
mfspr r31, pvr
rlwinm. r31, r31, 0, 0, 14
addi r29, r1, 0x00
stw r28, 0x05ec(r1)
beq @_168
li r30, 0x00
mtspr ibat0u, r30
mtspr ibat1u, r30
mtspr ibat2u, r30
mtspr ibat3u, r30
mtspr dbat0u, r30
mtspr dbat1u, r30
mtspr dbat2u, r30
mtspr dbat3u, r30
rlwimi r29, r28, 7, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
rlwinm r31, r31, 0, 29, 27
mtspr ibat0l, r31
mtspr ibat0u, r30
stw r31, 0x0304(r1)
stw r30, 0x0300(r1)
rlwimi r29, r28, 11, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
rlwinm r31, r31, 0, 29, 27
mtspr ibat1l, r31
mtspr ibat1u, r30
stw r31, 0x030c(r1)
stw r30, 0x0308(r1)
rlwimi r29, r28, 15, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
rlwinm r31, r31, 0, 29, 27
mtspr ibat2l, r31
mtspr ibat2u, r30
stw r31, 0x0314(r1)
stw r30, 0x0310(r1)
rlwimi r29, r28, 19, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
rlwinm r31, r31, 0, 29, 27
mtspr ibat3l, r31
mtspr ibat3u, r30
stw r31, 0x031c(r1)
stw r30, 0x0318(r1)
rlwimi r29, r28, 23, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
mtspr dbat0l, r31
mtspr dbat0u, r30
stw r31, 0x0324(r1)
stw r30, 0x0320(r1)
rlwimi r29, r28, 27, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
mtspr dbat1l, r31
mtspr dbat1u, r30
stw r31, 0x032c(r1)
stw r30, 0x0328(r1)
rlwimi r29, r28, 31, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
mtspr dbat2l, r31
mtspr dbat2u, r30
stw r31, 0x0334(r1)
stw r30, 0x0330(r1)
rlwimi r29, r28, 3, 25, 28
lwz r31, 0x0284(r29)
lwz r30, 0x0280(r29)
mtspr dbat3l, r31
mtspr dbat3u, r30
stw r31, 0x033c(r1)
stw r30, 0x0338(r1)
isync
cmpw r29, r29
blr
@_168
rlwimi r29, r28, 7, 25, 28
lwz r30, 0x0280(r29)
lwz r31, 0x0284(r29)
stw r30, 0x0300(r1)
stw r31, 0x0304(r1)
stw r30, 0x0320(r1)
stw r31, 0x0324(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat0u, r30
lwz r30, 0x0280(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat0l, r31
rlwimi r29, r28, 11, 25, 28
lwz r30, 0x0280(r29)
lwz r31, 0x0284(r29)
stw r30, 0x0308(r1)
stw r31, 0x030c(r1)
stw r30, 0x0328(r1)
stw r31, 0x032c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat1u, r30
lwz r30, 0x0280(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat1l, r31
rlwimi r29, r28, 15, 25, 28
lwz r30, 0x0280(r29)
lwz r31, 0x0284(r29)
stw r30, 0x0310(r1)
stw r31, 0x0314(r1)
stw r30, 0x0330(r1)
stw r31, 0x0334(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat2u, r30
lwz r30, 0x0280(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat2l, r31
rlwimi r29, r28, 19, 25, 28
lwz r30, 0x0280(r29)
lwz r31, 0x0284(r29)
stw r30, 0x0318(r1)
stw r31, 0x031c(r1)
stw r30, 0x0338(r1)
stw r31, 0x033c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat3u, r30
lwz r30, 0x0280(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat3l, r31
cmpw r29, r29
blr
PagingL2PWithBATs ; OUTSIDE REFERER
lwz r30, 0x0000(r29)
li r28, -0x01
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 0x0008(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 0x0008(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 0x0008(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
bne PagingL2PWithoutBATs
@_54
andi. r31, r30, 0x01
rlwinm r28, r28, 0, 8, 19
lwzu r31, 0x0004(r29)
and r28, r27, r28
or r31, r31, r28
bnelr
PagingL2PWithoutBATs ; OUTSIDE REFERER
mfsrin r31, r27
rlwinm r30, r27, 10, 26, 31
rlwimi r30, r31, 7, 1, 24
rlwinm r28, r27, 26, 10, 25
oris r30, r30, 0x8000
rlwinm r31, r31, 6, 7, 25
xor r28, r28, r31
lwz r31, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r31
or. r29, r29, r28
@_2c
lwz r31, 0x0000(r29)
lwz r28, 0x0008(r29)
cmpw cr6, r30, r31
lwz r31, 0x0010(r29)
cmpw cr7, r30, r28
lwzu r28, 0x0018(r29)
bne cr6, @_50
@_48
lwzu r31, -0x0014(r29)
blr
@_50
cmpw cr6, r30, r31
lwzu r31, 0x0008(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 0x0008(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, 0x0008(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 0x0008(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, -0x000c(r29)
beqlr cr7
cmpw cr7, r30, r28
lwzu r31, 0x0008(r29)
beqlr cr6
lwzu r31, 0x0008(r29)
beqlr cr7
lwz r31, KDP.PTEGMask(r1)
xori r30, r30, 0x40
andi. r28, r30, 0x40
addi r29, r29, -0x3c
xor r29, r29, r31
bne @_2c
blr
pb equ 12
PagingFlushTLB ; OUTSIDE REFERER
lhz r29, KDP.ProcessorInfo + NKProcessorInfo.TransCacheTotalSize(r1)
slwi r29, r29, pb
@loop
subi r29, r29, 1 << pb
cmpwi r29, 0
tlbie r29
bgt @loop
mfspr r29, pvr
rlwinm. r29, r29, 0, 0, 14
; All cpus
sync
beqlr
; Non-601 stuff
tlbsync
sync
isync
blr

View File

@ -1,695 +0,0 @@
; SEGMENTS
;
; The pool is made up of segments of contiguous memory. The first segment
; to be created is about 25k, running from 0x7000 below r1 to the start of
; the Primary System Area. It is initialised by InitPool. Every subsequent
; segment occupies a single page, plucked from the system free list by
; ExtendPool.
;
;
; BLOCKS
;
; Each segment is an array of variously sized blocks, with no gaps between
; them. The first block is a Begin (‡BGN) block, the last block is an End
; block (‡END), and all others are Allocated (‡loc) or Free (free) blocks.
; To allow the data in each Allocated block to be 16b-aligned, all
; Allocated and Free blocks start 8b below a 16b boundary.
;
;
; SINGLY LINKED LIST OF SEGMENTS
;
; PSA.FirstPoolSeg points to the start of the most recently added pool
; segment, i.e. to its Begin block. The OffsetToNext field of a Begin
; block points not to the block immediately beyond it in memory, but to
; the segment's End block. The OffsetToNext field of the End block points
; to the start of the next most recently added pool segment. If there is
; none, it contains zero.
;
;
; DOUBLY LINKED LIST OF FREE BLOCKS
;
; Every free block is a member of PSA.FreePool, a doubly linked list of
; free segments. The "LLL" structure occupies the first 16 bytes of the
; block.
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKConsoleLog
; printc
; printd
; printw
; NKThud
; panic
; EXPORTS:
; ExtendPool (=> NKMPCalls)
; InitPool (=> NKInit)
; PoolAlloc (=> NKInterrupts, NKSync, NKTasks)
; PoolAllocClear (=> NKAddressSpaces, NKIndex, NKInit, NKMPCalls, NKSync, NKTasks, NKTimers, NKVMCalls)
; PoolFree (=> NKAddressSpaces, NKMPCalls, NKSync, NKTasks, NKTimers)
Block record
kBeginSize equ 8
kEndSize equ 24
kPoolSig equ 'POOL'
kBeginSig equ 'BGN'
kEndSig equ 'END'
kAllocSig equ 'loc'
kFreeSig equ 'free'
; For free and allocated blocks, points to the next block
; For begin blocks, points to corresponding end block
; For end blocks, points to another begin block (or zero)
OffsetToNext ds.l 1 ; 0
Signature ds.l 1 ; 4
Data
LogiNextSeg
FreeNext ds.l 1 ; 8
FreePrev ds.l 1 ; c
endr
_PoolPanic
b panic
; Use all the memory from r1 - 0x7000 to PSA
InitPool
; Add first segment to global singly linked list
lwz r8, KDP.PA_ConfigInfo(r1)
lwz r8, NKConfigurationInfo.LA_KernelData(r8)
lisori r9, -kPoolOffsetFromGlobals
subf r9, r9, r8
stw r9, PSA.FirstPoolSegLogical(r1)
lisori r9, kPoolOffsetFromGlobals
add r9, r9, r1
stw r9, PSA.FirstPoolSeg(r1)
; Decide how big the segment will be
_pool_first_seg equ PSA.Base - kPoolOffsetFromGlobals
; Begin block (leave ptr to End in r23)
lisori r8, _pool_first_seg - Block.kEndSize
add r23, r8, r9
stw r8, Block.OffsetToNext(r9)
lisori r8, Block.kBeginSig
stw r8, Block.Signature(r9)
; Free block (leave ptr in r9)
addi r9, r9, Block.kBeginSize
lisori r8, _pool_first_seg - Block.kEndSize - Block.kBeginSize
stw r8, Block.OffsetToNext(r9)
lisori r8, Block.kFreeSig
stw r8, Block.Signature(r9)
; End block
li r8, 0
stw r8, Block.OffsetToNext(r23)
lisori r8, Block.kEndSig
stw r8, Block.Signature(r23)
; Add Free block to global doubly linked list
addi r8, r1, PSA.FreePool
stw r9, Block.FreeNext(r8)
stw r9, Block.FreePrev(r8)
stw r8, Block.FreeNext(r9)
stw r8, Block.FreePrev(r9)
lisori r9, Block.kPoolSig
stw r9, Block.Signature(r8)
; Return
blr
; The NanoKernel's malloc
; ARG size r8
; RET ptr r8
_poolalloc_noclr_cr_bit equ 30
PoolAllocClear
crclr _poolalloc_noclr_cr_bit
b _PoolAllocCommon
PoolAlloc
crset _poolalloc_noclr_cr_bit
_PoolAllocCommon
; Save LR and arg to EWA. Get lock.
mflr r17
mfsprg r18, 0
_Lock PSA.PoolLock, scratch1=r15, scratch2=r16
; These saves are my first real hint at the contents of that
; large unexplored area of the EWA. This file, then, owns
; part of the EWA, for its CPU-scoped globals. Because the
; kernel runs stackless.
stw r17, EWA.PoolSavedLR(r18)
stw r8, EWA.PoolSavedSizeArg(r18)
@recheck_for_new_block
; Sanity checks
cmpwi r8, 0
cmpwi cr1, r8, 0xfd8
ble _PoolPanic
bgt cr1, @request_too_large
; Up-align to 32b boundary and snatch an extra 8b
; This is our minimum OffsetToNext field
addi r8, r8, 8 + 31
rlwinm r8, r8, 0, 0xffffffe0
; Iterate the free-block list
addi r14, r1, PSA.FreePool
lwz r15, LLL.Next(r14)
@next_block
cmpw r14, r15
bne+ @try_block
; Global free-block list is empty (not great news)
; Got a free page in the system free list? It's ours.
li r8, 0 ; return zero if there is no page at all
li r9, 1 ; number of pages to grab
lwz r16, PSA.FreePageCount(r1)
lwz r17, PSA.UnheldFreePageCount(r1)
subf. r16, r9, r16
subf r17, r9, r17
blt _PoolReturn
stw r16, PSA.FreePageCount(r1)
stw r17, PSA.UnheldFreePageCount(r1)
; Get that page, mofo. Macros FTW.
lwz r8, PSA.FreeList + LLL.Next(r1)
RemoveFromList r8, scratch1=r17, scratch2=r18
; There was probably once a mechanism for virtual addressing of the pool!
li r9, 0
bl ExtendPool ; r8=page, r9=virt=0
; Now that the pool is not empty, start over.
mfsprg r18, 0
lwz r8, EWA.PoolSavedSizeArg(r18)
b @recheck_for_new_block
; Request was greater than the maximum block size
@request_too_large
li r8, 0
b _PoolReturn
; Try the free block that r15 points to
@try_block
@retry_newly_expanded_block
lwz r16, Block.OffsetToNext(r15)
cmplw r16, r8
lis r20, 'fr'
bgt @decide_whether_to_split
beq @do_not_split
ori r20, r20, 'ee'
; This block is too small to fit our allocation, but can it be mashed together
; with a physically adjacent free block? This might happen a few times before
; we decide to give up and search for another block.
lwz r16, Block.OffsetToNext(r15)
add r18, r16, r15
lwz r19, Block.Signature(r18)
cmplw cr1, r18, r15
cmpw r19, r20
ble cr1, _PoolPanic
bne @physically_adjacent_block_is_not_free
lwz r17, Block.OffsetToNext(r18)
rotlwi r19, r19, 8
add r17, r17, r16
stw r17, Block.OffsetToNext(r15)
stw r19, Block.Signature(r18) ; scramble old signature to clarify mem dumps
lwz r17, Block.FreePrev(r18)
lwz r16, Block.FreeNext(r18)
stw r16, Block.FreeNext(r17)
stw r17, Block.FreePrev(r16)
b @retry_newly_expanded_block
@physically_adjacent_block_is_not_free
lwz r15, Block.FreeNext(r15)
b @next_block
; Success: split the block if there is >=40b left over
@decide_whether_to_split
subf r16, r8, r16
cmpwi r16, 40
blt @do_not_split
; Use the rightmost part of the block, leaving ptr in r15
; (Leaving the leftmost part saves us touching the free block list)
stw r16, Block.OffsetToNext(r15)
add r15, r15, r16
stw r8, Block.OffsetToNext(r15)
b @proceed_with_block
; Success: use the entire block, leaving ptr in r15
@do_not_split
lwz r14, 0x000c(r15)
lwz r16, LLL.Next(r15)
stw r16, LLL.Next(r14)
stw r14, 0x000c(r16)
; Sign the block and return data ptr in r8
@proceed_with_block
lisori r8, Block.kAllocSig
stw r8, Block.Signature(r15)
addi r8, r15, Block.Data
; Optionally clear the block (quicker if we don't)
bc BO_IF, _poolalloc_noclr_cr_bit, _PoolReturn
lwz r16, Block.OffsetToNext(r15)
subi r16, r16, Block.Data
li r14, 0
add r16, r16, r15
addi r15, r15, 4
@clrloop
stwu r14, 4(r15)
cmpw r15, r16
ble @clrloop
b _PoolReturn
; The NanoKernel's free
; ARG r8 = ptr to contents of pool block
PoolFree
mflr r17
mfsprg r18, 0
_Lock PSA.PoolLock, scratch1=r15, scratch2=r16
stw r17, EWA.PoolSavedLR(r18)
bl _PoolAddBlockToFreeList
bl _PoolMergeAdjacentFreeBlocks
; Fall through...
; PoolAlloc and PoolFree save LR on entry, then return this way
_PoolReturn
mfsprg r18, 0
_AssertAndRelease PSA.PoolLock, scratch=r15
lwz r17, EWA.PoolSavedLR(r18)
mtlr r17
blr
; Re-label an Allocated block as Free, and add it to the global list
; Panics if block is not Allocated to start with!
; ARG r8 = ptr to contents of pool block
; RET r15 = ptr to pool block itself (r8 - 8)
_PoolAddBlockToFreeList
; Get the block containing the data
subi r15, r8, Block.Data
; Change the signature
_lstart r20, Block.kFreeSig
lhz r16, Block.Signature(r15)
_lfinish
cmplwi r16, 0x876c ; Block.kAllocSig >> 16
bne _PoolPanic
stw r20, Block.Signature(r15)
; Insert into the global free block list
addi r16, r1, PSA.FreePool
InsertAsPrev r15, r16, scratch=r17
blr
; Merge a free block with any free blocks to the right
; (Cannot look to the left because list is singly linked)
; ARG r15 = ptr to free block
_PoolMergeAdjacentFreeBlocks
@next_segment
_lstart r20, Block.kFreeSig
lwz r16, Block.OffsetToNext(r15)
_lfinish
add r18, r16, r15 ; r18 = block to the right
lwz r19, Block.Signature(r18) ; r19 = signature of that block
cmplw cr1, r18, r15
cmpw r19, r20
ble cr1, _PoolPanic ; die if block was of non-positive size!
bnelr ; return if block to right is not free
lwz r17, Block.OffsetToNext(r18)
rotlwi r19, r19, 8 ; scramble old signature to clarify mem dumps
add r17, r17, r16
stw r17, Block.OffsetToNext(r15) ; increase the size of the main block
stw r19, Block.Signature(r18)
lwz r17, Block.FreePrev(r18) ; remove the absorbed block from the list of free blocks
lwz r16, Block.FreeNext(r18)
stw r16, Block.FreeNext(r17)
stw r17, Block.FreePrev(r16)
b @next_segment
; Create a new pool segment from a physical page
; ARG PhysPtr r8, LogiPtr r9
ExtendPool
mflr r14
; This segment will occupy a page
_pool_page_seg equ 0x1000
rlwinm r17, r8, 0, -(_pool_page_seg)
; Counter can be viewed from Apple System Profiler
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.FreePoolExtendCount(r1)
addi r16, r16, 1
stw r16, KDP.NanoKernelInfo + NKNanoKernelInfo.FreePoolExtendCount(r1)
; Bit of palaver
_log 'Extend free pool: phys 0x'
mr r8, r17
bl Printw
_log ' virt 0x'
mr r8, r9
bl Printw
_log ' count: '
mr r8, r16
bl Printd
_log '^n'
; Clear the page
li r16, _pool_page_seg
@zeroloop
subi r16, r16, 32
cmpwi r16, 0
dcbz r16, r17
bgt @zeroloop
; Begin block
li r16, _pool_page_seg - Block.kEndSize
stw r16, Block.OffsetToNext(r17)
lisori r16, Block.kBeginSig
stw r16, Block.Signature(r17)
; Alloc block (_PoolAddBlockToFreeList will convert to Free)
addi r15, r17, Block.kBeginSize
li r16, _pool_page_seg - Block.kEndSize - Block.kBeginSize
stw r16, Block.OffsetToNext(r15)
lisori r16, Block.kAllocSig
stw r16, Block.Signature(r15)
; End block
addi r15, r17, _pool_page_seg - Block.kEndSize
lwz r18, PSA.FirstPoolSeg(r1)
subf r18, r15, r18
stw r18, Block.OffsetToNext(r15) ; point to next-most-recently-added segment
lisori r16, Block.kEndSig
stw r16, Block.Signature(r15)
lwz r16, PSA.FirstPoolSegLogical(r1) ; vestigial?
stw r16, Block.LogiNextSeg(r15)
; Add new segment to global singly linked list
stw r9, PSA.FirstPoolSegLogical(r1)
stw r17, PSA.FirstPoolSeg(r1)
; Free the Alloc block and add it to the global doubly linked list
addi r8, r17, Block.kBeginSize + Block.Data
bl _PoolAddBlockToFreeList
; This won't do anything, because there is no other free block in the segment
bl _PoolMergeAdjacentFreeBlocks
; Return
mtlr r14
blr
; Check the pool for corruption (dead code)
PoolCheck
mflr r19
lwz r20, PSA.FirstPoolSeg(r1)
; Check this segment, starting with first Allocated block
@next_segment
addi r8, r20, Block.kBeginSize
bl _PoolCheckBlocks
; Get End block
lwz r17, Block.OffsetToNext(r20)
add r17, r17, r20
; Use that to get another Begin block
lwz r18, Block.OffsetToNext(r17)
cmpwi r18, 0
add r20, r18, r17
bne @next_segment
; If there are no more Begins, we are done
mtlr r19
blr
; Only called by the above function
; Called on data ptrs? Or on block ptrs?
; ARG ptr r8
_PoolCheckBlocks
mflr r14
subi r16, r8, 8 ; Block.kBeginSize or Block.Data?
@loop
lwz r17, Block.Signature(r16)
lisori r18, Block.kEndSig
cmpw r17, r18
li r9, 0
beq @return
lisori r18, Block.kAllocSig
cmpw r17, r18
beq @block_is_allocated
lisori r18, Block.kFreeSig
li r9, 4
cmpw r17, r18
bne @block_corrupt
; From now we assume Free
lwz r17, Block.FreePrev(r16)
cmpwi r17, 0
li r9, 5
beq @block_corrupt
lwz r17, Block.FreeNext(r16)
cmpwi r17, 0
li r9, 6
beq @block_corrupt
@block_is_allocated
;or block is free (fallthru)
lwz r17, Block.OffsetToNext(r16)
add r16, r16, r17
cmpwi r17, 0
li r9, 7
bgt @loop
; 4: neither Allocated nor Free
; 5: Free with bad FreePrev ptr
; 6: Free with bad FreeNext ptr
; 7: bad OffsetToNext ptr
@block_corrupt
mr r18, r8
_log 'Heap segment corrupt '
mr r8, r9
bl Printd
_log 'at '
mr r8, r16
bl Printw
_log '^n'
; Dump some memory
subi r16, r16, 64
li r17, 8 ; 8 lines, 16 bytes each
@dump_next_line
mr r8, r16
bl Printw
_log ' '
lwz r8, 0(r16)
bl Printw
lwz r8, 4(r16)
bl Printw
lwz r8, 8(r16)
bl Printw
lwz r8, 12(r16)
bl Printw
_log ' *'
li r8, 16
subi r16, r16, 1
mtctr r8
@dump_next_char
lbzu r8, 1(r16)
cmpwi r8, ' '
bgt @dont_use_space
li r8, ' '
@dont_use_space
bl Printc
bdnz @dump_next_char
_log '*^n'
subi r17, r17, 1
addi r16, r16, 1
cmpwi r17, 0x00
bne @dump_next_line
mr r8, r18
@return
mtlr r14
blr

View File

@ -1,741 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKCache
; FlushCaches
; NKInterrupts
; IntReturn
; wordfill
; NKThud
; panic
; EXPORTS:
; InitIdleVecTable (=> NKInit)
; kcPowerDispatch (=> NKInit)
#### ## ## #### ######## ## ## ######## ###### ######## ######## ##
## ### ## ## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ###### ## ## ######## ##
## ## #### ## ## ## ## ## ## ## ## ## ##
## ## ### ## ## ## ## ## ## ## ## ## ## ##
#### ## ## #### ## ### ######## ###### ## ######## ########
; When we are asked via a PowerDispatch call to put a CPU into a non-full-
; on pwrmgt state, we will point its SPRG3 to this table. Any of these
; three interrupts will return the CPU to full-on mode, and we will return
; from the PowerDispatch call. Called at NK init time.
align kIntAlign
InitIdleVecTable
mflr r9
llabel r23, panic
add r23, r23, r25
addi r8, r1, PSA.VecBaseIdle
li r22, VecTable.Size
bl wordfill
mtlr r9
llabel r23, IntReturnToFullOn
add r23, r23, r25
stw r23, VecTable.SystemResetVector(r8)
stw r23, VecTable.ExternalIntVector(r8)
stw r23, VecTable.DecrementerVector(r8)
blr
######## #### ###### ######## ### ######## ###### ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ###### ######## ## ## ## ## #########
## ## ## ## ## ######### ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ## ##
######## #### ###### ## ## ## ## ###### ## ##
; Called using 68k `$FE0F` or PPC `twi ... 5`
; ARG selector r3 (0-11), ...
align kIntAlign
kcPowerDispatch
mtcr r7
lwz r4, KDP.TestIntMaskInit(r1)
cmplwi cr7, r3, 11
mr r9, r13
bc BO_IF, 8, @use_provided_mcr
lwz r9, PSA.MCR(r1)
@use_provided_mcr
and. r8, r4, r9
bgt cr7, PowerEarlyReturnError ; invalid selector
bne PowerEarlyReturnSuccess
cmplwi cr7, r3, 11
beq cr7, PwrInfiniteLoop
cmplwi cr7, r3, 8
beq cr7, PwrSuspendSystem
cmplwi cr7, r3, 9
beq cr7, PwrSetICTC
; Fall through to 0-7: PwrIdle
##### ######## #### ######## ## ########
## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ##
## ## ####### ## ## ## ## ## ######
## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ##
##### ## #### ######## ######## ########
; Selector 0-7
; Set the CPU static pwrmgt state to doze, idle or sleep, then return to
; full-on when we get an interrupt.
; ARG r3 & 1: which of the two pre-programmed pwrmgt states to invoke (see NKProcFlagsTbl.s)
; r3 & 4: whether to flush L1 and L2 caches
; Different 603+ chips have static power management states named "doze",
; "nap" and "sleep". A state is selected by setting the corresponding bit
; in HID0. The state is then invoked by setting MSR[POW]. The state is
; ended by a decrementer interrupt (doze/nap only) or external interrupt.
; This is a short term CPU-specific state, *not* system-wide "sleep".
; Because the NK timer code sets the decrementer, we can be sure that we
; will not miss a timer firing.
PwrIdle
; Get us some breathing room
_RegRangeToContextBlock r26, r31
; Activate the interrupt table that will rouse the CPU
mfsprg r31, 3 ; will restore r31 => SPRG3 after state exited
addi r8, r1, PSA.VecBaseIdle
mtsprg 3, r8
; Save argument & 4 (run-cache-code flag)
rlwinm r26, r3, 0, 29, 29
; Choose from the NK's two pre-programmed pwrmgt states for this CPU.
; Fail if we find zero (e.g. on the 601).
; arg pwrmgt state selector => r3
; r3 & 1 0=fail 1=DOZE 2=NAP 3=SLEEP
; ------ ---------------------------
; 0 (CpuSpecificByte1 >> 6) & 3
; 1 (CpuSpecificByte1 >> 4) & 3
clrlwi r3, r3, 30
lbz r8, KDP.CpuSpecificByte1(r1)
slwi r3, r3, 1
addi r3, r3, 26
rlwnm r3, r8, r3, 30, 31
cmpwi r3, 0
beq PowerEarlyRestoreReturnError
; Depending on pre-programmed flags, set:
; HID0[NHR] ("not hard reset" flag)
; HID0[ptrmgt state selected above]
lbz r9, KDP.CpuSpecificByte2(r1)
cmpwi r9, 0
beq @set_neither
mfspr r27, hid0 ; will restore r27 => HID0 when system wakes below
mr r8, r27
cmpwi r9, 1
beq @set_only_nhr
oris r9, r3, 0x0100 ; set bit 7
srw r9, r9, r9 ; shift right by 0-3
rlwimi r8, r9, 0, 8, 10 ; keep bits 8/9/10
@set_only_nhr
oris r8, r8, 1 ; also set NHR
mtspr hid0, r8
@set_neither
; Flush L1 and L2 caches if argument & 4
cmplwi r26, 4
beql FlushCaches
; Set MSR bits to enter the selected pwrmgt state
mfmsr r8
ori r8, r8, 0x8002 ; Always set MSR[EE] and MSR[RI] so we can wake!
cmplwi r3, 0 ; If using HID0[pwrmgt state], set MSR[POW] so it takes effect
beq @no_pow
oris r8, r8, 4
@no_pow
sync ; Apply MSR!
mtmsr r8
isync
; Loop while the state takes effect, then jump 4 bytes forward when we cop an interrupt
b *
IntReturnToFullOn
; Restore HID0 from r27, assuming that we mangled it
lbz r8, KDP.CpuSpecificByte2(r1)
cmpwi r8, 0
beq @hid_was_not_changed
mtspr hid0, r27
@hid_was_not_changed
; Restore registers and return successfully to caller.
; Not sure about the decrementer stuff.
mfsprg r1, 2
mtlr r1
mfsprg r1, 1
lis r9, 0x7fff
mfspr r8, dec
mtspr dec, r9
mtspr dec, r8
li r3, 0
PowerCallRestoreReturn
mtsprg 3, r31 ; saved SPRG3 above
_RegRangeFromContextBlock r26, r31
b IntReturn
; Return islands for other calls
PowerEarlyRestoreReturnError
li r3, -0x7267
b PowerCallRestoreReturn
PowerEarlyReturnSuccess
li r3, 0
b IntReturn
PowerEarlyReturnError
li r3, -1
b IntReturn
####### ###### ## ## ###### ######## ######## ## ## ########
## ## ## ## ## ## ## ## ## ## ## ### ## ## ##
## ## ## ## ## ## ## ## ## #### ## ## ##
####### ###### ## ## ###### ######## ###### ## ## ## ## ##
## ## ## ## ## ## ## ## ## #### ## ##
## ## ## ## ## ## ## ## ## ## ## ### ## ##
####### ###### ####### ###### ## ######## ## ## ########
; Selector 8
; Put this, the last scheduled CPU, into SLEEP mode.
; Save state. Call ActuallySuspend. Restore state. Return.
PwrSuspendSystem
; Cannot sleep if multiple CPUs are scheduled
mfsprg r9, 0
lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9)
lwz r9, CoherenceGroup.ScheduledCpuCount(r8)
cmpwi r9, 1
li r3, -0x7267
bgt IntReturn
; Some breathing room
_RegRangeToContextBlock r26, r31
bl FlushCaches
; Disable both L1 caches (via HID0)
mfspr r9, hid0
rlwinm r9, r9, 0, 18, 16 ; unset HID0[DCE] (data cache enable)
rlwinm r9, r9, 0, 17, 15 ; unset HID0[ICE] (inst cache enable)
mtspr hid0, r9
sync
isync
; Disable L2 cache (via L2CR, if present)
lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
andi. r26, r26, 1 << NKProcessorInfo.hasL2CR
beq @no_need_to_deactivate_l2
mfspr r9, l2cr
clrlwi r9, r9, 1 ; unset L2CR[L2E]
mtspr l2cr, r9
sync
isync
addi r8, r1, PSA.ProcessorState
stw r9, NKProcessorState.saveL2CR(r8)
@no_need_to_deactivate_l2
; Save some GPRs
stw r7, ContextBlock.Flags(r6)
_RegRangeToContextBlock r2, r5
_RegRangeToContextBlock r14, r25
stw r13, ContextBlock.CR(r6)
; Save floats
andi. r8, r11, 0x2000 ; MSR[FP]
beq @no_save_float
mfmsr r8
ori r8, r8, 0x2000 ; ensure that MSR bit is set?
mtmsr r8
isync
_FloatRangeToContextBlock f0, f16
mffs f0
_FloatRangeToContextBlock f17, f31
stfd f0, ContextBlock.PageInSystemHeap(r6) ; ???
@no_save_float
; Save misc SPRs
mfxer r9
addi r16, r1, PSA.ProcessorState
stw r9, ContextBlock.XER(r6)
mfctr r9
stw r9, ContextBlock.CTR(r6)
stw r12, ContextBlock.FE000000(r6)
stw r10, NKProcessorState.saveSRR0(r16)
stw r11, NKProcessorState.saveSRR1(r16)
mfspr r9, hid0
stw r9, NKProcessorState.saveHID0(r16)
; Save timebase
@tb_retry
mftbu r9
stw r9, NKProcessorState.saveTBU(r16)
mftb r9
stw r9, NKProcessorState.saveTBL(r16)
mftbu r8
lwz r9, NKProcessorState.saveTBU(r16)
cmpw r8, r9
bne @tb_retry
; Save MSR
mfmsr r9
stw r9, NKProcessorState.saveMSR(r16)
; Save SDR1
mfspr r9, sdr1
stw r9, NKProcessorState.saveSDR1(r16)
; Save BAT registers
mfspr r9, dbat0u
stw r9, NKProcessorState.saveDBAT0u(r16)
mfspr r9, dbat0l
stw r9, NKProcessorState.saveDBAT0l(r16)
mfspr r9, dbat1u
stw r9, NKProcessorState.saveDBAT1u(r16)
mfspr r9, dbat1l
stw r9, NKProcessorState.saveDBAT1l(r16)
mfspr r9, dbat2u
stw r9, NKProcessorState.saveDBAT2u(r16)
mfspr r9, dbat2l
stw r9, NKProcessorState.saveDBAT2l(r16)
mfspr r9, dbat3u
stw r9, NKProcessorState.saveDBAT3u(r16)
mfspr r9, dbat3l
stw r9, NKProcessorState.saveDBAT3l(r16)
mfspr r9, ibat0u
stw r9, NKProcessorState.saveIBAT0u(r16)
mfspr r9, ibat0l
stw r9, NKProcessorState.saveIBAT0l(r16)
mfspr r9, ibat1u
stw r9, NKProcessorState.saveIBAT1u(r16)
mfspr r9, ibat1l
stw r9, NKProcessorState.saveIBAT1l(r16)
mfspr r9, ibat2u
stw r9, NKProcessorState.saveIBAT2u(r16)
mfspr r9, ibat2l
stw r9, NKProcessorState.saveIBAT2l(r16)
mfspr r9, ibat3u
stw r9, NKProcessorState.saveIBAT3u(r16)
mfspr r9, ibat3l
stw r9, NKProcessorState.saveIBAT3l(r16)
; Save SPRGs
mfsprg r9, 0
stw r9, NKProcessorState.saveSPRG0(r16)
mfsprg r9, 1
stw r9, NKProcessorState.saveSPRG1(r16)
mfsprg r9, 2
stw r9, NKProcessorState.saveSPRG2(r16)
mfsprg r9, 3
stw r9, NKProcessorState.saveSPRG3(r16)
; Save ContextBlock ptr
stw r6, NKProcessorState.saveContextPtr(r16)
; Do the thing. The BL gives us a useful restore address.
bl ActuallySuspend
lwz r1, EWA.r1(r1)
addi r16, r1, PSA.ProcessorState
; Do something evil to the segment registers?
lisori r8, 0x1000000
lis r9, 0
@srin_loop
subis r9, r9, 0x1000
addis r8, r8, -0x10
mr. r9, r9
mtsrin r8, r9
bne @srin_loop
isync
; Reactivate L1 cache
mfspr r9, hid0
li r8, 0x800 ; HID0[ICFI] invalidate icache
ori r8, r8, 0x200 ; HID0[SPD] disable spec cache accesses
or r9, r9, r8
mtspr hid0, r9
isync
andc r9, r9, r8 ; now undo that?
mtspr hid0, r9
isync
ori r9, r9, 0x8000 ; set HID0[ICE]
ori r9, r9, 0x4000 ; set HID0[DCE]
mtspr hid0, r9
isync
; Reactivate L2 cache
lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1)
andi. r26, r26, 1 << NKProcessorInfo.hasL2CR
beq @no_need_to_reactivate_l2
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1)
mr. r8, r8
beq @no_need_to_reactivate_l2
mfspr r9, hid0
rlwinm r9, r9, 0, 12, 10
mtspr hid0, r9
isync
lwz r9, NKProcessorState.saveL2CR(r16)
mtspr l2cr, r9
sync
isync
lis r8, 0x20 ; set L2CR[L2I] to invalidate L2 cache
or r8, r9, r8
mtspr l2cr, r8
sync
isync
; spin while bottom bit (reserved) is set???
@l2_reactivate_loop
mfspr r8, l2cr
rlwinm. r8, r8, 31, 0, 0
bne @l2_reactivate_loop
mfspr r8, l2cr
lisori r9, 0xffdfffff ; unset bit 6 (reserved?)
and r8, r8, r9
mtspr l2cr, r8
sync
mfspr r8, hid0
oris r8, r8, 0x0010 ; set HID0[HIGH_BAT_EN] (was HID0[DOZE])
mtspr hid0, r8
isync
mfspr r8, l2cr
oris r8, r8, 0x8000 ; set L2CR[L2E]
mtspr l2cr, r8
sync
isync
@no_need_to_reactivate_l2
; Still working on this...
lwz r6, NKProcessorState.saveContextPtr(r16)
lwz r7, ContextBlock.Flags(r6)
lwz r13, ContextBlock.CR(r6)
lwz r9, ContextBlock.CTR(r6)
mtctr r9
lwz r12, ContextBlock.FE000000(r6)
lwz r9, ContextBlock.XER(r6)
mtxer r9
lwz r10, NKProcessorState.saveSRR0(r16)
lwz r11, NKProcessorState.saveSRR1(r16)
; Load some GPRs
_RegRangeFromContextBlock r2, r5
_RegRangeFromContextBlock r14, r15
_RegRangeFromContextBlock r17, r31
; Load floats
andi. r8, r11, 0x2000 ; MSR[FP]
beq @no_restore_float
mfmsr r8
ori r8, r8, 0x2000 ; ensure that MSR bit is set?
mtmsr r8
isync
lfd f31, ContextBlock.PageInSystemHeap(r6) ; bit odd
_FloatRangeFromContextBlock f0, f8
mtfsf 0xff, f31
_FloatRangeFromContextBlock f9, f31
@no_restore_float
; Load HID0, plus ICE and DCE bits
lwz r9, NKProcessorState.saveHID0(r16)
ori r9, r9, 0x8000
ori r9, r9, 0x4000
mtspr hid0, r9
sync
isync
; Load timebase
lwz r9, NKProcessorState.saveTBU(r16)
mtspr tbu, r9
lwz r9, NKProcessorState.saveTBL(r16)
mtspr tbl, r9
; Set decrementer quite low?
li r9, 1
mtspr dec, r9
; Load MSR
lwz r9, NKProcessorState.saveMSR(r16)
mtmsr r9
sync
isync
; Load SDR1
lwz r9, NKProcessorState.saveSDR1(r16)
mtspr sdr1, r9
; Load SPRGs
lwz r9, NKProcessorState.saveSPRG0(r16)
mtsprg 0, r9
lwz r9, NKProcessorState.saveSPRG1(r16)
mtsprg 1, r9
lwz r9, NKProcessorState.saveSPRG2(r16)
mtsprg 2, r9
lwz r9, NKProcessorState.saveSPRG3(r16)
mtsprg 3, r9
; Load BAT registers
lwz r9, NKProcessorState.saveDBAT0u(r16)
mtspr dbat0u, r9
lwz r9, NKProcessorState.saveDBAT0l(r16)
mtspr dbat0l, r9
lwz r9, NKProcessorState.saveDBAT1u(r16)
mtspr dbat1u, r9
lwz r9, NKProcessorState.saveDBAT1l(r16)
mtspr dbat1l, r9
lwz r9, NKProcessorState.saveDBAT2u(r16)
mtspr dbat2u, r9
lwz r9, NKProcessorState.saveDBAT2l(r16)
mtspr dbat2l, r9
lwz r9, NKProcessorState.saveDBAT3u(r16)
mtspr dbat3u, r9
lwz r9, NKProcessorState.saveDBAT3l(r16)
mtspr dbat3l, r9
lwz r9, NKProcessorState.saveIBAT0u(r16)
mtspr ibat0u, r9
lwz r9, NKProcessorState.saveIBAT0l(r16)
mtspr ibat0l, r9
lwz r9, NKProcessorState.saveIBAT1u(r16)
mtspr ibat1u, r9
lwz r9, NKProcessorState.saveIBAT1l(r16)
mtspr ibat1l, r9
lwz r9, NKProcessorState.saveIBAT2u(r16)
mtspr ibat2u, r9
lwz r9, NKProcessorState.saveIBAT2l(r16)
mtspr ibat2l, r9
lwz r9, NKProcessorState.saveIBAT3u(r16)
mtspr ibat3u, r9
lwz r9, NKProcessorState.saveIBAT3l(r16)
mtspr ibat3l, r9
; And reclaim the register we were using for ProcessorState
_RegRangeFromContextBlock r16, r16
; Hooray! We're back!
li r3, 0
b IntReturn
### ###### ## ## ###### ######## ######## ## ## ######## ###
## ## ## ## ## ## ## ## ## ## ### ## ## ## ##
## ## ## ## ## ## ## ## #### ## ## ## ##
## ###### ## ## ###### ######## ###### ## ## ## ## ## ##
## ## ## ## ## ## ## ## #### ## ## ##
## ## ## ## ## ## ## ## ## ## ### ## ## ##
### ###### ####### ###### ## ######## ## ## ######## ###
ActuallySuspend
mflr r9
stw r9, NKProcessorState.saveReturnAddr(r16)
stw r1, NKProcessorState.saveKernelDataPtr(r16)
addi r9, r16, NKProcessorState.saveKernelDataPtr - 4 ; so that 4(r9) goes to r1?
li r0, 0
stw r9, 0(0)
lisori r9, 'Lars'
stw r9, 4(0)
mfspr r9, hid0
andis. r9, r9, 0x0020 ; mask: only HID0[SLEEP]
mtspr hid0, r9
mfmsr r8
oris r8, r8, 0x0004 ; set MSR[POW] (but not yet)
mfspr r9, hid0
ori r9, r9, 0x8000 ; set HID0[ICE]
mtspr hid0, r9
; Get address of this table => r9
bl @l
@l mflr r9
addi r9, r9, @table_of_sixteen_zeros - @l
lisori r1, 0xcafebabe
b @evil_aligned_sleep_loop
align 8
@evil_aligned_sleep_loop
sync
mtmsr r8 ; sleep now
isync
cmpwi r1, 0
beq @evil_aligned_sleep_loop ; re-sleep until the world is sane?
lwz r0, 0(r9)
andi. r1, r1, 0
b @evil_aligned_sleep_loop ; actually, there is no escape
align 8
@table_of_sixteen_zeros
dcb.b 16, 0
####### ###### ######## ######## #### ###### ######## ######
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ##
######## ###### ###### ## ## ## ## ##
## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
####### ###### ######## ## #### ###### ## ######
; Selector 9
; Set ICTC (Instruction Cache Throttling Control) register
; (used to reduce temp without adjusting clock)
; ARG value r5
PwrSetICTC
mtspr 1019, r5
li r3, 0
b IntReturn
## ## ## ####### ####### ########
#### #### ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ########
## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ##
###### ###### ######## ####### ####### ##
; Selector 11
PwrInfiniteLoop
b *

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; EXPORTS:
; ProcessorFlagsTable (=> NKInit)
; Contains the table used by Init.s:SetProcessorFlags, and a label to find it with.
;
; Using this table, three fields in KDP are set:
; KDP.CpuSpecificByte1
; KDP.CpuSpecificByte2 (immediately follows Byte1)
; KDP.ProcessorInfo.ProcessorFlags
ProcessorFlagsTable
dcb.b 32 * (1 + 1 + 4), 0
ProcessorFlagsTableEnd
PflgTblCtr set 0
macro
PflgTblEnt &CpuSpecificByte1, &CpuSpecificByte2, &ProcessorFlags
@fb
org ProcessorFlagsTable + PflgTblCtr
dc.b &CpuSpecificByte1
org ProcessorFlagsTable + 32 + PflgTblCtr
dc.b &CpuSpecificByte2
org ProcessorFlagsTable + 64 + 4*PflgTblCtr
dc.l &ProcessorFlags
org @fb
PflgTblCtr set PflgTblCtr + 1
endm
with NKProcessorInfo
; 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
; 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

@ -1,57 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; EXPORTS:
; OverrideProcessorInfo (=> NKBuiltinInit)
; ProcessorInfoTable (=> NKBuiltinInit)
; Contains the table used by InitBuiltin.s:OverrideProcessorInfo
;
; If the Trampoline fails to pass in a signed HardwareInfo struct,
; this is our first choice for populating ProcessorInfo.
;
; Also contains a 'function' that will do the populating
; (not very clever), and fall through to the end of the file,
; where we expect to find Init.s:FinishInitBuiltin.
macro ; just to make the table below look nicer...
PnfoTblEnt &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o
dc.l &a * 1024, &b * 1024, &c * 1024
dc.w &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o
endm
ProcessorInfoTable
; - PageSize, KB
; | - DataCacheTotalSize, KB
; | | - InstCacheTotalSize, KB
; | | | - CoherencyBlockSize
; | | | | - ReservationGranuleSize
; | | | | | - CombinedCaches
; | | | | | | - InstCacheLineSize
; | | | | | | | - DataCacheLineSize
; | | | | | | | | - DataCacheBlockSizeTouch
; | | | | | | | | | - InstCacheBlockSize
; | | | | | | | | | | - DataCacheBlockSize
; | | | | | | | | | | | - InstCacheAssociativity
; | | | | | | | | | | | | - DataCacheAssociativity
; | | | | | | | | | | | | | - TransCacheTotalSize
; | | | | | | | | | | | | | | - TransCacheAssociativity
PnfoTblEnt 4, 32, 32, 32, 32, 1, 64, 64, 32, 32, 32, 8, 8, 256, 2 ; 0001 = 601
PnfoTblEnt 4, 8, 8, 32, 32, 0, 32, 32, 32, 32, 32, 2, 2, 64, 2 ; 0003 = 603
PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 128, 2 ; 0004 = 604
PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 64, 2 ; 0006 = 603e
PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 64, 2 ; 0007 = 750FX
PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 128, 2 ; 0008 = 750
PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 128, 2 ; 0009/a = ???
PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 128, 2 ; 000c = 7400
PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 256, 4 ; 000d = ???
OverrideProcessorInfo
@loop
subic. r9, r9, 4
lwzx r12, r11, r9
stwx r12, r10, r9
bgt @loop

View File

@ -1,192 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKInterrupts
; IntHandleSpecialFPException
; IntReturn
; bugger_around_with_floats
; NKPaging
; PagingL2PWithBATs
; NKThud
; panic
; EXPORTS:
; kcRTASDispatch (=> NKInit)
Local_Panic set *
b panic
; kcRTASDispatch
; Only major that hits the RTAS globals.
; RTAS requires some specific context stuff.
; > r1 = kdp
; > r6 = some kind of place
; > r7 = some kind of flags
align 5
kcRTASDispatch ; OUTSIDE REFERER
lwz r8, 0x0908(r1)
cmpwi r8, 0x00
bne rtas_is_available
li r3, -0x01
b IntReturn
rtas_is_available
_Lock PSA.RTASLock, scratch1=r8, scratch2=r9
mtcrf 0x3f, r7
lwz r9, KDP.PA_ECB(r1)
lwz r8, EWA.Enables(r1)
stw r7, 0x0000(r6)
stw r8, 0x0004(r6)
bns cr6, kcRTASDispatch_0x5c
stw r17, 0x0024(r6)
stw r20, 0x0028(r6)
stw r21, 0x002c(r6)
stw r19, 0x0034(r6)
stw r18, 0x003c(r6)
lmw r14, 0x0038(r1)
kcRTASDispatch_0x5c
mfxer r8
stw r13, 0x00dc(r6)
stw r8, 0x00d4(r6)
stw r12, 0x00ec(r6)
mfctr r8
stw r10, 0x00fc(r6)
stw r8, 0x00f4(r6)
ble cr3, kcRTASDispatch_0x8c
lwz r8, 0x00c4(r9)
mfspr r12, mq
mtspr mq, r8
stw r12, 0x00c4(r6)
kcRTASDispatch_0x8c
lwz r8, 0x0004(r1)
stw r8, 0x010c(r6)
stw r2, 0x0114(r6)
stw r3, 0x011c(r6)
stw r4, 0x0124(r6)
lwz r8, 0x0018(r1)
stw r5, 0x012c(r6)
stw r8, 0x0134(r6)
andi. r8, r11, 0x2000
stw r14, 0x0174(r6)
stw r15, 0x017c(r6)
stw r16, 0x0184(r6)
stw r17, 0x018c(r6)
stw r18, 0x0194(r6)
stw r19, 0x019c(r6)
stw r20, 0x01a4(r6)
stw r21, 0x01ac(r6)
stw r22, 0x01b4(r6)
stw r23, 0x01bc(r6)
stw r24, 0x01c4(r6)
stw r25, 0x01cc(r6)
stw r26, 0x01d4(r6)
stw r27, 0x01dc(r6)
stw r28, 0x01e4(r6)
stw r29, 0x01ec(r6)
stw r30, 0x01f4(r6)
stw r31, 0x01fc(r6)
bnel bugger_around_with_floats
stw r11, 0x00a4(r6)
mr r27, r3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beql Local_Panic
rlwimi r3, r31, 0, 0, 19
lhz r8, 0x0004(r3)
cmpwi r8, 0x00
beq kcRTASDispatch_0x14c
slwi r8, r8, 2
lwzx r27, r8, r3
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beql Local_Panic
lwzx r9, r8, r3
rlwimi r9, r31, 0, 0, 19
stwx r9, r8, r3
li r9, 0x00
sth r9, 0x0004(r3)
dcbf r8, r3
kcRTASDispatch_0x14c
li r9, 0x04
dcbf r9, r3
sync
isync
lwz r4, 0x090c(r1)
mfmsr r8
andi. r8, r8, 0x10cf
mtmsr r8
isync
mr r28, r3
lwz r9, 0x0908(r1)
bl rtas_make_actual_call
mfsprg r1, 0
lwz r6, -0x0014(r1)
clrlwi r29, r28, 0x14
subfic r29, r29, 0x1000
lhz r27, 0x0f4a(r1)
kcRTASDispatch_0x190
subf. r29, r27, r29
dcbf r29, r28
sync
icbi r29, r28
bge kcRTASDispatch_0x190
sync
isync
lwz r8, 0x0000(r6)
lwz r11, 0x00a4(r6)
mr r7, r8
andi. r8, r11, 0x900
lwz r8, 0x0004(r6)
lwz r13, 0x00dc(r6)
stw r8, EWA.Enables(r1)
lwz r8, 0x00d4(r6)
lwz r12, 0x00ec(r6)
mtxer r8
lwz r8, 0x00f4(r6)
lwz r10, 0x00fc(r6)
mtctr r8
bnel IntHandleSpecialFPException
lwz r8, 0x010c(r6)
stw r8, 0x0004(r1)
lwz r2, 0x0114(r6)
lwz r3, 0x011c(r6)
lwz r4, 0x0124(r6)
lwz r8, 0x0134(r6)
lwz r5, 0x012c(r6)
stw r8, 0x0018(r1)
lwz r14, 0x0174(r6)
lwz r15, 0x017c(r6)
lwz r16, 0x0184(r6)
lwz r17, 0x018c(r6)
lwz r18, 0x0194(r6)
lwz r19, 0x019c(r6)
lwz r20, 0x01a4(r6)
lwz r21, 0x01ac(r6)
lwz r22, 0x01b4(r6)
lwz r23, 0x01bc(r6)
lwz r24, 0x01c4(r6)
lwz r25, 0x01cc(r6)
lwz r26, 0x01d4(r6)
lwz r27, 0x01dc(r6)
lwz r28, 0x01e4(r6)
lwz r29, 0x01ec(r6)
lwz r30, 0x01f4(r6)
lwz r31, 0x01fc(r6)
_AssertAndRelease PSA.RTASLock, scratch=r8
li r3, 0x00
b IntReturn
rtas_make_actual_call
mtctr r9
bctr

View File

@ -1,497 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKConsoleLog
; printh
; printw
; NKInit
; CancelReplacement
; InitHighLevel
; InitIRP
; NKPrimaryIntHandlers
; LookupInterruptHandler
; NKScreenConsole
; InitScreenConsole
; NKTranslation
; FDP
; EXPORTS:
; InitReplacement (=> NKInit)
; sprg0 = old KDP/EWA/r1 ptr
; r3 = PA_NanoKernelCode
; r4 = physical base of our global area
; r5 = NoIdeaR23
; r6 = PA_EDP or zero?
; r7 = probably ROMHeader.ROMRelease ('rom vers', e.g. 0x10B5 is 1.0§5)
InitReplacement
crset cr5_eq
li r0, 0
; Position and initialise the kernel globals, IRP to KDP inclusive.
; (subset of builtin kernel)
; Zero from IRP (r4) to KDP (r4 + 10 pages)
lisori r12, kKDPfromIRP
mr r13, r4
@wipeloop
subic. r12, r12, 4
stwx r0, r13, r12
bgt @wipeloop
; Copy the old KDP to r4 + 10 pages.
; (r1 becomes our main ptr and r4 is discarded)
mfsprg r11, 0
lisori r1, kKDPfromIRP
add r1, r1, r4
li r12, 4096
@kdp_copyloop
subic. r12, r12, 4
lwzx r10, r11, r12
stwx r10, r1, r12
bgt @kdp_copyloop
; IRP goes at the base of the area we were given.
; Fill with repeating pattern and point EWA at it.
lisori r12, -kKDPfromIRP
add r12, r12, r1
stw r12, EWA.PA_IRP(r1)
bl InitIRP ; clobbers r10 and r12
; Play with some of the other values we were given
; Leave ROMRelease in r23.
mr r23, r7
; If no EDP (Emulator Data Page) pointer was provided,
; then put the EDP above our new KDP.
cmpwi r6, 0
stw r11, KDP.OldKDP(r1)
stw r9, 0x05a4(r1)
; discarded
bne @emulatordata_ptr_provided
addi r6, r1, 0x1000
@emulatordata_ptr_provided
; Save a few bits
stw r6, 0x05a8(r1)
stw r3, KDP.PA_NanoKernelCode(r1)
stw r5, PSA.NoIdeaR23(r1)
stw r1, EWA.PA_KDP(r1)
addi r12, r1, -0x340 ; get the base of the main CPU struct
li r10, -1
stw r10, CPU.ID(r12)
lwz r3, KDP.PA_ConfigInfo(r1)
bl LookupInterruptHandler
stw r7, KDP.PA_InterruptHandler(r1)
; Clearly changed our mind about where we might be.
bl @x
@x mflr r12
subi r12, r12, @x - NKTop
stw r12, KDP.PA_NanoKernelCode(r1)
; FDP
llabel r10, FDP
add r12, r10, r12
stw r12, KDP.PA_FDP(r1)
; Do something terrible with the CPU features
lwz r12, EWA.Flags(r1)
li r10, 0x00
rlwimi r10, r12, 0, 12, 15
rlwimi r10, r12, 0, 28, 30
stw r10, PSA.FlagsTemplate(r1)
; Cook up a MSR:
; MSR_EE = 1
; MSR_PR = 1
; MSR_FP = 0
; MSR_ME = 0
; MSR_FE0 = 0
; MSR_SE = 0
; MSR_BE = 0
; MSR_FE1 = 0
; MSR_IP = preserved
; MSR_IR = 1
; MSR_DR = 1
; MSR_RI = 0
; MSR_LE = 0
mfmsr r12
andi. r12, r12, 0x0040
ori r12, r12, 0xd032
stw r12, PSA.UserModeMSR(r1)
; Set SPRG0 (for this CPU at least)
mtsprg 0, r1
; r11 still contains the OLD EWA ptr (which is also KDP/PSA ptr?)
lhz r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r11)
cmpwi r12, 0x0101
bgt @replaces_later_than_0101
;
lwz r12, KDP.PA_ECB_Old(r1)
stw r12, EWA.PA_ContextBlock(r1)
lwz r12, 0x660(r1)
oris r12, r12, 0x20
stw r12, EWA.Flags(r1)
lwz r12, 0x0664(r1)
stw r12, EWA.Enables(r1) ; boy, better figure out what this is
b @endif
@replaces_later_than_0101
; Obviously cannot replace a v2 NanoKernel like myself
cmpwi r12, 0x0200
bge CancelReplacement
lwz r12, EWA.PA_ContextBlock(r11)
stw r12, EWA.PA_ContextBlock(r1)
lwz r12, EWA.Flags(r11)
oris r12, r12, 0x20
stw r12, EWA.Flags(r1)
lwz r12, -0x000c(r11)
stw r12, EWA.Enables(r1)
@endif
lwz r12, 0x0340(r11)
lwz r10, KDP.LA_NCB(r11)
cmpw r12, r10
beq replace_old_kernel_0x198
stw r12, KDP.LA_NCB(r1)
stw r0, 0x06b4(r1)
lwz r10, 0x05b0(r11)
stw r10, 0x06c0(r1)
lwz r10, KDP.LA_NCB(r11)
stw r10, 0x06c4(r1)
lwz r10, 0x05b8(r11)
stw r10, 0x06c8(r1)
lwz r10, 0x05bc(r11)
stw r10, 0x06cc(r1)
stw r0, 0x06d0(r1)
stw r0, 0x06d4(r1)
stw r0, 0x06d8(r1)
stw r0, 0x06dc(r1)
stw r0, 0x06e0(r1)
stw r0, 0x06e4(r1)
stw r0, 0x06e8(r1)
stw r0, 0x06ec(r1)
stw r0, 0x06f0(r1)
stw r0, 0x06f4(r1)
stw r0, 0x06f8(r1)
stw r0, 0x06fc(r1)
replace_old_kernel_0x198
; Adjust a few KDP pointers to point into the new KDP
lwz r12, KDP.PA_PageMapStart(r1)
subf r12, r11, r12
add r12, r12, r1
stw r12, KDP.PA_PageMapStart(r1)
lwz r12, KDP.PA_PageMapEnd(r1)
subf r12, r11, r12
add r12, r12, r1
stw r12, KDP.PA_PageMapEnd(r1)
lwz r12, 0x05e8(r1)
subf r12, r11, r12
add r12, r12, r1
stw r12, 0x05e8(r1)
; Wipe KDP's NKInfo and ProcessorInfo
li r12, 0x200
addi r10, r1, KDP.NanoKernelInfo
@wipeloop
subic. r12, r12, 4
stwx r0, r10, r12
bgt @wipeloop
; r9 = physical base of kernel
li r12, 0
addi r10, r1, KDP.InfoRecord
bl MoveRecord ; (NanoKernelCode, NewKDPInfoRecord, OldKDP, 0)
stw r10, KDP.InfoRecord + InfoRecord.InfoRecordPtr(r1)
stw r0, KDP.InfoRecord + InfoRecord.Zero(r1)
lhz r12, KDP.InfoRecord + InfoRecord.NKProcessorStateLen(r1)
addi r10, r1, PSA.ProcessorState
lwz r9, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1)
bl MoveRecord ; (OldProcessorState, NewPSAProcessorState, OldKDP, ProcessorStateLen)
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorStatePtr(r1)
lhz r12, KDP.InfoRecord + InfoRecord.NKHWInfoLen(r1)
lwz r10, EWA.PA_IRP(r1)
addi r10, r10, IRP.HWInfo
lwz r9, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1)
bl MoveRecord ; (OldHWInfo, NewIRPHWInfo, OldKDP, HWInfoLen)
stw r10, KDP.InfoRecord + InfoRecord.NKHWInfoPtr(r1)
lhz r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1)
addi r10, r1, KDP.ProcessorInfo
lwz r9, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1)
bl MoveRecord ; (OldProcessorInfo, NewKDPProcessorInfo, OldKDP, ProcessorInfoLen)
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr(r1)
stw r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoPtr2(r1)
lhz r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1)
cmplwi r10, 0x0112
bge @ProcessorInfo_version_already_current
li r12, 160
li r10, 0x0112
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen(r1)
sth r12, KDP.InfoRecord + InfoRecord.NKProcessorInfoLen2(r1)
sth r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer(r1)
sth r10, KDP.InfoRecord + InfoRecord.NKProcessorInfoVer2(r1)
@ProcessorInfo_version_already_current
lhz r12, KDP.InfoRecord + InfoRecord.NKDiagInfoLen(r1)
addi r10, r1, PSA.DiagInfo
lwz r9, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1)
bl MoveRecord ; (OldDiagInfo, NewPSADiagInfo, OldKDP, DiagInfoLen)
stw r10, KDP.InfoRecord + InfoRecord.NKDiagInfoPtr(r1)
lhz r12, KDP.InfoRecord + InfoRecord.NKSystemInfoLen(r1)
lwz r10, EWA.PA_IRP(r1)
addi r10, r10, IRP.SystemInfo
lwz r9, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1)
bl MoveRecord ; (OldSystemInfo, NewIRPSystemInfo, OldKDP, SystemInfoLen)
stw r10, KDP.InfoRecord + InfoRecord.NKSystemInfoPtr(r1)
lhz r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1)
addi r10, r1, KDP.NanoKernelInfo
lwz r9, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1)
bl MoveRecord ; (OldNanoKernelInfo, NewKDPNanoKernelInfo, OldKDP, NanoKernelInfoLen)
stw r10, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoPtr(r1)
li r12, 0x160
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoLen(r1)
li r12, kNanoKernelVersion
sth r12, KDP.InfoRecord + InfoRecord.NKNanoKernelInfoVer(r1)
lwz r8, KDP.ProcessorInfo + NKProcessorInfo.DecClockRateHz(r1)
stw r8, PSA.DecClockRateHzCopy(r1)
; Play with ConfigFlags
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
_bset r8, r8, 31 ; always set bit 31
if &TYPE('NKShowLog') != 'UNDEFINED'
_bset r8, r8, 28 ; see if someone can test this
endif
cmplwi r23, 0x27f3 ; set bit 27 on ROM 2.7f3 or later
blt @oldrom ; means later than PDM and Cordyceps
_bset r8, r8, 27
@oldrom
stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
; Say hello.
bl InitScreenConsole
_log 'Hello from the replacement multitasking NanoKernel. Version: '
mr r8, r12
bl printh
_log '^n Old KDP: '
mr r8, r11
bl printw
_log ' new KDP: '
mr r8, r1
bl printw
_log ' new irp: '
lwz r8, EWA.PA_IRP(r1)
mr r8, r8
bl printw
_log 'ROM vers: '
mr r8, r23
bl printh
_log '^n'
; Jump back into the common code path of Init.s
; The Emulator ContextBlock is expected in r6.
lwz r6, KDP.PA_ECB(r1)
b InitHighLevel
; MoveRecord
; r9 = base of kernel???
; Seems to be code to relocate some old structures.
MoveRecord ; OUTSIDE REFERER
; Check whether the old structure is in KDP
;
lwz r22, KDP.PA_ConfigInfo(r1)
lwz r22, NKConfigurationInfo.LA_InfoRecord(r22)
subf r9, r22, r9 ; r9 = offset of old address in irp
cmplwi r9, 0x1000
bge @kdp
add r21, r9, r11 ; r21 = the old address if it had been in KDP instead?
@0x18
; r9 = offset of old structure in old parent page
; r10 = destination
; r12 = length
;
@loop
subic. r12, r12, 4
blt @exit_loop
lwzx r9, r21, r12
stwx r9, r10, r12
bgt @loop
@exit_loop
lwz r22, KDP.PA_ConfigInfo(r1)
lwz r22, NKConfigurationInfo.LA_KernelData(r22)
subf r10, r1, r10
lisori r21, -9 * 4096
cmpw r10, r21 ; if dest is nearer than 9 pages below kdp...
blt @0x50
add r10, r10, r22
blr
@0x50
lwz r22, KDP.PA_ConfigInfo(r1)
lwz r22, NKConfigurationInfo.LA_InfoRecord(r22)
lwz r21, EWA.PA_IRP(r1)
add r10, r10, r1
subf r10, r21, r10
add r10, r10, r22
blr
@kdp
add r9, r9, r22
lwz r22, KDP.PA_ConfigInfo(r1)
lwz r22, NKConfigurationInfo.LA_KernelData(r22)
subf r9, r22, r9 ; r9 now equals an offset from old_kdp
add r21, r9, r11 ; r21 = address in new_kdp
b @0x18

469
NanoKernel/NKReset.s Executable file
View File

@ -0,0 +1,469 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MRInterrupts
; MRDataStorageInt
; MRMachineCheckInt
; NKColdInts
; InstStorageInt
; MachineCheckInt
; NKExceptions
; KCallReturnFromException
; NKFloatingPt
; FPUnavailInt
; NKHotInts
; AlignmentInt
; DataStorageInt
; DecrementerIntAlt
; DecrementerIntSys
; ExternalInt0
; ExternalInt1
; ExternalInt2
; NKLegacyVM
; KCallVMDispatch
; NKMemory
; FlushTLB
; PutPTE
; SetMap
; NKSoftInts
; KCallPrioritizeInterrupts
; KCallResetSystem
; KCallRunAlternateContext
; KCallSystemCrash
; ProgramInt
; SyscallInt
; TraceInt
; NKSystemCrash
; SystemCrash
########################################################################
; These registers will be used throughout
rCI set r26
lwz rCI, KDP.ConfigInfoPtr(r1)
rNK set r25
lwz rNK, KDP.CodeBase(r1)
rPgMap set r18
lwz rPgMap, KDP.PageMapStartPtr(r1)
rXER set r17
mfxer rXER
########################################################################
InitVectorTables
; System/Alternate Context tables
_kaddr r23, rNK, SystemCrash
addi r8, r1, KDP.VecTblSystem
li r22, 3 * VecTbl.Size
@vectab_initnext_segment
subic. r22, r22, 4
stwx r23, r8, r22
bne @vectab_initnext_segment
rSys set r9 ; to clarify which table is which
rAlt set r8
addi rSys, r1, KDP.VecTblSystem
mtsprg 3, rSys
addi rAlt, r1, KDP.VecTblAlternate
_kaddr r23, rNK, SystemCrash
stw r23, VecTbl.SystemReset(rSys)
stw r23, VecTbl.SystemReset(rAlt)
_kaddr r23, rNK, MachineCheckInt
stw r23, VecTbl.MachineCheck(rSys)
stw r23, VecTbl.MachineCheck(rAlt)
_kaddr r23, rNK, DataStorageInt
stw r23, VecTbl.DSI(rSys)
stw r23, VecTbl.DSI(rAlt)
_kaddr r23, rNK, InstStorageInt
stw r23, VecTbl.ISI(rSys)
stw r23, VecTbl.ISI(rAlt)
lbz r22, NKConfigurationInfo.InterruptHandlerKind(rCI)
cmpwi r22, 0
_kaddr r23, rNK, ExternalInt0
beq @chosenIntHandler
cmpwi r22, 1
_kaddr r23, rNK, ExternalInt1
beq @chosenIntHandler
cmpwi r22, 2
_kaddr r23, rNK, ExternalInt2
beq @chosenIntHandler
@chosenIntHandler
stw r23, VecTbl.External(rSys)
_kaddr r23, rNK, ProgramInt
stw r23, VecTbl.External(rAlt)
_kaddr r23, rNK, AlignmentInt
stw r23, VecTbl.Alignment(rSys)
stw r23, VecTbl.Alignment(rAlt)
_kaddr r23, rNK, ProgramInt
stw r23, VecTbl.Program(rSys)
stw r23, VecTbl.Program(rAlt)
_kaddr r23, rNK, FPUnavailInt
stw r23, VecTbl.FPUnavail(rSys)
stw r23, VecTbl.FPUnavail(rAlt)
_kaddr r23, rNK, DecrementerIntSys
stw r23, VecTbl.Decrementer(rSys)
_kaddr r23, rNK, DecrementerIntAlt
stw r23, VecTbl.Decrementer(rAlt)
_kaddr r23, rNK, SyscallInt
stw r23, VecTbl.Syscall(rSys)
stw r23, VecTbl.Syscall(rAlt)
_kaddr r23, rNK, TraceInt
stw r23, VecTbl.Trace(rSys)
stw r23, VecTbl.Trace(rAlt)
stw r23, VecTbl.OtherTrace(rSys)
stw r23, VecTbl.OtherTrace(rAlt)
; MemRetry vector table
addi r8, r1, KDP.VecTblMemRetry
_kaddr r23, rNK, MRMachineCheckInt
stw r23, VecTbl.MachineCheck(r8)
_kaddr r23, rNK, MRDataStorageInt
stw r23, VecTbl.DSI(r8)
########################################################################
; Fill the KCallTbl, the ProgramInt interface to the NanoKernel
InitKCalls
_kaddr r23, rNK, KCallSystemCrash ; Uninited call -> crash
addi r8, r1, KDP.KCallTbl
li r22, KCallTbl.Size
@loop
subic. r22, r22, 4
stwx r23, r8, r22
bne @loop
_kaddr r23, rNK, KCallReturnFromException
stw r23, KCallTbl.ReturnFromException(r8)
_kaddr r23, rNK, KCallRunAlternateContext
stw r23, KCallTbl.RunAlternateContext(r8)
_kaddr r23, rNK, KCallResetSystem
stw r23, KCallTbl.ResetSystem(r8)
_kaddr r23, rNK, KCallVMDispatch
stw r23, KCallTbl.VMDispatch(r8)
_kaddr r23, rNK, KCallPrioritizeInterrupts
stw r23, KCallTbl.PrioritizeInterrupts(r8)
_kaddr r23, rNK, KCallSystemCrash
stw r23, KCallTbl.SystemCrash(r8)
########################################################################
; Init the NCB Pointer Cache
_InvalNCBPointerCache scratch=r23
########################################################################
; Put HTABORG and PTEGMask in KDP, and zero out the last PTEG
InitHTAB
mfspr r8, sdr1
rlwinm r22, r8, 16, 7, 15 ; Get settable HTABMASK bits
rlwinm r8, r8, 0, 0, 15 ; and HTABORG
ori r22, r22, (-64) & 0xffff; "PTEGMask" from upper half of HTABMASK
stw r8, KDP.HTABORG(r1) ; Save
stw r22, KDP.PTEGMask(r1)
li r23, 0 ; Zero out the last PTEG in the HTAB
addi r22, r22, 64
@next_segment
subic. r22, r22, 4
stwx r23, r8, r22
bgt @next_segment
@skip_zeroing_pteg
bl FlushTLB ; Flush the TLB after touching the HTAB
########################################################################
; Get a copy of the PageMap (and the SegMaps required to interpret it)
; Each entry in the PageMap specifies a contiguous part of the MacOS
; address space (or it has a special value). The four SegMaps (supervisor,
; user, CPU, overlay) contain pointers that tell us which entries belong
; in which 256 MB "segments".
CopyPageMap
; r9 = PageMap ptr, r22 = PageMap size
lwz r9, NKConfigurationInfo.PageMapInitOffset(rCI)
lwz r22, NKConfigurationInfo.PageMapInitSize(rCI)
add r9, r9, rCI
@copynext_segment_pagemap
subi r22, r22, 4 ; load a word from the CI pagemap (top first)
lwzx r21, r9, r22
andi. r23, r21, PME.DaddyFlag | PME.PhysicalIsRelativeFlag
cmpwi r23, PME.PhysicalIsRelativeFlag
bne @physical_address_not_relative_to_config_info
; if the physical address of the area is relative to the ConfigInfo struct:
rlwinm r21, r21, 0, ~PME.PhysicalIsRelativeFlag
add r21, r21, rCI
@physical_address_not_relative_to_config_info
stwx r21, rPgMap, r22 ; save in the KDP pagemap
subic. r22, r22, 4
lwzx r20, r9, r22 ; load another word, but no be cray
stwx r20, rPgMap, r22 ; just save it in KDP
bgt @copynext_segment_pagemap
@skip_copying_pagemap
; Edit three entries in the PageMap that the kernel "owns"
lwz r8, NKConfigurationInfo.PageMapIRPOffset(rCI)
add r8, rPgMap, r8
lwz r23, PME.PBaseAndFlags(r8)
rlwimi r23, r1, 0, 0xFFFFF000
stw r23, PME.PBaseAndFlags(r8)
lwz r8, NKConfigurationInfo.PageMapKDPOffset(rCI)
add r8, rPgMap, r8
lwz r23, PME.PBaseAndFlags(r8)
rlwimi r23, r1, 0, 0xFFFFF000
stw r23, PME.PBaseAndFlags(r8)
lwz r19, KDP.EDPPtr(r1)
lwz r8, NKConfigurationInfo.PageMapEDPOffset(rCI)
add r8, rPgMap, r8
lwz r23, PME.PBaseAndFlags(r8)
rlwimi r23, r19, 0, 0xFFFFF000
stw r23, PME.PBaseAndFlags(r8)
; Copy the SegMap
addi r9, rCI, NKConfigurationInfo.SegMaps - 4
addi r8, r1, KDP.SegMaps - 4
li r22, 4*16*8 ; 4 maps * 16 segments * (ptr+flags=8b)
@segmap_copynext_segment
lwzu r23, 4(r9)
subic. r22, r22, 8
add r23, rPgMap, r23 ; even-indexed words are PMDT offsets in PageMap
stwu r23, 4(r8)
lwzu r23, 4(r9)
stwu r23, 4(r8)
bgt @segmap_copynext_segment
########################################################################
; Copy "BATRangeInit" array
CopyBATRangeInit
addi r9, rCI, NKConfigurationInfo.BATRangeInit - 4
addi r8, r1, KDP.BATs - 4
li r22, 4*4*8 ; 4 maps * 4 BATs * (UBAT+LBAT=8b)
@bat_copynext_segment
lwzu r20, 4(r9) ; grab UBAT
lwzu r21, 4(r9) ; grab LBAT
stwu r20, 4(r8) ; store UBAT
_clear r23, r21, 22 ; if LBAT[22] (reserved) is set:
cmpw r21, r23
beq @bitnotset
add r21, r23, rCI ; then LBAT[BRPN] is relative to ConfigInfo struct
@bitnotset
subic. r22, r22, 8
stwu r21, 4(r8) ; store LBAT
bgt @bat_copynext_segment
########################################################################
; Save some ptrs that allow us to enable Overlay mode, etc
addi r23, r1, KDP.SegMap32SupInit
stw r23, KDP.SupervisorMap.SegMapPtr(r1)
lwz r23, NKConfigurationInfo.BatMap32SupInit(rCI)
stw r23, KDP.SupervisorMap.BatMap(r1)
addi r23, r1, KDP.SegMap32UsrInit
stw r23, KDP.UserMap.SegMapPtr(r1)
lwz r23, NKConfigurationInfo.BatMap32UsrInit(rCI)
stw r23, KDP.UserMap.BatMap(r1)
addi r23, r1, KDP.SegMap32CPUInit
stw r23, KDP.CpuMap.SegMapPtr(r1)
lwz r23, NKConfigurationInfo.BatMap32CPUInit(rCI)
stw r23, KDP.CpuMap.BatMap(r1)
addi r23, r1, KDP.SegMap32OvlInit
stw r23, KDP.OverlayMap.SegMapPtr(r1)
lwz r23, NKConfigurationInfo.BatMap32OvlInit(rCI)
stw r23, KDP.OverlayMap.BatMap(r1)
########################################################################
; Create a PageList for the Primary Address Range
; Usable physical pages are:
; Inside a RAM bank, and
; NOT inside the kernel's reserved physical memory
; By 'draft PTE', I mean these parts of the second word of a PTE:
; physical page number (base & 0xfffff000)
; WIMG bits (from oddly formatted ConfigInfo.PageAttributeInit)
; bottom PP bit always set
; And all this goes at the bottom of the kernel reserved area.
; Leave ptr to kernel reserved area in r21
; Leave ptr to topmost entry in r29.
CreatePageList
lwz r21, KDP.KernelMemoryBase(r1) ; "KernelMemory" is forbidden
lwz r20, KDP.KernelMemoryEnd(r1)
subi r29, r21, 4 ; ptr to last added entry
addi r19, r1, KDP.SysInfo.Bank0Start - 8
lwz r23, KDP.PageAttributeInit(r1) ; default WIMG/PP settings in PTEs
; Pull WIMG bits out of PageAttributeInit
li r30, 1
rlwimi r30, r23, 1, 25, 25
rlwimi r30, r23, 31, 26, 26
xori r30, r30, 0x20
rlwimi r30, r23, 29, 27, 27
rlwimi r30, r23, 27, 28, 28
li r23, NKSystemInfo.MaxBanks
@nextbank
subic. r23, r23, 1
blt @done
lwzu r31, 8(r19) ; bank start address
lwz r22, 4(r19) ; bank size
or r31, r31, r30 ; looks a lot like the second word of a PTE
@nextpage
cmplwi r22, 4096
cmplw cr6, r31, r21
cmplw cr7, r31, r20
subi r22, r22, 4096
blt @nextbank
; Check that this page is outside the kernel's reserved area
blt cr6, @below_reserved
blt cr7, @in_reserved
@below_reserved
stwu r31, 4(r29) ; write that part-PTE at the base of kernel memory
@in_reserved
addi r31, r31, 4096
b @nextpage
@done
########################################################################
; In the PageMap, create a Primary Address Range matching the size of PageList
; For every segment that contains part of the PAR, the first PME will be rewritten
; Going in, r21/r29 point to first/last element of PageList
CreatePARInPageMap
; r19 = size of RAM represented in PageList ("Usable" and initial "Logical" RAM)
; r22 = number of 4096b pages, minus one page (counter)
subf r22, r21, r29
li r30, 0
addi r19, r22, 4
slwi r19, r19, 10
ori r30, r30, 0xffff
stw r19, KDP.SysInfo.UsableMemorySize(r1)
srwi r22, r22, 2
stw r19, KDP.SysInfo.LogicalMemorySize(r1)
; convert r19 to pages, and save in some places
srwi r19, r19, 12
stw r19, KDP.VMLogicalPages(r1)
stw r19, KDP.TotalPhysicalPages(r1)
addi r29, r1, KDP.PARPerSegmentPLEPtrs - 4 ; where to save per-segment PLE ptr
addi r19, r1, KDP.SegMap32SupInit - 8 ; which part of PageMap to update
stw r21, KDP.PARPageListPtr(r1)
@next_segment
cmplwi r22, 0xffff ; continue (bgt) while there are still pages left
; Rewrite the first PME in this segment
lwzu r8, 8(r19) ; find PME using SegMap32SupInit
rotlwi r31, r21, 10
ori r31, r31, 0xC00
stw r30, 0(r8) ; LBase = 0, PageCount = 0xFFFF
stw r31, 4(r8) ; PBase = PLE ptr, Flags = DaddyFlag + CountingFlag
stwu r21, 4(r29) ; point PARPerSegmentPLEPtrs to segments's first PLE
addis r21, r21, 4 ; increment pointer into PLE (64k pages/segment * 4b/PLE)
subis r22, r22, 1 ; decrement number of pending pages (64k pages/segment)
bgt @next_segment
; Reduce the number of pages in the last segment
sth r22, PME.PageCount(r8)
########################################################################
; Enable the ROM Overlay
addi r29, r1, KDP.OverlayMap
bl SetMap
########################################################################
; Make sure some important areas of RAM are in the HTAB
lwz r27, KDP.ConfigInfoPtr(r1)
lwz r27, NKConfigurationInfo.LA_InterruptCtl(r27)
bl PutPTE
lwz r27, KDP.ConfigInfoPtr(r1)
lwz r27, NKConfigurationInfo.LA_KernelData(r27)
bl PutPTE
lwz r27, KDP.ConfigInfoPtr(r1)
lwz r27, NKConfigurationInfo.LA_EmulatorData(r27)
bl PutPTE
########################################################################
; Restore the fixedpt exception register (clobbered by addic)
mtxer rXER

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,654 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKInterrupts
; SIGP
; NKMPCalls
; CommonMPCallReturnPath
; ReturnMPCallOOM
; ReturnParamErrFromMPCall
; ReturnZeroFromMPCall
; NKPaging
; PagingFlushTLB
; PagingFunc2AndAHalf
; PagingL2PWithBATs
; NKScheduler
; Save_f0_f31
; Save_v0_v31
; SchSwitchSpace
; NKThud
; panic
; Implements two MPCalls that seem to have something to do with COHGs
; Make conditional calls easier
Local_Panic set *
b panic
Local_ReturnParamErrFromMPCall
b ReturnParamErrFromMPCall
Local_ReturnInsufficientResourcesErrFromMPCall
b ReturnMPCallOOM
Local_CommonMPCallReturnPath
b CommonMPCallReturnPath
; RET OSStatus r3, something r4, something r4
DeclareMPCall 102, MPGetKernelStateSize
MPGetKernelStateSize
mfsprg r9, 0
lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9)
lwz r9, CoherenceGroup.ScheduledCpuCount(r8)
cmpwi r9, 1
bgt Local_ReturnInsufficientResourcesErrFromMPCall
bl KernelStateSize
mr r4, r8
mr r5, r9
b ReturnZeroFromMPCall
; ARG r3/r4/r5
; RET OSStatus r3
DeclareMPCall 103, MPGetKernelState
MPGetKernelState
mfsprg r9, 0
lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9)
lwz r9, CoherenceGroup.ScheduledCpuCount(r8)
cmpwi r9, 1
bgt Local_ReturnInsufficientResourcesErrFromMPCall
clrlwi. r8, r5, 20
bne Local_ReturnParamErrFromMPCall
bl KernelStateSize
cmpw r3, r8
blt Local_ReturnParamErrFromMPCall
cmpw r4, r9
blt Local_ReturnParamErrFromMPCall
bl PagingFlushTLB
mfsprg r9, 0
mfxer r8
stw r13, 0x00dc(r6)
stw r8, 0x00d4(r6)
stw r12, 0x00ec(r6)
mfctr r8
stw r10, 0x00fc(r6)
stw r8, 0x00f4(r6)
mfpvr r8
rlwinm. r8, r8, 0, 0, 14
bne @not_601
mfspr r8, mq
stw r8, ContextBlock.MQ(r6)
@not_601
lwz r8, EWA.r1(r9)
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(r9)
stw r5, ContextBlock.r5(r6)
stw r8, ContextBlock.r6(r6)
bnel Save_f0_f31
rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; flags
bnel+ Save_v0_v31
lwz r3, ContextBlock.r3(r6)
lwz r4, ContextBlock.r4(r6)
lwz r5, ContextBlock.r5(r6)
stw r11,ContextBlock.MSR(r6)
mr r27, r5
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beq Local_ReturnInsufficientResourcesErrFromMPCall
rlwimi r27, r31, 0, 0, 19
mr r17, r27
addi r15, r17, 0x34
srwi r3, r3, 12
MPGetKernelState_0xc8
mr r27, r5
addi r29, r1, KDP.BATs + 0xa0
bl PagingL2PWithBATs
beq Local_ReturnInsufficientResourcesErrFromMPCall
rlwimi r27, r31, 0, 0, 19
stwu r27, 0x0004(r15)
addi r3, r3, -0x01
addi r5, r5, 0x1000
cmpwi r3, 0x00
bge MPGetKernelState_0xc8
addi r15, r15, 0x04
subf r15, r17, r15
stw r15, 0x0034(r17)
mfsprg r15, 0
stw r15, 0x0024(r17)
mfsprg r8, 3
stw r8, 0x0028(r17)
@retry_time
mftbu r8
mftb r9
mftbu r16
cmpw r16, r8
bne- @retry_time
stw r8, EWA.SpacesSavedLR(r15)
stw r9, EWA.SpacesSavedCR(r15)
mr r29, r17
li r16, kSIGP6
stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15)
stw r16, EWA.SIGPCallR4(r15)
li r8, 2 ; args in EWA
bl SIGP
mr r17, r29
mfsdr1 r8
stw r8, 0x002c(r17)
rlwinm r9, r8, 16, 7, 15
cntlzw r18, r9
li r9, -0x01
srw r9, r9, r18
addi r9, r9, 0x01
stw r9, 0x000c(r17)
rlwinm r8, r8, 0, 0, 15
stw r8, 0x0010(r17)
lis r8, 0x00
ori r8, r8, 0xc000
stw r8, 0x0018(r17)
lis r9, 0x00
ori r9, r9, 0xa000
subf r8, r9, r1
stw r8, 0x001c(r17)
addi r9, r1, 120
lis r31, 0x00
li r14, 0x00
lwz r29, 0x0034(r17)
add r29, r29, r17
MPGetKernelState_0x1a0
lwzu r30, 0x0008(r9)
MPGetKernelState_0x1a4
lwz r18, 0x0004(r30)
lhz r15, 0x0000(r30)
andi. r19, r18, 0xe00
lhz r16, 0x0002(r30)
cmplwi r19, 0xc00
bne MPGetKernelState_0x1dc
addi r16, r16, 0x01
slwi r16, r16, 2
stw r16, 0x0000(r29)
rlwinm r18, r18, 22, 0, 29
stw r18, 0x0004(r29)
addi r29, r29, 0x0c
addi r14, r14, 0x01
b MPGetKernelState_0x1fc
MPGetKernelState_0x1dc
cmpwi r15, 0x00
bne MPGetKernelState_0x1fc
cmplwi r16, 0xffff
bne MPGetKernelState_0x1fc
addis r31, r31, 0x1000
cmpwi r31, 0x00
bne MPGetKernelState_0x1a0
b MPGetKernelState_0x204
MPGetKernelState_0x1fc
addi r30, r30, 0x08
b MPGetKernelState_0x1a4
MPGetKernelState_0x204
lwz r16, PSA.FirstPoolSeg(r1)
MPGetKernelState_0x208
lwz r31, 0x0000(r16)
add r18, r31, r16
lwz r19, 0x0000(r18)
addi r31, r31, 0x18
stw r31, 0x0000(r29)
stw r16, 0x0004(r29)
addi r29, r29, 0x0c
addi r14, r14, 0x01
cmpwi r19, 0x00
beq MPGetKernelState_0x238
add r16, r19, r18
b MPGetKernelState_0x208
MPGetKernelState_0x238
addi r19, r1, PSA.FreeList
lwz r31, PSA.FreeList + LLL.Next(r1)
MPGetKernelState_0x240
cmpw r31, r19
beq MPGetKernelState_0x264
li r18, 0x10
stw r18, 0x0000(r29)
stw r31, 0x0004(r29)
addi r29, r29, 0x0c
addi r14, r14, 0x01
lwz r31, 0x0008(r31)
b MPGetKernelState_0x240
MPGetKernelState_0x264
stw r14, 0x0030(r17)
lwz r30, 0x0034(r17)
add r30, r30, r17
MPGetKernelState_0x270
subf r8, r17, r29
stw r8, 0x0008(r30)
lwz r24, 0x0004(r30)
mr r25, r8
lwz r26, 0x0000(r30)
add r29, r29, r26
bl AnotherCoherenceFunc
addi r30, r30, 0x0c
addi r14, r14, -0x01
cmpwi r14, 0x00
bne MPGetKernelState_0x270
subf r8, r17, r29
stw r8, 0x0020(r17)
lwz r24, 0x001c(r17)
mr r25, r8
lwz r26, 0x0018(r17)
add r29, r29, r26
bl AnotherCoherenceFunc
subf r8, r17, r29
stw r8, 0x0014(r17)
lwz r24, 0x0010(r17)
mr r25, r8
lwz r26, 0x000c(r17)
add r29, r29, r26
bl AnotherCoherenceFunc
bl LoadStateRestoreFunc
mflr r9
stw r9, 0x0000(r17)
lwz r8, PSA.NoIdeaR23(r1)
stw r8, 0x0008(r17)
li r8, 0x00
stw r8, 0x0004(r17)
mfsprg r15, 0
li r16, kSIGP17
stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15)
stw r16, EWA.SIGPCallR4(r15)
li r8, 2 ; args in EWA
bl SIGP
li r3, 0
b Local_CommonMPCallReturnPath
LoadStateRestoreFunc
blrl
mr r17, r3
lwz r24, 0x0014(r17)
lwz r25, 0x0010(r17)
lwz r26, 0x000c(r17)
bl YetAnotherCoherenceFunc
lwz r24, 0x002c(r17)
mtsdr1 r24
lwz r24, 0x0020(r17)
lwz r25, 0x001c(r17)
lwz r26, 0x0018(r17)
bl YetAnotherCoherenceFunc
lwz r14, 0x0030(r17)
lwz r30, 0x0034(r17)
add r30, r30, r17
RestoreKernelState_0x38
lwz r24, 0x0008(r30)
lwz r25, 0x0004(r30)
lwz r26, 0x0000(r30)
bl YetAnotherCoherenceFunc
addi r30, r30, 0x0c
addi r14, r14, -0x01
cmpwi r14, 0x00
bne RestoreKernelState_0x38
lwz r16, 0x0024(r17)
mtsprg 0, r16
lwz r8, 0x0028(r17)
mtsprg 3, r8
lwz r1, -0x0004(r16)
lwz r6, -0x0014(r16)
lwz r7, -0x0010(r16)
li r8, -0x01
stw r8, 0x0004(r17)
lwz r8, EWA.SpacesSavedLR(r16)
lwz r9, EWA.SpacesSavedCR(r16)
li r16, 0x01
mttb r16
mttbu r8
mttb r9
mtdec r16
_log 'Resuming saved kernel state^n'
lwz r8, 0x00d4(r6)
lwz r13, 0x00dc(r6)
mtxer r8
lwz r12, 0x00ec(r6)
lwz r8, 0x00f4(r6)
lwz r10, 0x00fc(r6)
mtctr r8
lwz r11, 0x00a4(r6)
mfpvr r8
rlwinm. r8, r8, 0, 0, 14
bne RestoreKernelState_0xf8
lwz r8, 0x00c4(r6)
DIALECT POWER
mtmq r8
DIALECT PowerPC
RestoreKernelState_0xf8
lwz r4, -0x0020(r1)
li r2, 0x01
sth r2, 0x0910(r1)
li r2, -0x01
stw r2, 0x0912(r1)
stw r2, 0x0f90(r4)
xoris r2, r2, 0x100
stw r2, 0x0f8c(r4)
li r2, 0x00
stw r2, 0x0f28(r4)
stw r2, 0x0f2c(r4)
lwz r2, 0x0114(r6)
lwz r4, 0x0124(r6)
lwz r5, 0x012c(r6)
lwz r29, 0x00d8(r6)
cmpwi r29, 0x00
lwz r8, 0x0210(r29)
beq RestoreKernelState_0x144
mtspr vrsave, r8
RestoreKernelState_0x144
bl PagingFlushTLB
addi r29, r1, 0x5e0
bl PagingFunc2AndAHalf
mfsprg r15, 0
lwz r8, -0x001c(r15)
li r9, 0x00
bl SchSwitchSpace
isync
mfsprg r15, 0
li r16, kSIGP7
stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15)
stw r16, EWA.SIGPCallR4(r15)
li r8, 2 ; args in EWA
bl SIGP
mfsprg r15, 0
li r16, kSIGP17
stw r16, EWA.SIGPSelector(r15)
lhz r16, EWA.CPUIndex(r15)
stw r16, EWA.SIGPCallR4(r15)
li r8, 2 ; args in EWA
bl SIGP
li r3, 0
b Local_CommonMPCallReturnPath
; RET r8/r9
KernelStateSize
; Counter
li r24, 0
; Start with hash table
; Also inits counter r8 (bytes!)
mfsdr1 r16
rlwinm r16, r16, 16, 7, 15
cntlzw r17, r16
li r16, -1
srw r16, r16, r17
addi r8, r16, 1
addi r9, r1, KDP.SegMaps - 8
lis r31, 0 ; segment address counter
li r19, 0 ; page counter (to use later)
li r14, 0 ; entry counter (to use later)
@next_segment
lwzu r17, 8(r9)
@next_entry
lwz r18, PMDT.PBaseAndFlags(r17) ; PhysicalPage(20b) || pageAttr(12b)
lhz r15, PMDT.LBase(r17) ; LogicalPageIndexInSegment(16b)
; Same as usual: if
andi. r18, r18, PMDT.TopFieldMask ; r18 = 3b field at top of pageAttr
lhz r16, PMDT.PageCount(r17) ; PageCountMinus1(16b)
cmplwi r18, PMDT.DaddyFlag | PMDT.CountingFlag
bne @entry_seems_blank
addi r16, r16, 1
add r19, r19, r16
addi r14, r14, 1
b @continue_next_entry
@entry_seems_blank
cmpwi r15, 0 ; if not full-segment, might not be blank?
bne @continue_next_entry
cmplwi r16, 0xffff
bne @continue_next_entry
; This is the "normal" way to loop to the next segment
addis r31, r31, 0x1000
cmpwi r31, 0
bne @next_segment
b @exit
@continue_next_entry
addi r17, r17, 8
b @next_entry
@exit
slwi r19, r19, 2 ; 4 bytes per mapped page
add r8, r8, r19
cmpwi r14, 0x00 ; no entries? fail!
beq Local_ReturnInsufficientResourcesErrFromMPCall
mulli r9, r14, 12
add r8, r8, r9 ; 12 bytes per SegMap entry
add r24, r24, r9 ; also in the secondary counter?
; Count pool segments
li r9, 0 ; total size of pool segments
li r14, 0 ; count of pool segments
lwz r16, PSA.FirstPoolSeg(r1) ; current pool segment
@next_pool_segment
lwz r17, Block.OffsetToNext(r16) ; of Begin block
add r18, r17, r16
lwz r19, Block.OffsetToNext(r18) ; of End block
add r9, r9, r17
addi r9, r9, Block.kEndSize
addi r14, r14, 1
cmpwi r19, 0 ; last segment?
add r16, r19, r18
beq @exit_pool_counter
b @next_pool_segment ; odd... what happened here?
@exit_pool_counter
; Count pages in the system free list
addi r16, r1, PSA.FreeList
lwz r18, PSA.FreeList + LLL.Next(r1)
@next_page_in_freelist
cmpw r18, r16
beq @exit_freelist_counter
addi r9, r9, 16
addi r14, r14, 1
lwz r18, LLL.Next(r18)
b @next_page_in_freelist
@exit_freelist_counter
add r8, r8, r9 ; byte counter
mulli r9, r14, 12 ; 12 bytes per thing
add r8, r8, r9
add r24, r24, r9
lisori r9, 0xc000
add r8, r8, r9
lisori r9, 0x3c
add r8, r8, r9
add r24, r24, r9
srwi r9, r8, 12
slwi r9, r9, 2
addi r9, r9, 4
add r8, r8, r9
add r24, r24, r9
mr r9, r24
blr
CoherenceFunc_0x138 ; OUTSIDE REFERER
srwi r23, r28, 12
slwi r23, r23, 2
add r23, r23, r17
lwz r23, 0x0038(r23)
rlwimi r23, r28, 0, 20, 31
blr
AnotherCoherenceFunc ; OUTSIDE REFERER
cmpwi r26, 0x00
beqlr
mflr r22
addi r24, r24, -0x01
mr r28, r25
AnotherCoherenceFunc_0x14
bl CoherenceFunc_0x138
clrlwi r25, r23, 0x14
subfic r25, r25, 0x1000
cmplw r25, r26
blt AnotherCoherenceFunc_0x2c
mr r25, r26
AnotherCoherenceFunc_0x2c
mr r19, r23
mr r20, r25
addi r23, r23, -0x01
mtctr r25
AnotherCoherenceFunc_0x3c
lbzu r27, 0x0001(r24)
stbu r27, 0x0001(r23)
bdnz AnotherCoherenceFunc_0x3c
bl YetAnotherCoherenceFunc_0x64
subf r26, r25, r26
add r28, r28, r25
cmpwi r26, 0x00
bne AnotherCoherenceFunc_0x14
mtlr r22
blr
YetAnotherCoherenceFunc ; OUTSIDE REFERER
cmpwi r26, 0x00
beqlr
mr r19, r25
mr r20, r26
mflr r22
addi r25, r25, -0x01
mr r28, r24
YetAnotherCoherenceFunc_0x1c
bl CoherenceFunc_0x138
clrlwi r24, r23, 0x14
subfic r24, r24, 0x1000
cmplw r24, r26
blt YetAnotherCoherenceFunc_0x34
mr r24, r26
YetAnotherCoherenceFunc_0x34
addi r23, r23, -0x01
mtctr r24
YetAnotherCoherenceFunc_0x3c
lbzu r27, 0x0001(r23)
stbu r27, 0x0001(r25)
bdnz YetAnotherCoherenceFunc_0x3c
add r28, r28, r24
subf r26, r24, r26
cmpwi r26, 0x00
bne YetAnotherCoherenceFunc_0x1c
bl YetAnotherCoherenceFunc_0x64
mtlr r22
blr
YetAnotherCoherenceFunc_0x64 ; OUTSIDE REFERER
sync
isync
lhz r21, 0x0f4a(r1)
addi r15, r21, -0x01
add r20, r19, r20
add r20, r20, r15
neg r15, r21
and r19, r19, r15
and r20, r20, r15
YetAnotherCoherenceFunc_0x88
dcbst 0, r19
sync
icbi 0, r19
add r19, r19, r21
cmpw r19, r20
blt YetAnotherCoherenceFunc_0x88
sync
isync
blr

460
NanoKernel/NKSoftInts.s Normal file
View File

@ -0,0 +1,460 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; MROptabCode
; MRSecDone
; NKExceptions
; Exception
; KCallReturnFromExceptionFastPath
; LoadInterruptRegisters
; ReturnFromInt
; SwitchContext
; NKHotInts
; EmulateDataAccess
; NKMemory
; GetPhysical
; NKSystemCrash
; SystemCrash
; EXPORTS:
; KCallPrioritizeInterrupts (=> NKReset)
; KCallResetSystem (=> NKReset)
; KCallRunAlternateContext (=> NKReset)
; KCallSystemCrash (=> NKReset)
; ProgramInt (=> NKReset)
; SyscallInt (=> NKReset)
; TraceInt (=> NKReset)
########################################################################
IllegalInstruction
mfmsr r9
_set r8, r9, bitMsrDR
mtmsr r8
lwz r8, 0(r10)
mtmsr r9
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
stw r3, KDP.r3(r1)
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
lwz r9, CB.r7+4(r6)
stw r9, KDP.r7(r1)
lwz r9, CB.r8+4(r6)
stw r9, KDP.r8(r1)
lwz r9, CB.r9+4(r6)
stw r9, KDP.r9(r1)
lwz r9, CB.r10+4(r6)
stw r9, KDP.r10(r1)
lwz r9, CB.r11+4(r6)
stw r9, KDP.r11(r1)
lwz r9, CB.r12+4(r6)
stw r9, KDP.r12(r1)
lwz r9, CB.r13+4(r6)
stw r9, KDP.r13(r1)
stmw r14, KDP.r14(r1)
rlwinm r9, r8, 6, 15, 31
cmplwi r9, 0xB99F
beq @MFTB
rlwinm r9, r8, 17, 15, 20
insrwi r9, r8, 11, 21
cmplwi r9, 0xFFAE
beq @STFIWX
@FAIL
li r8, ecInvalidInstr
b Exception
@MFTB
extrwi r9, r8, 10, 11 ; r9 = tbr field
cmplwi cr7, r9, 0x188 ; TBL=268, mangled
cmplwi cr6, r9, 0x1A8 ; TBU=269, mangled
cror 15, cr6_eq, cr7_eq
bc BO_IF_NOT, 15, @FAIL
@retry_rtc
mfspr r20, rtcu
mfspr r21, rtcl
mfspr r23, rtcu
xor. r23, r23, r20
lis r23, 1000000000 >> 16
rlwinm r28, r8, 13, 25, 29 ; r28 = dest register number * 4
ori r23, r23, 1000000000 & 0xFFFF
bne @retry_rtc
mullw r8, r20, r23
mulhwu r20, r20, r23
mfxer r23
addc r21, r21, r8
addze r20, r20
mtxer r23
lwz r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
rlwimi r7, r7, 27, 26, 26 ; ContextFlagTraceWhenDone = MsrSE
addi r23, r23, 1
stw r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
stwx r21, r1, r28 ; save register into EWA
mr r16, r7
beq cr7, MRSecDone ; TBL
stwx r20, r1, r28
b MRSecDone ; TBU
@STFIWX
lwz r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
mr r27, r8
addi r23, r23, 1
stw r23, KDP.NKInfo.EmulatedUnimpInstCount(r1)
mfmsr r14
_set r15, r14, bitMsrDR
b EmulateDataAccess
########################################################################
_alignToCacheBlock
KCallRunAlternateContext
; ARG ContextBlock *r3, flags r4
; We accept a logical NCB ptr but the kernel needs a physical one.
; So we keep a four-entry cache in KDP, mapping logical NCB ptrs
; to physical ones. Never seen multiple contexts used before though.
and. r8, r4, r13
lwz r9, KDP.NCBCacheLA0(r1)
rlwinm r8, r3, 0, 0, 25
cmpw cr1, r8, r9
bne ReturnFromInt
lwz r9, KDP.NCBCachePA0(r1)
bne cr1, @search_cache
@found_physical_in_cache ; can come here from below after a more thorough search
addi r8, r1, KDP.VecTblAlternate ; the only use of this vector table?
mtsprg 3, r8
lwz r8, KDP.EmuKCallTblPtrLogical(r1)
mtcrf crMaskFlags, r7
clrlwi r7, r7, 8
stw r8, CB.IntraState.HandlerReturn+4(r9)
stw r9, KDP.ContextPtr(r1)
b SwitchContext ; OldCB *r6, NewCB *r9
@search_cache
lwz r9, KDP.NCBCacheLA1(r1)
cmpw cr1, r8, r9
beq cr1, @found_in_slot_1
lwz r9, KDP.NCBCacheLA2(r1)
cmpw cr1, r8, r9
beq cr1, @found_in_slot_2
lwz r9, KDP.NCBCacheLA3(r1)
cmpw cr1, r8, r9
beq cr1, @found_in_slot_3
; No luck with the cache
stmw r14, KDP.r14(r1)
cmpw cr1, r8, r6
beq cr1, @fail
mr r27, r8
addi r29, r1, KDP.BATs + 0xa0
bl GetPhysical
clrlwi r23, r8, 20
beq @fail
cmplwi r23, 0x0d00
mr r9, r8
mr r8, r31
ble @not_straddling_pages
addi r27, r27, 0x1000
addi r29, r1, KDP.BATs + 0xa0
bl GetPhysical
beq @fail
subi r31, r31, 0x1000
xor r23, r8, r31
rlwinm. r23, r23, 0, 25, 22
bne @fail ; because physical pages are discontiguous
@not_straddling_pages
clrlwi r23, r31, 30
cmpwi r23, 3
rlwimi r8, r9, 0, 20, 31
beq @fail
; Found a non-cached physical address for this NCB!
lwz r23, KDP.NKInfo.NCBPtrCacheMissCount(r1)
addi r23, r23, 1
stw r23, KDP.NKInfo.NCBPtrCacheMissCount(r1)
; Stick it in cache slot 3
lmw r14, KDP.r14(r1)
stw r8, KDP.NCBCachePA3(r1)
@found_in_slot_3 ; so promote to slot 2
lwz r8, KDP.NCBCacheLA2(r1)
stw r9, KDP.NCBCacheLA2(r1)
stw r8, KDP.NCBCacheLA3(r1)
lwz r9, KDP.NCBCachePA3(r1)
lwz r8, KDP.NCBCachePA2(r1)
stw r9, KDP.NCBCachePA2(r1)
stw r8, KDP.NCBCachePA3(r1)
lwz r9, KDP.NCBCacheLA2(r1)
@found_in_slot_2 ; so promote to slot 1
lwz r8, KDP.NCBCacheLA1(r1)
stw r9, KDP.NCBCacheLA1(r1)
stw r8, KDP.NCBCacheLA2(r1)
lwz r9, KDP.NCBCachePA2(r1)
lwz r8, KDP.NCBCachePA1(r1)
stw r9, KDP.NCBCachePA1(r1)
stw r8, KDP.NCBCachePA2(r1)
lwz r9, KDP.NCBCacheLA1(r1)
@found_in_slot_1 ; so promote to slot 0, save elsewhere, and push on
lwz r8, KDP.NCBCacheLA0(r1)
stw r9, KDP.NCBCacheLA0(r1)
; stw r9, KDP.LA_NCB(r1)
stw r8, KDP.NCBCacheLA1(r1)
lwz r9, KDP.NCBCachePA1(r1)
lwz r8, KDP.NCBCachePA0(r1)
stw r9, KDP.NCBCachePA0(r1)
stw r8, KDP.NCBCachePA1(r1)
b @found_physical_in_cache
@fail
lmw r14, KDP.r14(r1)
li r8, ecTrapInstr
b Exception
########################################################################
_alignToCacheBlock
KCallResetSystem
; PPC trap 1, or indirectly, 68k RESET
stmw r14, KDP.r14(r1)
xoris r8, r3, 'Ga'
cmplwi r8, 'ry'
bne Reset
xoris r8, r4, 0x0505
cmplwi r8, 0x1956
bne Reset
; Gary Davidian skeleton key: r5/D0 = MSR bits to unset, r7/D2 = MSR bits to set
andc r11, r11, r5
lwz r8, CB.r7+4(r6)
or r11, r11, r8
b ReturnFromInt
Reset
include 'NKReset.s'
lmw r14, KDP.r14(r1)
b KCallPrioritizeInterrupts
########################################################################
_alignToCacheBlock
KCallPrioritizeInterrupts
; Left side: roll back the interrupt preparation before the int handler repeats is
; Right side: jump to the external interrupt handler (PIH or ProgramInt)
mtsprg 2, r12
mtsrr0 r10
mtsrr1 r11
mtcr r13
lwz r10, CB.r10+4(r6)
lwz r11, CB.r11+4(r6)
lwz r12, CB.r12+4(r6)
lwz r13, CB.r13+4(r6)
lwz r7, CB.r7+4(r6)
lwz r8, KDP.r1(r1)
mfsprg r9, 3
lwz r9, VecTbl.External(r9)
mtsprg 1, r8
mtlr r9
lwz r8, CB.r8+4(r6)
lwz r9, CB.r9+4(r6)
lwz r6, KDP.r6(r1)
blrl ; (could this ever fall though to KCallSystemCrash?)
########################################################################
KCallSystemCrash
stw r0, KDP.r0(r1)
stw r2, KDP.r2(r1)
stw r3, KDP.r3(r1)
stw r4, KDP.r4(r1)
stw r5, KDP.r5(r1)
lwz r8, CB.r7+4(r6)
lwz r9, CB.r8+4(r6)
stw r8, KDP.r7(r1)
stw r9, KDP.r8(r1)
lwz r8, CB.r9+4(r6)
lwz r9, CB.r10+4(r6)
stw r8, KDP.r9(r1)
stw r9, KDP.r10(r1)
lwz r8, CB.r11+4(r6)
lwz r9, CB.r12+4(r6)
stw r8, KDP.r11(r1)
stw r9, KDP.r12(r1)
lwz r8, CB.r13+4(r6)
stw r8, KDP.r13(r1)
stmw r14, KDP.r14(r1)
bl SystemCrash
########################################################################
_alignToCacheBlock
ProgramInt
; (also called when the Alternate Context gets an External Int => Exception)
; Standard interrupt palaver
mfsprg r1, 0
stw r6, KDP.r6(r1)
mfsprg r6, 1
stw r6, KDP.r1(r1)
lwz r6, KDP.ContextPtr(r1)
stw r7, CB.r7+4(r6)
stw r8, CB.r8+4(r6)
stw r9, CB.r9+4(r6)
stw r10, CB.r10+4(r6)
stw r11, CB.r11+4(r6)
stw r12, CB.r12+4(r6)
stw r13, CB.r13+4(r6)
; Compare SRR0 with address of Emulator's KCall trap table
lwz r8, KDP.EmuKCallTblPtrLogical(r1)
mfsrr0 r10
mfcr r13
xor. r8, r10, r8
lwz r7, KDP.Flags(r1)
mfsprg r12, 2
beq KCallReturnFromExceptionFastPath ; KCall in Emulator table => fast path
rlwimi. r7, r7, bitGlobalFlagSystem, 0, 0
cmplwi cr7, r8, 16 * 4
bge cr0, @fromAltContext ; Alt Context cannot make KCalls; this might be an External Int
bge cr7, @notFromEmulatorTrapTable ; from Emulator but not from its KCall table => do more checks
; SUCCESSFUL TRAP from emulator KCall table
; => Service call then return to link register
add r8, r8, r1
lwz r11, KDP.NKInfo.NanoKernelCallCounts(r8)
lwz r10, KDP.KCallTbl(r8)
addi r11, r11, 1
stw r11, KDP.NKInfo.NanoKernelCallCounts(r8)
mtlr r10
mr r10, r12 ; ret addr: LR was saved to SPRG2, SPRG2 to r12 above, r12 to r10 now, r10 to SRR0 to program ctr later
mfsrr1 r11
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
blr
@notFromEmulatorTrapTable ; so check if it is even a trap...
mfsrr1 r11
mtcrf 0x70, r11
bc BO_IF_NOT, 14, @notTrap
mfmsr r9 ; fetch the instruction to get the "trap number"
_set r8, r9, bitMsrDR
mtmsr r8
lwz r8, 0(r10)
mtmsr r9
xoris r8, r8, 0xfff
cmplwi cr7, r8, 16 ; only traps 0-15 are allowed
slwi r8, r8, 2 ; (for "success" case below)
bge cr7, @illegalTrap
; SUCCESSFUL TRAP from outside emulator KCall table
; => Service call then return to following instruction
add r8, r8, r1
lwz r10, KDP.NKInfo.NanoKernelCallCounts(r8)
addi r10, r10, 1
stw r10, KDP.NKInfo.NanoKernelCallCounts(r8)
lwz r8, KDP.KCallTbl(r8)
mtlr r8
addi r10, r10, 4 ; continue executing the next instruction
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
blr
; Cannot service with a KCall => throw Exception
@fromAltContext ; external interrupt, or a (forbidden) KCall attempt
mfsrr1 r11
mtcrf 0x70, r11
@notTrap ; then it was some other software exception
bc BO_IF, 12, IllegalInstruction
bc BO_IF, 11, @floatingPointException
@illegalTrap ; because we only allow traps 0-15
rlwinm r8, r11, 17, 28, 29
addi r8, r8, 0x4b3
rlwnm r8, r8, r8, 28, 31
b Exception ; CLEVER BIT HACKING described below
; SRR1[13] SRR[14] Exception
; 0 0 ecNoException
; 0 1 ecTrapInstr
; 1 0 ecPrivilegedInstr
; 1 1 9 (floating-point?)
@floatingPointException
li r8, ecFloatException
bc BO_IF, 15, Exception ; SRR1[15] set => handler can retry
addi r10, r10, 4
rlwimi r7, r7, 32-5, 26, 26 ; something about MSR[SE]
b Exception ; SRR1[15] unset => can't retry
########################################################################
_alignToCacheBlock
SyscallInt
bl LoadInterruptRegisters
mfmsr r8
subi r10, r10, 4
rlwimi r11, r8, 0, 0xFFFF0000
li r8, ecSystemCall
b Exception
########################################################################
_alignToCacheBlock
TraceInt ; here because of MSR[SE/BE], possibly thanks to ContextFlagTraceWhenDone
bl LoadInterruptRegisters
li r8, ecInstTrace
b Exception

449
NanoKernel/NKStructs.s Normal file
View File

@ -0,0 +1,449 @@
VecTbl RECORD 0, INCR ; SPRG3 vector table (looked up by ROM vectors)
ds.l 1 ; 00 ; scratch for IVT
SystemReset ds.l 1 ; 04 ; from IVT+100
MachineCheck ds.l 1 ; 08 ; from IVT+200
DSI ds.l 1 ; 0c ; from IVT+300
ISI ds.l 1 ; 10 ; from IVT+400
External ds.l 1 ; 14 ; from IVT+500
Alignment ds.l 1 ; 18 ; from IVT+600
Program ds.l 1 ; 1c ; from IVT+700
FPUnavail ds.l 1 ; 20 ; from IVT+800
Decrementer ds.l 1 ; 24 ; from IVT+900
ReservedVector1 ds.l 1 ; 28 ; from IVT+a00
ReservedVector2 ds.l 1 ; 2c ; from IVT+b00
Syscall ds.l 1 ; 30 ; from IVT+c00
Trace ds.l 1 ; 34 ; from IVT+d00
FPAssist ds.l 1 ; 38 ; from IVT+e00
PerfMonitor ds.l 1 ; 3c ; from IVT+f00
ds.l 1 ; 40
ds.l 1 ; 44
ds.l 1 ; 48
ds.l 1 ; 4c ; Vectors from here downwards are called from
ds.l 1 ; 50 ; odd places in the IVT
ds.l 1 ; 54
ds.l 1 ; 58 ; seems AltiVec-related
ThermalEvent ds.l 1 ; 5c
ds.l 1 ; 60
ds.l 1 ; 64
ds.l 1 ; 68
ds.l 1 ; 6c
ds.l 1 ; 70
ds.l 1 ; 74
ds.l 1 ; 78
ds.l 1 ; 7c
OtherTrace ds.l 1 ; 80
ds.l 1 ; 84
ds.l 1 ; 88
ds.l 1 ; 8c
ds.l 1 ; 90
ds.l 1 ; 94
ds.l 1 ; 98
ds.l 1 ; 9c
ds.l 1 ; a0
ds.l 1 ; a4
ds.l 1 ; a8
ds.l 1 ; ac
ds.l 1 ; b0
ds.l 1 ; b4
ds.l 1 ; b8
ds.l 1 ; bc ; from IVT+0
Size equ *
ENDR
########################################################################
KCallTbl RECORD 0, INCR ; NanoKernel call table
ReturnFromException ds.l 1 ; 00, trap 0
RunAlternateContext ds.l 1 ; 04, trap 1
ResetSystem ds.l 1 ; 08, trap 2 ; 68k RESET
VMDispatch ds.l 1 ; 0c, trap 3 ; 68k $FE0A
PrioritizeInterrupts ds.l 1 ; 10, trap 4
PowerDispatch ds.l 1 ; 14, trap 5 ; 68k $FEOF
RTASDispatch ds.l 1 ; 18, trap 6
CacheDispatch ds.l 1 ; 1c, trap 7
MPDispatch ds.l 1 ; 20, trap 8
ds.l 1 ; 24, trap 9
ds.l 1 ; 28, trap 10
ds.l 1 ; 2c, trap 11
CallAdapterProcPPC ds.l 1 ; 30, trap 12
ds.l 1 ; 34, trap 13
CallAdapterProc68k ds.l 1 ; 38, trap 14
SystemCrash ds.l 1 ; 3c, trap 15
Size equ *
ENDR
########################################################################
PME RECORD 0, INCR ; PageMap Entry
LBase ds.w 1 ; 0 ; (base - segment) >> 12
PageCount ds.w 1 ; 2 ; page count MINUS ONE
PBaseAndFlags ds.l 1 ; 4 ; PBase page aligned
PBaseBits equ 20
FirstFlagBit equ 20
FirstFlag equ 0x800
DaddyFlag equ 0x800
CountingFlag equ 0x400
PhysicalIsRelativeFlag equ 0x200
; try not to use the equates above; they are dicey
TopFieldMask equ 0xe00
Size equ *
ENDR
########################################################################
BAT RECORD 0, INCR
U ds.l 1
L ds.l 1
ENDR
########################################################################
MemMap RECORD 0, INCR
SegMapPtr ds.l 1
BatMap ds.l 1 ; packed array of 4-bit indices into BATs
ENDR
########################################################################
KDP RECORD 0, INCR ; Kernel Data Page
r0 ds.l 1 ; 000 ; used for quick register saves at interrupt time
r1 ds.l 1 ; 004
r2 ds.l 1 ; 008
r3 ds.l 1 ; 00c
r4 ds.l 1 ; 010
r5 ds.l 1 ; 014
r6 ds.l 1 ; 018
r7 ds.l 1 ; 01c
r8 ds.l 1 ; 020
r9 ds.l 1 ; 024
r10 ds.l 1 ; 028
r11 ds.l 1 ; 02c
r12 ds.l 1 ; 030
r13 ds.l 1 ; 034
r14 ds.l 1 ; 038
r15 ds.l 1 ; 03c
r16 ds.l 1 ; 040
r17 ds.l 1 ; 044
r18 ds.l 1 ; 048
r19 ds.l 1 ; 04c
r20 ds.l 1 ; 050
r21 ds.l 1 ; 054
r22 ds.l 1 ; 058
r23 ds.l 1 ; 05c
r24 ds.l 1 ; 060
r25 ds.l 1 ; 064
r26 ds.l 1 ; 068
r27 ds.l 1 ; 06c
r28 ds.l 1 ; 070
r29 ds.l 1 ; 074
r30 ds.l 1 ; 078
r31 ds.l 1 ; 07c
SegMaps
SegMap32SupInit ds.l 32 ; 080:100
SegMap32UsrInit ds.l 32 ; 100:180
SegMap32CPUInit ds.l 32 ; 180:200
SegMap32OvlInit ds.l 32 ; 200:280
BATs ds.l 32 ; 280:300
CurIBAT0 ds BAT ; 300:308
CurIBAT1 ds BAT ; 308:310
CurIBAT2 ds BAT ; 310:318
CurIBAT3 ds BAT ; 318:320
CurDBAT0 ds BAT ; 320:328
CurDBAT1 ds BAT ; 328:330
CurDBAT2 ds BAT ; 330:338
CurDBAT3 ds BAT ; 338:340
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
VecTblSystem ds VecTbl ; 360:420 ; when 68k emulator is running, *or* any MTask
VecTblAlternate ds VecTbl ; 420:4e0 ; native PowerPC in blue task
VecTblMemRetry ds VecTbl ; 4e0:5a0 ; "FDP" instruction emulation
FloatScratch ds.d 1 ; 5a0:5a8
TopOfFreePages ds.l 1 ; 5a8 ; gotten from the old SPRG0
ds.l 1 ; 5ac
PARPerSegmentPLEPtrs ds.l 4 ; 5b0:5c0 ; for each PAR segment, a ptr into the PAR PageList
FloatingPtTemp1 ds.l 1 ; 5c0
FloatingPtTemp2 ds.l 1 ; 5c4
SupervisorMap ds MemMap ; 5c8:5d0
UserMap ds MemMap ; 5d0:5d8
CpuMap ds MemMap ; 5d8:5e0
OverlayMap ds MemMap ; 5e0:5e8
CurMap ds MemMap ; 5e8:5f0
KCallTbl ds KCallTbl ; 5f0:630
ConfigInfoPtr ds.l 1 ; 630
EDPPtr ds.l 1 ; 634
KernelMemoryBase ds.l 1 ; 638
KernelMemoryEnd ds.l 1 ; 63c
LowMemPtr ds.l 1 ; 640 ; physical address of PAR Low Memory
SharedMemoryAddr ds.l 1 ; 644 ; debug?
EmuKCallTblPtrLogical ds.l 1 ; 648
CodeBase ds.l 1 ; 64c
MRBase ds.l 1 ; 650
ECBPtrLogical ds.l 1 ; 654 ; Emulator/System ContextBlock
ECBPtr ds.l 1 ; 658
ContextPtr ds.l 1 ; 65c ; moved to EWA (per-CPU) in NKv2
Flags ds.l 1 ; 660 ; moved to EWA (per-CPU) in NKv2
Enables ds.l 1 ; 664 ; moved to EWA (per-CPU) in NKv2
OtherContextDEC ds.l 1 ; 668 ; ticks that the *inactive* context has left out of 1s
PageMapEndPtr ds.l 1 ; 66c ; et at the same time as PageMapStartPtr below
TestIntMaskInit ds.l 1 ; 670
PostIntMaskInit ds.l 1 ; 674 ; CR flags to set when posting an interrupt to the Emulator
ClearIntMaskInit ds.l 1 ; 678 ; CR flags to clear (as mask) when clearing an interrupt
EmuIntLevelPtr ds.l 1 ; 67c ; physical ptr to an Emulator global
DebugIntPtr ds.l 1 ; 680 ; within (debug?) shared memory
PageMapStartPtr ds.l 1 ; 684
PageAttributeInit ds.l 1 ; 688 ; defaults for PLE/PTE?
HtabTempPage ds.l 1 ; 68c ; a page that lives temporarily in the HTAB (per its PME)
HtabTempEntryPtr ds.l 1 ; 690 ; ptr to that PME
HtabLastEA ds.l 1 ; 694
ApproxCurrentPTEG ds.l 1 ; 698
OverflowingPTEG ds.l 1 ; 69c
PTEGMask ds.l 1 ; 6a0
HTABORG ds.l 1 ; 6a4
VMLogicalPages ds.l 1 ; 6a8 ; set at init and changed by VMInit
TotalPhysicalPages ds.l 1 ; 6ac ; does not take into acct maximum MacOS memory
PARPageListPtr ds.l 1 ; 6b0 ; VM puts this in system heap
VMMaxVirtualPages ds.l 1 ; 6b4 ; always 5fffe000, even with VM on
org 0x700
CrashTop
CrashR0 ds.l 1 ; 700
CrashR1 ds.l 1 ; 704
CrashR2 ds.l 1 ; 708
CrashR3 ds.l 1 ; 70c
CrashR4 ds.l 1 ; 710
CrashR5 ds.l 1 ; 714
CrashR6 ds.l 1 ; 718
CrashR7 ds.l 1 ; 71c
CrashR8 ds.l 1 ; 720
CrashR9 ds.l 1 ; 724
CrashR10 ds.l 1 ; 728
CrashR11 ds.l 1 ; 72c
CrashR12 ds.l 1 ; 730
CrashR13 ds.l 1 ; 734
CrashR14 ds.l 1 ; 738
CrashR15 ds.l 1 ; 73c
CrashR16 ds.l 1 ; 740
CrashR17 ds.l 1 ; 744
CrashR18 ds.l 1 ; 748
CrashR19 ds.l 1 ; 74c
CrashR20 ds.l 1 ; 750
CrashR21 ds.l 1 ; 754
CrashR22 ds.l 1 ; 758
CrashR23 ds.l 1 ; 75c
CrashR24 ds.l 1 ; 760
CrashR25 ds.l 1 ; 764
CrashR26 ds.l 1 ; 768
CrashR27 ds.l 1 ; 76c
CrashR28 ds.l 1 ; 770
CrashR29 ds.l 1 ; 774
CrashR30 ds.l 1 ; 778
CrashR31 ds.l 1 ; 77c
CrashCR ds.l 1 ; 780
CrashMQ ds.l 1 ; 784
CrashXER ds.l 1 ; 788
CrashLR ds.l 1 ; 78c
CrashCTR ds.l 1 ; 790
CrashPVR ds.l 1 ; 794
CrashDSISR ds.l 1 ; 798
CrashDAR ds.l 1 ; 79c
CrashRTCU ds.l 1 ; 7a0
CrashRTCL ds.l 1 ; 7a4
CrashDEC ds.l 1 ; 7a8
CrashHID0 ds.l 1 ; 7ac
CrashSDR1 ds.l 1 ; 7b0
CrashSRR0 ds.l 1 ; 7b4
CrashSRR1 ds.l 1 ; 7b8
CrashMSR ds.l 1 ; 7bc
CrashSR0 ds.l 1 ; 7c0
CrashSR1 ds.l 1 ; 7c4
CrashSR2 ds.l 1 ; 7c8
CrashSR3 ds.l 1 ; 7cc
CrashSR4 ds.l 1 ; 7d0
CrashSR5 ds.l 1 ; 7d4
CrashSR6 ds.l 1 ; 7d8
CrashSR7 ds.l 1 ; 7dc
CrashSR8 ds.l 1 ; 7e0
CrashSR9 ds.l 1 ; 7e4
CrashSR10 ds.l 1 ; 7e8
CrashSR11 ds.l 1 ; 7ec
CrashSR12 ds.l 1 ; 7f0
CrashSR13 ds.l 1 ; 7f4
CrashSR14 ds.l 1 ; 7f8
CrashSR15 ds.l 1 ; 7fc
CrashF0 ds.d 1 ; 800
CrashF1 ds.d 1 ; 808
CrashF2 ds.d 1 ; 810
CrashF3 ds.d 1 ; 818
CrashF4 ds.d 1 ; 820
CrashF5 ds.d 1 ; 828
CrashF6 ds.d 1 ; 830
CrashF7 ds.d 1 ; 838
CrashF8 ds.d 1 ; 840
CrashF9 ds.d 1 ; 848
CrashF10 ds.d 1 ; 850
CrashF11 ds.d 1 ; 858
CrashF12 ds.d 1 ; 860
CrashF13 ds.d 1 ; 868
CrashF14 ds.d 1 ; 870
CrashF15 ds.d 1 ; 878
CrashF16 ds.d 1 ; 880
CrashF17 ds.d 1 ; 888
CrashF18 ds.d 1 ; 890
CrashF19 ds.d 1 ; 898
CrashF20 ds.d 1 ; 8a0
CrashF21 ds.d 1 ; 8a8
CrashF22 ds.d 1 ; 8b0
CrashF23 ds.d 1 ; 8b8
CrashF24 ds.d 1 ; 8c0
CrashF25 ds.d 1 ; 8c8
CrashF26 ds.d 1 ; 8d0
CrashF27 ds.d 1 ; 8d8
CrashF28 ds.d 1 ; 8e0
CrashF29 ds.d 1 ; 8e8
CrashF30 ds.d 1 ; 8f0
CrashF31 ds.d 1 ; 8f8
CrashFPSCR ds.l 1 ; 900
CrashKernReturn ds.l 1 ; 904
CrashUnknown1 ds.l 1 ; 908
CrashUnknown2 ds.l 1 ; 90c
CrashBtm
PageMap ds.b 0x1a8 ; 910:ab8
org 0xCC0
SysInfo ds NKSystemInfo ; cc0:d80
DiagInfo ds NKDiagInfo ; d80:e80
NKInfo ds NKNanoKernelInfo ; e80:f80
ProcInfo ds NKProcessorInfo ; f80:fc0
InfoRecBlk ds.b 64 ; fc0:1000 ; Access using ptr equates in InfoRecords
ENDR
########################################################################
KernelState RECORD 0,INCR
Flags ds.l 1 ; 00
Enables ds.l 1 ; 04
Handler ds.d 1 ; 08
HandlerArg ds.d 1 ; 10
HandlerReturn ds.d 1 ; 18
MemRet17 ds.d 1 ; 20 ; MemRetry state
MemRetData ds.d 1 ; 28
MemRet19 ds.d 1 ; 30
MemRet18 ds.d 1 ; 38
ENDR
########################################################################
CB RECORD 0,INCR ; ContextBlock (Emulator/System or Native/Alternate)
InterState ds KernelState ; 000:040 ; for switching between contexts
IntraState ds KernelState ; 040:080 ; for raising/disposing exceptions within a context
FaultSrcPC ds.d 1 ; 080 ; saved when starting an exception handler
FaultSrcLR ds.d 1 ; 088
FaultSrcR3 ds.d 1 ; 090
FaultSrcR4 ds.d 1 ; 098
MSR ds.d 1 ; 0a0
ds.d 1 ; 0a8
ds.d 1 ; 0b0
ds.d 1 ; 0b8
MQ ds.d 1 ; 0c0 ; 601 only
ds.d 1 ; 0c8
XER ds.d 1 ; 0d0
CR ds.d 1 ; 0d8
FPSCR ds.d 1 ; 0e0 ; unsure, mffs/mtfs?
LR ds.d 1 ; 0e8
CTR ds.d 1 ; 0f0
PC ds.d 1 ; 0f8
r0 ds.d 1 ; 100 ; big-endian, so 32-bit value stored in second word
r1 ds.d 1 ; 108
r2 ds.d 1 ; 110
r3 ds.d 1 ; 118
r4 ds.d 1 ; 120
r5 ds.d 1 ; 128
r6 ds.d 1 ; 130
r7 ds.d 1 ; 138
r8 ds.d 1 ; 140
r9 ds.d 1 ; 148
r10 ds.d 1 ; 150
r11 ds.d 1 ; 158
r12 ds.d 1 ; 160
r13 ds.d 1 ; 168
r14 ds.d 1 ; 170
r15 ds.d 1 ; 178
r16 ds.d 1 ; 180
r17 ds.d 1 ; 188
r18 ds.d 1 ; 190
r19 ds.d 1 ; 198
r20 ds.d 1 ; 1a0
r21 ds.d 1 ; 1a8
r22 ds.d 1 ; 1b0
r23 ds.d 1 ; 1b8
r24 ds.d 1 ; 1c0
r25 ds.d 1 ; 1c8
r26 ds.d 1 ; 1d0
r27 ds.d 1 ; 1d8
r28 ds.d 1 ; 1e0
r29 ds.d 1 ; 1e8
r30 ds.d 1 ; 1f0
r31 ds.d 1 ; 1f8
f0 ds.d 1 ; 200
f1 ds.d 1 ; 208
f2 ds.d 1 ; 210
f3 ds.d 1 ; 218
f4 ds.d 1 ; 220
f5 ds.d 1 ; 228
f6 ds.d 1 ; 230
f7 ds.d 1 ; 238
f8 ds.d 1 ; 240
f9 ds.d 1 ; 248
f10 ds.d 1 ; 250
f11 ds.d 1 ; 258
f12 ds.d 1 ; 260
f13 ds.d 1 ; 268
f14 ds.d 1 ; 270
f15 ds.d 1 ; 278
f16 ds.d 1 ; 280
f17 ds.d 1 ; 288
f18 ds.d 1 ; 290
f19 ds.d 1 ; 298
f20 ds.d 1 ; 2a0
f21 ds.d 1 ; 2a8
f22 ds.d 1 ; 2b0
f23 ds.d 1 ; 2b8
f24 ds.d 1 ; 2c0
f25 ds.d 1 ; 2c8
f26 ds.d 1 ; 2d0
f27 ds.d 1 ; 2d8
f28 ds.d 1 ; 2e0
f29 ds.d 1 ; 2e8
f30 ds.d 1 ; 2f0
f31 ds.d 1 ; 2f8
ENDR

File diff suppressed because it is too large Load Diff

165
NanoKernel/NKSystemCrash.s Executable file
View File

@ -0,0 +1,165 @@
; AUTO-GENERATED SYMBOL LIST
; EXPORTS:
; SystemCrash (=> MRInterrupts, MROptabCode, NKExceptions, NKLegacyVM, NKMemory, NKReset, NKSoftInts)
########################################################################
SystemCrash
mfsprg r1, 0
stw r0, KDP.CrashR0(r1)
mfsprg r0, 1
stw r0, KDP.CrashR1(r1)
stmw r2, KDP.CrashR2(r1)
mfcr r0
stw r0, KDP.CrashCR(r1)
mfspr r0, mq
stw r0, KDP.CrashMQ(r1)
mfxer r0
stw r0, KDP.CrashXER(r1)
mfsprg r0, 2
stw r0, KDP.CrashLR(r1)
mfctr r0
stw r0, KDP.CrashCTR(r1)
mfspr r0, pvr
stw r0, KDP.CrashPVR(r1)
mfspr r0, dsisr
stw r0, KDP.CrashDSISR(r1)
mfspr r0, dar
stw r0, KDP.CrashDAR(r1)
mfspr r0, rtcu
stw r0, KDP.CrashRTCU(r1)
mfspr r0, rtcl
stw r0, KDP.CrashRTCL(r1)
mfspr r0, dec
stw r0, KDP.CrashDEC(r1)
mfspr r0, hid0
stw r0, KDP.CrashHID0(r1)
mfspr r0, sdr1
stw r0, KDP.CrashSDR1(r1)
mfsrr0 r0
stw r0, KDP.CrashSRR0(r1)
mfsrr1 r0
stw r0, KDP.CrashSRR1(r1)
mfmsr r0
stw r0, KDP.CrashMSR(r1)
mfsr r0, 0
stw r0, KDP.CrashSR0(r1)
mfsr r0, 1
stw r0, KDP.CrashSR1(r1)
mfsr r0, 2
stw r0, KDP.CrashSR2(r1)
mfsr r0, 3
stw r0, KDP.CrashSR3(r1)
mfsr r0, 4
stw r0, KDP.CrashSR4(r1)
mfsr r0, 5
stw r0, KDP.CrashSR5(r1)
mfsr r0, 6
stw r0, KDP.CrashSR6(r1)
mfsr r0, 7
stw r0, KDP.CrashSR7(r1)
mfsr r0, 8
stw r0, KDP.CrashSR8(r1)
mfsr r0, 9
stw r0, KDP.CrashSR9(r1)
mfsr r0, 10
stw r0, KDP.CrashSR10(r1)
mfsr r0, 11
stw r0, KDP.CrashSR11(r1)
mfsr r0, 12
stw r0, KDP.CrashSR12(r1)
mfsr r0, 13
stw r0, KDP.CrashSR13(r1)
mfsr r0, 14
stw r0, KDP.CrashSR14(r1)
mfsr r0, 15
stw r0, KDP.CrashSR15(r1)
mfmsr r0
_set r0, r0, bitMsrFP
mtmsr r0
stfd f0, KDP.CrashF0(r1)
stfd f1, KDP.CrashF1(r1)
stfd f2, KDP.CrashF2(r1)
stfd f3, KDP.CrashF3(r1)
stfd f4, KDP.CrashF4(r1)
stfd f5, KDP.CrashF5(r1)
stfd f6, KDP.CrashF6(r1)
stfd f7, KDP.CrashF7(r1)
stfd f8, KDP.CrashF8(r1)
stfd f9, KDP.CrashF9(r1)
stfd f10, KDP.CrashF10(r1)
stfd f11, KDP.CrashF11(r1)
stfd f12, KDP.CrashF12(r1)
stfd f13, KDP.CrashF13(r1)
stfd f14, KDP.CrashF14(r1)
stfd f15, KDP.CrashF15(r1)
stfd f16, KDP.CrashF16(r1)
stfd f17, KDP.CrashF17(r1)
stfd f18, KDP.CrashF18(r1)
stfd f19, KDP.CrashF19(r1)
stfd f20, KDP.CrashF20(r1)
stfd f21, KDP.CrashF21(r1)
stfd f22, KDP.CrashF22(r1)
stfd f23, KDP.CrashF23(r1)
stfd f24, KDP.CrashF24(r1)
stfd f25, KDP.CrashF25(r1)
stfd f26, KDP.CrashF26(r1)
stfd f27, KDP.CrashF27(r1)
stfd f28, KDP.CrashF28(r1)
stfd f29, KDP.CrashF29(r1)
stfd f30, KDP.CrashF30(r1)
stfd f31, KDP.CrashF31(r1)
mffs f31
lwz r0, KDP.CrashF31+4(r1)
stfd f31, KDP.CrashF31+4(r1)
stw r0, KDP.CrashF31+4(r1)
mflr r0
stw r0, KDP.CrashKernReturn(r1)
########################################################################
lis r2, 2 ; Count down from 64k to find a zero
@nonzero
lwzu r0, -4(r2)
mr. r2, r2
bne @nonzero
@retryrtc ; Save RTC in "Mac/Smurf shared message mem"
mfspr r2, rtcu
mfspr r3, rtcl
mfspr r0, rtcu
xor. r0, r0, r2
bne @retryrtc
lwz r1, KDP.SharedMemoryAddr(r1)
stw r2, 0(r1)
ori r3, r3, 1
stw r3, 4(r1)
dcbf 0, r1
sync
@loopforever
lwz r1, 0(0)
addi r1, r1, 1
stw r1, 0(0)
li r1, 0
dcbst r1, r1
b @loopforever

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,962 +0,0 @@
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKConsoleLog
; getchar
; printb
; printd
; printh
; printw
; NKIndex
; DeleteID
; LookupID
; NKPoolAllocator
; PoolAllocClear
; PoolFree
; NKScheduler
; CalculateTimeslice
; FlagSchEvaluationIfTaskRequires
; SchRdyTaskNow
; SchTaskUnrdy
; clear_cr0_lt
; major_0x149d4
; NKSync
; EnqueueMessage
; SetEvent
; SignalSemaphore
; NKThud
; panic
; panic_non_interactive
; EXPORTS:
; DequeueTimer (=> NKMPCalls, NKPrimaryIntHandlers, NKSync, NKTasks)
; EnqueueTimer (=> NKMPCalls, NKSync)
; GetTime (=> NKMPCalls, NKScheduler, NKSync, NKTasks)
; InitTMRQs (=> NKInit)
; SetTimesliceFromCurTime (=> NKScheduler)
; StartTimeslicing (=> NKInit)
; TimebaseTicksPerPeriod (=> NKScheduler, NKSync)
; TimerDispatch (=> NKInterrupts)
Local_Panic set *
b panic
InitTMRQs ; OUTSIDE REFERER
addi r9, r1, PSA.TimerQueue
lis r8, 0x544d
ori r8, r8, 0x5251
stw r8, 0x0004(r9)
stw r9, 0x0008(r9)
stw r9, 0x000c(r9)
li r8, 0x00
stb r8, 0x0014(r9)
li r8, 0x01
stb r8, 0x0016(r9)
stb r8, 0x0017(r9)
lis r8, 0x7fff
ori r8, r8, 0xffff
mtspr dec, r8
stw r8, 0x0038(r9)
oris r8, r8, 0xffff
stw r8, 0x003c(r9)
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
beq InitTMRQs_0x7c
mflr r30
li r8, 0x40
; r1 = kdp
; r8 = size
bl PoolAllocClear
; r8 = ptr
mr. r31, r8
beq Local_Panic
stw r31, PSA.OtherTimerQueuePtr(r1)
li r9, 0x07
stb r9, 0x0014(r31)
li r9, 0x01
stb r9, 0x0016(r31)
mtlr r30
InitTMRQs_0x7c
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
beq InitTMRQs_0xb4
mflr r30
li r8, 0x40
; r1 = kdp
; r8 = size
bl PoolAllocClear
; r8 = ptr
mr. r31, r8
beq Local_Panic
stw r31, PSA._364(r1)
li r9, 0x08
stb r9, 0x0014(r31)
li r9, 0x01
stb r9, 0x0016(r31)
mtlr r30
InitTMRQs_0xb4
; Activate the NanoDebugger (whatever that is...)
lwz r30, KDP.PA_ConfigInfo(r1)
lhz r31, NKConfigurationInfo.Debug(r30)
cmplwi r31, NKConfigurationInfo.DebugThreshold
blt @nodebug
lwz r31, NKConfigurationInfo.DebugFlags(r30)
rlwinm. r8, r31, 0, NKConfigurationInfo.NanodbgrFlagBit, NKConfigurationInfo.NanodbgrFlagBit
beq @nodebug
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
_bset r8, r8, NKNanoKernelInfo.NanodbgrFlagBit
stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
mflr r30
li r8, Timer.Size
bl PoolAllocClear ; one of those weird queue structures
mr. r31, r8
beq Local_Panic
li r9, Timer.kKind6
stb r9, Timer.Kind(r31)
li r9, 1
stb r9, Timer.KeepAfterFiring(r31)
bl GetTime
stw r8, Timer.Time(r31)
stw r9, Timer.Time+4(r31)
mr r8, r31
bl EnqueueTimer
_log 'Nanodebugger activated.^n'
mtlr r30
@nodebug
blr
TimerTable
dc.l TimerFireUnknownKind - NKTop ; Timer.kKind0
dc.l TimerFire1 - NKTop ; Timer.kKind1
dc.l TimerFire2 - NKTop ; Timer.kKind2
dc.l TimerFire3 - NKTop ; Timer.kKind3
dc.l TimerFire4 - NKTop ; Timer.kKind4
dc.l TimerFire5 - NKTop ; Timer.kKind5
dc.l TimerFire6 - NKTop ; Timer.kKind6
dc.l TimerFire7 - NKTop ; Timer.kKind7
dc.l TimerFire8 - NKTop ; Timer.kKind8
TimerDispatch ; OUTSIDE REFERER
mflr r19
mfsprg r18, 0
stw r19, EWA.TimerDispatchLR(r18)
TimerDispatch_0x30 ; OUTSIDE REFERER
mfspr r8, pvr
rlwinm. r8, r8, 0, 0, 14
beq @is_601
;not 601
@gettime_loop_non_601
mftbu r8
mftb r9
mftbu r16
cmpw r8, r16
bne- @gettime_loop_non_601
b @common
@is_601
@gettime_loop_601
mfspr r8, rtcu
mfspr r9, rtcl
mfspr r16, rtcu
cmpw r8, r16
bne- @gettime_loop_601
dialect POWER
liu r16, 1000000000 >> 16
oril r16, r16, 1000000000 & 0xffff
mfmq r17
mul r8, r16, r8
mfmq r16
mtmq r17
mfxer r17
a r9, r16, r9
aze r8, r8
mtxer r17
dialect PowerPC
@common
lbz r19, EWA.GlobalTimeIsValid(r18)
addi r30, r18, EWA.Base
cmpwi r19, 1
lwz r16, EWA.GlobalTime - EWA.Base(r30)
bne timer_earlier_than_sometime
lwz r17, EWA.GlobalTime + 4 - EWA.Base(r30)
_b_if_time_gt r16, r8, timer_earlier_than_sometime
@skipbranch
li r19, 0x00
stw r30, -0x0254(r18)
stb r19, 0x0017(r30)
b TimerFire4_0x10
timer_earlier_than_sometime
lwz r30, PSA.TimerQueue + LLL.Next(r1)
lwz r16, 0x0038(r30)
lwz r17, 0x003c(r30)
_b_if_time_gt r16, r8, TimerDispatch_0x188
RemoveFromList r30, scratch1=r19, scratch2=r20
lwz r19, 0x064c(r1)
lbz r20, Timer.Kind(r30)
rlwimi r19, r20, 2, 23, 29
cmplwi r20, 0x09
llabel r20, TimerTable
li r21, 0x00
add r20, r20, r19
bgel Local_Panic
stb r21, 0x0017(r30)
lwz r20, 0x0000(r20)
add r20, r20, r19
mtlr r20
stw r30, -0x0254(r18)
blr
TimerDispatch_0x144
mfsprg r18, 0
lwz r30, -0x0254(r18)
lbz r19, 0x0016(r30)
cmpwi r19, 0x01
lwz r8, 0x0000(r30)
beq TimerDispatch_0x30
bl DeleteID
mr r8, r30
bl PoolFree
lwz r8, 0x001c(r30)
cmpwi r8, 0x00
beq TimerDispatch_0x180
bl PoolFree
li r8, 0x00
stw r8, 0x001c(r30)
TimerDispatch_0x180:
mfsprg r18, 0
b TimerDispatch_0x30
TimerDispatch_0x188
lwz r19, EWA.TimerDispatchLR(r18)
mtlr r19
b SetTimesliceFromCurTimeAndTripTime
StartTimeslicing ; OUTSIDE REFERER
mfsprg r19, 0
li r8, 1
stb r8, EWA.GlobalTimeIsValid(r19)
li r8, 0
stw r8, EWA.GlobalTime(r19)
stw r8, EWA.GlobalTime + 4(r19)
mflr r19
_log 'Starting timeslicing^n'
mtlr r19
; CLOB r8/r9, r16-r21
SetTimeslice
mflr r19
bl GetTime
mtlr r19
; ARG TimeBase r8/r9 curTime
; CLOB r16-r21
SetTimesliceFromCurTime
; This should get the most distant time???
lwz r18, PSA.TimerQueue + LLL.Next(r1)
lwz r16, Timer.Time(r18)
lwz r17, Timer.Time+4(r18)
; ARG TimeBase r8/r9 curTime, TimeBase r16/r17 TripTime
; CLOB r18-r21
SetTimesliceFromCurTimeAndTripTime
mfxer r20
mfsprg r19, 0
lis r21, 0x7fff
lbz r18, EWA.GlobalTimeIsValid(r19)
ori r21, r21, 0xffff
cmpwi r18, 1
; r16/r17 = soonest(last timer, global PSA time if available)
bne global_time_invalid
lwz r18, EWA.GlobalTime(r19)
lwz r19, EWA.GlobalTime+4(r19)
_b_if_time_le r16, r18, last_timer_fires_sooner
mr r17, r19
mr r16, r18
last_timer_fires_sooner
global_time_invalid
; Subtract the current time (or what we were passed in r8/r9) from that time
subfc r17, r9, r17
subfe. r16, r8, r16
mtxer r20
blt @that_time_has_passed ; hi bit of r16 = 1
bne @that_time_is_in_future ;
cmplw r16, r21 ; typo? should be r17???
bgt @that_time_is_in_future ; will never be taken...
; When the times are roughly equal?
mtspr dec, r17
blr
@that_time_is_in_future
mtspr dec, r21
blr
@that_time_has_passed
mtspr dec, r21
mtspr dec, r16 ; this makes nearly no sense!
blr
; TimerFire0
TimerFireUnknownKind
_log 'TimerInformation.kind is zero??^n'
; TimerFire1
TimerFire1 ; OUTSIDE REFERER
bl Local_Panic
lwz r18, 0x0018(r30)
stw r16, 0x0080(r18)
stw r17, 0x0084(r18)
lwz r8, 0x0018(r30)
li r16, 0x00
lbz r17, 0x0018(r8)
lwz r19, 0x0088(r8)
cmpwi r17, 0x00
stw r16, 0x011c(r19)
bne TimerFire1_0x64
addi r16, r8, 0x08
RemoveFromList r16, scratch1=r17, scratch2=r19
li r17, 0x01
stb r17, 0x0019(r8)
bl SchRdyTaskNow
bl CalculateTimeslice
bl FlagSchEvaluationIfTaskRequires
b TimerDispatch_0x144
TimerFire1_0x64
lwz r16, 0x0064(r8)
rlwinm. r16, r16, 0, 30, 30
; TimerFire2
TimerFire2 ; OUTSIDE REFERER
bne TimerDispatch_0x144
bl Local_Panic
lwz r18, 0x0018(r30)
stw r16, 0x0080(r18)
stw r17, 0x0084(r18)
lwz r8, 0x0018(r30)
li r16, -0x7270
lbz r17, 0x0018(r8)
lwz r18, 0x0088(r8)
cmpwi r17, 0x00
bne TimerFire3_0x8
stw r16, 0x011c(r18)
lwz r8, 0x0008(r8)
lwz r8, 0x0000(r8)
; r8 = id
bl LookupID
cmpwi r9, Queue.kIDClass
cmpwi cr1, r9, 0x05
beq TimerFire2_0x8c
beq cr1, TimerFire2_0x7c
cmpwi r9, 0x09
cmpwi cr1, r9, 0x06
beq TimerFire2_0x6c
bne cr1, Local_Panic
lwz r16, 0x0020(r8)
addi r16, r16, -0x01
stw r16, 0x0020(r8)
b TimerFire2_0x98
TimerFire2_0x6c
lwz r16, 0x001c(r8)
addi r16, r16, -0x01
stw r16, 0x001c(r8)
b TimerFire2_0x98
TimerFire2_0x7c
lwz r16, 0x001c(r8)
addi r16, r16, -0x01
stw r16, 0x001c(r8)
b TimerFire2_0x98
TimerFire2_0x8c
lwz r16, 0x002c(r8)
addi r16, r16, -0x01
stw r16, 0x002c(r8)
TimerFire2_0x98
lwz r8, 0x0018(r30)
addi r16, r8, 0x08
RemoveFromList r16, scratch1=r17, scratch2=r18
bl SchRdyTaskNow
; TimerFire3
TimerFire3 ; OUTSIDE REFERER
bl FlagSchEvaluationIfTaskRequires
b TimerDispatch_0x144
TimerFire3_0x8 ; OUTSIDE REFERER
b Local_Panic
; major_0x13258
; Dead code -- probably removed from TimerTable
lwz r8, 0x0018(r30)
; r8 = id
bl LookupID
cmpwi r9, Queue.kIDClass
mr r31, r8
bne major_0x13258_0x68
lwz r16, 0x0024(r31)
lwz r8, 0x001c(r30)
cmpwi r16, 0x00
cmpwi cr1, r8, 0x00
beq major_0x13258_0x40
lwz r17, 0x0028(r31)
mr. r8, r17
lwz r17, 0x0008(r17)
beq major_0x13258_0x68
stw r17, 0x0028(r31)
b major_0x13258_0x4c
major_0x13258_0x40
beq cr1, major_0x13258_0x68
li r16, 0x00
stw r16, 0x001c(r30)
major_0x13258_0x4c
lwz r16, 0x0020(r30)
lwz r17, 0x0024(r30)
lwz r18, 0x0028(r30)
stw r16, 0x0010(r8)
stw r17, 0x0014(r8)
stw r18, 0x0018(r8)
bl EnqueueMessage ; Message *r8, Queue *r31
major_0x13258_0x68
lwz r8, 0x0034(r30)
; r8 = id
bl LookupID
cmpwi r9, Semaphore.kIDClass
mr r31, r8
bne major_0x13258_0x80
bl SignalSemaphore
major_0x13258_0x80
lwz r8, 0x002c(r30)
; r8 = id
bl LookupID
cmpwi r9, EventGroup.kIDClass
mr r31, r8
; TimerFire4
TimerFire4 ; OUTSIDE REFERER
bne TimerFire4_0xc
lwz r8, 0x0030(r30)
bl SetEvent
TimerFire4_0xc
b TimerDispatch_0x144
TimerFire4_0x10 ; OUTSIDE REFERER
mfsprg r28, 0
lwz r29, -0x0008(r28)
mr r8, r29
bl SchTaskUnrdy
lbz r17, 0x0019(r29)
cmpwi r17, 0x02
bge TimerFire4_0x64
mr r8, r29
lwz r16, 0x0038(r30)
lwz r17, 0x003c(r30)
bl clear_cr0_lt
bge TimerFire4_0x50
mr r8, r29
bl SchRdyTaskNow
bl CalculateTimeslice
b TimerFire5_0x8
TimerFire4_0x50
li r18, 0x02
stb r18, 0x0019(r29)
mr r8, r29
bl SchRdyTaskNow
b TimerFire5_0x8
TimerFire4_0x64
mr r8, r29
; TimerFire5
TimerFire5 ; OUTSIDE REFERER
bl SchRdyTaskNow
bl major_0x149d4
TimerFire5_0x8 ; OUTSIDE REFERER
bl FlagSchEvaluationIfTaskRequires
mfsprg r18, 0
b TimerDispatch_0x30
; major_0x13364
; Dead code -- probably removed from TimerTable
_log 'Heartbeat: Ext '
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1)
mr r8, r16
bl printd
_log 'Alerts '
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1)
mr r8, r16
bl printd
_log 'Blue cpu-'
lwz r17, PSA.PA_BlueTask(r1)
lhz r16, Task.CPUIndex(r17)
mr r8, r16
bl printb
_log 'state-'
lbz r16, Task.State(r17)
mr r8, r16
bl printb
_log 'scr-'
lwz r16, KDP.PA_ECB(r1)
lwz r18, KDP.PostIntMaskInit(r1)
lwz r16, ContextBlock.CR(r16)
and r16, r16, r18
mr r8, r16
bl printw
_log 'mcr-'
lwz r16, PSA.MCR(r1)
mr r8, r16
bl printw
_log 'IPL-'
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, ContextBlock.r25(r16)
andi. r16, r16, 7
mr r8, r16
bl printb
_log '^n'
mfxer r19
lwz r16, 0x0038(r30)
lwz r17, 0x003c(r30)
lwz r18, 0x0f2c(r1)
slwi r18, r18, 3
addc r17, r17, r18
; TimerFire7
TimerFire7 ; OUTSIDE REFERER
addze r16, r16
stw r16, 0x0038(r30)
stw r17, 0x003c(r30)
mtxer r19
mr r8, r30
bl EnqueueTimer
b TimerDispatch_0x144
; major_0x134d8
; Dead code -- probably removed from TimerTable
lwz r18, PSA.DecClockRateHzCopy(r1)
lwz r19, 0x0f88(r1)
subf. r19, r18, r19
ble TimerFire8_0x1c
srwi r19, r19, 11
mfxer r20
major_0x134d8_0x18
mftbu r16
mftb r17, 0x10c
mftbu r18
cmpw r16, r18
li r18, 0x00
bne- major_0x134d8_0x18
mttb r18
addc r17, r17, r19
addze r16, r16
mttbu r16
mttb r17
lwz r18, PSA.DecClockRateHzCopy(r1)
srwi r18, r18, 11
; TimerFire8
TimerFire8 ; OUTSIDE REFERER
addc r17, r17, r18
addze r16, r16
stw r16, 0x0038(r30)
stw r17, 0x003c(r30)
mtxer r20
mr r8, r30
bl EnqueueTimer
TimerFire8_0x1c ; OUTSIDE REFERER
b TimerDispatch_0x144
; major_0x13544
; Dead code -- probably removed from TimerTable
lwz r19, PSA._36c(r1)
mfxer r20
cmpwi cr1, r19, 0x00
srawi r8, r19, 31
beq cr1, TimerFire6_0x4
major_0x13544_0x14
mftbu r16
mftb r17, 0x10c
mftbu r18
cmpw r16, r18
li r18, 0x00
bne- major_0x13544_0x14
mttb r18
addc r19, r17, r19
adde r18, r16, r8
mttbu r18
mttb r19
bgt cr1, major_0x13544_0x64
major_0x13544_0x44
mftbu r18
mftb r19, 0x10c
mftbu r8
cmpw r18, r8
bne- major_0x13544_0x44
subfc r19, r17, r19
subfe. r18, r16, r18
blt major_0x13544_0x44
major_0x13544_0x64
lwz r18, PSA._368(r1)
addc r17, r17, r18
addze r16, r16
stw r16, 0x0038(r30)
; TimerFire6
TimerFire6 ; OUTSIDE REFERER
stw r17, 0x003c(r30)
TimerFire6_0x4 ; OUTSIDE REFERER
mtxer r20
beq cr1, TimerDispatch_0x144
mr r8, r30
bl EnqueueTimer
b TimerDispatch_0x144
; major_0x135d0
; Dead code -- probably removed from TimerTable
mfxer r19
lwz r16, 0x0038(r30)
lwz r17, 0x003c(r30)
lwz r18, 0x0f2c(r1)
srwi r18, r18, 1
addc r17, r17, r18
addze r16, r16
stw r16, 0x0038(r30)
stw r17, 0x003c(r30)
mtxer r19
mr r8, r30
bl EnqueueTimer
bl getchar
cmpwi r8, -0x01
beq TimerDispatch_0x144
bl panic_non_interactive
b TimerDispatch_0x144
; ARG Timer *r8
; CLOB r16-r20
EnqueueTimer ; OUTSIDE REFERER
; Keep the trip-time of this timer in r16/r17
lwz r16, Timer.Time(r8)
lwz r17, Timer.Time+4(r8)
; r20 = timer being considered
; r18/r19 = trip-time of timer being condidered
lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Next(r1)
lwz r18, Timer.Time(r20)
lwz r19, Timer.Time+4(r20)
; First try to insert at head of global TMRQ
cmpw r16, r18
cmplw cr1, r17, r19
bgt @insert_further_ahead
blt @insert_at_tail
bge cr1, @insert_further_ahead
@insert_at_tail
addi r20, r1, PSA.TimerQueue + TimerQueueStruct.LLL
li r18, 1
stb r18, Timer.Byte3(r8)
; Insert at the very back of the queue
lwz r19, LLL.Freeform(r8)
lwz r9, LLL.Freeform(r20)
stw r9, LLL.Freeform(r8) ; my freeform = considered freeform
lwz r9, LLL.Next(r20)
stw r9, LLL.Next(r8) ; my next = next of considered
stw r20, LLL.Prev(r8) ; my prev = considered
stw r8, LLL.Prev(r9) ; prev of next of considered = me
stw r8, LLL.Next(r20) ; next of considered = me
stw r19, LLL.Freeform(r8) ; my freeform = my original freeform
b SetTimeslice
@insert_further_ahead
lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Prev(r1)
@searchloop
lwz r18, Timer.Time(r20)
lwz r19, Timer.Time+4(r20)
cmpw r16, r18
cmplw cr1, r17, r19
bgt @insert_after_this_one
blt @next
bge cr1, @insert_after_this_one
@next
lwz r20, LLL.Prev(r20)
b @searchloop
@insert_after_this_one
li r18, 1
stb r18, Timer.Byte3(r8)
lwz r19, LLL.Freeform(r8)
lwz r9, LLL.Freeform(r20)
stw r9, LLL.Freeform(r8) ; my freeform = considered freeform
lwz r9, LLL.Next(r20)
stw r9, LLL.Next(r8) ; my next = next of considered
stw r20, LLL.Prev(r8) ; my prev = considered
stw r8, LLL.Prev(r9) ; prev of next of considered = me
stw r8, LLL.Next(r20) ; next of considered = me
stw r19, LLL.Freeform(r8) ; my freeform = my original freeform
blr
; Remove a Timer from the global timer firing queue (TMRQ).
; If the Timer was to be the next to fire, then perform the
; standard decrementer rollover adjustment.
; ARG Timer *r8
DequeueTimer
lwz r16, Timer.QueueLLL + LLL.FreeForm(r8)
cmpwi r16, 0
lwz r18, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Next(r1)
beq Local_Panic
RemoveFromList r8, scratch1=r16, scratch2=r17
li r16, 0
cmpw r18, r8
stb r16, Timer.Byte3(r8)
beq SetTimeslice
blr
; Get the number of timebase ticks in a specified period
; ARG long r8 period (positive for ms, negative for us)
TimebaseTicksPerPeriod
mr. r17, r8
li r19, 250
lwz r9, KDP.ProcessorInfo + NKProcessorInfo.DecClockRateHz(r1)
bgt+ @period_positive
blt+ @period_negative
li r8, 0
li r9, 0
blr ; fail
@period_negative
neg r17, r17
lisori r19, 250000
@period_positive
divw r19, r9, r19
mullw r9, r19, r17
mulhw r8, r19, r17
srwi r9, r9, 2
rlwimi r9, r8, 30, 0, 1
srwi r8, r8, 2
blr
; RET long r8 tbu, long r9 tbl
; CLOB r16, r17
GetTime
mfpvr r8
rlwinm. r8, r8, 0, 0, 14
beq @is_601
@retry_timebase:
mftbu r8
mftb r9
mftbu r16
cmpw r8, r16
bne- @retry_timebase
b @return
@is_601
dialect POWER ; disassembled this in POWER mode!
@retry_rtc
mfrtcu r8
mfrtcl r9
mfrtcu r16
cmp 0, r8, r16
dialect PowerPC
bne- @retry_rtc ; POWER chokes on hints?
dialect POWER
liu r16, 1000000000 >> 16
oril r16, r16, 1000000000 & 0xffff
mfmq r17
mul r8, r16, r8
mfmq r16
mtmq r17
mfxer r17
a r9, r16, r9
aze r8, r8
mtxer r17
dialect POWERPC
@return
blr

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +1,44 @@
include 'MacErrors.a'
include 'Multiprocessing.a'
include 'InfoRecords.a'
include 'InfoRecords.a'
include 'EmulatorPublic.a'
include 'NKPublic.a'
include 'NKOpaque.a'
include 'NKStructs.s'
include 'NKEquates.s'
include 'NKMacros.s'
include 'NKEquates.s'
include 'NKMacros.s'
CodeBase
include 'NKInit.s'
include 'NKSystemCrash.s'
include 'NKHotInts.s'
NKTop
include 'NKInit.s'
align 5
include 'NKInterrupts.s'
align 5
include 'NKPaging.s'
align 5
include 'NKTranslation.s'
align 5
include 'NKVMCalls.s'
align 5
include 'NKPowerCalls.s'
align 5
include 'NKRTASCalls.s'
align 5
include 'NKCache.s'
; Persistent MemRetry registers:
; r17 = status (0-5 MRRestab entry || 6-10 src/dest register || 11-15 base register || 21-25 ?? || 26-30 access len || 31 0=Store/1=Load)
; r18 = EA of memory
; r19 = EA of byte after memory
; r20/r21 = loaded data/data to store
; Mostly MP calls:
align 5
include 'NKMPCalls.s'
align 5
include 'NKSync.s'
align 5
include 'NKTasks.s'
align 5
include 'NKAddressSpaces.s'
; Other MemRetry registers:
; r14 = saved MSR
; r15 = temp MSR
; r16 = Flags
; r22/r23 = scratch
; r24 = saved VecBase
; r25 = MemRetry ptr (do not trust low 10 bits)
; r26 = Optab entry (sec routine ptr in low 8 bits might be set on DSI)
; r27 = instruction
; r28 = offset of register field in EWA (= reg num * 4)
; r29/r31 = scratch
align 5
include 'NKPoolAllocator.s'
align 5
include 'NKTimers.s'
align 5
include 'NKScheduler.s'
align 5
include 'NKIndex.s'
align 5
include 'NKPrimaryIntHandlers.s'
align 5
include 'NKConsoleLog.s'
align 5
include 'NKSleep.s'
align 5
include 'NKThud.s'
align 5
include 'NKScreenConsole.s'
align 5
include 'NKAdditions.s'
align 5
NKBtm
_align 10
MRBase
include 'MROptabCode.s'
include 'MRMemtabCode.s'
include 'MRInterrupts.s'
include 'MROptab.s'
include 'MRMemtab.s'
include 'MRRestab.s'
include 'NKColdInts.s'
include 'NKMemory.s'
include 'NKExceptions.s'
include 'NKFloatingPt.s'
include 'NKSoftInts.s'
include 'NKLegacyVM.s'