xref: /haiku/headers/private/kernel/arch/ppc/arch_mmu.h (revision b6f76ebe7153b94820cf35f8db4facc158841abb)
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