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
15enum {
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
36enum {
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
49extern 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
63extern 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