531 lines
9.3 KiB
ArmAsm
531 lines
9.3 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
|
|
; major_0x0db04
|
|
; 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
|
|
sync
|
|
|
|
lwz r15, PSA.PoolLock + Lock.Count(r1)
|
|
cmpwi cr1, r15, 0
|
|
li r15, 0
|
|
bne+ cr1, @no_panic
|
|
mflr r15
|
|
bl panic
|
|
@no_panic
|
|
|
|
stw r15, PSA.PoolLock + Lock.Count(r1)
|
|
|
|
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
|