fx@3.10: first take at TLB miss handling in %003

This commit is contained in:
Lephenixnoir 2020-06-11 22:09:31 +02:00
parent 782b7849d8
commit 6a56b61da0
Signed by untrusted user: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
2 changed files with 114 additions and 0 deletions

112
asm/fx@3.10/%003.txt Normal file
View File

@ -0,0 +1,112 @@
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.
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.
<%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

View File

@ -4,6 +4,8 @@ name: syscalls-lephe
%000 sys_init
%004 tlb_init
%016 System_ERROR_popup
%025 t6k11_read_datareg
%3fc tlb_map
%ac9 longjmp