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