mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2025-02-22 10:29:02 +00:00
Namely queues, semaphores, critical regions, event groups and "notifications". The MP calls implementing these services have been named after their MPLibrary wrapper functions. This convention will be followed in the future (no more NKCreateEvent).
522 lines
9.2 KiB
ArmAsm
522 lines
9.2 KiB
ArmAsm
Local_Panic set *
|
|
b panic
|
|
|
|
|
|
|
|
; InitPool
|
|
|
|
; Allocate one page for the kernel pool. Same layout at
|
|
; Memtop starts at 7 pages below KDP.
|
|
; Take note of the structure from kdp-ab0 to kdp-aa0
|
|
|
|
; Xrefs:
|
|
; setup
|
|
|
|
; > r1 = kdp
|
|
|
|
InitPool ; OUTSIDE REFERER
|
|
|
|
; r9 = LA_KD - 7 pages
|
|
lwz r8, KDP.PA_ConfigInfo(r1)
|
|
lwz r8, NKConfigurationInfo.LA_KernelData(r8)
|
|
lisori r9, 0x7000
|
|
subf r9, r9, r8
|
|
stw r9, -0x0a9c(r1)
|
|
|
|
lisori r9, -0x7000
|
|
add r9, r9, r1
|
|
stw r9, -0x0aa0(r1)
|
|
|
|
; bit of a mystery
|
|
lisori r8, 0x00006458
|
|
add r23, r8, r9
|
|
stw r8, 0x0000(r9)
|
|
|
|
lisori r8, '‡BGN'
|
|
stw r8, 0x0004(r9)
|
|
|
|
addi r9, r9, 0x08
|
|
lisori r8, 0x00006450
|
|
stw r8, 0x0000(r9)
|
|
|
|
lisori r8, 'free'
|
|
stw r8, 0x0004(r9)
|
|
|
|
li r8, 0x00
|
|
stw r8, 0x0000(r23)
|
|
|
|
lisori r8, '‡END'
|
|
stw r8, 0x0004(r23)
|
|
|
|
; set up linked list
|
|
addi r8, r1, PSA.FreePool
|
|
|
|
stw r9, LLL.Next(r8)
|
|
stw r9, LLL.Prev(r8)
|
|
stw r8, LLL.Next(r9)
|
|
stw r8, LLL.Prev(r9)
|
|
|
|
lisori r9, 'POOL'
|
|
stw r9, LLL.Signature(r8)
|
|
|
|
|
|
blr
|
|
|
|
|
|
|
|
; PoolAlloc
|
|
|
|
; Easy to use! 0xfd8 (a page minus 10 words) is the
|
|
; largest request that can be satisfied.
|
|
|
|
; Xrefs:
|
|
; setup
|
|
; major_0x02ccc
|
|
; KCCreateProcess
|
|
; KCCreateCpuStruct
|
|
; MPCall_15
|
|
; MPCall_39
|
|
; MPCall_17
|
|
; MPCall_20
|
|
; MPCall_25
|
|
; MPCall_49
|
|
; MPCall_40
|
|
; MPCall_31
|
|
; MPCall_64
|
|
; CauseNotification
|
|
; CreateTask
|
|
; MPCall_58
|
|
; convert_pmdts_to_areas
|
|
; NKCreateAddressSpaceSub
|
|
; MPCall_72
|
|
; createarea
|
|
; MPCall_73
|
|
; MPCall_130
|
|
; InitTMRQs
|
|
; InitIDIndex
|
|
; MakeID
|
|
|
|
; > r1 = kdp
|
|
; > r8 = size
|
|
|
|
; < r8 = ptr
|
|
|
|
PoolAlloc ; OUTSIDE REFERER
|
|
crclr cr7_eq
|
|
b PoolAllocCommon
|
|
|
|
PoolAlloc_with_crset ; OUTSIDE REFERER
|
|
crset cr7_eq
|
|
|
|
PoolAllocCommon
|
|
|
|
; Save LR and arg to EWA. Get lock.
|
|
mflr r17
|
|
mfsprg r18, 0
|
|
|
|
_Lock PSA.PoolLock, scratch1=r15, scratch2=r16
|
|
|
|
; These saves are my first real hint at the contents of that
|
|
; large unexplored area of the EWA. This file, then, owns
|
|
; part of the EWA, for its CPU-scoped globals. Because the
|
|
; kernel runs stackless.
|
|
stw r17, EWA.PoolSavedLR(r18)
|
|
stw r8, EWA.PoolSavedSizeArg(r18)
|
|
|
|
@try_again
|
|
; Check that requested allocation is in the doable size range.
|
|
cmpwi r8, 0
|
|
cmpwi cr1, r8, 0xfd8
|
|
ble+ Local_Panic ; zero-byte request => thud
|
|
bgt- cr1, @request_too_large
|
|
|
|
addi r8, r8, 39
|
|
rlwinm r8, r8, 0, 0, 26
|
|
|
|
; Check that the pool has any pages in it.
|
|
addi r14, r1, PSA.FreePool
|
|
lwz r15, LLL.Next(r14)
|
|
@try_different_page
|
|
cmpw r14, r15
|
|
|
|
bne+ @pool_has_page
|
|
|
|
; No? Then claim a page from the system free list for the pool?
|
|
|
|
; Got a free page in the system free list? It's ours.
|
|
li r8, 0 ; return zero if there is no page at all
|
|
li r9, 1 ; number of pages to grab
|
|
|
|
lwz r16, PSA.FreePageCount(r1)
|
|
lwz r17, PSA.UnheldFreePageCount(r1)
|
|
subf. r16, r9, r16
|
|
subf r17, r9, r17
|
|
blt- PoolCommonReturn
|
|
|
|
stw r16, PSA.FreePageCount(r1)
|
|
stw r17, PSA.UnheldFreePageCount(r1)
|
|
|
|
; Get that page, mofo. Macros FTW.
|
|
lwz r8, PSA.FreeList + LLL.Next(r1)
|
|
RemoveFromList r8, scratch1=r17, scratch2=r18
|
|
|
|
; There was probably once a mechanism for virtual addressing of the pool!
|
|
li r9, 0
|
|
bl ExtendPool ; r8=page, r9=virt=0
|
|
|
|
; Now that the pool is not empty, start over.
|
|
mfsprg r18, 0
|
|
lwz r8, EWA.PoolSavedSizeArg(r18)
|
|
b @try_again
|
|
|
|
@request_too_large
|
|
li r8, 0
|
|
b PoolCommonReturn
|
|
|
|
@pool_has_page
|
|
; We have a page (r15) that might have room in it.
|
|
; r8 contains the size describing our actual demand on the page!
|
|
|
|
lwz r16, PoolPage.FreeBytes(r15)
|
|
cmplw r16, r8
|
|
|
|
lis r20, 'fr'
|
|
bgt- @fits_with_leftover_space
|
|
beq- @fits_perfectly
|
|
ori r20, r20, 'ee'
|
|
|
|
lwz r16, PoolPage.FreeBytes(r15)
|
|
add r18, r16, r15 ; r18 = ???
|
|
lwz r19, 0x0004(r18)
|
|
cmplw cr1, r18, r15
|
|
cmpw r19, r20
|
|
ble+ cr1, Local_Panic
|
|
bne- @_118
|
|
lwz r17, 0x0000(r18)
|
|
rotlwi r19, r19, 0x08
|
|
add r17, r17, r16
|
|
stw r17, 0x0000(r15)
|
|
stw r19, 0x0004(r18)
|
|
lwz r17, 0x000c(r18)
|
|
lwz r16, LLL.Next(r18)
|
|
stw r16, LLL.Next(r17)
|
|
stw r17, 0x000c(r16)
|
|
b @pool_has_page
|
|
|
|
@_118
|
|
lwz r15, LLL.Next(r15)
|
|
b @try_different_page
|
|
|
|
@fits_with_leftover_space
|
|
subf r16, r8, r16
|
|
cmpwi r16, 0x28
|
|
blt- @fits_perfectly
|
|
stw r16, 0x0000(r15)
|
|
add r15, r15, r16
|
|
stw r8, 0x0000(r15)
|
|
b @_14c
|
|
|
|
@fits_perfectly
|
|
lwz r14, 0x000c(r15)
|
|
lwz r16, LLL.Next(r15)
|
|
stw r16, LLL.Next(r14)
|
|
stw r14, 0x000c(r16)
|
|
|
|
@_14c
|
|
lisori r8, '‡loc'
|
|
stw r8, 0x0004(r15)
|
|
addi r8, r15, 0x08
|
|
|
|
beq- cr7, PoolCommonReturn
|
|
lwz r16, 0x0000(r15)
|
|
addi r16, r16, -0x08
|
|
li r14, 0x00
|
|
add r16, r16, r15
|
|
addi r15, r15, 0x04
|
|
|
|
@_174
|
|
stwu r14, 0x0004(r15)
|
|
cmpw r15, r16
|
|
ble+ @_174
|
|
b PoolCommonReturn
|
|
|
|
|
|
|
|
; PoolFree
|
|
|
|
; ARG void *r8
|
|
|
|
PoolFree ; OUTSIDE REFERER
|
|
mflr r17
|
|
mfsprg r18, 0
|
|
|
|
_Lock PSA.PoolLock, scratch1=r15, scratch2=r16
|
|
|
|
stw r17, EWA.PoolSavedLR(r18)
|
|
bl major_0x129fc
|
|
bl major_0x12a34
|
|
|
|
|
|
|
|
; File-internal
|
|
|
|
; Return path of most of these functions?
|
|
; Releases Pool lock and Returns to the link
|
|
; address saved in EWA.
|
|
|
|
PoolCommonReturn ; OUTSIDE REFERER
|
|
mfsprg r18, 0
|
|
|
|
_AssertAndRelease PSA.PoolLock, scratch=r15
|
|
|
|
lwz r17, EWA.PoolSavedLR(r18)
|
|
mtlr r17
|
|
blr
|
|
|
|
|
|
|
|
; major_0x129fc
|
|
|
|
; Xrefs:
|
|
; PoolFree
|
|
; ExtendPool
|
|
|
|
; ARG Area *r8
|
|
|
|
major_0x129fc ; OUTSIDE REFERER
|
|
subi r15, r8, 8
|
|
|
|
lis r20, 'fr'
|
|
lhz r16, 4(r15)
|
|
ori r20, r20, 'ee'
|
|
cmplwi r16, 0x876c
|
|
bne+ Local_Panic
|
|
stw r20, 4(r15)
|
|
|
|
addi r16, r1, PSA.FreePool
|
|
|
|
InsertAsPrev r15, r16, scratch=r17
|
|
|
|
blr
|
|
|
|
|
|
|
|
; major_0x12a34
|
|
|
|
; Xrefs:
|
|
; PoolFree
|
|
; ExtendPool
|
|
|
|
major_0x12a34 ; OUTSIDE REFERER
|
|
lis r20, 0x6672
|
|
lwz r16, 0x0000(r15)
|
|
ori r20, r20, 0x6565
|
|
add r18, r16, r15
|
|
lwz r19, 0x0004(r18)
|
|
cmplw cr1, r18, r15
|
|
cmpw r19, r20
|
|
ble+ cr1, Local_Panic
|
|
bnelr-
|
|
lwz r17, 0x0000(r18)
|
|
rotlwi r19, r19, 0x08
|
|
add r17, r17, r16
|
|
stw r17, 0x0000(r15)
|
|
stw r19, 0x0004(r18)
|
|
lwz r17, 0x000c(r18)
|
|
lwz r16, LLL.Next(r18)
|
|
stw r16, LLL.Next(r17)
|
|
stw r17, 0x000c(r16)
|
|
b major_0x12a34
|
|
|
|
|
|
|
|
; ExtendPool
|
|
|
|
; 0xed0(r1) = pool extends (I increment)
|
|
; -0xa9c(r1) = virt last page (I update)
|
|
; -0xaa0(r1) = phys last page (I update)
|
|
; Assumes that cache blocks are 32 bytes! Uh-oh.
|
|
; Page gets decorated like this:
|
|
; 000: 00 00 0f e8
|
|
; 004: 87 'B 'G 'N
|
|
; 008: 00 00 0f e8
|
|
; 00c: 87 'l 'o 'c
|
|
; ... zeros << r8 passes ptr to here
|
|
; fe8: phys offset from here to prev page
|
|
; fec: 87 'E 'N 'D
|
|
; ff0: logical abs address of prev page
|
|
; ff4: 00 00 00 00
|
|
; ff8: 00 00 00 00
|
|
; ffc: 00 00 00 00
|
|
|
|
; Xrefs:
|
|
; MPCall_0
|
|
; PoolAlloc
|
|
|
|
; > r1 = kdp
|
|
; > r8 = anywhere in new page (phys)
|
|
; > r9 = page_virt
|
|
|
|
ExtendPool ; OUTSIDE REFERER
|
|
mflr r14
|
|
rlwinm r17, r8, 0, 0, 19
|
|
|
|
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.FreePoolExtendCount(r1)
|
|
addi r16, r16, 1
|
|
stw r16, KDP.NanoKernelInfo + NKNanoKernelInfo.FreePoolExtendCount(r1)
|
|
|
|
_log 'Extend free pool: phys 0x'
|
|
mr r8, r17
|
|
bl Printw
|
|
_log ' virt 0x'
|
|
mr r8, r9
|
|
bl Printw
|
|
_log ' count: '
|
|
mr r8, r16
|
|
bl Printd
|
|
_log '^n'
|
|
li r16, 0x1000
|
|
|
|
@zeroloop
|
|
subi r16, r16, 32
|
|
cmpwi r16, 0
|
|
dcbz r16, r17
|
|
bgt+ @zeroloop
|
|
|
|
; Put the funny stuff in
|
|
li r16, 0xfe8
|
|
stw r16, 0x0000(r17)
|
|
lisori r16, '‡BGN'
|
|
stw r16, 0x0004(r17)
|
|
addi r15, r17, 0x08
|
|
li r16, 0xfe0
|
|
stw r16, 0x0000(r15)
|
|
lisori r16, '‡loc'
|
|
stw r16, 0x0004(r15)
|
|
addi r15, r17, 0xfe8
|
|
lwz r18, -0x0aa0(r1)
|
|
subf r18, r15, r18
|
|
stw r18, 0x0000(r15)
|
|
lisori r16, '‡END'
|
|
stw r16, 0x0004(r15)
|
|
lwz r16, -0x0a9c(r1)
|
|
stw r16, LLL.Next(r15)
|
|
|
|
; Update globals
|
|
stw r9, -0x0a9c(r1)
|
|
stw r17, -0x0aa0(r1)
|
|
|
|
; Unknown func calls
|
|
addi r8, r17, 0x10
|
|
bl major_0x129fc
|
|
bl major_0x12a34
|
|
mtlr r14
|
|
blr
|
|
|
|
|
|
|
|
; major_0x12b94
|
|
|
|
; Xrefs:
|
|
; "HeapSegCorrupt"
|
|
|
|
mflr r19
|
|
lwz r20, -0x0aa0(r1)
|
|
|
|
major_0x12b94_0x8
|
|
addi r8, r20, 0x08
|
|
bl major_0x12b94_0x30
|
|
lwz r17, 0x0000(r20)
|
|
add r17, r17, r20
|
|
lwz r18, 0x0000(r17)
|
|
cmpwi r18, 0x00
|
|
add r20, r18, r17
|
|
bne+ major_0x12b94_0x8
|
|
mtlr r19
|
|
blr
|
|
|
|
major_0x12b94_0x30
|
|
mflr r14
|
|
addi r16, r8, -0x08
|
|
|
|
major_0x12b94_0x38
|
|
lwz r17, 0x0004(r16)
|
|
lis r18, -0x78bb
|
|
ori r18, r18, 0x4e44
|
|
cmpw r17, r18
|
|
li r9, 0x00
|
|
beq- major_0x12b94_0x1a4
|
|
lis r18, -0x7894
|
|
ori r18, r18, 0x6f63
|
|
cmpw r17, r18
|
|
beq- major_0x12b94_0x94
|
|
lis r18, 0x6672
|
|
ori r18, r18, 0x6565
|
|
li r9, 0x04
|
|
cmpw r17, r18
|
|
bne- major_0x12b94_0xa8
|
|
lwz r17, 0x000c(r16)
|
|
cmpwi r17, 0x00
|
|
li r9, 0x05
|
|
beq- major_0x12b94_0xa8
|
|
lwz r17, LLL.Next(r16)
|
|
cmpwi r17, 0x00
|
|
li r9, 0x06
|
|
beq- major_0x12b94_0xa8
|
|
|
|
major_0x12b94_0x94
|
|
lwz r17, 0x0000(r16)
|
|
add r16, r16, r17
|
|
cmpwi r17, 0x00
|
|
li r9, 0x07
|
|
bgt+ major_0x12b94_0x38
|
|
|
|
major_0x12b94_0xa8
|
|
mr r18, r8
|
|
_log 'Heap segment corrupt '
|
|
mr r8, r9
|
|
bl Printd
|
|
_log 'at '
|
|
mr r8, r16
|
|
bl Printw
|
|
_log '^n'
|
|
addi r16, r16, -0x40
|
|
li r17, 0x08
|
|
|
|
major_0x12b94_0x10c
|
|
mr r8, r16
|
|
bl Printw
|
|
_log ' '
|
|
lwz r8, 0x0000(r16)
|
|
bl Printw
|
|
lwz r8, 0x0004(r16)
|
|
bl Printw
|
|
lwz r8, LLL.Next(r16)
|
|
bl Printw
|
|
lwz r8, 0x000c(r16)
|
|
bl Printw
|
|
_log ' *'
|
|
li r8, 0x10
|
|
addi r16, r16, -0x01
|
|
mtctr r8
|
|
|
|
major_0x12b94_0x164
|
|
lbzu r8, 0x0001(r16)
|
|
cmpwi r8, 0x20
|
|
bgt- major_0x12b94_0x174
|
|
li r8, 0x20
|
|
|
|
major_0x12b94_0x174
|
|
bl Printc
|
|
bdnz+ major_0x12b94_0x164
|
|
_log '*^n'
|
|
addi r17, r17, -0x01
|
|
addi r16, r16, 0x01
|
|
cmpwi r17, 0x00
|
|
bne+ major_0x12b94_0x10c
|
|
mr r8, r18
|
|
|
|
major_0x12b94_0x1a4
|
|
mtlr r14
|
|
blr
|