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
17enum 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
32enum bat_protection {
33	BAT_READ_ONLY = 1,
34	BAT_READ_WRITE = 2,
35};
36
37struct 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
53	block_address_translation()
54	{
55		Clear();
56	}
57
58	void SetVirtualAddress(void *address)
59	{
60		page_index = uint32(address) >> 17;
61	}
62
63	void SetPhysicalAddress(void *address)
64	{
65		physical_block_number = uint32(address) >> 17;
66	}
67
68	void Clear()
69	{
70		memset((void *)this, 0, sizeof(block_address_translation));
71	}
72};
73
74struct 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
82	segment_descriptor()
83	{
84		Clear();
85	}
86
87	segment_descriptor(uint32 value)
88	{
89		*((uint32 *)this) = value;
90	}
91
92	void Clear()
93	{
94		memset((void *)this, 0, sizeof(segment_descriptor));
95	}
96};
97
98
99/*** PTE - page table entry ***/
100
101enum pte_protection {
102	PTE_READ_ONLY	= 3,
103	PTE_READ_WRITE	= 2,
104};
105
106struct 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
129struct page_table_entry_group {
130	struct page_table_entry entry[8];
131};
132
133extern void ppc_get_page_table(page_table_entry_group **_pageTable, size_t *_size);
134extern void ppc_set_page_table(page_table_entry_group *pageTable, size_t size);
135
136static inline segment_descriptor
137ppc_get_segment_register(void *virtualAddress)
138{
139	return (segment_descriptor)get_sr(virtualAddress);
140}
141
142
143static inline void
144ppc_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