1 /*
2 ** Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
5
6
7 #include <arch_mmu.h>
8
9 #include <arch_cpu.h>
10 #include <debug.h>
11
12
13 // Address space identifiers for the MMUs
14 // Ultrasparc User Manual, Table 6-10
15 enum {
16 instruction_control_asi = 0x50,
17 data_control_asi = 0x58,
18 instruction_8k_tsb_asi = 0x51,
19 data_8k_tsb_asi = 0x59,
20 instruction_64k_tsb_asi = 0x52,
21 data_64k_tsb_asi = 0x5A,
22 data_direct_tsb_asi = 0x5B,
23 instruction_tlb_in_asi = 0x54,
24 data_tlb_in_asi = 0x5C,
25 instruction_tlb_access_asi = 0x55,
26 data_tlb_access_asi = 0x5D,
27 instruction_tlb_read_asi = 0x56,
28 data_tlb_read_asi = 0x5E,
29 instruction_tlb_demap_asi = 0x57,
30 data_tlb_demap_asi = 0x5F,
31 };
32
33
34 // MMU register addresses
35 // Ultrasparc User Manual, Table 6-10
36 enum {
37 tsb_tag_target = 0x00, // I/D, RO
38 primary_context = 0x08, // D, RW
39 secondary_context = 0x10, // D, RW
40 synchronous_fault_status = 0x18, // I/D, RW
41 synchronous_fault_address = 0x20, // D, RO
42 tsb = 0x28, // I/D, RW
43 tlb_tag_access = 0x30, // I/D, RW
44 virtual_watchpoint = 0x38, // D, RW
45 physical_watchpoint = 0x40 // D, RW
46 };
47
48
sparc_get_instruction_tsb(TsbEntry ** _pageTable,size_t * _size)49 extern void sparc_get_instruction_tsb(TsbEntry **_pageTable, size_t *_size)
50 {
51 uint64_t tsbEntry;
52 asm("ldxa [%[mmuRegister]] 0x50, %[destination]"
53 : [destination] "=r"(tsbEntry)
54 : [mmuRegister] "r"(tsb));
55
56 *_pageTable = (TsbEntry*)(tsbEntry & ~((1ll << 13) - 1));
57 *_size = 512 * (1 << (tsbEntry & 3)) * sizeof(TsbEntry);
58 if (tsbEntry & (1 << 12))
59 *_size *= 2;
60 }
61
62
sparc_get_data_tsb(TsbEntry ** _pageTable,size_t * _size)63 extern void sparc_get_data_tsb(TsbEntry **_pageTable, size_t *_size)
64 {
65 uint64_t tsbEntry;
66 asm("ldxa [%[mmuRegister]] 0x58, %[destination]"
67 : [destination] "=r"(tsbEntry)
68 : [mmuRegister] "r"(tsb));
69
70 *_pageTable = (TsbEntry*)(tsbEntry & ~((1ll << 13) - 1));
71 *_size = 512 * (1 << (tsbEntry & 3)) * sizeof(TsbEntry);
72 if (tsbEntry & (1 << 12))
73 *_size *= 2;
74 }
75
76
77