190 lines
6.5 KiB
Plaintext
190 lines
6.5 KiB
Plaintext
Syscall %003 from Graph 35+E II OS 3.10
|
|
|
|
Disassembly objective:
|
|
Understand how TLB misses are handled to hopefully find a stable way of
|
|
calling the OS to manage the TLB from gint.
|
|
|
|
Conclusions:
|
|
* %003 answers the TLB miss by reading page values from an array in RAM. This
|
|
array is likely populated from filesystem when the add-in is loaded. %003
|
|
only answers TLB misses from ROM, which supports the idea that RAM pages
|
|
remain mapped all the time.
|
|
* %016 is the System ERROR popup; I haven't disassembled it yet, but I found
|
|
the "System ERROR!!" string in it so no doubt is possible.
|
|
* The subroutine at <80011238> loads to TLB a value of PTEH with ASID=0, so
|
|
ASID is probably staying at 0 all the time.
|
|
|
|
Discovered RAM memory:
|
|
0x8800c944: u32[] ADDIN_PAGE_TABLE
|
|
Page table for the add-in. Each entry is a pointer to ROM or P2 ROM.
|
|
-> Entries with NULL are considered invalid.
|
|
-> Other values are masked & 0x1fffffff and put to PTEL; clearly, these are
|
|
the matching physical addresses.
|
|
0x8800d144: u32 NEXT_TLB_EVICTION
|
|
Number of the next TLB entry to be evicted on a TLB miss. This varies
|
|
between 0 and 53 only, making sure that entries 54..63 remain in the TLB at
|
|
all times. According to experience, this covers RAM mappings and the 4k
|
|
page mapping NULL to ROM.
|
|
|
|
<%003 vbr_tlb_exception>
|
|
@PTEH @TEA Address that generated the TLB miss
|
|
Also takes some input from the stack, 54 bytes deep into the caller's frame
|
|
(likely saved registers from calling process) in case of error.
|
|
|
|
Stack> || r14 pr (likely caller's SPC:u32) (phys_addr:u32) (108)
|
|
(PTEH & 0xfffff000 = VPN; on error, TEA)
|
|
|
|
# Fill up the stack; r6=00300000
|
|
800113ce: 2fe6 mov.l r14, @-r15
|
|
800113d0: 4f22 sts.l pr, @-r15
|
|
800113d2: 7ff0 add #-16, r15
|
|
800113d4: eeff mov #-1, r14
|
|
800113d6: e1f0 mov #-16, r1
|
|
800113d8: 4e18 shll8 r14
|
|
800113da: e630 mov #48, r6
|
|
800113dc: 4e28 shll16 r14
|
|
800113de: 4118 shll8 r1
|
|
800113e0: 62e2 mov.l @r14, r2
|
|
800113e2: 4628 shll16 r6
|
|
800113e4: 2219 and r1, r2
|
|
800113e6: 2f22 mov.l r2, @r15
|
|
|
|
#---
|
|
# TLB miss resolution
|
|
#---
|
|
|
|
# If PTEH.VPN < 00300000, fail resolution
|
|
800113e8: 61f2 mov.l @r15, r1
|
|
800113ea: 3162 cmp/hs r6, r1
|
|
800113ec: 8b13 bf <80011416>
|
|
# r0 = (VPN - 00300000) >> 12 = VPN's page number in add-in ROM
|
|
800113ee: e16c mov #108, r1
|
|
800113f0: 1f11 mov.l r1, @(4,r15)
|
|
800113f2: 60f2 mov.l @r15, r0
|
|
800113f4: e2f4 mov #-12, r2
|
|
800113f6: d53a mov.l 0x8800c944, r5
|
|
800113f8: 3068 sub r6, r0
|
|
800113fa: 402d shld r2, r0
|
|
# phys_addr = ADDIN_PAGE_TABLE[r0] & 0x1fffffff; if NULL, fail resolution
|
|
800113fc: 4008 shll2 r0
|
|
800113fe: 065e mov.l @(r0,r5), r6
|
|
80011400: 2668 tst r6, r6
|
|
80011402: 8908 bt <80011416>
|
|
80011404: d237 mov.l 0x1fffffff, r2
|
|
80011406: 2629 and r2, r6
|
|
80011408: 1f62 mov.l r6, @(8,r15)
|
|
# <80011238>(VPN, phys_addr, 108)
|
|
8001140a: 56f1 mov.l @(4,r15), r6
|
|
8001140c: 64f2 mov.l @r15, r4
|
|
8001140e: bf13 bsr <80011238>
|
|
80011410: 55f2 mov.l @(8,r15), r5
|
|
80011412: a002 bra <8001141a>
|
|
80011414: 0009 nop
|
|
|
|
# If resolution fails, set VPN=NULL
|
|
80011416: e100 mov #0, r1
|
|
80011418: 2f12 mov.l r1, @r15
|
|
|
|
#---
|
|
# When resolution fails (if VPN is now NULL)
|
|
#---
|
|
|
|
# r0 = GetStackPtr() + 68 = 54 bytes under this function's frame; likely the
|
|
# value of SPC stored by the interrupt handler.
|
|
8001141a: 61f2 mov.l @r15, r1
|
|
8001141c: 2118 tst r1, r1
|
|
8001141e: 8b0b bf <80011438>
|
|
80011420: d731 mov.l %3fe GetStackPtr, r7
|
|
80011422: 54e3 mov.l @(12,r14), r4
|
|
80011424: 470b jsr @r7
|
|
80011426: 2f42 mov.l r4, @r15
|
|
80011428: 7044 add #68, r0
|
|
8001142a: 1f03 mov.l r0, @(12,r15)
|
|
8001142c: 51f3 mov.l @(12,r15), r1
|
|
8001142e: 6612 mov.l @r1, r6
|
|
80011430: 1f63 mov.l r6, @(12,r15)
|
|
|
|
# System_ERROR_popup(TEA, <stack value from above>, <again>)
|
|
80011432: 64f2 mov.l @r15, r4
|
|
80011434: beb2 bsr %016 System_ERROR_popup
|
|
80011436: 55f3 mov.l @(12,r15), r5
|
|
|
|
#---
|
|
# Epilogue
|
|
#---
|
|
|
|
80011438: 7f10 add #16, r15
|
|
8001143a: 4f26 lds.l @r15+, pr
|
|
8001143c: 000b rts
|
|
8001143e: 6ef6 mov.l @r15+, r14
|
|
|
|
#---
|
|
|
|
<80011238>
|
|
@r4 VPN to be updated
|
|
@r5 Corresponding physical address
|
|
@r6 Low bits of PTEL (=108 when called from %003)
|
|
|
|
Stack> || r15 (r6) (r5) (r4)
|
|
|
|
# r14 = ff000000 (MMU register base)
|
|
# r3 = a0000000 (random address for cache invalidation)
|
|
# MMUCR = (MMUCR & ffff03ff) | (NEXT_TLB_EVICTION << 8); this replace URC with
|
|
# the chosen NEXT_TLB_EVICTION entry to control eviction.
|
|
80011238: 2fe6 mov.l r14, @-r15
|
|
8001123a: 7ff4 add #-12, r15
|
|
8001123c: d7a1 mov.l 0x8800d144, r7
|
|
8001123e: eeff mov #-1, r14
|
|
80011240: 4e18 shll8 r14
|
|
80011242: d3a1 mov.l 0xffff03ff, r3
|
|
80011244: 4e28 shll16 r14
|
|
80011246: 1f62 mov.l r6, @(8,r15)
|
|
80011248: 2f42 mov.l r4, @r15
|
|
8001124a: 52e4 mov.l @(16,r14), r2
|
|
8001124c: 6172 mov.l @r7, r1
|
|
8001124e: 2239 and r3, r2
|
|
80011250: e3a0 mov #-96, r3
|
|
80011252: 4118 shll8 r1
|
|
80011254: 1f51 mov.l r5, @(4,r15)
|
|
80011256: 4108 shll2 r1
|
|
80011258: 4318 shll8 r3
|
|
8001125a: 221b or r1, r2
|
|
8001125c: 1e24 mov.l r2, @(16,r14)
|
|
8001125e: 4328 shll16 r3
|
|
|
|
# Invalidate instruction cache; load to TLB with
|
|
# -> PTEH=r4 (ASID implicitly 0)
|
|
# -> PTEL=r5|r6|0x110; when r6=108, this gives r5|0x17c:
|
|
# WT=0: Copy-back mode
|
|
# SH=0: Not shared (we're single process anyway)
|
|
# C=D=V=1: Cacheable, Dirty, Valid
|
|
# PR=3: All rings can read and write
|
|
# SZ=1: Page is 4k
|
|
80011260: 03e3 icbi @r3
|
|
80011262: 2e42 mov.l r4, @r14
|
|
80011264: e744 mov #68, r7
|
|
80011266: 4708 shll2 r7
|
|
80011268: 256b or r6, r5
|
|
8001126a: 257b or r7, r5
|
|
8001126c: 1e51 mov.l r5, @(4,r14)
|
|
8001126e: 0038 ldtlb
|
|
80011270: 0009 nop
|
|
80011272: 0009 nop
|
|
80011274: 0009 nop
|
|
|
|
# Invalidate instruction cache again; increment NEXT_TLB_EVICTION modulo 54
|
|
# and leave.
|
|
80011276: d193 mov.l 0x8800d144, r1
|
|
80011278: 03e3 icbi @r3
|
|
8001127a: ee36 mov #54, r14
|
|
8001127c: 6212 mov.l @r1, r2
|
|
8001127e: 32e3 cmp/ge r14, r2
|
|
80011280: 8901 bt <80011286>
|
|
80011282: a001 bra <80011288>
|
|
80011284: 7201 add #1, r2
|
|
80011286: e200 mov #0, r2
|
|
80011288: 2122 mov.l r2, @r1
|
|
8001128a: 7f0c add #12, r15
|
|
8001128c: 000b rts
|
|
8001128e: 6ef6 mov.l @r15+, r14
|