mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-06-09 22:29:30 +00:00
85c87e641a
The master branch builds 02.28. This branch builds 02.27, 02.26 and so on. It will be frequently rebased on master.
4786 lines
133 KiB
ArmAsm
4786 lines
133 KiB
ArmAsm
##### ###### ###
|
|
# # ##### ## #### ###### # # ## # # # #### # #### # ## # # #####
|
|
# # # # # # # # # # # # ## # # # # # # # # # ## # # #
|
|
##### # # # # # ##### ###### # # # # # # # # #### # # # # # # # #
|
|
# ##### ###### # # # ###### # # # # # # # # ###### # # # # #
|
|
# # # # # # # # # # # # ## # # # # # # # # # # ## # #
|
|
##### # # # #### ###### # # # # # # #### ### #### ###### # # # # #####
|
|
|
|
SpacePanicIsland
|
|
b panic
|
|
|
|
|
|
|
|
### ####### ###### #
|
|
# # # # ##### # ##### ###### ###### # # ## #### ###### # # #### #####
|
|
# ## # # # # # # # # # # # # # # # # # # #
|
|
# # # # # # ##### # # ##### ##### ###### # # # ##### # # #### #
|
|
# # # # # # # ##### # # # ###### # ### # # # # #
|
|
# # ## # # # # # # # # # # # # # # # # # #
|
|
### # # # # # # # ###### ###### # # # #### ###### ####### # #### #
|
|
|
|
InitFreePageList
|
|
addi r9, r1, PSA.FreeList
|
|
|
|
InitList r9, 'PHYS', scratch=r8
|
|
|
|
li r8, 0
|
|
stw r8, PSA.FreePageCount(r1)
|
|
stw r8, PSA.UnheldFreePageCount(r1)
|
|
stw r8, PSA.ZeroedByInitFreeList3(r1)
|
|
|
|
lwz r8, PSA.OtherSystemAddrSpcPtr(r1)
|
|
stw r8, PSA.OtherSystemAddrSpcPtr2(r1)
|
|
|
|
blr
|
|
|
|
|
|
|
|
##### # ####### ###### # #
|
|
# # ##### ###### ## ##### ###### # # ##### ###### ## #### # ##### #### # # # # ## #### ###### ## ## ## #####
|
|
# # # # # # # # # # # # # # # # # # # # # ## ## # # # # # # # # # # # # # # #
|
|
# # # ##### # # # ##### # # # # ##### # # #### ##### # # # # # ## # ###### # # # ##### # # # # # # #
|
|
# ##### # ###### # # ####### ##### # ###### # # ##### # # # # # ###### # ### # # # ###### #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
##### # # ###### # # # ###### # # # # ###### # # #### # # # #### # # # # # #### ###### # # # # #
|
|
|
|
; Pretty obvious from log output.
|
|
|
|
CreateAreasFromPageMap
|
|
|
|
; The kind of crap we have to do without a stack
|
|
mflr r16
|
|
mfcr r17
|
|
stw r16, EWA.SpacesSavedLR(r1)
|
|
stw r17, EWA.SpacesSavedCR(r1)
|
|
|
|
_log 'Converting PMDTs to areas^n'
|
|
|
|
lwz r17, PSA.UnheldFreePageCount(r1)
|
|
lwz r16, KDP.TotalPhysicalPages(r1)
|
|
add r17, r17, r16
|
|
stw r17, PSA.UnheldFreePageCount(r1)
|
|
|
|
|
|
;_______________________________________________________________________
|
|
; Code to increment a loop that:
|
|
; iterates over segmap entries, and
|
|
; iterates over PMDTs, starting at the one
|
|
; ref'd by the segmap entry
|
|
;_______________________________________________________________________
|
|
|
|
addi r27, r1, KDP.SegMaps - 8
|
|
lis r26, 0
|
|
|
|
@next_segment_entry
|
|
_wlog 'SEGMENT ', r26, '^n'
|
|
|
|
lwzu r25, 8(r27)
|
|
|
|
b @this_pmdt
|
|
@next_pmdt
|
|
addi r25, r25, PMDT.Size
|
|
@this_pmdt
|
|
|
|
|
|
;_______________________________________________________________________
|
|
; Now we enter the loop body:
|
|
; r27 points to segmap entry
|
|
; r25 points to the PMDT
|
|
; r26 equals the base address of this segment
|
|
;_______________________________________________________________________
|
|
|
|
|
|
; Load the contents of the PMDT.
|
|
|
|
lwz r17, PMDT.PBaseAndFlags(r25)
|
|
_wlog ' PMDT PBaseAndFlags ', r17, ' '
|
|
|
|
lhz r15, PMDT.LBase(r25)
|
|
_wlogh 'LBase ', r15, ' '
|
|
|
|
andi. r8, r17, $800 | $400 | $200 ; interested in 3 PBase flags
|
|
|
|
lhz r16, PMDT.PageCount(r25)
|
|
_wlogh 'PageCount ', r16, '^n', scratch=r9 ; cannot clobber r8 here
|
|
|
|
|
|
; Based on those flags, do one of two things
|
|
cmplwi r8, 0
|
|
cmplwi cr1, r8, $800 | $400
|
|
beq @pmdt_flags_are_zero
|
|
beq cr1, @pmdt_flags_are_c00
|
|
|
|
; Else if not a full-segment PMDT, next PMDT
|
|
cmplwi cr2, r15, 0x0000
|
|
cmplwi cr3, r16, 0xffff
|
|
bne cr2, @next_pmdt
|
|
bne cr3, @next_pmdt
|
|
|
|
; Else if there are segments remaining (16 total), next segment.
|
|
addis r26, r26, 0x1000
|
|
cmplwi r26, 0 ; once it wraps to zero, we're done
|
|
bne @next_segment_entry
|
|
|
|
; Else create special one-page Areas to catch naughty pointer derefs,
|
|
; then return.
|
|
|
|
; 61F168F1 (magic bus error incantation)
|
|
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq SpacePanicIsland
|
|
|
|
lwz r8, EWA.PA_CurAddressSpace(r1)
|
|
stw r8, Area.AddressSpacePtr(r31)
|
|
|
|
lisori r15, 0x68f168f1
|
|
stw r15, Area.LogicalBase(r31)
|
|
|
|
li r16, 0x1000
|
|
stw r16, Area.Length(r31)
|
|
|
|
lisori r8, 0x00008000
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
|
|
li r8, 0
|
|
stw r8, 0x001c(r31)
|
|
|
|
lisori r8, 0x0000e00c
|
|
stw r8, 0x0020(r31)
|
|
|
|
mr r8, r31
|
|
bl CreateArea
|
|
|
|
cmpwi r9, noErr
|
|
beq @success_68f168f1
|
|
mr r8, r31
|
|
bl PoolFree
|
|
@success_68f168f1
|
|
|
|
|
|
; DEADBEEF (all over the place)
|
|
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq SpacePanicIsland
|
|
|
|
lwz r8, EWA.PA_CurAddressSpace(r1)
|
|
stw r8, Area.AddressSpacePtr(r31)
|
|
|
|
lisori r15, 0xdeadbeef
|
|
stw r15, Area.LogicalBase(r31)
|
|
|
|
li r16, 0x1000
|
|
stw r16, Area.Length(r31)
|
|
|
|
lisori r8, 0x00008000
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
|
|
li r8, 0
|
|
stw r8, 0x001c(r31)
|
|
|
|
lisori r8, 0x0000e00c
|
|
stw r8, 0x0020(r31)
|
|
|
|
mr r8, r31
|
|
bl CreateArea
|
|
|
|
cmpwi r9, noErr
|
|
beq @success_deadbeef
|
|
mr r8, r31
|
|
bl PoolFree
|
|
@success_deadbeef
|
|
|
|
|
|
; Done -- return.
|
|
lwz r16, EWA.SpacesSavedLR(r1)
|
|
lwz r17, EWA.SpacesSavedCR(r1)
|
|
mtlr r16
|
|
mtcr r17
|
|
blr
|
|
|
|
|
|
; ONE OF THE "FLAGS" CASES: all tests bits unset
|
|
|
|
@pmdt_flags_are_zero
|
|
_clog ' pmdt_flags_are_zero^n'
|
|
|
|
; Apparently other iterations leave this to find?
|
|
lwz r8, EWA.SpacesDeferredAreaPtr(r1)
|
|
cmpwi r8, 0
|
|
beq @thing_is_zero
|
|
|
|
bl CreateArea
|
|
cmpwi r9, noErr
|
|
bne SpacePanicIsland
|
|
|
|
li r8, 0
|
|
stw r8, EWA.SpacesDeferredAreaPtr(r1)
|
|
@thing_is_zero
|
|
|
|
|
|
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq SpacePanicIsland
|
|
|
|
; Reload PMDT details
|
|
lwz r17, PMDT.PBaseAndFlags(r25)
|
|
lhz r15, PMDT.LBase(r25)
|
|
lhz r16, PMDT.PageCount(r25)
|
|
|
|
; Why do we need to sign the area? Isn't it 'AREA'?
|
|
lisori r8, 'area'
|
|
stw r8, Area.Signature(r31)
|
|
|
|
; Set r15/r16 to true logical base/length
|
|
slwi r15, r15, 12
|
|
addi r16, r16, 1
|
|
add r15, r15, r26 ; add a page, I think
|
|
slwi r16, r16, 12
|
|
|
|
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.blueProcessID(r1)
|
|
stw r8, Area.ProcessID(r31)
|
|
|
|
lwz r8, EWA.PA_CurAddressSpace(r1)
|
|
stw r8, Area.AddressSpacePtr(r31)
|
|
|
|
stw r15, Area.LogicalBase(r31)
|
|
|
|
stw r16, Area.Length(r31)
|
|
stw r16, Area.BytesMapped(r31)
|
|
|
|
li r8, 0
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
|
|
lwz r18, 0x007c(r31)
|
|
rlwinm r9, r17, 0, 0, 19
|
|
stw r9, 0x0070(r31)
|
|
andi. r16, r17, 0x03
|
|
bne @_20c
|
|
ori r17, r17, 0x02
|
|
@_20c
|
|
|
|
bl major_0x10d38_0x58
|
|
stw r18, 0x001c(r31)
|
|
|
|
|
|
@_214
|
|
|
|
|
|
|
|
lisori r8, 0x0000e00c
|
|
stw r8, 0x0020(r31)
|
|
|
|
|
|
; Try to create the Area. If we succeed then do the next PMDT.
|
|
mr r8, r31
|
|
bl CreateArea
|
|
cmpwi r9, noErr
|
|
mr r31, r8
|
|
beq @next_pmdt
|
|
|
|
; If CreateArea failed, assume that it was due to overlap with another Area.
|
|
|
|
; Find that AboveArea that we impinged on (=> r24).
|
|
lwz r9, Area.LogicalBase(r31)
|
|
lwz r8, Area.AddressSpacePtr(r31)
|
|
bl FindAreaAbove
|
|
mr r24, r8
|
|
|
|
; Shorten our FailedArea to fit below AboveArea.
|
|
lwz r15, Area.LogicalBase(r31)
|
|
lwz r16, Area.LogicalBase(r24)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
subf. r16, r15, r16 ; r16 = offset of found area from this one
|
|
stw r17, EWA.SpacesSavedAreaBase(r1) ; ???
|
|
stw r16, Area.Length(r31) ; we will try again, with no overlap
|
|
|
|
beq @found_area_has_same_base
|
|
|
|
; If FoundArea < FailedArea, panic (impossible for FindAreaAbove to return this)
|
|
bltl SpacePanicIsland ; below would be impossible
|
|
|
|
; If AboveArea > FailedArea, create NewArea (=> r30)
|
|
mr r8, r31
|
|
bl CreateArea
|
|
|
|
cmpwi r9, noErr ; strike three
|
|
mr r30, r8
|
|
bnel SpacePanicIsland
|
|
|
|
; If AboveArea.LogicalEnd >= FailedArea.LogicalEnd then continue to next PMDT.
|
|
lwz r15, Area.LogicalEnd(r24)
|
|
lwz r16, EWA.SpacesSavedAreaBase(r1)
|
|
subf. r16, r15, r16
|
|
ble @next_pmdt
|
|
|
|
; Else replace FailedArea with an Area copied from NewArea
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq SpacePanicIsland
|
|
|
|
li r8, Area.Size - 4
|
|
@area_copy_loop
|
|
lwzx r9, r8, r30
|
|
stwx r9, r8, r31
|
|
cmpwi r8, 0
|
|
subi r8, r8, 4
|
|
bgt @area_copy_loop
|
|
@found_area_has_same_base
|
|
|
|
; Else (AboveArea == ThisArea), do nothing special (endif)
|
|
|
|
|
|
lwz r9, Area.LogicalBase(r31)
|
|
|
|
lwz r15, 0x0028(r24)
|
|
lwz r16, EWA.SpacesSavedAreaBase(r1) ; this is FailedArea.LogicalEnd
|
|
subf. r16, r15, r16
|
|
addi r15, r15, 1
|
|
blel SpacePanicIsland
|
|
|
|
stw r16, Area.Length(r31)
|
|
stw r15, Area.LogicalBase(r31)
|
|
subf r9, r9, r15
|
|
lwz r8, 0x0070(r31)
|
|
add r8, r8, r9
|
|
stw r8, 0x0070(r31)
|
|
b @_214
|
|
|
|
|
|
|
|
|
|
@pmdt_flags_are_c00
|
|
_clog ' pmdt_flags_are_c00^n'
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq SpacePanicIsland
|
|
|
|
lwz r17, 0x0004(r25)
|
|
lhz r15, 0x0000(r25)
|
|
lhz r16, 0x0002(r25)
|
|
lis r8, 0x6172
|
|
ori r8, r8, 0x6561
|
|
stw r8, Area.Signature(r31)
|
|
slwi r15, r15, 12
|
|
addi r16, r16, 0x01
|
|
add r15, r15, r26
|
|
slwi r16, r16, 12
|
|
lwz r8, 0x0ec0(r1)
|
|
stw r8, Area.ProcessID(r31)
|
|
lwz r8, EWA.PA_CurAddressSpace(r1)
|
|
stw r8, Area.AddressSpacePtr(r31)
|
|
stw r15, Area.LogicalBase(r31)
|
|
stw r16, Area.Length(r31)
|
|
stw r16, Area.BytesMapped(r31)
|
|
li r8, 0x00
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
li r8, 0x07
|
|
stw r8, 0x001c(r31)
|
|
lis r8, 0x00
|
|
ori r8, r8, 0x600c
|
|
stw r8, 0x0020(r31)
|
|
rlwinm r8, r17, 22, 0, 29
|
|
stw r8, 0x0040(r31)
|
|
lwz r8, Area.Flags(r31)
|
|
ori r8, r8, 0x40
|
|
lwz r9, PSA.FreePageCount(r1)
|
|
cmpwi r9, noErr
|
|
|
|
bgt @_374
|
|
ori r8, r8, 0x80
|
|
@_374
|
|
|
|
stw r8, Area.Flags(r31)
|
|
cmpwi r15, 0x00
|
|
|
|
bne @_388
|
|
stw r31, EWA.SpacesDeferredAreaPtr(r1)
|
|
b @next_pmdt
|
|
@_388
|
|
|
|
lwz r18, EWA.SpacesDeferredAreaPtr(r1)
|
|
cmpwi r18, 0x00
|
|
beq @_3c8
|
|
lwz r8, 0x0024(r18)
|
|
lwz r9, 0x002c(r18)
|
|
add r19, r8, r9
|
|
cmplw r19, r15
|
|
bne @_3c8
|
|
add r9, r9, r16
|
|
addi r19, r9, -0x01
|
|
stw r9, 0x002c(r18)
|
|
stw r9, 0x0038(r18)
|
|
stw r19, 0x0028(r18)
|
|
mr r8, r31
|
|
bl PoolFree
|
|
b @next_pmdt
|
|
@_3c8
|
|
|
|
lwz r8, Area.Flags(r31)
|
|
ori r8, r8, 0x80
|
|
stw r8, Area.Flags(r31)
|
|
mr r8, r31
|
|
bl CreateArea
|
|
cmpwi r9, noErr
|
|
bne SpacePanicIsland
|
|
b @next_pmdt
|
|
|
|
|
|
|
|
# # ###### ##### ###### ##### #####
|
|
## ## # # # # ###### ##### # # ## #### ###### # # # ###### ###### # # # ## #### #### ###### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ###### # # # ##### ##### # # ##### # # # # #### #### ##### ####
|
|
# # # # # # # # ###### # ### # # # # # # # ###### # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### ##### # ###### ###### ##### ###### # # #### #### ###### ####
|
|
|
|
; The number of page size classes, 1 to n.
|
|
|
|
; MPPageSizeClass MPGetPageSizeClasses(void )
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: yes
|
|
|
|
DeclareMPCall 68, MPGetPageSizeClasses
|
|
|
|
MPGetPageSizeClasses
|
|
|
|
li r3, 1
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### ##### ###### #####
|
|
## ## # # # # ###### ##### # # ## #### ###### # # # ###### ######
|
|
# # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ###### # # # ##### ##### # # #####
|
|
# # # # # # # # ###### # ### # # # # #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### ##### # ###### ######
|
|
|
|
; The page size in bytes.
|
|
|
|
; ByteCount MPGetPageSize(MPPageSizeClass pageClass)
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: yes
|
|
|
|
DeclareMPCall 69, MPGetPageSize
|
|
|
|
MPGetPageSize
|
|
|
|
cmpwi r3, 1
|
|
bne ReturnParamErrFromMPCall
|
|
|
|
lwz r3, KDP.ProcessorInfo + NKProcessorInfo.PageSize(r1)
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### ##### # #####
|
|
## ## # # # # ##### ###### ## ##### ###### # # ##### ##### ##### ###### #### #### # # ##### ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # ##### # # # ##### # # # # # # # # ##### #### #### ##### # # # # # #####
|
|
# # # # ##### # ###### # # ####### # # # # ##### # # # # ##### ###### # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### # # ###### # # # ###### # # ##### ##### # # ###### #### #### ##### # # # #### ######
|
|
|
|
; ARG MPCoherenceID r3
|
|
; RET OSStatus r3, MPAddressSpaceID r4
|
|
|
|
; Straight MPLibrary wrapper: no
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 70, MPCreateAddressSpace
|
|
|
|
MPCreateAddressSpace
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mfsprg r16, 0
|
|
lwz r17, EWA.PA_CurTask(r16)
|
|
|
|
mr r8, r3
|
|
|
|
lwz r9, Area.AddressSpacePtr(r17)
|
|
lwz r16, AddressSpace.Flags(r9)
|
|
rlwinm. r16, r16, 0, AddressSpace.kFlag30, AddressSpace.kFlag30
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
bl NKCreateAddressSpaceSub
|
|
|
|
_AssertAndRelease PSA.SchLock, scratch=r16
|
|
|
|
mr. r3, r8
|
|
li r4, 0
|
|
bne CommonMPCallReturnPath ; failure
|
|
|
|
lwz r4, AddressSpace.ID(r9)
|
|
b CommonMPCallReturnPath ; success
|
|
|
|
|
|
|
|
# # # # ##### # ##### #####
|
|
## # # # # # ##### ###### ## ##### ###### # # ##### ##### ##### ###### #### #### # # ##### ## #### ###### # # # # #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ### # # # ##### # # # ##### # # # # # # # # ##### #### #### ##### # # # # # ##### ##### # # #####
|
|
# # # # # # ##### # ###### # # ####### # # # # ##### # # # # ##### ###### # # # # # # #
|
|
# ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # # ##### # # ###### # # # ###### # # ##### ##### # # ###### #### #### ##### # # # #### ###### ##### #### #####
|
|
|
|
; ARG MPCoherenceID r8 owningcgrp ; 0 to use mobo cgrp
|
|
; Process *r9 owningPROC
|
|
|
|
; RET osErr r8
|
|
; AddressSpace *r9
|
|
|
|
NKCreateAddressSpaceSub
|
|
cmpwi r8, 0
|
|
mr r27, r9 ; Save the process arg for later
|
|
mflr r30
|
|
|
|
; Use the motherboard coherence group if none is provided in r8
|
|
bne @cgrp_provided
|
|
mfsprg r15, 0
|
|
lwz r28, EWA.CPUBase + CPU.LLL + LLL.Freeform(r15)
|
|
|
|
b @got_cgrp
|
|
|
|
@cgrp_provided
|
|
bl LookupID ; takes id in r8, returns ptr in r8 and kind in r9
|
|
|
|
cmpwi r9, CoherenceGroup.kIDClass
|
|
mr r28, r8
|
|
bne @fail_notcgrp
|
|
lwz r28, CoherenceGroup.LLL + LLL.Next(r28)
|
|
|
|
@got_cgrp
|
|
|
|
|
|
; Read the SpecialPtr of this cgrp element in list of the owning CpuStruct
|
|
; But why? cgrp.LLL.Freeform does not seem to be set for the mobo cgrp
|
|
lwz r29, LLL.Freeform(r28)
|
|
|
|
|
|
; Boast (including the SpecialPtr)
|
|
_log 'NKCreateAddressSpaceSub - group at 0x'
|
|
|
|
mr r8, r28
|
|
bl printw
|
|
|
|
mr r8, r29
|
|
bl printw
|
|
|
|
_log '^n'
|
|
|
|
|
|
; Create the AddressSpace
|
|
li r8, AddressSpace.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq @fail_OOM
|
|
|
|
|
|
; Give the addr spc a copy of the SpecialPtr of its parent cgrp
|
|
stw r29, AddressSpace.ParentCoherenceSpecialPtr(r31)
|
|
|
|
|
|
; Give the addr spc an ID
|
|
li r9, AddressSpace.kIDClass
|
|
bl MakeID
|
|
|
|
cmpwi r8, 0x00
|
|
beq @fail_MakeID
|
|
|
|
stw r8, AddressSpace.ID(r31)
|
|
|
|
|
|
; Increment a counter in the cgrp (modulo a million, fail on overflow)
|
|
lwz r16, CoherenceGroup.Incrementer(r28)
|
|
addi r16, r16, 1
|
|
clrlwi. r16, r16, 12
|
|
beq @fail_toomanycalls
|
|
stw r16, CoherenceGroup.Incrementer(r28)
|
|
|
|
|
|
; Fill segment register fields in the address space struct like so:
|
|
; (8 bits = 0x20) || (4 bits = word idx) || (20 bits = prev call count)
|
|
|
|
addi r16, r16, -1
|
|
li r17, 0x40 - 4
|
|
oris r16, r16, 0x2000
|
|
addi r18, r31, AddressSpace.SRs
|
|
|
|
@fill_loop
|
|
cmpwi r17, 0
|
|
rlwimi r16, r17, 18, 8, 11 ; = index (15, 14, 13...) << 20
|
|
stwx r16, r17, r18
|
|
addi r17, r17, -4
|
|
bne @fill_loop
|
|
|
|
|
|
; Sign the addr spc struct
|
|
lisori r8, AddressSpace.kSignature
|
|
stw r8, AddressSpace.Signature(r31)
|
|
|
|
|
|
; Create an empty linked list of 'rsrv's (what are they?)
|
|
addi r16, r31, AddressSpace.RsrvList
|
|
InitList r16, 'rsrv', scratch=r17
|
|
|
|
|
|
; Create a linked list with one Area
|
|
addi r16, r31, AddressSpace.AreaList
|
|
InitList r16, 'area', scratch=r17
|
|
|
|
; Allocate the Area, check for errors
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r29, r8
|
|
beq @fail_OOM_again
|
|
|
|
; Sign the Area
|
|
lisori r8, Area.kSignature
|
|
stw r8, Area.Signature(r29)
|
|
|
|
; Pop some constants in
|
|
lisori r8, -1
|
|
stw r8, Area.LogicalBase(r29)
|
|
stw r8, Area.LogicalEnd(r29)
|
|
li r8, 256
|
|
stw r8, Area.Flags(r29)
|
|
|
|
; Give it a copy of the ID of its parent address space
|
|
lwz r8, AddressSpace.ID(r31)
|
|
stw r8, Area.AddressSpaceID(r29)
|
|
|
|
; Point the SpecialPtr to it and insert it in the list
|
|
addi r16, r31, AddressSpace.AreaList
|
|
addi r29, r29, Area.LLL
|
|
stw r16, LLL.Freeform(r29)
|
|
InsertAsPrev r29, r16, scratch=r17
|
|
|
|
|
|
; Point this struct by ID to its owning Process,
|
|
; and increment a counter in that struct.
|
|
lwz r18, Process.ID(r27)
|
|
stw r18, AddressSpace.ProcessID(r31)
|
|
|
|
lwz r17, Process.AddressSpaceCount(r27)
|
|
addi r17, r17, 1
|
|
stw r17, Process.AddressSpaceCount(r27)
|
|
|
|
|
|
; Done, with no errors
|
|
li r8, 0 ; kMPNoErr
|
|
mr r9, r31 ; ptr to new AddressSpace
|
|
b @return
|
|
|
|
@fail_OOM_again
|
|
lwz r8,Area.ID(r31)
|
|
|
|
@fail_toomanycalls
|
|
bl DeleteID
|
|
mr r8, r31
|
|
bl PoolFree
|
|
li r8, kMPInsufficientResourcesErr
|
|
b @return
|
|
|
|
@fail_MakeID
|
|
mr r8, r31
|
|
bl PoolFree
|
|
|
|
@fail_OOM
|
|
li r8, -29294
|
|
b @return
|
|
|
|
@fail_notcgrp
|
|
li r8, kMPInvalidIDErr
|
|
|
|
@return
|
|
mtlr r30
|
|
blr
|
|
|
|
|
|
|
|
# # ###### ###### # #####
|
|
## ## # # # # ###### # ###### ##### ###### # # ##### ##### ##### ###### #### #### # # ##### ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # ##### # ##### # ##### # # # # # # # # ##### #### #### ##### # # # # # #####
|
|
# # # # # # # # # # ####### # # # # ##### # # # # ##### ###### # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### ###### ###### # ###### # # ##### ##### # # ###### #### #### ##### # # # #### ######
|
|
|
|
; ARG MPAddressSpaceID r3
|
|
; RET OSStatus r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 71, MPDeleteAddressSpace
|
|
|
|
MPDeleteAddressSpace
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
mr r31, r8
|
|
|
|
; Die if a Task is using this Space
|
|
lwz r16, AddressSpace.TaskCount(r31)
|
|
cmpwi r16, 0
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
; Die if the Space has a non-empty RsrvList
|
|
addi r16, r31, AddressSpace.RsrvList
|
|
lwz r17, AddressSpace.RsrvList + LLL.Next(r31)
|
|
cmpw r16, r17
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
; Die if the Space has a non-empty AreaList
|
|
addi r16, r31, AddressSpace.AreaList
|
|
lwz r17, AddressSpace.AreaList + LLL.Next(r31)
|
|
cmpw r16, r17
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r8, AddressSpace.ProcessID(r31)
|
|
bl LookupID
|
|
lwz r17, Process.AddressSpaceCount(r8)
|
|
subi r17, r17, 1
|
|
stw r17, Process.AddressSpaceCount(r8)
|
|
|
|
; Kill
|
|
lwz r8, AddressSpace.ID(r31)
|
|
bl DeleteID
|
|
mr r8, r31
|
|
bl PoolFree
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # #####
|
|
## ## # # # # # # ##### ##### ###### # # ##### # # ##### ##### ##### ###### #### #### # # ##### ## #### ######
|
|
# # # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # # # # # ##### # # # # # # # # # # # # ##### #### #### ##### # # # # # #####
|
|
# # # # # # ##### ##### # # # # # ####### # # # # ##### # # # # ##### ###### # #
|
|
# # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### #### # # # # ###### # # # # # ##### ##### # # ###### #### #### ##### # # # #### ######
|
|
|
|
; RET MPAddressSpaceID r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 117, MPCurrentAddressSpace
|
|
|
|
MPCurrentAddressSpace
|
|
|
|
mfsprg r16, 0
|
|
lwz r17, EWA.PA_CurAddressSpace(r16)
|
|
lwz r3, AddressSpace.ID(r17)
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### # # # #####
|
|
## ## # # # # #### # # ###### # # ##### ##### ##### ###### #### #### # # ##### ## #### ######
|
|
# # # # # # # # # # ## ## # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ####### # # # ## # ##### # # # # # # # # ##### #### #### ##### # # # # # #####
|
|
# # # # # # # # # # ####### # # # # ##### # # # # ##### ###### # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # # # #### # # ###### # # ##### ##### # # ###### #### #### ##### # # # #### ######
|
|
|
|
; RET MPAddressSpaceID r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 118, MPHomeAddressSpace
|
|
|
|
MPHomeAddressSpace
|
|
|
|
mfsprg r16, 0
|
|
lwz r17, EWA.PA_CurTask(r16)
|
|
lwz r18, Task.OwningProcessPtr(r17)
|
|
lwz r19, Process.SystemAddressSpacePtr(r18)
|
|
lwz r3, AddressSpace.ID(r19)
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### ##### ####### # #####
|
|
## ## # # # # ###### ##### # ## #### # # # # ##### ##### ##### ###### #### #### # # ##### ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # # # # #### #### # # # # # # # # ##### #### #### ##### # # # # # #####
|
|
# # # # # # # ###### # # # ####### # # # # ##### # # # # ##### ###### # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### # # # # ##### ##### # # ###### #### #### ##### # # # #### ######
|
|
|
|
; ARG MPTaskID r3, MPAddressSpaceID r4
|
|
; RET OSStatus r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 119, MPSetTaskAddressSpace
|
|
|
|
MPSetTaskAddressSpace
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
|
|
; Get Task and do some checks
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
mr r31, r8
|
|
cmpwi r9, Task.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
lwz r16, Task.Flags(r31)
|
|
mtcr r16
|
|
|
|
li r3, kMPTaskAbortedErr
|
|
bc BO_IF, Task.kFlagAborted, ReleaseAndReturnMPCall
|
|
|
|
bc BO_IF_NOT, Task.kFlagStopped, ReleaseAndReturnMPCallOOM
|
|
|
|
lbz r16, Task.State(r31)
|
|
cmpwi r16, 0
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
; Get Address Space and do some checks
|
|
|
|
mr r8, r4
|
|
bl LookupID
|
|
mr r30, r8
|
|
|
|
lwz r16, Task.ProcessID(r31)
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
lwz r17, AddressSpace.ProcessID(r30)
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
; The Task and Address Space must already share a process ID
|
|
cmpw r16, r17
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r17, Task.AddressSpacePtr(r31)
|
|
|
|
; Decrement old Address Space
|
|
lwz r16, AddressSpace.TaskCount(r17)
|
|
subi r16, r16, 1
|
|
stw r16, AddressSpace.TaskCount(r17)
|
|
|
|
; Increment old Address Space
|
|
lwz r16, AddressSpace.TaskCount(r30)
|
|
addi r16, r16, 1
|
|
stw r16, AddressSpace.TaskCount(r30)
|
|
|
|
stw r30, Task.AddressSpacePtr(r31)
|
|
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### #
|
|
## ## # # # # ##### ###### ## ##### ###### # # ##### ###### ##
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # ##### # # # ##### # # # # ##### # #
|
|
# # # # ##### # ###### # # ####### ##### # ######
|
|
# # # # # # # # # # # # # # # # # # #
|
|
# # # ##### # # ###### # # # ###### # # # # ###### # #
|
|
|
|
; This MP call does some of the heavy lifting for the MPLibrary function
|
|
; of the same name. No pages are mapped into the Area.
|
|
|
|
; ARG AddressSpaceID r3 (optional)
|
|
; long r4 PTEConfig
|
|
; long r5 length
|
|
; long r6 LogicalSeparation
|
|
; long r7 flagsAndMinAlign
|
|
; char *r8 LogicalBase
|
|
; RET r3 OSErr
|
|
; char *r8 LogicalBase
|
|
; AreaID r9
|
|
|
|
; Hint: in the 9.2.2 System MPLibrary, MPCreateArea calls a syscall
|
|
; wrapper function at code offset 0x7fa8, with arguments pointing to save
|
|
; locations for r8 and r9.
|
|
|
|
DeclareMPCall 72, MPCreateArea
|
|
|
|
MPCreateArea
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
; If !r3 then use the current address space
|
|
mr. r8, r3
|
|
mfsprg r28, 0
|
|
lwz r30, EWA.PA_CurAddressSpace(r28)
|
|
beq @use_current_space
|
|
|
|
; ... else use the one specified.
|
|
bl LookupID
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
mr r30, r8
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
@use_current_space
|
|
|
|
; Allocate the new Area
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq ReleaseAndScrambleMPCall
|
|
|
|
; Populate
|
|
stw r30, Area.AddressSpacePtr(r31)
|
|
|
|
stw r4, Area.PTEConfig(r31)
|
|
|
|
stw r5, Area.Length(r31)
|
|
|
|
lwz r8, ContextBlock.r6(r6)
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
|
|
lwz r8, ContextBlock.r7(r6)
|
|
stw r8, Area.FlagsAndMinAlign(r31)
|
|
|
|
lwz r8, ContextBlock.r8(r6)
|
|
stw r8, Area.LogicalBase(r31)
|
|
|
|
; "Create" the area
|
|
mr r8, r31
|
|
bl CreateArea
|
|
|
|
_AssertAndRelease PSA.SchLock, scratch=r16
|
|
|
|
mr. r3, r9
|
|
bne @error
|
|
|
|
; CreateArea returned successfully
|
|
lwz r8, Area.LogicalBase(r31)
|
|
stw r8, ContextBlock.r8(r6)
|
|
|
|
lwz r8, Area.ID(r31)
|
|
stw r8, ContextBlock.r9(r6)
|
|
|
|
b CommonMPCallReturnPath
|
|
|
|
@error
|
|
bl PoolFree
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
##### #
|
|
# # ##### ###### ## ##### ###### # # ##### ###### ##
|
|
# # # # # # # # # # # # # # #
|
|
# # # ##### # # # ##### # # # # ##### # #
|
|
# ##### # ###### # # ####### ##### # ######
|
|
# # # # # # # # # # # # # # # #
|
|
##### # # ###### # # # ###### # # # # ###### # #
|
|
|
|
; This function actually gets passed its own structure.
|
|
; What the frick?
|
|
|
|
; Always returns via ReturnFromCreateArea
|
|
|
|
; ARG Area *r8
|
|
; RET ID r8, osErr r9
|
|
|
|
CreateArea ; OUTSIDE REFERER
|
|
|
|
; Always returns via ReturnFromCreateArea
|
|
mflr r16
|
|
mfsprg r9, 0
|
|
stw r16, EWA.CreateAreaSavedLR(r9)
|
|
stmw r25, EWA.CreateAreaSavedR25(r9)
|
|
|
|
; Keep the structure itself in r31 for the duration.
|
|
; r8 must be used for other things
|
|
mr r31, r8
|
|
|
|
; For if we need to return early
|
|
li r9, paramErr
|
|
|
|
|
|
lwz r16, Area.Flags(r31)
|
|
lwz r17, 0x0020(r31)
|
|
rlwinm. r16, r16, 0, 28, 28
|
|
|
|
lisori r16, 0xfffc13e0 ; if bit 28 = 0
|
|
beq @use_other
|
|
lisori r16, 0xfff99be0 ; if bit 28 = 1
|
|
@use_other
|
|
|
|
and. r16, r16, r17
|
|
bne ReturnFromCreateArea
|
|
|
|
andi. r16, r17, 0x1f
|
|
cmpwi cr1, r16, 0x0c
|
|
beq CreateArea_0x50
|
|
blt cr1, ReturnFromCreateArea
|
|
|
|
CreateArea_0x50
|
|
bne CreateArea_0x5c
|
|
ori r17, r17, 0x0c
|
|
stw r17, 0x0020(r31)
|
|
|
|
CreateArea_0x5c
|
|
andi. r16, r17, 0x1f
|
|
li r18, -0x01
|
|
slw r18, r18, r16
|
|
stw r18, 0x0078(r31)
|
|
rlwinm. r16, r17, 27, 27, 31
|
|
bne ReturnFromCreateArea
|
|
addi r16, r16, 0x0c
|
|
li r18, -0x01
|
|
slw r18, r18, r16
|
|
stw r18, 0x007c(r31)
|
|
neg r16, r18
|
|
not r19, r18
|
|
stw r16, 0x0068(r31)
|
|
lwz r16, Area.Length(r31)
|
|
add r16, r16, r19
|
|
and. r16, r16, r18
|
|
stw r16, Area.Length(r31)
|
|
beq ReturnFromCreateArea
|
|
lwz r18, 0x001c(r31)
|
|
lis r16, -0x01
|
|
ori r16, r16, 0xff10
|
|
and. r16, r16, r18
|
|
bne ReturnFromCreateArea
|
|
lwz r16, 0x0070(r31)
|
|
li r17, 0x200
|
|
rlwimi r17, r16, 0, 0, 19
|
|
bl major_0x10cb8 ; PTE r16/r17, control r18 // PTE r16/r17
|
|
stw r16, 0x0070(r31)
|
|
stw r17, 0x0074(r31)
|
|
mr r8, r31
|
|
|
|
li r9, Area.kIDClass
|
|
bl MakeID
|
|
cmpwi r8, 0
|
|
beq major_0x10320
|
|
|
|
stw r8, Area.ID(r31)
|
|
mfsprg r16, 0
|
|
lwz r17, -0x0008(r16)
|
|
lwz r18, 0x0060(r17)
|
|
lwz r30, Area.AddressSpacePtr(r17)
|
|
stw r18, Area.ProcessID(r31)
|
|
lwz r16, Area.AddressSpacePtr(r31)
|
|
lwz r17, 0x0000(r16)
|
|
stw r17, Area.AddressSpaceID(r31)
|
|
lwz r16, 0x0008(r30)
|
|
rlwinm. r16, r16, 0, 30, 30
|
|
bne major_0x10320_0x64
|
|
lis r16, 0x4152
|
|
ori r16, r16, 0x4541
|
|
stw r16, Area.Signature(r31)
|
|
lwz r17, 0x0020(r31)
|
|
lwz r16, Area.LogicalSeparation(r31)
|
|
addi r16, r16, 0xfff
|
|
rlwinm r16, r16, 0, 0, 19
|
|
stw r16, Area.LogicalSeparation(r31)
|
|
rlwinm r16, r17, 0, 17, 18
|
|
cmplwi cr7, r16, 0x6000
|
|
rlwinm. r16, r17, 0, 17, 17
|
|
beq cr7, CreateArea_0x150
|
|
bne CreateArea_0x150
|
|
crset cr7_gt
|
|
crclr cr7_lt
|
|
|
|
CreateArea_0x150
|
|
rlwinm. r16, r17, 0, 17, 18
|
|
lwz r18, Area.LogicalBase(r31)
|
|
lwz r19, Area.Length(r31)
|
|
blt cr7, CreateArea_0x16c
|
|
bne CreateArea_0x170
|
|
li r18, 0x00
|
|
b CreateArea_0x170
|
|
|
|
CreateArea_0x16c
|
|
subf r18, r19, r18
|
|
|
|
CreateArea_0x170
|
|
lwz r16, 0x0078(r31)
|
|
and r18, r18, r16
|
|
stw r18, Area.LogicalBase(r31)
|
|
add r16, r18, r19
|
|
addi r16, r16, -0x01
|
|
stw r16, Area.LogicalEnd(r31)
|
|
|
|
|
|
; Major hint here...
|
|
|
|
_log ' CreateArea [ '
|
|
mr r8, r18
|
|
bl Printw
|
|
mr r8, r16
|
|
bl Printw
|
|
_log '] ID '
|
|
|
|
|
|
lwz r8, Area.ID(r31)
|
|
mr r8, r8
|
|
bl Printw
|
|
|
|
|
|
bgt cr7, CreateArea_0x1f4
|
|
blt cr7, CreateArea_0x218
|
|
_log 'placed'
|
|
b CreateArea_0x234
|
|
|
|
CreateArea_0x1f4
|
|
_log 'placed at or above'
|
|
b CreateArea_0x234
|
|
|
|
CreateArea_0x218
|
|
_log 'placed below'
|
|
|
|
CreateArea_0x234
|
|
lwz r8, Area.AddressSpacePtr(r31)
|
|
lwz r16, Area.LogicalEnd(r31)
|
|
lwz r9, Area.LogicalBase(r31)
|
|
cmplw r9, r16
|
|
bge major_0x10320_0x64
|
|
bl FindAreaAbove
|
|
mr r30, r8
|
|
lwz r14, Area.LogicalBase(r31)
|
|
lwz r15, Area.LogicalEnd(r31)
|
|
lwz r16, Area.LogicalSeparation(r31)
|
|
lwz r17, 0x0024(r30)
|
|
lwz r18, 0x0028(r30)
|
|
lwz r19, 0x0030(r30)
|
|
lwz r21, Area.AddressSpacePtr(r31)
|
|
cmpwi r17, -0x01
|
|
add r8, r15, r16
|
|
add r9, r15, r19
|
|
beq CreateArea_0x2b8
|
|
cmplw r8, r17
|
|
cmplw cr1, r9, r17
|
|
bge CreateArea_0x28c
|
|
blt cr1, CreateArea_0x2b8
|
|
|
|
CreateArea_0x28c
|
|
beq cr7, major_0x10320_0x64
|
|
_log ' ... bc search^n'
|
|
bgt cr7, CreateArea_0x34c
|
|
b CreateArea_0x31c
|
|
|
|
CreateArea_0x2b8
|
|
addi r21, r21, 0x20
|
|
lwz r20, 0x0060(r30)
|
|
cmpw r20, r21
|
|
beq CreateArea_0x39c
|
|
addi r20, r20, -0x54
|
|
lwz r17, 0x0024(r20)
|
|
lwz r18, 0x0028(r20)
|
|
lwz r19, 0x0030(r20)
|
|
add r8, r18, r16
|
|
add r9, r18, r19
|
|
cmplw r8, r14
|
|
cmplw cr1, r9, r14
|
|
bge CreateArea_0x2f0
|
|
blt cr1, CreateArea_0x374
|
|
|
|
CreateArea_0x2f0
|
|
beq cr7, major_0x10320_0x64
|
|
_log ' ... ab search^n'
|
|
bgt cr7, CreateArea_0x34c
|
|
b CreateArea_0x31c
|
|
|
|
CreateArea_0x31c
|
|
subf r8, r19, r17
|
|
subf r9, r16, r17
|
|
cmplw r8, r9
|
|
lwz r21, Area.Length(r31)
|
|
ble CreateArea_0x334
|
|
mr r8, r9
|
|
|
|
CreateArea_0x334
|
|
subf r8, r21, r8
|
|
cmplw r8, r14
|
|
addi r18, r8, 0x01
|
|
lwz r19, Area.Length(r31)
|
|
bge major_0x10320_0x64
|
|
b CreateArea_0x170
|
|
|
|
CreateArea_0x34c
|
|
add r8, r18, r19
|
|
add r9, r18, r16
|
|
lwz r20, 0x0078(r31)
|
|
cmplw r8, r9
|
|
neg r21, r20
|
|
bge CreateArea_0x368
|
|
mr r8, r9
|
|
|
|
CreateArea_0x368
|
|
add r18, r8, r21
|
|
lwz r19, Area.Length(r31)
|
|
b CreateArea_0x170
|
|
|
|
CreateArea_0x374
|
|
addi r19, r31, 0x54
|
|
addi r20, r20, 0x54
|
|
lwz r16, 0x0000(r20)
|
|
stw r16, 0x0000(r19)
|
|
lwz r16, 0x0008(r20)
|
|
stw r16, 0x0008(r19)
|
|
stw r20, 0x000c(r19)
|
|
stw r19, 0x000c(r16)
|
|
stw r19, 0x0008(r20)
|
|
b CreateArea_0x3b8
|
|
|
|
CreateArea_0x39c
|
|
addi r19, r31, 0x54
|
|
stw r20, 0x0000(r19)
|
|
InsertAsNext r19, r20, scratch=r16
|
|
|
|
CreateArea_0x3b8
|
|
addi r16, r31, 0x90
|
|
InitList r16, 'fenc', scratch=r17
|
|
lwz r16, 0x0020(r31)
|
|
lwz r17, Area.Flags(r31)
|
|
rlwinm. r8, r16, 0, 16, 16
|
|
bne CreateArea_0x64c
|
|
rlwinm. r8, r17, 0, 25, 25
|
|
bne CreateArea_0x41c
|
|
lwz r8, Area.Length(r31)
|
|
rlwinm r8, r8, 22, 10, 29
|
|
mr r29, r8
|
|
|
|
; r1 = kdp
|
|
; r8 = size
|
|
bl PoolAllocClear
|
|
; r8 = ptr
|
|
|
|
cmpwi r8, 0x00
|
|
stw r8, 0x0040(r31)
|
|
beq CreateArea_0x460
|
|
lwz r9, Area.Length(r31)
|
|
srwi r9, r9, 12
|
|
bl major_0x10284
|
|
lwz r17, Area.Flags(r31)
|
|
ori r17, r17, 0x10
|
|
stw r17, Area.Flags(r31)
|
|
|
|
CreateArea_0x41c
|
|
lwz r17, Area.Flags(r31)
|
|
andi. r8, r17, 0x88
|
|
lwz r8, Area.Length(r31)
|
|
bne CreateArea_0x45c
|
|
rlwinm r8, r8, 21, 11, 30
|
|
mr r29, r8
|
|
|
|
; r1 = kdp
|
|
; r8 = size
|
|
bl PoolAllocClear
|
|
; r8 = ptr
|
|
|
|
cmpwi r8, 0x00
|
|
stw r8, 0x003c(r31)
|
|
beq CreateArea_0x460
|
|
lwz r9, Area.Length(r31)
|
|
srwi r9, r9, 12
|
|
bl major_0x102a8
|
|
lwz r16, Area.Flags(r31)
|
|
ori r16, r16, 0x01
|
|
stw r16, Area.Flags(r31)
|
|
|
|
CreateArea_0x45c
|
|
b CreateArea_0x64c
|
|
|
|
CreateArea_0x460
|
|
cmpwi r29, 0xfd8
|
|
ble major_0x10320_0x20
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r17, Area.Flags(r31)
|
|
li r27, 0x00
|
|
rlwinm. r8, r17, 0, 25, 25
|
|
bne CreateArea_0x4b4
|
|
lwz r27, Area.Length(r31)
|
|
srwi r27, r27, 12
|
|
cmpwi r27, 0x400
|
|
ble CreateArea_0x4ac
|
|
ori r17, r17, 0x20
|
|
stw r17, Area.Flags(r31)
|
|
addi r27, r27, 0x400
|
|
|
|
CreateArea_0x4ac
|
|
addi r27, r27, 0x3ff
|
|
srwi r27, r27, 10
|
|
|
|
CreateArea_0x4b4
|
|
lwz r8, Area.Flags(r31)
|
|
li r29, 0x00
|
|
rlwinm. r9, r8, 0, 28, 28
|
|
bne CreateArea_0x4e8
|
|
lwz r29, Area.Length(r31)
|
|
srwi r29, r29, 12
|
|
cmpwi r29, 0x800
|
|
ble CreateArea_0x4e0
|
|
ori r8, r8, 0x02
|
|
stw r8, Area.Flags(r31)
|
|
addi r29, r29, 0x800
|
|
|
|
CreateArea_0x4e0
|
|
addi r29, r29, 0x7ff
|
|
srwi r29, r29, 11
|
|
|
|
CreateArea_0x4e8
|
|
lwz r18, PSA.FreePageCount(r1)
|
|
add. r8, r27, r29
|
|
ble major_0x102c8
|
|
cmpw r8, r18
|
|
bgt major_0x102c8
|
|
lwz r16, PSA.FreePageCount(r1)
|
|
lwz r17, PSA.UnheldFreePageCount(r1)
|
|
subf r16, r8, r16
|
|
subf r17, r8, r17
|
|
stw r16, PSA.FreePageCount(r1)
|
|
stw r17, PSA.UnheldFreePageCount(r1)
|
|
mr. r18, r27
|
|
beq CreateArea_0x5a0
|
|
lwz r16, PSA.FreeList + LLL.Next(r1)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r19
|
|
addi r18, r18, -0x01
|
|
stw r16, 0x0040(r31)
|
|
cmpwi r18, 0x00
|
|
lwz r17, PSA.FreeList + LLL.Next(r1)
|
|
mr r8, r16
|
|
subi r16, r16, 4
|
|
bgt CreateArea_0x564
|
|
li r9, 0x400
|
|
bl major_0x10284
|
|
b CreateArea_0x5a0
|
|
|
|
CreateArea_0x564
|
|
RemoveFromList r17, scratch1=r19, scratch2=r20
|
|
addi r18, r18, -0x01
|
|
stwu r17, 0x0004(r16)
|
|
mr r8, r17
|
|
li r9, 0x400
|
|
bl major_0x10284
|
|
lwz r17, PSA.FreeList + LLL.Next(r1)
|
|
cmpwi r18, 0x00
|
|
bgt CreateArea_0x564
|
|
|
|
CreateArea_0x5a0
|
|
mr. r18, r29
|
|
beq CreateArea_0x62c
|
|
lwz r16, PSA.FreeList + LLL.Next(r1)
|
|
RemoveFromList r16, scratch1=r17, scratch2=r19
|
|
addi r18, r18, -0x01
|
|
stw r16, 0x003c(r31)
|
|
cmpwi r18, 0x00
|
|
lwz r17, PSA.FreeList + LLL.Next(r1)
|
|
mr r8, r16
|
|
subi r16, r16, 4
|
|
bgt CreateArea_0x5f0
|
|
li r9, 0x800
|
|
bl major_0x102a8
|
|
b CreateArea_0x62c
|
|
|
|
CreateArea_0x5f0
|
|
RemoveFromList r17, scratch1=r19, scratch2=r20
|
|
addi r18, r18, -0x01
|
|
stwu r17, 0x0004(r16)
|
|
mr r8, r17
|
|
li r9, 0x800
|
|
bl major_0x102a8
|
|
lwz r17, PSA.FreeList + LLL.Next(r1)
|
|
cmpwi r18, 0x00
|
|
bgt CreateArea_0x5f0
|
|
|
|
CreateArea_0x62c
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
CreateArea_0x64c
|
|
lwz r16, Area.Flags(r31)
|
|
rlwinm. r8, r16, 0, 28, 28
|
|
beq CreateArea_0x67c
|
|
lwz r16, 0x0044(r31)
|
|
addi r17, r31, 0x44
|
|
stw r16, 0x0000(r17)
|
|
InsertAsPrev r17, r16, scratch=r18
|
|
b major_0x10320_0x94
|
|
|
|
CreateArea_0x67c
|
|
addi r16, r31, 0x44
|
|
InitList r16, 'AKA ', scratch=r17
|
|
b major_0x10320_0x94
|
|
|
|
|
|
|
|
major_0x10284 ; OUTSIDE REFERER
|
|
subi r8, r8, 4
|
|
addi r9, r9, -0x01
|
|
lwz r20, 0x0074(r31)
|
|
ori r20, r20, 0x200
|
|
|
|
major_0x10284_0x10
|
|
cmpwi r9, noErr
|
|
stwu r20, 0x0004(r8)
|
|
addi r9, r9, -0x01
|
|
bgt major_0x10284_0x10
|
|
blr
|
|
|
|
|
|
|
|
major_0x102a8 ; OUTSIDE REFERER
|
|
addi r8, r8, -0x02
|
|
addi r9, r9, -0x01
|
|
li r20, 0x7fff
|
|
|
|
major_0x102a8_0xc
|
|
cmpwi r9, noErr
|
|
sthu r20, 0x0002(r8)
|
|
addi r9, r9, -0x01
|
|
bgt major_0x102a8_0xc
|
|
blr
|
|
|
|
|
|
|
|
major_0x102c8 ; OUTSIDE REFERER
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
addi r30, r8, 0x08
|
|
lwz r8, PSA.AgerID(r1)
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
|
|
mr r26, r8
|
|
bne major_0x10320_0x20
|
|
li r8, 0x02
|
|
stw r8, 0x0010(r26)
|
|
stw r30, 0x0014(r26)
|
|
li r29, 0x00
|
|
stw r29, 0x0018(r26)
|
|
mr r30, r26
|
|
bl CauseNotification
|
|
b major_0x10320_0x20
|
|
|
|
|
|
|
|
major_0x10320 ; OUTSIDE REFERER
|
|
mr r8, r31
|
|
li r9, -29294
|
|
b ReturnFromCreateArea
|
|
|
|
; Dead code:
|
|
lwz r8, Area.ID(r31)
|
|
bl DeleteID
|
|
mr r8, r31
|
|
li r9, kMPInvalidIDErr
|
|
b ReturnFromCreateArea
|
|
|
|
major_0x10320_0x20 ; OUTSIDE REFERER
|
|
addi r19, r31, 0x54
|
|
RemoveFromList r19, scratch1=r16, scratch2=r17
|
|
lwz r16, Area.Flags(r31)
|
|
lwz r8, 0x0040(r31)
|
|
rlwinm. r16, r16, 0, 25, 25
|
|
bne major_0x10320_0x58
|
|
cmpwi r8, 0x00
|
|
bnel PoolFree
|
|
|
|
major_0x10320_0x58
|
|
lwz r8, 0x003c(r31)
|
|
cmpwi r8, 0x00
|
|
bnel PoolFree
|
|
|
|
major_0x10320_0x64 ; OUTSIDE REFERER
|
|
_log ' ... skipped^n'
|
|
lwz r8, Area.ID(r31)
|
|
bl DeleteID
|
|
mr r8, r31
|
|
li r9, kMPInsufficientResourcesErr
|
|
b ReturnFromCreateArea
|
|
|
|
major_0x10320_0x94 ; OUTSIDE REFERER
|
|
_log ' ... created^n'
|
|
mr r8, r31
|
|
li r9, 0x00
|
|
|
|
|
|
|
|
ReturnFromCreateArea
|
|
mfsprg r16, 0
|
|
lwz r17, EWA.CreateAreaSavedLR(r16)
|
|
mtlr r17
|
|
lmw r25, EWA.CreateAreaSavedR25(r16)
|
|
blr
|
|
|
|
|
|
|
|
; ARG AddressSpace *r8,
|
|
; RET Area *r8
|
|
|
|
FindAreaAbove ; OUTSIDE REFERER
|
|
lwz r8, AddressSpace.AreaList + LLL.Next(r8)
|
|
|
|
@loop
|
|
subi r8, r8, Area.LLL
|
|
|
|
; Return an area such that:
|
|
; max(Area.LogicalBase, Area.LogicalEnd) >= r9
|
|
lwz r16, Area.LogicalBase(r8)
|
|
lwz r17, Area.LogicalEnd(r8)
|
|
cmplw r16, r9
|
|
cmplw cr1, r17, r9
|
|
bgelr
|
|
bgelr cr1
|
|
|
|
; Iterate over linked list
|
|
lwz r8, Area.LLL + LLL.Next(r8)
|
|
b @loop
|
|
|
|
|
|
|
|
# # ###### ##### # #
|
|
## ## # # # # ##### ###### ## ##### ###### # # # # ## #### # # ##### ###### ##
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # ##### # # # ##### # # # # # # #### # # # # ##### # #
|
|
# # # # ##### # ###### # # ####### # # ###### # ####### ##### # ######
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### # # ###### # # # ###### # # ###### # # # #### # # # # ###### # #
|
|
|
|
; This MP call does most of the work for the same-named MPLibrary
|
|
; function. An "alias" Area is created from a template. This code is very
|
|
; similar to regular MPCreateArea above, so differences are commented.
|
|
|
|
; ARG AreaID r3 ; Alias-specific
|
|
; long r4 PTEConfig
|
|
; long r5 length
|
|
; long r6 LogicalSeparation
|
|
; long r7 flagsAndMinAlign
|
|
; char *r8 LogicalBase
|
|
; long r9 unknown ; Alias-specific
|
|
; RET r3 OSErr
|
|
; char *r8 LogicalBase
|
|
; AreaID r10 ; Alias-specific
|
|
|
|
DeclareMPCall 73, MPCreateAliasArea
|
|
|
|
MPCreateAliasArea
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
; Confirm that the template Area is not itself an alias
|
|
mr r30, r8
|
|
lwz r16, Area.Flags(r30)
|
|
rlwinm. r8, r16, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
; Allocate the new Area
|
|
li r8, Area.Size
|
|
bl PoolAllocClear
|
|
mr. r31, r8
|
|
beq ReleaseAndScrambleMPCall
|
|
|
|
; Populate
|
|
mfsprg r28, 0
|
|
lwz r8, EWA.PA_CurAddressSpace(r28)
|
|
stw r8, Area.AddressSpacePtr(r31)
|
|
|
|
stw r3, Area.ParentAreaID(r31) ; Alias-specific
|
|
|
|
stw r30, Area.AliasLLL + LLL.Freeform(r31) ; Alias-specific
|
|
|
|
stw r4, Area.PTEConfig(r31)
|
|
|
|
stw r5, Area.Length(r31)
|
|
|
|
lwz r8, ContextBlock.r6(r6)
|
|
stw r8, Area.LogicalSeparation(r31)
|
|
|
|
lwz r8, ContextBlock.r7(r6)
|
|
stw r8, Area.FlagsAndMinAlign(r31)
|
|
|
|
lwz r8, ContextBlock.r8(r6)
|
|
stw r8, Area.LogicalBase(r31)
|
|
|
|
lwz r8, ContextBlock.r9(r6) ; Alias-specific
|
|
stw r8, 0x0080(r31)
|
|
|
|
li r8, 1 << (31 - Area.kAliasFlag) ; Alias-specific
|
|
stw r8, Area.Flags(r31)
|
|
|
|
; "Create" the area (everything after here is identical to MPCreateArea)
|
|
mr r8, r31
|
|
bl CreateArea
|
|
|
|
_AssertAndRelease PSA.SchLock, scratch=r16
|
|
|
|
mr. r3, r9
|
|
bne @error
|
|
|
|
; CreateArea returned successfully
|
|
lwz r8, Area.LogicalBase(r31)
|
|
stw r8, ContextBlock.r8(r6)
|
|
|
|
lwz r8, Area.ID(r31)
|
|
stw r8, ContextBlock.r10(r6) ; Alias-specific
|
|
|
|
b CommonMPCallReturnPath
|
|
|
|
; ...or not
|
|
@error
|
|
bl PoolFree
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### ###### #
|
|
## ## # # # # ###### # ###### ##### ###### # # ##### ###### ##
|
|
# # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # ##### # ##### # ##### # # # # ##### # #
|
|
# # # # # # # # # # ####### ##### # ######
|
|
# # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### ###### ###### # ###### # # # # ###### # #
|
|
|
|
; Delete an Area: the eponymous MPLibrary function is a simple wrapper
|
|
|
|
; 1. Only works on unprivileged Areas with no mapped pages.
|
|
; 2. Remove from parent address space.
|
|
; 3. Remove from template Area's alias list if applicable.
|
|
; 4. Delete the "PageMap" array if present.
|
|
; 5. Delete the "Fault Counter" array if present.
|
|
; 6. Delete the structure from the pool.
|
|
|
|
; ARG AreaID r3
|
|
; RET OSErr r3
|
|
|
|
DeclareMPCall 74, MPDeleteArea
|
|
|
|
MPDeleteArea
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
; Look up and validate
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
; If pages are still mapped in, fail with OOM
|
|
; If area is privileged, fail with privileged
|
|
lwz r17, Area.BytesMapped(r31)
|
|
lwz r29, Area.Flags(r31)
|
|
cmpwi cr1, r17, 0
|
|
rlwinm. r8, r29, 0, Area.kPrivilegedFlag, Area.kPrivilegedFlag
|
|
bne cr1, ReleaseAndReturnMPCallOOM
|
|
bne ReleaseAndReturnMPCallPrivilegedErr
|
|
|
|
; If is alias area and is not at back of queue (???), fail with OOM
|
|
rlwinm. r8, r29, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
lwz r16, Area.AliasLLL + LLL.Next(r31)
|
|
bne @dont_check_for_nonempty_alias
|
|
addi r17, r31, Area.AliasLLL
|
|
cmpw r16, r17
|
|
bne ReleaseAndReturnMPCallOOM
|
|
@dont_check_for_nonempty_alias
|
|
|
|
; HTAB lock wraps around all Address Space structures?
|
|
|
|
_Lock PSA.HTABLock, scratch1=r18, scratch2=r9
|
|
|
|
; Remove from parent address space
|
|
addi r16, r31, Area.LLL
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
|
|
; Remove from template area's list of aliases, if necessary
|
|
rlwinm. r8, r29, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
addi r16, r31, Area.AliasLLL
|
|
beq @not_alias_so_dont_remove_from_alias_list
|
|
RemoveFromList r16, scratch1=r17, scratch2=r18
|
|
@not_alias_so_dont_remove_from_alias_list
|
|
|
|
_AssertAndRelease PSA.HTABLock, scratch=r18
|
|
|
|
|
|
; DELETE PAGEMAP (array of [array of] per-page data)
|
|
; There are a few cases here...
|
|
|
|
lwz r8, Area.PageMapArrayPtr(r31)
|
|
rlwinm. r16, r29, 0, Area.kDontOwnPageMapArray, Area.kDontOwnPageMapArray
|
|
cmpwi cr1, r8, 0
|
|
bne @no_pagemap
|
|
rlwinm. r16, r29, 0, Area.kPageMapArrayInPool, Area.kPageMapArrayInPool
|
|
beq cr1, @no_pagemap
|
|
bne @pagemap_in_pool
|
|
|
|
|
|
; If PageMap occupies whole pages then return those pages
|
|
; directly to the free list without bothering the pool
|
|
|
|
; (Pool lock still protects free list)
|
|
_Lock PSA.PoolLock, scratch1=r18, scratch2=r9
|
|
|
|
rlwinm. r16, r29, 0, Area.kPageMapArrayIs2D, Area.kPageMapArrayIs2D
|
|
beq @pagemap_is_1d
|
|
|
|
|
|
; CASE: 2D array, all in whole pages
|
|
|
|
; r19 := size of ptr array in primary page
|
|
lwz r19, Area.Length(r31)
|
|
mr r20, r8
|
|
srwi r19, r19, 12
|
|
addi r19, r19, 0x3ff
|
|
srwi r19, r19, 10
|
|
slwi r19, r19, 2
|
|
|
|
; Free every second-level page
|
|
subi r19, r19, 4
|
|
@2d_pagemap_delete_loop
|
|
lwzx r8, r19, r20
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
cmpwi r19, 0
|
|
subi r19, r19, 4
|
|
bgt @2d_pagemap_delete_loop
|
|
|
|
mr r8, r20
|
|
|
|
|
|
; COMMON CASE: single first-level page of 2D or 1D-in-whole-page case
|
|
|
|
@pagemap_is_1d
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
|
|
_AssertAndRelease PSA.PoolLock, scratch=r18
|
|
|
|
b @pagemap_deleted
|
|
|
|
|
|
; CASE: 1D array in pool block (not whole page)
|
|
|
|
@pagemap_in_pool
|
|
bl PoolFree
|
|
|
|
|
|
@pagemap_deleted
|
|
@no_pagemap
|
|
|
|
|
|
; DELETE FAULT COUNTER ARRAY
|
|
; Again, the code to manage the cases is tricky.
|
|
|
|
lwz r8, Area.FaultCtrArrayPtr(r31)
|
|
rlwinm. r16, r29, 0, Area.kFaultCtrArrayInPool, Area.kFaultCtrArrayInPool
|
|
cmpwi cr1, r8, 0
|
|
beq cr1, @no_faultctr
|
|
bne @faultctr_in_pool
|
|
|
|
|
|
; Whole-page cases require us to get the Pool lock manually (for free list)
|
|
_Lock PSA.PoolLock, scratch1=r18, scratch2=r9
|
|
|
|
rlwinm. r16, r29, 0, Area.kFaultCtrArrayIs2D, Area.kFaultCtrArrayIs2D
|
|
beq @faultctr_is_1d
|
|
|
|
|
|
; CASE: 2D array, all in whole pages
|
|
|
|
; Once again, r19 = the size of the primary array
|
|
lwz r19, Area.Length(r31)
|
|
mr r20, r8
|
|
srwi r19, r19, 12
|
|
addi r19, r19, 0x7ff
|
|
srwi r19, r19, 11
|
|
slwi r19, r19, 2
|
|
|
|
; Free every second-level page
|
|
subi r19, r19, 4
|
|
@2d_faultctr_delete_loop
|
|
lwzx r8, r19, r20
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
cmpwi r19, 0
|
|
subi r19, r19, 4
|
|
bgt @2d_faultctr_delete_loop
|
|
|
|
mr r8, r20
|
|
|
|
|
|
; COMMON CASE: single first-level page of 2D or 1D-in-whole-page case
|
|
|
|
@faultctr_is_1d
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
|
|
_AssertAndRelease PSA.PoolLock, scratch=r18
|
|
|
|
b @faultctr_deleted
|
|
|
|
|
|
; CASE: 1D array in pool block (not whole page)
|
|
|
|
@faultctr_in_pool
|
|
bl PoolFree
|
|
|
|
|
|
@faultctr_deleted
|
|
@no_faultctr
|
|
|
|
|
|
; Delete the struct from the pool
|
|
lwz r8, Area.ID(r31)
|
|
bl DeleteID
|
|
mr r8, r31
|
|
bl PoolFree
|
|
|
|
|
|
; Return noErr
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # #####
|
|
## ## # # # # ###### ##### # # ##### ###### ## # # # ###### ######
|
|
# # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # # # # # ##### # # ##### # # #####
|
|
# # # # # # ####### ##### # ###### # # # #
|
|
# # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # ###### # # ##### # ###### ######
|
|
|
|
; ARG MPAreaID r3, flag_24_means_change_left_side r4
|
|
|
|
; Straight MPLibrary wrapper: no
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 75, MPSetAreaSize
|
|
|
|
MPSetAreaSize
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
mr r31, r8
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
; Chase Daniel about this field!
|
|
lwz r16, Area.FlagsAndMinAlign(r31)
|
|
rlwinm. r8, r16, 0, 16, 16
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r18, Area.DefaultAlignmentMask(r31)
|
|
lwz r17, Area.Length(r31)
|
|
and. r5, r5, r18
|
|
and r17, r17, r18
|
|
ble ReleaseAndReturnParamErrFromMPCall
|
|
|
|
|
|
; DECIDE: MAKE BIGGER OR MAKE SMALLER?
|
|
|
|
subf. r27, r17, r5 ; r27 = how much space to add
|
|
beq ReleaseAndReturnZeroFromMPCall ; area is already this size (ignoring change)
|
|
bgt @SHRINK_AREA ; not actually allowed
|
|
|
|
|
|
;EXPAND AREA
|
|
|
|
rlwinm. r8, r4, 0, 24, 24
|
|
lwz r28, Area.LogicalBase(r31)
|
|
lwz r29, Area.LogicalEnd(r31)
|
|
bne @expand_downwards
|
|
|
|
;expand upwards ; (replace LogicalBase with new LogicalEnd)
|
|
add r28, r27, r29
|
|
addi r28, r28, 1
|
|
b @endif
|
|
|
|
@expand_downwards ; (replace LogicalEnd with new LogicalBase)
|
|
subf r29, r27, r28
|
|
subi r29, r29, 1
|
|
@endif
|
|
|
|
|
|
_Lock PSA.PoolLock, scratch1=r14, scratch2=r15
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
|
|
; Free pages from LogicalBase to LogicalEnd, flushing PTEs that might conflict (a million iterations???)
|
|
|
|
lwz r27, Area.PageSize(r31)
|
|
|
|
@freelist_loop
|
|
mr r8, r28
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, @there_is_no_page_to_free
|
|
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
; Unset PLE bit kPLEFlagHasPhysPage and free the physical page
|
|
lwz r17, 0(r30)
|
|
_bclr r17, r17, Area.kPLEFlagHasPhysPage
|
|
rlwinm r8, r17, 0, 0xfffff000
|
|
stw r17, 0(r30)
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
|
|
@there_is_no_page_to_free
|
|
|
|
add r28, r28, r27
|
|
cmplw r28, r29
|
|
ble @freelist_loop
|
|
|
|
|
|
|
|
rlwinm. r8, r4, 0, 24, 24
|
|
lwz r28, Area.LogicalBase(r31)
|
|
beq @_138
|
|
|
|
lwz r27, 0x0068(r31)
|
|
add r29, r29, r27
|
|
|
|
@_100
|
|
mr r8, r28
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
mr r26, r30
|
|
mr r8, r29
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
lwz r17, 0x0000(r30)
|
|
stw r17, 0x0000(r26)
|
|
lwz r16, Area.LogicalEnd(r31)
|
|
add r28, r28, r27
|
|
add r29, r29, r27
|
|
cmplw r29, r16
|
|
ble @_100
|
|
|
|
@_138
|
|
|
|
_AssertAndRelease PSA.HTABLock, scratch=r8
|
|
|
|
|
|
lwz r16, Area.Flags(r31)
|
|
rlwinm. r8, r16, 0, 25, 25
|
|
bne @_16c
|
|
|
|
rlwinm. r8, r16, 0, 27, 27
|
|
bne @_16c
|
|
|
|
|
|
@_16c
|
|
_AssertAndRelease PSA.PoolLock, scratch=r8
|
|
b @_190
|
|
|
|
@_190
|
|
rlwinm. r8, r4, 0, 24, 24
|
|
lwz r16, Area.LogicalBase(r31)
|
|
bne @_1b0
|
|
add r17, r16, r5
|
|
addi r17, r17, -0x01
|
|
stw r5, Area.Length(r31)
|
|
stw r17, Area.LogicalEnd(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@_1b0
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
subf r16, r5, r17
|
|
stw r5, Area.Length(r31)
|
|
addi r16, r16, 0x01
|
|
stw r16, Area.LogicalBase(r31)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
@SHRINK_AREA
|
|
|
|
rlwinm. r8, r4, 0, 24, 24
|
|
lwz r28, Area.LogicalBase(r31)
|
|
lwz r29, Area.LogicalEnd(r31)
|
|
bne ReleaseAndMPCallWasBad
|
|
|
|
add r28, r27, r29
|
|
addi r28, r28, 0x01
|
|
|
|
b @_1ec
|
|
; Dead code:
|
|
subf r29, r27, r28
|
|
subi r29, r29, 1
|
|
@_1ec
|
|
|
|
b ReleaseAndMPCallWasBad
|
|
|
|
|
|
|
|
# # ###### ##### ##### ###### #
|
|
## ## # # # # ###### ##### # # # # ##### # # ## #### ###### # # #### #### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # ##### # # ##### ###### # # # ##### # # # # ##### #### ####
|
|
# # # # # # # # # # # # ###### # ### # ####### # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # ##### #### ##### # # # #### ###### # # #### #### ###### #### ####
|
|
|
|
; Straight MPLibrary wrapper: almost
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 130, MPSetSubPageAccess
|
|
|
|
MPSetSubPageAccess
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lis r16, -0x01
|
|
ori r16, r16, 0xfff8
|
|
lwz r17, 0x0020(r31)
|
|
and. r16, r16, r4
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
rlwinm. r8, r17, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
mr r29, r5
|
|
lwz r18, 0x0134(r6)
|
|
lwz r19, 0x0068(r31)
|
|
lwz r16, Area.LogicalBase(r31)
|
|
cmplw r18, r19
|
|
add r28, r18, r29
|
|
bge ReleaseAndReturnParamErrFromMPCall
|
|
lwz r17, 0x007c(r31)
|
|
addi r28, r28, -0x01
|
|
lwz r18, 0x0020(r31)
|
|
lwz r19, Area.LogicalEnd(r31)
|
|
cmplw cr1, r29, r16
|
|
cmplw cr2, r28, r19
|
|
blt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr2, ReleaseAndReturnParamErrFromMPCall
|
|
xor r8, r28, r29
|
|
rlwinm. r8, r8, 0, 0, 19
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r29
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
beq SpacePanicIsland
|
|
rlwinm r8, r16, 0, 29, 30
|
|
lwz r16, 0x0000(r30)
|
|
cmpwi cr7, r8, 0x04
|
|
beq cr7, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r16, 0x0098(r31)
|
|
|
|
MPCall_130_0xe8
|
|
addi r17, r31, 0x90
|
|
cmpw r16, r17
|
|
addi r17, r16, 0x14
|
|
beq MPCall_130_0x11c
|
|
lwz r8, 0x0010(r16)
|
|
cmplwi r8, 0x1f8
|
|
add r9, r8, r17
|
|
blt MPCall_130_0x110
|
|
lwz r16, 0x0008(r16)
|
|
b MPCall_130_0xe8
|
|
|
|
MPCall_130_0x110
|
|
addi r8, r8, 0x08
|
|
addi r9, r9, 0x08
|
|
b MPCall_130_0x15c
|
|
|
|
MPCall_130_0x11c
|
|
li r8, 0x214
|
|
|
|
; r1 = kdp
|
|
; r8 = size
|
|
bl PoolAllocClear
|
|
; r8 = ptr
|
|
|
|
mr. r16, r8
|
|
beq ReleaseAndScrambleMPCall
|
|
addi r18, r31, 0x90
|
|
lis r17, 0x4645
|
|
ori r17, r17, 0x4e43
|
|
stw r17, 0x0004(r16)
|
|
stw r18, 0x0000(r16)
|
|
InsertAsPrev r16, r18, scratch=r19
|
|
li r8, 0x00
|
|
addi r9, r16, 0x14
|
|
|
|
MPCall_130_0x15c
|
|
stw r8, 0x0010(r16)
|
|
stw r29, 0x0000(r9)
|
|
stw r28, 0x0004(r9)
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r29
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_130_0x19c
|
|
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
MPCall_130_0x19c
|
|
lwz r17, 0x0000(r30)
|
|
li r16, 0x06
|
|
rlwimi r17, r16, 0, 29, 30
|
|
stw r17, 0x0000(r30)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # #
|
|
## ## # # # # ###### ##### # # ##### ###### ## # # #### #### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # # # # # ##### # # # # # # ##### #### ####
|
|
# # # # # # ####### ##### # ###### ####### # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # ###### # # # # #### #### ###### #### ####
|
|
|
|
; ARG MPAreaID r3, bits_to_set r4, bits_to_unset r5, start r6, len r7
|
|
; RET OSStatus r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 76, MPSetAreaAccess
|
|
|
|
MPSetAreaAccess
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
; Fail if any bits other than these are set in r4
|
|
lisori r16, ~%11101111
|
|
and. r16, r16, r4
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
; Or in r5
|
|
lisori r16, ~%11101111
|
|
and. r16, r16, r5
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
; Get more args
|
|
lwz r29, ContextBlock.r6(r6)
|
|
lwz r18, ContextBlock.r7(r6)
|
|
|
|
; Figure out whether the Area covers the specified range
|
|
lwz r16, Area.LogicalBase(r31)
|
|
add r28, r18, r29
|
|
lwz r17, Area.DefaultAlignmentMask(r31) ; unused?
|
|
subi r28, r28, 1
|
|
lwz r18, Area.FlagsAndMinAlign(r31)
|
|
lwz r19, Area.LogicalEnd(r31)
|
|
|
|
; Check that range lies within Area (cr1/2).
|
|
; Also, two cases depending on FlagsAndMinAlign bit 16
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmplw cr1, r29, r16
|
|
cmplw cr2, r28, r19
|
|
blt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr2, ReleaseAndReturnParamErrFromMPCall
|
|
bne @BIT_16_SET
|
|
|
|
|
|
;BIT 16 CLEAR
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
@pageloop
|
|
mr r8, r29
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, @no_physical_page
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
@no_physical_page
|
|
|
|
lwz r17, 0(r30)
|
|
bl major_0x10d38
|
|
|
|
and r8, r4, r5
|
|
orc r9, r4, r5
|
|
or r18, r18, r8
|
|
and r18, r18, r9
|
|
|
|
lwz r17, 0(r30)
|
|
|
|
rlwinm. r8, r18, 0, 26, 26
|
|
bc BO_IF_NOT, 31, @118
|
|
bgt cr6, @118
|
|
beq @118
|
|
|
|
; Remove the page in question from the data cache
|
|
rlwinm r9, r17, 0, 0xFFFFF000
|
|
lwz r8, Area.PageSize(r31)
|
|
@dcache_flush_loop
|
|
subi r8, r8, 32
|
|
dcbf r8, r9
|
|
cmpwi r8, 0
|
|
bgt @dcache_flush_loop
|
|
sync
|
|
|
|
; Also from the inst cache
|
|
lwz r8, Area.PageSize(r31)
|
|
@icache_flush_loop
|
|
subi r8, r8, 32
|
|
icbi r8, r9
|
|
cmpwi r8, 0
|
|
bgt @icache_flush_loop
|
|
isync
|
|
|
|
@118
|
|
bl major_0x10cb8 ; PTE r16/r17, control r18 // PTE r16/r17
|
|
|
|
lwz r19, Area.PageSize(r31)
|
|
stw r17, 0(r30)
|
|
add r29, r29, r19
|
|
subf. r8, r29, r28
|
|
bge @pageloop
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@BIT_16_SET
|
|
|
|
bne cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r18, 0x001c(r31)
|
|
and r8, r4, r5
|
|
orc r9, r4, r5
|
|
or r18, r18, r8
|
|
and r18, r18, r9
|
|
stw r18, 0x001c(r31)
|
|
lwz r16, 0x0070(r31)
|
|
lwz r17, 0x0074(r31)
|
|
bl major_0x10cb8 ; PTE r16/r17, control r18 // PTE r16/r17
|
|
stw r16, 0x0070(r31)
|
|
stw r17, 0x0074(r31)
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
lwz r27, 0x0068(r31)
|
|
mr r28, r19
|
|
|
|
@1a4
|
|
mr r8, r29
|
|
lwz r9, Area.AddressSpacePtr(r31)
|
|
bl SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17
|
|
beq @1bc
|
|
bl InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bl DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
@1bc
|
|
add r29, r29, r27
|
|
subf. r8, r29, r28
|
|
bge @1a4
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
; ARG PTE r16, PTE r17, control r18
|
|
; RET PTE r16, PTE r17
|
|
; CLOB CR
|
|
|
|
|
|
major_0x10cb8 ; PTE r16/r17, control r18 // PTE r16/r17
|
|
|
|
rlwinm r16, r16, 0, 0xFFFFFF87 ; fill these in again...
|
|
rlwinm r17, r17, 0, 0xFFFFFF1F ;
|
|
rlwinm r16, r16, 0, 0xFFFFFFFC ; clear
|
|
rlwinm r17, r17, 0, 0xFFFFFFF9 ;
|
|
|
|
|
|
; Load control argument into condition register
|
|
; Note: this is a pretty expensive operation, not in hot path
|
|
|
|
mtcr r18
|
|
|
|
|
|
bge cr6, @80_not_set ; if(control & 0x80) {
|
|
ori r17, r17, 0x80 ; PTE2 |= 0x80; //set referenced bit
|
|
ori r16, r16, 0x08 ; PTE1 |= 0x08; //set guard bit
|
|
@80_not_set ; }
|
|
|
|
|
|
ble cr6, @40_not_set ; if(control & 0x40) {
|
|
ori r16, r16, 0x40 ; PTE1 |= 0x40; //set change bit
|
|
b @40_endif ; } else {
|
|
@40_not_set
|
|
ori r17, r17, 0x20 ; PTE2 |= 0x20; //set W bit
|
|
@40_endif ; }
|
|
|
|
|
|
bne cr6, @20_not_set ; if(control & 0x20) {
|
|
ori r17, r17, 0x40 ; PTE2 |= 0x40; //set change bit
|
|
ori r16, r16, 0x20 ; PTE1 |= 0x20; //set W bit
|
|
@20_not_set ; }
|
|
|
|
|
|
ble cr7, @04_not_set ; if(control & 0x04) {
|
|
@04_not_set ; }
|
|
|
|
|
|
bge cr7, @08_not_set ; if(control & 0x08) {
|
|
ori r17, r17, 0x06 ; PTE2 |= 0x06; //set leftmost protection bit and reserved bit
|
|
ori r16, r16, 0x01 ; PTE1 |= 0x01; //set rightmost protection bit
|
|
b @block_endif ; }
|
|
@08_not_set
|
|
bne cr7, @02_not_set ; else if(control & 0x02) {
|
|
ori r17, r17, 0x00 ; PTE2 |= 0x00; //useless instruction?
|
|
ori r16, r16, 0x02 ; PTE1 |= 0x02; //set second protection bit
|
|
b @block_endif ; }
|
|
@02_not_set
|
|
bc BO_IF_NOT, 31, @01_not_set ; else if(control & 0x01) {
|
|
ori r17, r17, 0x04 ; PTE2 |= 0x04; //set reserved bit.
|
|
ori r16, r16, 0x03 ; PTE1 |= 0x03: //set both protection bits
|
|
b @block_endif ; }
|
|
@01_not_set ; else {
|
|
ori r17, r17, 0x02 ; PTE2 |= 0x02; //set second protection bit
|
|
ori r16, r16, 0x00 ; PTE1 |= 0x00; //useless instruction?
|
|
@block_endif ; }
|
|
|
|
|
|
ori r16, r16, 0x10 ; PTE1 |= 0x10; //set M bit
|
|
|
|
|
|
blr ; return (PTE1, PTE2);
|
|
|
|
|
|
|
|
major_0x10d38 ; PLE r17
|
|
|
|
andi. r16, r17, %110
|
|
|
|
li r18, 0
|
|
|
|
cmpwi cr0, r16, %010
|
|
cmpwi cr1, r16, %110
|
|
beq cr0, @disconcordant
|
|
|
|
li r18, %100
|
|
andi. r16, r17, %100
|
|
ori r18, r18, %001 ; may as well have set both P bits in r8?
|
|
bne @disconcordant
|
|
ori r18, r18, %010
|
|
@disconcordant
|
|
|
|
bne cr1, major_0x10d38_0x30
|
|
ori r18, r18, 0x8
|
|
|
|
major_0x10d38_0x30
|
|
andi. r16, r17, 0x20
|
|
bne major_0x10d38_0x3c
|
|
ori r18, r18, 0x40
|
|
|
|
major_0x10d38_0x3c
|
|
andi. r16, r17, 0x40
|
|
beq major_0x10d38_0x48
|
|
ori r18, r18, 0x20
|
|
|
|
major_0x10d38_0x48
|
|
andi. r16, r17, 0x80
|
|
beq major_0x10d38_0x54
|
|
ori r18, r18, 0x80
|
|
|
|
major_0x10d38_0x54
|
|
blr
|
|
|
|
|
|
|
|
major_0x10d38_0x58 ; OUTSIDE REFERER
|
|
andi. r16, r17, 0x03
|
|
li r18, 0x04
|
|
cmpwi cr1, r16, 0x01
|
|
beq major_0x10d38_0x78
|
|
andi. r16, r17, 0x01
|
|
ori r18, r18, 0x01
|
|
bne major_0x10d38_0x78
|
|
ori r18, r18, 0x02
|
|
|
|
major_0x10d38_0x78
|
|
bne cr1, major_0x10d38_0x80
|
|
ori r18, r18, 0x08
|
|
|
|
major_0x10d38_0x80
|
|
andi. r16, r17, 0x40
|
|
beq major_0x10d38_0x8c
|
|
ori r18, r18, 0x40
|
|
|
|
major_0x10d38_0x8c
|
|
andi. r16, r17, 0x20
|
|
beq major_0x10d38_0x98
|
|
ori r18, r18, 0x20
|
|
|
|
major_0x10d38_0x98
|
|
andi. r16, r17, 0x08
|
|
beq major_0x10d38_0xa4
|
|
ori r18, r18, 0x80
|
|
|
|
major_0x10d38_0xa4
|
|
blr
|
|
|
|
|
|
|
|
# # ###### ##### # #
|
|
## ## # # # # ###### ##### # # ##### ###### ## # # #### #### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # # # # # ##### # # # # # # ##### #### ####
|
|
# # # # # # # ####### ##### # ###### ####### # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # ###### # # # # #### #### ###### #### ####
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 123, MPGetAreaAccess
|
|
|
|
MPGetAreaAccess
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
lwz r18, 0x0020(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
lwz r5, 0x001c(r31)
|
|
|
|
; r1 = kdp
|
|
bne ReleaseAndReturnZeroFromMPCall
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
lwz r17, 0x0000(r30)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
bl major_0x10d38
|
|
mr r5, r18
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # ###### ######
|
|
## ## # # # # ###### ##### # # ##### ###### ## # # ## #### # # # # # #### # # ##### #### # # # ##### ###### #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # # # # # ##### # # ###### # # # #### # # # # # ###### # # # # # # # # # ##### # #
|
|
# # # # # # ####### ##### # ###### # # ###### # # # # # # # # ### # ##### # # # # # # # # #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # ###### # # ###### # # #### # # # # # #### # # # #### ## # ##### ###### # #
|
|
|
|
; Does the blue task always get these notifications?
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
; ARG AreaID r3, NotificationID r4, long r5
|
|
; RET OSErr r3
|
|
|
|
DeclareMPCall 77, MPSetAreaBackingProvider
|
|
|
|
MPSetAreaBackingProvider
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
; Expect Area ID in r3
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
; r4 optionally contains...
|
|
mr. r8, r4
|
|
beq @no_notification
|
|
|
|
; a Notification ID
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
@no_notification
|
|
|
|
stw r4, Area.BackingProviderID(r31)
|
|
stw r5, Area.BackingProviderMisc(r31)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ####### #####
|
|
## ## # # # # ## # # # # # #
|
|
# # # # # # # # # # # # # #
|
|
# # # ###### # # # # # # #####
|
|
# # # # ###### # # # # #
|
|
# # # # # # # # # # # #
|
|
# # # ##### # # ###### ###### ###### # #####
|
|
|
|
; Dump Area info to userspace
|
|
|
|
DeclareMPCall 78, MPCall_78
|
|
|
|
MPCall_78 ; OUTSIDE REFERER
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
cmpwi r4, 0x01
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x00
|
|
bne MPCall_78_0x68
|
|
li r16, 0x01
|
|
stw r16, 0x0134(r6)
|
|
lwz r16, Area.ProcessID(r31)
|
|
stw r16, 0x013c(r6)
|
|
lwz r16, Area.AddressSpaceID(r31)
|
|
stw r16, 0x0144(r6)
|
|
lwz r16, 0x0014(r31)
|
|
stw r16, 0x014c(r6)
|
|
li r16, 0x10
|
|
stw r16, 0x0154(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_78_0x68
|
|
cmplwi r5, 0x10
|
|
bne MPCall_78_0x9c
|
|
lwz r16, 0x0018(r31)
|
|
stw r16, 0x0134(r6)
|
|
lwz r16, 0x001c(r31)
|
|
stw r16, 0x013c(r6)
|
|
lwz r16, 0x0020(r31)
|
|
stw r16, 0x0144(r6)
|
|
lwz r16, Area.LogicalBase(r31)
|
|
stw r16, 0x014c(r6)
|
|
li r16, 0x10
|
|
stw r16, 0x0154(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_78_0x9c
|
|
cmplwi r5, 0x20
|
|
bne MPCall_78_0xd0
|
|
lwz r16, Area.Length(r31)
|
|
stw r16, 0x0134(r6)
|
|
lwz r16, Area.LogicalSeparation(r31)
|
|
stw r16, 0x013c(r6)
|
|
lwz r16, 0x0034(r31)
|
|
stw r16, 0x0144(r6)
|
|
lwz r16, Area.BytesMapped(r31)
|
|
stw r16, 0x014c(r6)
|
|
li r16, 0x10
|
|
stw r16, 0x0154(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_78_0xd0
|
|
cmplwi r5, 0x30
|
|
bne MPCall_78_0xfc
|
|
lwz r16, 0x0068(r31)
|
|
stw r16, 0x0134(r6)
|
|
lwz r16, 0x0080(r31)
|
|
stw r16, 0x013c(r6)
|
|
lwz r16, 0x0084(r31)
|
|
stw r16, 0x0144(r6)
|
|
li r16, 0x0c
|
|
stw r16, 0x0154(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_78_0xfc
|
|
cmpwi r5, 0x3c
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
li r16, 0x00
|
|
stw r16, 0x0154(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # # # ### ######
|
|
## ## # # # # ###### ##### ## # ###### # # ##### # # ##### ###### ## # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # # # # ##### ## # # # # # ##### # # # # #
|
|
# # # # # # # # # # # ## # ####### ##### # ###### # # #
|
|
# # # # # # # # ## # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # ###### # # # # # # # ###### # # ### ######
|
|
|
|
; OSStatus MPGetNextAreaID(MPAddressSpaceID owningSpaceID, MPAreaID *areaID)
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: yes
|
|
|
|
DeclareMPCall 79, MPGetNextAreaID
|
|
|
|
MPGetNextAreaID
|
|
|
|
mr. r8, r3
|
|
mfsprg r28, 0
|
|
lwz r31, EWA.PA_CurAddressSpace(r28)
|
|
beq MPCall_79_0x20
|
|
bl LookupID
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
|
|
bne ReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
MPCall_79_0x20
|
|
lwz r3, Area.ID(r31)
|
|
|
|
MPCall_79_0x24
|
|
mr r8, r4
|
|
li r9, 0x0b
|
|
bl GetNextIDOfClass
|
|
cmpwi r8, 0x00
|
|
beq ReturnMPCallInvalidIDErr
|
|
mr r4, r8
|
|
bl LookupID
|
|
; r8 = something not sure what
|
|
; r9 = 0:inval, 1:proc, 2:task, 3:timer, 4:q, 5:sema, 6:cr, 7:cpu, 8:addrspc, 9:evtg, 10:cgrp, 11:area, 12:not, 13:log
|
|
|
|
lwz r16, 0x0010(r8)
|
|
cmpw r16, r3
|
|
bne MPCall_79_0x24
|
|
b ReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # ####### #
|
|
## ## # # # # ###### ##### # # ##### ###### ## # ##### #### # # # # ##### ##### ##### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # ## ## # # # # # # # # # # #
|
|
# # # ###### # #### ##### # # # # # ##### # # ##### # # # # # ## # # # # # # # # # ##### #### ####
|
|
# # # # # # # ####### ##### # ###### # ##### # # # # ####### # # # # ##### # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # ###### # # # # # #### # # # # ##### ##### # # ###### #### ####
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: yes
|
|
|
|
DeclareMPCall 80, MPGetAreaFromAddress
|
|
|
|
MPGetAreaFromAddress
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr. r8, r3
|
|
mfsprg r9, 0
|
|
bne MPCall_80_0x2c
|
|
lwz r8, EWA.PA_CurAddressSpace(r9)
|
|
b MPCall_80_0x38
|
|
|
|
MPCall_80_0x2c bl LookupID
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
MPCall_80_0x38
|
|
mr r9, r4
|
|
bl FindAreaAbove
|
|
lwz r16, 0x0024(r8)
|
|
li r5, 0x00
|
|
cmplw r16, r4
|
|
bgt ReleaseAndReturnParamErrFromMPCall
|
|
lwz r5, 0x0000(r8)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### # # # ####### #
|
|
## ## # # # # ###### ##### ## # ###### # # ##### # # ##### ###### ## # ##### #### # # # # ##### ##### ##### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # ## ## # # # # # # # # # # #
|
|
# # # ###### # #### ##### # # # # ##### ## # # # # # ##### # # ##### # # # # # ## # # # # # # # # # ##### #### ####
|
|
# # # # # # # # # # # ## # ####### ##### # ###### # ##### # # # # ####### # # # # ##### # # #
|
|
# # # # # # # # ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # ###### # # # # # # # ###### # # # # # #### # # # # ##### ##### # # ###### #### ####
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: yes
|
|
|
|
DeclareMPCall 125, MPGetNextAreaFromAddress
|
|
|
|
MPGetNextAreaFromAddress
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr. r8, r3
|
|
mfsprg r9, 0
|
|
bne MPCall_125_0x2c
|
|
lwz r8, EWA.PA_CurAddressSpace(r9)
|
|
b MPCall_125_0x38
|
|
|
|
MPCall_125_0x2c bl LookupID
|
|
cmpwi r9, AddressSpace.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
MPCall_125_0x38
|
|
mr r9, r4
|
|
bl FindAreaAbove
|
|
lwz r16, 0x0024(r8)
|
|
li r5, 0x00
|
|
cmplw r16, r4
|
|
bgt MPCall_125_0x58
|
|
lwz r8, 0x005c(r8)
|
|
addi r8, r8, -0x54
|
|
|
|
MPCall_125_0x58
|
|
lwz r9, 0x002c(r8)
|
|
cmpwi r9, noErr
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lwz r5, 0x0000(r8)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ###### #
|
|
## ## # # # # ###### ##### # # # # # # #### # #### ## # # # ##### ##### ##### ###### #### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ###### ###### # #### # # # # # # # # # # # # # ##### #### ####
|
|
# # # # # # # # # # # # # # ###### # ####### # # # # ##### # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # # #### # #### # # ###### # # ##### ##### # # ###### #### ####
|
|
|
|
; Straight MPLibrary wrapper: no
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 81, MPGetPhysicalAddress
|
|
|
|
MPGetPhysicalAddress
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
mr r31, r8
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
lwz r18, 0x0020(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
lwz r19, 0x0070(r31)
|
|
beq MPCall_81_0x70
|
|
lwz r17, Area.BytesMapped(r31)
|
|
rlwinm r19, r19, 0, 0, 19
|
|
cmpwi r17, 0x00
|
|
subf r18, r16, r4
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
add r5, r18, r19
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_81_0x70
|
|
li r3, 0x00
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_81_0xc8
|
|
mr r5, r17
|
|
rlwimi r5, r4, 0, 20, 31
|
|
|
|
MPCall_81_0xa4
|
|
_AssertAndRelease PSA.HTABLock, scratch=r8
|
|
b ReleaseAndReturnMPCall
|
|
|
|
MPCall_81_0xc8
|
|
li r3, kMPInsufficientResourcesErr
|
|
b MPCall_81_0xa4
|
|
|
|
|
|
|
|
# # ###### ##### ###### #######
|
|
## ## # # # # ###### ##### # # # # # # #### # #### ## # # # # ##### ###### # # #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # ## # #
|
|
# # # ###### # #### ##### # ###### ###### # #### # # # # # ##### ## # ##### # # # #
|
|
# # # # # # # # # # # # # # ###### # # ## # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # ## #
|
|
# # # ##### ###### # # # # # #### # #### # # ###### ####### # # # ###### # # #
|
|
|
|
; Straight MPLibrary wrapper: no
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 98, MPGetPhysicalExtent
|
|
|
|
MPGetPhysicalExtent
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
mr r31, r8
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
mr r29, r5
|
|
add r5, r5, r4
|
|
lwz r18, 0x0020(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r20, Area.BytesMapped(r31)
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmpwi cr1, r20, 0x00
|
|
beq MPCall_98_0x84
|
|
beq cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0070(r31)
|
|
subf r18, r16, r4
|
|
rlwinm r19, r19, 0, 0, 19
|
|
add r16, r18, r19
|
|
stw r16, 0x0134(r6)
|
|
stw r29, 0x013c(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_98_0x84
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r4
|
|
mr r28, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
crclr cr3_eq
|
|
li r3, 0x00
|
|
bso cr7, MPCall_98_0xc4
|
|
crset cr3_eq
|
|
li r3, kMPInsufficientResourcesErr
|
|
|
|
MPCall_98_0xc4
|
|
rlwimi r17, r4, 0, 20, 31
|
|
rlwinm r29, r17, 0, 0, 19
|
|
stw r17, 0x0134(r6)
|
|
|
|
MPCall_98_0xd0
|
|
lwz r16, 0x0068(r31)
|
|
add r28, r28, r16
|
|
add r29, r29, r16
|
|
cmplw cr2, r28, r5
|
|
bgt cr2, MPCall_98_0x140
|
|
mr r8, r28
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
rlwinm r17, r17, 0, 0, 19
|
|
crxor 31, 31, 14
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_98_0x10c
|
|
beq cr3, MPCall_98_0xd0
|
|
cmplw r29, r17
|
|
beq MPCall_98_0xd0
|
|
|
|
MPCall_98_0x10c
|
|
lwz r16, 0x007c(r31)
|
|
and r28, r28, r16
|
|
subf r16, r4, r28
|
|
|
|
MPCall_98_0x118
|
|
stw r16, 0x013c(r6)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r8
|
|
b ReleaseAndReturnMPCall
|
|
|
|
MPCall_98_0x140
|
|
addi r5, r5, 0x01
|
|
beq cr3, MPCall_98_0x170
|
|
mr r8, r28
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
rlwinm r17, r17, 0, 0, 19
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_98_0x170
|
|
cmplw r29, r17
|
|
bne MPCall_98_0x170
|
|
subf r16, r4, r5
|
|
b MPCall_98_0x118
|
|
|
|
MPCall_98_0x170
|
|
lwz r16, 0x007c(r31)
|
|
and r28, r28, r16
|
|
cmplw r5, r28
|
|
bge MPCall_98_0x184
|
|
mr r28, r5
|
|
|
|
MPCall_98_0x184
|
|
subf r16, r4, r28
|
|
b MPCall_98_0x118
|
|
|
|
|
|
|
|
# # ###### ###### #
|
|
## ## # # # # ###### #### # #### ##### ###### ##### # # #### ###### #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### ##### # # #### # ##### # # # # # ##### # #
|
|
# # # # # # # ### # # # # ##### ####### # ### # #####
|
|
# # # # # # # # # # # # # # # # # # # # # #
|
|
# # # # # ###### #### # #### # ###### # # # # #### ###### # #
|
|
|
|
; ARG MPNotificationID r3
|
|
; RET OSStatus r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 82, MPRegisterAger
|
|
|
|
MPRegisterAger
|
|
|
|
; May only register the ager once
|
|
lwz r8, PSA.AgerID(r1)
|
|
cmpwi r8, 0
|
|
bne ReturnMPCallOOM
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
|
|
stw r3, PSA.AgerID(r1)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ####### ######
|
|
## ## # # # # ###### ##### # ##### ###### ###### # # ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ##### # # ##### ##### ###### # # # #####
|
|
# # # # # # # # ##### # # # ###### # ### #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # ###### ###### # # # #### ######
|
|
|
|
; Pop page from system free list
|
|
|
|
; RET OSStatus r3, PhysicalPage *r4
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 83, MPGetFreePage
|
|
|
|
MPGetFreePage
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
bl FreePageListPop ; // PhysicalPage *r8
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
; Success
|
|
mr. r4, r8
|
|
bne ReturnZeroFromMPCall
|
|
|
|
; Failure. Fall through to something horrible!
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
|
|
|
|
# # # # # #
|
|
## ## # # #### # # # # ##### #### # # # # ##### # # # # ##### # # # # #### ###### #####
|
|
# # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # #
|
|
# # # # # # #### # # # # # # # # # # # # # # # # # # ###### # # # ##### # #
|
|
# # # # # # # ####### ##### # # # # # # # # # # # # # # # # ####### # ### # #####
|
|
# # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # # # # #
|
|
# # #### #### # # # # # # #### #### # # ##### ## ## # # # # # # #### ###### # #
|
|
|
|
FailMPCallAndNotifyAgerWeNeedPages
|
|
|
|
lwz r8, PSA.AgerID(r1)
|
|
bl LookupID
|
|
cmpwi r9, Notification.kIDClass
|
|
mr r31, r8
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r8, Notification.EventGroupID(r31)
|
|
bl LookupID
|
|
cmpwi r9, EventGroup.kIDClass
|
|
mr r31, r8
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
; Huh? Event Groups are 32 bytes. Bug?
|
|
lwz r8, 0x20(r31)
|
|
bl SetEvent
|
|
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
|
|
####### ###### # ######
|
|
# ##### ###### ###### # # ## #### ###### # # #### ##### # # #### #####
|
|
# # # # # # # # # # # # # # # # # # # # # #
|
|
##### # # ##### ##### ###### # # # ##### # # #### # ###### # # # #
|
|
# ##### # # # ###### # ### # # # # # # # # #####
|
|
# # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### # # # #### ###### ####### # #### # # #### #
|
|
|
|
; Requires PoolLock to be acquired!
|
|
|
|
FreePageListPop ; // PhysicalPage *r8
|
|
|
|
addi r18, r1, PSA.FreeList
|
|
lwz r8, PSA.FreeList + LLL.Next(r1)
|
|
cmpw r8, r18
|
|
beq @fail
|
|
|
|
RemoveFromList r8, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, PSA.FreePageCount(r1)
|
|
subi r16, r16, 1
|
|
stw r16, PSA.FreePageCount(r1)
|
|
|
|
; Daniel found the bug here!
|
|
lwz r17, LLL.Signature(r8)
|
|
mfspr r16, dec
|
|
eqv. r17, r18, r17
|
|
|
|
stw r16, 0(r8)
|
|
bne SpacePanicIsland
|
|
stw r16, 4(r8)
|
|
stw r16, 8(r8)
|
|
stw r16, 12(r8)
|
|
|
|
blr
|
|
|
|
@fail
|
|
li r8, 0
|
|
blr
|
|
|
|
|
|
|
|
# # ###### ###### ####### ######
|
|
## ## # # # # # # ##### # ##### ###### ###### # # ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### # # # ##### # # ##### ##### ###### # # # #####
|
|
# # # # # # # # ##### # # # ###### # ### #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # # #### # # # # ###### ###### # # # #### ######
|
|
|
|
; Checks some junk in the page first (consider removing this)
|
|
|
|
; ARG PhysicalPage *r3
|
|
; RET OSStatus r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 84, MPPutFreePage
|
|
|
|
MPPutFreePage
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, 4(r3)
|
|
lwz r17, 0(r3)
|
|
|
|
addi r18, r1, PSA.FreeList
|
|
eqv. r16, r16, r17
|
|
cmpw cr1, r17, r18
|
|
bne @succeed
|
|
bne cr1, @succeed
|
|
|
|
li r3, paramErr
|
|
b @return
|
|
|
|
@succeed
|
|
mr r8, r3
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
li r3, 0
|
|
|
|
@return
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
####### ###### # ######
|
|
# ##### ###### ###### # # ## #### ###### # # #### ##### # # # # #### # #
|
|
# # # # # # # # # # # # # # # # # # # # # # #
|
|
##### # # ##### ##### ###### # # # ##### # # #### # ###### # # #### ######
|
|
# ##### # # # ###### # ### # # # # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ###### # # # #### ###### ####### # #### # # #### #### # #
|
|
|
|
FreePageListPush ; PhysicalPage *r8
|
|
|
|
; Must be an actual page-aligned address
|
|
clrlwi. r9, r8, 20
|
|
addi r9, r1, PSA.FreeList
|
|
bne SpacePanicIsland
|
|
|
|
|
|
; This is probably an alternative to heavyweight locks around the free list
|
|
|
|
stw r9, 0(r8) ; store &parent in Freeform field
|
|
|
|
InsertAsPrev r8, r9, scratch=r16
|
|
|
|
not r9, r9
|
|
stw r9, 4(r8) ; store ^&parent in Signature field
|
|
|
|
|
|
lwz r8, PSA.FreePageCount(r1)
|
|
addi r8, r8, 1
|
|
stw r8, PSA.FreePageCount(r1)
|
|
|
|
blr
|
|
|
|
|
|
|
|
# # ###### ##### ####### ###### #####
|
|
## ## # # # # ###### ##### # ##### ###### ###### # # ## #### ###### # # #### # # # # #####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # ## # #
|
|
# # # ###### # #### ##### # ##### # # ##### ##### ###### # # # ##### # # # # # # # # #
|
|
# # # # # # # # ##### # # # ###### # ### # # # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # ## #
|
|
# # # ##### ###### # # # # ###### ###### # # # #### ###### ##### #### #### # # #
|
|
|
|
; RET r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 100, MPGetFreePageCount
|
|
|
|
MPGetFreePageCount
|
|
|
|
lwz r3, PSA.FreePageCount(r1)
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### ##### # # ###### #####
|
|
## ## # # # # ###### ##### # # # # # # ###### # ##### # # ## #### ###### # # #### # # # # #####
|
|
# # # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # ## # #
|
|
# # # ###### # #### ##### # # # # # # ###### ##### # # # ###### # # # ##### # # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # ###### # ### # # # # # # # # # #
|
|
# # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # ## #
|
|
# # # ##### ###### # ##### # # # # ###### ###### ##### # # # #### ###### ##### #### #### # # #
|
|
|
|
; RET r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 101, MPGetUnheldPageCount
|
|
|
|
MPGetUnheldPageCount
|
|
|
|
lwz r3, PSA.UnheldFreePageCount(r1)
|
|
b CommonMPCallReturnPath
|
|
|
|
|
|
|
|
# # ###### # # ######
|
|
## ## # # ## ## ## ##### # # ## #### ######
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # # # # # ###### # # # #####
|
|
# # # # # ###### ##### # ###### # ### #
|
|
# # # # # # # # # # # # # #
|
|
# # # # # # # # # # # #### ######
|
|
|
|
; ARG MPAreaID r3
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 85, MPMapPage
|
|
|
|
MPMapPage
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
lwz r16, Area.Flags(r31)
|
|
rlwinm. r8, r16, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
lwz r19, Area.FlagsAndMinAlign(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
|
|
rlwinm. r8, r19, 0, 16, 16 ; test Contig bit of FlagsAndMinAlign
|
|
cmplw cr1, r4, r16
|
|
lwz r20, Area.BytesMapped(r31)
|
|
beq @not_contig_area
|
|
bne cr1, ReleaseAndReturnParamErrFromMPCall
|
|
|
|
;is contig area
|
|
|
|
cmpwi r20, 0
|
|
lwz r8, Area.ContigPTETemplate(r31)
|
|
bne ReleaseAndReturnMPCallOOM
|
|
rlwimi r8, r5, 0, 0xFFFFF000
|
|
lwz r18, Area.DefaultAlignmentMask(r31)
|
|
lwz r20, Area.Length(r31)
|
|
stw r8, Area.ContigPTETemplate(r31)
|
|
stw r20, Area.BytesMapped(r31)
|
|
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@not_contig_area
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
|
|
lwz r29, 0(r30)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
rlwinm. r8, r29, 0, 31, 31
|
|
bne ReleaseAndReturnMPCallOOM
|
|
|
|
lwz r17, ContextBlock.r6(r6)
|
|
rlwinm. r8, r17, 0, 30, 30
|
|
bne KCMapPage_0x12c
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
bl FreePageListPop ; // PhysicalPage *r8
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
mr. r5, r8
|
|
beq FailMPCallAndNotifyAgerWeNeedPages
|
|
|
|
KCMapPage_0x12c
|
|
lwz r17, 0x0134(r6)
|
|
rlwinm. r8, r17, 0, 29, 29
|
|
beq KCMapPage_0x17c
|
|
rlwinm. r8, r29, 0, 25, 25
|
|
lwz r18, 0x0068(r31)
|
|
|
|
KCMapPage_0x140
|
|
addi r18, r18, -0x20
|
|
bne KCMapPage_0x174
|
|
dcbst r18, r5
|
|
|
|
KCMapPage_0x14c
|
|
cmpwi cr1, r18, 0x00
|
|
bgt cr1, KCMapPage_0x140
|
|
sync
|
|
lwz r18, 0x0068(r31)
|
|
|
|
KCMapPage_0x15c
|
|
addi r18, r18, -0x20
|
|
icbi r18, r5
|
|
cmpwi cr1, r18, 0x00
|
|
bgt cr1, KCMapPage_0x15c
|
|
isync
|
|
b KCMapPage_0x17c
|
|
|
|
KCMapPage_0x174
|
|
dcbf r18, r5
|
|
b KCMapPage_0x14c
|
|
|
|
KCMapPage_0x17c
|
|
lwz r18, 0x0068(r31)
|
|
andi. r29, r29, 0x7e7
|
|
ori r29, r29, 0x01
|
|
rlwimi r29, r5, 0, 0, 19
|
|
lwz r17, Area.BytesMapped(r31)
|
|
stw r29, 0x0000(r30)
|
|
add r17, r17, r18
|
|
stw r17, Area.BytesMapped(r31)
|
|
lwz r17, 0x0134(r6)
|
|
clrlwi. r8, r17, 0x1f
|
|
|
|
; r1 = kdp
|
|
beq ReleaseAndReturnZeroFromMPCall
|
|
lwz r5, 0x0068(r31)
|
|
b HoldPages
|
|
|
|
|
|
|
|
# # ###### # # ######
|
|
## ## # # # # # # # # ## ##### # # ## #### ###### ####
|
|
# # # # # # # # ## # ## ## # # # # # # # # # # # #
|
|
# # # ###### # # # # # # ## # # # # # ###### # # # ##### ####
|
|
# # # # # # # # # # ###### ##### # ###### # ### # #
|
|
# # # # # # ## # # # # # # # # # # # # #
|
|
# # # ##### # # # # # # # # # # #### ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 86, MPUnmapPages
|
|
|
|
MPUnmapPages
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r8, 0x0134(r6)
|
|
lwz r16, Area.Flags(r31)
|
|
rlwinm. r16, r16, 0, 28, 28
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
clrlwi. r8, r8, 0x1f
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
lwz r19, 0x0020(r31)
|
|
crmove 14, 2
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r29, 0x0068(r31)
|
|
lwz r20, Area.BytesMapped(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
cmplw cr1, r4, r16
|
|
beq KCUnmapPages_0xd8
|
|
bne cr1, ReleaseAndReturnParamErrFromMPCall
|
|
cmpwi r20, 0x00
|
|
li r20, 0x00
|
|
ble ReleaseAndReturnMPCallOOM
|
|
stw r20, Area.BytesMapped(r31)
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
li r30, 0x00
|
|
|
|
KCUnmapPages_0xac
|
|
mr r8, r4
|
|
lwz r9, Area.AddressSpacePtr(r31)
|
|
bl SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17
|
|
beq KCUnmapPages_0xc4
|
|
bl InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bl DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
KCUnmapPages_0xc4
|
|
add r4, r4, r29
|
|
subf. r8, r4, r5
|
|
bge KCUnmapPages_0xac
|
|
crclr cr3_eq
|
|
b KCUnmapPages_0x158
|
|
|
|
KCUnmapPages_0xd8
|
|
bne cr3, KCUnmapPages_0xf4
|
|
|
|
_Lock PSA.PoolLock, scratch1=r14, scratch2=r15
|
|
|
|
|
|
KCUnmapPages_0xf4
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
lwz r28, Area.BytesMapped(r31)
|
|
|
|
KCUnmapPages_0x110
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, KCUnmapPages_0x148
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
lwz r18, 0x0000(r30)
|
|
subf r28, r29, r28
|
|
rlwinm r18, r18, 0, 0, 30
|
|
stw r18, 0x0000(r30)
|
|
bne cr3, KCUnmapPages_0x148
|
|
rlwinm r8, r18, 0, 0, 19
|
|
|
|
; r1 = kdp
|
|
; r8 = maybe the page
|
|
bl FreePageListPush ; PhysicalPage *r8
|
|
|
|
KCUnmapPages_0x148
|
|
add r4, r4, r29
|
|
subf. r8, r4, r5
|
|
bge KCUnmapPages_0x110
|
|
stw r28, Area.BytesMapped(r31)
|
|
|
|
KCUnmapPages_0x158
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
bne cr3, ReleaseAndReturnZeroFromMPCall
|
|
_AssertAndRelease PSA.PoolLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### # # ###### #####
|
|
## ## # # ## ## ## # # ###### # # # # # # #### # #### ## # # # # # # #### # # ##### # #### # # #### # # ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # #
|
|
# # # ###### # # # # # #### ##### ###### ###### # #### # # # # # # # # # # # # # # # # # # # # # # ####
|
|
# # # # # ###### # # # # # # # # # # ###### # # # # # # # # # # # # ### # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # #
|
|
# # # # # # # # # ###### # # # # #### # #### # # ###### ###### # ##### #### # # # # #### #### #### #### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 127, MPMakePhysicallyContiguous
|
|
|
|
MPMakePhysicallyContiguous
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
mr r27, r5
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0020(r31)
|
|
lwz r29, 0x0068(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r27, r4
|
|
li r28, -0x01
|
|
|
|
NKMakePhysicallyContiguous_0x80
|
|
mr r8, r27
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, NKMakePhysicallyContiguous_0x150
|
|
rlwinm r8, r17, 0, 0, 19
|
|
cmpwi r28, -0x01
|
|
cmpw cr1, r28, r8
|
|
mr r28, r8
|
|
beq NKMakePhysicallyContiguous_0xac
|
|
bne cr1, NKMakePhysicallyContiguous_0xe0
|
|
|
|
NKMakePhysicallyContiguous_0xac
|
|
add r27, r27, r29
|
|
add r28, r28, r29
|
|
subf. r8, r27, r5
|
|
bge NKMakePhysicallyContiguous_0x80
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
NKMakePhysicallyContiguous_0xe0
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
addi r18, r1, PSA.FreeList
|
|
lwz r8, PSA.FreeList + LLL.Next(r1)
|
|
cmpw r8, r18
|
|
beq NKMakePhysicallyContiguous_0x174
|
|
b NKMakePhysicallyContiguous_0x174
|
|
|
|
; Dead code:
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
NKMakePhysicallyContiguous_0x150
|
|
_AssertAndRelease PSA.HTABLock, scratch=r16
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
NKMakePhysicallyContiguous_0x174
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
|
|
# # ###### # ######
|
|
## ## # # # #### #### # # # # ## #### ###### ####
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # # #### ###### # # # ##### ####
|
|
# # # # # # # # # # ###### # ### # #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # ####### #### #### # # # # # #### ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 87, MPLockPages
|
|
|
|
MPLockPages
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
mr r27, r5
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0020(r31)
|
|
lwz r29, 0x0068(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
mr r27, r4
|
|
li r28, 0x00
|
|
|
|
KCLockPages_0x68
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm r17, r18, 24, 25, 31
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmpwi cr1, r17, 0x7f
|
|
addi r28, r28, 0x01
|
|
beq KCLockPages_0x94
|
|
addi r28, r28, -0x01
|
|
bge cr1, major_0x0b0cc
|
|
|
|
KCLockPages_0x94
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCLockPages_0x68
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, PSA.UnheldFreePageCount(r1)
|
|
subf. r16, r28, r16
|
|
ble KCLockPages_0xc8
|
|
stw r16, PSA.UnheldFreePageCount(r1)
|
|
|
|
KCLockPages_0xc8
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
ble ReleaseAndReturnMPCallOOM
|
|
mr r27, r4
|
|
|
|
KCLockPages_0xf0
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq SpacePanicIsland
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm. r17, r18, 0, 16, 16
|
|
bne KCLockPages_0x10c
|
|
li r18, -0x8000
|
|
|
|
KCLockPages_0x10c
|
|
rlwinm r17, r18, 24, 25, 31
|
|
addi r17, r17, 0x01
|
|
rlwimi r18, r17, 8, 17, 23
|
|
sth r18, 0x0000(r30)
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCLockPages_0xf0
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### # # ######
|
|
## ## # # # # # # # #### #### # # # # ## #### ###### ####
|
|
# # # # # # # # ## # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # # # # # # # #### ###### # # # ##### ####
|
|
# # # # # # # # # # # # # # # ###### # ### # #
|
|
# # # # # # ## # # # # # # # # # # # # # # #
|
|
# # # ##### # # ###### #### #### # # # # # #### ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 88, MPUnlockPages
|
|
|
|
MPUnlockPages
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0020(r31)
|
|
lwz r29, 0x0068(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
mr r27, r4
|
|
|
|
KCUnlockPages_0x60
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm r17, r18, 24, 25, 31
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmpwi cr1, r17, 0x00
|
|
beq major_0x0b0cc
|
|
addi r28, r28, 0x01
|
|
beq cr1, major_0x0b0cc
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCUnlockPages_0x60
|
|
li r28, 0x00
|
|
|
|
KCUnlockPages_0x98
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm r17, r18, 24, 25, 31
|
|
addi r17, r17, -0x01
|
|
rlwimi r18, r17, 8, 17, 23
|
|
clrlwi. r8, r18, 0x11
|
|
bne KCUnlockPages_0xc4
|
|
rlwinm r18, r18, 0, 17, 15
|
|
addi r28, r28, 0x01
|
|
|
|
KCUnlockPages_0xc4
|
|
sth r18, 0x0000(r30)
|
|
add r4, r4, r29
|
|
subf. r8, r4, r5
|
|
bge KCUnlockPages_0x98
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, PSA.UnheldFreePageCount(r1)
|
|
add r16, r16, r28
|
|
stw r16, PSA.UnheldFreePageCount(r1)
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### # # ######
|
|
## ## # # # # #### # ##### # # ## #### ###### ####
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ####### # # # # # ###### # # # ##### ####
|
|
# # # # # # # # # # # ###### # ### # #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # # # #### ###### ##### # # # #### ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 89, MPHoldPages
|
|
|
|
MPHoldPages
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
|
|
|
|
# # ######
|
|
# # #### # ##### # # ## #### ###### ####
|
|
# # # # # # # # # # # # # # #
|
|
####### # # # # # ###### # # # ##### ####
|
|
# # # # # # # # ###### # ### # #
|
|
# # # # # # # # # # # # # # #
|
|
# # #### ###### ##### # # # #### ###### ####
|
|
|
|
HoldPages
|
|
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0020(r31)
|
|
lwz r29, 0x0068(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
mr r27, r4
|
|
li r28, 0x00
|
|
|
|
KCHoldPages_0x64
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
clrlwi r17, r18, 0x18
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmpwi cr1, r17, 0xff
|
|
addi r28, r28, 0x01
|
|
beq KCHoldPages_0x90
|
|
addi r28, r28, -0x01
|
|
bge cr1, major_0x0b0cc
|
|
|
|
KCHoldPages_0x90
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCHoldPages_0x64
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, PSA.UnheldFreePageCount(r1)
|
|
subf. r16, r28, r16
|
|
ble KCHoldPages_0xc4
|
|
stw r16, PSA.UnheldFreePageCount(r1)
|
|
|
|
KCHoldPages_0xc4
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
ble ReleaseAndReturnMPCallOOM
|
|
mr r27, r4
|
|
|
|
KCHoldPages_0xec
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq SpacePanicIsland
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm. r17, r18, 0, 16, 16
|
|
bne KCHoldPages_0x108
|
|
li r18, -0x8000
|
|
|
|
KCHoldPages_0x108
|
|
clrlwi r17, r18, 0x18
|
|
addi r17, r17, 0x01
|
|
rlwimi r18, r17, 0, 24, 31
|
|
sth r18, 0x0000(r30)
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCHoldPages_0xec
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### # # ######
|
|
## ## # # # # # # # # #### # ##### # # ## #### ###### ####
|
|
# # # # # # # # ## # # # # # # # # # # # # # # # #
|
|
# # # ###### # # # # # ###### # # # # # ###### # # # ##### ####
|
|
# # # # # # # # # # # # # # # # ###### # ### # #
|
|
# # # # # # ## # # # # # # # # # # # # # # #
|
|
# # # ##### # # # # #### ###### ##### # # # #### ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 90, MPUnholdPages
|
|
|
|
MPUnholdPages
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
add r5, r5, r4
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
addi r5, r5, -0x01
|
|
cmplw r4, r16
|
|
cmplw cr1, r5, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
lwz r19, 0x0020(r31)
|
|
lwz r29, 0x0068(r31)
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
mr r27, r4
|
|
|
|
KCUnholdPages_0x60
|
|
mr r8, r27
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
clrlwi r17, r18, 0x18
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
cmpwi cr1, r17, 0x00
|
|
beq major_0x0b0cc
|
|
addi r28, r28, 0x01
|
|
beq cr1, major_0x0b0cc
|
|
add r27, r27, r29
|
|
subf. r8, r27, r5
|
|
bge KCUnholdPages_0x60
|
|
li r28, 0x00
|
|
|
|
KCUnholdPages_0x98
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
clrlwi r17, r18, 0x18
|
|
addi r17, r17, -0x01
|
|
rlwimi r18, r17, 0, 24, 31
|
|
clrlwi. r8, r18, 0x11
|
|
bne KCUnholdPages_0xc4
|
|
rlwinm r18, r18, 0, 17, 15
|
|
addi r28, r28, 0x01
|
|
|
|
KCUnholdPages_0xc4
|
|
sth r18, 0x0000(r30)
|
|
add r4, r4, r29
|
|
subf. r8, r4, r5
|
|
bge KCUnholdPages_0x98
|
|
|
|
_Lock PSA.PoolLock, scratch1=r16, scratch2=r17
|
|
|
|
lwz r16, PSA.UnheldFreePageCount(r1)
|
|
add r16, r16, r28
|
|
stw r16, PSA.UnheldFreePageCount(r1)
|
|
_AssertAndRelease PSA.PoolLock, scratch=r16
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ###### #
|
|
## ## # # # # ###### ##### # # ## #### ###### # # ##### ##### ##### # ##### # # ##### ###### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ###### # # # ##### # # # # # # # ##### # # # ##### ####
|
|
# # # # # # # # ###### # ### # ####### # # ##### # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### # # # # # # # ##### #### # ###### ####
|
|
|
|
; ARG MPAreaID r3, LogicalPage *r4
|
|
; RET OSStatus r3, PageAttrs r5
|
|
|
|
DeclareMPCall 91, MPGetPageAttributes
|
|
|
|
MPGetPageAttributes
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
|
|
; Check that the passed address lies within the area
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
; Find the Page List Entry
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq @release_lock_return_oom
|
|
|
|
; Clear the PTE from the HTAB
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
; Get the PLE, and then we're clear of the HTAB lock
|
|
lwz r29, 0(r30)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
|
|
li r19, 0
|
|
beq @_ac
|
|
lhz r19, 0(r30)
|
|
@_ac
|
|
|
|
andi. r5, r29, 0x319
|
|
rlwinm. r8, r19, 0, 16, 16
|
|
rlwimi r5, r19, 0, 16, 16
|
|
beq ReleaseAndReturnZeroFromMPCall
|
|
|
|
rlwinm. r8, r19, 0, 17, 23
|
|
beq ReleaseAndReturnZeroFromMPCall
|
|
|
|
ori r5, r5, 0x4000
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
@release_lock_return_oom
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
|
|
# # ###### ##### ###### #
|
|
## ## # # # # ###### ##### # # ## #### ###### # # ##### ##### ##### # ##### # # ##### ###### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # ###### # # # ##### # # # # # # # ##### # # # ##### ####
|
|
# # # # # # # ###### # ### # ####### # # ##### # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### # # # # # # # ##### #### # ###### ####
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 92, MPSetPageAttributes
|
|
|
|
MPSetPageAttributes
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r16, Area.Flags(r31)
|
|
rlwinm. r8, r16, 0, 28, 28
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
lwz r29, 0x0134(r6)
|
|
li r8, 0x318
|
|
andc. r9, r5, r8
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
andc. r9, r29, r8
|
|
bne ReleaseAndReturnParamErrFromMPCall
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
|
|
_Lock PSA.HTABLock, scratch1=r14, scratch2=r15
|
|
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq MPCall_92_0xd8
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_92_0x9c
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
MPCall_92_0x9c
|
|
lwz r16, 0x0000(r30)
|
|
and r8, r5, r29
|
|
orc r9, r5, r29
|
|
or r16, r16, r8
|
|
and r16, r16, r9
|
|
stw r16, 0x0000(r30)
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
MPCall_92_0xd8
|
|
_AssertAndRelease PSA.HTABLock, scratch=r14
|
|
b ReleaseAndReturnMPCallOOM
|
|
|
|
|
|
|
|
# # ###### ##### ###### #
|
|
## ## # # # # ###### ##### # # ## #### ###### # # #### ######
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### # #### ##### # ###### # # # ##### # # # #####
|
|
# # # # # # # # ###### # ### # ####### # ### #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### # # #### ######
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 93, MPGetPageAge
|
|
|
|
MPGetPageAge
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
li r5, 0x00
|
|
|
|
; r1 = kdp
|
|
bne ReleaseAndReturnZeroFromMPCall
|
|
clrlwi r5, r18, 0x11
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ###### #
|
|
## ## # # # # ###### ##### # # ## #### ###### # # #### ######
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
# # # ###### ##### ##### # ###### # # # ##### # # # #####
|
|
# # # # # # # ###### # ### # ####### # ### #
|
|
# # # # # # # # # # # # # # # # # #
|
|
# # # ##### ###### # # # # #### ###### # # #### ######
|
|
|
|
; Straight MPLibrary wrapper: yes
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 94, MPSetPageAge
|
|
|
|
MPSetPageAge
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
cmplwi r5, 0x7fff
|
|
bgt ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
bne ReleaseAndReturnMPCallOOM
|
|
rlwimi r18, r5, 0, 17, 31
|
|
sth r18, 0x0000(r30)
|
|
|
|
_Lock PSA.HTABLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r4
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
bl GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
bc BO_IF_NOT, Area.kPLEFlagHasPhysPage, MPCall_94_0xa0
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
bcl BO_IF, Area.kPLEFlagIsInHTAB, DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
MPCall_94_0xa0
|
|
_AssertAndRelease PSA.HTABLock, scratch=r16
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ##### ###### # # # #####
|
|
## ## # # # # ###### ##### # # ## #### ###### # # #### # ##### # #### #### # # # # #### # # # # ##### ####
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # #
|
|
# # # ###### # #### ##### # ###### # # # ##### ####### # # # # # # # # # #### # # # # # # # # # ####
|
|
# # # # # # # # ###### # ### # # # # # # # # # # # # # # # # # # # # # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # #
|
|
# # # ##### ###### # # # # #### ###### # # #### ###### ##### ####### #### #### # # ##### #### #### # # # ####
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 129, MPGetPageHoldLockCounts
|
|
|
|
MPGetPageHoldLockCounts
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r3
|
|
bl LookupID
|
|
cmpwi r9, Area.kIDClass
|
|
|
|
bne ReleaseAndReturnMPCallInvalidIDErr
|
|
mr r31, r8
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r17, Area.LogicalEnd(r31)
|
|
cmplw r4, r16
|
|
cmplw cr1, r4, r17
|
|
blt ReleaseAndReturnParamErrFromMPCall
|
|
bgt cr1, ReleaseAndReturnParamErrFromMPCall
|
|
mr r8, r4
|
|
bl MPCall_95_0x254
|
|
beq ReleaseAndReturnParamErrFromMPCall
|
|
lhz r18, 0x0000(r30)
|
|
li r5, 0x00
|
|
rlwinm. r8, r18, 0, 16, 16
|
|
li r16, 0x00
|
|
beq MPCall_129_0x6c
|
|
rlwinm r16, r18, 24, 25, 31
|
|
clrlwi r5, r18, 0x18
|
|
|
|
MPCall_129_0x6c
|
|
stw r16, 0x0134(r6)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
# # ###### ####### # # ######
|
|
## ## # # # # # # ##### # # # #### ##### # # # # # ## #### ######
|
|
# # # # # # # # ## # # # # # # # # # # ## ## # # # # # # #
|
|
# # # ###### ##### # # # # # # # # # # # # # ## # ###### # # # #####
|
|
# # # # # # # # # # # # # # # # # # # ###### # ### #
|
|
# # # # # # ## # # # # # # # # # # # # # # # # #
|
|
# # # # # # # ##### # # #### # # # # # # # #### ######
|
|
|
|
; Straight MPLibrary wrapper: returns value via passed ptr
|
|
; In Universal Interfaces: no
|
|
|
|
DeclareMPCall 95, MPFindVictimPage
|
|
|
|
MPFindVictimPage
|
|
|
|
or. r8, r3, r4
|
|
|
|
bne @not_naughty
|
|
li r16, 0
|
|
stw r16, KDP.VMMaxVirtualPages(r1)
|
|
_log 'Areas capability probe detected^n'
|
|
b ReturnParamErrFromMPCall
|
|
@not_naughty
|
|
|
|
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
|
|
|
|
li r28, -0x01
|
|
li r4, 0x00
|
|
li r5, 0x00
|
|
lwz r8, PSA.UnheldFreePageCount(r1)
|
|
cmpwi r8, 0x00
|
|
ble ReleaseAndReturnMPCallOOM
|
|
lwz r27, PSA.DecClockRateHzCopy(r1)
|
|
srwi r27, r27, 15
|
|
mfspr r8, dec
|
|
subf r27, r27, r8
|
|
lwz r8, PSA.OtherSystemAddrSpcPtr2(r1)
|
|
lwz r9, PSA.ZeroedByInitFreeList3(r1)
|
|
mr r30, r9
|
|
bl FindAreaAbove
|
|
mr r31, r8
|
|
lwz r29, Area.LogicalBase(r31)
|
|
cmplw r29, r30
|
|
bgt MPCall_95_0xa8
|
|
mr r29, r30
|
|
|
|
MPCall_95_0xa8
|
|
crset cr2_eq
|
|
|
|
MPCall_95_0xac
|
|
mfspr r9, dec
|
|
subf. r9, r27, r9
|
|
blt MPCall_95_0x1c8
|
|
|
|
MPCall_95_0xb8
|
|
lwz r8, 0x0020(r31)
|
|
lwz r9, 0x0018(r31)
|
|
rlwinm. r8, r8, 0, 16, 16
|
|
cmpwi cr1, r3, 0x00
|
|
bne MPCall_95_0x19c
|
|
beq cr1, MPCall_95_0xe0
|
|
cmpwi cr3, r9, 0x00
|
|
beq cr3, MPCall_95_0xe0
|
|
cmpw cr1, r9, r3
|
|
bne cr1, MPCall_95_0x19c
|
|
|
|
MPCall_95_0xe0
|
|
lwz r9, Area.Flags(r31)
|
|
rlwinm. r8, r9, 0, 28, 28
|
|
bne MPCall_95_0x19c
|
|
rlwinm. r8, r9, 0, 23, 23
|
|
bne MPCall_95_0x19c
|
|
|
|
_Lock PSA.HTABLock, scratch1=r16, scratch2=r17
|
|
|
|
mr r8, r29
|
|
bl SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
beq SpacePanicIsland
|
|
_AssertAndRelease PSA.HTABLock, scratch=r16
|
|
lwz r16, 0x0000(r30)
|
|
clrlwi. r8, r16, 0x1f
|
|
beq MPCall_95_0x180
|
|
mr r8, r29
|
|
bl MPCall_95_0x254
|
|
beq MPCall_95_0x1c8
|
|
lhz r17, 0x0000(r30)
|
|
rlwinm. r8, r17, 0, 16, 16
|
|
clrlwi r17, r17, 0x11
|
|
bne MPCall_95_0x180
|
|
cmpw r17, r28
|
|
crclr cr2_eq
|
|
ble MPCall_95_0x180
|
|
mr r28, r17
|
|
lwz r4, Area.ID(r31)
|
|
cmplwi r17, 0x7fff
|
|
mr r5, r29
|
|
bge MPCall_95_0x1c8
|
|
|
|
MPCall_95_0x180
|
|
lwz r8, 0x0068(r31)
|
|
lwz r9, Area.LogicalEnd(r31)
|
|
add r29, r29, r8
|
|
subf. r9, r9, r29
|
|
bge MPCall_95_0x19c
|
|
bne cr2, MPCall_95_0xac
|
|
b MPCall_95_0xb8
|
|
|
|
MPCall_95_0x19c
|
|
lwz r8, 0x0054(r31)
|
|
lwz r9, 0x005c(r31)
|
|
cmpw r8, r9
|
|
addi r31, r9, -0x54
|
|
lwz r29, Area.LogicalBase(r31)
|
|
bne MPCall_95_0x1c0
|
|
lwz r9, 0x0008(r8)
|
|
addi r31, r9, -0x54
|
|
lwz r29, Area.LogicalBase(r31)
|
|
|
|
MPCall_95_0x1c0
|
|
bne cr2, MPCall_95_0xac
|
|
b MPCall_95_0xb8
|
|
|
|
MPCall_95_0x1c8
|
|
cmpwi r4, 0x00
|
|
stw r29, PSA.ZeroedByInitFreeList3(r1)
|
|
beq ReleaseAndReturnMPCallOOM
|
|
lwz r8, 0x0068(r31)
|
|
add r8, r8, r5
|
|
stw r8, PSA.ZeroedByInitFreeList3(r1)
|
|
|
|
; r1 = kdp
|
|
b ReleaseAndReturnZeroFromMPCall
|
|
|
|
|
|
|
|
##### ##### ###### ###### # #######
|
|
# # ##### ## #### ###### # # ###### ##### # # ## #### ###### # # # #
|
|
# # # # # # # # # # # # # # # # # # # # # #
|
|
##### # # # # # ##### # #### ##### # ###### # # # ##### ###### # #####
|
|
# ##### ###### # # # # # # # ###### # ### # # # #
|
|
# # # # # # # # # # # # # # # # # # # # #
|
|
##### # # # #### ###### ##### ###### # # # # #### ###### # ####### #######
|
|
|
|
SpaceGetPagePLE ; LogicalPage *r8, Area *r31 // PLE *r30, notfound cr0.eq
|
|
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r18, Area.Flags(r31)
|
|
lwz r30, Area.PageMapArrayPtr(r31)
|
|
|
|
; r17 = offset of ptr into area
|
|
subf r17, r16, r8
|
|
|
|
@loop_that_would_totally_happen_but_not
|
|
|
|
; Fail if Area has no page map array.
|
|
; r17 = offset of page's entry in page map (entries are 4b)
|
|
cmpwi r30, 0
|
|
rlwinm r17, r17, (32-10), 10, 29
|
|
beqlr
|
|
|
|
; Do another level of lookups if the array is 2D
|
|
; (i.e. the Area contains more than 1k pages)
|
|
rlwinm. r16, r18, 0, Area.kPageMapArrayIs2D, Area.kPageMapArrayIs2D
|
|
rlwinm r16, r17, (32-10), 20, 29 ; offset of secondary ptr in page map
|
|
beq @not_2d
|
|
rlwinm r17, r17, 0, 20, 29
|
|
lwzx r30, r30, r16
|
|
@not_2d
|
|
|
|
; Return r30, a pointer to the list entry
|
|
; cr0.eq if we failed
|
|
add. r30, r30, r17
|
|
blr
|
|
|
|
; Dead code:
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r18, Area.Flags(r31)
|
|
lwz r30, 0x0040(r31)
|
|
|
|
rlwinm. r17, r18, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
subf r17, r16, r8
|
|
beq @loop_that_would_totally_happen_but_not
|
|
|
|
lwz r30, Area.AliasLLL(r31)
|
|
lwz r18, 0x80(r31)
|
|
subi r30, r30, Area.AliasLLL
|
|
subf r17, r16, r8
|
|
add r17, r17, r18
|
|
lwz r18, Area.Flags(r30)
|
|
lwz r30, Area.PageMapArrayPtr(r30)
|
|
b @loop_that_would_totally_happen_but_not
|
|
|
|
|
|
|
|
MPCall_95_0x254 ; OUTSIDE REFERER
|
|
lwz r16, Area.LogicalBase(r31)
|
|
lwz r18, Area.Flags(r31)
|
|
lwz r30, 0x003c(r31)
|
|
rlwinm. r17, r18, 0, Area.kAliasFlag, Area.kAliasFlag
|
|
subf r17, r16, r8
|
|
beq MPCall_95_0x288
|
|
|
|
lwz r30, 0x0044(r31)
|
|
lwz r18, 0x0080(r31)
|
|
addi r30, r30, -0x44
|
|
subf r17, r16, r8
|
|
add r17, r17, r18
|
|
lwz r18, 0x0008(r30)
|
|
lwz r30, 0x003c(r30)
|
|
|
|
MPCall_95_0x288
|
|
cmpwi r30, 0x00
|
|
rlwinm r17, r17, 21, 11, 30
|
|
beqlr
|
|
rlwinm. r16, r18, 0, 30, 30
|
|
rlwinm r16, r17, 22, 20, 29
|
|
beq MPCall_95_0x2a8
|
|
rlwinm r17, r17, 0, 20, 30
|
|
lwzx r30, r30, r16
|
|
|
|
MPCall_95_0x2a8
|
|
add. r30, r30, r17
|
|
blr
|
|
|
|
|
|
|
|
##### ###### ####### ####### ####### ###### # #######
|
|
# # ###### ##### # # # # # ##### #### # # # # # #
|
|
# # # # # # # # # # # # ## ## # # # #
|
|
# #### ##### # ###### # ##### ##### # # # # # ## # ###### # #####
|
|
# # # # # # # # ##### # # # # # # #
|
|
# # # # # # # # # # # # # # # # #
|
|
##### ###### # # # ####### # # # #### # # # ####### #######
|
|
|
|
; If a logical page (of an Area of an AddressSpace) is featured in the HTAB,
|
|
; its NanoKernel Page List Entry (PLE) should point at that PowerPC Page Table
|
|
; Entry (PTE, of a PTEG in the HTAB). If there is a physical page mapped to
|
|
; that logical page, but it is not yet in the HTAB, then the PLE will point
|
|
; directly to the page.
|
|
|
|
GetPTEFromPLE ; PLE *r30 // PTE r16/r17, PTE *r18, PTEflags cr0, PLEflags cr5-7
|
|
|
|
lwz r19, 0(r30) ; r19 = contents of page list entry
|
|
lwz r18, KDP.HTABORG(r1) ; r18 = HTAB base, in case like me you were confused
|
|
|
|
mtcrf %00000111, r19 ; cr5-7 = flags from PLE
|
|
|
|
; Returning early because we are not in HTAB? Cook up a fake PTE.
|
|
rlwinm r17, r19, 0, 0, 19 ; lower has RPN
|
|
rlwinm r16, r19, (32-9), 0+9, 19+9 ; will actually use this as PTE offset within HTAB!
|
|
|
|
bclr BO_IF_NOT, Area.kPLEFlagHasPhysPage
|
|
bclr BO_IF_NOT, Area.kPLEFlagIsInHTAB
|
|
|
|
; r16/r17 = PTE
|
|
; r18 = &PTE
|
|
lwzux r16, r18, r16
|
|
lwz r17, 4(r18)
|
|
|
|
; Die if V bit is not set (entry is invalid).
|
|
; Return flags.
|
|
mtcrf %10000000, r16
|
|
bc BO_IF_NOT, 0, SpacePanicIsland
|
|
|
|
blr
|
|
|
|
|
|
|
|
### ###### ####### #######
|
|
# # # # # ## # # # # #
|
|
# ## # # # # # # # # # #
|
|
# # # # # # # # # ###### # #####
|
|
# # # # # # ###### # # # #
|
|
# # ## # # # # # # # #
|
|
### # # ## # # ###### # # #######
|
|
|
|
InvalPTE ; page *r8, PTE r16/r17, PTE *r18, PLE *r30 // PLEflags cr5-7
|
|
|
|
; Special-case 601.
|
|
; Clear V bit of PTE.
|
|
mfspr r14, pvr
|
|
_bclr r16, r16, 0
|
|
rlwinm. r14, r14, 0, 0xFFFE0000
|
|
stw r16, 0(r18)
|
|
|
|
; Now that HTAB is touched, bump our page from the TLB
|
|
sync
|
|
tlbie r8
|
|
beq @is_601
|
|
sync
|
|
tlbsync
|
|
@is_601
|
|
sync
|
|
isync
|
|
|
|
; Prepare to re-set V bit, but return if there is no PLE
|
|
cmpwi r30, 0
|
|
|
|
; Be needlessly sure that these registers don't get clobbered
|
|
lwz r14, 0(r30) ; r14 = PLE
|
|
lwz r17, 4(r18) ; r17 = lower PTE
|
|
_bset r16, r16, 0 ; r16 = upper PTE
|
|
|
|
beqlr
|
|
|
|
; Continue if there is a PLE involved... INTERESTING PART
|
|
rlwimi r14, r17, (32-3), 27, 27 ; lowest two bits of VSID into 27/28 of PLE
|
|
rlwimi r14, r17, (32-5), 28, 28
|
|
|
|
; Slightly update the cond reg with the new PLE
|
|
; (flags 27 and 28, others should be unchanged)
|
|
mtcrf %00000111, r14 ; set CR (is return value)
|
|
stw r14, 0(r30) ; save that PLE
|
|
|
|
blr
|
|
|
|
|
|
|
|
##### ###### ####### #######
|
|
# # ###### ##### # # # #
|
|
# # # # # # #
|
|
##### ##### # ###### # #####
|
|
# # # # # #
|
|
# # # # # # #
|
|
##### ###### # # # #######
|
|
|
|
SetPTE ; PTE r16/r17, PTE *r18
|
|
|
|
stw r17, 4(r18)
|
|
eieio
|
|
stw r16, 0(r18)
|
|
sync
|
|
blr
|
|
|
|
|
|
|
|
###### ###### ####### #######
|
|
# # ###### # ###### ##### ###### # # # #
|
|
# # # # # # # # # # #
|
|
# # ##### # ##### # ##### ###### # #####
|
|
# # # # # # # # # #
|
|
# # # # # # # # # #
|
|
###### ###### ###### ###### # ###### # # #######
|
|
|
|
DeletePTE ; PTE *r18, PLE *r30
|
|
|
|
lwz r14, 0(r30)
|
|
|
|
_InvalNCBPointerCache scratch=r16
|
|
|
|
foo set KDP.NanoKernelInfo + NKNanoKernelInfo.HashTableDeleteCount
|
|
lwz r16, foo(r1)
|
|
_bclr r14, r14, Area.kPLEFlagIsInHTAB
|
|
addi r16, r16, 1
|
|
stw r16, foo(r1)
|
|
|
|
; Change "PLE>PTE>page" to "PLE>page"
|
|
rlwimi r14, r17, 0, 0xfffff000
|
|
|
|
; Fully zero the PTE.
|
|
; But only zero the PLE if the ptr is non-null.
|
|
cmpwi r30, 0
|
|
li r16, 0
|
|
li r17, 0
|
|
beq SetPTE ; PTE r16/r17, PTE *r18
|
|
stw r14, 0(r30)
|
|
b SetPTE ; PTE r16/r17, PTE *r18
|
|
|
|
|
|
|
|
##### # ##### ###### # # ###### # #######
|
|
# # ##### ## #### ###### # # # # # # # #### # # # #### # # # # # ####
|
|
# # # # # # # # # # # # # # # # ## # # # # # # # # #
|
|
##### # # # # # ##### # ##### ###### # # #### # # # # # ###### # # # ####
|
|
# ##### ###### # # # # # # # # # # # # # ### # # ####### # #
|
|
# # # # # # # # # # # # # # # # # ## # # # # # # # # #
|
|
##### # # # #### ###### ####### ####### # ##### #### # # # #### ###### # # # ####
|
|
|
|
SpaceL2PUsingBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17
|
|
|
|
MACRO
|
|
_v2pguts ; cr0.eq = match
|
|
rlwimi r19, r16, 15, 0, 14 ; r19 = 0000 (4b) || BEPI (11b) || 11111111111111111 (17b) = bits that needn't match
|
|
xor r17, r8, r16 ; xor the two things we are comparing
|
|
andc. r17, r17, r19 ; mask away the bits that needn't match
|
|
ENDM
|
|
|
|
|
|
; Use current Address Space if none specified
|
|
|
|
mr. r19, r9
|
|
mfsprg r17, 0
|
|
bne @addrspc_provided
|
|
lwz r19, EWA.PA_CurAddressSpace(r17)
|
|
@addrspc_provided
|
|
|
|
|
|
; Search all 8 UBAT registers for one that contains our effective address
|
|
|
|
addi r18, r19, AddressSpace.BATs
|
|
|
|
lwz r16, 0(r18)
|
|
li r19, -1
|
|
_v2pguts
|
|
beq @bat_yes
|
|
|
|
lwzu r16, 8(r18)
|
|
_v2pguts
|
|
beq @bat_yes
|
|
|
|
lwzu r16, 8(r18)
|
|
_v2pguts
|
|
beq @bat_yes
|
|
|
|
lwzu r16, 8(r18)
|
|
_v2pguts
|
|
bne @bat_no
|
|
|
|
@bat_yes
|
|
andi. r17, r16, 1 ; cr0.eq = !UBAT[Vp]
|
|
rlwinm r19, r19, 0, 8, 19
|
|
lwzu r17, 4(r18) ; r17 = LBAT
|
|
and r19, r8, r19
|
|
or r17, r17, r19
|
|
bnelr ; succeed if UBAT[Vp] is set
|
|
|
|
@bat_no
|
|
|
|
|
|
|
|
##### # ##### ###### ### ###### # #######
|
|
# # ##### ## #### ###### # # # # # # #### # # #### ##### # # # #### # # # # # ####
|
|
# # # # # # # # # # # # # # # ## # # # # # # ## # # # # # # # # #
|
|
##### # # # # # ##### # ##### ###### # # # # # # # # # # # # # # ###### # # # ####
|
|
# ##### ###### # # # # # # # ### # # # # # ##### # # # # # ### # # ####### # #
|
|
# # # # # # # # # # # # # # # ## # # # # # # ## # # # # # # # # #
|
|
##### # # # #### ###### ####### ####### # ### #### # # #### # # # # # #### ###### # # # ####
|
|
|
|
SpaceL2PIgnoringBATs ; LogicalPage *r8, MPAddressSpace *r9 // PhysicalPage *r17
|
|
|
|
; r17 = segment descriptor (from addrspc or actual register)
|
|
|
|
cmpwi r9, 0
|
|
addi r16, r9, AddressSpace.SRs
|
|
beq @no_addrspc_provided
|
|
|
|
;addrspc provided
|
|
rlwinm r17, r8, (32-26), 26, 29
|
|
lwzx r17, r16, r17
|
|
b @endif_addrspc
|
|
|
|
@no_addrspc_provided
|
|
mfsrin r17, r8
|
|
|
|
@endif_addrspc
|
|
|
|
|
|
; Do the "(VSID || page index) -> PTEG address" hashing function
|
|
; Remember, PTEG = 8 x 8b PTEs
|
|
|
|
; r18 = physical address of 64b PTEG to search
|
|
; r16 = upper PTE to check for (V, VSID and API fields)
|
|
|
|
rlwinm r16, r8, 10, 26, 31 ; set API field of r16
|
|
rlwimi r16, r17, 7, 1, 24 ; set VSID field of r16
|
|
rlwinm r9, r8, 32-6, 10, 25 ; r9 = page index in bits 0x003FFFC0
|
|
_bset r16, r16, 0 ; set V(alid) bit of r16 to 1
|
|
rlwinm r17, r17, 6, 7, 25
|
|
xor r9, r9, r17 ; r9 ^= (VSID & 0x7FFFF) in bits 0x01FFFFC0
|
|
|
|
lwz r17, KDP.PTEGMask(r1)
|
|
lwz r18, KDP.HTABORG(r1)
|
|
|
|
and r9, r9, r17 ; r9 %= HTAB size
|
|
or. r18, r18, r9 ; r18 = &HTAB + r9 = &PTEG
|
|
|
|
|
|
; This is tightly coded, but is obviously searching the PTEG for a match with r16
|
|
|
|
@try_other_four_PTEs
|
|
lwz r17, 0*8(r18) ; load this upper PTE
|
|
lwz r9, 1*8(r18) ; and the next upper PTE
|
|
cmpw cr6, r16, r17
|
|
lwz r17, 2*8(r18) ; and the next upper PTE
|
|
cmpw cr7, r16, r9
|
|
lwzu r9, 3*8(r18) ; and the next upper PTE, and update
|
|
|
|
bne cr6, @nope
|
|
|
|
@yes_this_one
|
|
lwzu r17, -20(r18)
|
|
blr
|
|
|
|
@nope
|
|
cmpw cr6, r16, r17
|
|
lwzu r17, 8(r18)
|
|
beq cr7, @yes_this_one
|
|
|
|
cmpw cr7, r16, r9
|
|
lwzu r9, 8(r18)
|
|
beq cr6, @yes_this_one
|
|
|
|
cmpw cr6, r16, r17
|
|
lwzu r17, 8(r18)
|
|
beq cr7, @yes_this_one
|
|
|
|
cmpw cr7, r16, r9
|
|
lwzu r9, 8(r18)
|
|
beq cr6, @yes_this_one
|
|
|
|
cmpw cr6, r16, r17
|
|
lwzu r17, -12(r18)
|
|
beqlr cr7
|
|
|
|
cmpw cr7, r16, r9
|
|
lwzu r17, 8(r18)
|
|
beqlr cr6
|
|
|
|
lwzu r17, 8(r18)
|
|
beqlr cr7
|
|
|
|
lwz r17, KDP.PTEGMask(r1)
|
|
|
|
xori r16, r16, 0x40 ; try the other four PTEs in this PTEG
|
|
andi. r9, r16, 0x40 ; but if that bit went back to 0 from 1 then we're out of PTEs!
|
|
|
|
addi r18, r18, -0x3c
|
|
xor r18, r18, r17
|
|
|
|
bne @try_other_four_PTEs
|
|
|
|
blr ; fail
|