powermac-rom/NanoKernel/NKMemory.s

550 lines
18 KiB
ArmAsm
Raw Permalink Normal View History

2018-07-28 06:20:23 +00:00
; AUTO-GENERATED SYMBOL LIST
; IMPORTS:
; NKSystemCrash
; SystemCrash
; EXPORTS:
; FlushTLB (=> NKReset)
; GetPhysical (=> MRInterrupts, NKSoftInts)
; PutPTE (=> MRInterrupts, NKColdInts, NKLegacyVM, NKReset)
; SetMap (=> NKReset)
2018-07-09 06:53:50 +00:00
########################################################################
########################################################################
2018-07-24 04:56:38 +00:00
PutPTE ; EA r27 // PTE r30/r31, EQ=Success, GT=Invalid, LT=Fault
2018-07-28 06:20:23 +00:00
lwz r29, KDP.CurMap.SegMapPtr(r1)
rlwinm r28, r27, 7, 0x0000000F << 3 ; convert segment of passed ptr to offset into SegMap
lwzx r29, r29, r28 ; r29 = ptr to start of segment in PageMap
rlwinm r28, r27, 20, 0x0000FFFF ; r27 = page index within SegMap
lhz r30, PME.LBase(r29)
b @find_pme
@try_next_pme ; Point r29 to the PageMapEntry that concerns this page
lhzu r30, 8(r29) ; get another PME.LBase
2018-07-09 06:53:50 +00:00
@find_pme
2018-07-28 06:20:23 +00:00
lhz r31, PME.PageCount(r29)
subf r30, r30, r28 ; r30 = page index within area
cmplw cr7, r30, r31
bgt cr7, @try_next_pme
lwz r28, KDP.HtabTempEntryPtr(r1) ; (remove temp PTE if present)
lwz r31, PME.PBaseAndFlags(r29)
cmpwi cr7, r28, 0 ; (remove temp PTE if present)
extlwi. r26, r31, 2, 20 ; DaddyFlag and CountingFlag in top bits
bne cr7, @remove_temp_pte ; (remove temp PTE if present)
blt @daddy_flag ; >>>>> DaddyFlag = 1
@return_remove_temp_pte ; (optimized: if LT then to jumps to @daddy_flag)
bgt @create_temp_pte ; >>>>> DaddyFlag = 0, CountingFlag = 1
; fallthru ; >>>>> DaddyFlag = 0, CountingFlag = 0
2018-07-09 06:53:50 +00:00
########################################################################
; CODE TO CREATE A PAGE TABLE ENTRY
2018-07-28 06:20:23 +00:00
; <<<<< Fallthru from main entry point (top two flags of PME are zero)
slwi r28, r30, 12
add r31, r31, r28 ; r31 = physical page ptr plus 12 bits of PageMapEntry flags
@return_daddy_flag ; <<<<< @daddy_flag comes here
@return_create_temp_pte ; <<<<< @create_temp_pte comes here (r31=pageptr, r26=0x5A5A)
mfsrin r30, r27 ; HASH FUNCTION: get address of PTEG
rlwinm r28, r27, 26, 10, 25 ; r28 = (1st arg of XOR) * 64b
rlwinm r30, r30, 6, 7, 25 ; r30 = (2nd arg of XOR) * 64b
xor r28, r28, r30 ; r28 (hash output * 64b) = r28 ^ r30
lwz r30, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r30
or. r29, r29, r28 ; result (PTEG address) into r29
@retry_other_pteg ; <<<<< @no_blanks_in_pteg can return here after doing sec'dary hash
lwz r30, 0(r29) ; Take address of PTEG in r29, find empty/"invalid" PTE within (optimized!)
lwz r28, 8(r29)
cmpwi cr6, r30, 0
lwz r30, 16(r29)
cmpwi cr7, r28, 0
lwzu r28, 24(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
lwzu r30, 8(r29)
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
lwzu r28, 8(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
lwzu r30, 8(r29)
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
lwzu r28, 8(r29)
bge cr6, @found_blank_pte
cmpwi cr6, r30, 0
addi r29, r29, 8
bge cr7, @found_blank_pte
cmpwi cr7, r28, 0
addi r29, r29, 8
bge cr6, @found_blank_pte
rlwinm r28, r31, 0, 26, 26 ; wImg bit in PTE???
addi r29, r29, 8 ; Leave PTE + 24 in r29
blt cr7, @no_blanks_in_pteg ; >>>>> This might cause PutPTE to return an error (BNE)
@found_blank_pte ; Take PTE address (plus 24) in r29, draft PTE[lo] in r31
cmpwi r26, 0 ; NOTE: top bit of r31 will be set if sec'dary hash func was used
mfsrin r28, r27
extrwi r30, r27, 6, 4 ; PTE[API/26-31] taken from upper 6 bits of offset-within-segment
stw r27, KDP.HtabLastEA(r1)
ori r31, r31, 0x100 ; set PTE[R(eference)]
rlwimi r30, r31, 27, 25, 25 ; set PTE[H(ash func ID)] to cheeky topmost bit of the phys addr in r31
rlwinm r31, r31, 0, 21, 19 ; unset upper reserved bit in PTE[lo]
insrwi r30, r28, 24, 1 ; get PTE[VSID] from segment register
stw r31, -20(r29) ; PTE[lo] = r31
oris r30, r30, 0x8000 ; set PTE[V(alid)]
sync ; because we just wanged the page table
stwu r30, -24(r29) ; PTE[hi] = r30
lwz r28, KDP.NKInfo.HashTableCreateCount(r1)
stw r29, KDP.ApproxCurrentPTEG(r1)
addi r28, r28, 1
stw r28, KDP.NKInfo.HashTableCreateCount(r1)
beqlr ; >>>>> RETURN "BEQ" if we got to "Case 1" directly
cmpwi r26, 0x5A5A ; Special value set so that we take note of this new temporary PTE?
bne @notemp
stw r29, KDP.HtabTempEntryPtr(r1)
cmpw r29, r29 ; >>>>> RETURN "BEQ" if we got to "Case 1" via @create_temp_pte
blr
2018-07-09 06:53:50 +00:00
@notemp
2018-07-28 06:20:23 +00:00
lwz r28, 0(r26) ; Otherwise, we got here via @daddy_flag? Looks nonsensical.
lwz r30, KDP.HTABORG(r1)
ori r28, r28, 0x801
subf r30, r30, r29
cmpw r29, r29
rlwimi r28, r30, 9, 0, 19
stw r28, 0(r26)
blr ; >>>>> RETURN "BEQ" otherwise
2018-07-09 06:53:50 +00:00
########################################################################
; Helpful code that jumps back to roughly where it started
@remove_temp_pte
2018-07-28 06:20:23 +00:00
lwz r28, KDP.NKInfo.HashTableDeleteCount(r1)
lwz r29, KDP.HtabTempEntryPtr(r1)
addi r28, r28, 1
stw r28, KDP.NKInfo.HashTableDeleteCount(r1)
li r28, 0
stw r28, 0(r29)
lwz r29, KDP.HtabTempPage(r1)
stw r28, KDP.HtabTempPage(r1)
stw r28, KDP.HtabTempEntryPtr(r1)
sync
tlbie r29
sync
bge @return_remove_temp_pte ; Optimization: would otherwise branch to a "blt @daddy_flag"
2018-07-09 06:53:50 +00:00
########################################################################
; r30 = page index within area, r31 = PBaseAndFlags
@daddy_flag
2018-07-28 06:20:23 +00:00
extlwi. r28, r31, 2, 21 ; top bits of r28 = CountingFlag, PhysicalIsRelativeFlag
bge @return_via_pf2 ; if !CountingFlag: return (if !PIRFlag: via PF2)
rlwinm r28, r30, 2, 0xFFFFFFFC ; r28 = pageIdxInArea * 4
rlwinm r26, r31, 22, 0xFFFFFFFC ; r26 = PIRFlag << 31 | BtmBit << 22 | physBase * 4
lwzux r28, r26, r28 ; this makes no sense!!
lwz r31, KDP.PageAttributeInit(r1)
andi. r30, r28, 0x881
rlwimi r31, r28, 0, 0xFFFFF000
cmplwi r30, 1
cmplwi cr7, r30, 0x81
ori r31, r31, 0x100
rlwimi r31, r28, 3, 24, 24
rlwimi r31, r28, 31, 26, 26
rlwimi r31, r28, 1, 25, 25
xori r31, r31, 0x40
rlwimi r31, r28, 30, 31, 31
beq @return_daddy_flag
bltlr cr7
bl SystemCrash
2018-07-09 06:53:50 +00:00
########################################################################
; Helpful code that jumps back to roughly where it started
2018-07-28 06:20:23 +00:00
@create_temp_pte ; Make "temp" PageMapEntry, when flags look like 0x800
ori r28, r27, 0xfff ; r27 = passed ptr, r31 = PBaseAndFlags
stw r28, KDP.HtabTempPage(r1)
rlwinm r31, r31, 0, 22, 19 ; clear CountingFlag in r31
li r26, 0x5A5A ; set magic number in r26 so that KDP.HtabTempEntryPtr gets set
b @return_create_temp_pte
2018-07-09 06:53:50 +00:00
########################################################################
; Helpful return code for @daddy_flag
@return_via_pf2
2018-07-28 06:20:23 +00:00
bgtlr
addi r29, r1, KDP.SupervisorMap
b SetMap
2018-07-09 06:53:50 +00:00
########################################################################
; So try the secondary hashing function, if we haven't already
@no_blanks_in_pteg
2018-07-28 06:20:23 +00:00
cmplw cr6, r28, r26
subi r29, r29, 64 + 16
ble cr6, @search_for_matching_pte
crnot cr0_eq, cr0_eq
lwz r30, KDP.PTEGMask(r1)
xori r31, r31, 0x800
xor r29, r29, r30
beq @retry_other_pteg
2018-07-09 06:53:50 +00:00
########################################################################
2018-07-28 06:20:23 +00:00
@search_for_matching_pte ; r29 = full PTEG
lwz r26, KDP.OverflowingPTEG(r1) ; this could be zero
crclr cr6_eq ; prepare to return "failure"
rlwimi r26, r29, 0, -64
addi r29, r26, 8
b @first_pte
2018-07-09 06:53:50 +00:00
@rethink_pte_search
2018-07-28 06:20:23 +00:00
bne cr6, @next_pte
mr r26, r29
2018-07-09 06:53:50 +00:00
@next_pte
2018-07-28 06:20:23 +00:00
cmpw cr6, r29, r26
addi r29, r29, 8
2018-07-09 06:53:50 +00:00
@first_pte
2018-07-28 06:20:23 +00:00
rlwimi r29, r26, 0, 0, 25
lwz r31, 4(r29)
lwz r30, 0(r29)
beq cr6, @got_pte
rlwinm r28, r31, 30, 25, 25
andc. r28, r28, r30 ; R && !H (i.e. page has been read and is not in "secondary hash" PTEG)
bne @next_pte ; if so,
2018-07-09 06:53:50 +00:00
@got_pte
########################################################################
2018-07-28 06:20:23 +00:00
clrlwi r28, r31, 30
cmpwi cr7, r28, 0
clrrwi r28, r31, 12
cmpw r28, r1
lwz r30, KDP.ContextPtr(r1)
beq cr7, @rethink_pte_search
addi r31, r30, 768-1
beq @rethink_pte_search
rlwinm r30, r30, 0, 0xFFFFF000
cmpwi cr7, r28, 30
lwz r30, 0(r29)
rlwinm r31, r31, 0, 0xFFFFF000
cmpwi r28, 31
rlwinm r31, r30, 0, 0x00000040
beq cr7, @rethink_pte_search
extlwi r28, r30, 4, 1
beq @rethink_pte_search
neg r31, r31
insrwi r28, r30, 6, 4
xor r31, r31, r29
rlwimi r28, r30, 5, 10, 19
rlwinm r31, r31, 6, 10, 19
xor r28, r28, r31
lwz r26, KDP.CurMap.SegMapPtr(r1)
rlwinm r30, r28, (32-25), 0x00000078
lwzx r26, r26, r30 ; r26 pts into PageMap @ current segment
@tinyloop ; find the last non-blank PME in the segment
lhz r30, PME.LBase(r26)
rlwinm r31, r28, 20, 0x0000FFFF
subf r30, r30, r31
lhz r31, PME.PageCount(r26)
addi r26, r26, 8
cmplw cr7, r30, r31
lwz r31, PME.PBaseAndFlags - 8(r26)
andi. r31, r31, 0xe01
cmpwi r31, 0xa01
bgt cr7, @tinyloop
beq @tinyloop
lwz r26, PME.PBaseAndFlags - 8(r26) ; got that PME (26)
slwi r30, r30, 2
extrwi r31, r26, 2, 20
cmpwi cr7, r31, 3 ; not a DaddyFlag + CountingFlag? Try again!
lwz r31, KDP.NKInfo.HashTableOverflowCount(r1)
stw r29, KDP.OverflowingPTEG(r1)
addi r31, r31, 1
stw r31, KDP.NKInfo.HashTableOverflowCount(r1)
lwz r31, KDP.NKInfo.HashTableDeleteCount(r1)
stw r30, 0(r29)
addi r31, r31, 1
stw r31, KDP.NKInfo.HashTableDeleteCount(r1)
sync
tlbie r28
sync
_InvalNCBPointerCache scratch=r28
bne cr7, PutPTE ; not a DaddyFlag + CountingFlag? Retriable...
rlwinm r26, r26, 22, 0xFFFFFFFC ; PIRFlag << 31 | BtmBit << 22 | physBase * 4
lwzux r28, r26, r30
lwz r31, 4(r29)
andi. r30, r28, 0x800
rlwinm r30, r28, (32-9), 0x007FFFF8
xor r30, r30, r29
beq SystemCrash
andi. r30, r30, 0xffff
xori r28, r28, 0x800
bne SystemCrash
rlwimi r28, r31, 0, 0, 19 ; r28 = EA of victim of overflow
rlwimi r28, r31, 29, 27, 27
rlwimi r28, r31, 27, 28, 28
stw r28, 0(r26)
b PutPTE
2018-07-09 06:53:50 +00:00
########################################################################
########################################################################
SetMap ; MemMap r29
2018-07-28 06:20:23 +00:00
lwz r28, MemMap.SegMapPtr(r29)
stw r28, KDP.CurMap.SegMapPtr(r1)
addi r28, r28, 16*8 + 4
lis r31, 0
@next_seg ; SEGMENT REGISTERS
lwzu r30, -8(r28)
subis r31, r31, 0x1000
mr. r31, r31
mtsrin r30, r31
bne @next_seg
mfpvr r31
lwz r28, MemMap.BatMap(r29)
andis. r31, r31, 0xFFFE
addi r29, r1, 0
stw r28, KDP.CurMap.BatMap(r1)
beq @601
rlwimi r29, r28, 7, 0x00000078 ; BATS, non-601
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat0u, r30
mtspr ibat0l, r31
stw r30, KDP.CurIBAT0.U(r1)
stw r31, KDP.CurIBAT0.L(r1)
rlwimi r29, r28, 11, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat1u, r30
mtspr ibat1l, r31
stw r30, KDP.CurIBAT1.U(r1)
stw r31, KDP.CurIBAT1.L(r1)
rlwimi r29, r28, 15, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat2u, r30
mtspr ibat2l, r31
stw r30, KDP.CurIBAT2.U(r1)
stw r31, KDP.CurIBAT2.L(r1)
rlwimi r29, r28, 19, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr ibat3u, r30
mtspr ibat3l, r31
stw r30, KDP.CurIBAT3.U(r1)
stw r31, KDP.CurIBAT3.L(r1)
rlwimi r29, r28, 23, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat0u, r30
mtspr dbat0l, r31
stw r30, KDP.CurDBAT0.U(r1)
stw r31, KDP.CurDBAT0.L(r1)
rlwimi r29, r28, 27, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat1u, r30
mtspr dbat1l, r31
stw r30, KDP.CurDBAT1.U(r1)
stw r31, KDP.CurDBAT1.L(r1)
rlwimi r29, r28, 31, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat2u, r30
mtspr dbat2l, r31
stw r30, KDP.CurDBAT2.U(r1)
stw r31, KDP.CurDBAT2.L(r1)
rlwimi r29, r28, 3, 0x00000078
lwz r30, KDP.BATs + BAT.U(r29)
lwz r31, KDP.BATs + BAT.L(r29)
mtspr dbat3u, r30
mtspr dbat3l, r31
stw r30, KDP.CurDBAT3.U(r1)
stw r31, KDP.CurDBAT3.L(r1)
cmpw r29, r29
blr
2018-07-09 06:53:50 +00:00
@601
2018-07-28 06:20:23 +00:00
rlwimi r29, r28, 7, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0300(r1)
stw r31, 0x0304(r1)
stw r30, 0x0320(r1)
stw r31, 0x0324(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat0u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat0l, r31
rlwimi r29, r28, 11, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0308(r1)
stw r31, 0x030c(r1)
stw r30, 0x0328(r1)
stw r31, 0x032c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat1u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat1l, r31
rlwimi r29, r28, 15, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0310(r1)
stw r31, 0x0314(r1)
stw r30, 0x0330(r1)
stw r31, 0x0334(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat2u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat2l, r31
rlwimi r29, r28, 19, 25, 28
lwz r30, KDP.BATs + 0(r29)
lwz r31, KDP.BATs + 4(r29)
stw r30, 0x0318(r1)
stw r31, 0x031c(r1)
stw r30, 0x0338(r1)
stw r31, 0x033c(r1)
rlwimi r30, r31, 0, 25, 31
mtspr ibat3u, r30
lwz r30, KDP.BATs + 0(r29)
rlwimi r31, r30, 30, 26, 31
rlwimi r31, r30, 6, 25, 25
mtspr ibat3l, r31
cmpw r29, r29
blr
2018-07-09 06:53:50 +00:00
########################################################################
########################################################################
2018-07-24 04:56:38 +00:00
GetPhysical ; EA r27, batPtr r29 // PA r31, EQ=Fail
2018-07-28 06:20:23 +00:00
lwz r30, 0(r29)
li r28, -1
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
beq @_54
lwzu r30, 8(r29)
rlwimi r28, r30, 15, 0, 14
xor r31, r27, r30
andc. r31, r31, r28
bne GetPhysicalFromHTAB
2018-07-09 06:53:50 +00:00
@_54
2018-07-28 06:20:23 +00:00
andi. r31, r30, 1
rlwinm r28, r28, 0, 8, 19
lwzu r31, 4(r29)
and r28, r27, r28
or r31, r31, r28
bnelr
2018-07-09 06:53:50 +00:00
2018-07-24 04:56:38 +00:00
GetPhysicalFromHTAB ; EA r27 // PA r31, EQ=Fail
2018-07-28 06:20:23 +00:00
mfsrin r31, r27
rlwinm r30, r27, 10, 26, 31
rlwimi r30, r31, 7, 1, 24
rlwinm r28, r27, 26, 10, 25
oris r30, r30, 0x8000
rlwinm r31, r31, 6, 7, 25
xor r28, r28, r31
lwz r31, KDP.PTEGMask(r1)
lwz r29, KDP.HTABORG(r1)
and r28, r28, r31
or. r29, r29, r28
2018-07-09 06:53:50 +00:00
@_2c
2018-07-28 06:20:23 +00:00
lwz r31, 0(r29)
lwz r28, 8(r29)
cmpw cr6, r30, r31
lwz r31, 16(r29)
cmpw cr7, r30, r28
lwzu r28, 24(r29)
bne cr6, @_50
2018-07-09 06:53:50 +00:00
@_48
2018-07-28 06:20:23 +00:00
lwzu r31, -0x0014(r29)
blr
2018-07-09 06:53:50 +00:00
@_50
2018-07-28 06:20:23 +00:00
cmpw cr6, r30, r31
lwzu r31, 8(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 8(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, 8(r29)
beq cr7, @_48
cmpw cr7, r30, r28
lwzu r28, 8(r29)
beq cr6, @_48
cmpw cr6, r30, r31
lwzu r31, -0x000c(r29)
beqlr cr7
cmpw cr7, r30, r28
lwzu r31, 8(r29)
beqlr cr6
lwzu r31, 8(r29)
beqlr cr7
lwz r31, KDP.PTEGMask(r1)
xori r30, r30, 0x40
andi. r28, r30, 0x40
addi r29, r29, -0x3c
xor r29, r29, r31
bne @_2c
blr
2018-07-09 06:53:50 +00:00
########################################################################
########################################################################
FlushTLB
2018-07-28 06:20:23 +00:00
lhz r29, KDP.ProcInfo.TransCacheTotalSize(r1)
slwi r29, r29, 11
2018-07-09 06:53:50 +00:00
@loop
2018-07-28 06:20:23 +00:00
subi r29, r29, 4096
cmpwi r29, 0
tlbie r29
bgt @loop
sync
blr