;_______________________________________________________________________ ; Data structures internal to the NanoKernel ;_______________________________________________________________________ ;_______________________________________________________________________ ; NOTE: DECLARING BIT FIELDS ; ; Bit fields get defined inside a record only in order to give them a ; namespace (e.g. MSR_IP). The _bitEqu macro is used to produce three ; equates per bit: ; (name) = the bit's place value ; (name)bit = the bit's PowerPC index (0 is leftmost) ; (name)shift = the bit's 68k index (0 is rightmost) ;_______________________________________________________________________ macro _bitEqu &name, &bit &name equ 1 << (31-&bit) &name.bit equ &bit &name.shift equ 31 - &bit endm ;_______________________________________________________________________ ; INFORECORD PAGE ; ; Lives at 5fffe000 on most (all?) PowerPC Macs. The public-ish part ; is the InfoRecord, which lives in the upper 64 bytes. This contains ; logical pointers, sizes and versions for the data structures that ; are shared between the NanoKernel and userspace. See ; PPCInfoRecordsPriv.s for the contents of these structures. ; ;_______________________________________________________________________ IRP record 0xdc0,INCR SystemInfo ds.l 80 ; dc0:f00 ; other NK versions keep their structures elsewhere, HWInfo ds.l 48 ; f00:fc0 ; so always use InfoRecord to find them from userspace InfoRecord ds.l 16 ; fc0:1000 ; the public part endr ; Some InfoRecord fields are obliquely referenced from PPCInfoRecordsPriv.h ; (e.g. nkSystemInfoPtr = 0x5FFFEFF0) InfoRecord record 0,INCR InfoRecordPtr ds.l 1 ; 00 kdp/irp+fc0 ; set in kdp, copied to irp Zero ds.l 1 ; 04 kdp/irp+fc4 ; const NKProcessorStatePtr ds.l 1 ; 08 kdp/irp+fc8 ; in PSA NKProcessorStateVer ds.w 1 ; 0c kdp/irp+fcc ; const NKProcessorStateLen ds.w 1 ; 0e kdp/irp+fce ; const NKHWInfoPtr ds.l 1 ; 10 kdp/irp+fd0 ; in IRP NKHWInfoVer ds.w 1 ; 14 kdp/irp+fd4 ; const NKHWInfoLen ds.w 1 ; 16 kdp/irp+fd6 ; const NKProcessorInfoPtr ds.l 1 ; 18 kdp/irp+fd8 ; in KDP NKProcessorInfoVer ds.w 1 ; 1c kdp/irp+fdc ; const NKProcessorInfoLen ds.w 1 ; 1e kdp/irp+fde ; const NKNanoKernelInfoPtr ds.l 1 ; 20 kdp/irp+fe0 ; in KDP NKNanoKernelInfoVer ds.w 1 ; 24 kdp/irp+fe4 ; BCD NKNanoKernelInfoLen ds.w 1 ; 26 kdp/irp+fe6 ; const NKDiagInfoPtr ds.l 1 ; 28 kdp/irp+fe8 ; in PSA NKDiagInfoVer ds.w 1 ; 2c kdp/irp+fec ; const NKDiagInfoLen ds.w 1 ; 2e kdp/irp+fee ; const NKSystemInfoPtr ds.l 1 ; 30 kdp/irp+ff0 ; in IRP NKSystemInfoVer ds.w 1 ; 34 kdp/irp+ff4 ; const NKSystemInfoLen ds.w 1 ; 36 kdp/irp+ff6 ; const NKProcessorInfoPtr2 ds.l 1 ; 38 kdp/irp+ff8 ; in KDP (same as above) NKProcessorInfoVer2 ds.w 1 ; 3c kdp/irp+ffc ; const NKProcessorInfoLen2 ds.w 1 ; 3e kdp/irp+ffe ; const Size equ * endr ;_______________________________________________________________________ ; PRIMARY SYSTEM AREA ; ; The PSA is Rene's homage to the ESA390's prefix storage area. ; It contains "the PowerPC IVT and some NK pointers." ; ; New to NKv2, it lives in the page below the KDP. On CPU0, this is ; also just below the below-SPRG0 part of the Exception Work Area. ; It is almost always accessed by negative offset from GPR1, hence ; the negative offsets. ;_______________________________________________________________________ PSA record {EndOfPSA},INCR Base HTABLock ds.l 8 ; -b90:-b70 PIHLock ds.l 8 ; -b70:-b50 SchLock ds.l 8 ; -b50:-b30 ThudLock ds.l 8 ; -b30:-b10 ; for the interactive debugger RTASLock ds.l 8 ; -b10:-af0 DbugLock ds.l 8 ; -af0:-ad0 PoolLock ds.l 8 ; -ad0:-ab0 FreePool ds.l 4 ; -ab0 ; LLL with signature 'POOL' FirstPoolSeg ds.l 1 ; -aa0 ; singly linked list (=>BGN=>END=>BGN...) FirstPoolSegLogical ds.l 1 ; -a9c IndexPtr ds.l 1 ; -a98 ; index of opaque IDs CoherenceGrpList ds.l 4 ; -a94:-a84 ; signature 'GRPS' TimerQueue ds.l 16 ; -a84:-a44 ; there are more of these in the pool DelayQueue ds.l 4 ; -a44:-a34 DbugQueue ds.l 4 ; -a34:-a24 PageQueue ds.l 4 ; -a24:-a14 NotQueue ds.l 4 ; -a14:-a04 _a04 ds.l 1 ; -a04 QueueRelatedZero1 ds.l 1 ; -a00 ; set to zero when queues are inited QueueRelatedZero2 ds.l 1 ; -9fc ; same again _9f8 ds.l 1 ; -9f8 _9f4 ds.l 1 ; -9f4 ReadyQueues CriticalReadyQ ds.l 8 ; -9f0:-9d0 ; unblocked tasks with priority 0 LatencyProtectReadyQ ds.l 8 ; -9d0:-9b0 ; unblocked tasks with priority 1 NominalReadyQ ds.l 8 ; -9b0:-990 ; unblocked tasks with priority 2 IdleReadyQ ds.l 8 ; -990:-970 ; unblocked tasks with priority 3 PriorityFlags ds.l 1 ; -970 ; bit 0 is 0, bit 1 is 1, etc... ScrambledMPCallTime ds.l 1 ; -96c ; by MP call return FlagsTemplate ds.l 1 ; -968 ; typically just EWA.kFlagVec UserModeMSR ds.l 1 ; -964 ThudBuffer ds.b 96 ; -960:-900 ; that's the kernel debugger NoIdeaR23 ds.l 1 ; -900 ; r23 copies here... replated to RTAS? _8fc ds.l 1 ; -8fc _8f8 ds.l 1 ; -8f8 _8f4 ds.w 1 ; -8f4 _8f2 ds.w 1 ; -8f2 PA_BlueTask ds.l 1 ; -8f0 ; set at the same time as the one below _8ec ds.l 1 ; -8ec _8e8 ds.l 1 ; -8e8 OtherSystemContextPtr ds.l 1 ; -8e4 ; sometimes set to PA_ECB VectorRegInitWord ds.l 1 ; -8e0 ; task vector regs get inited with this word x 4 SevenFFFDead2 ds.l 1 ; -8dc SevenFFFDead3 ds.l 1 ; -8d8 SevenFFFDead4 ds.l 1 ; -8d4 VioletVecBase ds.l 48 ; -8d0:-810 VecBaseIdle ds.l 48 ; -810:-750 ; to wake from DOZE/NAP/SLEEP state VecBasePIH ds.l 48 ; -750:-690 ; gets enabled by PDM PIH VecBaseScreenConsole ds.l 48 ; -690:-5d0 DiagInfo ds.b 256 ; -5d0:-4d0 ProcessorState ds.b 128 ; -4d0:-450 ; interesting what this gets used by FreeList ds.l 4 ; -450:-440 MCR ds.l 1 ; -440 ; reported by heartbeat code Pending68kInt ds.w 1 ; -43c ; used when Sch interrupts blue task (-1 means "none") _43a ds.w 1 ; -43a DecClockRateHzCopy ds.l 1 ; -438 ; copied by Init.s OtherTimerQueuePtr ds.l 1 ; -434 ; unsigned timer queue in the pool, set by InitTMRQs FreePageCount ds.l 1 ; -430 ; zeroed by InitFreePageList UnheldFreePageCount ds.l 1 ; -42c ExternalHandlerID ds.l 1 ; -428 ; notification for PIH to bump SystemAddressSpaceID ds.l 1 ; -424 AgerID ds.l 1 ; -420 blueProcessPtr ds.l 1 ; -41c ; physical ptr to first type-1 struct created ThermalHandlerID ds.l 1 ; -418 ; is a Note struct PMFHandlerID ds.l 1 ; -414 ; also a Note struct BlueSpinningOn ds.l 1 ; -410 ; ID or 0 or -1 _40c ds.l 1 ; -40c _408 ds.l 1 ; -408 _404 ds.l 1 ; -404 _400 ds.l 1 ; -400 OtherSystemAddrSpcPtr ds.l 1 ; -3fc OtherSystemAddrSpcPtr2 ds.l 1 ; -3f8 ; copied from the one above by InitFreePageList ZeroedByInitFreeList3 ds.l 1 ; -3f4 _3f0 ds.l 1 ; -3f0 _3ec ds.l 1 ; -3ec _3e8 ds.l 1 ; -3e8 _3e4 ds.l 1 ; -3e4 _3e0 ds.l 1 ; -3e0 _3dc ds.l 1 ; -3dc _3d8 ds.l 1 ; -3d8 _3d4 ds.l 1 ; -3d4 _3d0 ds.l 1 ; -3d0 _3cc ds.l 1 ; -3cc _3c8 ds.l 1 ; -3c8 _3c4 ds.l 1 ; -3c4 _3c0 ds.l 1 ; -3c0 _3bc ds.l 1 ; -3bc _3b8 ds.l 1 ; -3b8 _3b4 ds.l 1 ; -3b4 _3b0 ds.l 1 ; -3b0 _3ac ds.l 1 ; -3ac _3a8 ds.l 1 ; -3a8 _3a4 ds.l 1 ; -3a4 _3a0 ds.l 1 ; -3a0 _39c ds.l 1 ; -39c _398 ds.l 1 ; -398 _394 ds.l 1 ; -394 _390 ds.l 1 ; -390 _38c ds.l 1 ; -38c _388 ds.l 1 ; -388 _384 ds.l 1 ; -384 _380 ds.l 1 ; -380 _37c ds.l 1 ; -37c _378 ds.l 1 ; -378 _374 ds.l 1 ; -374 _370 ds.l 1 ; -370 _36c ds.l 1 ; -36c _368 ds.l 1 ; -368 _364 ds.l 1 ; -364 _360 ds.w 1 ; -360 _35e ds.w 1 ; -35e _35c ds.w 1 ; -35c _35a ds.w 1 ; -35a _358 ds.w 1 ; -358 _356 ds.w 1 ; -356 _354 ds.l 1 ; -354 _350 ds.l 1 ; -350 _34c ds.l 1 ; -34c _348 ds.l 1 ; -348 _344 ds.l 1 ; -344 EWAFiller ds.b 0x340 EndOfPSA endr ;_______________________________________________________________________ ; EXCEPTION WORK AREA ; ; Each CPU has one of these. It is half-heartedly enclosed by a "CPU" ; MP struct. Along with the SPRG registers, it is essential in order ; for the CPU to get its bearings at interrupt time. Each CPU's SPRG0 ; always points *into* that CPU's EWA. ;_______________________________________________________________________ EWA record -0x340,INCR ; Fun fact: offsets before here contain the additional kernel globals ; ("Primary System Area"), but only on CPU-0. ; It's kind of complicated, but the CPU MP struct of CPU-0 ; starts life as a chunk of the kernel globals, carefully placed ; so the "middle" (zero offset) of the Exception Work Area ; within that CPU struct will equal the "middle" (zero offset) ; of the kernel globals (i.e. between the negative-index v2-only ; Primary System Area and the positive-offset Kernel Data Page). ; Subsequent CPU structs are just large allocations in the kernel ; pool, with the CPU's SPRG0 register being pointed to the zero ; point of that CPU struct's EWA. CPUBase ds.b 32 ; -340:-320 ; not really part of the EWA, but more an MP struct Base ; used when init'ed as part of the enclosing CPU struct ; Now for the actual meat of sandwich. ; Many of these fields are used by functions at interrupt time ; to save/restore registers, in lieu of a stack. TimeList ds.l 4 ; -320:-310, cpu+020 ds.l 1 ; -310, cpu+030 ds.b 1 ; -30c, cpu+034 ds.b 1 ; -30b, cpu+035 ds.b 1 ; -30a, cpu+036 GlobalTimeIsValid ds.b 1 ; -309, cpu+037 ds.l 1 ; -308, cpu+038 ds.l 1 ; -304, cpu+03c ds.l 1 ; -300, cpu+040 ds.l 1 ; -2fc, cpu+044 ds.l 1 ; -2f8, cpu+048 ds.l 1 ; -2f4, cpu+04c ds.l 1 ; -2f0, cpu+050 ds.l 1 ; -2ec, cpu+054 GlobalTime ds.l 2 ; -2e8, cpu+058 ThudSavedR29 ds.l 1 ; -2e0, cpu+060 ThudSavedR30 ds.l 1 ; -2dc, cpu+064 ThudSavedR31 ds.l 1 ; -2d8, cpu+068 ds.l 1 ; -2d4, cpu+06c SIGPSavedR10 ds.l 1 ; -2d0, cpu+070 SIGPSavedR11 ds.l 1 ; -2cc, cpu+074 SIGPSavedR12 ds.l 1 ; -2c8, cpu+078 SIGPSavedR13 ds.l 1 ; -2c4, cpu+07c SIGPSavedXER ds.l 1 ; -2c0, cpu+080 SIGPSavedCTR ds.l 1 ; -2bc, cpu+084 SIGPSavedLR ds.l 1 ; -2b8, cpu+088 SIGPSavedR6 ds.l 1 ; -2b4, cpu+08c SIGPSavedR7 ds.l 1 ; -2b0, cpu+090 SIGPSpacOnResume ds.l 1 ; -2ac, cpu+094 ; address space ptr to switch to when plug has executed ds.l 1 ; -2a8, cpu+098 ds.l 1 ; -2a4, cpu+09c ds.l 1 ; -2a0, cpu+0a0 ds.l 1 ; -29c, cpu+0a4 ds.l 1 ; -298, cpu+0a8 ds.l 1 ; -294, cpu+0ac ds.l 1 ; -290, cpu+0b0 ds.l 1 ; -28c, cpu+0b4 ds.l 1 ; -288, cpu+0b8 ds.l 1 ; -284, cpu+0bc ds.l 1 ; -280, cpu+0c0 ds.l 1 ; -27c, cpu+0c4 SpacesSavedLR ds.l 1 ; -278, cpu+0c8 SpacesSavedCR ds.l 1 ; -274, cpu+0cc SpacesSavedAreaBase ds.l 1 ; -270, cpu+0d0 SpacesDeferredAreaPtr ds.l 1 ; -26c, cpu+0d4 ds.l 1 ; -268, cpu+0d8 ds.l 1 ; -264, cpu+0dc SchSavedIncomingTask ds.l 1 ; -260, cpu+0e0 ds.l 1 ; -25c, cpu+0e4 TimerDispatchLR ds.l 1 ; -258, cpu+0e8 ds.l 1 ; -254, cpu+0ec ds.l 1 ; -250, cpu+0f0 ds.l 1 ; -24c, cpu+0f4 ds.l 1 ; -248, cpu+0f8 ds.l 1 ; -244, cpu+0fc ds.l 1 ; -240, cpu+100 ds.l 1 ; -23c, cpu+104 SIGPSelector ds.l 1 ; -238, cpu+108 SIGPCallR4 ds.l 1 ; -234, cpu+10c SIGPCallR5 ds.l 1 ; -230, cpu+110 SIGPCallR6 ds.l 1 ; -22c, cpu+114 SIGPCallR7 ds.l 1 ; -228, cpu+118 SIGPCallR8 ds.l 1 ; -224, cpu+11c SIGPCallR9 ds.l 1 ; -220, cpu+120 SIGPCallR10 ds.l 1 ; -21c, cpu+124 ds.l 1 ; -218, cpu+128 ds.l 1 ; -214, cpu+12c ds.l 1 ; -210, cpu+130 ds.l 1 ; -20c, cpu+134 ds.l 1 ; -208, cpu+138 ds.l 1 ; -204, cpu+13c ds.l 1 ; -200, cpu+140 ds.l 1 ; -1fc, cpu+144 ds.l 1 ; -1f8, cpu+148 ds.l 1 ; -1f4, cpu+14c ds.l 1 ; -1f0, cpu+150 ds.l 1 ; -1ec, cpu+154 ds.l 1 ; -1e8, cpu+158 ds.l 1 ; -1e4, cpu+15c ds.l 1 ; -1e0, cpu+160 ds.l 1 ; -1dc, cpu+164 ds.l 1 ; -1d8, cpu+168 ds.l 1 ; -1d4, cpu+16c ds.l 1 ; -1d0, cpu+170 ds.l 1 ; -1cc, cpu+174 ds.l 1 ; -1c8, cpu+178 ds.l 1 ; -1c4, cpu+17c ds.l 1 ; -1c0, cpu+180 ds.l 1 ; -1bc, cpu+184 ds.l 1 ; -1b8, cpu+188 ds.l 1 ; -1b4, cpu+18c ds.l 1 ; -1b0, cpu+190 ds.l 1 ; -1ac, cpu+194 ds.l 1 ; -1a8, cpu+198 ds.l 1 ; -1a4, cpu+19c ds.l 1 ; -1a0, cpu+1a0 ds.l 1 ; -19c, cpu+1a4 ds.l 1 ; -198, cpu+1a8 ds.l 1 ; -194, cpu+1ac ds.l 1 ; -190, cpu+1b0 ds.l 1 ; -18c, cpu+1b4 ds.l 1 ; -188, cpu+1b8 ds.l 1 ; -184, cpu+1bc ds.l 1 ; -180, cpu+1c0 ds.l 1 ; -17c, cpu+1c4 ds.l 1 ; -178, cpu+1c8 ds.l 1 ; -174, cpu+1cc ds.l 1 ; -170, cpu+1d0 ds.l 1 ; -16c, cpu+1d4 ds.l 1 ; -168, cpu+1d8 ds.l 1 ; -164, cpu+1dc ds.l 1 ; -160, cpu+1e0 ds.l 1 ; -15c, cpu+1e4 ds.l 1 ; -158, cpu+1e8 ds.l 1 ; -154, cpu+1ec ds.l 1 ; -150, cpu+1f0 ds.l 1 ; -14c, cpu+1f4 ds.l 1 ; -148, cpu+1f8 ds.l 1 ; -144, cpu+1fc ds.l 1 ; -140, cpu+200 ds.l 1 ; -13c, cpu+204 ds.l 1 ; -138, cpu+208 ds.l 1 ; -134, cpu+20c ds.l 1 ; -130, cpu+210 ds.l 1 ; -12c, cpu+214 ds.l 1 ; -128, cpu+218 ds.l 1 ; -124, cpu+21c ds.l 1 ; -120, cpu+220 ds.l 1 ; -11c, cpu+224 SchEvalFlag ds.b 1 ; -118, cpu+228 TaskPriority ds.b 1 ; -117, cpu+229 CPUIndex ds.w 1 ; -116, cpu+22a WeMightClear ds.l 1 ; -114, cpu+22c ; still boots if not cleared ds.l 1 ; -110, cpu+230 ds.l 1 ; -10c, cpu+234 ds.l 1 ; -108, cpu+238 ds.l 1 ; -104, cpu+23c ds.l 1 ; -100, cpu+240 ds.l 1 ; -0fc, cpu+244 ds.l 1 ; -0f8, cpu+248 ds.l 1 ; -0f4, cpu+24c ds.l 1 ; -0f0, cpu+250 ds.l 1 ; -0ec, cpu+254 ds.l 1 ; -0e8, cpu+258 SpecialAreaPtr ds.l 1 ; -0e4, cpu+25c ; will panic on page fault if this is not valid ds.l 1 ; -0e0, cpu+260 ds.l 1 ; -0dc, cpu+264 ds.l 1 ; -0d8, cpu+268 ds.l 1 ; -0d4, cpu+26c ds.l 1 ; -0d0, cpu+270 ds.l 1 ; -0cc, cpu+274 ds.l 1 ; -0c8, cpu+278 ds.l 1 ; -0c4, cpu+27c ds.l 1 ; -0c0, cpu+280 ds.l 1 ; -0bc, cpu+284 ds.l 1 ; -0b8, cpu+288 ds.l 1 ; -0b4, cpu+28c ds.l 1 ; -0b0, cpu+290 ds.l 1 ; -0ac, cpu+294 ds.l 1 ; -0a8, cpu+298 ds.l 1 ; -0a4, cpu+29c ds.l 1 ; -0a0, cpu+2a0 ds.l 1 ; -09c, cpu+2a4 ds.l 1 ; -098, cpu+2a8 ds.l 1 ; -094, cpu+2ac ds.l 1 ; -090, cpu+2b0 ds.l 1 ; -08c, cpu+2b4 ds.l 1 ; -088, cpu+2b8 ds.l 1 ; -084, cpu+2bc ds.l 1 ; -080, cpu+2c0 ds.l 1 ; -07c, cpu+2c4 ds.l 1 ; -078, cpu+2c8 ds.l 1 ; -074, cpu+2cc ds.l 1 ; -070, cpu+2d0 ds.l 1 ; -06c, cpu+2d4 ds.l 1 ; -068, cpu+2d8 ds.l 1 ; -064, cpu+2dc PoolSavedLR ds.l 1 ; -060, cpu+2e0 PoolSavedSizeArg ds.l 1 ; -05c, cpu+2e4 ds.l 1 ; -058, cpu+2e8 ds.l 1 ; -054, cpu+2ec ds.l 1 ; -050, cpu+2f0 ds.l 1 ; -04c, cpu+2f4 ds.l 1 ; -048, cpu+2f8 ds.l 1 ; -044, cpu+2fc CreateAreaSavedLR ds.l 1 ; -040, cpu+300 CreateAreaSavedR25 ds.l 1 ; -03c, cpu+304 ; ???!!! CreateAreaSavedR26 ds.l 1 ; -038, cpu+308 CreateAreaSavedR27 ds.l 1 ; -034, cpu+30c CreateAreaSavedR28 ds.l 1 ; -030, cpu+310 CreateAreaSavedR29 ds.l 1 ; -02c, cpu+314 CreateAreaSavedR30 ds.l 1 ; -028, cpu+318 CreateAreaSavedR31 ds.l 1 ; -024, cpu+31c PA_IRP ds.l 1 ; -020, cpu+320 PA_CurAddressSpace ds.l 1 ; -01c, cpu+324 PA_PSA ds.l 1 ; -018, cpu+328 PA_ContextBlock ds.l 1 ; -014, cpu+32c Flags ds.l 1 ; -010, cpu+330 Enables ds.l 1 ; -00c, cpu+334 PA_CurTask ds.l 1 ; -008, cpu+338 PA_KDP ds.l 1 ; -004, cpu+33c ; ZERO (SPRG0 points here) r0 ds.l 1 ; 000, cpu+340 ; used for quick register saves at exception time... r1 ds.l 1 ; 004, cpu+344 r2 ds.l 1 ; 008, cpu+348 r3 ds.l 1 ; 00c, cpu+34c r4 ds.l 1 ; 010, cpu+350 r5 ds.l 1 ; 014, cpu+354 r6 ds.l 1 ; 018, cpu+358 r7 ds.l 1 ; 01c, cpu+35c r8 ds.l 1 ; 020, cpu+360 r9 ds.l 1 ; 024, cpu+364 r10 ds.l 1 ; 028, cpu+368 r11 ds.l 1 ; 02c, cpu+36c r12 ds.l 1 ; 030, cpu+370 r13 ds.l 1 ; 034, cpu+374 r14 ds.l 1 ; 038, cpu+378 r15 ds.l 1 ; 03c, cpu+37c r16 ds.l 1 ; 040, cpu+380 r17 ds.l 1 ; 044, cpu+384 r18 ds.l 1 ; 048, cpu+388 r19 ds.l 1 ; 04c, cpu+38c r20 ds.l 1 ; 050, cpu+390 r21 ds.l 1 ; 054, cpu+394 r22 ds.l 1 ; 058, cpu+398 r23 ds.l 1 ; 05c, cpu+39c r24 ds.l 1 ; 060, cpu+3a0 r25 ds.l 1 ; 064, cpu+3a4 r26 ds.l 1 ; 068, cpu+3a8 r27 ds.l 1 ; 06c, cpu+3ac r28 ds.l 1 ; 070, cpu+3b0 r29 ds.l 1 ; 074, cpu+3b4 r30 ds.l 1 ; 078, cpu+3b8 r31 ds.l 1 ; 07c, cpu+3bc ; Fun fact: offsets past here contain the main kernel globals ; ("Kernel Data Page"), but only on CPU-0. kFlag0 equ 0 kFlag1 equ 1 kFlag2 equ 2 kFlag3 equ 3 kFlag4 equ 4 kFlag5 equ 5 kFlag6 equ 6 kFlag7 equ 7 ; PER-TASK FLAGS kFlagEmu equ 8 ; emulator is running kFlag9 equ 9 ; * = preserved on alt>sys switch kFlagBlue equ 10 ; * kFlag11 equ 11 ; * kFlagVec equ 12 ; * kFlagHasMQ equ 13 ; * kFlag14 equ 14 ; * kFlag15 equ 15 ; * kFlagSIGP equ 16 ; * ; PER-CONTEXT FLAGS kFlag17 equ 17 kFlag18 equ 18 kFlag19 equ 19 kFlagFE0 equ 20 ; these correspond with MSR bits kFlagSE equ 21 kFlagBE equ 22 kFlagFE1 equ 23 kFlag24 equ 24 kFlag25 equ 25 kFlag26 equ 26 ; can be copied from kFlagSE kFlagLowSaves equ 27 kFlag28 equ 28 kFlag29 equ 29 kFlag30 equ 30 kFlag31 equ 31 endr ;_______________________________________________________________________ ; KERNEL DATA PAGE ; ; Positive offsets from the kernel global pointer (which can be found ; in the PA_KDP field of any CPU's EWA, and directly in the SPRG0 of ; CPU-0). Except for offsets < 128 bytes, which belong to the GPR save ; area of CPU-0's EWA (see the r0, r1 etc. directly above here?) ;_______________________________________________________________________ KDP record 0x80,INCR 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 ; GAP org 0x340 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 VecBaseSystem ds.l 48 ; 360:420 ; when 68k emulator is running, *or* any MTask VecBaseAlternate ds.l 48 ; 420:4e0 ; native PowerPC in blue task VecBaseMemRetry ds.l 48 ; 4e0:5a0 ; "FDP" instruction emulation OldKDP ds.l 1 ; 5a0 ; gotten from the old SPRG0 OtherFreeThing ds.l 1 ; 5a4 TopOfFreePages ds.l 1 ; 5a8 ; gotten from the old SPRG0 ds.l 1 ; 5ac PA_InterruptHandler ds.l 1 ; 5b0 LA_NCB ds.l 1 ; 5b4 ; most recent physical address found HiLevelPerfMonitorBits ds.l 1 ; 5b8 ds.l 1 ; 5bc PerfMonitorBits ds.l 1 ; 5c0 ds.l 1 ; 5c4 SegMap32SupInitPtr ds.l 1 ; 5c8 BatMap32SupInit ds.l 1 ; 5cc SegMap32UsrInitPtr ds.l 1 ; 5d0 BatMap32UsrInit ds.l 1 ; 5d4 SegMap32CPUInitPtr ds.l 1 ; 5d8 BatMap32CPUInit ds.l 1 ; 5dc SegMap32OvlInitPtr ds.l 1 ; 5e0 BatMap32OvlInit ds.l 1 ; 5e4 ds.l 1 ; 5e8 ds.l 1 ; 5ec NanoKernelCallTable ds.l 16 ; 5f0:630 PA_ConfigInfo ds.l 1 ; 630 PA_EmulatorData ds.l 1 ; 634 KernelMemoryBase ds.l 1 ; 638 KernelMemoryEnd ds.l 1 ; 63c ; Top of HTAB (and entire kernel reserved area). Set by Init.s PA_RelocatedLowMemInit ds.l 1 ; 640 ; From ConfigInfo. Ptr to Mac LowMem vars, which Init.s sets up SharedMemoryAddr ds.l 1 ; 644 ; From ConfigInfo. Not sure what latest use is. LA_EmulatorKernelTrapTable ds.l 1 ; 648 ; Calculated from ConfigInfo. PA_NanoKernelCode ds.l 1 ; 64c ; Calculated by NanoKernel itself. PA_FDP ds.l 1 ; 650 ; See notes in NanoKernel. Very interesting. LA_ECB ds.l 1 ; 654 ; Logical ptr into EDP. PA_ECB ds.l 1 ; 658 ; gets called "system context" PA_ECB_Old ds.l 1 ; 65c ; copied from NKv<=01.01 to EWA.PA_ContextBlock. ds.l 1 ; 660 ds.l 1 ; 664 ds.l 1 ; 668 PA_PageMapEnd ds.l 1 ; 66c ; Set at the same time as PA_PageMapStart below... TestIntMaskInit ds.l 1 ; 670 ; These are all copied from ConfigInfo... PostIntMaskInit ds.l 1 ; 674 ClearIntMaskInit ds.l 1 ; 678 PA_EmulatorIplValue ds.l 1 ; 67c ; Physical ptr into EDP SharedMemoryAddrPlus ds.l 1 ; 680 ; Really not sure PA_PageMapStart ds.l 1 ; 684 ; Physical ptr to PageMap (= KDP+0x920) PageAttributeInit ds.l 1 ; 688 ; defaults for page table entries (see ConfigInfo) ds.l 1 ; 68c ds.l 1 ; 690 ds.l 1 ; 694 ds.l 1 ; 698 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 FlatPageListPtr ds.l 1 ; 6b0 ; VM puts this in system heap VMMaxVirtualPages ds.l 1 ; 6b4 ; always 5fffe000, even with VM on CpuSpecificBytes CpuSpecificByte1 ds.b 1 ; 6b8 ; seems to contain flags (set from PVR & tbl by Init.s) CpuSpecificByte2 ds.b 1 ; 6b9 ; probably not flags (set in same way) ds.b 1 ; 6ba ds.b 1 ; 6bb ds.l 1 ; 6bc FlatPageListSegPtrs ds.l 16 ; 6c0 StartOfPanicArea ; PROTECTED BY THUD LOCK ThudSavedR0 ds.l 1 ; 700 ThudSavedR1 ds.l 1 ; 704 ; via SPRG1 ThudSavedR2 ds.l 1 ; 708 ThudSavedR3 ds.l 1 ; 70c ThudSavedR4 ds.l 1 ; 710 ThudSavedR5 ds.l 1 ; 714 ThudSavedR6 ds.l 1 ; 718 ThudSavedR7 ds.l 1 ; 71c ThudSavedR8 ds.l 1 ; 720 ThudSavedR9 ds.l 1 ; 724 ThudSavedR10 ds.l 1 ; 728 ThudSavedR11 ds.l 1 ; 72c ThudSavedR12 ds.l 1 ; 730 ThudSavedR13 ds.l 1 ; 734 ThudSavedR14 ds.l 1 ; 738 ThudSavedR15 ds.l 1 ; 73c ThudSavedR16 ds.l 1 ; 740 ThudSavedR17 ds.l 1 ; 744 ThudSavedR18 ds.l 1 ; 748 ThudSavedR19 ds.l 1 ; 74c ThudSavedR20 ds.l 1 ; 750 ThudSavedR21 ds.l 1 ; 754 ThudSavedR22 ds.l 1 ; 758 ThudSavedR23 ds.l 1 ; 75c ThudSavedR24 ds.l 1 ; 760 ThudSavedR25 ds.l 1 ; 764 ThudSavedR26 ds.l 1 ; 768 ThudSavedR27 ds.l 1 ; 76c ThudSavedR28 ds.l 1 ; 770 ThudSavedR29 ds.l 1 ; 774 ThudSavedR30 ds.l 1 ; 778 ThudSavedR31 ds.l 1 ; 77c ThudSavedCR ds.l 1 ; 780 ThudSavedMQ ds.l 1 ; 784 ThudSavedXER ds.l 1 ; 788 ThudSavedSPRG2 ds.l 1 ; 78c ; 'LR' ThudSavedCTR ds.l 1 ; 790 ThudSavedPVR ds.l 1 ; 794 ThudSavedDSISR ds.l 1 ; 798 ThudSavedDAR ds.l 1 ; 79c ThudSavedTBU ds.l 1 ; 7a0 ; RTCU on 601 ThudSavedTB ds.l 1 ; 7a4 ; RTCL on 601 ThudSavedDEC ds.l 1 ; 7a8 ThudSavedHID0 ds.l 1 ; 7ac ThudSavedSDR1 ds.l 1 ; 7b0 ThudSavedSRR0 ds.l 1 ; 7b4 ThudSavedSRR1 ds.l 1 ; 7b8 ThudSavedMSR ds.l 1 ; 7bc ThudSavedSR0 ds.l 1 ; 7c0 ThudSavedSR1 ds.l 1 ; 7c4 ThudSavedSR2 ds.l 1 ; 7c8 ThudSavedSR3 ds.l 1 ; 7cc ThudSavedSR4 ds.l 1 ; 7d0 ThudSavedSR5 ds.l 1 ; 7d4 ThudSavedSR6 ds.l 1 ; 7d8 ThudSavedSR7 ds.l 1 ; 7dc ThudSavedSR8 ds.l 1 ; 7e0 ThudSavedSR9 ds.l 1 ; 7e4 ThudSavedSR10 ds.l 1 ; 7e8 ThudSavedSR11 ds.l 1 ; 7ec ThudSavedSR12 ds.l 1 ; 7f0 ThudSavedSR13 ds.l 1 ; 7f4 ThudSavedSR14 ds.l 1 ; 7f8 ThudSavedSR15 ds.l 1 ; 7fc ThudSavedF0 ds.d 1 ; KDP.BATs + 0xa0 ThudSavedF1 ds.d 1 ; 808 ThudSavedF2 ds.d 1 ; 810 ThudSavedF3 ds.d 1 ; 818 ThudSavedF4 ds.d 1 ; 820 ThudSavedF5 ds.d 1 ; 828 ThudSavedF6 ds.d 1 ; 830 ThudSavedF7 ds.d 1 ; 838 ThudSavedF8 ds.d 1 ; 840 ThudSavedF9 ds.d 1 ; 848 ThudSavedF10 ds.d 1 ; 850 ThudSavedF11 ds.d 1 ; 858 ThudSavedF12 ds.d 1 ; 860 ThudSavedF13 ds.d 1 ; 868 ThudSavedF14 ds.d 1 ; 870 ThudSavedF15 ds.d 1 ; 878 ThudSavedF16 ds.d 1 ; 880 ThudSavedF17 ds.d 1 ; 888 ThudSavedF18 ds.d 1 ; 890 ThudSavedF19 ds.d 1 ; 898 ThudSavedF20 ds.d 1 ; 8a0 ThudSavedF21 ds.d 1 ; 8a8 ThudSavedF22 ds.d 1 ; 8b0 ThudSavedF23 ds.d 1 ; 8b8 ThudSavedF24 ds.d 1 ; 8c0 ThudSavedF25 ds.d 1 ; 8c8 ThudSavedF26 ds.d 1 ; 8d0 ThudSavedF27 ds.d 1 ; 8d8 ThudSavedF28 ds.d 1 ; 8e0 ThudSavedF29 ds.d 1 ; 8e8 ThudSavedF30 ds.d 1 ; 8f0 ThudSavedF31 ds.d 1 ; 8f8 SomethingSerial ds.l 1 ; 900 ; 'fpscr' ThudSavedLR ds.l 1 ; 904 ; 'caller' RTAS_Proc ds.l 1 ; 908 ; r8 on kernel entry EndOfPanicArea RTAS_PrivDataArea ds.l 1 ; 90c ; copied from HWInfo ZeroWord ds.l 1 ; 910 ; Only NewWorld and Unknown PIHes touch this ds.l 1 ; 914 ds.l 1 ; 918 ds.l 1 ; 91c PageMap ds.b 1184; 920:dc0 NanoKernelInfo ds.b 352 ; dc0:f20 ; see NKNanoKernelInfo in PPCInfoRecordsPriv ProcessorInfo ds.b 160 ; f20:fc0 InfoRecord ds.b 64 ; fc0:1000 ; was main copy in NKv1, now vestigial? endr ;_______________________________________________________________________ ; KERNEL VECTOR TABLE ; ; The kernel creates several of these, and activates one by pointing ; a CPU's SPRG3 ("vecBase") register at it. Find them in PSA and KDP. ; (For want of more information, I have colour coded them for now.) ; ; Each entry is a (hopefully 64-byte aligned) physical pointer to an ; interrupt service routine in the kernel. One entry roughly ; corresponds with one of the 256-byte aligned entry points into ; the PowerPC interrupt (="exception") vector table. Code for those ; can be found in :RISC:ExceptionTable.s. ;_______________________________________________________________________ VecTable record 0,INCR ; VBGYOR ds.l 1 ; 00 ; scratch for IVT? SystemResetVector ds.l 1 ; 04 ; called by IVT+100 (system reset) MachineCheckVector ds.l 1 ; 08 ; called by IVT+200 (machine check) DSIVector ds.l 1 ; 0c ; called by IVT+300 (DSI) ISIVector ds.l 1 ; 10 ; called by IVT+400 (ISI) ExternalIntVector ds.l 1 ; 14 ; called by IVT+500 (external interrupt) AlignmentIntVector ds.l 1 ; 18 ; called by IVT+600 (alignment) ProgramIntVector ds.l 1 ; 1c ; called by IVT+700 (program) FPUnavailVector ds.l 1 ; 20 ; called by IVT+KDP.BATs + 0xa0 (FP unavail) DecrementerVector ds.l 1 ; 24 ; called by IVT+900 (decrementer) ReservedVector1 ds.l 1 ; 28 ; called by IVT+a00 (reserved) ReservedVector2 ds.l 1 ; 2c ; called by IVT+b00 (reserved) SyscallVector ds.l 1 ; 30 ; called by IVT+c00 (system call) TraceVector ds.l 1 ; 34 ; called by IVT+d00 (trace) FPAssistVector ds.l 1 ; 38 ; called by IVT+e00 (FP assist) PerfMonitorVector ds.l 1 ; 3c ; called by IVT+f00 (perf monitor) 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 ThermalEventVector 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 ; ds.l 1 ; 80 ; shares with TraceVector in Y and G 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 ; called by IVT+0 (reserved) Size equ * endr ;_______________________________________________________________________ ; NANOKERNEL CALL (KCALL) TABLE ; ; You can also use this record to index the NanoKernelCallCounts in ; PPCInfoRecordsPriv.s:NKNanoKernelInfo. ;_______________________________________________________________________ NanoKernelCallTable record 0,INCR ReturnFromException ds.l 1 ; 00, kdp+5f0, trap 0 ; SS replaces with jump to emu+f900 RunAlternateContext ds.l 1 ; 04, kdp+5f4, trap 1 ResetSystem ds.l 1 ; 08, kdp+5f8, trap 2 ; SS replaces with jump to emu+fb00 VMDispatch ds.l 1 ; 0c, kdp+5fc, trap 3 ; FE0A (VM/MMU/NK) trap PrioritizeInterrupts ds.l 1 ; 10, kdp+600, trap 4 ; SS forbids PowerDispatch ds.l 1 ; 14, kdp+604, trap 5 ; FEOF RTASDispatch ds.l 1 ; 18, kdp+608, trap 6 ; SS forbids the use of this trap and below CacheDispatch ds.l 1 ; 1c, kdp+60c, trap 7 MPDispatch ds.l 1 ; 20, kdp+610, trap 8 ; also accessible via syscall interface ds.l 1 ; 24, kdp+614, trap 9 ; unused ds.l 1 ; 28, kdp+618, trap 10 ; unused ds.l 1 ; 2c, kdp+61c, trap 11 ; unused CallAdapterProcPPC ds.l 1 ; 30, kdp+620, trap 12 ; unused ds.l 1 ; 34, kdp+624, trap 13 ; unused CallAdapterProc68k ds.l 1 ; 38, kdp+628, trap 14 ; unused Thud ds.l 1 ; 3c, kdp+62c, trap 15 ; basically just panic Size equ * endr ;_______________________________________________________________________ ; PAGEMAP DESCRIPTOR TABLE ; ; An 8-byte entry in the PageMap tables passed to the NanoKernel via ; ConfigInfo. Roughly corresponds with a contiguous logical address ; range lying within 256MB (segment) boundaries, and therefore ; roughly corresponds with the NKv2 MP "Area" struct. ; ; It could be that these are actually PageMap Descriptor *Entries*, ; and I have misunderstood. ;_______________________________________________________________________ PMDT record 0,INCR 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 ;_______________________________________________________________________ ; KERNEL SPINLOCK ; ; Seven of these, each with a four-byte signature, live in the PSA. ; The signatures describe the protected structures adequately. ; ; The function to acquire a lock seems to have been inlined, because ; it always saves and restores r8 and r9 (even to and from themselves) ; around a bl to NanoKernelInit.s:AcquireLock. It has therefore been ; macrofied as NanoKernelMacros.s:_Lock. ;_______________________________________________________________________ Lock record 0,INCR Count ds.l 1 ; 00 ; target for lwarx/stwcx Signature ds.l 1 ; 04 kHTABLockSignature equ 'htab' kPIHLockSignature equ 'pih ' kSchLockSignature equ 'sch ' kThudLockSignature equ 'thud' kRTASLockSignature equ 'rtas' kDbugLockSignature equ 'dbug' kPoolLockSignature equ 'pool' org 0x10 Holder ds.l 1 ; 10 org 0x20 endr ; Structs after this point are inadequately commented. Sorry! Index record 0,INCR kSignature equ 'INDX' HalfOne ds.w 1 ; 000 HalfTwo ds.w 1 ; 002 Signature ds.l 1 ; 004 IDsPtr ds.l 1 ; 008 org 520 Size equ * endr ; Special opaque NanoKernel stuff! ; These seem to go in a notification queue? LLL record 0,INCR Freeform ds.l 1 ; 0 Signature ds.l 1 ; 4 Next ds.l 1 ; 8 Prev ds.l 1 ; c endr ; Special case of LLL ; Init'ed by InitTMRQs (called by Init.s) ; There is one copy of this struct at kdp-a84 below the (shorter) queue structs, ; and two copies in the pool, pointed to by kdp-434 and kdp-364. TimerQueueStruct record 0,INCR LLL ds.l 4 ; 00 Unused ds.l 1 ; 10 ZeroByte ds.b 1 ; 14 ; can also be set to 7 or 8 UnusedByte ds.b 1 ; 15 OneByte1 ds.b 1 ; 16 OneByte2 ds.b 1 ; 17 ; can also be unset ; GAP org 0x38 TimeCtr ds.d 1 ; 38 ; high half in DEC reg or whole thing in TB endr ; For altivec, mofo VectorSaveArea record 0,INCR org 23*16 ;RegisterAreaSize equ *-VectorSaveArea RegisterAreaSize equ 23*16 org 32*16 + 20 endr