1 /*
2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
5 #ifndef _KERNEL_ARCH_PPC_MMU_H
6 #define _KERNEL_ARCH_PPC_MMU_H
7
8
9 #include <SupportDefs.h>
10 #include <string.h>
11
12 #include <arch_cpu.h>
13
14
15 /*** BAT - block address translation ***/
16
17 enum bat_length {
18 BAT_LENGTH_128kB = 0x0000,
19 BAT_LENGTH_256kB = 0x0001,
20 BAT_LENGTH_512kB = 0x0003,
21 BAT_LENGTH_1MB = 0x0007,
22 BAT_LENGTH_2MB = 0x000f,
23 BAT_LENGTH_4MB = 0x001f,
24 BAT_LENGTH_8MB = 0x003f,
25 BAT_LENGTH_16MB = 0x007f,
26 BAT_LENGTH_32MB = 0x00ff,
27 BAT_LENGTH_64MB = 0x01ff,
28 BAT_LENGTH_128MB = 0x03ff,
29 BAT_LENGTH_256MB = 0x07ff,
30 };
31
32 enum bat_protection {
33 BAT_READ_ONLY = 1,
34 BAT_READ_WRITE = 2,
35 };
36
37 struct block_address_translation {
38 // upper 32 bit
39 uint32 page_index : 15; // BEPI, block effective page index
40 uint32 _reserved0 : 4;
41 uint32 length : 11;
42 uint32 kernel_valid : 1; // Vs, Supervisor-state valid
43 uint32 user_valid : 1; // Vp, User-state valid
44 // lower 32 bit
45 uint32 physical_block_number : 15; // BPRN
46 uint32 write_through : 1; // WIMG
47 uint32 caching_inhibited : 1;
48 uint32 memory_coherent : 1;
49 uint32 guarded : 1;
50 uint32 _reserved1 : 1;
51 uint32 protection : 2;
52
block_address_translationblock_address_translation53 block_address_translation()
54 {
55 Clear();
56 }
57
SetVirtualAddressblock_address_translation58 void SetVirtualAddress(void *address)
59 {
60 page_index = uint32(address) >> 17;
61 }
62
SetPhysicalAddressblock_address_translation63 void SetPhysicalAddress(void *address)
64 {
65 physical_block_number = uint32(address) >> 17;
66 }
67
Clearblock_address_translation68 void Clear()
69 {
70 memset((void *)this, 0, sizeof(block_address_translation));
71 }
72 };
73
74 struct segment_descriptor {
75 uint32 type : 1; // 0 for page translation descriptors
76 uint32 kernel_protection_key : 1; // Ks, Supervisor-state protection key
77 uint32 user_protection_key : 1; // Kp, User-state protection key
78 uint32 no_execute_protection : 1;
79 uint32 _reserved : 4;
80 uint32 virtual_segment_id : 24;
81
segment_descriptorsegment_descriptor82 segment_descriptor()
83 {
84 Clear();
85 }
86
segment_descriptorsegment_descriptor87 segment_descriptor(uint32 value)
88 {
89 *((uint32 *)this) = value;
90 }
91
Clearsegment_descriptor92 void Clear()
93 {
94 memset((void *)this, 0, sizeof(segment_descriptor));
95 }
96 };
97
98
99 /*** PTE - page table entry ***/
100
101 enum pte_protection {
102 PTE_READ_ONLY = 3,
103 PTE_READ_WRITE = 2,
104 };
105
106 struct page_table_entry {
107 // upper 32 bit
108 uint32 valid : 1;
109 uint32 virtual_segment_id : 24;
110 uint32 secondary_hash : 1;
111 uint32 abbr_page_index : 6;
112 // lower 32 bit
113 uint32 physical_page_number : 20;
114 uint32 _reserved0 : 3;
115 uint32 referenced : 1;
116 uint32 changed : 1;
117 uint32 write_through : 1; // WIMG
118 uint32 caching_inhibited : 1;
119 uint32 memory_coherent : 1;
120 uint32 guarded : 1;
121 uint32 _reserved1 : 1;
122 uint32 page_protection : 2;
123
124 static uint32 PrimaryHash(uint32 virtualSegmentID, uint32 virtualAddress);
125 static uint32 SecondaryHash(uint32 virtualSegmentID, uint32 virtualAddress);
126 static uint32 SecondaryHash(uint32 primaryHash);
127 };
128
129 struct page_table_entry_group {
130 struct page_table_entry entry[8];
131 };
132
133 extern void ppc_get_page_table(page_table_entry_group **_pageTable, size_t *_size);
134 extern void ppc_set_page_table(page_table_entry_group *pageTable, size_t size);
135
136 static inline segment_descriptor
ppc_get_segment_register(void * virtualAddress)137 ppc_get_segment_register(void *virtualAddress)
138 {
139 return (segment_descriptor)get_sr(virtualAddress);
140 }
141
142
143 static inline void
ppc_set_segment_register(void * virtualAddress,segment_descriptor segment)144 ppc_set_segment_register(void *virtualAddress, segment_descriptor segment)
145 {
146 set_sr(virtualAddress, *(uint32 *)&segment);
147 }
148
149 #endif /* _KERNEL_ARCH_PPC_MMU_H */
150