xref: /haiku/src/system/kernel/arch/sparc/arch_mmu.cpp (revision 56f9c76088b8146faec4a37a3d77e5cd3047d202)
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