mirror of
https://github.com/elliotnunn/powermac-rom.git
synced 2024-06-07 08:30:20 +00:00
vm bump
This commit is contained in:
parent
074823a713
commit
51020bbbf3
|
@ -93,9 +93,9 @@ mrFlagDidLoad equ cr3_so
|
|||
|
||||
; Upper word of a Page Table Entry (PTE):
|
||||
_bitequate 0, UpteValid ; [V] if valid then a signed compare will raise the LT bit
|
||||
; bits 1-24 hold the Virtual Segment ID (VSID, allows one HTAB to hold many addr spaces)
|
||||
UpteVSID equ 0x7FFFFF80 ; bits 1-24 = Virtual Segment ID (allows one HTAB to hold many addr spaces)
|
||||
_bitequate 25, UpteHash ; [H] set if this PTE is placed according to secondary hash
|
||||
; bits 26-31 hold the Abbreviated Page Index (API, the EA bits that aren't implicit in the hash)
|
||||
UpteAPI equ 0x0000003F ; bits 26-31 = Abbreviated Page Index (the EA bits that aren't implicit in the hash)
|
||||
|
||||
; Lower word of a Page Table Entry (PTE):
|
||||
; bits 0-19 hold the Real Page Number (RPN, the address of the physical page)
|
||||
|
@ -173,30 +173,30 @@ PMDT_PTE_Single_Rel equ 0x600
|
|||
########################################################################
|
||||
|
||||
; 68k Page Descriptors
|
||||
A handful of special PMDTs describe the MacOS "Primary Address Range"
|
||||
(the contiguous RAM starting at address 0 and containing the sys and app
|
||||
heaps etc). Instead of referring directly to physical pages, each of
|
||||
these PMDTs has in its RPN field a pointer to an array of 68k Page
|
||||
Descriptors! These are in the 68k 4k-page format, and could also be
|
||||
called 68k Page Table Entries. Besides being friendly to old 68k code
|
||||
using the VMDispatch trap (FE0A), this provides a convenient way to
|
||||
store state for individual logical pages and to allow them to use
|
||||
discontiguous physical backing.
|
||||
; A handful of special PMDTs describe the MacOS "Primary Address Range"
|
||||
; (the contiguous RAM starting at address 0 and containing the sys and app
|
||||
; heaps etc). Instead of referring directly to physical pages, each of
|
||||
; these PMDTs has in its RPN field a pointer to an array of 68k Page
|
||||
; Descriptors! These are in the 68k 4k-page format, and could also be
|
||||
; called 68k Page Table Entries. Besides being friendly to old 68k code
|
||||
; using the VMDispatch trap (FE0A), this provides a convenient way to
|
||||
; store state for individual logical pages and to allow them to use
|
||||
; discontiguous physical backing.
|
||||
|
||||
; Bits 0-19:
|
||||
; if M68pdInHTAB: native PTE index relative to HTABORG
|
||||
; else: physical page address
|
||||
_bitequate 20, M68pdInHTAB ; [11 UR] user-reserved
|
||||
_bitequate 20, M68pdInHTAB ; [11 UR] (reserved bit) page in PowerPC HTAB
|
||||
_bitequate 21, M68pdGlobal ; [10 G] page immune to PFLUSH (unused?)
|
||||
_bitequate 22, M68pdFrozenUsed ; [9 U1] copied from Used by VMLRU
|
||||
_bitequate 23, M68pdU0 ; [8 U0] in 68k arch
|
||||
_bitequate 23, M68pdShouldClean ; [8 U0] set whenever VMShouldClean returns 1
|
||||
_bitequate 24, M68pdSupProtect ; [7 S] supervisor access only
|
||||
_bitequate 25, M68pdCacheMode1 ; [6 CM1] like PPC Inhibcache
|
||||
_bitequate 26, M68pdCacheMode0 ; [5 CM0] like inverse of PPC Writethru
|
||||
_bitequate 25, M68pdCacheinhib ; [6 CM1] like PPC Inhibcache
|
||||
_bitequate 26, M68pdCacheNotIO ; [5 CM0] like inverse of PPC Writethru
|
||||
_bitequate 27, M68pdModified ; [4 M] like PPC Change
|
||||
_bitequate 28, M68pdUsed ; [3 U] like PPC Reference
|
||||
_bitequate 29, M68pdWriteProtect ; [2 WP] ?unused
|
||||
_bitequate 30, M68pdIndirect ; [1 PDT1]
|
||||
_bitequate 29, M68pdWriteProtect ; [2 WP]
|
||||
_bitequate 30, M68pdIndirect ; [1 PDT1] would make this a ptr to another PD (not used)
|
||||
_bitequate 31, M68pdResident ; [0 PDT0]
|
||||
|
||||
; Cache Mode (CM) bits:
|
||||
|
@ -205,8 +205,8 @@ discontiguous physical backing.
|
|||
; 01 Cachable,Copyback
|
||||
; 10 Noncachable,Serialized
|
||||
; 11 Noncachable
|
||||
; Therefore CM1 should match PPC Inhibcache,
|
||||
; and CM0 should be inverse of PPC Writethru
|
||||
; Therefore CM1 (M68pdCacheinhib) should match PPC Inhibcache,
|
||||
; and CM0 (M68pdCacheNotIO) should be inverse of PPC Writethru
|
||||
|
||||
; User Page Attribute (U) bits:
|
||||
; In the 68k arch these are user-defined, but they are exposed on
|
||||
|
@ -364,9 +364,9 @@ VecTblAlternate ds VecTbl ; 420:4e0 ; native PowerPC in blue task
|
|||
VecTblMemRetry ds VecTbl ; 4e0:5a0 ; "FDP" instruction emulation
|
||||
|
||||
FloatScratch ds.d 1 ; 5a0:5a8
|
||||
TopOfFreePages ds.l 1 ; 5a8 ; gotten from the old SPRG0
|
||||
ds.l 1 ; 5a8
|
||||
ds.l 1 ; 5ac
|
||||
PARPerSegmentPLEPtrs ds.l 4 ; 5b0:5c0 ; for each PAR segment, a ptr into the PAR PageList
|
||||
SegmentPageArrays ds.l 4 ; 5b0:5c0 ; for each PAR segment, a ptr into the PAR PageList
|
||||
FloatingPtTemp1 ds.l 1 ; 5c0
|
||||
FloatingPtTemp2 ds.l 1 ; 5c4
|
||||
|
||||
|
@ -382,7 +382,7 @@ ConfigInfoPtr ds.l 1 ; 630
|
|||
EDPPtr ds.l 1 ; 634
|
||||
KernelMemoryBase ds.l 1 ; 638
|
||||
KernelMemoryEnd ds.l 1 ; 63c
|
||||
LowMemPtr ds.l 1 ; 640 ; physical address of PAR Low Memory
|
||||
LowMemPtr ds.l 1 ; 640 ; physical address of MacOS Low Memory
|
||||
SharedMemoryAddr ds.l 1 ; 644 ; debug?
|
||||
EmuKCallTblPtrLogical ds.l 1 ; 648
|
||||
CodeBase ds.l 1 ; 64c
|
||||
|
@ -410,7 +410,7 @@ PTEGMask ds.l 1 ; 6a0
|
|||
HTABORG ds.l 1 ; 6a4
|
||||
VMLogicalPages ds.l 1 ; 6a8 ; size of VM Manager's address space
|
||||
VMPhysicalPages ds.l 1 ; 6ac ; how many pages VM Manager may use
|
||||
VMPageArray ds.l 1 ; 6b0 ; array of 68k Page Table Entries
|
||||
VMPageArray ds.l 1 ; 6b0 ; array of 68k Page Descriptors
|
||||
|
||||
org 0x700
|
||||
CrashTop
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
|
||||
; This file is a horrible mess. It needs a do-over.
|
||||
|
||||
ispaged equ cr4_lt
|
||||
|
||||
;r4=pg, r9=areapgcnt // cr[16]=ispaged, r16/r15/cr[20-31]=68kPTE/ptr/attrs, r8/r9/r14=PTE-hi/lo/ptr
|
||||
|
||||
; Registers used throughout: (maybe we'll just call these "conventions")
|
||||
vmrMisc1 equ r8
|
||||
vmrMisc2 equ r9
|
||||
|
@ -71,8 +67,8 @@ VMTab ; Placeholders indented
|
|||
vmtabLine vmRet ; 16 VMFlushCodeCache: wack the code cache
|
||||
vmtabLine VMMakePageCacheable ; 17 VMMakePageCacheable: make it so...
|
||||
vmtabLine VMMakePageNonCacheable ; 18 VMMakePageNonCacheable: make it so...
|
||||
vmtabLine getPTEntryGivenPage ; 19 getPTEntryGivenPage: given a page, get its 68K PTE
|
||||
vmtabLine setPTEntryGivenPage ; 20 setPTEntryGivenPage: given a page & 68K pte, set the real PTE
|
||||
vmtabLine VMGetPTEntryGivenPage ; 19 VMGetPTEntryGivenPage: given a page, get its 68K PTE
|
||||
vmtabLine VMSetPTEntryGivenPage ; 20 VMSetPTEntryGivenPage: given a page & 68K pte, set the real PTE
|
||||
vmtabLine VMPTest ; 21 VMPTest: ask why we got this page fault
|
||||
vmtabLine VMLRU ; 22 VMLRU: least recently used?
|
||||
vmtabLine VMMarkUndefined ; 23 VMMarkUndefined
|
||||
|
@ -101,7 +97,7 @@ vmRet
|
|||
|
||||
VMInit
|
||||
lwz r7, KDP.VMPageArray(r1) ; check that zero seg isn't empty
|
||||
lwz r8, KDP.PARPerSegmentPLEPtrs + 0(r1)
|
||||
lwz r8, KDP.SegmentPageArrays + 0(r1)
|
||||
cmpw r7, r8
|
||||
bne vmRet1
|
||||
|
||||
|
@ -126,7 +122,7 @@ VMInit_BigLoop
|
|||
bne VMInit_0x110
|
||||
bnel cr1, SystemCrash
|
||||
rlwinm r15, r8, 22, 0, 29
|
||||
addi r3, r1, KDP.PARPerSegmentPLEPtrs
|
||||
addi r3, r1, KDP.SegmentPageArrays
|
||||
rlwimi r3, r5, 2, 28, 29
|
||||
stw r15, 0x0000(r3)
|
||||
slwi r3, r5, 16
|
||||
|
@ -155,7 +151,7 @@ VMInit_0xa8
|
|||
cmpw r3, r4
|
||||
bnel SystemCrash
|
||||
; bl RemovePageFromTLB
|
||||
bl RemovePTEFromHTAB
|
||||
bl DeletePTE
|
||||
|
||||
VMInitple_or_pte0
|
||||
cmpwi r7, 0x00
|
||||
|
@ -202,13 +198,13 @@ VMInit_0x110
|
|||
blt VMInit_Fail
|
||||
|
||||
srwi r7, r5, 12
|
||||
bl major_0x09c9c
|
||||
bl QuickGetPhysical
|
||||
stw r9, KDP.VMPageArray(r1)
|
||||
mr r15, r9
|
||||
srwi r7, r5, 12
|
||||
add r7, r7, r6
|
||||
addi r7, r7, -0x01
|
||||
bl major_0x09c9c
|
||||
bl QuickGetPhysical
|
||||
subf r9, r15, r9
|
||||
srwi r9, r9, 12
|
||||
addi r9, r9, 0x01
|
||||
|
@ -234,7 +230,7 @@ VMInit_0x1d4
|
|||
VMInit_0x1ec
|
||||
subi r6, r6, 4
|
||||
srwi r7, r6, 2
|
||||
bl major_0x09c9c
|
||||
bl QuickGetPhysical
|
||||
cmpwi r6, 0x00
|
||||
ori r16, r9, 0x21
|
||||
stwx r16, r15, r6
|
||||
|
@ -295,7 +291,7 @@ VMInit_0x29c
|
|||
|
||||
VMInit_Fail
|
||||
lwz r7, KDP.VMPhysicalPages(r1)
|
||||
lwz r8, KDP.PARPerSegmentPLEPtrs + 0(r1)
|
||||
lwz r8, KDP.SegmentPageArrays + 0(r1)
|
||||
stw r7, KDP.VMLogicalPages(r1)
|
||||
stw r8, KDP.VMPageArray(r1)
|
||||
|
||||
|
@ -305,24 +301,24 @@ VMInit_Fail
|
|||
|
||||
VMExchangePages
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1 ; must be in pageable area
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area
|
||||
bc BO_IF, 21, vmRetNeg1
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1 ; must be resident
|
||||
bc BO_IF, bM68pdCacheMode1, vmRetNeg1 ; must not have special properties
|
||||
bc BO_IF_NOT, bM68pdCacheMode0, vmRetNeg1
|
||||
bcl BO_IF, M68pdInHTAB, RemovePTEFromHTAB ; if in HTAB, must be removed
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1 ; must be resident
|
||||
bc BO_IF, bM68pdCacheinhib, vmRetNeg1 ; must not have special properties
|
||||
bc BO_IF_NOT, bM68pdCacheNotIO, vmRetNeg1
|
||||
bcl BO_IF, bM68pdInHTAB, DeletePTE ; if in HTAB, must be removed
|
||||
mr r6, r15 ; r6 = src 68k PTE ptr
|
||||
|
||||
mr r4, r5
|
||||
mr r5, r16 ; r5 = src 68k PTE
|
||||
lwz r9, KDP.VMLogicalPages(r1)
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1
|
||||
bc BO_IF, 21, vmRetNeg1
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1
|
||||
bc BO_IF, bM68pdCacheMode1, vmRetNeg1
|
||||
bc BO_IF_NOT, bM68pdCacheMode0, vmRetNeg1
|
||||
bcl BO_IF, M68pdInHTAB, RemovePTEFromHTAB
|
||||
bc BO_IF, bM68pdCacheinhib, vmRetNeg1
|
||||
bc BO_IF_NOT, bM68pdCacheNotIO, vmRetNeg1
|
||||
bcl BO_IF, bM68pdInHTAB, DeletePTE
|
||||
|
||||
stw r5, 0(r15) ; swap 68k PTEs (in that big flat list)
|
||||
stw r16, 0(r6)
|
||||
|
@ -352,7 +348,7 @@ VMGetPhysicalPage
|
|||
|
||||
########################################################################
|
||||
|
||||
getPTEntryGivenPage
|
||||
VMGetPTEntryGivenPage
|
||||
bl PageInfo
|
||||
mr r3, r16
|
||||
bc BO_IF_NOT, bM68pdResident, vmRet
|
||||
|
@ -384,14 +380,14 @@ VMIsUnmodified
|
|||
|
||||
########################################################################
|
||||
|
||||
VMLRU ; For each resident page: save Update bit and clear original
|
||||
VMLRU ; For each resident page: save Used bit and clear original
|
||||
slwi r9, r9, 2 ; (r9 is VMLogicalPages)
|
||||
lwz r15, KDP.VMPageArray(r1)
|
||||
lwz r14, KDP.HTABORG(r1)
|
||||
add r15, r15, r9 ; r15 = loop PageArray ptr
|
||||
srwi r4, r9, 2 ; r4 = loop counter
|
||||
|
||||
li r5, LpteReference ; for clearing bits with andc
|
||||
li r5, LpteReference ; r5/r6 or clearing bits with andc
|
||||
li r6, M68pdUsed
|
||||
|
||||
@loop ; over every logical page
|
||||
|
@ -408,12 +404,12 @@ VMLRU ; For each resident page: save Update bit and clear original
|
|||
lwz r9, 4(r14) ; bit back to 68k PTE and clear
|
||||
_mvbit r16, bM68pdUsed, r9, bLpteReference
|
||||
andc r9, r9, r5
|
||||
bl ChangeNativeLowerPTE
|
||||
bl SaveLowerPTE
|
||||
subf r14, r7, r14
|
||||
@not_in_htab
|
||||
|
||||
_mvbit r16, bM68pdFrozenUsed, r16, bM68pdUsed
|
||||
andc r16, r16, r6 ; save Update and clear original
|
||||
andc r16, r16, r6 ; save Used and clear original
|
||||
stw r16, 0(r15) ; save changed 68k PTE
|
||||
@nonresident
|
||||
|
||||
|
@ -423,194 +419,210 @@ VMLRU ; For each resident page: save Update bit and clear original
|
|||
########################################################################
|
||||
|
||||
VMMakePageCacheable
|
||||
; PPC: W=0, I=0
|
||||
; 68k: Nonwritethru=0, Inhibcache=0
|
||||
; PPC: LpteWritethru(W)=0, LpteInhibcache(I)=0
|
||||
; 68k: M68pdCacheNotIO(CM0)=1, M68pdCacheinhib(CM1)=0 ["Cachable,Copyback"]
|
||||
bl PageInfo
|
||||
rlwinm r7, r16, 0, M68pdCacheMode1 | M68pdCacheMode0
|
||||
cmpwi r7, M68pdCacheMode0
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1
|
||||
beq vmRet
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
rlwinm r7, r16, 0, M68pdCacheNotIO | M68pdCacheinhib ; test CM0/CM1
|
||||
cmpwi r7, M68pdCacheNotIO
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1 ; not resident!
|
||||
beq vmRet ; already write-through
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area, so fail!
|
||||
|
||||
bcl BO_IF_NOT, M68pdInHTAB, VMSecondLastExportedFunc
|
||||
bcl BO_IF_NOT, bM68pdInHTAB, QuickCalcPTE ; need to have a PPC PTE
|
||||
|
||||
rlwinm r16, r16, 0, ~(M68pdCacheMode1 | M68pdCacheMode0)
|
||||
rlwinm r16, r16, 0, ~(M68pdCacheinhib | M68pdCacheNotIO)
|
||||
rlwinm r9, r9, 0, ~(LpteWritethru | LpteInhibcache)
|
||||
ori r16, r16, M68pdCacheMode0
|
||||
bl ChangeNativeAnd68kPTEs
|
||||
ori r16, r16, M68pdCacheNotIO
|
||||
bl SavePTEAnd68kPD
|
||||
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMMakePageWriteThrough
|
||||
; PPC: LpteWritethru(W)=1, LpteInhibcache(I)=0
|
||||
; 68k: M68pdCacheNotIO(CM0)=0, M68pdCacheinhib(CM1)=0 ["Cachable,Write-through"]
|
||||
bl PageInfo
|
||||
rlwinm. r7, r16, 0, 25, 26
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1
|
||||
beq vmRet
|
||||
bc BO_IF_NOT, ispaged, VMMakePageWriteThrough_0x3c
|
||||
bcl BO_IF_NOT, M68pdInHTAB, VMSecondLastExportedFunc
|
||||
rlwinm r16, r16, 0, 27, 24
|
||||
rlwinm r9, r9, 0, 27, 24
|
||||
ori r9, r9, 0x40
|
||||
bl ChangeNativeAnd68kPTEs
|
||||
b VMMakePageNonCacheable_0x3c
|
||||
rlwinm. r7, r16, 0, M68pdCacheNotIO | M68pdCacheinhib ; test CM0/CM1
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1 ; not resident!
|
||||
beq vmRet ; already write-through
|
||||
bc BO_IF_NOT, cr4_lt, @not_paged ; not a paged area, so use PMDT!
|
||||
|
||||
VMMakePageWriteThrough_0x3c
|
||||
rlwinm r7, r4, 16, 28, 31
|
||||
cmpwi r7, 0x09
|
||||
bcl BO_IF_NOT, bM68pdInHTAB, QuickCalcPTE ; need to have a PPC PTE
|
||||
|
||||
rlwinm r16, r16, 0, ~(M68pdCacheNotIO | M68pdCacheinhib)
|
||||
rlwinm r9, r9, 0, ~(LpteWritethru | LpteInhibcache)
|
||||
ori r9, r9, LpteWritethru
|
||||
bl SavePTEAnd68kPD
|
||||
|
||||
b FlushPageAndReturn
|
||||
|
||||
@not_paged ; so try to find a free PMDT to use (quite messy)
|
||||
rlwinm r7, r4, 16, 0xF ; address must be in segments 8-F
|
||||
cmpwi r7, 9
|
||||
blt vmRetNeg1
|
||||
bc BO_IF_NOT, M68pdCacheMode1, vmRetNeg1
|
||||
lwz r5, 0x000c(r15)
|
||||
andi. r6, r5, 0xe01
|
||||
cmpwi r6, 0xa01
|
||||
beq VMMakePageWriteThrough_0xec
|
||||
addi r15, r15, -0x08
|
||||
lwz r5, 0x0004(r15)
|
||||
lhz r6, 0x0000(r15)
|
||||
andi. r5, r5, 0xc00
|
||||
lhz r5, 0x0002(r15)
|
||||
bne vmRetNeg1
|
||||
addi r5, r5, 0x01
|
||||
|
||||
bc BO_IF_NOT, M68pdCacheinhib, vmRetNeg1 ; must already be cache-inhibited??
|
||||
|
||||
lwz r5, PMDT.Size + PMDT.Word2(r15) ; take over the following PMDT if
|
||||
andi. r6, r5, EveryPattr ; it is "available"
|
||||
cmpwi r6, PMDT_Available
|
||||
beq @next_pmdt_free
|
||||
|
||||
; no free PMDT... hijack the previous one if it is PMDT_PTE_Range
|
||||
subi r15, r15, PMDT.Size
|
||||
lwz r5, PMDT.Word2(r15)
|
||||
lhz r6, PMDT.PageIdx(r15)
|
||||
andi. r5, r5, Pattr_NotPTE | Pattr_PTE_Single
|
||||
lhz r5, PMDT.PageCount(r15)
|
||||
bne vmRetNeg1 ; demand PMDT_PTE_Range
|
||||
addi r5, r5, 1
|
||||
add r6, r6, r5
|
||||
xor r6, r6, r4
|
||||
andi. r6, r6, 0xffff
|
||||
andi. r6, r6, 0xffff ; does the previous PMDT abut this one?
|
||||
bne vmRetNeg1
|
||||
sth r5, 0x0002(r15)
|
||||
b PageSetCommon
|
||||
sth r5, PMDT.PageCount(r15)
|
||||
b @edited_pmdt
|
||||
|
||||
VMMakePageWriteThrough_0xec
|
||||
lwz r5, 0x0000(r15)
|
||||
lwz r6, 0x0004(r15)
|
||||
stw r5, 0x0008(r15)
|
||||
stw r6, 0x000c(r15)
|
||||
slwi r5, r4, 16
|
||||
stw r5, 0x0000(r15)
|
||||
slwi r5, r4, 12
|
||||
ori r5, r5, 0x42
|
||||
stw r5, 0x0004(r15)
|
||||
@next_pmdt_free ; so replace it with copy of current one, then turn current one into PMDT_PTE_Range
|
||||
lwz r5, 0(r15) ; copy current PMDT to next
|
||||
lwz r6, 4(r15)
|
||||
stw r5, PMDT.Size + 0(r15)
|
||||
stw r6, PMDT.Size + 4(r15)
|
||||
|
||||
########################################################################
|
||||
slwi r5, r4, 16 ; PMDT PageIdx=this, PageCount=single
|
||||
stw r5, 0(r15)
|
||||
slwi r5, r4, 12 ; PMDT RPN = logical address of page
|
||||
ori r5, r5, LpteWritethru | LpteP0 ; and raise these flags too
|
||||
stw r5, PMDT.Word2(r15)
|
||||
|
||||
PageSetCommon
|
||||
lwz r15, KDP.PTEGMask(r1)
|
||||
@edited_pmdt ; now to delete any existing PTE derived from the original PMDT
|
||||
lwz r15, KDP.PTEGMask(r1) ; hash to find the PTEG
|
||||
lwz r14, KDP.HTABORG(r1)
|
||||
slwi r6, r4, 12
|
||||
mfsrin r6, r6
|
||||
rlwinm r8, r6, 7, 0, 20
|
||||
rlwinm r8, r6, 7, UpteValid | UpteVSID
|
||||
xor r6, r6, r4
|
||||
slwi r7, r6, 6
|
||||
slwi r7, r6, 6
|
||||
and r15, r15, r7
|
||||
rlwimi r8, r4, 22, 26, 31
|
||||
crset cr0_eq
|
||||
oris r8, r8, 0x8000
|
||||
rlwimi r8, r4, 22, UpteAPI
|
||||
crset cr0_eq ; clear cr0_eq when trying the secondary hash
|
||||
oris r8, r8, UpteValid ; r8 = the exact upper PTE word to search
|
||||
|
||||
PageSetCommon_0x2c
|
||||
lwzux r7, r14, r15
|
||||
lwz r15, 0x0008(r14)
|
||||
lwz r6, 0x0010(r14)
|
||||
lwz r5, 0x0018(r14)
|
||||
@secondary_hash
|
||||
lwzux r7, r14, r15 ; search the primary or secondary PTEG for r8
|
||||
lwz r15, 8(r14)
|
||||
lwz r6, 16(r14)
|
||||
lwz r5, 24(r14)
|
||||
cmplw cr1, r7, r8
|
||||
cmplw cr2, r15, r8
|
||||
cmplw cr3, r6, r8
|
||||
cmplw cr4, r5, r8
|
||||
beq cr1, PageSetCommon_0xc8
|
||||
beq cr2, PageSetCommon_0xc4
|
||||
beq cr3, PageSetCommon_0xc0
|
||||
beq cr4, PageSetCommon_0xbc
|
||||
lwzu r7, 0x0020(r14)
|
||||
lwz r15, 0x0008(r14)
|
||||
lwz r6, 0x0010(r14)
|
||||
lwz r5, 0x0018(r14)
|
||||
beq cr1, @pte_at_r14
|
||||
beq cr2, @pte_at_r14_plus_8
|
||||
beq cr3, @pte_at_r14_plus_16
|
||||
beq cr4, @pte_at_r14_plus_24
|
||||
lwzu r7, 32(r14)
|
||||
lwz r15, 8(r14)
|
||||
lwz r6, 16(r14)
|
||||
lwz r5, 24(r14)
|
||||
cmplw cr1, r7, r8
|
||||
cmplw cr2, r15, r8
|
||||
cmplw cr3, r6, r8
|
||||
cmplw cr4, r5, r8
|
||||
beq cr1, PageSetCommon_0xc8
|
||||
beq cr2, PageSetCommon_0xc4
|
||||
beq cr3, PageSetCommon_0xc0
|
||||
beq cr4, PageSetCommon_0xbc
|
||||
crnot 2, 2
|
||||
beq cr1, @pte_at_r14
|
||||
beq cr2, @pte_at_r14_plus_8
|
||||
beq cr3, @pte_at_r14_plus_16
|
||||
beq cr4, @pte_at_r14_plus_24
|
||||
|
||||
crnot cr0_eq, cr0_eq ; can't find it => try again with secondary hash
|
||||
lwz r15, KDP.PTEGMask(r1)
|
||||
lwz r14, KDP.HTABORG(r1)
|
||||
slwi r6, r4, 12
|
||||
mfsrin r6, r6
|
||||
xor r6, r6, r4
|
||||
not r6, r6
|
||||
slwi r7, r6, 6
|
||||
slwi r7, r6, 6
|
||||
and r15, r15, r7
|
||||
xori r8, r8, 0x40
|
||||
bne PageSetCommon_0x2c
|
||||
xori r8, r8, UpteHash
|
||||
bc BO_IF_NOT, cr0_eq, @secondary_hash
|
||||
b vmRet
|
||||
|
||||
PageSetCommon_0xbc
|
||||
addi r14, r14, 0x08
|
||||
|
||||
PageSetCommon_0xc0
|
||||
addi r14, r14, 0x08
|
||||
|
||||
PageSetCommon_0xc4
|
||||
addi r14, r14, 0x08
|
||||
|
||||
PageSetCommon_0xc8
|
||||
; bl RemovePageFromTLB
|
||||
li r8, 0x00
|
||||
li r9, 0x00
|
||||
bl ChangeNativePTE
|
||||
@pte_at_r14_plus_24
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14_plus_16
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14_plus_8
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14 ; found PTE based on original PMDT => delete it
|
||||
li r8, 0
|
||||
li r9, 0
|
||||
bl SavePTE
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMMakePageNonCacheable
|
||||
VMMakePageNonCacheable ; set WI=01 and CM0/CM1=11
|
||||
bl PageInfo
|
||||
rlwinm r7, r16, 0, 25, 26
|
||||
cmpwi r7, 0x60
|
||||
rlwinm r7, r16, 0, M68pdCacheNotIO | M68pdCacheinhib
|
||||
cmpwi r7, M68pdCacheNotIO | M68pdCacheinhib ; these should both end up set
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1
|
||||
beq vmRet
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
bl BO_IF_NOT, 20, VMSecondLastExportedFunc
|
||||
rlwinm r9, r9, 0, 27, 24
|
||||
ori r16, r16, 0x60
|
||||
ori r9, r9, 0x20
|
||||
bl ChangeNativeAnd68kPTEs
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area
|
||||
|
||||
VMMakePageNonCacheable_0x3c
|
||||
rlwinm r4, r9, 0, 0, 19
|
||||
addi r5, r4, 0x20
|
||||
li r7, 0x1000
|
||||
li r8, 0x40
|
||||
bcl BO_IF_NOT, bM68pdInHTAB, QuickCalcPTE
|
||||
|
||||
VMMakePageNonCacheable_0x50
|
||||
rlwinm r9, r9, 0, ~(LpteWritethru | LpteInhibcache)
|
||||
ori r16, r16, M68pdCacheNotIO | M68pdCacheinhib
|
||||
ori r9, r9, LpteInhibcache
|
||||
|
||||
bl SavePTEAnd68kPD
|
||||
; Fall through to FlushPageAndReturn
|
||||
|
||||
########################################################################
|
||||
|
||||
FlushPageAndReturn ; When making page write-though or noncacheable
|
||||
rlwinm r4, r9, 0, 0xFFFFF000
|
||||
addi r5, r4, 32
|
||||
li r7, 0x1000
|
||||
li r8, 64
|
||||
@loop
|
||||
subf. r7, r8, r7
|
||||
dcbf r7, r4
|
||||
dcbf r7, r5
|
||||
bne VMMakePageNonCacheable_0x50
|
||||
bne @loop
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMMarkBacking
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
bc BO_IF, 21, vmRetNeg1
|
||||
bcl BO_IF, M68pdInHTAB, RemovePTEFromHTAB
|
||||
rlwimi r16, r5, 16, 15, 15
|
||||
li r7, 0x01
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area
|
||||
bc BO_IF, bM68pdGlobal, vmRetNeg1
|
||||
|
||||
bcl BO_IF, bM68pdInHTAB, DeletePTE
|
||||
|
||||
_mvbit r16, 15, r5, 31
|
||||
li r7, M68pdResident
|
||||
andc r16, r16, r7
|
||||
stw r16, 0x0000(r15)
|
||||
stw r16, 0(r15)
|
||||
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMMarkCleanUnused
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area
|
||||
bc BO_IF_NOT, bM68pdResident, vmRetNeg1
|
||||
bl BO_IF_NOT, 20, VMSecondLastExportedFunc
|
||||
li r7, 0x180
|
||||
|
||||
bcl BO_IF_NOT, bM68pdInHTAB, QuickCalcPTE
|
||||
|
||||
li r7, LpteReference | LpteChange
|
||||
andc r9, r9, r7
|
||||
ori r16, r16, 0x100
|
||||
bl ChangeNativeAnd68kPTEs
|
||||
ori r16, r16, M68pdModified
|
||||
bl SavePTEAnd68kPD
|
||||
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
@ -638,84 +650,97 @@ VMMarkUndefined_0x28
|
|||
|
||||
########################################################################
|
||||
|
||||
VMMarkResident
|
||||
VMMarkResident ; physical page number in a0/r5
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
bc BO_IF, bM68pdResident, vmRetNeg1
|
||||
bcl BO_IF, M68pdInHTAB, SystemCrash
|
||||
rlwimi r16, r5, 12, 0, 19
|
||||
ori r16, r16, 0x01
|
||||
stw r16, 0x0000(r15)
|
||||
bl VMSecondLastExportedFunc
|
||||
bl ChangeNativeAnd68kPTEs
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area!
|
||||
bc BO_IF, bM68pdResident, vmRetNeg1 ; already resident!
|
||||
bcl BO_IF, bM68pdInHTAB, SystemCrash ; corrupt 68k PD!
|
||||
|
||||
rlwimi r16, r5, 12, 0xFFFFF000 ; make up a 68k PD
|
||||
ori r16, r16, M68pdResident ; save it
|
||||
stw r16, 0(r15)
|
||||
|
||||
bl QuickCalcPTE ; make up a PPC PTE
|
||||
bl SavePTEAnd68kPD ; save it
|
||||
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMPTest
|
||||
srwi r4, r4, 12
|
||||
VMPTest ; return reason for fault on page a0/r4, based on action in d1/r6
|
||||
srwi r4, r4, 12 ; because it was outside a paged area?
|
||||
cmplw r4, r9
|
||||
li r3, 0x4000
|
||||
li r3, 1 << 14
|
||||
bge vmRet
|
||||
bl PageInfo
|
||||
li r3, 0x400
|
||||
|
||||
bl PageInfo ; because the page was non-resident?
|
||||
li r3, 1 << 10
|
||||
bc BO_IF_NOT, bM68pdResident, vmRet
|
||||
li r3, 0x00
|
||||
ori r3, r3, 0x8000
|
||||
|
||||
li r3, 0 ; unknown!
|
||||
ori r3, r3, 1 << 15
|
||||
bc BO_IF_NOT, bM68pdWriteProtect, vmRet
|
||||
cmpwi r6, 0x00
|
||||
cmpwi r6, 0
|
||||
beq vmRet
|
||||
li r3, 0x800
|
||||
b vmRet
|
||||
|
||||
li r3, 1 << 11 ; because wrote to write-protected page
|
||||
b vmRet ; (requires d1/r6 to be non-zero)
|
||||
|
||||
########################################################################
|
||||
|
||||
setPTEntryGivenPage
|
||||
VMSetPTEntryGivenPage
|
||||
mr r6, r4
|
||||
mr r4, r5
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
xor r7, r16, r6
|
||||
li r3, 0x461
|
||||
rlwimi r3, r16, 24, 29, 29
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area
|
||||
|
||||
xor r7, r16, r6 ; r17 = bits to be changed
|
||||
|
||||
; cannot change G/CM0/CM1/PTD0 with this call
|
||||
li r3, M68pdGlobal | M68pdCacheinhib | M68pdCacheNotIO | M68pdResident
|
||||
_mvbit r3, bM68pdWriteProtect, r16, bM68pdGlobal ; cannot change WP if G is set
|
||||
and. r3, r3, r7
|
||||
bne vmRetNeg1
|
||||
andi. r7, r7, 0x11c
|
||||
xor r16, r16, r7
|
||||
stw r16, 0x0000(r15)
|
||||
bc BO_IF_NOT, bM68pdInHTAB, vmRet
|
||||
rlwimi r9, r16, 5, 23, 23
|
||||
rlwimi r9, r16, 3, 24, 24
|
||||
rlwimi r9, r16, 30, 31, 31
|
||||
bl ChangeNativeLowerPTE
|
||||
bne vmRetNeg1 ; fail if trying to change a forbidden bit
|
||||
|
||||
andi. r7, r7, M68pdShouldClean | M68pdModified | M68pdUsed | M68pdWriteProtect
|
||||
xor r16, r16, r7 ; silently refuse to change U0/M/U/WP
|
||||
stw r16, 0(r15) ; save new 68k PD
|
||||
|
||||
bc BO_IF_NOT, bM68pdInHTAB, vmRet ; edit PPC PTE if applicable
|
||||
_mvbit r9, bLpteReference, r16, bM68pdUsed
|
||||
_mvbit r9, bLpteChange, r16, bM68pdModified
|
||||
_mvbit r9, bLpteP1, r16, bM68pdWriteProtect
|
||||
bl SaveLowerPTE
|
||||
b vmRet
|
||||
|
||||
########################################################################
|
||||
|
||||
VMShouldClean
|
||||
VMShouldClean ; is this page is a good candidate for writing to disk?
|
||||
bl PageInfo
|
||||
bc BO_IF_NOT, bM68pdResident, vmRet0
|
||||
bc BO_IF, bM68pdUsed, vmRet0
|
||||
bc BO_IF_NOT, bM68pdModified, vmRet0
|
||||
bc BO_IF_NOT, ispaged, vmRetNeg1
|
||||
xori r16, r16, 0x10
|
||||
ori r16, r16, 0x100
|
||||
stw r16, 0x0000(r15)
|
||||
bc BO_IF_NOT, bM68pdInHTAB, vmRet1
|
||||
xori r9, r9, 0x80
|
||||
bl ChangeNativeLowerPTE
|
||||
b vmRet1
|
||||
bc BO_IF_NOT, bM68pdResident, vmRet0 ; already paged out: no
|
||||
bc BO_IF, bM68pdUsed, vmRet0 ; been read recently: no
|
||||
bc BO_IF_NOT, bM68pdModified, vmRet0 ; unwritten ('clean'): no
|
||||
bc BO_IF_NOT, cr4_lt, vmRetNeg1 ; not a paged area: error
|
||||
|
||||
xori r16, r16, M68pdModified ; clear 68k-PD[M]
|
||||
ori r16, r16, M68pdShouldClean ; set user-defined bit
|
||||
stw r16, 0(r15)
|
||||
|
||||
bc BO_IF_NOT, bM68pdInHTAB, vmRet1 ; clear PPC-PTE[C]
|
||||
xori r9, r9, LpteChange ; (if necessary)
|
||||
bl SaveLowerPTE
|
||||
b vmRet1 ; return yes!
|
||||
|
||||
########################################################################
|
||||
|
||||
VMAllocateMemory
|
||||
lwz r7, KDP.VMPageArray(r1)
|
||||
lwz r8, KDP.PARPerSegmentPLEPtrs + 0(r1)
|
||||
lwz r8, KDP.SegmentPageArrays + 0(r1)
|
||||
cmpwi cr6, r5, 0x00
|
||||
cmpw cr7, r7, r8
|
||||
or r7, r4, r6
|
||||
rlwinm. r7, r7, 0, 0, 11
|
||||
bc BO_IF_NOT, M68pdCacheMode1, vmRetNeg1
|
||||
bc BO_IF_NOT, M68pdCacheinhib, vmRetNeg1
|
||||
lwz r9, KDP.VMLogicalPages(r1)
|
||||
bne cr7, vmRetNeg1
|
||||
mr r7, r4
|
||||
|
@ -727,7 +752,7 @@ VMAllocateMemory
|
|||
VMAllocateMemory_0x74
|
||||
addi r4, r4, -0x01
|
||||
bl PageInfo
|
||||
bcl BO_IF, M68pdInHTAB, RemovePTEFromHTAB
|
||||
bcl BO_IF, bM68pdInHTAB, DeletePTE
|
||||
lwz r9, KDP.VMLogicalPages(r1)
|
||||
subf r8, r4, r9
|
||||
cmplw cr7, r5, r8
|
||||
|
@ -838,21 +863,30 @@ VMAllocateMemory_0x324
|
|||
|
||||
########################################################################
|
||||
|
||||
; This function gets sent an page for a page in the main mac os memory
|
||||
; area and returns a bunch of useful info on it. Return values that
|
||||
; mention HTAB are undefined when the PTE is not in the HTAB HTAB
|
||||
; residence is determined by bit 20 (value 0x800) of the PTE. This is
|
||||
; often checked by a bltl cr5
|
||||
; Given the index of a page (r4/A0), this function queries its 68k Page
|
||||
; Descriptor (PD) and, if it is currently in the HTAB, its PowerPC Page
|
||||
; Table Entry (PTE). This information is returned in registers, with the
|
||||
; attribute flags of the 68k PD additionally placed in Condition Register
|
||||
; bits for easy testing. The page must be within the VM address space
|
||||
; (i.e. < VMLogicalPages), or cr4_lt will be cleared to indicate an error.
|
||||
; VMLogicalPages must be passed in r9 (as set by VMDispatch).
|
||||
|
||||
; Individual VM calls usually BL straight to this function.
|
||||
; Return values:
|
||||
; if in paged area: cr4_lt = 1
|
||||
; r16/r15/cr5-7 = 68k Page Descriptor [PD/pointer/attr-bits]
|
||||
; r8/r9/r14 = PowerPC Page Table Entry [PTE-high/PTE-low/pointer]
|
||||
;
|
||||
; if not paged: cr4_lt = 0
|
||||
; r16/cr5-7 = fake 68k Page Descriptor [PD/attr-bits]
|
||||
; r15 = PMDT pointer
|
||||
|
||||
PageInfo ; r4=pg, r9=areapgcnt // cr[16]=ispaged, r16/r15/cr[20-31]=68kPTE/ptr/attrs, r8/r9/r14=PTE-hi/lo/ptr
|
||||
PageInfo
|
||||
cmplw cr4, r4, r9
|
||||
lwz r15, KDP.VMPageArray(r1) ; r15 = Page List base
|
||||
slwi r8, r4, 2 ; r18 = Page List Entry offset
|
||||
bge cr4, @not_par
|
||||
|
||||
@ple_or_pte ;
|
||||
@paged ;
|
||||
lwzux r16, r15, r8 ; Get Page List Entry (will return ptr in r15)
|
||||
lwz r14, KDP.HTABORG(r1) ; ...which might point to a Page Table Entry
|
||||
mtcrf %00000111, r16 ; Set all flags in CR (but not RealPgNum)
|
||||
|
@ -896,49 +930,43 @@ PageInfo ; r4=pg, r9=areapgcnt // cr[16]=ispaged, r16/r15/cr[20-31]=68kPTE/ptr/a
|
|||
andi. r16, r9, Pattr_NotPTE | Pattr_PTE_Single
|
||||
cmpwi cr6, r16, Pattr_PTE_Single
|
||||
cmpwi cr7, r16, Pattr_NotPTE | Pattr_PTE_Single
|
||||
beq @range
|
||||
beq cr6, @single
|
||||
beq @range_pmdt
|
||||
beq cr6, @single_pmdt
|
||||
bne cr7, vmRetNeg1
|
||||
|
||||
slwi r8, r8, 2
|
||||
rlwinm r15, r9, 22, 0, 29
|
||||
crset cr4_lt
|
||||
b @ple_or_pte
|
||||
crset cr4_lt ; return "is paged"
|
||||
b @paged
|
||||
|
||||
@range
|
||||
@range_pmdt
|
||||
slwi r8, r8, 12
|
||||
add r9, r9, r8
|
||||
@single_pmdt
|
||||
rlwinm r16, r9, 0, 0xFFFFF000 ; fabricate a 68k Page Descriptor
|
||||
crclr cr4_lt ; return "is not paged"
|
||||
rlwinm r9, r9, 0, ~PMDT_68k
|
||||
_mvbit r16, bM68pdCacheinhib, r9, bLpteInhibcache
|
||||
_mvbit r16, bM68pdCacheNotIO, r9, bLpteWritethru
|
||||
xori r16, r16, M68pdCacheNotIO
|
||||
_mvbit r16, bM68pdModified, r9, bLpteChange
|
||||
_mvbit r16, bM68pdUsed, r9, bLpteChange
|
||||
_mvbit r16, bM68pdWriteProtect, r9, bLpteP1
|
||||
ori r16, r16, M68pdResident
|
||||
|
||||
@single
|
||||
rlwinm r16, r9, 0, 0, 19
|
||||
crclr cr4_lt
|
||||
rlwinm r9, r9, 0, 22, 19
|
||||
rlwimi r16, r9, 1, 25, 25
|
||||
rlwimi r16, r9, 31, 26, 26
|
||||
xori r16, r16, 0x20
|
||||
rlwimi r16, r9, 29, 27, 27
|
||||
rlwimi r16, r9, 28, 28, 28
|
||||
rlwimi r16, r9, 2, 29, 29
|
||||
ori r16, r16, 0x01
|
||||
mtcrf %00000111, r16
|
||||
mtcrf %00000111, r16 ; extract flags from it
|
||||
blr
|
||||
|
||||
########################################################################
|
||||
|
||||
;updates stored PTE and HTAB entry for PTE
|
||||
;r16 is PTE value
|
||||
;r15 is address of stored PTE
|
||||
;r8 is lower word of HTAB entry
|
||||
;r9 is upper word of HTAB entry
|
||||
;r14 is address of HTAB entry
|
||||
ChangeNativeAnd68kPTEs
|
||||
stw r16, 0(r15)
|
||||
ChangeNativePTE
|
||||
stw r8, 0(r14)
|
||||
ChangeNativeLowerPTE
|
||||
stw r9, 4(r14) ;upper word of HTAB entry contains valid bit
|
||||
SavePTEAnd68kPD
|
||||
stw r16, 0(r15) ; save r16 (PD) into r15 (PD ptr)
|
||||
SavePTE
|
||||
stw r8, 0(r14) ; save r8 (upper PTE) into r14 (PTE ptr)
|
||||
SaveLowerPTE
|
||||
stw r9, 4(r14) ; save r9 (lower PTE) into r14 (PTE ptr) + 4
|
||||
|
||||
slwi r8, r4, 12
|
||||
slwi r8, r4, 12 ; trash TLB
|
||||
sync
|
||||
tlbie r8
|
||||
sync
|
||||
|
@ -947,95 +975,92 @@ ChangeNativeLowerPTE
|
|||
|
||||
########################################################################
|
||||
|
||||
;Removes a page from the HTAB.
|
||||
;
|
||||
;also updates NK statistics?
|
||||
;r9 is low word of HTAB entry
|
||||
;r14 ia address of HTAB entry
|
||||
;r15 is address of stored PTE
|
||||
;r16 is PTE value
|
||||
RemovePTEFromHTAB
|
||||
lwz r8, KDP.NKInfo.HashTableDeleteCount(r1);update a value in NanoKernelInfo
|
||||
rlwinm r16, r16, 0, 21, 19 ;update PTE flags to indicate not in HTAB
|
||||
addi r8, r8, 0x01
|
||||
DeletePTE
|
||||
lwz r8, KDP.NKInfo.HashTableDeleteCount(r1)
|
||||
rlwinm r16, r16, 0, 21, 19 ~M68pdInHTAB
|
||||
addi r8, r8, 1
|
||||
stw r8, KDP.NKInfo.HashTableDeleteCount(r1)
|
||||
rlwimi r16, r9, 0, 0, 19 ;move page# back into PTE
|
||||
rlwimi r16, r9, 0, 0xFFFFF000 ; edit new 68k PD
|
||||
|
||||
_clrNCBCache scr=r8
|
||||
_clrNCBCache scr=r8 ; page can now move, so clr NCBs
|
||||
|
||||
li r8, 0x00 ;0 upper HTAB word
|
||||
li r9, 0x00 ;0 lower HTAB word
|
||||
b ChangeNativeAnd68kPTEs ;update stored PTE and invalidate HTAB entry
|
||||
li r8, 0 ; zero new PPC PTE
|
||||
li r9, 0
|
||||
|
||||
b SavePTEAnd68kPD
|
||||
|
||||
########################################################################
|
||||
|
||||
VMSecondLastExportedFunc
|
||||
lwz r8, KDP.PTEGMask(r1)
|
||||
VMLastExportedFunc
|
||||
; Calculate a new PowerPC PTE for a page that is not currently in the
|
||||
; HTAB. The new PTE (and new ptr) will be in the usual r8/r9 and r14, and
|
||||
; the new 68k PD (and unchanged ptr) will be in the usual r16 and r15.
|
||||
; Because it tries a quick path but falls back on the big fat PutPTE, this
|
||||
; function may or may not actually put the PowerPC and 68k structures into
|
||||
; place. The caller must do this.
|
||||
|
||||
QuickCalcPTE
|
||||
lwz r8, KDP.PTEGMask(r1) ; Calculate hash to find PTEG
|
||||
lwz r14, KDP.HTABORG(r1)
|
||||
slwi r9, r4, 12
|
||||
mfsrin r6, r9
|
||||
xor r9, r6, r4
|
||||
slwi r7, r9, 6
|
||||
slwi r7, r9, 6
|
||||
and r8, r8, r7
|
||||
lwzux r7, r14, r8
|
||||
lwz r8, 0x0008(r14)
|
||||
lwz r9, 0x0010(r14)
|
||||
lwz r5, 0x0018(r14)
|
||||
cmpwi r7, 0x00
|
||||
cmpwi cr1, r8, 0x00
|
||||
cmpwi cr2, r9, 0x00
|
||||
cmpwi cr3, r5, 0x00
|
||||
bge VMLastExportedFunc_0x87
|
||||
bge cr1, VMLastExportedFunc_0x83
|
||||
bge cr2, VMLastExportedFunc_0x7f
|
||||
bge cr3, VMLastExportedFunc_0x7b
|
||||
lwzu r7, 0x0020(r14)
|
||||
lwz r8, 0x0008(r14)
|
||||
lwz r9, 0x0010(r14)
|
||||
lwz r5, 0x0018(r14)
|
||||
cmpwi r7, 0x00
|
||||
cmpwi cr1, r8, 0x00
|
||||
cmpwi cr2, r9, 0x00
|
||||
cmpwi cr3, r5, 0x00
|
||||
bge VMLastExportedFunc_0x87
|
||||
bge cr1, VMLastExportedFunc_0x83
|
||||
bge cr2, VMLastExportedFunc_0x7f
|
||||
blt cr3, VMLastExportedFunc_0xd7
|
||||
|
||||
VMLastExportedFunc_0x7b
|
||||
addi r14, r14, 0x08
|
||||
lwzux r7, r14, r8 ; Find an invalid PTE in the right PTEG...
|
||||
lwz r8, 8(r14)
|
||||
lwz r9, 16(r14)
|
||||
lwz r5, 24(r14)
|
||||
cmpwi cr0, r7, 0
|
||||
cmpwi cr1, r8, 0
|
||||
cmpwi cr2, r9, 0
|
||||
cmpwi cr3, r5, 0
|
||||
bge cr0, @pte_at_r14
|
||||
bge cr1, @pte_at_r14_plus_8
|
||||
bge cr2, @pte_at_r14_plus_16
|
||||
bge cr3, @pte_at_r14_plus_24
|
||||
lwzu r7, 32(r14)
|
||||
lwz r8, 8(r14)
|
||||
lwz r9, 16(r14)
|
||||
lwz r5, 24(r14)
|
||||
cmpwi cr0, r7, 0
|
||||
cmpwi cr1, r8, 0
|
||||
cmpwi cr2, r9, 0
|
||||
cmpwi cr3, r5, 0
|
||||
bge cr0, @pte_at_r14
|
||||
bge cr1, @pte_at_r14_plus_8
|
||||
bge cr2, @pte_at_r14_plus_16
|
||||
blt cr3, @heavyweight ; (no free slot, so use PutPTE and rerun PageInfo)
|
||||
@pte_at_r14_plus_24
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14_plus_16
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14_plus_8
|
||||
addi r14, r14, 8
|
||||
@pte_at_r14 ; ... and put a pointer in r14.
|
||||
|
||||
VMLastExportedFunc_0x7f
|
||||
addi r14, r14, 0x08
|
||||
|
||||
VMLastExportedFunc_0x83
|
||||
addi r14, r14, 0x08
|
||||
|
||||
VMLastExportedFunc_0x87
|
||||
; Quick path: there is a PTE slot that the caller can fill
|
||||
lwz r9, KDP.NKInfo.HashTableCreateCount(r1)
|
||||
rlwinm r8, r6, 7, 1, 24
|
||||
addi r9, r9, 0x01
|
||||
rlwinm r8, r6, 7, UpteVSID ; r8 will be new upper PTE
|
||||
addi r9, r9, 1
|
||||
stw r9, KDP.NKInfo.HashTableCreateCount(r1)
|
||||
rlwimi r8, r4, 22, 26, 31
|
||||
|
||||
lwz r9, KDP.PageAttributeInit(r1)
|
||||
oris r8, r8, 0x8000
|
||||
|
||||
rlwimi r8, r4, 22, UpteAPI
|
||||
lwz r9, KDP.PageAttributeInit(r1) ; r9 will be new lower PTE
|
||||
oris r8, r8, UpteValid
|
||||
_mvbit r9, bLpteReference, r16, bM68pdUsed
|
||||
_mvbit r9, bLpteChange, r16, bM68pdModified
|
||||
_mvbit r9, bLpteInhibcache, r16, bM68pdCacheMode1
|
||||
_mvbit r9, bLpteWritethru, r16, bM68pdCacheMode0
|
||||
xori r9, M68pdCacheMode1
|
||||
_mvbit r9, bLpteInhibcache, r16, bM68pdCacheinhib
|
||||
_mvbit r9, bLpteWritethru, r16, bM68pdCacheNotIO
|
||||
xori r9, M68pdCacheinhib
|
||||
_mvbit r9, bLpteP1, r16, bM68pdWriteProtect
|
||||
|
||||
lwz r7, KDP.HTABORG(r1)
|
||||
ori r16, r16, M68pdInHTAB | M68pdResident
|
||||
subf r7, r7, r14
|
||||
rlwimi r16, r7, 9, 0xFFFFF000
|
||||
rlwimi r16, r7, 9, 0xFFFFF000 ; put PTE ptr info into 68k PD
|
||||
blr
|
||||
|
||||
VMLastExportedFunc_0xd7
|
||||
@heavyweight ; Slow path: the full PutPTE, with all its weird registers!
|
||||
mr r7, r27
|
||||
mr r8, r29
|
||||
mr r9, r30
|
||||
|
@ -1053,19 +1078,23 @@ VMLastExportedFunc_0xd7
|
|||
mr r28, r16
|
||||
mr r26, r14
|
||||
mtlr r6
|
||||
|
||||
lwz r9, KDP.VMLogicalPages(r1)
|
||||
b PageInfo
|
||||
b PageInfo ; <= r4
|
||||
|
||||
########################################################################
|
||||
|
||||
major_0x09c9c
|
||||
addi r8, r1, KDP.PARPerSegmentPLEPtrs
|
||||
; Assumes that the page numbered r4 is within the paged area, resident,
|
||||
; and not in the HTAB. Returns a physical pointer in r9.
|
||||
|
||||
QuickGetPhysical
|
||||
addi r8, r1, KDP.SegmentPageArrays
|
||||
lwz r9, KDP.VMPhysicalPages(r1)
|
||||
rlwimi r8, r7, 18, 28, 29
|
||||
rlwimi r8, r7, 18, 0xF * 4
|
||||
cmplw r7, r9
|
||||
lwz r8, 0x0000(r8)
|
||||
rlwinm r7, r7, 2, 14, 29
|
||||
lwz r8, 0(r8)
|
||||
rlwinm r7, r7, 2, 0xFFFF * 4
|
||||
bge vmRetNeg1
|
||||
lwzx r9, r8, r7
|
||||
rlwinm r9, r9, 0, 0, 19
|
||||
lwzx r9, r8, r7 ; r9 = 68k PD
|
||||
rlwinm r9, r9, 0, 0xFFFFF000
|
||||
blr
|
||||
|
|
|
@ -159,8 +159,8 @@ PutPTE ; EA r27 // PTE r30/r31, EQ=Success, GT=Invalid, LT=Fault
|
|||
|
||||
ori r31, r31, LpteReference
|
||||
_mvbit r31, bLpteChange, r28, bM68pdModified
|
||||
_mvbit r31, bLpteInhibcache, r28, bM68pdCacheMode1
|
||||
_mvbit r31, bLpteWritethru, r28, bM68pdCacheMode0
|
||||
_mvbit r31, bLpteInhibcache, r28, bM68pdCacheinhib
|
||||
_mvbit r31, bLpteWritethru, r28, bM68pdCacheNotIO
|
||||
xori r31, r31, LpteWritethru
|
||||
_mvbit r31, bLpteP1, r28, bM68pdWriteProtect
|
||||
|
||||
|
@ -286,7 +286,7 @@ PutPTE ; EA r27 // PTE r30/r31, EQ=Success, GT=Invalid, LT=Fault
|
|||
tlbie r28
|
||||
sync
|
||||
|
||||
_clrNCBCache scr=r28 ; Also clobber NCB cache if page could get moved
|
||||
_clrNCBCache scr=r28 ; Also clobber NCB cache if page could get moved
|
||||
|
||||
bne cr7, PutPTE ; Is there a PageListEntry we need to edit?
|
||||
rlwinm r26, r26, 22, 0xFFFFFFFC ; r26 = RPN * 4
|
||||
|
|
|
@ -327,9 +327,9 @@ Create68kPTEs
|
|||
lwz r23, KDP.PageAttributeInit(r1) ; "default WIMG/PP settings for PTE creation"
|
||||
|
||||
li r30, M68pdResident
|
||||
_mvbit r30, bM68pdCacheMode1, r23, bLpteInhibcache
|
||||
_mvbit r30, bM68pdCacheMode0, r23, bLpteWritethru
|
||||
xori r30, r30, bM68pdCacheMode0
|
||||
_mvbit r30, bM68pdCacheinhib, r23, bLpteInhibcache
|
||||
_mvbit r30, bM68pdCacheNotIO, r23, bLpteWritethru
|
||||
xori r30, r30, bM68pdCacheNotIO
|
||||
_mvbit r30, bM68pdModified, r23, bLpteChange
|
||||
_mvbit r30, bM68pdUsed, r23, bLpteReference
|
||||
|
||||
|
@ -378,7 +378,7 @@ PutLogicalAreaInPageMap
|
|||
stw r19, KDP.VMLogicalPages(r1)
|
||||
stw r19, KDP.VMPhysicalPages(r1)
|
||||
|
||||
addi r29, r1, KDP.PARPerSegmentPLEPtrs - 4 ; where to save per-segment PLE ptr
|
||||
addi r29, r1, KDP.SegmentPageArrays - 4 ; where to save per-segment PLE ptr
|
||||
addi r19, r1, KDP.SegMap32SupInit - 8 ; which part of PageMap to update
|
||||
|
||||
stw r21, KDP.VMPageArray(r1)
|
||||
|
@ -393,7 +393,7 @@ PutLogicalAreaInPageMap
|
|||
stw r30, 0(r8) ; use entire segment (PageIdx = 0, PageCount = 0xFFFF)
|
||||
stw r31, 4(r8) ; RPN = PLE ptr | PMDT_NotPTE_PageList
|
||||
|
||||
stwu r21, 4(r29) ; point PARPerSegmentPLEPtrs to segments's first PLE
|
||||
stwu r21, 4(r29) ; point SegmentPageArrays to segments's first PLE
|
||||
|
||||
addis r21, r21, 4 ; increment pointer into PLE (64k pages/segment * 4b/PLE)
|
||||
subis r22, r22, 1 ; decrement number of pending pages (64k pages/segment)
|
||||
|
|
Loading…
Reference in New Issue
Block a user