├── BuildResults └── ThisFolderMustExist ├── README.md ├── EasyBuild ├── MakeFile ├── Emulator.x ├── RomMondo.bin ├── .gitignore ├── Linker ├── LinkPowerROM └── LinkPowerROM.c ├── NanoKernel ├── NKThud.s ├── InnerMakeFile ├── NKScheduler.s ├── NKPoolAllocator.s ├── NKReplacementInit.s ├── MakeFile ├── NanoKernel.s ├── NKAdditions.s ├── NKEquates.s ├── NKProcInfoTbl.s ├── NKProcFlagsTbl.s ├── NKRTASCalls.s ├── NKMacros.s ├── NKIndex.s ├── NKCache.s ├── NKConsoleLog.s ├── NKSleep.s ├── NKPaging.s ├── NKPowerCalls.s ├── NKTimers.s └── NKScreenConsole.s ├── SetFileTypes.sh ├── EasyBuild.sh ├── AsmSymScanner.py ├── Internal ├── EmulatorPublic.a └── NKOpaque.a ├── ConfigInfo.s └── PPCExceptionTable.s /BuildResults/ThisFolderMustExist: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Use https://github.com/elliotnunn/tbxi instead! 2 | -------------------------------------------------------------------------------- /EasyBuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/EasyBuild -------------------------------------------------------------------------------- /MakeFile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/MakeFile -------------------------------------------------------------------------------- /Emulator.x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/Emulator.x -------------------------------------------------------------------------------- /RomMondo.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/RomMondo.bin -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | BuildResults/ 3 | *.NJ 4 | *.tool 5 | RomMondo.bin.x 6 | *.dmg 7 | -------------------------------------------------------------------------------- /Linker/LinkPowerROM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/Linker/LinkPowerROM -------------------------------------------------------------------------------- /NanoKernel/NKThud.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/NanoKernel/NKThud.s -------------------------------------------------------------------------------- /NanoKernel/InnerMakeFile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/NanoKernel/InnerMakeFile -------------------------------------------------------------------------------- /NanoKernel/NKScheduler.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/NanoKernel/NKScheduler.s -------------------------------------------------------------------------------- /NanoKernel/NKPoolAllocator.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/NanoKernel/NKPoolAllocator.s -------------------------------------------------------------------------------- /NanoKernel/NKReplacementInit.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elliotnunn/powermac-rom/HEAD/NanoKernel/NKReplacementInit.s -------------------------------------------------------------------------------- /SetFileTypes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd "`dirname "$0"`" && find . -type f -not -path '*/.*' -not -ipath './BuildResults/*' \( -not -name '*.*' -o -iname '*.s' -o -iname '*.a' -o -iname '*.c' -o -iname '*.h' \) -exec SetFile -t 'TEXT' -c 'MPS ' {} \; 4 | -------------------------------------------------------------------------------- /NanoKernel/MakeFile: -------------------------------------------------------------------------------- 1 | # Lets you just run Make in this directory, 2 | # while ignoring the rest of the build system 3 | 4 | NKDir = : 5 | NKIncDir = {NKDir}:Internal: 6 | NKBin = {NKDir}NanoKernel.s.x 7 | NKOpts = 8 | 9 | #include "{NKDir}InnerMakeFile" 10 | -------------------------------------------------------------------------------- /EasyBuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Uncomment this block to use https://github.com/elliotnunn/mac-rom 4 | 5 | # echo "> Diving into mac-rom repo" 6 | # cd ../mac-rom 7 | # ./EasyBuild.sh 8 | # cmp -s BuildResults/RISC/Image/RomMondo "$OLDPWD/RomMondo.bin" || cp BuildResults/RISC/Image/RomMondo "$OLDPWD/RomMondo.bin" 9 | # cd "$OLDPWD" 10 | # echo "< Done with mac-rom repo" 11 | 12 | 13 | # Avoid the uber-slow step of running the emulator when nothing has changed 14 | 15 | if [ ! -f BuildResults/PowerROM ] 16 | then 17 | echo "PowerROM not yet built" 18 | echo "> Starting emulator to build PowerROM" 19 | empw -b EasyBuild 20 | echo "< Emulator done" 21 | exit 22 | fi 23 | 24 | echo "Checking for files updated since PowerROM" 25 | find **/*.s *.s *.x *.bin -newer BuildResults/PowerROM | grep . || exit 0 26 | 27 | echo "> Starting emulator to build PowerROM" 28 | empw -b EasyBuild 29 | echo "< Emulator done" 30 | -------------------------------------------------------------------------------- /NanoKernel/NanoKernel.s: -------------------------------------------------------------------------------- 1 | include 'MacErrors.a' 2 | include 'Multiprocessing.a' 3 | 4 | include 'InfoRecords.a' 5 | include 'EmulatorPublic.a' 6 | include 'NKPublic.a' 7 | include 'NKOpaque.a' 8 | 9 | include 'NKEquates.s' 10 | include 'NKMacros.s' 11 | 12 | NKTop 13 | include 'NKInit.s' 14 | align 5 15 | include 'NKInterrupts.s' 16 | align 5 17 | include 'NKPaging.s' 18 | align 5 19 | include 'NKTranslation.s' 20 | align 5 21 | include 'NKVMCalls.s' 22 | align 5 23 | include 'NKPowerCalls.s' 24 | align 5 25 | include 'NKRTASCalls.s' 26 | align 5 27 | include 'NKCache.s' 28 | 29 | ; Mostly MP calls: 30 | align 5 31 | include 'NKMPCalls.s' 32 | align 5 33 | include 'NKSync.s' 34 | align 5 35 | include 'NKTasks.s' 36 | align 5 37 | include 'NKAddressSpaces.s' 38 | 39 | align 5 40 | include 'NKPoolAllocator.s' 41 | align 5 42 | include 'NKTimers.s' 43 | align 5 44 | include 'NKScheduler.s' 45 | align 5 46 | include 'NKIndex.s' 47 | align 5 48 | include 'NKPrimaryIntHandlers.s' 49 | align 5 50 | include 'NKConsoleLog.s' 51 | align 5 52 | include 'NKSleep.s' 53 | align 5 54 | include 'NKThud.s' 55 | align 5 56 | include 'NKScreenConsole.s' 57 | align 5 58 | include 'NKAdditions.s' 59 | align 5 60 | NKBtm 61 | -------------------------------------------------------------------------------- /NanoKernel/NKAdditions.s: -------------------------------------------------------------------------------- 1 | ;_______________________________________________________________________ 2 | ; My additions to the NanoKernel, to go at the end of the code image 3 | ;_______________________________________________________________________ 4 | 5 | if &TYPE('NKDebugShim') != 'UNDEFINED' 6 | 7 | DeclareMPCall 200, NKDebug 8 | 9 | NKDebug 10 | 11 | ; Lifted from NKxprintf: 12 | ; Put the physical address of the r3 arg in r8 13 | 14 | rlwinm. r9, r11, 0, MSR_DRbit, MSR_DRbit ; IntSyscall sets this 15 | mr r8, r3 16 | 17 | beq @already_physical 18 | li r9, 0 19 | bl SpaceL2PUsingBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17 20 | beq @fail 21 | rlwimi r8, r17, 0, 0, 19 22 | @already_physical 23 | 24 | 25 | ; Copy the command into the KDP buffer reserved for this purpose: 26 | ; r8 = src 27 | ; r29 = dest 28 | ; r30 = ctr 29 | ; r31 = val 30 | 31 | mfsprg r1, 0 32 | lwz r1, EWA.PA_KDP(r1) 33 | 34 | li r30, 0 35 | addi r29, r1, PSA.ThudBuffer 36 | @cmdloop 37 | lbzx r31, r8, r30 38 | stbx r31, r29, r30 39 | addi r30, r30, 1 40 | cmpwi r31, 0 41 | bne @cmdloop 42 | 43 | lwz r31, PSA._404(r1) 44 | 45 | stw r8, PSA._404(r1) 46 | 47 | bl panic 48 | 49 | lwz r8, PSA._404(r1) 50 | li r0, 0 51 | stw r0, 0(r8) 52 | 53 | stw r31, PSA._404(r1) 54 | 55 | b ReturnZeroFromMPCall 56 | 57 | 58 | @fail 59 | b ReturnMPCallOOM 60 | 61 | endif 62 | -------------------------------------------------------------------------------- /NanoKernel/NKEquates.s: -------------------------------------------------------------------------------- 1 | ;_______________________________________________________________________ 2 | ; Equates for the whole NanoKernel 3 | ;_______________________________________________________________________ 4 | 5 | 6 | kNanoKernelVersion equ $0228 7 | 8 | 9 | ; PowerPC Machine Status Register (MSR) bits 10 | ; (borrowing the _bitEqu macro from NKInfoRecordsPriv.s) 11 | 12 | _bitEqu MSR_POW, 13 13 | _bitEqu MSR_ILE, 15 14 | _bitEqu MSR_EE, 16 15 | _bitEqu MSR_PR, 17 16 | _bitEqu MSR_FP, 18 17 | _bitEqu MSR_ME, 19 18 | _bitEqu MSR_FE0, 20 19 | _bitEqu MSR_SE, 21 20 | _bitEqu MSR_BE, 22 21 | _bitEqu MSR_FE1, 23 22 | _bitEqu MSR_IP, 25 23 | _bitEqu MSR_IR, 26 24 | _bitEqu MSR_DR, 27 25 | _bitEqu MSR_RI, 30 26 | _bitEqu MSR_LE, 31 27 | 28 | 29 | ; Special Purpose Registers (SPRs) not understood by MPW 30 | 31 | l2cr equ 1017 32 | 33 | 34 | ; Alignment for NanoKernel interrupt routines (mostly Interrupts.s) 35 | 36 | kIntAlign equ 5 37 | 38 | 39 | 40 | ; Junk 41 | 42 | 43 | ; IRP is 10 pages below KDP (measured start to start) 44 | ; This should be neatened up to describe the kernel global area 45 | IRPOffset equ (-10) * 4096 46 | kKDPfromIRP equ 10 * 4096 47 | kPoolOffsetFromGlobals equ (-7) * 4096 ; goes all the way up to 24 bytes short of PSA 48 | 49 | 50 | 51 | ; Branch instruction BO fields 52 | ; (disregarding static prediction :) 53 | BO_IF equ 12 54 | BO_IF_NOT equ 4 55 | 56 | Z equ 0x80000000 57 | 58 | 59 | ; SIGP (SIGnal Plugin) selectors used by the kernel: 60 | kStartProcessor equ 1 ; r4 = target CPU idx, r5 = cpu's entry point, r6 = entry point's r3 (CPU struct ptr) 61 | kStopProcessor equ 3 ; r4 = target CPU idx 62 | kResetProcessor equ 4 ; r4 = target CPU idx 63 | kAlert equ 5 ; r4 = target CPU idx? ; my name, has something to do with timers 64 | kSIGP6 equ 6 ; r4 = target CPU idx? 65 | kSIGP7 equ 7 ; r4 = target CPU idx? 66 | kSynchClock equ 8 ; r4 = target CPU idx, 67 | kSIGP9 equ 9 ; no args? 68 | kGetProcessorTemp equ 12 ; r4 = selector (ignored on Core99), r5 = cpu ID ; my name 69 | kSIGP17 equ 17 ; r4 = target CPU idx? 70 | -------------------------------------------------------------------------------- /NanoKernel/NKProcInfoTbl.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; EXPORTS: 3 | ; OverrideProcessorInfo (=> NKBuiltinInit) 4 | ; ProcessorInfoTable (=> NKBuiltinInit) 5 | 6 | ; Contains the table used by InitBuiltin.s:OverrideProcessorInfo 7 | ; 8 | ; If the Trampoline fails to pass in a signed HardwareInfo struct, 9 | ; this is our first choice for populating ProcessorInfo. 10 | ; 11 | ; Also contains a 'function' that will do the populating 12 | ; (not very clever), and fall through to the end of the file, 13 | ; where we expect to find Init.s:FinishInitBuiltin. 14 | 15 | macro ; just to make the table below look nicer... 16 | PnfoTblEnt &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o 17 | dc.l &a * 1024, &b * 1024, &c * 1024 18 | dc.w &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o 19 | endm 20 | 21 | ProcessorInfoTable 22 | 23 | ; - PageSize, KB 24 | ; | - DataCacheTotalSize, KB 25 | ; | | - InstCacheTotalSize, KB 26 | ; | | | - CoherencyBlockSize 27 | ; | | | | - ReservationGranuleSize 28 | ; | | | | | - CombinedCaches 29 | ; | | | | | | - InstCacheLineSize 30 | ; | | | | | | | - DataCacheLineSize 31 | ; | | | | | | | | - DataCacheBlockSizeTouch 32 | ; | | | | | | | | | - InstCacheBlockSize 33 | ; | | | | | | | | | | - DataCacheBlockSize 34 | ; | | | | | | | | | | | - InstCacheAssociativity 35 | ; | | | | | | | | | | | | - DataCacheAssociativity 36 | ; | | | | | | | | | | | | | - TransCacheTotalSize 37 | ; | | | | | | | | | | | | | | - TransCacheAssociativity 38 | 39 | PnfoTblEnt 4, 32, 32, 32, 32, 1, 64, 64, 32, 32, 32, 8, 8, 256, 2 ; 0001 = 601 40 | PnfoTblEnt 4, 8, 8, 32, 32, 0, 32, 32, 32, 32, 32, 2, 2, 64, 2 ; 0003 = 603 41 | PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 128, 2 ; 0004 = 604 42 | PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 64, 2 ; 0006 = 603e 43 | PnfoTblEnt 4, 16, 16, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 64, 2 ; 0007 = 750FX 44 | PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 128, 2 ; 0008 = 750 45 | PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 4, 4, 128, 2 ; 0009/a = ??? 46 | PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 128, 2 ; 000c = 7400 47 | PnfoTblEnt 4, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 8, 8, 256, 4 ; 000d = ??? 48 | 49 | 50 | 51 | OverrideProcessorInfo 52 | 53 | @loop 54 | subic. r9, r9, 4 55 | lwzx r12, r11, r9 56 | stwx r12, r10, r9 57 | bgt @loop 58 | -------------------------------------------------------------------------------- /NanoKernel/NKProcFlagsTbl.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; EXPORTS: 3 | ; ProcessorFlagsTable (=> NKInit) 4 | 5 | ; Contains the table used by Init.s:SetProcessorFlags, and a label to find it with. 6 | ; 7 | ; Using this table, three fields in KDP are set: 8 | ; KDP.CpuSpecificByte1 9 | ; KDP.CpuSpecificByte2 (immediately follows Byte1) 10 | ; KDP.ProcessorInfo.ProcessorFlags 11 | 12 | ProcessorFlagsTable 13 | dcb.b 32 * (1 + 1 + 4), 0 14 | ProcessorFlagsTableEnd 15 | 16 | 17 | 18 | PflgTblCtr set 0 19 | 20 | macro 21 | PflgTblEnt &CpuSpecificByte1, &CpuSpecificByte2, &ProcessorFlags 22 | 23 | @fb 24 | org ProcessorFlagsTable + PflgTblCtr 25 | dc.b &CpuSpecificByte1 26 | org ProcessorFlagsTable + 32 + PflgTblCtr 27 | dc.b &CpuSpecificByte2 28 | org ProcessorFlagsTable + 64 + 4*PflgTblCtr 29 | dc.l &ProcessorFlags 30 | org @fb 31 | PflgTblCtr set PflgTblCtr + 1 32 | 33 | endm 34 | 35 | 36 | 37 | with NKProcessorInfo 38 | 39 | ; CpuSpecificByte2: 40 | HID0_NHR_only equ 1 ; Idle Power calls should set the HID0[NHR] bit 41 | HID0_NHR_and_sleep equ 2 ; ...and the HID0 bit that potentiates MSR[POW] 42 | HID0_neither equ 0 43 | 44 | ; See NKPowerCalls for info on CpuSpecificByte1. Its upper nybble specifies how to idle the CPU. 45 | 46 | ; CpuSpecificByte 47 | ; 1 2 ProcessorFlags CPU 48 | ; - - -------------- --- 49 | PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**0 50 | PflgTblEnt 0x00, HID0_neither, 0 ; 0**1 = 601 51 | PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**2 52 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**3 = 603 53 | PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**4 = 604 54 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**5 55 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**6 = 603e 56 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 0 ; 0**7 = 750FX 57 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU ; 0**8 = 750 58 | PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**9 59 | PflgTblEnt 0x0a, HID0_NHR_only, 0 ; 0**a 60 | PflgTblEnt 0x03, HID0_NHR_only, 0 ; 0**b 61 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 0**c = 7400 62 | PflgTblEnt 0x0b, HID0_NHR_and_sleep, 0 ; 0**d 63 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**e 64 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 0**f 65 | 66 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**0 = 7450 (see note below) 67 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**1 = 7445/55 68 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**2 = 7447 (OS X only) 69 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**3 70 | PflgTblEnt 0x03, HID0_NHR_only, 0 ; 8**4 71 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**5 72 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**6 73 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**7 74 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**8 75 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**9 76 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**a 77 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**b 78 | PflgTblEnt 0x1b, HID0_NHR_and_sleep, 1<< hasL2CR | 1<< hasPLRUL1 | 1<< hasTAU | 1<< hasVMX | 1<< hasMSSregs ; 8**c = 7410 79 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**d 80 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**e 81 | PflgTblEnt 0x03, HID0_NHR_and_sleep, 0 ; 8**f 82 | 83 | ; NB: PPC 7450 ("G4e") and its descendants (744x/745x) lack the HID0[DOZE] bit (they have HID0[HIGH_BAT_EN] instead). 84 | ; Therefore the upper nybble of CpuSpecificByte1 should be 0, or 2 for NAP (works), or 3 for SLEEP (freezes). 85 | 86 | endwith 87 | -------------------------------------------------------------------------------- /NanoKernel/NKRTASCalls.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKInterrupts 4 | ; IntHandleSpecialFPException 5 | ; IntReturn 6 | ; bugger_around_with_floats 7 | ; NKPaging 8 | ; PagingL2PWithBATs 9 | ; NKThud 10 | ; panic 11 | ; EXPORTS: 12 | ; kcRTASDispatch (=> NKInit) 13 | 14 | 15 | Local_Panic set * 16 | b panic 17 | 18 | 19 | 20 | ; kcRTASDispatch 21 | 22 | ; Only major that hits the RTAS globals. 23 | ; RTAS requires some specific context stuff. 24 | 25 | ; > r1 = kdp 26 | ; > r6 = some kind of place 27 | ; > r7 = some kind of flags 28 | 29 | align 5 30 | 31 | kcRTASDispatch ; OUTSIDE REFERER 32 | lwz r8, 0x0908(r1) 33 | cmpwi r8, 0x00 34 | bne rtas_is_available 35 | li r3, -0x01 36 | b IntReturn 37 | 38 | rtas_is_available 39 | 40 | _Lock PSA.RTASLock, scratch1=r8, scratch2=r9 41 | 42 | mtcrf 0x3f, r7 43 | lwz r9, KDP.PA_ECB(r1) 44 | lwz r8, EWA.Enables(r1) 45 | stw r7, 0x0000(r6) 46 | stw r8, 0x0004(r6) 47 | bns cr6, kcRTASDispatch_0x5c 48 | stw r17, 0x0024(r6) 49 | stw r20, 0x0028(r6) 50 | stw r21, 0x002c(r6) 51 | stw r19, 0x0034(r6) 52 | stw r18, 0x003c(r6) 53 | lmw r14, 0x0038(r1) 54 | 55 | kcRTASDispatch_0x5c 56 | mfxer r8 57 | stw r13, 0x00dc(r6) 58 | stw r8, 0x00d4(r6) 59 | stw r12, 0x00ec(r6) 60 | mfctr r8 61 | stw r10, 0x00fc(r6) 62 | stw r8, 0x00f4(r6) 63 | ble cr3, kcRTASDispatch_0x8c 64 | lwz r8, 0x00c4(r9) 65 | mfspr r12, mq 66 | mtspr mq, r8 67 | stw r12, 0x00c4(r6) 68 | 69 | kcRTASDispatch_0x8c 70 | lwz r8, 0x0004(r1) 71 | stw r8, 0x010c(r6) 72 | stw r2, 0x0114(r6) 73 | stw r3, 0x011c(r6) 74 | stw r4, 0x0124(r6) 75 | lwz r8, 0x0018(r1) 76 | stw r5, 0x012c(r6) 77 | stw r8, 0x0134(r6) 78 | andi. r8, r11, 0x2000 79 | stw r14, 0x0174(r6) 80 | stw r15, 0x017c(r6) 81 | stw r16, 0x0184(r6) 82 | stw r17, 0x018c(r6) 83 | stw r18, 0x0194(r6) 84 | stw r19, 0x019c(r6) 85 | stw r20, 0x01a4(r6) 86 | stw r21, 0x01ac(r6) 87 | stw r22, 0x01b4(r6) 88 | stw r23, 0x01bc(r6) 89 | stw r24, 0x01c4(r6) 90 | stw r25, 0x01cc(r6) 91 | stw r26, 0x01d4(r6) 92 | stw r27, 0x01dc(r6) 93 | stw r28, 0x01e4(r6) 94 | stw r29, 0x01ec(r6) 95 | stw r30, 0x01f4(r6) 96 | stw r31, 0x01fc(r6) 97 | bnel bugger_around_with_floats 98 | stw r11, 0x00a4(r6) 99 | mr r27, r3 100 | addi r29, r1, KDP.BATs + 0xa0 101 | bl PagingL2PWithBATs 102 | beql Local_Panic 103 | rlwimi r3, r31, 0, 0, 19 104 | lhz r8, 0x0004(r3) 105 | cmpwi r8, 0x00 106 | beq kcRTASDispatch_0x14c 107 | slwi r8, r8, 2 108 | lwzx r27, r8, r3 109 | addi r29, r1, KDP.BATs + 0xa0 110 | bl PagingL2PWithBATs 111 | beql Local_Panic 112 | lwzx r9, r8, r3 113 | rlwimi r9, r31, 0, 0, 19 114 | stwx r9, r8, r3 115 | li r9, 0x00 116 | sth r9, 0x0004(r3) 117 | dcbf r8, r3 118 | 119 | kcRTASDispatch_0x14c 120 | li r9, 0x04 121 | dcbf r9, r3 122 | sync 123 | isync 124 | lwz r4, 0x090c(r1) 125 | mfmsr r8 126 | andi. r8, r8, 0x10cf 127 | mtmsr r8 128 | isync 129 | mr r28, r3 130 | lwz r9, 0x0908(r1) 131 | bl rtas_make_actual_call 132 | mfsprg r1, 0 133 | lwz r6, -0x0014(r1) 134 | clrlwi r29, r28, 0x14 135 | subfic r29, r29, 0x1000 136 | lhz r27, 0x0f4a(r1) 137 | 138 | kcRTASDispatch_0x190 139 | subf. r29, r27, r29 140 | dcbf r29, r28 141 | sync 142 | icbi r29, r28 143 | bge kcRTASDispatch_0x190 144 | sync 145 | isync 146 | lwz r8, 0x0000(r6) 147 | lwz r11, 0x00a4(r6) 148 | mr r7, r8 149 | andi. r8, r11, 0x900 150 | lwz r8, 0x0004(r6) 151 | lwz r13, 0x00dc(r6) 152 | stw r8, EWA.Enables(r1) 153 | lwz r8, 0x00d4(r6) 154 | lwz r12, 0x00ec(r6) 155 | mtxer r8 156 | lwz r8, 0x00f4(r6) 157 | lwz r10, 0x00fc(r6) 158 | mtctr r8 159 | bnel IntHandleSpecialFPException 160 | lwz r8, 0x010c(r6) 161 | stw r8, 0x0004(r1) 162 | lwz r2, 0x0114(r6) 163 | lwz r3, 0x011c(r6) 164 | lwz r4, 0x0124(r6) 165 | lwz r8, 0x0134(r6) 166 | lwz r5, 0x012c(r6) 167 | stw r8, 0x0018(r1) 168 | lwz r14, 0x0174(r6) 169 | lwz r15, 0x017c(r6) 170 | lwz r16, 0x0184(r6) 171 | lwz r17, 0x018c(r6) 172 | lwz r18, 0x0194(r6) 173 | lwz r19, 0x019c(r6) 174 | lwz r20, 0x01a4(r6) 175 | lwz r21, 0x01ac(r6) 176 | lwz r22, 0x01b4(r6) 177 | lwz r23, 0x01bc(r6) 178 | lwz r24, 0x01c4(r6) 179 | lwz r25, 0x01cc(r6) 180 | lwz r26, 0x01d4(r6) 181 | lwz r27, 0x01dc(r6) 182 | lwz r28, 0x01e4(r6) 183 | lwz r29, 0x01ec(r6) 184 | lwz r30, 0x01f4(r6) 185 | lwz r31, 0x01fc(r6) 186 | _AssertAndRelease PSA.RTASLock, scratch=r8 187 | li r3, 0x00 188 | b IntReturn 189 | 190 | rtas_make_actual_call 191 | mtctr r9 192 | bctr 193 | -------------------------------------------------------------------------------- /AsmSymScanner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import re 5 | import os.path 6 | 7 | HEADER = 'AUTO-GENERATED SYMBOL LIST' 8 | ENC = 'macroman' 9 | RECORD = re.compile(r'^[^;\s]*\s+record', re.I) 10 | ENDR = re.compile(r'^\s+endr', re.I) 11 | 12 | SETEQU = re.compile(r'^\S+\s+(dc\.|ds\.|set|equ|record)', flags=re.I) 13 | 14 | def neaten_name(x): 15 | bn = os.path.basename(x) 16 | bn = os.path.splitext(bn)[0] 17 | return bn 18 | 19 | all_args = list(sys.argv[1:]) 20 | opts = [] 21 | 22 | while all_args and all_args[0].startswith('-'): 23 | opts.append(all_args.pop(0)) 24 | 25 | fnames = all_args 26 | 27 | fnames = [fn for fn in fnames if HEADER in open(fn, encoding=ENC).read(2048)] 28 | 29 | fexports = [] 30 | for name in fnames: 31 | exports = set() 32 | can_keep = False 33 | 34 | with open(name, encoding=ENC) as f: 35 | forbid = False 36 | for l in f: 37 | if not forbid and RECORD.match(l): 38 | forbid=True 39 | elif forbid and ENDR.match(l): 40 | forbid=False 41 | 42 | if not forbid: 43 | m = re.match(r'^(\w+)', l) 44 | if m and not SETEQU.match(l): 45 | exports.add(m.group(1)) 46 | 47 | fexports.append(exports) 48 | 49 | regex_cache = {} 50 | for export_set in fexports: 51 | for export in export_set: 52 | if export not in regex_cache: 53 | regex_cache[export] = re.compile(r'^[^;]+\b' + re.escape(export) + r'\b', flags=re.I) 54 | 55 | export_matrix = set() 56 | for expname, exports in zip(fnames, fexports): 57 | for impname in fnames: 58 | if impname == expname: continue 59 | 60 | with open(impname, encoding=ENC) as f: 61 | for l in f: 62 | for e in exports: 63 | er = regex_cache[e] 64 | if er.match(l): 65 | export_matrix.add((expname, impname, e)) 66 | 67 | for exp, imp, sym in sorted(export_matrix): 68 | print(exp.rpartition('/')[2], imp.rpartition('/')[2], sym) 69 | 70 | dict_exporter = {} 71 | for exp, imp, sym in export_matrix: 72 | dict_exporter[sym] = exp 73 | 74 | dict_importers = {} 75 | for exp, imp, sym in export_matrix: 76 | if sym not in dict_importers: 77 | dict_importers[sym] = set() 78 | dict_importers[sym].add(imp) 79 | 80 | dict_fileimports = {} 81 | for exp, imp, sym in export_matrix: 82 | if imp not in dict_fileimports: 83 | dict_fileimports[imp] = set() 84 | dict_fileimports[imp].add(sym) 85 | 86 | dict_fileexports = {} 87 | for exp, imp, sym in export_matrix: 88 | if exp not in dict_fileexports: 89 | dict_fileexports[exp] = set() 90 | dict_fileexports[exp].add(sym) 91 | 92 | for f in fnames: 93 | if f not in dict_fileimports: 94 | dict_fileimports[f] = set() 95 | if f not in dict_fileexports: 96 | dict_fileexports[f] = set() 97 | 98 | for path in fnames: 99 | with open(path, encoding=ENC) as i: 100 | with open(path + '~', 'w', encoding=ENC) as o: 101 | for l in i: 102 | o.write(l) 103 | if HEADER in l: 104 | prefix, _, suffix = l.partition(HEADER) 105 | imports = sorted(dict_fileimports[path]) 106 | exports = sorted(dict_fileexports[path]) 107 | 108 | if imports: 109 | dict_exp_to_imp = {} 110 | for imp in imports: 111 | exporter = dict_exporter[imp] 112 | if exporter not in dict_exp_to_imp: 113 | dict_exp_to_imp[exporter] = set() 114 | dict_exp_to_imp[exporter].add(imp) 115 | 116 | o.write(prefix + 'IMPORTS:' + suffix) 117 | 118 | for exp, imps in sorted(dict_exp_to_imp.items()): 119 | o.write(prefix + ' ' + neaten_name(exp) + suffix) 120 | for imp in sorted(imps): 121 | o.write(prefix + ' ' + imp + suffix) 122 | 123 | if exports: 124 | o.write(prefix + 'EXPORTS:' + suffix) 125 | for exp in exports: 126 | importers = sorted(dict_importers[exp]) 127 | importers = [neaten_name(x) for x in importers] 128 | impstring = ' (=> %s)' % (', '.join(importers)) 129 | o.write(prefix + ' ' + exp + impstring + suffix) 130 | 131 | for l in i: 132 | if not l.startswith(prefix): 133 | o.write(l) 134 | break 135 | 136 | open(path, 'wb').write(open(path + '~', 'rb').read().replace(b'\n', b'\r')) 137 | os.unlink(path + '~') 138 | -------------------------------------------------------------------------------- /Linker/LinkPowerROM.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef macintosh 6 | typedef unsigned long uint32_t; 7 | typedef long int32_t; 8 | typedef unsigned short uint16_t; 9 | typedef short int16_t; 10 | typedef unsigned char uint8_t; 11 | typedef char int8_t; 12 | #endif 13 | 14 | uint32_t narrow[8]; 15 | uint32_t wide[2]; 16 | 17 | int slurp(char *path, uint8_t **datap, unsigned long *sizep) 18 | { 19 | FILE *f; 20 | long pos; 21 | uint8_t *bytes; 22 | 23 | f = fopen(path, "rb"); 24 | if(f == NULL) return 1; 25 | 26 | fseek(f, 0, SEEK_END); 27 | pos = ftell(f); 28 | fseek(f, 0, SEEK_SET); 29 | 30 | bytes = (uint8_t *)malloc(pos); 31 | if(bytes == NULL) return 1; 32 | 33 | fread(bytes, pos, 1, f); 34 | 35 | fclose(f); 36 | 37 | *datap = bytes; 38 | *sizep = pos; 39 | 40 | return 0; /* no error */ 41 | } 42 | 43 | const uint16_t pretend_header[] = { 44 | 0x01df /*f_magic*/, 45 | 1 /*f_nscns*/, 46 | 0xd611, 0x2977 /*f_timdat*/, 47 | 0, 0 /*f_symptr*/, 48 | 0, 2 /*f_nsyms*/, 49 | 0 /*f_opthdr*/, 50 | 0 /*f_flags*/, 51 | 52 | /* now for single .text symbol header */ 53 | 0x2e74, 0x6578, 0x7400, 0x0000 /*s_name = .text*/, 54 | 0, 0 /*s_paddr*/, 55 | 0, 0 /*s_vaddr*/, 56 | 1234, 5678 /*s_size*/, 57 | 0, 0x3c /*s_scnptr = len of this header*/, 58 | 0, 0 /*s_relptr*/, 59 | 0, 0 /*s_lnnoptr*/, 60 | 0 /*s_nreloc*/, 61 | 0 /*s_nlnno*/, 62 | 0, 0x20 /*s_flags = text*/ 63 | }; 64 | 65 | const uint16_t pretend_footer[] = { 66 | 0, 0, 67 | 0, 0, 68 | 0, 0, 69 | 1, 0, 70 | 0x6b01, 71 | 1234, 5678, 72 | 0, 0, 0, 73 | 0x1100, 0, 0, 0 74 | }; 75 | 76 | 77 | int main(int argc, char **argv) 78 | { 79 | FILE *fp; 80 | uint8_t *buf, *sec, *dest; 81 | unsigned long buflen, seclen, destlen; 82 | unsigned long i; 83 | 84 | if(argc < 2) 85 | { 86 | fprintf(stderr, "%s: No command specified -- use tox, fromx or cksum\n", argv[0]); 87 | return 1; 88 | } 89 | 90 | if(!strcmp(argv[1], "cksum")) 91 | { 92 | unsigned long offset; 93 | 94 | if(argc < 3) 95 | { 96 | fprintf(stderr, "%s: %s: Specify a file!\n", argv[0], argv[1]); 97 | return 1; 98 | } 99 | 100 | if(argc < 4) 101 | { 102 | return 0; /* No offset specified -- fail silently */ 103 | } 104 | 105 | if(slurp(argv[2], &buf, &buflen)) 106 | { 107 | fprintf(stderr, "%s: %s: Could not open input\n", argv[0], argv[1]); 108 | return 1; 109 | } 110 | 111 | offset = strtoul(argv[3], NULL, 0); 112 | 113 | if(offset > buflen - 40) { 114 | fprintf(stderr, "%s: Bad offset for ConfigInfo checksum: 0x%x\n", argv[0], offset); 115 | return 1; 116 | } 117 | 118 | memset(buf + offset, 0, 40); 119 | 120 | for(i=0; if_opthdr); 173 | 174 | sec = buf + shp->s_scnptr; 175 | seclen = shp->s_size; 176 | } 177 | 178 | /* now to create my template XCOFF */ 179 | 180 | if(!strcmp(argv[1], "tox")) 181 | { 182 | destlen = sizeof pretend_header + seclen + sizeof pretend_footer; 183 | dest = (uint8_t *)malloc(destlen); 184 | if(dest == NULL) 185 | { 186 | fprintf(stderr, "%s: OOM\n", argv[0]); 187 | return 1; 188 | } 189 | 190 | memcpy(dest, (const char *)pretend_header, sizeof pretend_header); 191 | memcpy(dest + sizeof pretend_header, sec, seclen); 192 | memcpy(dest + sizeof pretend_header + seclen, (const char *)pretend_footer, sizeof pretend_footer); 193 | 194 | *(uint32_t *)(dest + 36) = seclen; 195 | *(uint32_t *)(dest + 8) = sizeof pretend_header + seclen; 196 | *(uint32_t *)(dest + sizeof pretend_header + seclen + 18) = seclen; 197 | } 198 | else if(!strcmp(argv[1], "fromx")) 199 | { 200 | dest = sec; 201 | destlen = seclen; 202 | } 203 | 204 | fp = fopen(argv[3], "wb"); 205 | if(!fp) { 206 | fprintf(stderr, "%s: Could not open output\n", argv[0]); 207 | return 1; 208 | } 209 | 210 | fwrite(dest, 1, destlen, fp); 211 | 212 | fclose(fp); 213 | } 214 | 215 | return 0; 216 | } 217 | -------------------------------------------------------------------------------- /Internal/EmulatorPublic.a: -------------------------------------------------------------------------------- 1 | EDP record 0,INCR 2 | 3 | D0 ds.l 1 ; 000 ; r8 4 | D1 ds.l 1 ; 004 ; r9 5 | D2 ds.l 1 ; 008 ; r10 6 | D3 ds.l 1 ; 00c ; r11 7 | D4 ds.l 1 ; 010 ; r12 8 | D5 ds.l 1 ; 014 ; r13 9 | D6 ds.l 1 ; 018 ; r14 10 | D7 ds.l 1 ; 01c ; r15 11 | 12 | A0 ds.l 1 ; 020 ; r16 13 | A1 ds.l 1 ; 024 ; r17 14 | A2 ds.l 1 ; 028 ; r18 15 | A3 ds.l 1 ; 02c ; r19 16 | A4 ds.l 1 ; 030 ; r20 17 | A5 ds.l 1 ; 034 ; r30 18 | A6 ds.l 1 ; 038 ; r31 19 | A7 ds.l 1 ; 03c ; r1 (PowerPC SP) 20 | 21 | SR ds.l 1 ; 040 22 | PC ds.l 1 ; 044 23 | USP ds.l 1 ; 048 24 | ISP ds.l 1 ; 04c 25 | MSP ds.l 1 ; 050 26 | VBR ds.l 1 ; 054 27 | SFC ds.l 1 ; 058 28 | DFC ds.l 1 ; 05c 29 | ds.l 1 ; 060 ; these four are 'cac-ar,instr,trc_pc' 30 | ds.l 1 ; 064 31 | ds.l 1 ; 068 32 | ds.l 1 ; 06c 33 | INTM_L ds.l 1 ; 070 ; interrupt level or -1 (halfword) 34 | DISP ds.l 1 ; 074 35 | CODE ds.l 1 ; 078 36 | SP ds.l 1 ; 07c 37 | ds.l 1 ; 080 ; these four are 'ctxflg,info-adr,uea' 38 | ds.l 1 ; 084 39 | ds.l 1 ; 088 40 | ds.l 1 ; 08c 41 | ds.l 1 ; 090 ; these four are 'data_h-l,data,imm_d' 42 | ds.l 1 ; 094 43 | ds.l 1 ; 098 44 | ds.l 1 ; 09c 45 | B_DSP ds.l 1 ; 0a0 46 | SR_FLG ds.l 1 ; 0a4 47 | CTR ds.l 1 ; 0a8 48 | LR ds.l 1 ; 0ac 49 | NIA ds.l 1 ; 0b0 50 | XER ds.l 1 ; 0b4 51 | CRL_VFL ds.l 1 ; 0b8 52 | SSW ds.l 1 ; 0bc 53 | 54 | org 0x100 55 | ContextBlock ds.b 768 ; 100:300 ; Emulator Context Block, ECB; NKv2 ties this to blue task 56 | 57 | EmuControlRegisters org 0x740 58 | Reg0 ds.l 1 ; 740 59 | Reg1 ds.l 1 ; 744 60 | Reg2 ds.l 1 ; 748 61 | Reg3 ds.l 1 ; 74c 62 | 63 | Reg8 ds.l 1 ; 750 64 | Reg9 ds.l 1 ; 754 65 | Reg10 ds.l 1 ; 758 66 | Reg11 ds.l 1 ; 75c 67 | 68 | Reg4 ds.l 1 ; 760 69 | Reg5 ds.l 1 ; 764 70 | Reg6 ds.l 1 ; 768 71 | Reg7 ds.l 1 ; 76c 72 | 73 | Reg12 ds.l 1 ; 770 74 | Reg13 ds.l 1 ; 774 75 | Reg14 ds.l 1 ; 778 76 | 77 | org 0xf00 78 | BootstrapVersion ds.b 16 ; f00:f10 ; Bootstrap loader version info, from ConfigInfo 79 | 80 | endr 81 | 82 | 83 | 84 | 85 | 86 | ; Lives in EDP. Keeping a separate record to EDP makes the code nicer. 87 | ; Gets called the "system context" 88 | ContextBlock record 0,INCR 89 | 90 | Flags ds.l 1 ; 000 ; (SPAC) copied from kdp by CreateTask 91 | Enables ds.l 1 ; 004 92 | 93 | org 0x40 94 | SavedFlags ds.l 1 ; 040 ; from before exception 95 | 96 | org 0x44 97 | SavedEnables ds.l 1 ; 044 ; from before exception 98 | 99 | org 0x4c 100 | ExceptionHandler ds.l 1 ; 04c 101 | 102 | org 0x5c 103 | LA_EmulatorKernelTrapTable ds.l 1 104 | 105 | org 0x74 106 | SRR0 ds.l 1 ; 074 107 | 108 | org 0x84 109 | LA_EmulatorEntry ds.l 1 ; 084 ; Entry pt of emulator; set by NK Init.s 110 | 111 | org 0x94 112 | LA_EmulatorData ds.l 1 113 | 114 | org 0x9c 115 | LA_DispatchTable ds.l 1 116 | 117 | org 0xa4 118 | MSR ds.l 1 ; 0a4 ; (SPAC) copied from kdp by CreateTask 119 | 120 | org 0xc4 121 | MQ ds.l 1 ; 0c4 ; 601 only 122 | EDPOffsetSWIRelated ds.l 1 ; 0c8 123 | PriorityShifty ds.l 1 ; 0cc ; if low nybble is empty, SchInit sets this to 2 124 | SWIEventGroupID ds.l 1 ; 0d0 ; what? 125 | XER ds.l 1 ; 0d4 126 | VectorSaveArea ds.l 1 ; 0d8 ; AltiVec hack: vector registers don't fit in CB! 127 | CR ds.l 1 ; 0dc ; from heartbeat code, unsure of meaning (ANDed with PostIntMaskInit) r13 128 | PageInSystemHeap ds.l 1 ; 0e0 ; these are set by StartInit.a:FiddleWithEmulator 129 | OtherPageInSystemHeap ds.l 1 ; 0e4 130 | FE000000 ds.l 1 ; 0e8 ; also LR? 131 | LR ds.l 1 ; 0ec 132 | CTR ds.l 1 ; 0f0 133 | KernelCTR ds.l 1 ; 0f4 134 | 135 | org 0xfc 136 | CodePtr ds.l 1 ; 0fc ; probably goes in SRR0? 137 | 138 | org 0x100 139 | ds.l 1 140 | r0 ds.l 1 ; 104 141 | ds.l 1 142 | r1 ds.l 1 ; 10c 143 | ds.l 1 144 | r2 ds.l 1 ; 114 145 | ds.l 1 146 | r3 ds.l 1 ; 11c 147 | ds.l 1 148 | r4 ds.l 1 ; 124 149 | ds.l 1 150 | r5 ds.l 1 ; 12c 151 | ds.l 1 152 | r6 ds.l 1 ; 134 153 | ds.l 1 154 | r7 ds.l 1 ; 13c 155 | ds.l 1 156 | r8 ds.l 1 ; 144 157 | ds.l 1 158 | r9 ds.l 1 ; 14c 159 | ds.l 1 160 | r10 ds.l 1 ; 154 161 | ds.l 1 162 | r11 ds.l 1 ; 15c 163 | ds.l 1 164 | r12 ds.l 1 ; 164 165 | ds.l 1 166 | r13 ds.l 1 ; 16c 167 | ds.l 1 168 | r14 ds.l 1 ; 174 169 | ds.l 1 170 | r15 ds.l 1 ; 17c 171 | ds.l 1 172 | r16 ds.l 1 ; 184 173 | ds.l 1 174 | r17 ds.l 1 ; 18c 175 | ds.l 1 176 | r18 ds.l 1 ; 194 177 | ds.l 1 178 | r19 ds.l 1 ; 19c 179 | ds.l 1 180 | r20 ds.l 1 ; 1a4 181 | ds.l 1 182 | r21 ds.l 1 ; 1ac 183 | ds.l 1 184 | r22 ds.l 1 ; 1b4 185 | ds.l 1 186 | r23 ds.l 1 ; 1bc 187 | ds.l 1 188 | r24 ds.l 1 ; 1c4 189 | ds.l 1 190 | r25 ds.l 1 ; 1cc 191 | ds.l 1 192 | r26 ds.l 1 ; 1d4 193 | ds.l 1 194 | r27 ds.l 1 ; 1dc 195 | ds.l 1 196 | r28 ds.l 1 ; 1e4 197 | ds.l 1 198 | r29 ds.l 1 ; 1ec 199 | ds.l 1 200 | r30 ds.l 1 ; 1f4 201 | ds.l 1 202 | r31 ds.l 1 ; 1fc 203 | 204 | FloatRegisters ds.d 32 ; 200:300 205 | 206 | endr 207 | -------------------------------------------------------------------------------- /NanoKernel/NKMacros.s: -------------------------------------------------------------------------------- 1 | MACRO 2 | _log &s 3 | BL @paststring 4 | STRING AsIs 5 | DC.B &s, 0, 0 6 | ALIGN 2 7 | @paststring 8 | mflr r8 9 | BL PrintS 10 | ENDM 11 | 12 | ; Cool macro for one-line debug calls 13 | MACRO 14 | _wlog &s1, ®, &s2, &scratch==r8 15 | 16 | if &TYPE('ExtraNKLogging') != 'UNDEFINED' 17 | mr &scratch, r8 18 | 19 | _log &s1 20 | _log '[ ' 21 | 22 | mr r8, ® 23 | bl PrintW 24 | 25 | _log ']' 26 | _log &s2 27 | 28 | mr r8, &scratch 29 | endif 30 | 31 | ENDM 32 | 33 | MACRO 34 | _wlogh &s1, ®, &s2, &scratch==r8 35 | 36 | if &TYPE('ExtraNKLogging') != 'UNDEFINED' 37 | mr &scratch, r8 38 | 39 | _log &s1 40 | _log '[ ' 41 | 42 | mr r8, ® 43 | bl PrintH 44 | 45 | _log ']' 46 | _log &s2 47 | 48 | mr r8, &scratch 49 | endif 50 | 51 | ENDM 52 | 53 | MACRO 54 | _clog &s 55 | 56 | if &TYPE('ExtraNKLogging') != 'UNDEFINED' 57 | _log &s 58 | endif 59 | 60 | ENDM 61 | 62 | 63 | MACRO 64 | LHHI ®, &val 65 | lis (®), ((&val) >> 16) & 0xffff 66 | ENDM 67 | 68 | 69 | MACRO 70 | LLHI ®, &val 71 | ori (®), (®), (&val) & 0xffff 72 | ENDM 73 | 74 | 75 | MACRO 76 | lisori ®, &val 77 | lis ®, ((&val) >> 16) & 0xffff 78 | ori ®, ®, (&val) & 0xffff 79 | ENDM 80 | 81 | MACRO 82 | llabel ®, &val 83 | lisori ®, &val - NKTop 84 | ENDM 85 | 86 | 87 | 88 | MACRO 89 | _lstart ®, &val 90 | LHHI (®), (&val) 91 | HalfLoadedWord set (&val) 92 | HalfLoadedReg set (®) 93 | ENDM 94 | 95 | 96 | MACRO 97 | _lfinish 98 | LLHI HalfLoadedReg, HalfLoadedWord 99 | ENDM 100 | 101 | 102 | MACRO 103 | InitList &ptr, &sig, &scratch==r8 104 | _lstart &scratch, &sig 105 | stw &ptr, LLL.Next(&ptr) 106 | _lfinish 107 | stw &ptr, LLL.Prev(&ptr) 108 | stw &scratch, LLL.Signature(&ptr) 109 | ENDM 110 | 111 | 112 | ; Next is 8, Prev is C 113 | 114 | MACRO 115 | InsertAsPrev &el, &next, &scratch==r18 116 | 117 | stw &next, LLL.Next(&el) 118 | lwz &scratch, LLL.Prev(&next) 119 | stw &scratch, LLL.Prev(&el) 120 | stw &el, LLL.Next(&scratch) 121 | stw &el, LLL.Prev(&next) 122 | 123 | ENDM 124 | 125 | 126 | MACRO 127 | InsertAsNext &el, &prev, &scratch==r18 128 | 129 | stw &prev, LLL.Prev(&el) 130 | lwz &scratch, LLL.Next(&prev) 131 | stw &scratch, LLL.Next(&el) 132 | stw &el, LLL.Prev(&scratch) 133 | stw &el, LLL.Next(&prev) 134 | 135 | ENDM 136 | 137 | 138 | MACRO 139 | RemoveFromList &el, &scratch1==r17, &scratch2==r18 140 | 141 | ; Point neighbours of el up and down at each other 142 | lwz &scratch1, 8(&el) 143 | lwz &scratch2, 12(&el) 144 | stw &scratch1, 8(&scratch2) 145 | stw &scratch2, 12(&scratch1) 146 | 147 | ; Zero out the pointers in el 148 | li &scratch1, 0 149 | stw &scratch1, 8(&el) 150 | stw &scratch1, 12(&el) 151 | 152 | ENDM 153 | 154 | 155 | MACRO 156 | _Lock &lockoffset, &scratch1==r17, &scratch2==r18 157 | mr &scratch1, r8 158 | mr &scratch2, r9 159 | addi r8, r1, &lockoffset 160 | bl AcquireLock 161 | mr r8, &scratch1 162 | mr r9, &scratch2 163 | ENDM 164 | 165 | MACRO 166 | _AssertAndRelease &lockoffset, &scratch==r18 167 | sync 168 | lwz &scratch, &lockoffset(r1) 169 | cmpwi cr1, &scratch, 0 170 | li &scratch, 0 171 | bne+ cr1, @okay 172 | mflr &scratch 173 | bl panic 174 | 175 | @okay stw &scratch, &lockoffset(r1) 176 | ENDM 177 | 178 | MACRO 179 | _bset &dest, &src, &bit 180 | 181 | IF &bit < 16 182 | oris&dot &dest, &src, 1 << (15 - (&bit)) 183 | ELSE 184 | ori&dot &dest, &src, 1 << (31 - (&bit)) 185 | ENDIF 186 | 187 | ENDM 188 | 189 | MACRO 190 | _bclr &dest, &src, &bit 191 | 192 | _bclr_rbit set &bit+1 193 | if _bclr_rbit > 31 194 | _bclr_rbit set 0 195 | endif 196 | 197 | _bclr_lbit set &bit-1 198 | if _bclr_lbit < 0 199 | _bclr_lbit set 31 200 | endif 201 | 202 | rlwinm&dot &dest, &src, 0, _bclr_rbit, _bclr_lbit 203 | 204 | ENDM 205 | 206 | MACRO 207 | _band &dest, &src, &bit 208 | 209 | IF &bit < 16 210 | andis&dot &dest, &src, 1 << (15 - (&bit)) 211 | ELSE 212 | andi&dot &dest, &src, 1 << (31 - (&bit)) 213 | ENDIF 214 | 215 | ENDM 216 | 217 | 218 | MACRO 219 | _b_if_time_gt &lhi, &rhi, &targ 220 | 221 | cmpw &lhi, &rhi 222 | cmplw cr1, &lhi + 1, &rhi + 1 223 | bgt &targ 224 | blt @fallthru 225 | bgt cr1, &targ 226 | @fallthru 227 | 228 | ENDM 229 | 230 | 231 | MACRO 232 | _b_if_time_le &lhi, &rhi, &targ 233 | 234 | cmpw &lhi, &rhi 235 | cmplw cr1, &lhi + 1, &rhi + 1 236 | blt &targ 237 | bgt @fallthru 238 | ble cr1, &targ 239 | @fallthru 240 | 241 | ENDM 242 | 243 | 244 | MACRO 245 | _RegRangeToContextBlock &first, &last 246 | 247 | stw &first, $104+8*(&first)(r6) 248 | 249 | IF &first != &last 250 | _RegRangeToContextBlock &first+1, &last 251 | ENDIF 252 | 253 | ENDM 254 | 255 | 256 | MACRO 257 | _RegRangeFromContextBlock &first, &last 258 | 259 | lwz &first, $104+8*(&first)(r6) 260 | 261 | IF &first != &last 262 | _RegRangeFromContextBlock &first+1, &last 263 | ENDIF 264 | 265 | ENDM 266 | 267 | 268 | MACRO 269 | _FloatRangeToContextBlock &first, &last 270 | 271 | stfd &first, ContextBlock.FloatRegisters+8*(&first)(r6) 272 | 273 | IF &first != &last 274 | _FloatRangeToContextBlock &first+1, &last 275 | ENDIF 276 | 277 | ENDM 278 | 279 | 280 | MACRO 281 | _FloatRangeFromContextBlock &first, &last 282 | 283 | lfd &first, ContextBlock.FloatRegisters+8*(&first)(r6) 284 | 285 | IF &first != &last 286 | _FloatRangeFromContextBlock &first+1, &last 287 | ENDIF 288 | 289 | ENDM 290 | 291 | 292 | MACRO 293 | _InvalNCBPointerCache &scratch==r0, &offset==0 294 | 295 | IF &offset = 0 296 | li &scratch, -1 297 | ENDIF 298 | 299 | IF KDP.NCBPointerCache + &offset < KDP.NCBPointerCacheEnd 300 | stw &scratch, KDP.NCBPointerCache + &offset(r1) 301 | _InvalNCBPointerCache scratch=&scratch, offset=(&offset+8) 302 | ENDIF 303 | 304 | ENDM 305 | -------------------------------------------------------------------------------- /ConfigInfo.s: -------------------------------------------------------------------------------- 1 | ; ROM version of NKConfigurationInfo struct, based on Mac OS ROM 8=9=10. 2 | ; Lives at ROM + 0x30d000 (and other addresses on OldWorld). 3 | 4 | ; From start of ConfigInfo to end of LoMemInit = 4k: 5 | 6 | 7 | 8 | ; Auto-align fields 9 | 10 | aligning on 11 | 12 | 13 | 14 | import RomTop, RomBtm 15 | import Mac68kRomTop, Mac68kRomBtm 16 | import ExTblTop 17 | import NKTop 18 | import EmTop, EmBtm, EmEntry, EmKernelTrapTable 19 | import OpcodeTblTop, OpcodeTblBtm 20 | 21 | 22 | 23 | ConfigInfo 24 | 25 | ; These sums are not checked on NewWorld, but :Tools:ToolSource:RiscLayout.c calcs them anyway 26 | dcb.l 8, 0 ; 000 ; ROMByteCheckSums ; ROM Checksums - one word for each of 8 byte lanes 27 | dcb.l 2, 0 ; 020 ; ROMCheckSum64 ; ROM Checksum - 64 bit sum of doublewords 28 | 29 | dc.l RomTop-ConfigInfo ; 028 ; ROMImageBaseOffset ; Offset of Base of total ROM image 30 | dc.l RomBtm-RomTop ; 02c ; ROMImageSize ; Number of bytes in ROM image 31 | dc.l 0 ; 030 ; ROMImageVersion ; ROM Version number for entire ROM 32 | 33 | ; ROM component Info (offsets are from base of ConfigInfo page) 34 | dc.l Mac68kRomTop-ConfigInfo ; 034 ; Mac68KROMOffset ; Offset of base of Macintosh 68K ROM 35 | dc.l Mac68kRomBtm-Mac68kRomTop ; 038 ; Mac68KROMSize ; Number of bytes in Macintosh 68K ROM 36 | 37 | dc.l ExTblTop-ConfigInfo ; 03c ; ExceptionTableOffset ; Offset of base of PowerPC Exception Table Code 38 | dc.l 0xc000 ; 040 ; ExceptionTableSize ; Number of bytes in PowerPC Exception Table Code (generous) 39 | 40 | dc.l RomTop+0x320000-ConfigInfo ; 044 ; HWInitCodeOffset ; Offset of base of Hardware Init Code (no longer exists) 41 | dc.l 0x10000 ; 048 ; HWInitCodeSize ; Number of bytes in Hardware Init Code 42 | 43 | dc.l NKTop-ConfigInfo ; 04c ; KernelCodeOffset ; Offset of base of NanoKernel Code 44 | dc.l 0x10000 ; 050 ; KernelCodeSize ; Number of bytes in NanoKernel Code (too small) 45 | 46 | dc.l EmTop-ConfigInfo ; 054 ; EmulatorCodeOffset ; Offset of base of Emulator Code 47 | dc.l EmBtm-EmTop ; 058 ; EmulatorCodeSize ; Number of bytes in Emulator Code 48 | 49 | dc.l OpcodeTblTop-ConfigInfo ; 05c ; OpcodeTableOffset ; Offset of base of Opcode Table 50 | dc.l OpcodeTblBtm-OpcodeTblTop ; 060 ; OpcodeTableSize ; Number of bytes in Opcode Table 51 | 52 | ; Offsets within the Emulator Data Page. 53 | string AsIs 54 | @s dc.b 'NewWorld v1.0' ; 064 ; BootstrapVersion ; Bootstrap loader version info 55 | org @s + 16 56 | 57 | dc.l 0xf00 ; 074 ; BootVersionOffset ; offset within EmulatorData of BootstrapVersion 58 | dc.l 0x100 ; 078 ; ECBOffset ; offset within EmulatorData of ECB 59 | dc.l 0x070 ; 07c ; IplValueOffset ; offset within EmulatorData of IplValue 60 | 61 | ; Offsets within the Emulator Code. 62 | dc.l EmEntry-EmTop ; 080 ; EmulatorEntryOffset ; offset within Emulator Code of entry point 63 | dc.l EmKernelTrapTable-EmTop ; 084 ; KernelTrapTableOffset ; offset within Emulator Code of KernelTrapTable 64 | 65 | ; Interrupt Passing Masks. 66 | dc.l 0x00200000 ; 088 ; TestIntMaskInit ; initial value for test interrupt mask 67 | dc.l 0xff9fffff ; 08c ; ClearIntMaskInit ; initial value for clear interrupt mask 68 | dc.l 0x00e00000 ; 090 ; PostIntMaskInit ; initial value for post interrupt mask 69 | dc.l 0x808e0000 ; 094 ; LA_InterruptCtl ; logical address of Interrupt Control I/O page 70 | dc.b 6 ; 098 ; InterruptHandlerKind ; kind of handler to use 71 | 72 | dc.l 0x5fffe000 ; 09c ; LA_InfoRecord ; logical address of InfoRecord page 73 | dc.l 0x68ffe000 ; 0a0 ; LA_KernelData ; logical address of KernelData page 74 | dc.l 0x68fff000 ; 0a4 ; LA_EmulatorData ; logical address of EmulatorData page 75 | dc.l 0x68080000 ; 0a8 ; LA_DispatchTable ; logical address of Dispatch Table 76 | dc.l 0x68060000 ; 0ac ; LA_EmulatorCode ; logical address of Emulator Code 77 | 78 | dc.l LowMemVals-ConfigInfo ; 0b0 ; MacLowMemInitOffset ; offset to list of LowMem addr/data values 79 | 80 | 81 | ; 82 | ; Then the pagemap init stuff is filled by the trampoline at boot 83 | ; 84 | 85 | 86 | ; Address Space Mapping 87 | dc.l 0 ; 0b4 ; PageAttributeInit ; default WIMG, PP settings for PTE creation 88 | dc.l 0 ; 0b8 ; PageMapInitSize ; size of page mapping info 89 | dc.l 0 ; 0bc ; PageMapInitOffset ; offset to page mapping info (from base of ConfigInfo) 90 | dc.l 0 ; 0c0 ; PageMapIRPOffset ; offset of InfoRecord map info (from base of PageMap) 91 | dc.l 0 ; 0c4 ; PageMapKDPOffset ; offset of KernelData map info (from base of PageMap) 92 | dc.l 0 ; 0c8 ; PageMapEDPOffset ; offset of EmulatorData map info (from base of PageMap) 93 | 94 | dcb.l 32, 0 ; 0cc ; SegMap32SupInit ; 32 bit mode Segment Map Supervisor space 95 | dcb.l 32, 0 ; 14c ; SegMap32UsrInit ; 32 bit mode Segment Map User space 96 | dcb.l 32, 0 ; 1cc ; SegMap32CPUInit ; 32 bit mode Segment Map CPU space 97 | dcb.l 32, 0 ; 24c ; SegMap32OvlInit ; 32 bit mode Segment Map Overlay mode 98 | 99 | dcb.l 32, 0 ; 2cc ; BATRangeInit ; BAT mapping ranges 100 | 101 | dc.l 0 ; 34c ; BatMap32SupInit ; 32 bit mode BAT Map Supervisor space 102 | dc.l 0 ; 350 ; BatMap32UsrInit ; 32 bit mode BAT Map User space 103 | dc.l 0 ; 354 ; BatMap32CPUInit ; 32 bit mode BAT Map CPU space 104 | dc.l 0 ; 358 ; BatMap32OvlInit ; 32 bit mode BAT Map Overlay mode 105 | 106 | ; Only needed for Smurf 107 | dc.l 0 ; 35c ; SharedMemoryAddr ; physical address of Mac/Smurf shared message mem 108 | 109 | dc.l -1 ; 360 ; PA_RelocatedLowMemInit ; physical address of RelocatedLowMem 110 | 111 | dc.l 0x330000 - 0x30d000 ; 364 ; OpenFWBundleOffset ; Offset of base of OpenFirmware PEF Bundle 112 | dc.l 0x20000 ; 368 ; OpenFWBundleSize ; Number of bytes in OpenFirmware PEF Bundle 113 | 114 | dc.l 0xff800000 ; 36c ; LA_OpenFirmware ; logical address of Open Firmware 115 | dc.l 0x00400000 ; 370 ; PA_OpenFirmware ; physical address of Open Firmware 116 | dc.l 0xfff0c000 ; 374 ; LA_HardwarePriv ; logical address of HardwarePriv callback 117 | 118 | ; There are still some fixed-location fields here that the Trampoline will populate, 119 | ; but the ROM we are building contains just zeros. 120 | 121 | 122 | 123 | ; 124 | ; Key/value pairs for initializing Low Memory Globals. 125 | ; (at the end of ConfigInfo's 4k max size) 126 | ; 127 | 128 | ; A wee little macro to write LoMem key/value pairs *below* the asm location counter 129 | 130 | macro 131 | LowMem &addr, &val 132 | @b 133 | org @b - 4 134 | dc.l &val 135 | org @b - 8 136 | dc.l &addr 137 | org @b - 8 138 | endm 139 | 140 | 141 | ; Sentinel zero at end (late address) of list 142 | 143 | org 4096 - 4 144 | dc.l 0 145 | org 4096 - 4 146 | 147 | 148 | ; The table (older RISC versions have more in here.) 149 | 150 | ; The 68k emulator's cold-start vector, points to a "JMP StartBoot" 151 | ; instruction in the 68k ROM header. (Normally this value would be 152 | ; read from the ROM while it was overlaid on RAM at cold start, but 153 | ; why emulate that on a PowerPC?) 154 | 155 | ; SheepShaver patches the 68k reset vector around this location, 156 | ; but assumed offset 0xfd8. 157 | 158 | LowMem 0x00000004, 0xffc0002a 159 | 160 | LowMemVals 161 | -------------------------------------------------------------------------------- /NanoKernel/NKIndex.s: -------------------------------------------------------------------------------- 1 | ;_______________________________________________________________________ 2 | ; NanoKernel Opaque ID Index 3 | ; 4 | ; Creates opaque structure IDs and stores them in the Pool. An opaque 5 | ; ID maps back to the (type, pointer) pair passed to MakeID. 6 | ; 7 | ; This abstraction is very important to the Multiprocessing Services. 8 | ; 9 | ; Rene on comp.sys.mac.programmer.help, 26 Oct 01: 10 | ; 11 | ; Total opaque IDs - The number of IDs currently in use. All MP 12 | ; objects: address spaces, areas, processors, memory coherence groups, 13 | ; queues, semaphores, critical regions, event groups, timers, 14 | ; notifications, etc. are assigned an ID when created, and they are 15 | ; accessed by way of this ID. The kernel presently handles 65,000 16 | ; simultaneous IDs with a bit pattern reuse probability of 1 in 4 17 | ; billion. 18 | ; 19 | ; AUTO-GENERATED SYMBOL LIST 20 | ; IMPORTS: 21 | ; NKPoolAllocator 22 | ; PoolAllocClear 23 | ; NKThud 24 | ; panic 25 | ; EXPORTS: 26 | ; DeleteID (=> NKAddressSpaces, NKMPCalls, NKSync, NKTasks, NKTimers) 27 | ; GetNextIDOfClass (=> NKAddressSpaces, NKMPCalls, NKThud) 28 | ; InitIDIndex (=> NKInit) 29 | ; LookupID (=> NKAddressSpaces, NKInterrupts, NKMPCalls, NKPrimaryIntHandlers, NKSync, NKTasks, NKThud, NKTimers) 30 | ; MakeID (=> NKAddressSpaces, NKInit, NKMPCalls, NKSync, NKTasks) 31 | ;_______________________________________________________________________ 32 | 33 | Local_Panic set * 34 | b panic 35 | 36 | 37 | 38 | ; ARG KDP *r1 39 | 40 | InitIDIndex 41 | mflr r23 42 | 43 | li r8, Index.Size 44 | bl PoolAllocClear 45 | 46 | mr. r22, r8 47 | stw r8, PSA.IndexPtr(r1) 48 | beq Local_Panic 49 | 50 | li r9, 0 51 | stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1) 52 | 53 | sth r9, Index.HalfOne(r22) 54 | sth r9, Index.HalfTwo(r22) 55 | 56 | lisori r9, Index.kSignature 57 | stw r9, Index.Signature(r22) 58 | 59 | 60 | ; Then what the hell is this? 61 | li r8, 0xfd8 62 | bl PoolAllocClear 63 | 64 | cmpwi r8, 0 65 | stw r8, Index.IDsPtr(r22) 66 | beq Local_Panic 67 | 68 | mtlr r23 69 | 70 | li r9, 0x00 71 | sth r9, 0x0000(r8) 72 | li r9, 0x1fa 73 | sth r9, 0x0002(r8) 74 | lisori r9, 'IDs ' 75 | stw r9, 0x0004(r8) 76 | blr 77 | 78 | 79 | 80 | ; ARG void *r8, IDClass r9 81 | ; RET ID r8 82 | 83 | MakeID 84 | lwz r18, PSA.IndexPtr(r1) 85 | lhz r19, 0x0000(r18) 86 | mr r21, r19 87 | 88 | @_c 89 | lwz r18, PSA.IndexPtr(r1) 90 | rlwinm r20, r19, 25, 23, 29 91 | addi r20, r20, 0x08 92 | clrlwi. r19, r19, 0x17 93 | lwzx r18, r18, r20 94 | slwi r22, r19, 3 95 | addi r20, r18, 0x08 96 | cmpwi r18, 0x00 97 | add r22, r22, r20 98 | bne @_48 99 | li r19, 0x00 100 | b @_c 101 | 102 | @_3c 103 | add r20, r20, r19 104 | cmpw r20, r21 105 | beq @_70 106 | 107 | @_48 108 | lbz r23, 0x0000(r22) 109 | cmpwi r23, 0x00 110 | beq @_f0 111 | addi r19, r19, 0x01 112 | cmpwi cr1, r19, 0x1fa 113 | addi r22, r22, 0x08 114 | lhz r20, 0x0000(r18) 115 | blt cr1, @_3c 116 | addi r19, r20, 0x200 117 | b @_c 118 | 119 | @_70 120 | lwz r18, PSA.IndexPtr(r1) 121 | mr r21, r8 122 | lhz r19, 0x0002(r18) 123 | mr r22, r9 124 | addi r19, r19, 0x200 125 | rlwinm. r20, r19, 25, 23, 29 126 | li r8, 0x00 127 | beqlr 128 | mflr r23 129 | li r8, 0xfd8 130 | 131 | ; r1 = kdp 132 | ; r8 = size 133 | bl PoolAllocClear 134 | ; r8 = ptr 135 | 136 | mr. r18, r8 137 | mtlr r23 138 | li r8, 0x00 139 | beqlr 140 | lwz r17, PSA.IndexPtr(r1) 141 | lhz r19, 0x0002(r17) 142 | addi r19, r19, 0x200 143 | rlwinm r20, r19, 25, 23, 29 144 | addi r20, r20, 0x08 145 | sth r19, 0x0002(r17) 146 | stwx r18, r20, r17 147 | sth r19, 0x0000(r18) 148 | li r9, 0x1fa 149 | sth r9, 0x0002(r18) 150 | lis r9, 0x4944 151 | ori r9, r9, 0x7320 152 | stw r9, 0x0004(r18) 153 | li r19, 0x00 154 | mr r8, r21 155 | mr r9, r22 156 | addi r22, r18, 0x08 157 | 158 | @_f0 159 | stw r8, 0x0004(r22) 160 | stb r9, 0x0000(r22) 161 | lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1) 162 | addi r9, r9, 0x01 163 | stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1) 164 | lhz r20, 0x0000(r18) 165 | lhz r8, 0x0002(r22) 166 | lwz r21, PSA.IndexPtr(r1) 167 | add r19, r19, r20 168 | addi r8, r8, 0x01 169 | lhz r20, 0x0002(r18) 170 | sth r8, 0x0002(r22) 171 | addi r20, r20, -0x01 172 | rlwimi. r8, r19, 16, 0, 15 173 | sth r20, 0x0002(r18) 174 | sth r19, 0x0000(r21) 175 | bnelr+ 176 | lhz r8, 0x0002(r22) 177 | addi r8, r8, 0x01 178 | sth r8, 0x0002(r22) 179 | rlwimi r8, r19, 16, 0, 15 180 | blr 181 | 182 | 183 | 184 | ; ARG ID r8 185 | 186 | align 5 187 | 188 | DeleteID 189 | rlwinm r20, r8, 9, 23, 29 190 | lwz r18, PSA.IndexPtr(r1) 191 | addi r20, r20, 0x08 192 | rlwinm. r19, r8, 16, 23, 31 193 | lwzx r18, r18, r20 194 | cmplwi cr1, r19, 0x1fa 195 | cmpwi r18, 0x00 196 | addi r20, r18, 0x08 197 | slwi r22, r19, 3 198 | add r22, r22, r20 199 | clrlwi r20, r8, 0x10 200 | li r8, 0x00 201 | bgelr cr1 202 | beqlr 203 | lbz r19, 0x0000(r22) 204 | lhz r23, 0x0002(r22) 205 | cmpwi r19, 0x00 206 | cmpw cr1, r23, r20 207 | beqlr 208 | bnelr cr1 209 | lwz r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1) 210 | addi r9, r9, -0x01 211 | stw r9, KDP.NanoKernelInfo + NKNanoKernelInfo.IDCtr(r1) 212 | lhz r20, 0x0002(r18) 213 | stb r8, 0x0000(r22) 214 | addi r20, r20, 0x01 215 | li r8, 0x01 216 | sth r20, 0x0002(r18) 217 | blr 218 | 219 | 220 | 221 | ; ARG ID r8 222 | ; RET Ptr r8, IDClass r9 223 | 224 | align 5 225 | 226 | LookupID 227 | rlwinm r20, r8, 9, 23, 29 228 | lwz r18, PSA.IndexPtr(r1) 229 | addi r20, r20, 0x08 230 | rlwinm. r19, r8, 16, 23, 31 231 | lwzx r18, r18, r20 232 | cmplwi cr1, r19, 0x1fa 233 | cmpwi r18, 0x00 234 | addi r20, r18, 0x08 235 | slwi r22, r19, 3 236 | add r22, r22, r20 237 | clrlwi r20, r8, 0x10 238 | li r8, 0x00 239 | li r9, 0x00 240 | bgelr cr1 241 | beqlr 242 | lbz r19, 0x0000(r22) 243 | lhz r23, 0x0002(r22) 244 | cmpwi r19, 0x00 245 | cmpw cr1, r23, r20 246 | beqlr 247 | bnelr cr1 248 | lwz r8, 0x0004(r22) 249 | mr r9, r19 250 | blr 251 | 252 | 253 | 254 | ; ARG ID r8, IDClass r9 255 | ; RET ID r8 256 | 257 | align 5 258 | 259 | GetNextIDOfClass 260 | rlwinm r20, r8, 9, 23, 29 261 | lwz r18, PSA.IndexPtr(r1) 262 | addi r20, r20, 0x08 263 | rlwinm. r19, r8, 16, 23, 31 264 | lwzx r18, r18, r20 265 | cmplwi cr1, r19, 0x1fa 266 | cmpwi r18, 0x00 267 | cmpwi cr2, r8, 0x00 268 | addi r20, r18, 0x08 269 | slwi r22, r19, 3 270 | li r8, 0x00 271 | bgelr cr1 272 | beqlr 273 | add r22, r22, r20 274 | bne cr2, @_48 275 | 276 | @_3c 277 | lbz r23, 0x0000(r22) 278 | cmpwi r23, 0x00 279 | bne @_8c 280 | 281 | @_48 282 | addi r19, r19, 0x01 283 | cmpwi r19, 0x1fa 284 | addi r22, r22, 0x08 285 | blt @_3c 286 | lhz r20, 0x0000(r18) 287 | addi r20, r20, 0x200 288 | rlwinm. r20, r20, 25, 23, 29 289 | lwz r18, PSA.IndexPtr(r1) 290 | beqlr 291 | addi r20, r20, 0x08 292 | li r19, 0x00 293 | lwzx r18, r18, r20 294 | cmpwi r18, 0x00 295 | addi r22, r18, 0x08 296 | bne @_3c 297 | li r8, 0x00 298 | blr 299 | 300 | @_8c 301 | cmpwi r9, 0x00 302 | cmpw cr1, r9, r23 303 | beq @_9c 304 | bne cr1, @_48 305 | 306 | @_9c 307 | lhz r20, 0x0000(r18) 308 | lhz r8, 0x0002(r22) 309 | add r19, r19, r20 310 | rlwimi r8, r19, 16, 0, 15 311 | blr 312 | -------------------------------------------------------------------------------- /PPCExceptionTable.s: -------------------------------------------------------------------------------- 1 | HASH1 equ 978 2 | HASH2 equ 979 3 | ICMP equ 981 4 | DCMP equ 977 5 | IMISS equ 980 6 | DMISS equ 976 7 | RPA equ 982 8 | 9 | 10 | 11 | macro 12 | Vanilla &idx 13 | 14 | @start 15 | b @jump1 16 | b @jump2 17 | 18 | @jump1 19 | ; r1 -> SPRG1 20 | ; LR -> SPRG2 21 | ; targ -> r1 22 | ; optr -> LR 23 | mtsprg 1, r1 24 | mflr r1 25 | mtsprg 2, r1 26 | mfsprg r1, 3 27 | lwz r1, &idx(r1) 28 | mtlr r1 29 | blrl 30 | dc.l @start - TableStart 31 | mflr r1 32 | 33 | @jump2 34 | mtsprg 1, r1 35 | mfsprg r1, 3 36 | mtsprg 2, r1 37 | mtlr r1 38 | lwz r1, &idx(r1) 39 | dc.l @start - TableStart 40 | blrl 41 | 42 | endm 43 | 44 | 45 | 46 | TableStart 47 | 48 | 49 | 50 | ; 0000-00ff: For software use only 51 | 52 | org 0x0000 53 | mtsprg 1, r1 54 | mfsprg r1, 3 55 | lwz r1, 0x00BC(r1) 56 | mtlr r1 57 | blrl 58 | 59 | 60 | org 0x0080 61 | dc.l 0x0000D000 ; '....' (invalid instruction) 62 | 63 | 64 | 65 | ; 0100-0fff: Architecture-defined exceptions 66 | 67 | org 0x0100 68 | b $+0x0008 ; 0x00000108 69 | b $+0x0050 ; 0x00000154 70 | mtsprg 1, r1 71 | mfcr r1 72 | mtsprg 2, r1 73 | mfsrr1 r1 74 | mtcrf 255, r1 75 | bne cr7, RTASFairyDust 76 | mfspr r1, HID0 77 | mtcrf 255, r1 78 | bns cr3, RTASFairyDust 79 | mfsprg r1, 2 80 | mtcrf 255, r1 81 | mflr r1 82 | mtsprg 2, r1 83 | mfsprg r1, 3 84 | lwz r1, 0x0004(r1) 85 | mtlr r1 86 | blrl 87 | dc.l 0x00000100 ; '....' (invalid instruction) 88 | 89 | 90 | org 0x180 91 | PerfMon 92 | mtsprg 2, r1 93 | mfsprg r1, 3 94 | stw r2, 0x0000(r1) 95 | mfsprg r2, 2 96 | rlwinm r2, r2, 26, 24, 29 97 | lwzx r1, r2, r1 98 | mflr r2 99 | mtlr r1 100 | mfsprg r1, 2 101 | mtsprg 2, r2 102 | mfsprg r2, 3 103 | lwz r2, 0x0000(r2) 104 | blr 105 | 106 | 107 | org 0x0200 ; Machine Check 108 | Vanilla 0x0008 109 | 110 | 111 | org 0x0300 ; Data Storage 112 | Vanilla 0x000C 113 | 114 | 115 | org 0x0400 ; Instruction Storage 116 | Vanilla 0x0010 117 | 118 | 119 | org 0x0500 ; External 120 | Vanilla 0x0014 121 | 122 | 123 | org 0x0600 ; Alignment 124 | Vanilla 0x0018 125 | 126 | 127 | org 0x0700 ; Program 128 | Vanilla 0x001C 129 | 130 | 131 | org 0x0800 ; FP Unavailable 132 | Vanilla 0x0020 133 | 134 | 135 | org 0x0900 ; Decrementer 136 | Vanilla 0x0024 137 | 138 | 139 | org 0x0A00 140 | Vanilla 0x0028 141 | 142 | 143 | org 0x0B00 144 | Vanilla 0x002C 145 | 146 | 147 | org 0x0C00 ; System Call 148 | Vanilla 0x0030 149 | 150 | 151 | org 0x0D00 ; Trace 152 | Vanilla 0x0034 153 | 154 | 155 | org 0x0E00 156 | Vanilla 0x0038 157 | 158 | 159 | ; Performance monitor??? 160 | 161 | org 0x0F00 162 | mtsprg 1, r1 163 | li r1, 0xF00 164 | b PerfMon 165 | 166 | org 0x0F20 167 | mtsprg 1, r1 168 | li r1, 0xF20 169 | b PerfMon 170 | 171 | 172 | 173 | 174 | ; 1000-2fff: Implementation-specific exceptions 175 | 176 | org 0x1000 177 | mfspr r2, HASH1 178 | lwz r1, 0x0000(r2) 179 | mfctr r0 180 | mfspr r3, ICMP 181 | cmpw r1, r3 182 | beq $+0x001C ; 0x00001030 183 | li r1, 7 184 | mtctr r1 185 | lwzu r1, 0x0008(r2) 186 | cmpw r1, r3 187 | bdnzf cr0_EQ, $-0x0008 ; 0x00001020 188 | bne $+0x0038 ; 0x00001064 189 | lwz r1, 0x0004(r2) 190 | mtctr r0 191 | andi. r3, r1, 0x0008 192 | bne $+0x006C ; 0x000010A8 193 | mfspr r0, IMISS 194 | mfsrr1 r3 195 | mtcrf 128, r3 196 | mtspr RPA, r1 197 | ori r1, r1, 0x0100 198 | srwi r1, r1, 8 199 | dc.l 0x7C0007E4 ; '|...' (invalid instruction) 200 | stb r1, 0x0006(r2) 201 | rfi 202 | andi. r1, r3, 0x0040 203 | bne $+0x0014 ; 0x0000107C 204 | mfspr r2, HASH2 205 | lwz r1, 0x0000(r2) 206 | ori r3, r3, 0x0040 207 | b $-0x0068 ; 0x00001010 208 | mfsrr1 r3 209 | clrlwi r2, r3, 16 210 | oris r2, r2, 0x4000 211 | mtctr r0 212 | mtsrr1 r2 213 | mfmsr r0 214 | xoris r0, r0, 0x0002 215 | mtcrf 128, r3 216 | mtmsr r0 217 | isync 218 | b $-0x0CA4 ; 0x00000400 219 | mfsrr1 r3 220 | clrlwi r2, r3, 16 221 | oris r2, r2, 0x1000 222 | b $-0x0028 ; 0x0000108C 223 | 224 | 225 | org 0x1100 226 | mfspr r2, HASH1 227 | lwz r1, 0x0000(r2) 228 | mfctr r0 229 | mfspr r3, DCMP 230 | cmpw r1, r3 231 | beq $+0x001C ; 0x00001130 232 | li r1, 7 233 | mtctr r1 234 | lwzu r1, 0x0008(r2) 235 | cmpw r1, r3 236 | bdnzf cr0_EQ, $-0x0008 ; 0x00001120 237 | bne $+0x0034 ; 0x00001160 238 | lwz r1, 0x0004(r2) 239 | mtctr r0 240 | mfspr r0, DMISS 241 | mfsrr1 r3 242 | mtcrf 128, r3 243 | mtspr RPA, r1 244 | ori r1, r1, 0x0100 245 | srwi r1, r1, 8 246 | dc.l 0x7C0007A4 ; '|...' (invalid instruction) 247 | stb r1, 0x0006(r2) 248 | rfi 249 | nop 250 | andi. r1, r3, 0x0040 251 | bne $+0x013C ; 0x000012A0 252 | mfspr r2, HASH2 253 | lwz r1, 0x0000(r2) 254 | ori r3, r3, 0x0040 255 | b $-0x0064 ; 0x00001110 256 | 257 | 258 | org 0x1200 259 | mfspr r2, HASH1 260 | lwz r1, 0x0000(r2) 261 | mfctr r0 262 | mfspr r3, DCMP 263 | cmpw r1, r3 264 | beq $+0x001C ; 0x00001230 265 | li r1, 7 266 | mtctr r1 267 | lwzu r1, 0x0008(r2) 268 | cmpw r1, r3 269 | bdnzf cr0_EQ, $-0x0008 ; 0x00001220 270 | bne $+0x003C ; 0x00001268 271 | lwz r1, 0x0004(r2) 272 | mtctr r0 273 | slwi. r3, r1, 30 274 | bge $+0x0044 ; 0x00001280 275 | andi. r3, r1, 0x0001 276 | bne $+0x0054 ; 0x00001298 277 | mfspr r0, DMISS 278 | mfsrr1 r3 279 | mtcrf 128, r3 280 | ori r1, r1, 0x0180 281 | mtspr RPA, r1 282 | dc.l 0x7C0007A4 ; '|...' (invalid instruction) 283 | sth r1, 0x0006(r2) 284 | rfi 285 | andi. r1, r3, 0x0040 286 | bne $+0x0034 ; 0x000012A0 287 | mfspr r2, HASH2 288 | lwz r1, 0x0000(r2) 289 | ori r3, r3, 0x0040 290 | b $-0x006C ; 0x00001210 291 | mfsrr1 r0 292 | extrwi r0, r0, 1, 17 293 | mfspr r3, DMISS 294 | mfsrin r3, r3 295 | rlwnm. r3, r3, r0, 1, 1 296 | beq $-0x004C ; 0x00001248 297 | lis r1, 2048 298 | b $+0x000C ; 0x000012A8 299 | lis r1, 16384 300 | mtctr r0 301 | mfsrr1 r3 302 | rlwimi r1, r3, 9, 6, 6 303 | clrlwi r2, r3, 16 304 | mtsrr1 r2 305 | mtdsisr r1 306 | mfspr r1, DMISS 307 | andi. r2, r2, 0x0001 308 | beq+ $+0x0008 ; 0x000012CC 309 | xori r1, r1, 0x0007 310 | mtdar r1 311 | mfmsr r0 312 | xoris r0, r0, 0x0002 313 | mtcrf 128, r3 314 | mtmsr r0 315 | isync 316 | b $-0x0FE4 ; 0x00000300 317 | 318 | 319 | org 0x1300 320 | Vanilla 0x004C 321 | 322 | 323 | org 0x1400 324 | Vanilla 0x0050 325 | 326 | 327 | org 0x1500 328 | Vanilla 0x0054 329 | 330 | 331 | org 0x1600 332 | Vanilla 0x0058 333 | 334 | 335 | org 0x1700 336 | Vanilla 0x005C 337 | 338 | 339 | org 0x1800 340 | Vanilla 0x0060 341 | 342 | 343 | org 0x1900 344 | Vanilla 0x0064 345 | 346 | 347 | org 0x1A00 348 | Vanilla 0x0068 349 | 350 | 351 | org 0x1B00 352 | Vanilla 0x006C 353 | 354 | 355 | org 0x1C00 356 | Vanilla 0x0070 357 | 358 | 359 | org 0x1D00 360 | Vanilla 0x0074 361 | 362 | 363 | org 0x1E00 364 | Vanilla 0x0078 365 | 366 | 367 | org 0x1F00 368 | Vanilla 0x007C 369 | 370 | 371 | org 0x2000 372 | Vanilla 0x0080 373 | 374 | 375 | org 0x2100 376 | Vanilla 0x0084 377 | 378 | 379 | org 0x2200 380 | Vanilla 0x0088 381 | 382 | 383 | org 0x2300 384 | Vanilla 0x008C 385 | 386 | 387 | org 0x2400 388 | Vanilla 0x0090 389 | 390 | 391 | org 0x2500 392 | Vanilla 0x0094 393 | 394 | 395 | org 0x2600 396 | Vanilla 0x0098 397 | 398 | 399 | org 0x2700 400 | Vanilla 0x009C 401 | 402 | 403 | org 0x2800 404 | Vanilla 0x00A0 405 | 406 | 407 | org 0x2900 408 | Vanilla 0x00A4 409 | 410 | 411 | org 0x2A00 412 | Vanilla 0x00A8 413 | 414 | 415 | org 0x2B00 416 | Vanilla 0x00AC 417 | 418 | 419 | org 0x2C00 420 | Vanilla 0x00B0 421 | 422 | 423 | org 0x2D00 424 | Vanilla 0x00B4 425 | 426 | 427 | org 0x2E00 428 | Vanilla 0x00B8 429 | 430 | 431 | org 0x2F00 432 | Vanilla 0x00BC 433 | 434 | 435 | 436 | ; Outside the exception table, but called by it: 437 | 438 | org 0x3000 439 | RTASFairyDust 440 | mr r21,r3 441 | 442 | li r0,0 443 | 444 | lwz r5, 0(r21) 445 | lwz r4, 4(r21) 446 | 447 | lwz r9, 12(r21) 448 | lwz r3, 12(r9) 449 | 450 | lwz r6, 8(r21) 451 | lwz r8, 16(r21) 452 | lwz r22,24(r21) 453 | lwz r23,28(r21) 454 | 455 | bl @clrbats 456 | 457 | lis r7, 'RT' 458 | ori r7,r7,'AS' 459 | 460 | ; Soo, we jump to *(arg + 24) the ugly way 461 | mtlr r22 462 | blr 463 | 464 | @clrbats 465 | mtdbatl 0,r0 466 | mtdbatu 0,r0 467 | mtdbatl 1,r0 468 | mtdbatu 1,r0 469 | mtdbatl 2,r0 470 | mtdbatu 2,r0 471 | mtdbatl 3,r0 472 | mtdbatu 3,r0 473 | mtibatl 0,r0 474 | mtibatu 0,r0 475 | mtibatl 1,r0 476 | mtibatu 1,r0 477 | mtibatl 2,r0 478 | mtibatu 2,r0 479 | mtibatl 3,r0 480 | mtibatu 3,r0 481 | isync 482 | 483 | blr 484 | -------------------------------------------------------------------------------- /NanoKernel/NKCache.s: -------------------------------------------------------------------------------- 1 | ###### ### ###### ## ## ######## ###### ### ## ## 2 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 3 | ## ## ## ## ## ## ## ## ## ## ## ## 4 | ## ## ## ## ######### ###### ## ## ## ## ## 5 | ## ######### ## ## ## ## ## ######### ## ## 6 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 7 | ###### ## ## ###### ## ## ######## ###### ## ## ######## ######## 8 | 9 | ; Enable/disable/probe the L1/2 data/inst cache 10 | 11 | ; Probably called using an unknown 68k F-trap. Not usually called on my 12 | ; G4, but can be tested by hacking the MPCall table. Uses fancy new CPU 13 | ; features (MSSCR0), so probably not legacy code. For CPU accelerator 14 | ; cards? `FlushCache` needs to be nopped out to prevent a crash. 15 | 16 | ; ARGUMENT (r3) 17 | ; r3.hi = action flags 18 | ; enable specified caches $8000 19 | ; disable specified caches $4000 20 | ; report pre-change state $2000 21 | ; also enable (???) $1000 22 | ; enable/disable I-cache $0800 23 | ; enable/disable D-cache $0400 24 | ; 25 | ; r3.lo = which cache (L1/2) 26 | ; level 1 1 27 | ; level 2 2 28 | ; 29 | ; RETURN VALUE (r3) 30 | ; r3.hi = pre-change state flags (resemble action flags) 31 | ; both caches disabled $4000 32 | ; either cache enabled $8000 33 | ; I-cache enabled $0800 34 | ; D-cache enabled $0400 35 | ; 36 | ; r3.lo = return status 37 | ; success 0 38 | ; failure < 0 39 | ; checked L1 but did not set 1 40 | ; checked L2 but did not set 2 41 | 42 | ; AUTO-GENERATED SYMBOL LIST 43 | ; IMPORTS: 44 | ; NKInterrupts 45 | ; IntReturn 46 | ; EXPORTS: 47 | ; FlushCaches (=> NKPowerCalls) 48 | ; FlushL1CacheUsingMSSCR0 (=> NKInterrupts) 49 | ; kcCacheDispatch (=> NKInit) 50 | 51 | ; DeclareMPCall 199, kcCacheDispatch ; DEBUG 52 | 53 | kcCacheDispatch 54 | 55 | _RegRangeToContextBlock r21, r23 ; get some breathing room 56 | 57 | ; _log 'kcCacheDispatch ' ; DEBUG 58 | ; mr r8, r3 ; DEBUG 59 | ; bl printw ; DEBUG 60 | ; _log '^n' ; DEBUG 61 | 62 | clrlwi r8, r3, 16 ; bad selector 63 | cmplwi r8, 2 64 | bgt @fail_bad_selector 65 | 66 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 67 | andi. r8, r8, 1 << NKProcessorInfo.hasL2CR 68 | beq CacheCallFailNoL2 ; no L2CR => fail (what about 601?) 69 | 70 | rlwinm. r9, r3, 0, 2, 2 ; if flagged, get cache state in r23 71 | bnel CacheCallGetInfoForReturnValue ; (otherwise, r23 is undefined) 72 | 73 | srwi r8, r3, 30 ; cannot enable *and* disable 74 | cmpwi r8, 3 75 | beq CacheCallFailBadFlags 76 | 77 | clrlwi r8, r3, 16 ; go to main code for level 1/2 cache 78 | cmplwi r8, 1 79 | beq CacheCallDispatchL1 80 | cmplwi r8, 2 81 | beq CacheCallDispatchL2 82 | 83 | @fail_bad_selector ; fall through => bad selector 84 | lisori r3, -2 85 | b CacheCallReturn 86 | 87 | 88 | 89 | ### ## ## ### 90 | ## ## #### ## 91 | ## ## ## ## 92 | ## ## ## ## 93 | ## ## ## ## 94 | ## ## ## ## 95 | ### ######## ###### ### 96 | 97 | CacheCallDispatchL1 98 | 99 | rlwinm. r9, r3, 0, 1, 1 100 | bne CacheCallL1DisableSelected 101 | 102 | rlwinm. r9, r3, 0, 0, 0 103 | bne CacheCallL1EnableSelected 104 | 105 | rlwinm. r9, r3, 0, 3, 3 ; ??? 106 | 107 | bl FlushCaches 108 | 109 | b CacheCallReturn 110 | 111 | 112 | 113 | CacheCallL1DisableSelected 114 | 115 | bl FlushCaches 116 | 117 | rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE] 118 | srwi r22, r22, 12 119 | mfspr r21, hid0 120 | andc r21, r21, r22 ; HID0 &= ~mybits 121 | sync 122 | mtspr hid0, r21 123 | 124 | li r3, 0 125 | b CacheCallReturn 126 | 127 | 128 | 129 | CacheCallL1EnableSelected 130 | 131 | rlwinm r22, r3, 0, 4, 5 ; shift arg bits to align with HID0[DCE/ICE] 132 | srwi r22, r22, 12 133 | mfspr r21, hid0 134 | or r21, r21, r22 ; HID0 |= mybits 135 | sync 136 | mtspr hid0, r21 137 | 138 | li r3, 0 139 | b CacheCallReturn 140 | 141 | 142 | 143 | ### ## ####### ### 144 | ## ## ## ## ## 145 | ## ## ## ## 146 | ## ## ####### ## 147 | ## ## ## ## 148 | ## ## ## ## 149 | ### ######## ######### ### 150 | 151 | CacheCallDispatchL2 152 | 153 | rlwinm. r9, r3, 0, 1, 1 154 | bne CacheCallL2DisableSelected 155 | 156 | rlwinm. r9, r3, 0, 0, 0 157 | bne CacheCallL2EnableSelected 158 | 159 | rlwinm. r9, r3, 0, 3, 3 160 | bne CacheCallL2Flag3 ; goes to DisableSelected 161 | 162 | rlwinm. r9, r3, 0, 2, 2 163 | ;bne removed? 164 | 165 | bne CacheCallReturn 166 | 167 | 168 | 169 | CacheCallFailBadFlags 170 | 171 | lisori r3, -4 172 | b CacheCallReturn 173 | 174 | 175 | 176 | CacheCallL2Flag3 177 | 178 | bl CacheCallL2DisableSelected ; typo? should be `b` 179 | 180 | 181 | 182 | CacheCallL2EnableSelected 183 | 184 | mfspr r21, l2cr ; fail if L2CR[L2E] already set 185 | sync 186 | andis. r21, r21, 0x8000 187 | bne CacheCallReturn 188 | 189 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) 190 | and. r8, r8, r8 191 | beq CacheCallFailNoL2 ; fail if zero-sized cache reported 192 | 193 | mfspr r21, hid0 ; save HID0 194 | 195 | rlwinm r8, r21, 0, 12, 10 ; clear HID0[DPM] (dynamic power management) 196 | mtspr hid0, r8 ; presumably to keep L2 working while we wait? 197 | sync 198 | 199 | addi r8, r1, PSA.ProcessorState 200 | lwz r8, NKProcessorState.saveL2CR(r8) 201 | and. r8, r8, r8 202 | beq CacheCallReturn ; fail if zero L2CR was saved? 203 | sync 204 | 205 | lis r9, 0x0020 ; set L2CR[GI] (global invalidate) 206 | or r8, r8, r9 207 | mtspr l2cr, r8 208 | sync 209 | @inval_loop 210 | mfspr r8, l2cr ; check L2CR[IP] (invalidate progress) 211 | sync 212 | andi. r9, r8, 1 213 | bne @inval_loop 214 | 215 | lis r9, 0x0020 ; clear L2CR[GI] 216 | andc r8, r8, r9 217 | mtspr l2cr, r8 218 | sync 219 | 220 | lis r9, 0x8000 ; set L2CR[L2E] (L2 enable) 221 | or r8, r8, r9 222 | mtspr l2cr, r8 223 | sync 224 | 225 | mtspr hid0, r21 ; restore HID0 226 | sync 227 | 228 | li r3, 0 ; return successfully 229 | b CacheCallReturn 230 | 231 | 232 | 233 | CacheCallFailNoL2 234 | 235 | li r3, -2 236 | b CacheCallReturn 237 | 238 | 239 | 240 | CacheCallL2DisableSelected 241 | 242 | mfspr r22, l2cr ; return if already disabled per L2CR[L2E] 243 | sync 244 | andis. r22, r22, 0x8000 245 | beq CacheCallReturn 246 | 247 | bl FlushCaches 248 | 249 | mfspr r22, l2cr ; clear L2CR[L2E] 250 | sync 251 | clrlwi r22, r22, 1 252 | mtspr l2cr, r22 253 | sync 254 | 255 | addi r8, r1, PSA.ProcessorState 256 | stw r22, NKProcessorState.saveL2CR(r8) ; update saveL2CR 257 | sync 258 | 259 | rlwinm r22, r22, 0, 7, 3 ; clear L2CR[3/5/6] (all reserved) 260 | oris r22, r22, 0x0010 ; set L2CR[13] (also reserved) 261 | mtspr l2cr, r22 262 | sync 263 | 264 | ;b CacheCallReturn ; fall through 265 | 266 | 267 | 268 | ### ######## ######## ######## ## ## ######## ## ## ### 269 | ## ## ## ## ## ## ## ## ## ### ## ## 270 | ## ## ## ## ## ## ## ## ## #### ## ## 271 | ## ######## ###### ## ## ## ######## ## ## ## ## 272 | ## ## ## ## ## ## ## ## ## ## #### ## 273 | ## ## ## ## ## ## ## ## ## ## ### ## 274 | ### ## ## ######## ## ####### ## ## ## ## ### 275 | 276 | CacheCallReturn 277 | 278 | ori r23, r23, 0xffff ; put the r23.hi from CacheCallGetInfoForReturnValue into r3.hi 279 | oris r3, r3, 0xffff 280 | and r3, r3, r23 281 | 282 | CacheCallReturnWithoutFlags 283 | _RegRangeFromContextBlock r21, r23 284 | sync 285 | 286 | ; _log 'Return ' ; DEBUG 287 | ; mr r8, r3 ; DEBUG 288 | ; bl printw ; DEBUG 289 | ; _log '^n' ; DEBUG 290 | 291 | b IntReturn 292 | 293 | 294 | 295 | ### ######## ######## ####### ######## ######## ### 296 | ## ## ## ## ## ## ## ## ## ## ## 297 | ## ## ## ## ## ## ## ## ## ## ## 298 | ## ######## ######## ## ## ######## ###### ## 299 | ## ## ## ## ## ## ## ## ## ## 300 | ## ## ## ## ## ## ## ## ## ## 301 | ### ## ## ## ####### ######## ######## ### 302 | 303 | ; RET r23.hi = flags describing state of specified cache (see top of file) 304 | 305 | CacheCallGetInfoForReturnValue 306 | 307 | clrlwi r8, r3, 16 308 | 309 | cmplwi r8, 1 310 | beq @level1 311 | cmplwi r8, 2 312 | beq @level2 313 | 314 | lisori r3, -5 315 | b CacheCallReturnWithoutFlags 316 | 317 | @level1 318 | mfspr r21, hid0 319 | rlwinm. r21, r21, 12, 4, 5 320 | beq @all_off 321 | 322 | oris r23, r21, 0x8000 323 | blr 324 | 325 | @level2 326 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) 327 | and. r8, r8, r8 328 | beq CacheCallFailNoL2 329 | 330 | mfspr r21, hid0 ; same bits as above 331 | rlwinm r21, r21, 12, 4, 5 332 | 333 | mfspr r22, l2cr ; L2-D is on if L1-D is on and L2CR[DO] is cleared 334 | rlwinm r22, r22, 5, 4, 4 335 | andc r21, r21, r22 336 | 337 | mfspr r22, l2cr ; then again, both L2s are off if L2CR[L2E] is cleared 338 | andis. r22, r22, 0x8000 339 | beq @all_off 340 | 341 | or r23, r21, r22 342 | blr 343 | 344 | @all_off 345 | lisori r23, 0x40000000 346 | blr 347 | 348 | 349 | 350 | ######## ## ## ## ###### ## ## ######## ## ## ## ## ###### ###### 351 | ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## 352 | ## ## ## ## ## ## ## ## ## ## #### ## ## ## 353 | ###### ## ## ## ###### ######### ###### ## ## ## ## ## ## ###### 354 | ## ## ## ## ## ## ## ## ## ## ## #### ## ## 355 | ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## 356 | ## ######## ####### ###### ## ## ## ####### ## ## ###### ###### 357 | 358 | ; Flush L1 and L2 caches 359 | ; Also used by NKPowerCalls.s 360 | 361 | ; ARG KDP *r1, ContextBlock *r6 362 | ; CLOB r8, r9, cr 363 | 364 | FlushCaches 365 | 366 | ; blr ; DEBUG 367 | 368 | ; Be cautious 369 | 370 | mfctr r8 371 | stw r25, ContextBlock.r25(r6) 372 | stw r24, ContextBlock.r24(r6) 373 | stw r8, ContextBlock.KernelCTR(r6) 374 | 375 | 376 | ; Flush level 1 377 | 378 | lhz r25, KDP.ProcessorInfo + NKProcessorInfo.DataCacheLineSize(r1) 379 | and. r25, r25, r25 ; r25 = L1-D line size 380 | cntlzw r8, r25 381 | beq @return 382 | subfic r9, r8, 31 ; r9 = logb(L1-D line size) 383 | 384 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.DataCacheTotalSize(r1) 385 | and. r8, r8, r8 ; r8 = L1-D size 386 | beq @return 387 | 388 | lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 389 | mtcr r24 390 | 391 | bc BO_IF, 31 - NKProcessorInfo.hasMSSregs, @use_SPRs_to_invalidate 392 | ; => go away to handle weird CPUs 393 | 394 | bc BO_IF_NOT, 31 - NKProcessorInfo.hasPLRUL1, @no_pseudo_lru 395 | slwi r24, r8, 1 396 | add r8, r8, r24 397 | srwi r8, r8, 1 ; be generous with pseudo-LRU caches 398 | @no_pseudo_lru 399 | 400 | srw r8, r8, r9 401 | mtctr r8 ; loop counter = cache/line 402 | 403 | lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM 404 | lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8) 405 | add r8, r8, r9 406 | 407 | @loop_L1 408 | lwzux r9, r8, r25 409 | bdnz @loop_L1 410 | 411 | 412 | ; Flush level 2 (very similar to above) 413 | 414 | lwz r24, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 415 | andi. r24, r24, 1 << NKProcessorInfo.hasL2CR 416 | beq @return ; return if L2CR unavailable 417 | 418 | mfspr r24, l2cr 419 | andis. r24, r24, 0x8000 420 | beq @return ; return if L2 off (per L2CR[L2E]) 421 | 422 | lhz r25, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DBlockSize(r1) 423 | and. r25, r25, r25 ; r25 = L2-D line size 424 | cntlzw r8, r25 425 | beq @return 426 | subfic r9, r8, 31 ; r9 = logb(L2-D line size) 427 | 428 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) 429 | and. r8, r8, r8 ; r8 = L2-D size 430 | beq @return 431 | 432 | srw r8, r8, r9 433 | mtctr r8 ; loop counter = cache/line 434 | 435 | mfspr r24, l2cr ; set L2CR[DO] (disables L2-I) 436 | oris r24, r24, 0x0040 437 | mtspr l2cr, r24 438 | isync 439 | 440 | lwz r8, KDP.PA_ConfigInfo(r1) ; fill the cache with Mac ROM 441 | lwz r9, NKConfigurationInfo.ROMImageBaseOffset(r8) 442 | add r8, r8, r9 443 | 444 | addis r8, r8, 0x19 ; start high in ROM and count backwards 445 | neg r25, r25 446 | 447 | @loop_L2 448 | lwzux r9, r8, r25 449 | bdnz @loop_L2 450 | 451 | rlwinm r24, r24, 0, 10, 8 452 | mtspr l2cr, r24 ; clear L2CR[DO] (reenables L2-I) 453 | isync 454 | 455 | 456 | ; Done (this return path is also called from the sneaky code below) 457 | 458 | @return 459 | lwz r8, ContextBlock.KernelCTR(r6) 460 | lwz r25, ContextBlock.r25(r6) 461 | lwz r24, ContextBlock.r24(r6) 462 | sync 463 | mtctr r8 464 | blr 465 | 466 | 467 | ; If "hasMSSregs" flag (my name) is set in ProcessorFlags, L1 and L2 can 468 | ; instead be flushed by clobbering reserved bits in MSSCR0 and L2CR 469 | ; respectively. 470 | 471 | @use_SPRs_to_invalidate 472 | 473 | ; Flush level 1: set MSSCR0[8] and spin until it clears 474 | 475 | dssall ; AltiVec needs to know 476 | 477 | sync 478 | mfspr r8, msscr0 479 | oris r8, r8, 0x0080 480 | mtspr msscr0, r8 481 | sync 482 | @loop_msscr0 483 | mfspr r8, msscr0 484 | sync 485 | andis. r8, r8, 0x0080 486 | bne @loop_msscr0 487 | 488 | 489 | ; Flush level 2: set L2CR[4] and spin until it clears 490 | 491 | mfspr r8, l2cr 492 | ori r8, r8, 0x0800 493 | mtspr l2cr, r8 494 | sync 495 | @loop_l2cr 496 | mfspr r8, l2cr 497 | sync 498 | andi. r8, r8, 0x0800 499 | bne @loop_l2cr 500 | 501 | 502 | ; Jump back up to main code path to return 503 | 504 | b @return 505 | 506 | 507 | 508 | ; Called when we cop a machine check with the "L1 data cache error" 509 | ; flag set in SRR1, followed by an interrupt return. Same trick as 510 | ; above. 511 | 512 | ; CLOB r8, cr 513 | 514 | FlushL1CacheUsingMSSCR0 515 | 516 | ; Return if MSSCR0 unavailable 517 | 518 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 519 | mtcr r8 520 | bclr BO_IF_NOT, 31-NKProcessorInfo.hasMSSregs 521 | 522 | 523 | ; Flush level 1: set MSSCR0[8] and spin until it clears 524 | 525 | dssall ; AltiVec needs to know 526 | 527 | sync 528 | mfspr r8, msscr0 529 | oris r8, r8, 0x0080 530 | mtspr msscr0, r8 531 | sync 532 | @loop_msscr0 533 | mfspr r8, msscr0 534 | sync 535 | andis. r8, r8, 0x0080 536 | bne @loop_msscr0 537 | 538 | blr 539 | -------------------------------------------------------------------------------- /NanoKernel/NKConsoleLog.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKScreenConsole 4 | ; ScreenConsole_putchar 5 | ; ScreenConsole_redraw 6 | ; EXPORTS: 7 | ; getchar (=> NKThud, NKTimers) 8 | ; print_unknown (=> NKThud) 9 | ; printb (=> NKInit, NKMPCalls, NKTimers) 10 | ; printc (=> NKInit, NKPoolAllocator, NKThud) 11 | ; printd (=> NKInit, NKMPCalls, NKPoolAllocator, NKTimers) 12 | ; printh (=> NKBuiltinInit, NKMPCalls, NKReplacementInit, NKScheduler, NKThud, NKTimers) 13 | ; prints (=> NKMPCalls, NKThud) 14 | ; printw (=> NKAddressSpaces, NKInit, NKInterrupts, NKMPCalls, NKPaging, NKPoolAllocator, NKReplacementInit, NKScheduler, NKThud, NKTimers, NKVMCalls) 15 | 16 | 17 | 18 | ; prints 19 | 20 | ; _log null-terminated string with a few special escapes. 21 | ; Not done figuring this out, with the serial and stuff. 22 | 23 | prints ; OUTSIDE REFERER 24 | mfsprg r1, 0 25 | stmw r24, -0x0108(r1) 26 | mflr r24 27 | mfcr r25 28 | stw r24, -0x0110(r1) 29 | stw r25, -0x010c(r1) 30 | lwz r1, -0x0004(r1) 31 | lwz r28, PSA.NoIdeaR23(r1) 32 | lwz r29, 0x0edc(r1) 33 | 34 | _Lock PSA.DbugLock, scratch1=r30, scratch2=r31 35 | 36 | cmpwi cr7, r28, 0x00 37 | andi. r29, r29, 0x02 38 | beq cr7, prints_skip_serial 39 | crmove 30, 2 40 | beq PrintS_skip_serial 41 | mfmsr r31 42 | bl serial_io 43 | bl serial_flush 44 | 45 | prints_skip_serial 46 | addi r8, r8, -0x01 47 | 48 | prints_next_char 49 | bl serial_busywait 50 | lbzu r29, 0x0001(r8) 51 | cmpwi r29, 0x00 52 | beq print_common 53 | cmpwi r29, 10 54 | beq PrintS_newline 55 | cmpwi r29, 13 56 | beq PrintS_newline 57 | cmpwi r29, '\\' 58 | beq PrintS_escape_code 59 | cmpwi r29, '^' 60 | bne PrintS_normal_char 61 | 62 | prints_escape_code 63 | lbzu r29, 0x0001(r8) 64 | cmpwi r29, 'n' 65 | beq PrintS_newline 66 | cmpwi r29, 'r' 67 | beq PrintS_newline 68 | cmpwi r29, 'b' 69 | bne PrintS_literal_backslash_or_caret 70 | li r29, 0x07 71 | b PrintS_normal_char 72 | 73 | prints_literal_backslash_or_caret 74 | lbzu r29, -0x0001(r8) 75 | addi r8, r8, 0x01 76 | 77 | prints_normal_char 78 | mr r24, r29 79 | 80 | ; r1 = kdp 81 | bl ScreenConsole_putchar 82 | beq cr7, prints_0xe4 83 | ori r30, r31, 0x10 84 | mtmsr r30 85 | isync 86 | stb r24, 0x0006(r28) 87 | eieio 88 | mtmsr r31 89 | isync 90 | 91 | prints_0xe4 92 | b PrintS_next_char 93 | 94 | prints_newline 95 | li r29, 0x0d 96 | 97 | ; r1 = kdp 98 | bl ScreenConsole_putchar 99 | li r29, 0x0a 100 | 101 | ; r1 = kdp 102 | bl ScreenConsole_putchar 103 | 104 | ; r1 = kdp 105 | bl ScreenConsole_redraw 106 | beq cr7, prints_0x13c 107 | ori r30, r31, 0x10 108 | mtmsr r30 109 | isync 110 | li r29, 0x0d 111 | stb r29, 0x0006(r28) 112 | eieio 113 | 114 | prints_0x118 115 | lbz r29, 0x0002(r28) 116 | eieio 117 | andi. r29, r29, 0x04 118 | beq PrintS_0x118 119 | li r29, 0x0a 120 | stb r29, 0x0006(r28) 121 | eieio 122 | mtmsr r31 123 | isync 124 | 125 | prints_0x13c 126 | b PrintS_next_char 127 | 128 | 129 | 130 | print_common ; OUTSIDE REFERER 131 | beq cr7, print_common_0x8c 132 | mtmsr r31 133 | isync 134 | lwz r29, PSA.DecClockRateHzCopy(r1) 135 | srwi r29, r29, 8 136 | mfspr r30, dec 137 | subf r29, r29, r30 138 | ori r30, r31, 0x10 139 | mtmsr r30 140 | isync 141 | 142 | print_common_0x28 143 | mfspr r30, dec 144 | subf. r30, r29, r30 145 | ble print_common_0x50 146 | li r30, 0x01 147 | stb r30, 0x0002(r28) 148 | eieio 149 | lbz r30, 0x0002(r28) 150 | eieio 151 | andi. r30, r30, 0x01 152 | beq print_common_0x28 153 | 154 | print_common_0x50 155 | sync 156 | mtmsr r31 157 | isync 158 | mfspr r30, pvr 159 | rlwinm. r30, r30, 0, 0, 14 160 | li r31, 0x00 161 | beq print_common_0x78 162 | mtspr dbat3u, r31 163 | mtspr dbat3l, r31 164 | b print_common_0x80 165 | 166 | print_common_0x78 167 | mtspr ibat3l, r31 168 | mtspr ibat3u, r31 169 | 170 | print_common_0x80 171 | isync 172 | mtspr srr0, r26 173 | mtspr srr1, r27 174 | 175 | print_common_0x8c 176 | _AssertAndRelease PSA.DbugLock, scratch=r30 177 | 178 | 179 | 180 | ; print_return 181 | 182 | ; Restores registers from EWA and returns. 183 | 184 | print_return ; OUTSIDE REFERER 185 | mfsprg r1, 0 186 | lwz r24, -0x0110(r1) 187 | lwz r25, -0x010c(r1) 188 | mtlr r24 189 | mtcr r25 190 | lmw r24, -0x0108(r1) 191 | lwz r1, -0x0004(r1) 192 | blr 193 | 194 | 195 | 196 | ; printd 197 | 198 | ; _log decimal 199 | 200 | printd ; OUTSIDE REFERER 201 | mfsprg r1, 0 202 | stmw r24, -0x0108(r1) 203 | mflr r24 204 | mfcr r25 205 | stw r24, -0x0110(r1) 206 | stw r25, -0x010c(r1) 207 | lwz r1, -0x0004(r1) 208 | lwz r28, PSA.NoIdeaR23(r1) 209 | lwz r29, 0x0edc(r1) 210 | 211 | _Lock PSA.DbugLock, scratch1=r30, scratch2=r31 212 | 213 | cmpwi cr7, r28, 0x00 214 | andi. r29, r29, 0x02 215 | beq cr7, printd_0x58 216 | crmove 30, 2 217 | beq Printd_0x58 218 | bl serial_io 219 | bl serial_flush 220 | 221 | printd_0x58 222 | cmpwi r8, 0x00 223 | li r25, 0x2d 224 | blt Printd_0x9c 225 | 226 | printd_0x64 227 | mr. r24, r8 228 | li r25, 0x30 229 | beq Printd_0x9c 230 | lis r24, 0x3b9a 231 | ori r24, r24, 0xca00 232 | 233 | printd_0x78 234 | divw. r25, r8, r24 235 | bne Printd_0x8c 236 | li r25, 0x0a 237 | divw r24, r24, r25 238 | b Printd_0x78 239 | 240 | printd_0x8c 241 | divw r29, r8, r24 242 | addi r25, r29, 0x30 243 | mullw r29, r29, r24 244 | subf r8, r29, r8 245 | 246 | printd_0x9c 247 | bl serial_busywait 248 | mr r29, r25 249 | 250 | ; r1 = kdp 251 | bl ScreenConsole_putchar 252 | beq cr7, printd_0xc8 253 | ori r30, r31, 0x10 254 | mtmsr r30 255 | isync 256 | stb r25, 0x0006(r28) 257 | eieio 258 | mtmsr r31 259 | isync 260 | 261 | printd_0xc8 262 | cmpwi r8, 0x00 263 | bge Printd_0xd8 264 | neg r8, r8 265 | b Printd_0x64 266 | 267 | printd_0xd8 268 | li r25, 0x0a 269 | divw. r24, r24, r25 270 | bne Printd_0x8c 271 | li r29, 0x20 272 | 273 | ; r1 = kdp 274 | bl ScreenConsole_putchar 275 | beq cr7, printd_0x120 276 | ori r30, r31, 0x10 277 | mtmsr r30 278 | isync 279 | 280 | printd_0xfc 281 | lbz r30, 0x0002(r28) 282 | eieio 283 | andi. r30, r30, 0x04 284 | beq Printd_0xfc 285 | li r29, 0x20 286 | stb r29, 0x0006(r28) 287 | eieio 288 | mtmsr r31 289 | isync 290 | 291 | printd_0x120 292 | b print_common 293 | 294 | 295 | 296 | ; printw 297 | 298 | ; _log word (hex) then a space 299 | 300 | printw ; OUTSIDE REFERER 301 | mfsprg r1, 0 302 | stmw r24, -0x0108(r1) 303 | mflr r24 304 | mfcr r25 305 | stw r24, -0x0110(r1) 306 | stw r25, -0x010c(r1) 307 | li r24, 0x08 308 | crset cr6_eq 309 | b print_digity_common 310 | 311 | 312 | 313 | ; printh 314 | 315 | ; _log halfword (hex) then a space 316 | 317 | printh ; OUTSIDE REFERER 318 | mfsprg r1, 0 319 | stmw r24, -0x0108(r1) 320 | mflr r24 321 | mfcr r25 322 | stw r24, -0x0110(r1) 323 | stw r25, -0x010c(r1) 324 | li r24, 0x04 325 | rotlwi r8, r8, 0x10 326 | crset cr6_eq 327 | b print_digity_common 328 | 329 | 330 | 331 | ; printb 332 | 333 | ; _log byte (hex) then a space 334 | 335 | printb ; OUTSIDE REFERER 336 | mfsprg r1, 0 337 | stmw r24, -0x0108(r1) 338 | mflr r24 339 | mfcr r25 340 | stw r24, -0x0110(r1) 341 | stw r25, -0x010c(r1) 342 | li r24, 0x02 343 | rotlwi r8, r8, 0x18 344 | crset cr6_eq 345 | b print_digity_common 346 | 347 | 348 | 349 | print_unknown ; OUTSIDE REFERER 350 | mfsprg r1, 0 351 | stmw r24, -0x0108(r1) 352 | mflr r24 353 | mfcr r25 354 | stw r24, -0x0110(r1) 355 | stw r25, -0x010c(r1) 356 | li r24, 0x02 357 | rotlwi r8, r8, 0x18 358 | crclr cr6_eq 359 | b print_digity_common 360 | 361 | 362 | 363 | print_digity_common ; OUTSIDE REFERER 364 | lwz r1, -0x0004(r1) 365 | lwz r28, PSA.NoIdeaR23(r1) 366 | lwz r29, 0x0edc(r1) 367 | 368 | _Lock PSA.DbugLock, scratch1=r30, scratch2=r31 369 | 370 | cmpwi cr7, r28, 0x00 371 | andi. r29, r29, 0x02 372 | beq cr7, print_digity_common_0x40 373 | crmove 30, 2 374 | beq print_digity_common_0x40 375 | bl serial_io 376 | bl serial_flush 377 | 378 | print_digity_common_0x40 379 | bl serial_busywait 380 | li r25, 0x30 381 | rlwimi r25, r8, 4, 28, 31 382 | rotlwi r8, r8, 0x04 383 | cmpwi r25, 0x39 384 | ble print_digity_common_0x5c 385 | addi r25, r25, 0x27 386 | 387 | print_digity_common_0x5c 388 | mr r29, r25 389 | 390 | ; r1 = kdp 391 | bl ScreenConsole_putchar 392 | beq cr7, print_digity_common_0x84 393 | ori r30, r31, 0x10 394 | mtmsr r30 395 | isync 396 | stb r25, 0x0006(r28) 397 | eieio 398 | mtmsr r31 399 | isync 400 | 401 | print_digity_common_0x84 402 | addi r24, r24, -0x01 403 | mr. r24, r24 404 | bne print_digity_common_0x40 405 | bne cr6, print_digity_common_0xd0 406 | li r29, 0x20 407 | 408 | ; r1 = kdp 409 | bl ScreenConsole_putchar 410 | beq cr7, print_digity_common_0xd0 411 | ori r30, r31, 0x10 412 | mtmsr r30 413 | isync 414 | 415 | print_digity_common_0xac 416 | lbz r30, 0x0002(r28) 417 | eieio 418 | andi. r30, r30, 0x04 419 | beq print_digity_common_0xac 420 | li r29, 0x20 421 | stb r29, 0x0006(r28) 422 | eieio 423 | mtmsr r31 424 | isync 425 | 426 | print_digity_common_0xd0 427 | b print_common 428 | 429 | 430 | 431 | getchar ; OUTSIDE REFERER 432 | mfsprg r1, 0 433 | stmw r24, -0x0108(r1) 434 | mflr r24 435 | mfcr r25 436 | stw r24, -0x0110(r1) 437 | stw r25, -0x010c(r1) 438 | 439 | lwz r1, EWA.PA_KDP(r1) 440 | lwz r28, PSA.NoIdeaR23(r1) 441 | cmpwi cr7, r28, 0x00 442 | li r8, -0x01 443 | beq cr7, print_return 444 | 445 | _Lock PSA.DbugLock, scratch1=r30, scratch2=r31 446 | 447 | bl serial_io 448 | ori r30, r31, 0x10 449 | mtmsr r30 450 | isync 451 | lbz r30, 0x0002(r28) 452 | eieio 453 | andi. r30, r30, 0x01 454 | beq print_common 455 | lbz r8, 0x0006(r28) 456 | b print_common 457 | 458 | 459 | 460 | ; printc 461 | 462 | ; _log char 463 | 464 | printc ; OUTSIDE REFERER 465 | mfsprg r1, 0 466 | stmw r24, -0x0108(r1) 467 | mflr r24 468 | mfcr r25 469 | stw r24, -0x0110(r1) 470 | stw r25, -0x010c(r1) 471 | lwz r1, -0x0004(r1) 472 | lwz r28, PSA.NoIdeaR23(r1) 473 | lwz r29, 0x0edc(r1) 474 | 475 | _Lock PSA.DbugLock, scratch1=r30, scratch2=r31 476 | 477 | cmpwi cr7, r28, 0x00 478 | andi. r29, r29, 0x02 479 | beq cr7, printc_0x58 480 | crmove 30, 2 481 | beq Printc_0x58 482 | bl serial_io 483 | bl serial_flush 484 | 485 | printc_0x58 486 | mr r29, r8 487 | 488 | ; r1 = kdp 489 | bl ScreenConsole_putchar 490 | beq cr7, printc_0x90 491 | ori r30, r31, 0x10 492 | mtmsr r30 493 | isync 494 | 495 | printc_0x70 496 | lbz r30, 0x0002(r28) 497 | eieio 498 | andi. r30, r30, 0x04 499 | beq Printc_0x70 500 | stb r8, 0x0006(r28) 501 | eieio 502 | mtmsr r31 503 | isync 504 | 505 | printc_0x90 506 | b print_common 507 | 508 | 509 | 510 | ; serial_flush 511 | 512 | ; This and the following func are a bit speculative, but 513 | ; whatever. 514 | 515 | ; Whoa. Turns on data but not code paging. Crikey. 516 | 517 | serial_flush ; OUTSIDE REFERER 518 | ori r30, r31, MSR_DR 519 | mtmsr r30 520 | isync 521 | lbz r29, 0x0002(r28);make sure next write goes to command register 522 | li r29, 0x09 523 | stb r29, 0x0002(r28);set register pointer to 9 (next write goes to WR9) 524 | eieio 525 | li r29, 0x80;load code for channel A (also disables interrupts) 526 | stb r29, 0x0002(r28);reset channel A 527 | eieio 528 | lbz r29, 0x0002(r28);make sure next write goes to command register 529 | li r29, 0x04 530 | stb r29, 0x0002(r28);set register pointer to 4 (next write goes to WR4) 531 | eieio 532 | li r29, 0x48;X16 clock, 8-bit sync, 1.5 stop bits, parity off 533 | stb r29, 0x0002(r28) 534 | eieio 535 | lbz r29, 0x0002(r28);make sure next write goes to command register 536 | li r29, 0x03 537 | stb r29, 0x0002(r28);set reg pointer to 3 (next write to WR3) 538 | eieio 539 | li r29, 0xc0;recieve 8 bits per character (but recieve off) 540 | stb r29, 0x0002(r28) 541 | eieio 542 | lbz r29, 0x0002(r28);make sure next write goes to command register 543 | li r29, 0x05 544 | stb r29, 0x0002(r28);set reg pointer to 5 (next write to WR5) 545 | eieio 546 | li r29, 0x60;transmit 8 bits per char (but transmit off) 547 | stb r29, 0x0002(r28) 548 | eieio 549 | lbz r29, 0x0002(r28);make sure next write goes to command register 550 | li r29, 0x09 551 | stb r29, 0x0002(r28);set reg pointer to 9 (next write to WR9) 552 | eieio 553 | li r29, 0x00 554 | stb r29, 0x0002(r28);stop channel A reset? 555 | eieio 556 | lbz r29, 0x0002(r28);make sure next write goes to command register 557 | li r29, 0x0a 558 | stb r29, 0x0002(r28);set reg pointer to 10 (next write to WR10) 559 | eieio 560 | li r29, 0x00;8-bit sync, NRZ encoding 561 | stb r29, 0x0002(r28) 562 | eieio 563 | lbz r29, 0x0002(r28);make sure next write goes to command register 564 | li r29, 0x0b 565 | stb r29, 0x0002(r28);set reg pointer to 11 (next write to WR11) 566 | eieio 567 | li r29, 0x50;rx and tx using BR Generator 568 | stb r29, 0x0002(r28) 569 | eieio 570 | lbz r29, 0x0002(r28);make sure next write goes to command register 571 | li r29, 0x0c 572 | stb r29, 0x0002(r28);set reg pointer to 12 (next write to WR12) 573 | eieio 574 | li r29, 0x00;0 time constant low byte 575 | stb r29, 0x0002(r28) 576 | eieio 577 | lbz r29, 0x0002(r28);make sure next write goes to command register 578 | li r29, 0x0d 579 | stb r29, 0x0002(r28);set reg pointer to 13 (next write to WR13) 580 | eieio 581 | li r29, 0x00;0 time constant high byte 582 | stb r29, 0x0002(r28) 583 | eieio 584 | lbz r29, 0x0002(r28);make sure next write goes to command register 585 | li r29, 0x0e 586 | stb r29, 0x0002(r28);set reg pointer to 14 (next write to WR14) 587 | eieio 588 | li r29, 0x01;enable Baud Rate generator 589 | stb r29, 0x0002(r28) 590 | eieio 591 | lbz r29, 0x0002(r28);make sure next write goes to command register 592 | li r29, 0x03 593 | stb r29, 0x0002(r28);set reg pointer to 3 (next write to WR3) 594 | eieio 595 | li r29, 0xc1;enable reciever 596 | stb r29, 0x0002(r28) 597 | eieio 598 | lbz r29, 0x0002(r28);make sure next write goes to command register 599 | li r29, 0x05 600 | stb r29, 0x0002(r28);set reg pointer to 5 (next write to WR5) 601 | eieio 602 | li r29, 0xea;assert DTR and RTS, set 8 bit characters, and enable transmitter 603 | stb r29, 0x0002(r28) 604 | eieio 605 | mtmsr r31 ;restore previous MSR 606 | isync 607 | blr 608 | 609 | 610 | 611 | ; serial_io 612 | ;appears to set BAT 3 so the scc can be accessed from logical memory space. 613 | 614 | serial_io ; OUTSIDE REFERER 615 | mfspr r26, srr0 616 | mfspr r27, srr1 617 | isync 618 | mfspr r30, pvr 619 | rlwinm. r30, r30, 0, 0, 14 620 | rlwinm r29, r28, 0, 0, 14 621 | beq serial_io_0x38 622 | li r30, 0x03 623 | or r30, r30, r29 624 | li r31, 0x3a 625 | or r31, r31, r29 626 | mtspr dbat3l, r31 627 | mtspr dbat3u, r30 628 | b serial_io_0x50 629 | 630 | serial_io_0x38 631 | li r30, 0x32 632 | or r30, r30, r29 633 | li r31, 0x40 634 | or r31, r31, r29 635 | mtspr ibat3u, r30 636 | mtspr ibat3l, r31 637 | 638 | serial_io_0x50 639 | isync 640 | mfmsr r31 641 | blr 642 | 643 | 644 | 645 | ; serial_busywait 646 | 647 | ; See disclaimer above. 648 | 649 | serial_busywait ; OUTSIDE 650 | beqlr cr7 651 | ori r30, r31, 0x10 652 | mtmsr r30 653 | isync 654 | 655 | serial_busywait_0x10 656 | lbz r30, 0x0002(r28) 657 | eieio 658 | andi. r30, r30, 0x04 659 | beq serial_busywait_0x10 660 | mtmsr r31 661 | isync 662 | blr 663 | -------------------------------------------------------------------------------- /NanoKernel/NKSleep.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKInterrupts 4 | ; SIGP 5 | ; NKMPCalls 6 | ; CommonMPCallReturnPath 7 | ; ReturnMPCallOOM 8 | ; ReturnParamErrFromMPCall 9 | ; ReturnZeroFromMPCall 10 | ; NKPaging 11 | ; PagingFlushTLB 12 | ; PagingFunc2AndAHalf 13 | ; PagingL2PWithBATs 14 | ; NKScheduler 15 | ; Save_f0_f31 16 | ; Save_v0_v31 17 | ; SchSwitchSpace 18 | ; NKThud 19 | ; panic 20 | 21 | 22 | ; Implements two MPCalls that seem to have something to do with COHGs 23 | 24 | 25 | 26 | ; Make conditional calls easier 27 | Local_Panic set * 28 | b panic 29 | 30 | Local_ReturnParamErrFromMPCall 31 | b ReturnParamErrFromMPCall 32 | 33 | Local_ReturnInsufficientResourcesErrFromMPCall 34 | b ReturnMPCallOOM 35 | 36 | Local_CommonMPCallReturnPath 37 | b CommonMPCallReturnPath 38 | 39 | 40 | 41 | ; RET OSStatus r3, something r4, something r4 42 | 43 | DeclareMPCall 102, MPGetKernelStateSize 44 | 45 | MPGetKernelStateSize 46 | 47 | mfsprg r9, 0 48 | 49 | lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) 50 | lwz r9, CoherenceGroup.ScheduledCpuCount(r8) 51 | cmpwi r9, 1 52 | bgt Local_ReturnInsufficientResourcesErrFromMPCall 53 | 54 | bl KernelStateSize 55 | 56 | mr r4, r8 57 | mr r5, r9 58 | 59 | b ReturnZeroFromMPCall 60 | 61 | 62 | 63 | ; ARG r3/r4/r5 64 | ; RET OSStatus r3 65 | 66 | DeclareMPCall 103, MPGetKernelState 67 | 68 | MPGetKernelState 69 | 70 | mfsprg r9, 0 71 | lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) 72 | lwz r9, CoherenceGroup.ScheduledCpuCount(r8) 73 | cmpwi r9, 1 74 | bgt Local_ReturnInsufficientResourcesErrFromMPCall 75 | 76 | clrlwi. r8, r5, 20 77 | bne Local_ReturnParamErrFromMPCall 78 | 79 | bl KernelStateSize 80 | cmpw r3, r8 81 | blt Local_ReturnParamErrFromMPCall 82 | cmpw r4, r9 83 | blt Local_ReturnParamErrFromMPCall 84 | 85 | bl PagingFlushTLB 86 | mfsprg r9, 0 87 | mfxer r8 88 | stw r13, 0x00dc(r6) 89 | stw r8, 0x00d4(r6) 90 | stw r12, 0x00ec(r6) 91 | mfctr r8 92 | stw r10, 0x00fc(r6) 93 | stw r8, 0x00f4(r6) 94 | 95 | mfpvr r8 96 | rlwinm. r8, r8, 0, 0, 14 97 | bne @not_601 98 | mfspr r8, mq 99 | stw r8, ContextBlock.MQ(r6) 100 | @not_601 101 | 102 | lwz r8, EWA.r1(r9) 103 | stw r8, ContextBlock.r1(r6) 104 | stw r2, ContextBlock.r2(r6) 105 | stw r3, ContextBlock.r3(r6) 106 | andi. r8, r11, MSR_FP 107 | stw r4, ContextBlock.r4(r6) 108 | lwz r8, EWA.r6(r9) 109 | stw r5, ContextBlock.r5(r6) 110 | stw r8, ContextBlock.r6(r6) 111 | bnel Save_f0_f31 112 | rlwinm. r8, r7, 0, EWA.kFlagVec, EWA.kFlagVec ; flags 113 | bnel+ Save_v0_v31 114 | 115 | lwz r3, ContextBlock.r3(r6) 116 | lwz r4, ContextBlock.r4(r6) 117 | lwz r5, ContextBlock.r5(r6) 118 | 119 | stw r11,ContextBlock.MSR(r6) 120 | mr r27, r5 121 | addi r29, r1, KDP.BATs + 0xa0 122 | bl PagingL2PWithBATs 123 | beq Local_ReturnInsufficientResourcesErrFromMPCall 124 | rlwimi r27, r31, 0, 0, 19 125 | mr r17, r27 126 | addi r15, r17, 0x34 127 | srwi r3, r3, 12 128 | 129 | MPGetKernelState_0xc8 130 | mr r27, r5 131 | addi r29, r1, KDP.BATs + 0xa0 132 | bl PagingL2PWithBATs 133 | beq Local_ReturnInsufficientResourcesErrFromMPCall 134 | rlwimi r27, r31, 0, 0, 19 135 | stwu r27, 0x0004(r15) 136 | addi r3, r3, -0x01 137 | addi r5, r5, 0x1000 138 | cmpwi r3, 0x00 139 | bge MPGetKernelState_0xc8 140 | addi r15, r15, 0x04 141 | subf r15, r17, r15 142 | stw r15, 0x0034(r17) 143 | mfsprg r15, 0 144 | stw r15, 0x0024(r17) 145 | mfsprg r8, 3 146 | stw r8, 0x0028(r17) 147 | 148 | @retry_time 149 | mftbu r8 150 | mftb r9 151 | mftbu r16 152 | cmpw r16, r8 153 | bne- @retry_time 154 | 155 | stw r8, EWA.SpacesSavedLR(r15) 156 | stw r9, EWA.SpacesSavedCR(r15) 157 | 158 | mr r29, r17 159 | li r16, kSIGP6 160 | stw r16, EWA.SIGPSelector(r15) 161 | lhz r16, EWA.CPUIndex(r15) 162 | stw r16, EWA.SIGPCallR4(r15) 163 | li r8, 2 ; args in EWA 164 | bl SIGP 165 | mr r17, r29 166 | mfsdr1 r8 167 | stw r8, 0x002c(r17) 168 | rlwinm r9, r8, 16, 7, 15 169 | cntlzw r18, r9 170 | li r9, -0x01 171 | srw r9, r9, r18 172 | addi r9, r9, 0x01 173 | stw r9, 0x000c(r17) 174 | rlwinm r8, r8, 0, 0, 15 175 | stw r8, 0x0010(r17) 176 | lis r8, 0x00 177 | ori r8, r8, 0xc000 178 | stw r8, 0x0018(r17) 179 | lis r9, 0x00 180 | ori r9, r9, 0xa000 181 | subf r8, r9, r1 182 | stw r8, 0x001c(r17) 183 | addi r9, r1, 120 184 | lis r31, 0x00 185 | li r14, 0x00 186 | lwz r29, 0x0034(r17) 187 | add r29, r29, r17 188 | 189 | MPGetKernelState_0x1a0 190 | lwzu r30, 0x0008(r9) 191 | 192 | MPGetKernelState_0x1a4 193 | lwz r18, 0x0004(r30) 194 | lhz r15, 0x0000(r30) 195 | andi. r19, r18, 0xe00 196 | lhz r16, 0x0002(r30) 197 | cmplwi r19, 0xc00 198 | bne MPGetKernelState_0x1dc 199 | addi r16, r16, 0x01 200 | slwi r16, r16, 2 201 | stw r16, 0x0000(r29) 202 | rlwinm r18, r18, 22, 0, 29 203 | stw r18, 0x0004(r29) 204 | addi r29, r29, 0x0c 205 | addi r14, r14, 0x01 206 | b MPGetKernelState_0x1fc 207 | 208 | MPGetKernelState_0x1dc 209 | cmpwi r15, 0x00 210 | bne MPGetKernelState_0x1fc 211 | cmplwi r16, 0xffff 212 | bne MPGetKernelState_0x1fc 213 | addis r31, r31, 0x1000 214 | cmpwi r31, 0x00 215 | bne MPGetKernelState_0x1a0 216 | b MPGetKernelState_0x204 217 | 218 | MPGetKernelState_0x1fc 219 | addi r30, r30, 0x08 220 | b MPGetKernelState_0x1a4 221 | 222 | MPGetKernelState_0x204 223 | lwz r16, PSA.FirstPoolSeg(r1) 224 | 225 | MPGetKernelState_0x208 226 | lwz r31, 0x0000(r16) 227 | add r18, r31, r16 228 | lwz r19, 0x0000(r18) 229 | addi r31, r31, 0x18 230 | stw r31, 0x0000(r29) 231 | stw r16, 0x0004(r29) 232 | addi r29, r29, 0x0c 233 | addi r14, r14, 0x01 234 | cmpwi r19, 0x00 235 | beq MPGetKernelState_0x238 236 | add r16, r19, r18 237 | b MPGetKernelState_0x208 238 | 239 | MPGetKernelState_0x238 240 | addi r19, r1, PSA.FreeList 241 | lwz r31, PSA.FreeList + LLL.Next(r1) 242 | 243 | MPGetKernelState_0x240 244 | cmpw r31, r19 245 | beq MPGetKernelState_0x264 246 | li r18, 0x10 247 | stw r18, 0x0000(r29) 248 | stw r31, 0x0004(r29) 249 | addi r29, r29, 0x0c 250 | addi r14, r14, 0x01 251 | lwz r31, 0x0008(r31) 252 | b MPGetKernelState_0x240 253 | 254 | MPGetKernelState_0x264 255 | stw r14, 0x0030(r17) 256 | lwz r30, 0x0034(r17) 257 | add r30, r30, r17 258 | 259 | MPGetKernelState_0x270 260 | subf r8, r17, r29 261 | stw r8, 0x0008(r30) 262 | lwz r24, 0x0004(r30) 263 | mr r25, r8 264 | lwz r26, 0x0000(r30) 265 | add r29, r29, r26 266 | bl AnotherCoherenceFunc 267 | addi r30, r30, 0x0c 268 | addi r14, r14, -0x01 269 | cmpwi r14, 0x00 270 | bne MPGetKernelState_0x270 271 | subf r8, r17, r29 272 | stw r8, 0x0020(r17) 273 | lwz r24, 0x001c(r17) 274 | mr r25, r8 275 | lwz r26, 0x0018(r17) 276 | add r29, r29, r26 277 | bl AnotherCoherenceFunc 278 | subf r8, r17, r29 279 | stw r8, 0x0014(r17) 280 | lwz r24, 0x0010(r17) 281 | mr r25, r8 282 | lwz r26, 0x000c(r17) 283 | add r29, r29, r26 284 | bl AnotherCoherenceFunc 285 | bl LoadStateRestoreFunc 286 | mflr r9 287 | stw r9, 0x0000(r17) 288 | lwz r8, PSA.NoIdeaR23(r1) 289 | stw r8, 0x0008(r17) 290 | li r8, 0x00 291 | stw r8, 0x0004(r17) 292 | 293 | mfsprg r15, 0 294 | li r16, kSIGP17 295 | stw r16, EWA.SIGPSelector(r15) 296 | lhz r16, EWA.CPUIndex(r15) 297 | stw r16, EWA.SIGPCallR4(r15) 298 | li r8, 2 ; args in EWA 299 | bl SIGP 300 | 301 | li r3, 0 302 | b Local_CommonMPCallReturnPath 303 | 304 | 305 | 306 | LoadStateRestoreFunc 307 | blrl 308 | 309 | mr r17, r3 310 | lwz r24, 0x0014(r17) 311 | lwz r25, 0x0010(r17) 312 | lwz r26, 0x000c(r17) 313 | bl YetAnotherCoherenceFunc 314 | lwz r24, 0x002c(r17) 315 | mtsdr1 r24 316 | lwz r24, 0x0020(r17) 317 | lwz r25, 0x001c(r17) 318 | lwz r26, 0x0018(r17) 319 | bl YetAnotherCoherenceFunc 320 | lwz r14, 0x0030(r17) 321 | lwz r30, 0x0034(r17) 322 | add r30, r30, r17 323 | 324 | RestoreKernelState_0x38 325 | lwz r24, 0x0008(r30) 326 | lwz r25, 0x0004(r30) 327 | lwz r26, 0x0000(r30) 328 | bl YetAnotherCoherenceFunc 329 | addi r30, r30, 0x0c 330 | addi r14, r14, -0x01 331 | cmpwi r14, 0x00 332 | bne RestoreKernelState_0x38 333 | lwz r16, 0x0024(r17) 334 | mtsprg 0, r16 335 | lwz r8, 0x0028(r17) 336 | mtsprg 3, r8 337 | lwz r1, -0x0004(r16) 338 | lwz r6, -0x0014(r16) 339 | lwz r7, -0x0010(r16) 340 | li r8, -0x01 341 | stw r8, 0x0004(r17) 342 | 343 | lwz r8, EWA.SpacesSavedLR(r16) 344 | lwz r9, EWA.SpacesSavedCR(r16) 345 | li r16, 0x01 346 | mttb r16 347 | mttbu r8 348 | mttb r9 349 | mtdec r16 350 | 351 | _log 'Resuming saved kernel state^n' 352 | 353 | lwz r8, 0x00d4(r6) 354 | lwz r13, 0x00dc(r6) 355 | mtxer r8 356 | lwz r12, 0x00ec(r6) 357 | lwz r8, 0x00f4(r6) 358 | lwz r10, 0x00fc(r6) 359 | mtctr r8 360 | lwz r11, 0x00a4(r6) 361 | 362 | mfpvr r8 363 | rlwinm. r8, r8, 0, 0, 14 364 | bne RestoreKernelState_0xf8 365 | lwz r8, 0x00c4(r6) 366 | DIALECT POWER 367 | mtmq r8 368 | DIALECT PowerPC 369 | RestoreKernelState_0xf8 370 | 371 | lwz r4, -0x0020(r1) 372 | li r2, 0x01 373 | sth r2, 0x0910(r1) 374 | li r2, -0x01 375 | stw r2, 0x0912(r1) 376 | stw r2, 0x0f90(r4) 377 | xoris r2, r2, 0x100 378 | stw r2, 0x0f8c(r4) 379 | li r2, 0x00 380 | stw r2, 0x0f28(r4) 381 | stw r2, 0x0f2c(r4) 382 | lwz r2, 0x0114(r6) 383 | lwz r4, 0x0124(r6) 384 | lwz r5, 0x012c(r6) 385 | lwz r29, 0x00d8(r6) 386 | cmpwi r29, 0x00 387 | lwz r8, 0x0210(r29) 388 | beq RestoreKernelState_0x144 389 | mtspr vrsave, r8 390 | 391 | RestoreKernelState_0x144 392 | bl PagingFlushTLB 393 | addi r29, r1, 0x5e0 394 | bl PagingFunc2AndAHalf 395 | mfsprg r15, 0 396 | lwz r8, -0x001c(r15) 397 | li r9, 0x00 398 | bl SchSwitchSpace 399 | isync 400 | 401 | mfsprg r15, 0 402 | li r16, kSIGP7 403 | stw r16, EWA.SIGPSelector(r15) 404 | lhz r16, EWA.CPUIndex(r15) 405 | stw r16, EWA.SIGPCallR4(r15) 406 | li r8, 2 ; args in EWA 407 | bl SIGP 408 | 409 | mfsprg r15, 0 410 | li r16, kSIGP17 411 | stw r16, EWA.SIGPSelector(r15) 412 | lhz r16, EWA.CPUIndex(r15) 413 | stw r16, EWA.SIGPCallR4(r15) 414 | li r8, 2 ; args in EWA 415 | bl SIGP 416 | 417 | li r3, 0 418 | b Local_CommonMPCallReturnPath 419 | 420 | 421 | 422 | ; RET r8/r9 423 | 424 | KernelStateSize 425 | 426 | ; Counter 427 | 428 | li r24, 0 429 | 430 | 431 | ; Start with hash table 432 | ; Also inits counter r8 (bytes!) 433 | 434 | mfsdr1 r16 435 | rlwinm r16, r16, 16, 7, 15 436 | cntlzw r17, r16 437 | li r16, -1 438 | srw r16, r16, r17 439 | addi r8, r16, 1 440 | 441 | 442 | 443 | 444 | addi r9, r1, KDP.SegMaps - 8 445 | lis r31, 0 ; segment address counter 446 | li r19, 0 ; page counter (to use later) 447 | li r14, 0 ; entry counter (to use later) 448 | 449 | @next_segment 450 | lwzu r17, 8(r9) 451 | 452 | @next_entry 453 | lwz r18, PMDT.PBaseAndFlags(r17) ; PhysicalPage(20b) || pageAttr(12b) 454 | lhz r15, PMDT.LBase(r17) ; LogicalPageIndexInSegment(16b) 455 | 456 | ; Same as usual: if 457 | andi. r18, r18, PMDT.TopFieldMask ; r18 = 3b field at top of pageAttr 458 | lhz r16, PMDT.PageCount(r17) ; PageCountMinus1(16b) 459 | cmplwi r18, PMDT.DaddyFlag | PMDT.CountingFlag 460 | bne @entry_seems_blank 461 | 462 | addi r16, r16, 1 463 | add r19, r19, r16 464 | addi r14, r14, 1 465 | b @continue_next_entry 466 | @entry_seems_blank 467 | 468 | cmpwi r15, 0 ; if not full-segment, might not be blank? 469 | bne @continue_next_entry 470 | cmplwi r16, 0xffff 471 | bne @continue_next_entry 472 | 473 | ; This is the "normal" way to loop to the next segment 474 | addis r31, r31, 0x1000 475 | cmpwi r31, 0 476 | bne @next_segment 477 | b @exit 478 | 479 | @continue_next_entry 480 | addi r17, r17, 8 481 | b @next_entry 482 | @exit 483 | 484 | 485 | 486 | 487 | slwi r19, r19, 2 ; 4 bytes per mapped page 488 | add r8, r8, r19 489 | 490 | cmpwi r14, 0x00 ; no entries? fail! 491 | beq Local_ReturnInsufficientResourcesErrFromMPCall 492 | mulli r9, r14, 12 493 | add r8, r8, r9 ; 12 bytes per SegMap entry 494 | 495 | add r24, r24, r9 ; also in the secondary counter? 496 | 497 | 498 | ; Count pool segments 499 | 500 | li r9, 0 ; total size of pool segments 501 | li r14, 0 ; count of pool segments 502 | lwz r16, PSA.FirstPoolSeg(r1) ; current pool segment 503 | 504 | @next_pool_segment 505 | lwz r17, Block.OffsetToNext(r16) ; of Begin block 506 | add r18, r17, r16 507 | lwz r19, Block.OffsetToNext(r18) ; of End block 508 | 509 | add r9, r9, r17 510 | addi r9, r9, Block.kEndSize 511 | 512 | addi r14, r14, 1 513 | 514 | cmpwi r19, 0 ; last segment? 515 | add r16, r19, r18 516 | beq @exit_pool_counter 517 | b @next_pool_segment ; odd... what happened here? 518 | @exit_pool_counter 519 | 520 | 521 | ; Count pages in the system free list 522 | 523 | addi r16, r1, PSA.FreeList 524 | lwz r18, PSA.FreeList + LLL.Next(r1) 525 | 526 | @next_page_in_freelist 527 | cmpw r18, r16 528 | beq @exit_freelist_counter 529 | addi r9, r9, 16 530 | addi r14, r14, 1 531 | lwz r18, LLL.Next(r18) 532 | b @next_page_in_freelist 533 | @exit_freelist_counter 534 | 535 | 536 | add r8, r8, r9 ; byte counter 537 | mulli r9, r14, 12 ; 12 bytes per thing 538 | add r8, r8, r9 539 | add r24, r24, r9 540 | 541 | lisori r9, 0xc000 542 | add r8, r8, r9 543 | 544 | lisori r9, 0x3c 545 | add r8, r8, r9 546 | add r24, r24, r9 547 | srwi r9, r8, 12 548 | slwi r9, r9, 2 549 | addi r9, r9, 4 550 | add r8, r8, r9 551 | add r24, r24, r9 552 | mr r9, r24 553 | blr 554 | 555 | 556 | CoherenceFunc_0x138 ; OUTSIDE REFERER 557 | srwi r23, r28, 12 558 | slwi r23, r23, 2 559 | add r23, r23, r17 560 | lwz r23, 0x0038(r23) 561 | rlwimi r23, r28, 0, 20, 31 562 | blr 563 | 564 | 565 | 566 | AnotherCoherenceFunc ; OUTSIDE REFERER 567 | cmpwi r26, 0x00 568 | beqlr 569 | mflr r22 570 | addi r24, r24, -0x01 571 | mr r28, r25 572 | 573 | AnotherCoherenceFunc_0x14 574 | bl CoherenceFunc_0x138 575 | clrlwi r25, r23, 0x14 576 | subfic r25, r25, 0x1000 577 | cmplw r25, r26 578 | blt AnotherCoherenceFunc_0x2c 579 | mr r25, r26 580 | 581 | AnotherCoherenceFunc_0x2c 582 | mr r19, r23 583 | mr r20, r25 584 | addi r23, r23, -0x01 585 | mtctr r25 586 | 587 | AnotherCoherenceFunc_0x3c 588 | lbzu r27, 0x0001(r24) 589 | stbu r27, 0x0001(r23) 590 | bdnz AnotherCoherenceFunc_0x3c 591 | bl YetAnotherCoherenceFunc_0x64 592 | subf r26, r25, r26 593 | add r28, r28, r25 594 | cmpwi r26, 0x00 595 | bne AnotherCoherenceFunc_0x14 596 | mtlr r22 597 | blr 598 | 599 | 600 | 601 | YetAnotherCoherenceFunc ; OUTSIDE REFERER 602 | cmpwi r26, 0x00 603 | beqlr 604 | mr r19, r25 605 | mr r20, r26 606 | mflr r22 607 | addi r25, r25, -0x01 608 | mr r28, r24 609 | 610 | YetAnotherCoherenceFunc_0x1c 611 | bl CoherenceFunc_0x138 612 | clrlwi r24, r23, 0x14 613 | subfic r24, r24, 0x1000 614 | cmplw r24, r26 615 | blt YetAnotherCoherenceFunc_0x34 616 | mr r24, r26 617 | 618 | YetAnotherCoherenceFunc_0x34 619 | addi r23, r23, -0x01 620 | mtctr r24 621 | 622 | YetAnotherCoherenceFunc_0x3c 623 | lbzu r27, 0x0001(r23) 624 | stbu r27, 0x0001(r25) 625 | bdnz YetAnotherCoherenceFunc_0x3c 626 | add r28, r28, r24 627 | subf r26, r24, r26 628 | cmpwi r26, 0x00 629 | bne YetAnotherCoherenceFunc_0x1c 630 | bl YetAnotherCoherenceFunc_0x64 631 | mtlr r22 632 | blr 633 | 634 | YetAnotherCoherenceFunc_0x64 ; OUTSIDE REFERER 635 | sync 636 | isync 637 | lhz r21, 0x0f4a(r1) 638 | addi r15, r21, -0x01 639 | add r20, r19, r20 640 | add r20, r20, r15 641 | neg r15, r21 642 | and r19, r19, r15 643 | and r20, r20, r15 644 | 645 | YetAnotherCoherenceFunc_0x88 646 | dcbst 0, r19 647 | sync 648 | icbi 0, r19 649 | add r19, r19, r21 650 | cmpw r19, r20 651 | blt YetAnotherCoherenceFunc_0x88 652 | sync 653 | isync 654 | blr 655 | -------------------------------------------------------------------------------- /NanoKernel/NKPaging.s: -------------------------------------------------------------------------------- 1 | Local_Panic set * 2 | b panic 3 | 4 | 5 | 6 | ; AUTO-GENERATED SYMBOL LIST 7 | ; IMPORTS: 8 | ; NKAddressSpaces 9 | ; FindAreaAbove 10 | ; MPCall_95_0x254 11 | ; SpaceGetPagePLE 12 | ; NKConsoleLog 13 | ; printw 14 | ; NKThud 15 | ; panic 16 | ; EXPORTS: 17 | ; PagingFlushTLB (=> NKInit, NKScheduler, NKSleep) 18 | ; PagingFunc1 (=> NKInit, NKInterrupts, NKThud, NKVMCalls) 19 | ; PagingFunc2 (=> NKInit) 20 | ; PagingFunc2AndAHalf (=> NKSleep) 21 | ; PagingL2PWithBATs (=> NKInterrupts, NKMPCalls, NKRTASCalls, NKSleep) 22 | ; PagingL2PWithoutBATs (=> NKInit, NKScreenConsole, NKThud) 23 | 24 | 25 | 26 | align 5 27 | 28 | PagingFunc1 ; OUTSIDE REFERER 29 | mfsprg r29, 0 30 | mflr r28 31 | stw r8, -0x00dc(r29) 32 | mfcr r8 33 | stw r9, -0x00d8(r29) 34 | stw r8, -0x00a4(r29) 35 | stw r14, -0x00d4(r29) 36 | stw r15, -0x00d0(r29) 37 | stw r16, -0x00cc(r29) 38 | stw r17, -0x00c8(r29) 39 | stw r18, -0x00c4(r29) 40 | stw r19, -0x00c0(r29) 41 | stw r20, -0x00bc(r29) 42 | stw r21, -0x00b8(r29) 43 | stw r22, -0x00b4(r29) 44 | stw r28, -0x00e0(r29) 45 | b @_88 46 | 47 | @_44 48 | mfsprg r29, 0 49 | lwz r8, -0x00a4(r29) 50 | lwz r28, -0x00e0(r29) 51 | mtcrf 0x7f, r8 52 | lwz r8, -0x00dc(r29) 53 | mtlr r28 54 | lwz r9, -0x00d8(r29) 55 | lwz r14, -0x00d4(r29) 56 | lwz r15, -0x00d0(r29) 57 | lwz r16, -0x00cc(r29) 58 | lwz r17, -0x00c8(r29) 59 | lwz r18, -0x00c4(r29) 60 | lwz r19, -0x00c0(r29) 61 | lwz r20, -0x00bc(r29) 62 | lwz r21, -0x00b8(r29) 63 | lwz r22, -0x00b4(r29) 64 | blr 65 | 66 | @_88 67 | mfsprg r30, 0 68 | mr r9, r27 69 | lwz r8, -0x001c(r30) 70 | bl FindAreaAbove 71 | mr r31, r8 72 | stw r8, EWA.SpecialAreaPtr(r30) 73 | stw r27, -0x00e8(r30) 74 | lwz r16, 0x0024(r31) 75 | lwz r17, 0x0020(r31) 76 | cmplw r16, r27 77 | lwz r18, 0x007c(r31) 78 | bgt @_1a0 79 | bgt @_44 80 | and r28, r27, r18 81 | rlwinm. r26, r17, 0, 16, 16 82 | lwz r17, 0x0038(r31) 83 | beq @_fc 84 | lwz r18, 0x0070(r31) 85 | subf r19, r16, r28 86 | clrlwi r31, r18, 0x1e 87 | cmpwi cr7, r17, -0x01 88 | cmpwi cr6, r31, 0x00 89 | beq cr7, @_1a0 90 | beq cr6, @_44 91 | cmpwi r17, 0x01 92 | add r31, r18, r19 93 | blt @_44 94 | li r26, 0x00 95 | b @_208 96 | 97 | @_fc 98 | mr r8, r27 99 | bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq 100 | lwz r28, 0x0000(r30) 101 | mr r26, r30 102 | mr r8, r27 103 | bl MPCall_95_0x254 104 | beq @_12c 105 | lhz r16, 0x0000(r30) 106 | rlwinm. r8, r16, 0, 16, 16 107 | bne @_12c 108 | srwi r16, r16, 1 109 | sth r16, 0x0000(r30) 110 | 111 | @_12c 112 | lwz r8, 0x0024(r31) 113 | lwz r9, 0x06b4(r1) 114 | cmpwi r8, 0x00 115 | cmpwi cr6, r9, 0x00 116 | li r8, 0x801 117 | li r9, 0x01 118 | bne @_154 119 | beq cr6, @_154 120 | li r8, 0x881 121 | li r9, 0x81 122 | 123 | @_154 124 | lwz r31, 0x0688(r1) 125 | and. r30, r28, r8 126 | rlwimi r31, r28, 0, 0, 19 127 | cmplwi cr6, r30, 0x800 128 | cmplwi r30, 0x01 129 | bge cr6, @_2ec 130 | cmplw cr7, r30, r9 131 | ori r31, r31, 0x100 132 | rlwimi r31, r28, 28, 28, 28 133 | rlwimi r31, r28, 3, 24, 24 134 | rlwimi r31, r28, 31, 26, 26 135 | rlwimi r31, r28, 1, 25, 25 136 | xori r31, r31, 0x40 137 | rlwimi r31, r28, 30, 31, 31 138 | rlwimi r31, r28, 0, 30, 30 139 | xori r31, r31, 0x02 140 | beq @_208 141 | blt cr7, @_44 142 | bl Local_Panic 143 | 144 | @_1a0 145 | lwz r29, 0x05e8(r1) 146 | rlwinm r28, r27, 7, 25, 28 147 | lwzx r29, r29, r28 148 | rlwinm r28, r27, 20, 16, 31 149 | lhz r30, 0x0000(r29) 150 | b @_1bc 151 | 152 | @_1b8 153 | lhzu r30, 0x0008(r29) 154 | 155 | @_1bc 156 | lhz r31, 0x0002(r29) 157 | subf r30, r30, r28 158 | cmplw cr7, r30, r31 159 | bgt cr7, @_1b8 160 | lwz r28, 0x0690(r1) 161 | lwz r31, 0x0004(r29) 162 | cmpwi cr7, r28, 0x00 163 | bnel cr7, @_314 164 | rlwinm. r26, r31, 23, 29, 30 165 | cmplwi cr7, r26, 0x06 166 | beq @_200 167 | cmplwi cr6, r26, 0x02 168 | beq cr7, @_368 169 | beq cr6, @_3b8 170 | b @_44 171 | 172 | ; Dead code: 173 | blt @_360 174 | bgt @_3b8 175 | 176 | @_200 177 | slwi r28, r30, 12 178 | add r31, r31, r28 179 | 180 | @_208 181 | mfsrin r30, r27 182 | rlwinm r28, r27, 26, 10, 25 183 | rlwinm r30, r30, 6, 7, 25 184 | xor r28, r28, r30 185 | lwz r30, KDP.PTEGMask(r1) 186 | lwz r29, KDP.HTABORG(r1) 187 | and r28, r28, r30 188 | or. r29, r29, r28 189 | 190 | @_228 191 | lwz r30, 0x0000(r29) 192 | lwz r28, 0x0008(r29) 193 | cmpwi cr6, r30, 0x00 194 | lwz r30, 0x0010(r29) 195 | cmpwi cr7, r28, 0x00 196 | lwzu r28, 0x0018(r29) 197 | bge cr6, @_298 198 | cmpwi cr6, r30, 0x00 199 | lwzu r30, 0x0008(r29) 200 | bge cr7, @_298 201 | cmpwi cr7, r28, 0x00 202 | lwzu r28, 0x0008(r29) 203 | bge cr6, @_298 204 | cmpwi cr6, r30, 0x00 205 | lwzu r30, 0x0008(r29) 206 | bge cr7, @_298 207 | cmpwi cr7, r28, 0x00 208 | lwzu r28, 0x0008(r29) 209 | bge cr6, @_298 210 | cmpwi cr6, r30, 0x00 211 | addi r29, r29, 0x08 212 | bge cr7, @_298 213 | cmpwi cr7, r28, 0x00 214 | addi r29, r29, 0x08 215 | bge cr6, @_298 216 | rlwinm r28, r31, 0, 26, 26 217 | addi r29, r29, 0x08 218 | blt cr7, @_3e0 219 | 220 | @_298 221 | cmpwi r26, 0x00 222 | mfsrin r28, r27 223 | rlwinm r30, r27, 10, 26, 31 224 | stw r27, 0x0694(r1) 225 | oris r30, r30, 0x8000 226 | ori r31, r31, 0x100 227 | rlwimi r30, r31, 27, 25, 25 228 | rlwinm r31, r31, 0, 21, 19 229 | rlwimi r30, r28, 7, 1, 24 230 | stw r31, -0x0014(r29) 231 | eieio 232 | stwu r30, -0x0018(r29) 233 | sync 234 | lwz r28, 0x0e94(r1) 235 | stw r29, 0x0698(r1) 236 | addi r28, r28, 0x01 237 | stw r28, 0x0e94(r1) 238 | beq @_44 239 | cmpwi r26, 0x5a5a 240 | bne @_2f4 241 | stw r29, 0x0690(r1) 242 | 243 | @_2ec 244 | cmpw r29, r29 245 | b @_44 246 | 247 | @_2f4 248 | lwz r28, 0x0000(r26) 249 | lwz r30, KDP.HTABORG(r1) 250 | ori r28, r28, 0x800 251 | subf r30, r30, r29 252 | cmpw r29, r29 253 | rlwimi r28, r30, 9, 0, 19 254 | stw r28, 0x0000(r26) 255 | b @_44 256 | 257 | @_314 258 | lwz r28, 0x0e98(r1) 259 | lwz r29, 0x0690(r1) 260 | addi r28, r28, 0x01 261 | stw r28, 0x0e98(r1) 262 | li r28, 0x00 263 | stw r28, 0x0000(r29) 264 | lwz r29, 0x068c(r1) 265 | stw r28, 0x068c(r1) 266 | stw r28, 0x0690(r1) 267 | mfspr r28, pvr 268 | rlwinm. r28, r28, 0, 0, 14 269 | sync 270 | tlbie r29 271 | beq @_354 272 | sync 273 | tlbsync 274 | 275 | @_354 276 | sync 277 | isync 278 | blr 279 | 280 | ; Dead code: 281 | @_360 282 | rlwinm. r28, r31, 21, 0, 1 283 | bge @_3cc 284 | 285 | @_368 286 | slwi r28, r30, 2 287 | rlwinm r26, r31, 22, 0, 29 288 | lwzux r28, r26, r28 289 | lwz r31, 0x0688(r1) 290 | andi. r30, r28, 0x881 291 | rlwimi r31, r28, 0, 0, 19 292 | cmplwi cr6, r30, 0x800 293 | cmplwi cr7, r30, 0x81 294 | cmplwi r30, 0x01 295 | bge cr6, @_2ec 296 | cmplwi cr7, r30, 0x81 297 | ori r31, r31, 0x100 298 | rlwimi r31, r28, 3, 24, 24 299 | rlwimi r31, r28, 31, 26, 26 300 | rlwimi r31, r28, 1, 25, 25 301 | xori r31, r31, 0x40 302 | rlwimi r31, r28, 30, 31, 31 303 | beq @_208 304 | blt cr7, @_44 305 | bl Local_Panic 306 | 307 | @_3b8 308 | ori r28, r27, 0xfff 309 | stw r28, 0x068c(r1) 310 | rlwinm r31, r31, 0, 22, 19 311 | li r26, 0x5a5a 312 | b @_208 313 | 314 | ; Dead code: 315 | @_3cc 316 | bgt @_44 317 | bl Local_Panic 318 | addi r29, r1, KDP.SegMap32SupInitPtr 319 | bl PagingFunc2 320 | b @_44 321 | 322 | @_3e0 323 | cmplw cr6, r28, r26 324 | addi r29, r29, -0x50 325 | ble cr6, @_400 326 | crnot 2, 2 327 | lwz r30, KDP.PTEGMask(r1) 328 | xori r31, r31, 0x800 329 | xor r29, r29, r30 330 | beq @_228 331 | 332 | @_400 333 | lwz r26, 0x069c(r1) 334 | crclr cr6_eq 335 | rlwimi r26, r29, 0, 0, 25 336 | li r9, 0x08 337 | addi r29, r26, 0x08 338 | b @_428 339 | 340 | ; Dead code: 341 | @_418 342 | bne cr6, @_420 343 | mr r26, r29 344 | 345 | @_420 346 | cmpw cr6, r29, r26 347 | addi r29, r29, 0x08 348 | 349 | @_428 350 | rlwimi r29, r26, 0, 0, 25 351 | lwz r31, 0x0004(r29) 352 | lwz r30, 0x0000(r29) 353 | beq cr6, @_444 354 | rlwinm r28, r31, 30, 25, 25 355 | andc. r28, r28, r30 356 | bne @_420 357 | 358 | @_444 359 | addi r9, r9, -0x01 360 | cmpwi cr7, r9, 0x00 361 | rlwinm r31, r30, 0, 25, 25 362 | blel cr7, Local_Panic 363 | rlwinm r28, r30, 1, 0, 3 364 | neg r31, r31 365 | rlwimi r28, r30, 22, 4, 9 366 | xor r31, r31, r29 367 | rlwimi r28, r30, 5, 10, 19 368 | rlwinm r31, r31, 6, 10, 19 369 | xor r28, r28, r31 370 | xoris r30, r30, 0x8000 371 | lwz r31, 0x0e9c(r1) 372 | stw r29, 0x069c(r1) 373 | addi r31, r31, 0x01 374 | stw r31, 0x0e9c(r1) 375 | lwz r31, 0x0e98(r1) 376 | stw r30, 0x0000(r29) 377 | addi r31, r31, 0x01 378 | stw r31, 0x0e98(r1) 379 | sync 380 | mfspr r31, pvr 381 | rlwinm. r31, r31, 0, 0, 14 382 | tlbie r28 383 | beq @_4b0 384 | sync 385 | tlbsync 386 | 387 | @_4b0 388 | sync 389 | isync 390 | 391 | _InvalNCBPointerCache scratch=r8 392 | 393 | mfsprg r8, 0 394 | mr r9, r28 395 | lwz r8, -0x001c(r8) 396 | bl FindAreaAbove 397 | lwz r16, 0x0024(r8) 398 | mr r31, r8 399 | cmplw r16, r28 400 | mr r8, r28 401 | bgt @_600 402 | bgt Local_Panic 403 | bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq 404 | mr r26, r30 405 | beql @_88 406 | 407 | @_500 408 | lwz r28, 0x0000(r26) 409 | lwz r31, 0x0004(r29) 410 | andi. r30, r28, 0x800 411 | rlwinm r30, r28, 23, 9, 28 412 | xor r30, r30, r29 413 | beq Local_Panic 414 | andi. r30, r30, 0xffff 415 | xori r28, r28, 0x800 416 | bne Local_Panic 417 | rlwimi r28, r31, 0, 0, 19 418 | rlwimi r28, r31, 29, 27, 27 419 | rlwimi r28, r31, 27, 28, 28 420 | stw r28, 0x0000(r26) 421 | bl @_88 422 | _log 'PTEG overflow: EA ' 423 | mr r8, r27 424 | bl Printw 425 | _log 'Victim EA: ' 426 | mr r8, r28 427 | bl Printw 428 | _log 'MapInfo: ' 429 | mr r8, r29 430 | bl Printw 431 | lwz r16, 0x0000(r26) 432 | mr r8, r26 433 | bl Printw 434 | mr r8, r16 435 | bl Printw 436 | _log ' PTE: ' 437 | lwz r16, 0x0000(r29) 438 | lwz r17, 0x0004(r29) 439 | mr r8, r29 440 | bl Printw 441 | mr r8, r16 442 | bl Printw 443 | mr r8, r17 444 | bl Printw 445 | _log '^n' 446 | bl @_88 447 | 448 | @_600 449 | lwz r26, 0x05e8(r1) 450 | rlwinm r30, r28, 7, 25, 28 451 | lwzx r26, r26, r30 452 | 453 | @_60c 454 | lhz r30, 0x0000(r26) 455 | rlwinm r31, r28, 20, 16, 31 456 | subf r30, r30, r31 457 | lhz r31, 0x0002(r26) 458 | addi r26, r26, 0x08 459 | cmplw cr7, r30, r31 460 | lwz r31, -0x0004(r26) 461 | andi. r31, r31, 0xe01 462 | cmpwi r31, 0xa01 463 | bgt cr7, @_60c 464 | beq @_60c 465 | lwz r26, -0x0004(r26) 466 | slwi r30, r30, 2 467 | rlwinm r31, r26, 22, 30, 31 468 | cmpwi cr7, r31, 0x03 469 | rlwinm r26, r26, 22, 0, 29 470 | add r26, r26, r30 471 | bnel cr7, @_88 472 | b @_500 473 | 474 | 475 | 476 | PagingFunc2 ; OUTSIDE REFERER 477 | sync 478 | isync 479 | lwz r28, 0x0000(r29) 480 | stw r28, 0x05e8(r1) 481 | addi r28, r28, 0x84 482 | lis r31, 0x00 483 | 484 | @_18 485 | lwzu r30, -0x0008(r28) 486 | addis r31, r31, -0x1000 487 | mr. r31, r31 488 | mtsrin r30, r31 489 | bne @_18 490 | isync 491 | 492 | PagingFunc2AndAHalf 493 | lwz r28, 0x0004(r29) 494 | mfspr r31, pvr 495 | rlwinm. r31, r31, 0, 0, 14 496 | addi r29, r1, 0x00 497 | stw r28, 0x05ec(r1) 498 | beq @_168 499 | li r30, 0x00 500 | mtspr ibat0u, r30 501 | mtspr ibat1u, r30 502 | mtspr ibat2u, r30 503 | mtspr ibat3u, r30 504 | mtspr dbat0u, r30 505 | mtspr dbat1u, r30 506 | mtspr dbat2u, r30 507 | mtspr dbat3u, r30 508 | rlwimi r29, r28, 7, 25, 28 509 | lwz r31, 0x0284(r29) 510 | lwz r30, 0x0280(r29) 511 | rlwinm r31, r31, 0, 29, 27 512 | mtspr ibat0l, r31 513 | mtspr ibat0u, r30 514 | stw r31, 0x0304(r1) 515 | stw r30, 0x0300(r1) 516 | rlwimi r29, r28, 11, 25, 28 517 | lwz r31, 0x0284(r29) 518 | lwz r30, 0x0280(r29) 519 | rlwinm r31, r31, 0, 29, 27 520 | mtspr ibat1l, r31 521 | mtspr ibat1u, r30 522 | stw r31, 0x030c(r1) 523 | stw r30, 0x0308(r1) 524 | rlwimi r29, r28, 15, 25, 28 525 | lwz r31, 0x0284(r29) 526 | lwz r30, 0x0280(r29) 527 | rlwinm r31, r31, 0, 29, 27 528 | mtspr ibat2l, r31 529 | mtspr ibat2u, r30 530 | stw r31, 0x0314(r1) 531 | stw r30, 0x0310(r1) 532 | rlwimi r29, r28, 19, 25, 28 533 | lwz r31, 0x0284(r29) 534 | lwz r30, 0x0280(r29) 535 | rlwinm r31, r31, 0, 29, 27 536 | mtspr ibat3l, r31 537 | mtspr ibat3u, r30 538 | stw r31, 0x031c(r1) 539 | stw r30, 0x0318(r1) 540 | rlwimi r29, r28, 23, 25, 28 541 | lwz r31, 0x0284(r29) 542 | lwz r30, 0x0280(r29) 543 | mtspr dbat0l, r31 544 | mtspr dbat0u, r30 545 | stw r31, 0x0324(r1) 546 | stw r30, 0x0320(r1) 547 | rlwimi r29, r28, 27, 25, 28 548 | lwz r31, 0x0284(r29) 549 | lwz r30, 0x0280(r29) 550 | mtspr dbat1l, r31 551 | mtspr dbat1u, r30 552 | stw r31, 0x032c(r1) 553 | stw r30, 0x0328(r1) 554 | rlwimi r29, r28, 31, 25, 28 555 | lwz r31, 0x0284(r29) 556 | lwz r30, 0x0280(r29) 557 | mtspr dbat2l, r31 558 | mtspr dbat2u, r30 559 | stw r31, 0x0334(r1) 560 | stw r30, 0x0330(r1) 561 | rlwimi r29, r28, 3, 25, 28 562 | lwz r31, 0x0284(r29) 563 | lwz r30, 0x0280(r29) 564 | mtspr dbat3l, r31 565 | mtspr dbat3u, r30 566 | stw r31, 0x033c(r1) 567 | stw r30, 0x0338(r1) 568 | isync 569 | cmpw r29, r29 570 | blr 571 | 572 | @_168 573 | rlwimi r29, r28, 7, 25, 28 574 | lwz r30, 0x0280(r29) 575 | lwz r31, 0x0284(r29) 576 | stw r30, 0x0300(r1) 577 | stw r31, 0x0304(r1) 578 | stw r30, 0x0320(r1) 579 | stw r31, 0x0324(r1) 580 | rlwimi r30, r31, 0, 25, 31 581 | mtspr ibat0u, r30 582 | lwz r30, 0x0280(r29) 583 | rlwimi r31, r30, 30, 26, 31 584 | rlwimi r31, r30, 6, 25, 25 585 | mtspr ibat0l, r31 586 | rlwimi r29, r28, 11, 25, 28 587 | lwz r30, 0x0280(r29) 588 | lwz r31, 0x0284(r29) 589 | stw r30, 0x0308(r1) 590 | stw r31, 0x030c(r1) 591 | stw r30, 0x0328(r1) 592 | stw r31, 0x032c(r1) 593 | rlwimi r30, r31, 0, 25, 31 594 | mtspr ibat1u, r30 595 | lwz r30, 0x0280(r29) 596 | rlwimi r31, r30, 30, 26, 31 597 | rlwimi r31, r30, 6, 25, 25 598 | mtspr ibat1l, r31 599 | rlwimi r29, r28, 15, 25, 28 600 | lwz r30, 0x0280(r29) 601 | lwz r31, 0x0284(r29) 602 | stw r30, 0x0310(r1) 603 | stw r31, 0x0314(r1) 604 | stw r30, 0x0330(r1) 605 | stw r31, 0x0334(r1) 606 | rlwimi r30, r31, 0, 25, 31 607 | mtspr ibat2u, r30 608 | lwz r30, 0x0280(r29) 609 | rlwimi r31, r30, 30, 26, 31 610 | rlwimi r31, r30, 6, 25, 25 611 | mtspr ibat2l, r31 612 | rlwimi r29, r28, 19, 25, 28 613 | lwz r30, 0x0280(r29) 614 | lwz r31, 0x0284(r29) 615 | stw r30, 0x0318(r1) 616 | stw r31, 0x031c(r1) 617 | stw r30, 0x0338(r1) 618 | stw r31, 0x033c(r1) 619 | rlwimi r30, r31, 0, 25, 31 620 | mtspr ibat3u, r30 621 | lwz r30, 0x0280(r29) 622 | rlwimi r31, r30, 30, 26, 31 623 | rlwimi r31, r30, 6, 25, 25 624 | mtspr ibat3l, r31 625 | cmpw r29, r29 626 | blr 627 | 628 | 629 | 630 | PagingL2PWithBATs ; OUTSIDE REFERER 631 | lwz r30, 0x0000(r29) 632 | li r28, -0x01 633 | rlwimi r28, r30, 15, 0, 14 634 | xor r31, r27, r30 635 | andc. r31, r31, r28 636 | beq @_54 637 | lwzu r30, 0x0008(r29) 638 | rlwimi r28, r30, 15, 0, 14 639 | xor r31, r27, r30 640 | andc. r31, r31, r28 641 | beq @_54 642 | lwzu r30, 0x0008(r29) 643 | rlwimi r28, r30, 15, 0, 14 644 | xor r31, r27, r30 645 | andc. r31, r31, r28 646 | beq @_54 647 | lwzu r30, 0x0008(r29) 648 | rlwimi r28, r30, 15, 0, 14 649 | xor r31, r27, r30 650 | andc. r31, r31, r28 651 | bne PagingL2PWithoutBATs 652 | 653 | @_54 654 | andi. r31, r30, 0x01 655 | rlwinm r28, r28, 0, 8, 19 656 | lwzu r31, 0x0004(r29) 657 | and r28, r27, r28 658 | or r31, r31, r28 659 | bnelr 660 | 661 | 662 | 663 | PagingL2PWithoutBATs ; OUTSIDE REFERER 664 | mfsrin r31, r27 665 | rlwinm r30, r27, 10, 26, 31 666 | rlwimi r30, r31, 7, 1, 24 667 | rlwinm r28, r27, 26, 10, 25 668 | oris r30, r30, 0x8000 669 | rlwinm r31, r31, 6, 7, 25 670 | xor r28, r28, r31 671 | lwz r31, KDP.PTEGMask(r1) 672 | lwz r29, KDP.HTABORG(r1) 673 | and r28, r28, r31 674 | or. r29, r29, r28 675 | 676 | @_2c 677 | lwz r31, 0x0000(r29) 678 | lwz r28, 0x0008(r29) 679 | cmpw cr6, r30, r31 680 | lwz r31, 0x0010(r29) 681 | cmpw cr7, r30, r28 682 | lwzu r28, 0x0018(r29) 683 | bne cr6, @_50 684 | 685 | @_48 686 | lwzu r31, -0x0014(r29) 687 | blr 688 | 689 | @_50 690 | cmpw cr6, r30, r31 691 | lwzu r31, 0x0008(r29) 692 | beq cr7, @_48 693 | cmpw cr7, r30, r28 694 | lwzu r28, 0x0008(r29) 695 | beq cr6, @_48 696 | cmpw cr6, r30, r31 697 | lwzu r31, 0x0008(r29) 698 | beq cr7, @_48 699 | cmpw cr7, r30, r28 700 | lwzu r28, 0x0008(r29) 701 | beq cr6, @_48 702 | cmpw cr6, r30, r31 703 | lwzu r31, -0x000c(r29) 704 | beqlr cr7 705 | cmpw cr7, r30, r28 706 | lwzu r31, 0x0008(r29) 707 | beqlr cr6 708 | lwzu r31, 0x0008(r29) 709 | beqlr cr7 710 | lwz r31, KDP.PTEGMask(r1) 711 | xori r30, r30, 0x40 712 | andi. r28, r30, 0x40 713 | addi r29, r29, -0x3c 714 | xor r29, r29, r31 715 | bne @_2c 716 | blr 717 | 718 | 719 | 720 | pb equ 12 721 | 722 | PagingFlushTLB ; OUTSIDE REFERER 723 | lhz r29, KDP.ProcessorInfo + NKProcessorInfo.TransCacheTotalSize(r1) 724 | slwi r29, r29, pb 725 | 726 | @loop 727 | subi r29, r29, 1 << pb 728 | cmpwi r29, 0 729 | tlbie r29 730 | bgt @loop 731 | 732 | mfspr r29, pvr 733 | rlwinm. r29, r29, 0, 0, 14 734 | 735 | ; All cpus 736 | sync 737 | beqlr 738 | 739 | ; Non-601 stuff 740 | tlbsync 741 | sync 742 | isync 743 | blr 744 | -------------------------------------------------------------------------------- /Internal/NKOpaque.a: -------------------------------------------------------------------------------- 1 | ; Opaque NanoKernel structures: 2 | ; - stored in the NanoKernel pool (not always) 3 | ; - associated with a class number and opaque ID (not always) 4 | ; - referenced by opaque ID (for MPLibrary's benefit) 5 | 6 | 7 | 8 | 9 | 10 | ;_______________________________________________________________________ 11 | ; ID CLASS 1: PROCESS 12 | ; (size: 32b, thud command: id -p) 13 | ; 14 | ; The NanoKernel's internal representation of a cooperative process 15 | ; within the blue environment. Processes and tasks have a many-to-one 16 | ; relationship. 17 | ; 18 | ; There is a special 'blue' process that owns the blue task and all 19 | ; the CPU idle tasks. 20 | ;_______________________________________________________________________ 21 | 22 | Process record 0,INCR 23 | 24 | kIDClass equ 1 25 | kFirstID equ 0x00010001 26 | kSignature equ 'PROC' 27 | 28 | ;_______________________ 29 | ; Fields 30 | ;_______________________ 31 | 32 | ID ds.l 1 ; 00 33 | Signature ds.l 1 ; 04 ; 'PROC' 34 | Flags ds.l 1 ; 08 ; MPCall_5 does something here 35 | kFlag0 equ 0 36 | kFlag1 equ 1 37 | kFlag2 equ 2 38 | kFlag3 equ 3 39 | kFlag4 equ 4 40 | kFlag5 equ 5 41 | kFlag6 equ 6 42 | kFlag7 equ 7 43 | kFlag8 equ 8 44 | kFlag9 equ 9 45 | kFlag10 equ 10 46 | kFlag11 equ 11 47 | kFlag12 equ 12 48 | kFlag13 equ 13 49 | kFlag14 equ 14 50 | kFlag15 equ 15 51 | kFlag16 equ 16 52 | kFlag17 equ 17 53 | kFlag18 equ 18 54 | kFlag19 equ 19 55 | kFlag20 equ 20 56 | kFlag21 equ 21 57 | kFlag22 equ 22 58 | kFlag23 equ 23 59 | kFlag24 equ 24 60 | kFlag25 equ 25 61 | kFlag26 equ 26 62 | kFlag27 equ 27 63 | kFlag28 equ 28 64 | kFlag29 equ 29 65 | kFlag30 equ 30 66 | kFlag31 equ 31 67 | SystemAddressSpaceID ds.l 1 ; 0c ; set by Init.s after addrspc creation 68 | TaskCount ds.l 1 ; 10 ; incremented by CreateTask 69 | SystemAddressSpacePtr ds.l 1 ; 14 70 | AddressSpaceCount ds.l 1 ; 18 ; incremented by NKCreateAddressSpaceSub 71 | ds.l 1 ; 1c 72 | 73 | Size equ * 74 | endr 75 | 76 | 77 | 78 | 79 | ;_______________________________________________________________________ 80 | ; ID CLASS 2: TASK 81 | ; (size: 1k, thud command: id -t) 82 | ; 83 | ; What the MPLibrary and NanoKernel call the unit of multitasking. 84 | ; (Remember that 'Thread' and 'Process' were taken.) 85 | ; 86 | ; Contains space for a ContextBlock in the style of the ECB, but 87 | ; blue's ContextBlockPtr is redirected to the ECB. 88 | ;_______________________________________________________________________ 89 | 90 | Task record 0,INCR 91 | 92 | kIDClass equ 2 93 | kFirstID equ 0x00020001 94 | kSignature equ 'TASK' 95 | 96 | ;_______________________ 97 | ; Task priorities 98 | ;_______________________ 99 | 100 | kCriticalPriority equ 0 101 | kLatencyProtectPriority equ 1 102 | kNominalPriority equ 2 103 | kIdlePriority equ 3 104 | 105 | ;_______________________ 106 | ; Fields 107 | ;_______________________ 108 | 109 | ID ds.l 1 ; 000 110 | Signature ds.l 1 ; 004 111 | QueueMember ds.l 4 ; 008:018 ; a task is always a member of a queue, e.g. the RDYQ 112 | State ds.b 1 ; 018 ; non-zero when running 113 | Priority ds.b 1 ; 019 ; CreateTask sets 2 by default 114 | CPUIndex ds.w 1 ; 01a 115 | Weight ds.l 1 ; 01c ; default is 100, blue gets 200, idle gets 1 116 | 117 | Timer ds.b 64 ; 020:060 118 | 119 | ProcessID ds.l 1 ; 060 120 | Flags ds.l 1 ; 064 ; IntAlignment is interested in bit 9, MPCalls 52/116 in bit 15 121 | kFlag0 equ 0 122 | kFlag1 equ 1 123 | kFlag2 equ 2 124 | kFlag3 equ 3 125 | kFlag4 equ 4 126 | kFlag5 equ 5 127 | kFlag6 equ 6 128 | kFlag7 equ 7 129 | kFlag8 equ 8 130 | kFlagTakesAllExceptions equ 9 131 | kFlag10 equ 10 132 | kFlag11 equ 11 133 | kFlag12 equ 12 ; set for idle1, idle2 134 | kFlag13 equ 13 135 | kFlagNotDebuggable equ 14 ; set for blue, idle1 136 | kFlagBlue equ 15 137 | kFlag16 equ 16 138 | kFlag17 equ 17 139 | kFlagPageFaulted equ 18 140 | kFlag19 equ 19 141 | kFlag20 equ 20 142 | kFlagPerfMon equ 21 ; set by MPMarkPMFTask, means perf monitor 143 | kFlagStopped equ 22 144 | kFlag23 equ 23 145 | kFlag24 equ 24 146 | kFlag25 equ 25 ; set for idle1, idle2 147 | kFlag26 equ 26 ; set for blue, cleared when preempted, set when run 148 | kFlagSchToInterruptEmu equ 27 ; set when scheduler should trigger a 68k interrupt in this task 149 | kFlag28 equ 28 ; set for blue 150 | kFlag29 equ 29 151 | kFlagAborted equ 30 152 | kFlag31 equ 31 153 | 154 | ds.l 1 ; 068 155 | OwningProcessPtr ds.l 1 ; 06c 156 | AddressSpacePtr ds.l 1 ; 070 ; borrowed from PROC argument to CreateTask 157 | Name ds.l 1 ; 074 ; 'blue', creator of owning cooperative process, etc 158 | CpuID ds.l 1 ; 078 159 | ds.l 1 ; 07c 160 | CreateTime3 ds.d 1 ; 080 161 | ContextBlockPtr ds.l 1 ; 088 ; points internally by default, and to EDP.ECB in blue 162 | VectorSaveArea ds.l 1 ; 08c 163 | ds.l 1 ; 090 164 | ds.l 1 ; 094 165 | ds.l 1 ; 098 166 | NotificationPtr ds.l 1 ; 09c 167 | PageFaultSema ds.b 32 ; 0a0:0c0 ; task blocks on this fake sema, only to run when high-priority blue is done 168 | Zero1 ds.l 1 ; 0c0 169 | Zero2 ds.l 1 ; 0c4 170 | CreateTime1 ds.d 1 ; 0c8 171 | CreateTime2 ds.d 1 ; 0d0 172 | ds.l 1 ; 0d8 173 | ds.l 1 ; 0dc 174 | CodeFaultCtr ds.l 1 ; 0e0 ; these two only climb when VM is on 175 | DataFaultCtr ds.l 1 ; 0e4 176 | PreemptCtr ds.l 1 ; 0e8 177 | SomeLabelField ds.l 1 ; 0ec 178 | VecBase ds.l 1 ; 0f0 179 | ExceptionHandlerID ds.l 1 ; 0f4 ; a queue 180 | ErrToReturnIfIDie ds.l 1 ; 0f8 181 | ds.l 1 ; 0fc 182 | ContextBlock ds.b 768 ; 100:400 ; like the EDP's Emulator Context Block -- unsure of size 183 | 184 | Size equ * 185 | endr 186 | 187 | 188 | 189 | 190 | ;_______________________________________________________________________ 191 | ; ID CLASS 3: TIMER 192 | ; (size: 64b, thud command: id -tm) 193 | ; 194 | ; "Prev" is actually the next timer to fire! 195 | ;_______________________________________________________________________ 196 | 197 | Timer record 0,INCR 198 | 199 | kIDClass equ 3 200 | kFirstID equ 0x00030001 201 | kSignature equ 'TIME' 202 | 203 | ;_______________________ 204 | ; Fields 205 | ;_______________________ 206 | 207 | ID ds.l 1 ; 00 ; task+20 208 | Signature ds.l 1 ; 04 ; task+24 209 | QueueLLL ds.l 1 ; 08 ; task+28 ; overlaps with the below bytefields, as a union? 210 | ds.l 1 ; 0c ; task+2c 211 | ProcessID ds.l 1 ; 10 ; task+30 212 | 213 | Kind ds.b 1 ; 14 ; task+34 ; InitTMRQs sets to 6, MPCall 55 to 1, MPCall 52 to 2 214 | kKind1 equ 1 215 | kKind2 equ 2 216 | kKind3 equ 3 217 | kKind4 equ 4 218 | kKind5 equ 5 219 | kKind6 equ 6 220 | kKind7 equ 7 221 | 222 | Byte1 ds.b 1 ; 15 ; task+35 223 | KeepAfterFiring ds.b 1 ; 16 ; task+36 ; InitTMRQs sets to 1 224 | Byte3 ds.b 1 ; 17 ; task+37 ; called_by_init_tmrqs sets to 1 225 | 226 | MessageQueueID 227 | ParentTaskPtr ds.l 1 ; 18 ; task+38 ; task to be unblocked when timer fires 228 | ReservedMessage ds.l 1 ; 1c ; task+3c ; 'note' allocated when timer armed 229 | Message1 ds.l 1 ; 20 ; task+40 ; if I hit a message queue 230 | Message2 ds.l 1 ; 24 ; task+44 231 | Message3 ds.l 1 ; 28 ; task+48 232 | EventGroupID ds.l 1 ; 2c ; task+4c ; if I hit an event group 233 | EventGroupFlags ds.l 1 ; 30 ; task+50 234 | SemaphoreID ds.l 1 ; 34 ; task+54 235 | Time ds.l 2 ; 38 ; task+58 ; set from first two args to MPCall 55 236 | 237 | Size equ * 238 | endr 239 | 240 | 241 | 242 | 243 | ;_______________________________________________________________________ 244 | ; ID CLASS 4: QUEUE 245 | ; (size: 52b, thud command: id -q) 246 | ; 247 | ;_______________________________________________________________________ 248 | 249 | Queue record 0,INCR 250 | 251 | kIDClass equ 4 252 | kFirstID equ 0x00040001 253 | 254 | ;_______________________ 255 | ; Fields 256 | ;_______________________ 257 | 258 | BlockedTasks ds.l 4 ; 00:10 ; titled MSGQ ; waiting for messages 259 | Messages ds.l 4 ; 10:20 ; titled NOTQ ; waiting for tasks 260 | ProcessID ds.l 1 ; 20 ; why associate a queue with a process? 261 | ReserveCount ds.l 1 ; 24 ; as number of messages, from MPSetQueueReserve 262 | ReservePtr ds.l 1 ; 28 ; ptr to first element of 263 | BlockedTaskCount ds.l 1 ; 2c 264 | MessageCount ds.l 1 ; 30 265 | 266 | Size equ * 267 | endr 268 | 269 | 270 | 271 | ReadyQueue record 0,INCR 272 | 273 | LLL ds.l 4 ; 00:10 ; nothing fancy, freeform contains priority flag 274 | Counter ds.l 1 ; 10 ; SchInit sets, SchRdyTaskLater bumps, major_0x13e4c decs 275 | TotalWeight ds.l 1 ; 14 ; divide available time by these 276 | Timecake ds.d 1 ; 18 ; period of ~1ms, 8ms, 64ms, 512ms 277 | 278 | 279 | org 0x20 280 | ; Constants 281 | kSignature equ 'RDYQ' 282 | 283 | endr 284 | 285 | 286 | 287 | 288 | Message record 0,INCR 289 | 290 | kSignature equ 'note' 291 | kReservedSignature equ 'notr' 292 | 293 | LLL ds.l 4 ; 00:10 ; singly linked (next ptrs) only 294 | Word1 ds.l 1 ; 10 295 | Word2 ds.l 1 ; 14 296 | Word3 ds.l 1 ; 18 297 | 298 | Size equ * 299 | endr 300 | 301 | 302 | kTimerQueueSignature equ 'TMRQ' 303 | kDelayQueueSignature equ 'DLYQ' 304 | kDbugQueueSignature equ 'DBUG' 305 | kPageQueueSignature equ 'PAGQ' 306 | kNotQueueSignature equ 'NOTQ' 307 | kSemaQueueSignature equ 'SEMQ' 308 | 309 | 310 | 311 | 312 | ;_______________________________________________________________________ 313 | ; ID CLASS 5: SEMAPHORE 314 | ; (size: 32b, thud command: id -s) 315 | ; 316 | ;_______________________________________________________________________ 317 | 318 | Semaphore record 0,INCR 319 | 320 | kIDClass equ 5 321 | kFirstID equ 0x00050001 322 | kSignature equ 'SEMA' 323 | 324 | ;_______________________ 325 | ; Fields 326 | ;_______________________ 327 | 328 | BlockedTasks ds.l 4 ; 00:10 ; blocked tasks 329 | Value ds.l 1 ; 10 ; negative if tasks are blocked??? 330 | MaxValue ds.l 1 ; 14 331 | ProcessID ds.l 1 ; 18 332 | BlockedTaskCount ds.l 1 ; 1c ; starts as 0 333 | 334 | Size equ * 335 | endr 336 | 337 | 338 | 339 | 340 | ;_______________________________________________________________________ 341 | ; ID CLASS 6: CRITICAL REGION 342 | ; (size: 36b, thud command: id -r) 343 | ; 344 | ;_______________________________________________________________________ 345 | 346 | CriticalRegion record 0,INCR 347 | 348 | kIDClass equ 6 349 | kFirstID equ 0x00060001 350 | kSignature equ 'CRGN' 351 | 352 | ;_______________________ 353 | ; Fields 354 | ;_______________________ 355 | 356 | LLL ds.l 4 ; 00:10 357 | ProcessID ds.l 4 ; 10:20 ; lll.freeform is the field? 358 | ds.l 1 ; 20 359 | 360 | Size equ * 361 | endr 362 | 363 | 364 | 365 | 366 | ;_______________________________________________________________________ 367 | ; ID CLASS 7: CPU 368 | ; (size: 32+800+128 = 960b, thud command: id -c) 369 | ; 370 | ;_______________________________________________________________________ 371 | 372 | CPU record 0,INCR 373 | 374 | kIDClass equ 7 375 | kFirstID equ 0x00070001 376 | kSignature equ 'CPU ' 377 | 378 | ;_______________________ 379 | ; Fields 380 | ;_______________________ 381 | 382 | ID ds.l 1 ; 00 383 | Signature ds.l 1 ; 04 384 | LLL ds.l 4 ; 08:18 ; member of CGRP 385 | Flags ds.l 1 ; 18 ; contains 0x0000000f ; cannot delete if this field & 9 386 | IdleTaskPtr ds.l 1 ; 1c 387 | 388 | EWABase ds.b 800 ; negative-indexed parts of EWA 389 | EWA ds.b 128 ; positive-indexed parts of EWA 390 | 391 | kFlag0 equ 0 392 | kFlag1 equ 1 393 | kFlag2 equ 2 394 | kFlag3 equ 3 395 | kFlag4 equ 4 396 | kFlag5 equ 5 397 | kFlag6 equ 6 398 | kFlag7 equ 7 399 | kFlag8 equ 8 400 | kFlag9 equ 9 401 | kFlag10 equ 10 402 | kFlag11 equ 11 403 | kFlag12 equ 12 404 | kFlag13 equ 13 405 | kFlag14 equ 14 406 | kFlag15 equ 15 407 | kFlag16 equ 16 408 | kFlag17 equ 17 409 | kFlag18 equ 18 410 | kFlag19 equ 19 411 | kFlag20 equ 20 412 | kFlag21 equ 21 413 | kFlag22 equ 22 414 | kFlag23 equ 23 415 | kFlag24 equ 24 416 | kFlag25 equ 25 417 | kFlag26 equ 26 418 | kFlag27 equ 27 419 | kFlagScheduled equ 28 420 | kFlag29 equ 29 421 | kFlag30 equ 30 422 | kFlag31 equ 31 423 | 424 | 425 | Size equ * 426 | endr 427 | 428 | 429 | 430 | 431 | 432 | ;_______________________________________________________________________ 433 | ; ID CLASS 8: ADDRESS SPACE 434 | ; (size: 192b, thud command: id -sp) 435 | ; 436 | ;_______________________________________________________________________ 437 | 438 | AddressSpace record 0,INCR 439 | 440 | kIDClass equ 8 441 | kFirstID equ 0x00080001 442 | kSignature equ 'SPAC' 443 | 444 | ;_______________________ 445 | ; Fields 446 | ;_______________________ 447 | 448 | ID ds.l 1 ; 00 449 | Signature ds.l 1 ; 04 450 | Flags ds.l 1 ; 08 451 | kFlag30 equ 30 452 | TaskCount ds.l 1 ; 0c ; incremented by CreateTask 453 | RsrvList ds.l 4 ; 10:20 ; LLL 454 | AreaList ds.l 4 ; 20:30 ; LLL 455 | SRs ds.l 16 ; 30:70 ; segment register values 456 | ParentCoherenceSpecialPtr ds.l 1 ; 70 ; SpecialPtr of owning cgrp (in list owned by Cpu) 457 | ProcessID ds.l 1 ; 74 ; ID of owning PROC 458 | ds.l 1 ; 78 459 | ds.l 1 ; 7c 460 | BATs 461 | BAT0U ds.l 1 ; 80 462 | BAT0L ds.l 1 ; 84 463 | BAT1U ds.l 1 ; 88 464 | BAT1L ds.l 1 ; 8c 465 | BAT2U ds.l 1 ; 90 466 | BAT2L ds.l 1 ; 94 467 | BAT3U ds.l 1 ; 98 468 | BAT3L ds.l 1 ; 9c 469 | ExtraBATs ; the flag that enables these is never set? 470 | ExtraBAT0U ds.l 1 ; a0 471 | ExtraBAT0L ds.l 1 ; a4 472 | ExtraBAT1U ds.l 1 ; a8 473 | ExtraBAT1L ds.l 1 ; ac 474 | ExtraBAT2U ds.l 1 ; b0 475 | ExtraBAT2L ds.l 1 ; b4 476 | ExtraBAT3U ds.l 1 ; b8 477 | ExtraBAT3L ds.l 1 ; bc 478 | 479 | Size equ * 480 | endr 481 | 482 | 483 | 484 | 485 | ;_______________________________________________________________________ 486 | ; ID CLASS 9: EVENT GROUP 487 | ; (size: 32b, thud command: id -e) 488 | ; 489 | ;_______________________________________________________________________ 490 | 491 | EventGroup record 0,INCR 492 | 493 | kIDClass equ 9 494 | kFirstID equ 0x00090001 495 | kSignature equ 'EVNT' 496 | 497 | ;_______________________ 498 | ; Fields 499 | ;_______________________ 500 | 501 | LLL ds.l 4 ; 00:10 ; first field is ID 502 | Flags ds.l 1 ; 10 503 | ProcessID ds.l 1 ; 14 504 | SWI ds.l 1 ; 18 ; contains 1-8 +/- 16 ; flag 27 (=16) means "is swi" 505 | Counter ds.l 1 ; 1c 506 | 507 | Size equ * 508 | endr 509 | 510 | 511 | 512 | 513 | ;_______________________________________________________________________ 514 | ; ID CLASS 10: COHERENCE GROUP 515 | ; (size: 88b, thud command: id -cg) 516 | ; 517 | ;_______________________________________________________________________ 518 | 519 | CoherenceGroup record 0,INCR 520 | 521 | kIDClass equ 10 522 | kFirstID equ 0x000a0001 523 | kSignature equ 'CGRP' 524 | 525 | ;_______________________ 526 | ; Fields 527 | ;_______________________ 528 | 529 | CPUList ds.l 4 ; 00:10 ; CPUs on this "motherboard" 530 | LLL ds.l 4 ; 10:20 ; member of global CGRP list 531 | CpuCount ds.l 1 ; 20 532 | ScheduledCpuCount ds.l 1 ; 24 533 | LA_CpuPlugin ds.l 1 ; 28 ; page-aligned 534 | PA_CpuPlugin ds.l 1 ; 2c ; page-aligned 535 | CpuPluginSize ds.l 1 ; 30 ; page-aligned size 536 | LA_CpuPluginDesc ds.l 1 ; 34 ; non-page-aligned ; [1c] = count, [20...] = entry table 537 | PA_CpuPluginDesc ds.l 1 ; 38 ; non-page-aligned 538 | PA_CpuPluginTOC ds.l 1 ; 3c ; "table of contents": a TVector pointer for each selector 539 | PA_CpuPluginStackPtrs ds.l 1 ; 40 ; array of stack pointers (one per CPU) 540 | CpuPluginSelectorCount ds.l 1 ; 44 ; max of 64 541 | Incrementer ds.l 1 ; 48 ; number of NKCreateAddressSpaceSub calls % 1M 542 | CpuPluginSpacePtr ds.l 1 ; 4c ; space that cpup runs in 543 | ds.l 1 ; 50 544 | ds.l 1 ; 54 545 | 546 | Size equ * 547 | endr 548 | 549 | 550 | 551 | 552 | ;_______________________________________________________________________ 553 | ; ID CLASS 11: AREA 554 | ; (size: 160b, thud command: id -a) 555 | ; 556 | ; A contiguous region of effective addresses with similar properties. 557 | ;_______________________________________________________________________ 558 | 559 | Area record 0,INCR 560 | 561 | kIDClass equ 11 562 | kFirstID equ 0x000b0001 563 | kSignature equ 'AREA' 564 | 565 | kPLEFlagIsInHTAB equ 20 ; bits 0-19 = HTAB offset if set, else physical page 566 | kPLEFlagHasPhysPage equ 31 567 | 568 | ;_______________________ 569 | ; Fields 570 | ;_______________________ 571 | 572 | ID ds.l 1 ; 00 573 | Signature ds.l 1 ; 04 574 | Flags ds.l 1 ; 08 575 | kDontOwnPageMapArray equ 25 576 | kPageMapArrayIs2D equ 26 577 | kPageMapArrayInPool equ 27 578 | kAliasFlag equ 28 579 | kPrivilegedFlag equ 29 580 | kFaultCtrArrayIs2D equ 30 581 | kFaultCtrArrayInPool equ 31 582 | ProcessID ds.l 1 ; 0c 583 | AddressSpaceID ds.l 1 ; 10 584 | ParentAreaID ds.l 1 ; 14 ; if alias 585 | BackingProviderID ds.l 1 ; 18 ; notification ID 586 | PTEConfig ds.l 1 ; 1c 587 | FlagsAndMinAlign ds.l 1 ; 20 ; detailed description to come 588 | LogicalBase ds.l 1 ; 24 589 | LogicalEnd ds.l 1 ; 28 ; the last valid address in the area 590 | Length ds.l 1 ; 2c ; in actual bytes! 591 | LogicalSeparation ds.l 1 ; 30 ; min logical distance to any other area 592 | Counter ds.l 1 ; 34 593 | BytesMapped ds.l 1 ; 38 ; total size of pages actually mapped to me 594 | FaultCtrArrayPtr ds.l 1 ; 3c ; in paged areas, tracks how many times pages are added to HTAB 595 | PageMapArrayPtr ds.l 1 ; 40 ; in paged areas, stores PTE template for each page 596 | AliasLLL ds.l 4 ; 44:54 597 | LLL ds.l 4 ; 54:64 ; member of address space 598 | ds.l 1 ; 64 599 | PageSize ds.l 1 ; 68 ; always 4k, the size of a PPC page 600 | AddressSpacePtr ds.l 1 ; 6c 601 | ContigPTETemplate ds.l 1 ; 70 ; in contig areas, acts as PTE template for every page (whole Area is same page) 602 | PagedPTETemplate ds.l 1 ; 74 ; when paged area is created this fills PageMapArray 603 | AlignmentMask ds.l 1 ; 78 ; bit mask that LogicalBase is aligned to 604 | DefaultAlignmentMask ds.l 1 ; 7c ; always 0xFFFFF000 (page alignment) 605 | ds.l 1 ; 80 606 | BackingProviderMisc ds.l 1 ; 84 ; seems to be arbitrary (third arg to MPSetAreaBackingProvider) 607 | ds.l 1 ; 88 608 | ds.l 1 ; 8c 609 | FenceLLL ds.l 4 ; 90:a0 ; function unknown, id is 'fenc' 610 | 611 | Size equ * 612 | endr 613 | 614 | ; Page List Entry bits: 615 | 616 | 617 | 618 | 619 | 620 | ;_______________________________________________________________________ 621 | ; ID CLASS 12: NOTIFICATION 622 | ; (size: 40b, thud command: id -n) 623 | ; 624 | ;_______________________________________________________________________ 625 | 626 | Notification record 0,INCR 627 | 628 | kIDClass equ 12 629 | kFirstID equ 0x000c0001 630 | kSignature equ 'KNOT' 631 | 632 | ;_______________________ 633 | ; Fields 634 | ;_______________________ 635 | 636 | TaskPtr ds.l 1 ; 00 ; (set on init) 637 | Signature ds.l 1 ; 04 ; (set on init) 638 | ProcessID ds.l 1 ; 08 ; (set on init) 639 | 640 | QueueID ds.l 1 ; 0c ; message queue 641 | MsgWord1 ds.l 1 ; 10 642 | MsgWord2 ds.l 1 ; 14 643 | MsgWord3 ds.l 1 ; 18 644 | 645 | EventGroupID ds.l 1 ; 1c 646 | EventFlags ds.l 1 ; 20 647 | 648 | SemaphoreID ds.l 1 ; 24 649 | 650 | Size equ * 651 | endr 652 | 653 | 654 | 655 | 656 | ;_______________________________________________________________________ 657 | ; ID CLASS 13: CONSOLE LOG 658 | ; (size: 16b, thud command: id -nc) 659 | ; 660 | ; Never seen one in the wild -- must have been in debug builds. 661 | ;_______________________________________________________________________ 662 | 663 | ConsoleLog record 0,INCR 664 | 665 | kIDClass equ 13 666 | kFirstID equ 0x000d0001 667 | 668 | ;_______________________ 669 | ; Fields 670 | ;_______________________ 671 | 672 | ds.l 1 ; 00 673 | ds.l 1 ; 04 674 | ProcessID ds.l 1 ; 08 675 | ds.l 1 ; 0c 676 | 677 | Size equ * 678 | endr 679 | -------------------------------------------------------------------------------- /NanoKernel/NKPowerCalls.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKCache 4 | ; FlushCaches 5 | ; NKInterrupts 6 | ; IntReturn 7 | ; wordfill 8 | ; NKThud 9 | ; panic 10 | ; EXPORTS: 11 | ; InitIdleVecTable (=> NKInit) 12 | ; kcPowerDispatch (=> NKInit) 13 | 14 | 15 | #### ## ## #### ######## ## ## ######## ###### ######## ######## ## 16 | ## ### ## ## ## ## ## ## ## ## ## ## ## ## 17 | ## #### ## ## ## ## ## ## ## ## ## ## ## 18 | ## ## ## ## ## ## ## ## ###### ## ## ######## ## 19 | ## ## #### ## ## ## ## ## ## ## ## ## ## 20 | ## ## ### ## ## ## ## ## ## ## ## ## ## ## 21 | #### ## ## #### ## ### ######## ###### ## ######## ######## 22 | 23 | ; When we are asked via a PowerDispatch call to put a CPU into a non-full- 24 | ; on pwrmgt state, we will point its SPRG3 to this table. Any of these 25 | ; three interrupts will return the CPU to full-on mode, and we will return 26 | ; from the PowerDispatch call. Called at NK init time. 27 | 28 | align kIntAlign 29 | 30 | InitIdleVecTable 31 | 32 | mflr r9 33 | llabel r23, panic 34 | add r23, r23, r25 35 | addi r8, r1, PSA.VecBaseIdle 36 | li r22, VecTable.Size 37 | bl wordfill 38 | mtlr r9 39 | llabel r23, IntReturnToFullOn 40 | add r23, r23, r25 41 | stw r23, VecTable.SystemResetVector(r8) 42 | stw r23, VecTable.ExternalIntVector(r8) 43 | stw r23, VecTable.DecrementerVector(r8) 44 | blr 45 | 46 | 47 | ######## #### ###### ######## ### ######## ###### ## ## 48 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## 49 | ## ## ## ## ## ## ## ## ## ## ## ## 50 | ## ## ## ###### ######## ## ## ## ## ######### 51 | ## ## ## ## ## ######### ## ## ## ## 52 | ## ## ## ## ## ## ## ## ## ## ## ## ## 53 | ######## #### ###### ## ## ## ## ###### ## ## 54 | 55 | ; Called using 68k `$FE0F` or PPC `twi ... 5` 56 | 57 | ; ARG selector r3 (0-11), ... 58 | 59 | align kIntAlign 60 | 61 | kcPowerDispatch 62 | 63 | mtcr r7 64 | lwz r4, KDP.TestIntMaskInit(r1) 65 | cmplwi cr7, r3, 11 66 | mr r9, r13 67 | bc BO_IF, 8, @use_provided_mcr 68 | lwz r9, PSA.MCR(r1) 69 | @use_provided_mcr 70 | 71 | and. r8, r4, r9 72 | bgt cr7, PowerEarlyReturnError ; invalid selector 73 | bne PowerEarlyReturnSuccess 74 | 75 | cmplwi cr7, r3, 11 76 | beq cr7, PwrInfiniteLoop 77 | 78 | cmplwi cr7, r3, 8 79 | beq cr7, PwrSuspendSystem 80 | 81 | cmplwi cr7, r3, 9 82 | beq cr7, PwrSetICTC 83 | 84 | ; Fall through to 0-7: PwrIdle 85 | 86 | 87 | 88 | ##### ######## #### ######## ## ######## 89 | ## ## ## ## ## ## ## ## ## 90 | ## ## ## ## ## ## ## ## 91 | ## ## ####### ## ## ## ## ## ###### 92 | ## ## ## ## ## ## ## ## 93 | ## ## ## ## ## ## ## ## 94 | ##### ## #### ######## ######## ######## 95 | 96 | ; Selector 0-7 97 | 98 | ; Set the CPU static pwrmgt state to doze, idle or sleep, then return to 99 | ; full-on when we get an interrupt. 100 | 101 | ; ARG r3 & 1: which of the two pre-programmed pwrmgt states to invoke (see NKProcFlagsTbl.s) 102 | ; r3 & 4: whether to flush L1 and L2 caches 103 | 104 | ; Different 603+ chips have static power management states named "doze", 105 | ; "nap" and "sleep". A state is selected by setting the corresponding bit 106 | ; in HID0. The state is then invoked by setting MSR[POW]. The state is 107 | ; ended by a decrementer interrupt (doze/nap only) or external interrupt. 108 | ; This is a short term CPU-specific state, *not* system-wide "sleep". 109 | 110 | ; Because the NK timer code sets the decrementer, we can be sure that we 111 | ; will not miss a timer firing. 112 | 113 | PwrIdle 114 | 115 | ; Get us some breathing room 116 | 117 | _RegRangeToContextBlock r26, r31 118 | 119 | 120 | ; Activate the interrupt table that will rouse the CPU 121 | 122 | mfsprg r31, 3 ; will restore r31 => SPRG3 after state exited 123 | addi r8, r1, PSA.VecBaseIdle 124 | mtsprg 3, r8 125 | 126 | 127 | ; Save argument & 4 (run-cache-code flag) 128 | 129 | rlwinm r26, r3, 0, 29, 29 130 | 131 | 132 | ; Choose from the NK's two pre-programmed pwrmgt states for this CPU. 133 | ; Fail if we find zero (e.g. on the 601). 134 | 135 | ; arg pwrmgt state selector => r3 136 | ; r3 & 1 0=fail 1=DOZE 2=NAP 3=SLEEP 137 | ; ------ --------------------------- 138 | ; 0 (CpuSpecificByte1 >> 6) & 3 139 | ; 1 (CpuSpecificByte1 >> 4) & 3 140 | 141 | clrlwi r3, r3, 30 142 | lbz r8, KDP.CpuSpecificByte1(r1) 143 | slwi r3, r3, 1 144 | addi r3, r3, 26 145 | rlwnm r3, r8, r3, 30, 31 146 | cmpwi r3, 0 147 | beq PowerEarlyRestoreReturnError 148 | 149 | 150 | ; Depending on pre-programmed flags, set: 151 | ; HID0[NHR] ("not hard reset" flag) 152 | ; HID0[ptrmgt state selected above] 153 | 154 | lbz r9, KDP.CpuSpecificByte2(r1) 155 | cmpwi r9, 0 156 | beq @set_neither 157 | 158 | mfspr r27, hid0 ; will restore r27 => HID0 when system wakes below 159 | mr r8, r27 160 | cmpwi r9, 1 161 | beq @set_only_nhr 162 | 163 | oris r9, r3, 0x0100 ; set bit 7 164 | srw r9, r9, r9 ; shift right by 0-3 165 | rlwimi r8, r9, 0, 8, 10 ; keep bits 8/9/10 166 | @set_only_nhr 167 | 168 | oris r8, r8, 1 ; also set NHR 169 | mtspr hid0, r8 170 | @set_neither 171 | 172 | 173 | ; Flush L1 and L2 caches if argument & 4 174 | 175 | cmplwi r26, 4 176 | beql FlushCaches 177 | 178 | 179 | ; Set MSR bits to enter the selected pwrmgt state 180 | 181 | mfmsr r8 182 | ori r8, r8, 0x8002 ; Always set MSR[EE] and MSR[RI] so we can wake! 183 | cmplwi r3, 0 ; If using HID0[pwrmgt state], set MSR[POW] so it takes effect 184 | beq @no_pow 185 | oris r8, r8, 4 186 | @no_pow 187 | sync ; Apply MSR! 188 | mtmsr r8 189 | isync 190 | 191 | 192 | ; Loop while the state takes effect, then jump 4 bytes forward when we cop an interrupt 193 | 194 | b * 195 | IntReturnToFullOn 196 | 197 | 198 | ; Restore HID0 from r27, assuming that we mangled it 199 | 200 | lbz r8, KDP.CpuSpecificByte2(r1) 201 | cmpwi r8, 0 202 | beq @hid_was_not_changed 203 | mtspr hid0, r27 204 | @hid_was_not_changed 205 | 206 | 207 | ; Restore registers and return successfully to caller. 208 | ; Not sure about the decrementer stuff. 209 | 210 | mfsprg r1, 2 211 | mtlr r1 212 | mfsprg r1, 1 213 | 214 | lis r9, 0x7fff 215 | mfspr r8, dec 216 | mtspr dec, r9 217 | mtspr dec, r8 218 | 219 | li r3, 0 220 | 221 | PowerCallRestoreReturn 222 | 223 | mtsprg 3, r31 ; saved SPRG3 above 224 | 225 | _RegRangeFromContextBlock r26, r31 226 | 227 | b IntReturn 228 | 229 | 230 | 231 | ; Return islands for other calls 232 | 233 | PowerEarlyRestoreReturnError 234 | li r3, -0x7267 235 | b PowerCallRestoreReturn 236 | 237 | PowerEarlyReturnSuccess 238 | li r3, 0 239 | b IntReturn 240 | 241 | PowerEarlyReturnError 242 | li r3, -1 243 | b IntReturn 244 | 245 | 246 | 247 | ####### ###### ## ## ###### ######## ######## ## ## ######## 248 | ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## 249 | ## ## ## ## ## ## ## ## ## #### ## ## ## 250 | ####### ###### ## ## ###### ######## ###### ## ## ## ## ## 251 | ## ## ## ## ## ## ## ## ## #### ## ## 252 | ## ## ## ## ## ## ## ## ## ## ## ### ## ## 253 | ####### ###### ####### ###### ## ######## ## ## ######## 254 | 255 | ; Selector 8 256 | 257 | ; Put this, the last scheduled CPU, into SLEEP mode. 258 | ; Save state. Call ActuallySuspend. Restore state. Return. 259 | 260 | PwrSuspendSystem 261 | 262 | ; Cannot sleep if multiple CPUs are scheduled 263 | 264 | mfsprg r9, 0 265 | lwz r8, EWA.CPUBase + CPU.LLL + LLL.Freeform(r9) 266 | lwz r9, CoherenceGroup.ScheduledCpuCount(r8) 267 | cmpwi r9, 1 268 | li r3, -0x7267 269 | bgt IntReturn 270 | 271 | 272 | ; Some breathing room 273 | 274 | _RegRangeToContextBlock r26, r31 275 | 276 | 277 | bl FlushCaches 278 | 279 | 280 | ; Disable both L1 caches (via HID0) 281 | 282 | mfspr r9, hid0 283 | rlwinm r9, r9, 0, 18, 16 ; unset HID0[DCE] (data cache enable) 284 | rlwinm r9, r9, 0, 17, 15 ; unset HID0[ICE] (inst cache enable) 285 | mtspr hid0, r9 286 | sync 287 | isync 288 | 289 | 290 | ; Disable L2 cache (via L2CR, if present) 291 | 292 | lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 293 | andi. r26, r26, 1 << NKProcessorInfo.hasL2CR 294 | beq @no_need_to_deactivate_l2 295 | mfspr r9, l2cr 296 | clrlwi r9, r9, 1 ; unset L2CR[L2E] 297 | mtspr l2cr, r9 298 | sync 299 | isync 300 | addi r8, r1, PSA.ProcessorState 301 | stw r9, NKProcessorState.saveL2CR(r8) 302 | @no_need_to_deactivate_l2 303 | 304 | 305 | ; Save some GPRs 306 | 307 | stw r7, ContextBlock.Flags(r6) 308 | _RegRangeToContextBlock r2, r5 309 | _RegRangeToContextBlock r14, r25 310 | stw r13, ContextBlock.CR(r6) 311 | 312 | 313 | ; Save floats 314 | 315 | andi. r8, r11, 0x2000 ; MSR[FP] 316 | beq @no_save_float 317 | mfmsr r8 318 | ori r8, r8, 0x2000 ; ensure that MSR bit is set? 319 | mtmsr r8 320 | isync 321 | _FloatRangeToContextBlock f0, f16 322 | mffs f0 323 | _FloatRangeToContextBlock f17, f31 324 | stfd f0, ContextBlock.PageInSystemHeap(r6) ; ??? 325 | @no_save_float 326 | 327 | 328 | ; Save misc SPRs 329 | 330 | mfxer r9 331 | addi r16, r1, PSA.ProcessorState 332 | stw r9, ContextBlock.XER(r6) 333 | mfctr r9 334 | stw r9, ContextBlock.CTR(r6) 335 | stw r12, ContextBlock.FE000000(r6) 336 | stw r10, NKProcessorState.saveSRR0(r16) 337 | stw r11, NKProcessorState.saveSRR1(r16) 338 | mfspr r9, hid0 339 | stw r9, NKProcessorState.saveHID0(r16) 340 | 341 | 342 | ; Save timebase 343 | 344 | @tb_retry 345 | mftbu r9 346 | stw r9, NKProcessorState.saveTBU(r16) 347 | mftb r9 348 | stw r9, NKProcessorState.saveTBL(r16) 349 | mftbu r8 350 | lwz r9, NKProcessorState.saveTBU(r16) 351 | cmpw r8, r9 352 | bne @tb_retry 353 | 354 | 355 | ; Save MSR 356 | 357 | mfmsr r9 358 | stw r9, NKProcessorState.saveMSR(r16) 359 | 360 | 361 | ; Save SDR1 362 | 363 | mfspr r9, sdr1 364 | stw r9, NKProcessorState.saveSDR1(r16) 365 | 366 | 367 | ; Save BAT registers 368 | 369 | mfspr r9, dbat0u 370 | stw r9, NKProcessorState.saveDBAT0u(r16) 371 | mfspr r9, dbat0l 372 | stw r9, NKProcessorState.saveDBAT0l(r16) 373 | mfspr r9, dbat1u 374 | stw r9, NKProcessorState.saveDBAT1u(r16) 375 | mfspr r9, dbat1l 376 | stw r9, NKProcessorState.saveDBAT1l(r16) 377 | mfspr r9, dbat2u 378 | stw r9, NKProcessorState.saveDBAT2u(r16) 379 | mfspr r9, dbat2l 380 | stw r9, NKProcessorState.saveDBAT2l(r16) 381 | mfspr r9, dbat3u 382 | stw r9, NKProcessorState.saveDBAT3u(r16) 383 | mfspr r9, dbat3l 384 | stw r9, NKProcessorState.saveDBAT3l(r16) 385 | mfspr r9, ibat0u 386 | stw r9, NKProcessorState.saveIBAT0u(r16) 387 | mfspr r9, ibat0l 388 | stw r9, NKProcessorState.saveIBAT0l(r16) 389 | mfspr r9, ibat1u 390 | stw r9, NKProcessorState.saveIBAT1u(r16) 391 | mfspr r9, ibat1l 392 | stw r9, NKProcessorState.saveIBAT1l(r16) 393 | mfspr r9, ibat2u 394 | stw r9, NKProcessorState.saveIBAT2u(r16) 395 | mfspr r9, ibat2l 396 | stw r9, NKProcessorState.saveIBAT2l(r16) 397 | mfspr r9, ibat3u 398 | stw r9, NKProcessorState.saveIBAT3u(r16) 399 | mfspr r9, ibat3l 400 | stw r9, NKProcessorState.saveIBAT3l(r16) 401 | 402 | 403 | ; Save SPRGs 404 | 405 | mfsprg r9, 0 406 | stw r9, NKProcessorState.saveSPRG0(r16) 407 | mfsprg r9, 1 408 | stw r9, NKProcessorState.saveSPRG1(r16) 409 | mfsprg r9, 2 410 | stw r9, NKProcessorState.saveSPRG2(r16) 411 | mfsprg r9, 3 412 | stw r9, NKProcessorState.saveSPRG3(r16) 413 | 414 | 415 | ; Save ContextBlock ptr 416 | 417 | stw r6, NKProcessorState.saveContextPtr(r16) 418 | 419 | 420 | ; Do the thing. The BL gives us a useful restore address. 421 | 422 | bl ActuallySuspend 423 | 424 | 425 | lwz r1, EWA.r1(r1) 426 | addi r16, r1, PSA.ProcessorState 427 | 428 | 429 | ; Do something evil to the segment registers? 430 | 431 | lisori r8, 0x1000000 432 | lis r9, 0 433 | @srin_loop 434 | subis r9, r9, 0x1000 435 | addis r8, r8, -0x10 436 | mr. r9, r9 437 | mtsrin r8, r9 438 | bne @srin_loop 439 | isync 440 | 441 | 442 | ; Reactivate L1 cache 443 | 444 | mfspr r9, hid0 445 | li r8, 0x800 ; HID0[ICFI] invalidate icache 446 | ori r8, r8, 0x200 ; HID0[SPD] disable spec cache accesses 447 | or r9, r9, r8 448 | mtspr hid0, r9 449 | isync 450 | andc r9, r9, r8 ; now undo that? 451 | mtspr hid0, r9 452 | isync 453 | ori r9, r9, 0x8000 ; set HID0[ICE] 454 | ori r9, r9, 0x4000 ; set HID0[DCE] 455 | mtspr hid0, r9 456 | isync 457 | 458 | 459 | ; Reactivate L2 cache 460 | 461 | lwz r26, KDP.ProcessorInfo + NKProcessorInfo.ProcessorFlags(r1) 462 | andi. r26, r26, 1 << NKProcessorInfo.hasL2CR 463 | beq @no_need_to_reactivate_l2 464 | lwz r8, KDP.ProcessorInfo + NKProcessorInfo.ProcessorL2DSize(r1) 465 | mr. r8, r8 466 | beq @no_need_to_reactivate_l2 467 | 468 | mfspr r9, hid0 469 | rlwinm r9, r9, 0, 12, 10 470 | mtspr hid0, r9 471 | isync 472 | 473 | lwz r9, NKProcessorState.saveL2CR(r16) 474 | mtspr l2cr, r9 475 | sync 476 | isync 477 | lis r8, 0x20 ; set L2CR[L2I] to invalidate L2 cache 478 | or r8, r9, r8 479 | mtspr l2cr, r8 480 | sync 481 | isync 482 | 483 | ; spin while bottom bit (reserved) is set??? 484 | @l2_reactivate_loop 485 | mfspr r8, l2cr 486 | rlwinm. r8, r8, 31, 0, 0 487 | bne @l2_reactivate_loop 488 | 489 | 490 | mfspr r8, l2cr 491 | lisori r9, 0xffdfffff ; unset bit 6 (reserved?) 492 | and r8, r8, r9 493 | mtspr l2cr, r8 494 | sync 495 | 496 | 497 | mfspr r8, hid0 498 | oris r8, r8, 0x0010 ; set HID0[HIGH_BAT_EN] (was HID0[DOZE]) 499 | mtspr hid0, r8 500 | isync 501 | 502 | 503 | mfspr r8, l2cr 504 | oris r8, r8, 0x8000 ; set L2CR[L2E] 505 | mtspr l2cr, r8 506 | sync 507 | isync 508 | @no_need_to_reactivate_l2 509 | 510 | 511 | ; Still working on this... 512 | 513 | lwz r6, NKProcessorState.saveContextPtr(r16) 514 | lwz r7, ContextBlock.Flags(r6) 515 | lwz r13, ContextBlock.CR(r6) 516 | lwz r9, ContextBlock.CTR(r6) 517 | mtctr r9 518 | lwz r12, ContextBlock.FE000000(r6) 519 | lwz r9, ContextBlock.XER(r6) 520 | mtxer r9 521 | lwz r10, NKProcessorState.saveSRR0(r16) 522 | lwz r11, NKProcessorState.saveSRR1(r16) 523 | 524 | 525 | ; Load some GPRs 526 | 527 | _RegRangeFromContextBlock r2, r5 528 | _RegRangeFromContextBlock r14, r15 529 | _RegRangeFromContextBlock r17, r31 530 | 531 | 532 | ; Load floats 533 | 534 | andi. r8, r11, 0x2000 ; MSR[FP] 535 | beq @no_restore_float 536 | mfmsr r8 537 | ori r8, r8, 0x2000 ; ensure that MSR bit is set? 538 | mtmsr r8 539 | isync 540 | lfd f31, ContextBlock.PageInSystemHeap(r6) ; bit odd 541 | _FloatRangeFromContextBlock f0, f8 542 | mtfsf 0xff, f31 543 | _FloatRangeFromContextBlock f9, f31 544 | @no_restore_float 545 | 546 | 547 | ; Load HID0, plus ICE and DCE bits 548 | 549 | lwz r9, NKProcessorState.saveHID0(r16) 550 | ori r9, r9, 0x8000 551 | ori r9, r9, 0x4000 552 | mtspr hid0, r9 553 | sync 554 | isync 555 | 556 | 557 | ; Load timebase 558 | 559 | lwz r9, NKProcessorState.saveTBU(r16) 560 | mtspr tbu, r9 561 | lwz r9, NKProcessorState.saveTBL(r16) 562 | mtspr tbl, r9 563 | 564 | 565 | ; Set decrementer quite low? 566 | 567 | li r9, 1 568 | mtspr dec, r9 569 | 570 | 571 | ; Load MSR 572 | 573 | lwz r9, NKProcessorState.saveMSR(r16) 574 | mtmsr r9 575 | sync 576 | isync 577 | 578 | 579 | ; Load SDR1 580 | 581 | lwz r9, NKProcessorState.saveSDR1(r16) 582 | mtspr sdr1, r9 583 | 584 | 585 | ; Load SPRGs 586 | 587 | lwz r9, NKProcessorState.saveSPRG0(r16) 588 | mtsprg 0, r9 589 | lwz r9, NKProcessorState.saveSPRG1(r16) 590 | mtsprg 1, r9 591 | lwz r9, NKProcessorState.saveSPRG2(r16) 592 | mtsprg 2, r9 593 | lwz r9, NKProcessorState.saveSPRG3(r16) 594 | mtsprg 3, r9 595 | 596 | 597 | ; Load BAT registers 598 | 599 | lwz r9, NKProcessorState.saveDBAT0u(r16) 600 | mtspr dbat0u, r9 601 | lwz r9, NKProcessorState.saveDBAT0l(r16) 602 | mtspr dbat0l, r9 603 | lwz r9, NKProcessorState.saveDBAT1u(r16) 604 | mtspr dbat1u, r9 605 | lwz r9, NKProcessorState.saveDBAT1l(r16) 606 | mtspr dbat1l, r9 607 | lwz r9, NKProcessorState.saveDBAT2u(r16) 608 | mtspr dbat2u, r9 609 | lwz r9, NKProcessorState.saveDBAT2l(r16) 610 | mtspr dbat2l, r9 611 | lwz r9, NKProcessorState.saveDBAT3u(r16) 612 | mtspr dbat3u, r9 613 | lwz r9, NKProcessorState.saveDBAT3l(r16) 614 | mtspr dbat3l, r9 615 | lwz r9, NKProcessorState.saveIBAT0u(r16) 616 | mtspr ibat0u, r9 617 | lwz r9, NKProcessorState.saveIBAT0l(r16) 618 | mtspr ibat0l, r9 619 | lwz r9, NKProcessorState.saveIBAT1u(r16) 620 | mtspr ibat1u, r9 621 | lwz r9, NKProcessorState.saveIBAT1l(r16) 622 | mtspr ibat1l, r9 623 | lwz r9, NKProcessorState.saveIBAT2u(r16) 624 | mtspr ibat2u, r9 625 | lwz r9, NKProcessorState.saveIBAT2l(r16) 626 | mtspr ibat2l, r9 627 | lwz r9, NKProcessorState.saveIBAT3u(r16) 628 | mtspr ibat3u, r9 629 | lwz r9, NKProcessorState.saveIBAT3l(r16) 630 | mtspr ibat3l, r9 631 | 632 | 633 | ; And reclaim the register we were using for ProcessorState 634 | 635 | _RegRangeFromContextBlock r16, r16 636 | 637 | 638 | ; Hooray! We're back! 639 | 640 | li r3, 0 641 | b IntReturn 642 | 643 | 644 | 645 | ### ###### ## ## ###### ######## ######## ## ## ######## ### 646 | ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## 647 | ## ## ## ## ## ## ## ## #### ## ## ## ## 648 | ## ###### ## ## ###### ######## ###### ## ## ## ## ## ## 649 | ## ## ## ## ## ## ## ## #### ## ## ## 650 | ## ## ## ## ## ## ## ## ## ## ### ## ## ## 651 | ### ###### ####### ###### ## ######## ## ## ######## ### 652 | 653 | ActuallySuspend 654 | mflr r9 655 | stw r9, NKProcessorState.saveReturnAddr(r16) 656 | stw r1, NKProcessorState.saveKernelDataPtr(r16) 657 | addi r9, r16, NKProcessorState.saveKernelDataPtr - 4 ; so that 4(r9) goes to r1? 658 | li r0, 0 659 | stw r9, 0(0) 660 | lisori r9, 'Lars' 661 | stw r9, 4(0) 662 | 663 | 664 | mfspr r9, hid0 665 | andis. r9, r9, 0x0020 ; mask: only HID0[SLEEP] 666 | mtspr hid0, r9 667 | 668 | 669 | mfmsr r8 670 | oris r8, r8, 0x0004 ; set MSR[POW] (but not yet) 671 | 672 | 673 | mfspr r9, hid0 674 | ori r9, r9, 0x8000 ; set HID0[ICE] 675 | mtspr hid0, r9 676 | 677 | 678 | ; Get address of this table => r9 679 | bl @l 680 | @l mflr r9 681 | addi r9, r9, @table_of_sixteen_zeros - @l 682 | 683 | 684 | lisori r1, 0xcafebabe 685 | 686 | 687 | b @evil_aligned_sleep_loop 688 | align 8 689 | @evil_aligned_sleep_loop 690 | sync 691 | mtmsr r8 ; sleep now 692 | isync 693 | cmpwi r1, 0 694 | beq @evil_aligned_sleep_loop ; re-sleep until the world is sane? 695 | lwz r0, 0(r9) 696 | andi. r1, r1, 0 697 | b @evil_aligned_sleep_loop ; actually, there is no escape 698 | 699 | 700 | align 8 701 | @table_of_sixteen_zeros 702 | dcb.b 16, 0 703 | 704 | 705 | 706 | ####### ###### ######## ######## #### ###### ######## ###### 707 | ## ## ## ## ## ## ## ## ## ## ## ## 708 | ## ## ## ## ## ## ## ## ## 709 | ######## ###### ###### ## ## ## ## ## 710 | ## ## ## ## ## ## ## ## 711 | ## ## ## ## ## ## ## ## ## ## ## ## 712 | ####### ###### ######## ## #### ###### ## ###### 713 | 714 | ; Selector 9 715 | 716 | ; Set ICTC (Instruction Cache Throttling Control) register 717 | ; (used to reduce temp without adjusting clock) 718 | 719 | ; ARG value r5 720 | 721 | PwrSetICTC 722 | 723 | mtspr 1019, r5 724 | li r3, 0 725 | b IntReturn 726 | 727 | 728 | 729 | ## ## ## ####### ####### ######## 730 | #### #### ## ## ## ## ## ## ## 731 | ## ## ## ## ## ## ## ## ## 732 | ## ## ## ## ## ## ## ######## 733 | ## ## ## ## ## ## ## ## 734 | ## ## ## ## ## ## ## ## 735 | ###### ###### ######## ####### ####### ## 736 | 737 | ; Selector 11 738 | 739 | PwrInfiniteLoop 740 | 741 | b * 742 | -------------------------------------------------------------------------------- /NanoKernel/NKTimers.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKConsoleLog 4 | ; getchar 5 | ; printb 6 | ; printd 7 | ; printh 8 | ; printw 9 | ; NKIndex 10 | ; DeleteID 11 | ; LookupID 12 | ; NKPoolAllocator 13 | ; PoolAllocClear 14 | ; PoolFree 15 | ; NKScheduler 16 | ; CalculateTimeslice 17 | ; FlagSchEvaluationIfTaskRequires 18 | ; SchRdyTaskNow 19 | ; SchTaskUnrdy 20 | ; clear_cr0_lt 21 | ; major_0x149d4 22 | ; NKSync 23 | ; EnqueueMessage 24 | ; SetEvent 25 | ; SignalSemaphore 26 | ; NKThud 27 | ; panic 28 | ; panic_non_interactive 29 | ; EXPORTS: 30 | ; DequeueTimer (=> NKMPCalls, NKPrimaryIntHandlers, NKSync, NKTasks) 31 | ; EnqueueTimer (=> NKMPCalls, NKSync) 32 | ; GetTime (=> NKMPCalls, NKScheduler, NKSync, NKTasks) 33 | ; InitTMRQs (=> NKInit) 34 | ; SetTimesliceFromCurTime (=> NKScheduler) 35 | ; StartTimeslicing (=> NKInit) 36 | ; TimebaseTicksPerPeriod (=> NKScheduler, NKSync) 37 | ; TimerDispatch (=> NKInterrupts) 38 | 39 | 40 | Local_Panic set * 41 | b panic 42 | 43 | 44 | 45 | InitTMRQs ; OUTSIDE REFERER 46 | addi r9, r1, PSA.TimerQueue 47 | lis r8, 0x544d 48 | ori r8, r8, 0x5251 49 | stw r8, 0x0004(r9) 50 | stw r9, 0x0008(r9) 51 | stw r9, 0x000c(r9) 52 | li r8, 0x00 53 | stb r8, 0x0014(r9) 54 | li r8, 0x01 55 | stb r8, 0x0016(r9) 56 | stb r8, 0x0017(r9) 57 | lis r8, 0x7fff 58 | ori r8, r8, 0xffff 59 | mtspr dec, r8 60 | stw r8, 0x0038(r9) 61 | oris r8, r8, 0xffff 62 | stw r8, 0x003c(r9) 63 | mfspr r8, pvr 64 | rlwinm. r8, r8, 0, 0, 14 65 | beq InitTMRQs_0x7c 66 | mflr r30 67 | li r8, 0x40 68 | 69 | ; r1 = kdp 70 | ; r8 = size 71 | bl PoolAllocClear 72 | ; r8 = ptr 73 | 74 | mr. r31, r8 75 | beq Local_Panic 76 | stw r31, PSA.OtherTimerQueuePtr(r1) 77 | li r9, 0x07 78 | stb r9, 0x0014(r31) 79 | li r9, 0x01 80 | stb r9, 0x0016(r31) 81 | mtlr r30 82 | 83 | InitTMRQs_0x7c 84 | mfspr r8, pvr 85 | rlwinm. r8, r8, 0, 0, 14 86 | beq InitTMRQs_0xb4 87 | mflr r30 88 | li r8, 0x40 89 | 90 | ; r1 = kdp 91 | ; r8 = size 92 | bl PoolAllocClear 93 | ; r8 = ptr 94 | 95 | mr. r31, r8 96 | beq Local_Panic 97 | stw r31, PSA._364(r1) 98 | li r9, 0x08 99 | stb r9, 0x0014(r31) 100 | li r9, 0x01 101 | stb r9, 0x0016(r31) 102 | mtlr r30 103 | 104 | InitTMRQs_0xb4 105 | 106 | 107 | ; Activate the NanoDebugger (whatever that is...) 108 | 109 | lwz r30, KDP.PA_ConfigInfo(r1) 110 | lhz r31, NKConfigurationInfo.Debug(r30) 111 | cmplwi r31, NKConfigurationInfo.DebugThreshold 112 | blt @nodebug 113 | 114 | lwz r31, NKConfigurationInfo.DebugFlags(r30) 115 | rlwinm. r8, r31, 0, NKConfigurationInfo.NanodbgrFlagBit, NKConfigurationInfo.NanodbgrFlagBit 116 | beq @nodebug 117 | 118 | lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1) 119 | _bset r8, r8, NKNanoKernelInfo.NanodbgrFlagBit 120 | stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1) 121 | 122 | mflr r30 123 | 124 | li r8, Timer.Size 125 | bl PoolAllocClear ; one of those weird queue structures 126 | mr. r31, r8 127 | beq Local_Panic 128 | 129 | li r9, Timer.kKind6 130 | stb r9, Timer.Kind(r31) 131 | 132 | li r9, 1 133 | stb r9, Timer.KeepAfterFiring(r31) 134 | 135 | bl GetTime 136 | stw r8, Timer.Time(r31) 137 | stw r9, Timer.Time+4(r31) 138 | 139 | mr r8, r31 140 | bl EnqueueTimer 141 | 142 | _log 'Nanodebugger activated.^n' 143 | 144 | mtlr r30 145 | @nodebug 146 | blr 147 | 148 | 149 | 150 | TimerTable 151 | 152 | dc.l TimerFireUnknownKind - NKTop ; Timer.kKind0 153 | dc.l TimerFire1 - NKTop ; Timer.kKind1 154 | dc.l TimerFire2 - NKTop ; Timer.kKind2 155 | dc.l TimerFire3 - NKTop ; Timer.kKind3 156 | dc.l TimerFire4 - NKTop ; Timer.kKind4 157 | dc.l TimerFire5 - NKTop ; Timer.kKind5 158 | dc.l TimerFire6 - NKTop ; Timer.kKind6 159 | dc.l TimerFire7 - NKTop ; Timer.kKind7 160 | dc.l TimerFire8 - NKTop ; Timer.kKind8 161 | 162 | TimerDispatch ; OUTSIDE REFERER 163 | mflr r19 164 | mfsprg r18, 0 165 | stw r19, EWA.TimerDispatchLR(r18) 166 | 167 | TimerDispatch_0x30 ; OUTSIDE REFERER 168 | mfspr r8, pvr 169 | rlwinm. r8, r8, 0, 0, 14 170 | beq @is_601 171 | 172 | ;not 601 173 | @gettime_loop_non_601 174 | mftbu r8 175 | mftb r9 176 | mftbu r16 177 | cmpw r8, r16 178 | bne- @gettime_loop_non_601 179 | b @common 180 | 181 | @is_601 182 | @gettime_loop_601 183 | mfspr r8, rtcu 184 | mfspr r9, rtcl 185 | mfspr r16, rtcu 186 | cmpw r8, r16 187 | bne- @gettime_loop_601 188 | 189 | dialect POWER 190 | 191 | liu r16, 1000000000 >> 16 192 | oril r16, r16, 1000000000 & 0xffff 193 | 194 | mfmq r17 195 | mul r8, r16, r8 196 | mfmq r16 197 | mtmq r17 198 | 199 | mfxer r17 200 | a r9, r16, r9 201 | aze r8, r8 202 | mtxer r17 203 | 204 | dialect PowerPC 205 | @common 206 | 207 | 208 | 209 | lbz r19, EWA.GlobalTimeIsValid(r18) 210 | addi r30, r18, EWA.Base 211 | cmpwi r19, 1 212 | lwz r16, EWA.GlobalTime - EWA.Base(r30) 213 | bne timer_earlier_than_sometime 214 | lwz r17, EWA.GlobalTime + 4 - EWA.Base(r30) 215 | 216 | _b_if_time_gt r16, r8, timer_earlier_than_sometime 217 | @skipbranch 218 | li r19, 0x00 219 | stw r30, -0x0254(r18) 220 | stb r19, 0x0017(r30) 221 | b TimerFire4_0x10 222 | 223 | timer_earlier_than_sometime 224 | lwz r30, PSA.TimerQueue + LLL.Next(r1) 225 | lwz r16, 0x0038(r30) 226 | lwz r17, 0x003c(r30) 227 | 228 | _b_if_time_gt r16, r8, TimerDispatch_0x188 229 | 230 | RemoveFromList r30, scratch1=r19, scratch2=r20 231 | lwz r19, 0x064c(r1) 232 | lbz r20, Timer.Kind(r30) 233 | rlwimi r19, r20, 2, 23, 29 234 | cmplwi r20, 0x09 235 | llabel r20, TimerTable 236 | li r21, 0x00 237 | add r20, r20, r19 238 | bgel Local_Panic 239 | stb r21, 0x0017(r30) 240 | lwz r20, 0x0000(r20) 241 | add r20, r20, r19 242 | mtlr r20 243 | stw r30, -0x0254(r18) 244 | blr 245 | 246 | TimerDispatch_0x144 247 | mfsprg r18, 0 248 | lwz r30, -0x0254(r18) 249 | lbz r19, 0x0016(r30) 250 | cmpwi r19, 0x01 251 | lwz r8, 0x0000(r30) 252 | beq TimerDispatch_0x30 253 | bl DeleteID 254 | mr r8, r30 255 | bl PoolFree 256 | lwz r8, 0x001c(r30) 257 | cmpwi r8, 0x00 258 | beq TimerDispatch_0x180 259 | bl PoolFree 260 | li r8, 0x00 261 | stw r8, 0x001c(r30) 262 | 263 | TimerDispatch_0x180: 264 | mfsprg r18, 0 265 | b TimerDispatch_0x30 266 | 267 | TimerDispatch_0x188 268 | lwz r19, EWA.TimerDispatchLR(r18) 269 | mtlr r19 270 | b SetTimesliceFromCurTimeAndTripTime 271 | 272 | 273 | 274 | StartTimeslicing ; OUTSIDE REFERER 275 | mfsprg r19, 0 276 | 277 | li r8, 1 278 | stb r8, EWA.GlobalTimeIsValid(r19) 279 | 280 | li r8, 0 281 | stw r8, EWA.GlobalTime(r19) 282 | stw r8, EWA.GlobalTime + 4(r19) 283 | 284 | mflr r19 285 | _log 'Starting timeslicing^n' 286 | mtlr r19 287 | 288 | 289 | 290 | 291 | ; CLOB r8/r9, r16-r21 292 | 293 | SetTimeslice 294 | 295 | mflr r19 296 | bl GetTime 297 | mtlr r19 298 | 299 | 300 | 301 | 302 | ; ARG TimeBase r8/r9 curTime 303 | ; CLOB r16-r21 304 | 305 | SetTimesliceFromCurTime 306 | 307 | ; This should get the most distant time??? 308 | lwz r18, PSA.TimerQueue + LLL.Next(r1) 309 | lwz r16, Timer.Time(r18) 310 | lwz r17, Timer.Time+4(r18) 311 | 312 | 313 | 314 | 315 | ; ARG TimeBase r8/r9 curTime, TimeBase r16/r17 TripTime 316 | ; CLOB r18-r21 317 | 318 | SetTimesliceFromCurTimeAndTripTime 319 | 320 | mfxer r20 321 | mfsprg r19, 0 322 | 323 | lis r21, 0x7fff 324 | lbz r18, EWA.GlobalTimeIsValid(r19) 325 | ori r21, r21, 0xffff 326 | cmpwi r18, 1 327 | 328 | ; r16/r17 = soonest(last timer, global PSA time if available) 329 | 330 | bne global_time_invalid 331 | lwz r18, EWA.GlobalTime(r19) 332 | lwz r19, EWA.GlobalTime+4(r19) 333 | 334 | _b_if_time_le r16, r18, last_timer_fires_sooner 335 | mr r17, r19 336 | mr r16, r18 337 | last_timer_fires_sooner 338 | global_time_invalid 339 | 340 | 341 | ; Subtract the current time (or what we were passed in r8/r9) from that time 342 | subfc r17, r9, r17 343 | subfe. r16, r8, r16 344 | mtxer r20 345 | 346 | blt @that_time_has_passed ; hi bit of r16 = 1 347 | bne @that_time_is_in_future ; 348 | cmplw r16, r21 ; typo? should be r17??? 349 | bgt @that_time_is_in_future ; will never be taken... 350 | 351 | ; When the times are roughly equal? 352 | mtspr dec, r17 353 | blr 354 | 355 | @that_time_is_in_future 356 | mtspr dec, r21 357 | blr 358 | 359 | @that_time_has_passed 360 | mtspr dec, r21 361 | mtspr dec, r16 ; this makes nearly no sense! 362 | blr 363 | 364 | 365 | 366 | ; TimerFire0 367 | 368 | TimerFireUnknownKind 369 | _log 'TimerInformation.kind is zero??^n' 370 | 371 | 372 | 373 | ; TimerFire1 374 | 375 | TimerFire1 ; OUTSIDE REFERER 376 | bl Local_Panic 377 | lwz r18, 0x0018(r30) 378 | stw r16, 0x0080(r18) 379 | stw r17, 0x0084(r18) 380 | lwz r8, 0x0018(r30) 381 | li r16, 0x00 382 | lbz r17, 0x0018(r8) 383 | lwz r19, 0x0088(r8) 384 | cmpwi r17, 0x00 385 | stw r16, 0x011c(r19) 386 | bne TimerFire1_0x64 387 | addi r16, r8, 0x08 388 | RemoveFromList r16, scratch1=r17, scratch2=r19 389 | li r17, 0x01 390 | stb r17, 0x0019(r8) 391 | bl SchRdyTaskNow 392 | bl CalculateTimeslice 393 | bl FlagSchEvaluationIfTaskRequires 394 | b TimerDispatch_0x144 395 | 396 | TimerFire1_0x64 397 | lwz r16, 0x0064(r8) 398 | rlwinm. r16, r16, 0, 30, 30 399 | 400 | 401 | 402 | ; TimerFire2 403 | 404 | TimerFire2 ; OUTSIDE REFERER 405 | bne TimerDispatch_0x144 406 | bl Local_Panic 407 | lwz r18, 0x0018(r30) 408 | stw r16, 0x0080(r18) 409 | stw r17, 0x0084(r18) 410 | lwz r8, 0x0018(r30) 411 | li r16, -0x7270 412 | lbz r17, 0x0018(r8) 413 | lwz r18, 0x0088(r8) 414 | cmpwi r17, 0x00 415 | bne TimerFire3_0x8 416 | stw r16, 0x011c(r18) 417 | lwz r8, 0x0008(r8) 418 | lwz r8, 0x0000(r8) 419 | 420 | ; r8 = id 421 | bl LookupID 422 | cmpwi r9, Queue.kIDClass 423 | 424 | cmpwi cr1, r9, 0x05 425 | beq TimerFire2_0x8c 426 | beq cr1, TimerFire2_0x7c 427 | cmpwi r9, 0x09 428 | cmpwi cr1, r9, 0x06 429 | beq TimerFire2_0x6c 430 | bne cr1, Local_Panic 431 | lwz r16, 0x0020(r8) 432 | addi r16, r16, -0x01 433 | stw r16, 0x0020(r8) 434 | b TimerFire2_0x98 435 | 436 | TimerFire2_0x6c 437 | lwz r16, 0x001c(r8) 438 | addi r16, r16, -0x01 439 | stw r16, 0x001c(r8) 440 | b TimerFire2_0x98 441 | 442 | TimerFire2_0x7c 443 | lwz r16, 0x001c(r8) 444 | addi r16, r16, -0x01 445 | stw r16, 0x001c(r8) 446 | b TimerFire2_0x98 447 | 448 | TimerFire2_0x8c 449 | lwz r16, 0x002c(r8) 450 | addi r16, r16, -0x01 451 | stw r16, 0x002c(r8) 452 | 453 | TimerFire2_0x98 454 | lwz r8, 0x0018(r30) 455 | addi r16, r8, 0x08 456 | RemoveFromList r16, scratch1=r17, scratch2=r18 457 | bl SchRdyTaskNow 458 | 459 | 460 | 461 | ; TimerFire3 462 | 463 | TimerFire3 ; OUTSIDE REFERER 464 | bl FlagSchEvaluationIfTaskRequires 465 | b TimerDispatch_0x144 466 | 467 | TimerFire3_0x8 ; OUTSIDE REFERER 468 | b Local_Panic 469 | 470 | 471 | 472 | ; major_0x13258 473 | 474 | ; Dead code -- probably removed from TimerTable 475 | 476 | lwz r8, 0x0018(r30) 477 | 478 | ; r8 = id 479 | bl LookupID 480 | cmpwi r9, Queue.kIDClass 481 | 482 | mr r31, r8 483 | bne major_0x13258_0x68 484 | lwz r16, 0x0024(r31) 485 | lwz r8, 0x001c(r30) 486 | cmpwi r16, 0x00 487 | cmpwi cr1, r8, 0x00 488 | beq major_0x13258_0x40 489 | lwz r17, 0x0028(r31) 490 | mr. r8, r17 491 | lwz r17, 0x0008(r17) 492 | beq major_0x13258_0x68 493 | stw r17, 0x0028(r31) 494 | b major_0x13258_0x4c 495 | 496 | major_0x13258_0x40 497 | beq cr1, major_0x13258_0x68 498 | li r16, 0x00 499 | stw r16, 0x001c(r30) 500 | 501 | major_0x13258_0x4c 502 | lwz r16, 0x0020(r30) 503 | lwz r17, 0x0024(r30) 504 | lwz r18, 0x0028(r30) 505 | stw r16, 0x0010(r8) 506 | stw r17, 0x0014(r8) 507 | stw r18, 0x0018(r8) 508 | bl EnqueueMessage ; Message *r8, Queue *r31 509 | 510 | major_0x13258_0x68 511 | lwz r8, 0x0034(r30) 512 | 513 | ; r8 = id 514 | bl LookupID 515 | cmpwi r9, Semaphore.kIDClass 516 | 517 | mr r31, r8 518 | bne major_0x13258_0x80 519 | bl SignalSemaphore 520 | 521 | major_0x13258_0x80 522 | lwz r8, 0x002c(r30) 523 | 524 | ; r8 = id 525 | bl LookupID 526 | cmpwi r9, EventGroup.kIDClass 527 | 528 | mr r31, r8 529 | 530 | 531 | 532 | ; TimerFire4 533 | 534 | TimerFire4 ; OUTSIDE REFERER 535 | bne TimerFire4_0xc 536 | lwz r8, 0x0030(r30) 537 | bl SetEvent 538 | 539 | TimerFire4_0xc 540 | b TimerDispatch_0x144 541 | 542 | TimerFire4_0x10 ; OUTSIDE REFERER 543 | mfsprg r28, 0 544 | lwz r29, -0x0008(r28) 545 | mr r8, r29 546 | bl SchTaskUnrdy 547 | lbz r17, 0x0019(r29) 548 | cmpwi r17, 0x02 549 | bge TimerFire4_0x64 550 | mr r8, r29 551 | lwz r16, 0x0038(r30) 552 | lwz r17, 0x003c(r30) 553 | bl clear_cr0_lt 554 | bge TimerFire4_0x50 555 | mr r8, r29 556 | bl SchRdyTaskNow 557 | bl CalculateTimeslice 558 | b TimerFire5_0x8 559 | 560 | TimerFire4_0x50 561 | li r18, 0x02 562 | stb r18, 0x0019(r29) 563 | mr r8, r29 564 | bl SchRdyTaskNow 565 | b TimerFire5_0x8 566 | 567 | TimerFire4_0x64 568 | mr r8, r29 569 | 570 | 571 | 572 | ; TimerFire5 573 | 574 | TimerFire5 ; OUTSIDE REFERER 575 | bl SchRdyTaskNow 576 | bl major_0x149d4 577 | 578 | TimerFire5_0x8 ; OUTSIDE REFERER 579 | bl FlagSchEvaluationIfTaskRequires 580 | mfsprg r18, 0 581 | b TimerDispatch_0x30 582 | 583 | 584 | 585 | ; major_0x13364 586 | 587 | ; Dead code -- probably removed from TimerTable 588 | 589 | _log 'Heartbeat: Ext ' 590 | lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1) 591 | mr r8, r16 592 | bl printd 593 | 594 | _log 'Alerts ' 595 | lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.AlertCount(r1) 596 | mr r8, r16 597 | bl printd 598 | 599 | _log 'Blue cpu-' 600 | lwz r17, PSA.PA_BlueTask(r1) 601 | lhz r16, Task.CPUIndex(r17) 602 | mr r8, r16 603 | bl printb 604 | 605 | _log 'state-' 606 | lbz r16, Task.State(r17) 607 | mr r8, r16 608 | bl printb 609 | 610 | _log 'scr-' 611 | lwz r16, KDP.PA_ECB(r1) 612 | lwz r18, KDP.PostIntMaskInit(r1) 613 | lwz r16, ContextBlock.CR(r16) 614 | and r16, r16, r18 615 | mr r8, r16 616 | bl printw 617 | 618 | _log 'mcr-' 619 | lwz r16, PSA.MCR(r1) 620 | mr r8, r16 621 | bl printw 622 | 623 | _log 'IPL-' 624 | lwz r16, KDP.PA_EmulatorIplValue(r1) 625 | lhz r16, 0(r16) 626 | mr r8, r16 627 | bl printh 628 | 629 | _log 'eSR-' 630 | lwz r16, KDP.PA_ECB(r1) 631 | lwz r16, ContextBlock.r25(r16) 632 | andi. r16, r16, 7 633 | mr r8, r16 634 | bl printb 635 | _log '^n' 636 | 637 | mfxer r19 638 | lwz r16, 0x0038(r30) 639 | lwz r17, 0x003c(r30) 640 | lwz r18, 0x0f2c(r1) 641 | slwi r18, r18, 3 642 | addc r17, r17, r18 643 | 644 | 645 | 646 | ; TimerFire7 647 | 648 | TimerFire7 ; OUTSIDE REFERER 649 | addze r16, r16 650 | stw r16, 0x0038(r30) 651 | stw r17, 0x003c(r30) 652 | mtxer r19 653 | mr r8, r30 654 | bl EnqueueTimer 655 | b TimerDispatch_0x144 656 | 657 | 658 | 659 | ; major_0x134d8 660 | 661 | ; Dead code -- probably removed from TimerTable 662 | 663 | lwz r18, PSA.DecClockRateHzCopy(r1) 664 | lwz r19, 0x0f88(r1) 665 | subf. r19, r18, r19 666 | ble TimerFire8_0x1c 667 | srwi r19, r19, 11 668 | mfxer r20 669 | 670 | major_0x134d8_0x18 671 | mftbu r16 672 | mftb r17, 0x10c 673 | mftbu r18 674 | cmpw r16, r18 675 | li r18, 0x00 676 | bne- major_0x134d8_0x18 677 | mttb r18 678 | addc r17, r17, r19 679 | addze r16, r16 680 | mttbu r16 681 | mttb r17 682 | lwz r18, PSA.DecClockRateHzCopy(r1) 683 | srwi r18, r18, 11 684 | 685 | 686 | 687 | ; TimerFire8 688 | 689 | TimerFire8 ; OUTSIDE REFERER 690 | addc r17, r17, r18 691 | addze r16, r16 692 | stw r16, 0x0038(r30) 693 | stw r17, 0x003c(r30) 694 | mtxer r20 695 | mr r8, r30 696 | bl EnqueueTimer 697 | 698 | TimerFire8_0x1c ; OUTSIDE REFERER 699 | b TimerDispatch_0x144 700 | 701 | 702 | 703 | ; major_0x13544 704 | 705 | ; Dead code -- probably removed from TimerTable 706 | 707 | lwz r19, PSA._36c(r1) 708 | mfxer r20 709 | cmpwi cr1, r19, 0x00 710 | srawi r8, r19, 31 711 | beq cr1, TimerFire6_0x4 712 | 713 | major_0x13544_0x14 714 | mftbu r16 715 | mftb r17, 0x10c 716 | mftbu r18 717 | cmpw r16, r18 718 | li r18, 0x00 719 | bne- major_0x13544_0x14 720 | mttb r18 721 | addc r19, r17, r19 722 | adde r18, r16, r8 723 | mttbu r18 724 | mttb r19 725 | bgt cr1, major_0x13544_0x64 726 | 727 | major_0x13544_0x44 728 | mftbu r18 729 | mftb r19, 0x10c 730 | mftbu r8 731 | cmpw r18, r8 732 | bne- major_0x13544_0x44 733 | subfc r19, r17, r19 734 | subfe. r18, r16, r18 735 | blt major_0x13544_0x44 736 | 737 | major_0x13544_0x64 738 | lwz r18, PSA._368(r1) 739 | addc r17, r17, r18 740 | addze r16, r16 741 | stw r16, 0x0038(r30) 742 | 743 | 744 | 745 | ; TimerFire6 746 | 747 | TimerFire6 ; OUTSIDE REFERER 748 | stw r17, 0x003c(r30) 749 | 750 | TimerFire6_0x4 ; OUTSIDE REFERER 751 | mtxer r20 752 | beq cr1, TimerDispatch_0x144 753 | mr r8, r30 754 | bl EnqueueTimer 755 | b TimerDispatch_0x144 756 | 757 | 758 | 759 | ; major_0x135d0 760 | 761 | ; Dead code -- probably removed from TimerTable 762 | 763 | mfxer r19 764 | lwz r16, 0x0038(r30) 765 | lwz r17, 0x003c(r30) 766 | lwz r18, 0x0f2c(r1) 767 | srwi r18, r18, 1 768 | addc r17, r17, r18 769 | addze r16, r16 770 | stw r16, 0x0038(r30) 771 | stw r17, 0x003c(r30) 772 | mtxer r19 773 | mr r8, r30 774 | bl EnqueueTimer 775 | bl getchar 776 | cmpwi r8, -0x01 777 | beq TimerDispatch_0x144 778 | bl panic_non_interactive 779 | b TimerDispatch_0x144 780 | 781 | 782 | 783 | ; ARG Timer *r8 784 | ; CLOB r16-r20 785 | 786 | EnqueueTimer ; OUTSIDE REFERER 787 | 788 | ; Keep the trip-time of this timer in r16/r17 789 | lwz r16, Timer.Time(r8) 790 | lwz r17, Timer.Time+4(r8) 791 | 792 | ; r20 = timer being considered 793 | ; r18/r19 = trip-time of timer being condidered 794 | lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Next(r1) 795 | lwz r18, Timer.Time(r20) 796 | lwz r19, Timer.Time+4(r20) 797 | 798 | ; First try to insert at head of global TMRQ 799 | cmpw r16, r18 800 | cmplw cr1, r17, r19 801 | bgt @insert_further_ahead 802 | blt @insert_at_tail 803 | bge cr1, @insert_further_ahead 804 | 805 | @insert_at_tail 806 | addi r20, r1, PSA.TimerQueue + TimerQueueStruct.LLL 807 | 808 | li r18, 1 809 | stb r18, Timer.Byte3(r8) 810 | 811 | ; Insert at the very back of the queue 812 | lwz r19, LLL.Freeform(r8) 813 | lwz r9, LLL.Freeform(r20) 814 | stw r9, LLL.Freeform(r8) ; my freeform = considered freeform 815 | lwz r9, LLL.Next(r20) 816 | stw r9, LLL.Next(r8) ; my next = next of considered 817 | stw r20, LLL.Prev(r8) ; my prev = considered 818 | stw r8, LLL.Prev(r9) ; prev of next of considered = me 819 | stw r8, LLL.Next(r20) ; next of considered = me 820 | stw r19, LLL.Freeform(r8) ; my freeform = my original freeform 821 | 822 | b SetTimeslice 823 | 824 | @insert_further_ahead 825 | lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Prev(r1) 826 | 827 | @searchloop 828 | lwz r18, Timer.Time(r20) 829 | lwz r19, Timer.Time+4(r20) 830 | cmpw r16, r18 831 | cmplw cr1, r17, r19 832 | bgt @insert_after_this_one 833 | blt @next 834 | bge cr1, @insert_after_this_one 835 | 836 | @next 837 | lwz r20, LLL.Prev(r20) 838 | b @searchloop 839 | 840 | @insert_after_this_one 841 | li r18, 1 842 | stb r18, Timer.Byte3(r8) 843 | 844 | lwz r19, LLL.Freeform(r8) 845 | lwz r9, LLL.Freeform(r20) 846 | stw r9, LLL.Freeform(r8) ; my freeform = considered freeform 847 | lwz r9, LLL.Next(r20) 848 | stw r9, LLL.Next(r8) ; my next = next of considered 849 | stw r20, LLL.Prev(r8) ; my prev = considered 850 | stw r8, LLL.Prev(r9) ; prev of next of considered = me 851 | stw r8, LLL.Next(r20) ; next of considered = me 852 | stw r19, LLL.Freeform(r8) ; my freeform = my original freeform 853 | 854 | blr 855 | 856 | 857 | 858 | ; Remove a Timer from the global timer firing queue (TMRQ). 859 | ; If the Timer was to be the next to fire, then perform the 860 | ; standard decrementer rollover adjustment. 861 | 862 | ; ARG Timer *r8 863 | 864 | DequeueTimer 865 | lwz r16, Timer.QueueLLL + LLL.FreeForm(r8) 866 | cmpwi r16, 0 867 | lwz r18, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Next(r1) 868 | beq Local_Panic 869 | 870 | RemoveFromList r8, scratch1=r16, scratch2=r17 871 | 872 | li r16, 0 873 | cmpw r18, r8 874 | stb r16, Timer.Byte3(r8) 875 | 876 | beq SetTimeslice 877 | 878 | blr 879 | 880 | 881 | 882 | ; Get the number of timebase ticks in a specified period 883 | 884 | ; ARG long r8 period (positive for ms, negative for us) 885 | 886 | TimebaseTicksPerPeriod 887 | mr. r17, r8 888 | li r19, 250 889 | lwz r9, KDP.ProcessorInfo + NKProcessorInfo.DecClockRateHz(r1) 890 | 891 | bgt+ @period_positive 892 | blt+ @period_negative 893 | li r8, 0 894 | li r9, 0 895 | blr ; fail 896 | @period_negative 897 | neg r17, r17 898 | lisori r19, 250000 899 | @period_positive 900 | 901 | divw r19, r9, r19 902 | 903 | mullw r9, r19, r17 904 | mulhw r8, r19, r17 905 | 906 | srwi r9, r9, 2 907 | rlwimi r9, r8, 30, 0, 1 908 | srwi r8, r8, 2 909 | 910 | blr 911 | 912 | 913 | 914 | 915 | ; RET long r8 tbu, long r9 tbl 916 | ; CLOB r16, r17 917 | 918 | GetTime 919 | 920 | mfpvr r8 921 | rlwinm. r8, r8, 0, 0, 14 922 | beq @is_601 923 | 924 | @retry_timebase: 925 | mftbu r8 926 | mftb r9 927 | mftbu r16 928 | cmpw r8, r16 929 | bne- @retry_timebase 930 | 931 | b @return 932 | 933 | @is_601 934 | dialect POWER ; disassembled this in POWER mode! 935 | 936 | @retry_rtc 937 | mfrtcu r8 938 | mfrtcl r9 939 | mfrtcu r16 940 | cmp 0, r8, r16 941 | 942 | dialect PowerPC 943 | bne- @retry_rtc ; POWER chokes on hints? 944 | dialect POWER 945 | 946 | liu r16, 1000000000 >> 16 947 | oril r16, r16, 1000000000 & 0xffff 948 | 949 | mfmq r17 950 | mul r8, r16, r8 951 | mfmq r16 952 | mtmq r17 953 | 954 | mfxer r17 955 | a r9, r16, r9 956 | aze r8, r8 957 | mtxer r17 958 | 959 | dialect POWERPC 960 | 961 | @return 962 | blr 963 | -------------------------------------------------------------------------------- /NanoKernel/NKScreenConsole.s: -------------------------------------------------------------------------------- 1 | ; AUTO-GENERATED SYMBOL LIST 2 | ; IMPORTS: 3 | ; NKPaging 4 | ; PagingL2PWithoutBATs 5 | ; EXPORTS: 6 | ; InitScreenConsole (=> NKBuiltinInit, NKInit, NKReplacementInit) 7 | ; ScreenConsole_putchar (=> NKConsoleLog) 8 | ; ScreenConsole_redraw (=> NKConsoleLog, NKMPCalls) 9 | 10 | 11 | ScreenConsoleX equ 24 12 | ScreenConsoleY equ 22 13 | 14 | 15 | if &TYPE('ExtraNKLogging') != 'UNDEFINED' 16 | ScreenConsoleWidth equ 800-24 17 | ScreenConsoleHeight equ 900-22 18 | else 19 | ScreenConsoleWidth equ 588 20 | ScreenConsoleHeight equ 502 21 | endif 22 | 23 | ScreenConsoleBG equ 0xfffffeee 24 | ScreenConsoleFG equ 0x44444444 25 | 26 | 27 | 28 | align 8 ; odd! 29 | ; > r1 = kdp 30 | 31 | InitScreenConsole ; OUTSIDE REFERER 32 | stmw r29, -0x0110(r1) 33 | lis r30, -0x01 34 | ori r30, r30, 0x7000 35 | add r30, r30, r1 36 | addi r31, r30, 0x2000 37 | addi r30, r30, 0x04 38 | 39 | InitScreenConsole_0x18 40 | cmplw r30, r31 41 | addi r29, r31, 0x04 42 | bge InitScreenConsole_0x2c 43 | stwu r29, -0x1000(r31) 44 | b InitScreenConsole_0x18 45 | 46 | InitScreenConsole_0x2c 47 | addi r31, r30, 0x1000 48 | stw r30, -0x0004(r31) 49 | stw r30, PSA._404(r1) 50 | stw r30, PSA._400(r1) 51 | li r29, ScreenConsoleY 52 | sth r29, PSA._360(r1) 53 | li r29, ScreenConsoleX 54 | sth r29, PSA._35e(r1) 55 | li r29, ScreenConsoleHeight 56 | sth r29, PSA._35c(r1) 57 | li r29, ScreenConsoleWidth 58 | sth r29, PSA._35a(r1) 59 | li r29, 0x5e 60 | sth r29, PSA._358(r1) 61 | li r29, 0x30 62 | sth r29, PSA._356(r1) 63 | lmw r29, -0x0110(r1) 64 | blr 65 | 66 | 67 | 68 | ; > r1 = kdp 69 | 70 | ScreenConsole_putchar ; OUTSIDE REFERER 71 | lwz r30, PSA._404(r1) 72 | stb r29, 0x0000(r30) 73 | addi r30, r30, 0x01 74 | andi. r29, r30, 0xfff 75 | stw r30, PSA._404(r1) 76 | bnelr 77 | lwz r30, -0x1000(r30) 78 | stw r30, PSA._404(r1) 79 | blr 80 | 81 | 82 | 83 | ; > r1 = kdp 84 | 85 | ScreenConsole_redraw ; OUTSIDE REFERER 86 | stmw r2, PSA._3e8(r1) 87 | mflr r14 88 | mfcr r15 89 | stw r14, PSA._3f0(r1) 90 | stw r15, PSA._3ec(r1) 91 | addi r26, r1, PSA.VecBaseScreenConsole 92 | mfsprg r2, 3 93 | mtsprg 3, r26 94 | lwz r26, 0x0edc(r1) 95 | andi. r26, r26, 0x08 96 | beq major_0x18bec 97 | lwz r14, PSA._404(r1) 98 | lwz r15, PSA._400(r1) 99 | cmpw r14, r15 100 | beq major_0x18bec 101 | bl major_0x18c18 102 | 103 | ScreenConsole_redraw_0x40 104 | li r9, 0x00 105 | li r10, 0x00 106 | li r25, 0x20 107 | bl major_0x18e54 108 | bl major_0x19018 109 | mflr r21 110 | bl major_0x18e24 111 | bl funny_thing 112 | bl major_0x18e24 113 | bl funny_thing 114 | lwz r14, PSA._404(r1) 115 | lwz r15, PSA._400(r1) 116 | li r16, 0x00 117 | 118 | ScreenConsole_redraw_0x74 119 | cmpw r14, r15 120 | beq ScreenConsole_redraw_0x118 121 | lbz r25, 0x0000(r15) 122 | addi r15, r15, 0x01 123 | andi. r17, r15, 0xfff 124 | bne+ ScreenConsole_redraw_0x90 125 | lwz r15, -0x1000(r15) 126 | 127 | ScreenConsole_redraw_0x90 128 | cmplwi r25, 0x0d 129 | cmplwi cr1, r25, 0x0a 130 | beq ScreenConsole_redraw_0x74 131 | beq cr1, ScreenConsole_redraw_0xc0 132 | cmpwi r25, 0x00 133 | cmpwi cr1, r25, 0x07 134 | beq ScreenConsole_redraw_0x74 135 | beq cr1, ScreenConsole_redraw_0xe4 136 | bl major_0x18e54 137 | lhz r17, PSA._358(r1) 138 | cmpw r9, r17 139 | blt ScreenConsole_redraw_0x74 140 | 141 | ScreenConsole_redraw_0xc0 142 | cmpwi r16, 0x00 143 | bne ScreenConsole_redraw_0xcc 144 | mr r16, r15 145 | 146 | ScreenConsole_redraw_0xcc 147 | bl funny_thing 148 | lhz r17, PSA._356(r1) 149 | cmpw r10, r17 150 | blt ScreenConsole_redraw_0x74 151 | stw r16, PSA._400(r1) 152 | b ScreenConsole_redraw_0x40 153 | 154 | ScreenConsole_redraw_0xe4 155 | lhz r17, PSA._356(r1) 156 | addi r17, r17, -0x01 157 | cmpw r10, r17 158 | blt ScreenConsole_redraw_0x74 159 | lwz r17, PSA.DecClockRateHzCopy(r1) 160 | slwi r25, r17, 2 161 | add r25, r25, r17 162 | mfspr r17, dec 163 | subf r17, r25, r17 164 | 165 | ScreenConsole_redraw_0x108 166 | mfspr r25, dec 167 | subf. r25, r17, r25 168 | bge ScreenConsole_redraw_0x108 169 | b ScreenConsole_redraw_0x74 170 | 171 | ScreenConsole_redraw_0x118 172 | bl funny_thing_0x8 173 | mfspr r31, pvr 174 | rlwinm. r31, r31, 0, 0, 14 175 | li r31, 0x00 176 | bne ScreenConsole_redraw_0x140 177 | mtspr ibat3l, r31 178 | isync 179 | mtspr ibat3u, r18 180 | mtspr ibat3l, r19 181 | b ScreenConsole_redraw_0x150 182 | 183 | ScreenConsole_redraw_0x140 184 | mtspr dbat3u, r31 185 | isync 186 | mtspr dbat3l, r19 187 | mtspr dbat3u, r18 188 | 189 | ScreenConsole_redraw_0x150 190 | isync 191 | 192 | 193 | 194 | major_0x18bec ; OUTSIDE REFERER 195 | mtsprg 3, r2 196 | lwz r14, PSA._3f0(r1) 197 | lwz r15, PSA._3ec(r1) 198 | mtlr r14 199 | mtcr r15 200 | lmw r2, PSA._3e8(r1) 201 | blr 202 | 203 | 204 | 205 | major_0x18c08 ; OUTSIDE REFERER 206 | mfsrin r31, r27 207 | cmpwi r31, 0x00 208 | beqlr 209 | b PagingL2PWithoutBATs 210 | 211 | 212 | 213 | major_0x18c18 ; OUTSIDE REFERER 214 | mflr r13 215 | lwz r27, PSA._8f8(r1) 216 | cmpwi r27, 0x00 217 | bne major_0x18c18_0x40 218 | lwz r27, 0x0630(r1) 219 | lhz r31, 0x0378(r27) 220 | cmpwi r31, 0x00 221 | beq major_0x18c18_0x40 222 | lwz r31, 0x037c(r27) 223 | cmpwi r31, 0x00 224 | beq major_0x18c18_0x40 225 | stw r31, PSA._8f8(r1) 226 | lhz r31, 0x0384(r27) 227 | sth r31, PSA._8f4(r1) 228 | lhz r31, 0x0386(r27) 229 | sth r31, PSA._8f2(r1) 230 | 231 | major_0x18c18_0x40 232 | li r27, 0x8a4 233 | bl major_0x18c08 234 | beq major_0x18c18_0xe0 235 | rlwimi. r27, r31, 0, 0, 19 236 | ble major_0x18c18_0xe0 237 | lwz r27, 0x0000(r27) 238 | cmpwi r27, 0x00 239 | ble major_0x18c18_0xe0 240 | bl major_0x18c08 241 | beq major_0x18c18_0xe0 242 | rlwimi r27, r31, 0, 0, 19 243 | lwz r27, 0x0000(r27) 244 | cmpwi r27, 0x00 245 | ble major_0x18c18_0xe0 246 | addi r27, r27, 0x16 247 | bl major_0x18c08 248 | beq major_0x18c18_0xe0 249 | rlwimi r27, r31, 0, 0, 19 250 | lwz r27, 0x0000(r27) 251 | cmpwi r27, 0x00 252 | ble major_0x18c18_0xe0 253 | bl major_0x18c08 254 | beq major_0x18c18_0xe0 255 | rlwimi r27, r31, 0, 0, 19 256 | lwz r27, 0x0000(r27) 257 | cmpwi r27, 0x00 258 | ble major_0x18c18_0xe0 259 | bl major_0x18c08 260 | beq major_0x18c18_0xe0 261 | rlwimi r27, r31, 0, 0, 19 262 | lwz r3, 0x0000(r27) 263 | lhz r5, 0x0004(r27) 264 | andi. r5, r5, 0x7fff 265 | lhz r6, 0x0020(r27) 266 | srwi r6, r6, 3 267 | cmplwi r6, 0x08 268 | bgt major_0x18c18_0xe0 269 | stw r3, PSA._8f8(r1) 270 | sth r5, PSA._8f4(r1) 271 | sth r6, PSA._8f2(r1) 272 | 273 | major_0x18c18_0xe0 274 | lwz r3, PSA._8f8(r1) 275 | lhz r5, PSA._8f4(r1) 276 | lhz r6, PSA._8f2(r1) 277 | cmpwi r3, 0x00 278 | bne major_0x18d5c 279 | b major_0x18bec 280 | 281 | 282 | 283 | ; Dead code @ 18d10: 284 | 285 | lisori r3, 0x81800200 286 | li r5, 0x340 287 | li r6, 1 288 | b @end 289 | 290 | lisori r3, 0xa6008000 291 | li r5, 0x400 292 | li r6, 1 293 | b @end 294 | 295 | lisori r3, 0x96008000 296 | li r5, 0x400 297 | li r6, 1 298 | b @end 299 | 300 | lisori r3, 0x96008000 301 | li r5, 0x400 302 | li r6, 1 303 | 304 | @end 305 | 306 | 307 | 308 | major_0x18d5c ; OUTSIDE REFERER 309 | cmpwi cr4, r6, 0x02 310 | bl major_0x19ab0 311 | blt cr4, major_0x18d5c_0x18 312 | bl major_0x19b00 313 | beq cr4, major_0x18d5c_0x18 314 | bl load_log_colours 315 | 316 | major_0x18d5c_0x18 317 | mflr r24 318 | mfspr r31, pvr 319 | rlwinm. r31, r31, 0, 0, 14 320 | li r31, 0x00 321 | bne major_0x18d5c_0x3c 322 | mfspr r19, ibat3l 323 | mfspr r18, ibat3u 324 | mtspr ibat3l, r31 325 | b major_0x18d5c_0x48 326 | 327 | major_0x18d5c_0x3c 328 | mfspr r18, dbat3u 329 | mfspr r19, dbat3l 330 | mtspr dbat3u, r31 331 | 332 | major_0x18d5c_0x48 333 | isync 334 | rlwinm r29, r3, 0, 0, 7 335 | beq major_0x18d5c_0x70 336 | li r30, 0x7e 337 | or r30, r30, r29 338 | li r31, 0x32 339 | or r31, r31, r29 340 | mtspr dbat3l, r31 341 | mtspr dbat3u, r30 342 | b major_0x18d5c_0x88 343 | 344 | major_0x18d5c_0x70 345 | li r30, 0x32 346 | or r30, r30, r29 347 | li r31, 0x5f 348 | or r31, r31, r29 349 | mtspr ibat3u, r30 350 | mtspr ibat3l, r31 351 | 352 | major_0x18d5c_0x88 353 | isync 354 | mfmsr r22 355 | lhz r29, PSA._360(r1) 356 | lhz r30, PSA._35c(r1) 357 | subf r29, r29, r30 358 | li r30, 0x0a 359 | divw r29, r29, r30 360 | sth r29, PSA._356(r1) 361 | lhz r29, PSA._35e(r1) 362 | lhz r30, PSA._35a(r1) 363 | subf r29, r29, r30 364 | li r30, 0x06 365 | divw r29, r29, r30 366 | sth r29, PSA._358(r1) 367 | mtlr r13 368 | blr 369 | 370 | 371 | 372 | major_0x18e24 ; OUTSIDE REFERER 373 | mflr r12 374 | 375 | major_0x18e24_0x4 376 | lhz r25, PSA._358(r1) 377 | cmpw cr1, r9, r25 378 | lbz r25, 0x0000(r21) 379 | cmplwi r25, 0x00 380 | addi r21, r21, 0x01 381 | beq major_0x18e24_0x28 382 | bge cr1, major_0x18e24_0x4 383 | bl major_0x18e54 384 | b major_0x18e24_0x4 385 | 386 | major_0x18e24_0x28 387 | mtlr r12 388 | blr 389 | 390 | 391 | 392 | major_0x18e54 ; OUTSIDE REFERER 393 | mflr r13 394 | cmpwi cr4, r6, 0x02 395 | bl load_log_font 396 | mflr r23 397 | add r23, r25, r23 398 | mulli r27, r5, 0x0a 399 | mullw r27, r27, r10 400 | mulli r7, r9, 0x06 401 | mullw r7, r7, r6 402 | add r7, r7, r27 403 | add r7, r7, r3 404 | lhz r27, PSA._360(r1) 405 | lhz r28, PSA._35e(r1) 406 | mullw r27, r5, r27 407 | mullw r28, r6, r28 408 | add r7, r7, r27 409 | add r7, r7, r28 410 | subf. r27, r3, r7 411 | blt major_0x18e54_0x174 412 | li r8, 0x00 413 | 414 | major_0x18e54_0x50 415 | beq cr4, major_0x18e54_0x9c 416 | bgt cr4, major_0x18e54_0xe0 417 | lbz r27, 0x0000(r23) 418 | rlwinm r27, r27, 28, 28, 29 419 | lwzx r28, r24, r27 420 | lbz r27, 0x0000(r23) 421 | rlwinm r27, r27, 0, 26, 29 422 | lwzx r27, r24, r27 423 | ori r22, r22, 0x10 424 | mtmsr r22 425 | isync 426 | sth r28, 0x0000(r7) 427 | sth r27, 0x0004(r7) 428 | srwi r27, r27, 16 429 | sth r27, 0x0002(r7) 430 | rlwinm r22, r22, 0, 28, 26 431 | mtmsr r22 432 | isync 433 | b major_0x18e54_0x160 434 | 435 | major_0x18e54_0x9c 436 | lbz r28, 0x0000(r23) 437 | rlwinm r27, r28, 28, 28, 29 438 | lwzx r27, r24, r27 439 | rlwinm r29, r28, 30, 28, 29 440 | lwzx r29, r24, r29 441 | rlwinm r30, r28, 0, 28, 29 442 | lwzx r30, r24, r30 443 | ori r22, r22, 0x10 444 | mtmsr r22 445 | isync 446 | stw r27, 0x0000(r7) 447 | stw r29, 0x0004(r7) 448 | stw r30, 0x0008(r7) 449 | rlwinm r22, r22, 0, 28, 26 450 | mtmsr r22 451 | isync 452 | b major_0x18e54_0x160 453 | 454 | major_0x18e54_0xe0 455 | lbz r28, 0x0000(r23) 456 | rlwinm r27, r28, 27, 29, 29 457 | lwzx r27, r24, r27 458 | rlwinm r29, r28, 28, 29, 29 459 | lwzx r29, r24, r29 460 | rlwinm r30, r28, 29, 29, 29 461 | lwzx r30, r24, r30 462 | rlwinm r31, r28, 30, 29, 29 463 | lwzx r31, r24, r31 464 | ori r22, r22, 0x10 465 | mtmsr r22 466 | isync 467 | stw r27, 0x0000(r7) 468 | stw r29, 0x0004(r7) 469 | stw r30, 0x0008(r7) 470 | stw r31, 0x000c(r7) 471 | rlwinm r22, r22, 0, 28, 26 472 | mtmsr r22 473 | isync 474 | rlwinm r27, r28, 31, 29, 29 475 | lwzx r27, r24, r27 476 | rlwinm r29, r28, 0, 29, 29 477 | lwzx r29, r24, r29 478 | ori r22, r22, 0x10 479 | mtmsr r22 480 | isync 481 | stw r27, 0x0010(r7) 482 | stw r29, 0x0014(r7) 483 | rlwinm r22, r22, 0, 28, 26 484 | mtmsr r22 485 | isync 486 | b major_0x18e54_0x160 487 | 488 | major_0x18e54_0x160 489 | addi r8, r8, 0x01 490 | cmplwi r8, 0x0a 491 | add r7, r7, r5 492 | addi r23, r23, 0x100 493 | blt major_0x18e54_0x50 494 | 495 | major_0x18e54_0x174 496 | addi r9, r9, 0x01 497 | mtlr r13 498 | blr 499 | 500 | 501 | 502 | funny_thing ; OUTSIDE REFERER 503 | crclr cr2_eq 504 | b funny_thing_0xc 505 | 506 | funny_thing_0x8 ; OUTSIDE REFERER 507 | crset cr2_eq 508 | 509 | funny_thing_0xc 510 | mflr r12 511 | 512 | funny_thing_0x10 513 | lhz r25, PSA._358(r1) 514 | cmpw r9, r25 515 | bge funny_thing_0x28 516 | li r25, 0x20 517 | bl major_0x18e54 518 | b funny_thing_0x10 519 | 520 | funny_thing_0x28 521 | beq cr2, funny_thing_0x3c 522 | li r9, 0x00 523 | addi r10, r10, 0x01 524 | li r25, 0x20 525 | bl major_0x18e54 526 | 527 | funny_thing_0x3c 528 | mtlr r12 529 | blr 530 | 531 | 532 | 533 | major_0x19018 ; OUTSIDE REFERER 534 | 535 | blrl 536 | 537 | string CString 538 | dc.b ' NanoKernel Log ' 539 | dc.b ' -------------- ' 540 | align 2 541 | 542 | 543 | 544 | ; Unfortunately inaccessible 545 | 546 | blrl 547 | 548 | string CString 549 | dc.b ' System Termination ' 550 | dc.b ' ------------------ ' 551 | align 2 552 | 553 | 554 | 555 | load_log_font ; OUTSIDE REFERER 556 | blrl 557 | dc.l 0x907070f0 558 | dc.l 0xf0f06000 559 | dc.l 0xe0008090 560 | dc.l 0xf0007070 561 | dc.l 0xe0e0e0e0 562 | dc.l 0xe09070f0 563 | dc.l 0x70f070f0 564 | dc.l 0xf070e090 565 | dc.l 0 566 | dc.l 0x20000000 567 | dc.l 0 568 | dc.l 0 569 | dc.l 0 570 | dc.l 0 571 | dc.l 0 572 | dc.l 0 573 | dc.l 0 574 | dc.l 0 575 | dc.l 0 576 | dc.l 0 577 | dc.l 0 578 | dc.l 0 579 | dc.l 0 580 | dc.l 0 581 | dc.l 0 582 | dc.l 0 583 | dc.l 0 584 | dc.l 0 585 | dc.l 0 586 | dc.l 0 587 | dc.l 0x00000008 588 | dc.l 0x20400000 589 | dc.l 0x50200010 590 | dc.l 0x68505000 591 | dc.l 0 592 | dc.l 0 593 | dc.l 0 594 | dc.l 0 595 | dc.l 0 596 | dc.l 0 597 | dc.l 0 598 | dc.l 0x70000000 599 | dc.l 0 600 | dc.l 0 601 | dc.l 0 602 | dc.l 0 603 | dc.l 0x00001800 604 | dc.l 0 605 | dc.l 0 606 | dc.l 0x18000000 607 | dc.l 0x00000040 608 | dc.l 0x68680000 609 | dc.l 0 610 | dc.l 0 611 | dc.l 0x00500000 612 | dc.l 0 613 | dc.l 0 614 | dc.l 0 615 | dc.l 0 616 | dc.l 0 617 | dc.l 0 618 | dc.l 0 619 | dc.l 0 620 | dc.l 0 621 | dc.l 0xd0808080 622 | dc.l 0x80809000 623 | dc.l 0x90008090 624 | dc.l 0x80088080 625 | dc.l 0x90909090 626 | dc.l 0x90d08080 627 | dc.l 0x80808080 628 | dc.l 0x80809090 629 | dc.l 0x00205050 630 | dc.l 0x70786020 631 | dc.l 0x10200000 632 | dc.l 0x00000008 633 | dc.l 0x70207070 634 | dc.l 0x10f870f8 635 | dc.l 0x70700000 636 | dc.l 0x00000070 637 | dc.l 0x7070f070 638 | dc.l 0xf0f8f870 639 | dc.l 0x88700888 640 | dc.l 0x80888870 641 | dc.l 0xf070f070 642 | dc.l 0xf8888888 643 | dc.l 0x8888f830 644 | dc.l 0x40302000 645 | dc.l 0x20008000 646 | dc.l 0x08001800 647 | dc.l 0x80202080 648 | dc.l 0x20000000 649 | dc.l 0 650 | dc.l 0x20000000 651 | dc.l 0x00000010 652 | dc.l 0x20200000 653 | dc.l 0x00500020 654 | dc.l 0xb8000010 655 | dc.l 0x40200068 656 | dc.l 0x30001040 657 | dc.l 0x20001040 658 | dc.l 0x20006810 659 | dc.l 0x40200068 660 | dc.l 0x10402000 661 | dc.l 0x00300060 662 | dc.l 0x88007830 663 | dc.l 0 664 | dc.l 0 665 | dc.l 0x00001040 666 | dc.l 0x880020f8 667 | dc.l 0xf8002038 668 | dc.l 0x30700000 669 | dc.l 0x20200000 670 | dc.l 0x20000000 671 | dc.l 0x00000020 672 | dc.l 0xb0b00000 673 | dc.l 0x00005050 674 | dc.l 0x20600000 675 | dc.l 0x50000000 676 | dc.l 0x00003030 677 | dc.l 0 678 | dc.l 0x40202010 679 | dc.l 0x00201020 680 | dc.l 0x00201020 681 | dc.l 0x30201020 682 | dc.l 0x20002068 683 | dc.l 0x70482020 684 | dc.l 0x00280050 685 | dc.l 0xb06060e0 686 | dc.l 0xe0e0f020 687 | dc.l 0xe0208090 688 | dc.l 0xe0086060 689 | dc.l 0x90909090 690 | dc.l 0x90b060e0 691 | dc.l 0x80e060e0 692 | dc.l 0xe0b0e090 693 | dc.l 0x002050f8 694 | dc.l 0xa8a89020 695 | dc.l 0x20102020 696 | dc.l 0x00000008 697 | dc.l 0x88608888 698 | dc.l 0x30808008 699 | dc.l 0x88880000 700 | dc.l 0x10004088 701 | dc.l 0x88888888 702 | dc.l 0x88808088 703 | dc.l 0x88200890 704 | dc.l 0x80d8c888 705 | dc.l 0x88888888 706 | dc.l 0x20888888 707 | dc.l 0x88880820 708 | dc.l 0x40105000 709 | dc.l 0x10008000 710 | dc.l 0x08002000 711 | dc.l 0x80000080 712 | dc.l 0x20000000 713 | dc.l 0 714 | dc.l 0x20000000 715 | dc.l 0x00000010 716 | dc.l 0x20206800 717 | dc.l 0x702070f8 718 | dc.l 0x88708820 719 | dc.l 0x205050b0 720 | dc.l 0x48002020 721 | dc.l 0x50502020 722 | dc.l 0x5050b020 723 | dc.l 0x205050b0 724 | dc.l 0x20205050 725 | dc.l 0x20480090 726 | dc.l 0x4800a848 727 | dc.l 0xe0e0f410 728 | dc.l 0x50007870 729 | dc.l 0x00202020 730 | dc.l 0x50001048 731 | dc.l 0x50002048 732 | dc.l 0x48880000 733 | dc.l 0x00000018 734 | dc.l 0x20082000 735 | dc.l 0x00000070 736 | dc.l 0x70707800 737 | dc.l 0x0000a050 738 | dc.l 0x40200000 739 | dc.l 0x00880884 740 | dc.l 0x00004048 741 | dc.l 0x20000000 742 | dc.l 0xa0505020 743 | dc.l 0x50102050 744 | dc.l 0x50102050 745 | dc.l 0x20102050 746 | dc.l 0x100050b0 747 | dc.l 0x00300050 748 | dc.l 0x00500020 749 | dc.l 0x90101080 750 | dc.l 0x80809070 751 | dc.l 0x9030f0a0 752 | dc.l 0x80281010 753 | dc.l 0x90909090 754 | dc.l 0x90901080 755 | dc.l 0x80801080 756 | dc.l 0x8090a090 757 | dc.l 0x00200050 758 | dc.l 0xa0b0a000 759 | dc.l 0x4008a820 760 | dc.l 0x00000010 761 | dc.l 0x98200808 762 | dc.l 0x50f0f008 763 | dc.l 0x88882020 764 | dc.l 0x20f82008 765 | dc.l 0xe8888880 766 | dc.l 0x88808080 767 | dc.l 0x882008a0 768 | dc.l 0x80a8a888 769 | dc.l 0x88888880 770 | dc.l 0x20888888 771 | dc.l 0x50881020 772 | dc.l 0x20108800 773 | dc.l 0x0078f070 774 | dc.l 0x78707078 775 | dc.l 0xf0202090 776 | dc.l 0x20f0b070 777 | dc.l 0xf078b078 778 | dc.l 0x708888a8 779 | dc.l 0x8888f810 780 | dc.l 0x2020b000 781 | dc.l 0x88708880 782 | dc.l 0xc8888800 783 | dc.l 0 784 | dc.l 0x30700000 785 | dc.l 0 786 | dc.l 0 787 | dc.l 0 788 | dc.l 0 789 | dc.l 0x70482080 790 | dc.l 0xa000a888 791 | dc.l 0x10105c20 792 | dc.l 0x0010a088 793 | dc.l 0xd8204010 794 | dc.l 0xf8901820 795 | dc.l 0x50f82048 796 | dc.l 0x48887070 797 | dc.l 0x20200010 798 | dc.l 0x20702000 799 | dc.l 0x00000088 800 | dc.l 0x8888a000 801 | dc.l 0x0000a0a0 802 | dc.l 0x60402020 803 | dc.l 0x88881030 804 | dc.l 0x0000e8e8 805 | dc.l 0x70000000 806 | dc.l 0x40000000 807 | dc.l 0 808 | dc.l 0 809 | dc.l 0x58000000 810 | dc.l 0x00200000 811 | dc.l 0x00000020 812 | dc.l 0 813 | dc.l 0x90e0e0f0 814 | dc.l 0xf0f09070 815 | dc.l 0xe0f80040 816 | dc.l 0x8068e0e0 817 | dc.l 0xe0e0e0e0 818 | dc.l 0xe090e0f0 819 | dc.l 0x70f0e0f0 820 | dc.l 0x80609060 821 | dc.l 0x002000f8 822 | dc.l 0x70504000 823 | dc.l 0x400870f8 824 | dc.l 0x00f80010 825 | dc.l 0xa8201030 826 | dc.l 0x90088810 827 | dc.l 0x70880000 828 | dc.l 0x40001010 829 | dc.l 0xa8f8f080 830 | dc.l 0x88f0f098 831 | dc.l 0xf82008c0 832 | dc.l 0x80889888 833 | dc.l 0xf088f070 834 | dc.l 0x20888888 835 | dc.l 0x20502020 836 | dc.l 0x20100000 837 | dc.l 0x00888888 838 | dc.l 0x88882088 839 | dc.l 0x882020a0 840 | dc.l 0x20a8c888 841 | dc.l 0x8888c880 842 | dc.l 0x208888a8 843 | dc.l 0x50881020 844 | dc.l 0x20100000 845 | dc.l 0x88888080 846 | dc.l 0xa8888878 847 | dc.l 0x78787878 848 | dc.l 0x78887070 849 | dc.l 0x70702020 850 | dc.l 0x2020b070 851 | dc.l 0x70707070 852 | dc.l 0x88888888 853 | dc.l 0x203070e0 854 | dc.l 0x9030a890 855 | dc.l 0xc8685c00 856 | dc.l 0x00f8a098 857 | dc.l 0xa8f82020 858 | dc.l 0x20902810 859 | dc.l 0x50502038 860 | dc.l 0x3088a898 861 | dc.l 0x4020f820 862 | dc.l 0x70885048 863 | dc.l 0x90000088 864 | dc.l 0x8888a050 865 | dc.l 0 866 | dc.l 0x00000050 867 | dc.l 0x88882048 868 | dc.l 0x00004848 869 | dc.l 0x20200000 870 | dc.l 0x1c70f870 871 | dc.l 0xf8f87070 872 | dc.l 0x70707070 873 | dc.l 0xf0708888 874 | dc.l 0x88200000 875 | dc.l 0 876 | dc.l 0 877 | dc.l 0x48484848 878 | dc.l 0x003048f8 879 | dc.l 0x38307800 880 | dc.l 0x78f83830 881 | dc.l 0x00107070 882 | dc.l 0x10484870 883 | dc.l 0x00007038 884 | dc.l 0x38383838 885 | dc.l 0x00200050 886 | dc.l 0x2868a800 887 | dc.l 0x4008a820 888 | dc.l 0x00000020 889 | dc.l 0xc8202008 890 | dc.l 0xf8088820 891 | dc.l 0x88782000 892 | dc.l 0x20f82020 893 | dc.l 0xf0888880 894 | dc.l 0x88808088 895 | dc.l 0x882088a0 896 | dc.l 0x80888888 897 | dc.l 0x80888808 898 | dc.l 0x208888a8 899 | dc.l 0x50204020 900 | dc.l 0x10100000 901 | dc.l 0x00888880 902 | dc.l 0x88f82088 903 | dc.l 0x882020e0 904 | dc.l 0x20a88888 905 | dc.l 0x88888070 906 | dc.l 0x208888a8 907 | dc.l 0x20882010 908 | dc.l 0x20200000 909 | dc.l 0xf88880f0 910 | dc.l 0x98888888 911 | dc.l 0x88888888 912 | dc.l 0x88808888 913 | dc.l 0x88882020 914 | dc.l 0x2020c888 915 | dc.l 0x88888888 916 | dc.l 0x88888888 917 | dc.l 0x2000a880 918 | dc.l 0x48307890 919 | dc.l 0xa8880000 920 | dc.l 0x0020f0a8 921 | dc.l 0xd8201040 922 | dc.l 0xf8904820 923 | dc.l 0x50502000 924 | dc.l 0x0088b8a8 925 | dc.l 0x802008a0 926 | dc.l 0x20705090 927 | dc.l 0x480000f8 928 | dc.l 0xf888b0a8 929 | dc.l 0x70f80000 930 | dc.l 0x0000f888 931 | dc.l 0x88504048 932 | dc.l 0x10404848 933 | dc.l 0x20000000 934 | dc.l 0xe0888088 935 | dc.l 0x80802020 936 | dc.l 0x20208888 937 | dc.l 0xf8888888 938 | dc.l 0x88200000 939 | dc.l 0 940 | dc.l 0 941 | dc.l 0x48484848 942 | dc.l 0x384850f8 943 | dc.l 0x40204038 944 | dc.l 0x40601048 945 | dc.l 0x40300808 946 | dc.l 0x30504848 947 | dc.l 0x48884840 948 | dc.l 0x40404040 949 | dc.l 0 950 | dc.l 0xa8a89000 951 | dc.l 0x20102020 952 | dc.l 0x00000020 953 | dc.l 0x88204088 954 | dc.l 0x10888820 955 | dc.l 0x88080000 956 | dc.l 0x10004000 957 | dc.l 0x80888888 958 | dc.l 0x88808088 959 | dc.l 0x88208890 960 | dc.l 0x80888888 961 | dc.l 0x80888888 962 | dc.l 0x208850d8 963 | dc.l 0x88208020 964 | dc.l 0x10100000 965 | dc.l 0x00988880 966 | dc.l 0x88802088 967 | dc.l 0x88202090 968 | dc.l 0x20a88888 969 | dc.l 0x88888008 970 | dc.l 0x209850a8 971 | dc.l 0x50884010 972 | dc.l 0x20200000 973 | dc.l 0x88f88080 974 | dc.l 0x88888888 975 | dc.l 0x88888888 976 | dc.l 0x8880f8f8 977 | dc.l 0xf8f82020 978 | dc.l 0x20208888 979 | dc.l 0x88888888 980 | dc.l 0x88888888 981 | dc.l 0x2000a080 982 | dc.l 0x28002888 983 | dc.l 0xc8680000 984 | dc.l 0x00f8a0c8 985 | dc.l 0x00200000 986 | dc.l 0x20904848 987 | dc.l 0x50502078 988 | dc.l 0x7850a0c8 989 | dc.l 0x88200840 990 | dc.l 0x20808890 991 | dc.l 0x48000088 992 | dc.l 0x8888a0b8 993 | dc.l 0 994 | dc.l 0x00000050 995 | dc.l 0x88208030 996 | dc.l 0x20204848 997 | dc.l 0x20000000 998 | dc.l 0x00f8f0f8 999 | dc.l 0xf0f02020 1000 | dc.l 0x20208888 1001 | dc.l 0xf8888888 1002 | dc.l 0x88200000 1003 | dc.l 0 1004 | dc.l 0 1005 | dc.l 0x48783030 1006 | dc.l 0x10487020 1007 | dc.l 0x30007010 1008 | dc.l 0x70201048 1009 | dc.l 0x40101030 1010 | dc.l 0x78703070 1011 | dc.l 0x68d87040 1012 | dc.l 0x30303030 1013 | dc.l 0x00200000 1014 | dc.l 0x70906800 1015 | dc.l 0x10200000 1016 | dc.l 0x20002040 1017 | dc.l 0x7020f870 1018 | dc.l 0x10707020 1019 | dc.l 0x70700020 1020 | dc.l 0x00000020 1021 | dc.l 0x7088f070 1022 | dc.l 0xf0f88070 1023 | dc.l 0x88707088 1024 | dc.l 0xf8888870 1025 | dc.l 0x80708870 1026 | dc.l 0x20702088 1027 | dc.l 0x8820f830 1028 | dc.l 0x083000f8 1029 | dc.l 0x0068f078 1030 | dc.l 0x78782078 1031 | dc.l 0x88202088 1032 | dc.l 0x20a88870 1033 | dc.l 0xf07880f0 1034 | dc.l 0x18682050 1035 | dc.l 0x8878f810 1036 | dc.l 0x20200000 1037 | dc.l 0x88888880 1038 | dc.l 0x88888898 1039 | dc.l 0x98989898 1040 | dc.l 0x98788080 1041 | dc.l 0x80802020 1042 | dc.l 0x20208888 1043 | dc.l 0x88888888 1044 | dc.l 0x98989898 1045 | dc.l 0x0000a888 1046 | dc.l 0x90002888 1047 | dc.l 0xb0100000 1048 | dc.l 0x0040a088 1049 | dc.l 0x00f87070 1050 | dc.l 0x20e830f8 1051 | dc.l 0x50502000 1052 | dc.l 0x00d87870 1053 | dc.l 0x70200040 1054 | dc.l 0x2000f848 1055 | dc.l 0x90a80088 1056 | dc.l 0x8888a0a0 1057 | dc.l 0 1058 | dc.l 0x00002020 1059 | dc.l 0x78200084 1060 | dc.l 0x10404848 1061 | dc.l 0x70002050 1062 | dc.l 0x48888088 1063 | dc.l 0x80802020 1064 | dc.l 0x20208888 1065 | dc.l 0x50888888 1066 | dc.l 0x88200000 1067 | dc.l 0 1068 | dc.l 0x20001000 1069 | dc.l 0x30484848 1070 | dc.l 0x10584800 1071 | dc.l 0x08004010 1072 | dc.l 0x40001048 1073 | dc.l 0x40102008 1074 | dc.l 0x10481048 1075 | dc.l 0x58a84840 1076 | dc.l 0x08080808 1077 | dc.l 0 1078 | dc.l 0x20000000 1079 | dc.l 0 1080 | dc.l 0x20000040 1081 | dc.l 0 1082 | dc.l 0 1083 | dc.l 0x00000020 1084 | dc.l 0 1085 | dc.l 0 1086 | dc.l 0 1087 | dc.l 0 1088 | dc.l 0 1089 | dc.l 0x00080000 1090 | dc.l 0 1091 | dc.l 0 1092 | dc.l 0x08000000 1093 | dc.l 0 1094 | dc.l 0x00000008 1095 | dc.l 0x00002000 1096 | dc.l 0 1097 | dc.l 0x80080000 1098 | dc.l 0 1099 | dc.l 0x00080008 1100 | dc.l 0x20400000 1101 | dc.l 0x888870f8 1102 | dc.l 0x88707068 1103 | dc.l 0x68686868 1104 | dc.l 0x68207878 1105 | dc.l 0x78782020 1106 | dc.l 0x20208870 1107 | dc.l 0x70707070 1108 | dc.l 0x68686868 1109 | dc.l 0x000070f0 1110 | dc.l 0x880028b0 1111 | dc.l 0x00e00000 1112 | dc.l 0x0000b870 1113 | dc.l 0 1114 | dc.l 0x00800000 1115 | dc.l 0x00002000 1116 | dc.l 0 1117 | dc.l 0 1118 | dc.l 0x20000000 1119 | dc.l 0x00000088 1120 | dc.l 0x88707858 1121 | dc.l 0 1122 | dc.l 0 1123 | dc.l 0x08200000 1124 | dc.l 0 1125 | dc.l 0x20002050 1126 | dc.l 0xb488f888 1127 | dc.l 0xf8f87070 1128 | dc.l 0x70708888 1129 | dc.l 0x00887070 1130 | dc.l 0x70000000 1131 | dc.l 0 1132 | dc.l 0x10002000 1133 | dc.l 0x00484848 1134 | dc.l 0x10384800 1135 | dc.l 0x70004010 1136 | dc.l 0x40003830 1137 | dc.l 0x70387870 1138 | dc.l 0x10481070 1139 | dc.l 0x48887038 1140 | dc.l 0x70707070 1141 | dc.l 0 1142 | dc.l 0 1143 | dc.l 0 1144 | dc.l 0x40000000 1145 | dc.l 0 1146 | dc.l 0 1147 | dc.l 0x00000040 1148 | dc.l 0 1149 | dc.l 0 1150 | dc.l 0 1151 | dc.l 0 1152 | dc.l 0 1153 | dc.l 0 1154 | dc.l 0 1155 | dc.l 0 1156 | dc.l 0 1157 | dc.l 0 1158 | dc.l 0x00000070 1159 | dc.l 0x0000c000 1160 | dc.l 0 1161 | dc.l 0x80080000 1162 | dc.l 0 1163 | dc.l 0x00700000 1164 | dc.l 0 1165 | dc.l 0 1166 | dc.l 0 1167 | dc.l 0 1168 | dc.l 0x00400000 1169 | dc.l 0 1170 | dc.l 0 1171 | dc.l 0 1172 | dc.l 0 1173 | dc.l 0x00002000 1174 | dc.l 0x70000080 1175 | dc.l 0 1176 | dc.l 0 1177 | dc.l 0 1178 | dc.l 0x00800000 1179 | dc.l 0x0000c000 1180 | dc.l 0 1181 | dc.l 0 1182 | dc.l 0xc0000000 1183 | dc.l 0 1184 | dc.l 0 1185 | dc.l 0 1186 | dc.l 0 1187 | dc.l 0x70000000 1188 | dc.l 0 1189 | dc.l 0x000040a0 1190 | dc.l 0x48000000 1191 | dc.l 0 1192 | dc.l 0x00007070 1193 | dc.l 0x00700000 1194 | dc.l 0 1195 | dc.l 0 1196 | dc.l 0x30003000 1197 | 1198 | 1199 | 1200 | align 4 1201 | 1202 | major_0x19ab0 ; OUTSIDE REFERER 1203 | blrl 1204 | dc.l 0x06060606 1205 | dc.l 0x060606ff 1206 | dc.l 0x0606ff06 1207 | dc.l 0x0606ffff 1208 | dc.l 0x06ff0606 1209 | dc.l 0x06ff06ff 1210 | dc.l 0x06ffff06 1211 | dc.l 0x06ffffff 1212 | dc.l 0xff060606 1213 | dc.l 0xff0606ff 1214 | dc.l 0xff06ff06 1215 | dc.l 0xff06ffff 1216 | dc.l 0xffff0606 1217 | dc.l 0xffff06ff 1218 | dc.l 0xffffff06 1219 | dc.l 0xffffffff 1220 | 1221 | 1222 | 1223 | align 4 1224 | 1225 | major_0x19b00 ; OUTSIDE REFERER 1226 | blrl 1227 | dc.l 0xff7eff7e 1228 | dc.l 0xff7e0000 1229 | dc.l 0x0000ff7e 1230 | dc.l 0 1231 | 1232 | 1233 | 1234 | ; load_log_colours 1235 | 1236 | ; Each word is RGB with the high byte ignored. Background 1237 | ; and text. 1238 | 1239 | align 4 1240 | 1241 | load_log_colours ; OUTSIDE REFERER 1242 | blrl 1243 | dc.l ScreenConsoleBG 1244 | dc.l ScreenConsoleFG 1245 | --------------------------------------------------------------------------------