powermac-rom/NanoKernel/NKAddressSpaces.s

4852 lines
134 KiB
ArmAsm

; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKConsoleLog
; printw
; NKIndex
; DeleteID
; GetNextIDOfClass
; LookupID
; MakeID
; NKMPCalls
; CommonMPCallReturnPath
; ReleaseAndMPCallWasBad
; ReleaseAndReturnMPCall
; ReleaseAndReturnMPCallInvalidIDErr
; ReleaseAndReturnMPCallOOM
; ReleaseAndReturnMPCallPrivilegedErr
; ReleaseAndReturnParamErrFromMPCall
; ReleaseAndReturnZeroFromMPCall
; ReleaseAndScrambleMPCall
; ReturnMPCallInvalidIDErr
; ReturnMPCallOOM
; ReturnParamErrFromMPCall
; ReturnZeroFromMPCall
; major_0x0b0cc
; NKPoolAllocator
; PoolAllocClear
; PoolFree
; NKSync
; CauseNotification
; SetEvent
; NKThud
; panic
; EXPORTS:
; CreateArea (=> NKVMCalls)
; CreateAreasFromPageMap (=> NKInit)
; DeletePTE (=> NKVMCalls)
; FindAreaAbove (=> NKInterrupts, NKPaging, NKTasks, NKVMCalls)
; FreePageListPush (=> NKInit)
; GetPTEFromPLE (=> NKVMCalls)
; InitFreePageList (=> NKInit)
; InvalPTE (=> NKVMCalls)
; MPCall_95_0x254 (=> NKPaging)
; NKCreateAddressSpaceSub (=> NKInit)
; SetPTE (=> NKVMCalls)
; SpaceGetPagePLE (=> NKInterrupts, NKPaging, NKVMCalls)
; SpaceL2PIgnoringBATs (=> NKMPCalls)
; SpaceL2PUsingBATs (=> NKInterrupts, NKMPCalls)
##### ###### ###
# # ##### ## #### ###### # # ## # # # #### # #### # ## # # #####
# # # # # # # # # # # # ## # # # # # # # # # ## # # #
##### # # # # # ##### ###### # # # # # # # # #### # # # # # # # #
# ##### ###### # # # ###### # # # # # # # # ###### # # # # #
# # # # # # # # # # # # ## # # # # # # # # # # ## # #
##### # # # #### ###### # # # # # # #### ### #### ###### # # # # #####
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
beq @bat_yes
lwzu r16, 8(r18)
_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