From a323be3c8b6c90b494ef51c2ffc293b15fc2306b Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Sun, 18 Feb 2018 11:17:23 +0800 Subject: [PATCH] Reverse some VM functions (Daniel) VeryPopularFunction (now GetPARPageInfo) takes a page number in the PAR and returns a bunch of info on it. The flags of the PTE are copied into cr5-cr7 of the condition register so that VMCalls can easily make decisions off of them. I had already figured out the bit flags of the PTEs Mac OS 9 uses when I reversed PagingFunc1. The definitions are in the end of the 'Area Definitions.txt' file I sent you a while ago. If you see a ' bltl cr5, VMDoSomethingWithTLB' (now RemovePageFromTLB) followed by a ' bltl cr5, major_0x09b40' (now RemovePTEFromHTAB), you know that the function is manipulating pages directly. RemovePageFromTLB clears a page from the TLB if it follows a VeryPopularFunction call. RemovePTEFromHTAB takes a page that is resident in the HTAB and removes its HTAB entry. cr5_lt is bit 20 (mask 0x800), which my notes tell me is set when the PTE is in the HTAB. Altogether, the sequence translates to 'if the page is in the HTAB, flush it from the TLB and delete its HTAB entry'. VMExchangePages uses this (twice) to make sure there are no race conditions when it is swapping the data in the pages. I still don't have proof, but I am very very strongly convinced that KDP.FlatPageListPointer is always equal to the PAR's PageMapArrayPtr. On an unrelated note, KCMapPage seems to always panic when called on an area where the PageMapArrayPtr is 2d. I have absolutely no idea why this happens, but it is bad news for MPMapper because the threshold for 2-dimensionality is around 1 MB. I would have to make 512 separate CreateArea calls to map all the memory without the NK panicking. I will have to look into this. --- NanoKernel/NKMPCalls.s | 6 +- NanoKernel/NKVMCalls.s | 326 +++++++++++++++++------------------------ 2 files changed, 141 insertions(+), 191 deletions(-) diff --git a/NanoKernel/NKMPCalls.s b/NanoKernel/NKMPCalls.s index 84f24ee..5477077 100644 --- a/NanoKernel/NKMPCalls.s +++ b/NanoKernel/NKMPCalls.s @@ -724,17 +724,17 @@ MPCall_0 ; OUTSIDE REFERER _Lock PSA.HTABLock, scratch1=r17, scratch2=r18 - bl VeryPopularFunction + bl GetPARPageInfo bge- cr4, MPCall_0_0xd8 bgt- cr5, MPCall_0_0xd8 bns- cr7, MPCall_0_0xd8 bgt- cr7, MPCall_0_0xd8 - bltl+ cr5, VMDoSomethingWithTLB + bltl+ cr5, RemovePageFromTLB bgel+ cr5, VMSecondLastExportedFunc ori r16, r16, 0x404 li r31, 0x03 rlwimi r9, r31, 0, 30, 31 - bl VMDoSomeIO + bl EditPTEInHTAB mr r7, r30 mr r6, r29 _AssertAndRelease PSA.HTABLock, scratch=r16 diff --git a/NanoKernel/NKVMCalls.s b/NanoKernel/NKVMCalls.s index 75b4502..0abc0ff 100644 --- a/NanoKernel/NKVMCalls.s +++ b/NanoKernel/NKVMCalls.s @@ -164,7 +164,7 @@ VMDispatchTableEnd ; setPTEntryGivenPage ; VMShouldClean ; VMAllocateMemory -; VeryPopularFunction +; GetPARPageInfo ; major_0x09c9c VMReturnMinus1 ; OUTSIDE REFERER @@ -231,13 +231,13 @@ VMFinalInit ; OUTSIDE REFERER @loop srwi r4, r31, 12 lwz r9, KDP.PrimaryAddrRangePages(r1) - bl VeryPopularFunction + bl GetPARPageInfo bge- cr4, @skip - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB bgel- cr5, VMSecondLastExportedFunc ori r16, r16, 0x400 rlwimi r9, r29, 0, 0, 19 - bl major_0x09b40 + bl RemovePTEFromHTAB addi r31, r31, 0x1000 cmplw r31, r30 ble+ @loop @@ -315,8 +315,8 @@ VMInit_0xa8 rlwimi r3, r8, 21, 12, 15 cmpw r3, r4 bnel+ Local_Panic - bl VMDoSomethingWithTLB - bl major_0x09b40 + bl RemovePageFromTLB + bl RemovePTEFromHTAB VMInit_0x100 cmpwi r7, 0x00 @@ -514,26 +514,26 @@ VMInit_Fail DeclareVMCallWithAlt 12, VMExchangePages, VMReturnNotReady VMExchangePages ; OUTSIDE REFERER - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 bgt+ cr5, VMReturnMinus1 bns+ cr7, VMReturnMinus1 bgt+ cr6, VMReturnMinus1 bne+ cr6, VMReturnMinus1 - bltl- cr5, VMDoSomethingWithTLB - bltl- cr5, major_0x09b40 + bltl- cr5, RemovePageFromTLB + bltl- cr5, RemovePTEFromHTAB mr r6, r15 mr r4, r5 mr r5, r16 lwz r9, KDP.PrimaryAddrRangePages(r1) - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 bgt+ cr5, VMReturnMinus1 bns+ cr7, VMReturnMinus1 bgt+ cr6, VMReturnMinus1 bne+ cr6, VMReturnMinus1 - bltl- cr5, VMDoSomethingWithTLB - bltl- cr5, major_0x09b40 + bltl- cr5, RemovePageFromTLB + bltl- cr5, RemovePTEFromHTAB stw r5, 0x0000(r15) stw r16, 0x0000(r6) rlwinm r4, r5, 0, 0, 19 @@ -578,7 +578,7 @@ VMGetPhysicalPage_0x28 lwz r9, KDP.PrimaryAddrRangePages(r1) VMGetPhysicalPage_0x30 - bl VeryPopularFunction + bl GetPARPageInfo bns+ cr7, VMReturnMinus1 srwi r3, r9, 12 b VMReturn @@ -621,13 +621,13 @@ getPTEntryGivenPage_0x48 lwz r9, KDP.PrimaryAddrRangePages(r1) getPTEntryGivenPage_0x50 - bl VeryPopularFunction + bl GetPARPageInfo mr r3, r16 bns- cr7, getPTEntryGivenPage_0x74 rlwimi r3, r9, 0, 0, 19 bge- cr5, getPTEntryGivenPage_0x74 - bl VMDoSomethingWithTLB - bl VMDoSomeIO_0x4 + bl RemovePageFromTLB + bl EditPTEOnlyInHTAB mr r3, r16 rlwimi r3, r9, 0, 0, 19 @@ -713,7 +713,7 @@ major_0x08d88_0xb0 ; OUTSIDE REFERER DeclareVMCallWithAlt 5, VMIsInited, VMReturnNotReady VMIsInited ; OUTSIDE REFERER - bl VeryPopularFunction + bl GetPARPageInfo bso+ cr7, VMReturn1 rlwinm r3, r16, 16, 31, 31 b VMReturn @@ -746,7 +746,7 @@ VMIsResident_0x28 lwz r9, KDP.PrimaryAddrRangePages(r1) VMIsResident_0x30 - bl VeryPopularFunction + bl GetPARPageInfo clrlwi r3, r16, 0x1f b VMReturn @@ -757,12 +757,12 @@ VMIsResident_0x30 DeclareVMCallWithAlt 4, VMIsUnmodified, VMReturnNotReady VMIsUnmodified ; OUTSIDE REFERER - bl VeryPopularFunction + bl GetPARPageInfo rlwinm r3, r16, 28, 31, 31 xori r3, r3, 0x01 bge+ cr5, VMReturn - bl VMDoSomethingWithTLB - bl VMDoSomeIO_0x4 + bl RemovePageFromTLB + bl EditPTEOnlyInHTAB rlwinm r3, r16, 28, 31, 31 xori r3, r3, 0x01 b VMReturn @@ -792,9 +792,9 @@ VMLRU_0x1c bge- cr5, VMLRU_0x50 add r14, r14, r7 lwz r8, 0x0000(r14) - bl VMDoSomethingWithTLB + bl RemovePageFromTLB andc r9, r9, r5 - bl major_0x09b40 + bl RemovePTEFromHTAB subf r14, r7, r14 VMLRU_0x50 @@ -846,20 +846,20 @@ VMMakePageCacheable ; OUTSIDE REFERER bne- cr1, VMMakePageCacheable_0x4 VMMakePageCacheable_0x4 - bl VeryPopularFunction + bl GetPARPageInfo rlwinm r7, r16, 0, 25, 26 cmpwi r7, 0x20 bns+ cr7, VMReturnMinus1 beq+ VMReturn bge- cr4, VMMakePageCacheable_0x40 - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB bgel- cr5, VMSecondLastExportedFunc rlwinm r16, r16, 0, 27, 24 rlwinm r9, r9, 0, 27, 24 lwz r7, KDP.PageAttributeInit(r1) rlwimi r9, r7, 0, 27, 28 ori r16, r16, 0x20 - bl VMDoSomeIO + bl EditPTEInHTAB b VMReturn VMMakePageCacheable_0x40 @@ -922,19 +922,19 @@ VMMakePageWriteThrough ; OUTSIDE REFERER bne- cr1, VMMakePageWriteThrough_0x4 VMMakePageWriteThrough_0x4 - bl VeryPopularFunction + bl GetPARPageInfo rlwinm. r7, r16, 0, 25, 26 bns+ cr7, VMReturnMinus1 beq+ VMReturn bge- cr4, VMMakePageWriteThrough_0x3c - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB bgel- cr5, VMSecondLastExportedFunc rlwinm r16, r16, 0, 27, 24 rlwinm r9, r9, 0, 27, 24 lwz r7, KDP.PageAttributeInit(r1) rlwimi r9, r7, 0, 27, 28 ori r9, r9, 0x40 - bl VMDoSomeIO + bl EditPTEInHTAB b VMMakePageNonCacheable_0x3c VMMakePageWriteThrough_0x3c @@ -1056,10 +1056,10 @@ PageSetCommon_0xc4 addi r14, r14, 0x08 PageSetCommon_0xc8 - bl VMDoSomethingWithTLB + bl RemovePageFromTLB li r8, 0x00 li r9, 0x00 - bl VMDoSomeIO_0x4 + bl EditPTEOnlyInHTAB b VMReturn @@ -1072,20 +1072,20 @@ VMMakePageNonCacheable ; OUTSIDE REFERER bne- cr1, VMMakePageNonCacheable_0x4 VMMakePageNonCacheable_0x4 - bl VeryPopularFunction + bl GetPARPageInfo rlwinm r7, r16, 0, 25, 26 cmpwi r7, 0x60 bns+ cr7, VMReturnMinus1 beq+ VMReturn bge- cr4, VMMakePageNonCacheable_0x78 - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB bgel- cr5, VMSecondLastExportedFunc rlwinm r9, r9, 0, 27, 24 lwz r7, KDP.PageAttributeInit(r1) rlwimi r9, r7, 0, 27, 28 ori r16, r16, 0x60 ori r9, r9, 0x20 - bl VMDoSomeIO + bl EditPTEInHTAB VMMakePageNonCacheable_0x3c ; OUTSIDE REFERER rlwinm r4, r9, 0, 0, 19 @@ -1200,11 +1200,11 @@ VMMarkBacking_0x50 lwz r9, KDP.PrimaryAddrRangePages(r1) VMMarkBacking_0x58 - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 bgt+ cr5, VMReturnMinus1 - bltl- cr5, VMDoSomethingWithTLB - bltl- cr5, major_0x09b40 + bltl- cr5, RemovePageFromTLB + bltl- cr5, RemovePTEFromHTAB rlwimi r16, r5, 16, 15, 15 li r7, 0x01 andc r16, r16, r7 @@ -1218,16 +1218,16 @@ VMMarkBacking_0x58 DeclareVMCallWithAlt 9, VMMarkCleanUnused, VMReturnNotReady VMMarkCleanUnused ; OUTSIDE REFERER - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 bns+ cr7, VMReturnMinus1 - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB beq- cr2, VMMarkCleanUnused_0x2c bgel- cr5, VMSecondLastExportedFunc li r7, 0x180 andc r9, r9, r7 ori r16, r16, 0x100 - bl VMDoSomeIO + bl EditPTEInHTAB b VMReturn VMMarkCleanUnused_0x2c @@ -1235,7 +1235,7 @@ VMMarkCleanUnused_0x2c ori r16, r16, 0x100 li r7, 0x18 andc r16, r16, r7 - bl major_0x09b40 + bl RemovePTEFromHTAB b VMReturn @@ -1303,7 +1303,7 @@ VMMarkResident_0x50 lwz r9, KDP.PrimaryAddrRangePages(r1) VMMarkResident_0x58 - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 bso+ cr7, VMReturnMinus1 bltl+ cr5, Local_Panic @@ -1311,7 +1311,7 @@ VMMarkResident_0x58 ori r16, r16, 0x01 stw r16, 0x0000(r15) bl VMSecondLastExportedFunc - bl VMDoSomeIO + bl EditPTEInHTAB b VMReturn @@ -1325,7 +1325,7 @@ VMPTest ; OUTSIDE REFERER cmplw r4, r9 li r3, 0x4000 bge+ VMReturn - bl VeryPopularFunction + bl GetPARPageInfo li r3, 0x400 bns+ cr7, VMReturn li r3, 0x00 @@ -1381,7 +1381,7 @@ setPTEntryGivenPage_0x5c setPTEntryGivenPage_0x64 mr r6, r4 mr r4, r5 - bl VeryPopularFunction + bl GetPARPageInfo bge+ cr4, VMReturnMinus1 xor r7, r16, r6 li r3, 0x461 @@ -1392,19 +1392,19 @@ setPTEntryGivenPage_0x64 xor r16, r16, r7 stw r16, 0x0000(r15) bge+ cr5, VMReturn - bl VMDoSomethingWithTLB + bl RemovePageFromTLB lwz r16, 0x0000(r15) bne- cr2, setPTEntryGivenPage_0xb4 andi. r7, r16, 0x08 bne- setPTEntryGivenPage_0xb4 - bl major_0x09b40 + bl RemovePTEFromHTAB b VMReturn setPTEntryGivenPage_0xb4 rlwimi r9, r16, 5, 23, 23 rlwimi r9, r16, 3, 24, 24 rlwimi r9, r16, 30, 31, 31 - bl VMDoSomeIO_0x4 + bl EditPTEOnlyInHTAB b VMReturn @@ -1414,10 +1414,10 @@ setPTEntryGivenPage_0xb4 DeclareVMCallWithAlt 6, VMShouldClean, VMReturnNotReady VMShouldClean ; OUTSIDE REFERER - bl VeryPopularFunction + bl GetPARPageInfo bns+ cr7, VMReturn0 bge+ cr4, VMReturnMinus1 - bltl- cr5, VMDoSomethingWithTLB + bltl- cr5, RemovePageFromTLB blt- cr7, VMShouldClean_0x34 bns- cr6, VMShouldClean_0x34 xori r16, r16, 0x10 @@ -1425,11 +1425,11 @@ VMShouldClean ; OUTSIDE REFERER stw r16, 0x0000(r15) bge+ cr5, VMReturn1 xori r9, r9, 0x80 - bl VMDoSomeIO_0x4 + bl EditPTEOnlyInHTAB b VMReturn1 VMShouldClean_0x34 - bltl- cr5, VMDoSomeIO_0x4 + bltl- cr5, EditPTEOnlyInHTAB b VMReturn0 @@ -1473,9 +1473,9 @@ VMAllocateMemory_0x6c VMAllocateMemory_0x74 addi r4, r4, -0x01 - bl VeryPopularFunction - bltl- cr5, VMDoSomethingWithTLB - bltl- cr5, major_0x09b40 + bl GetPARPageInfo + bltl- cr5, RemovePageFromTLB + bltl- cr5, RemovePTEFromHTAB lwz r9, KDP.PrimaryAddrRangePages(r1) subf r8, r4, r9 cmplw cr7, r5, r8 @@ -1684,87 +1684,72 @@ VMAllocateMemory_0x360 -; VeryPopularFunction +;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 -; Xrefs: -; VMFinalInit -; VMExchangePages -; VMGetPhysicalPage -; getPTEntryGivenPage -; VMIsInited -; VMIsResident -; VMIsUnmodified -; VMMakePageCacheable -; VMMakePageWriteThrough -; VMMakePageNonCacheable -; VMMarkBacking -; VMMarkCleanUnused -; VMMarkResident -; VMPTest -; setPTEntryGivenPage -; VMShouldClean -; VMAllocateMemory -; VMLastExportedFunc -; major_0x0b144 +; ARG page# r4, KDP.VMMaxVirtualPages r9, +; RET PTE_flags CR, HTAB_upper r8, HTAB_lower r9, PTE_value r16, HTAB_entry_loc r14, PTE_loc r15, -VeryPopularFunction ; OUTSIDE REFERER - cmplw cr4, r4, r9 + +GetPARPageInfo ; OUTSIDE REFERER + cmplw cr4, r4, r9 ;r9 is VMMaxVirtualPages by convention lwz r15, KDP.FlatPageListPtr(r1) slwi r8, r4, 2 - bge- cr4, VeryPopularFunction_0x40 + bge- cr4, GetPARPageInfo_0x40 -VeryPopularFunction_0x10 - lwzux r16, r15, r8 - lwz r14, KDP.HTABORG(r1) - mtcrf 0x07, r16 - rlwinm r8, r16, 23, 9, 28 - rlwinm r9, r16, 0, 0, 19 - bgelr- cr5 - lwzux r8, r14, r8 - lwz r9, 0x0004(r14) +GetPARPageInfo_0x10 + lwzux r16, r15, r8 ;get PTE from KDP.FlatPageListPointer + lwz r14, KDP.HTABORG(r1) + mtcrf 0x07, r16 ;copy bits 20-31 to cr + rlwinm r8, r16, 23, 9, 28;convert page# into an index + rlwinm r9, r16, 0, 0, 19;get unshifted page# + bgelr- cr5 ;return if PTE is not in HTAB + lwzux r8, r14, r8 ;get first word of PTE from HTAB + lwz r9, 0x0004(r14);get second word of PTE from HTAB mtcrf 0x80, r8 - bns+ cr7, Local_Panic - bltlr- - bl Local_Panic + bns+ cr7, Local_Panic;panic if the PTE is in the HTAB but isn't mapped to a real page + bltlr- ;return if PTE is valid + bl Local_Panic;panic if PTE isn't valid but is in the HTAB -VeryPopularFunction_0x40 - lwz r9, KDP.VMMaxVirtualPages(r1) +GetPARPageInfo_0x40 ;some kind of little-used code path for when VMMaxVirtualPages is invalid? ROM overlay? + lwz r9, KDP.VMMaxVirtualPages(r1) cmplw cr4, r4, r9 rlwinm. r9, r4, 0, 0, 11 - blt+ cr4, VMReturnMinus1 - bne+ VMReturnMinus1 - lwz r15, 0x05e8(r1) - rlwinm r9, r4, 19, 25, 28 - lwzx r15, r15, r9 - clrlwi r9, r4, 0x10 + blt+ cr4, VMReturnMinus1;return failure if r4