2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the MIT License.
5 #ifndef _KERNEL_ARCH_M68K_040_MMU_H
6 #define _KERNEL_ARCH_M68K_040_MMU_H
9 #include <SupportDefs.h>
14 // global pages only available on 040/060
16 #define MMU_HAS_GLOBAL_PAGES
19 enum _mmu040_cache_mode
{
20 CM_CACHABLE_WRITETHROUGH
,
22 CM_DISABLED_SERIALIZED
,
26 /* This is the normal layout of the descriptors, as per documentation.
27 * When page size > 256, several bits are unused in the LSB of page
28 * addresses, which we can use in addition of other unused bits.
29 * the structs dedlared later reflect this for 4K pages.
31 // = names in MC user's manual
33 struct short_page_directory_entry
{
35 uint32 addr
: 28; // address
36 uint32 accessed
: 1; // = used
37 uint32 write_protect
: 1;
38 uint32 type
: 2; // DT_*
41 struct short_page_table_entry
{
42 uint32 addr
: 20; // address
43 uint32 user_reserved
: 1;
45 uint32 upa0
: 1; // User Page Attribute 0
46 uint32 upa1
: 1; // User Page Attribute 1
47 uint32 supervisor
: 1;
48 uint32 cache_mode
: 2;
49 uint32 dirty
: 1; // = modified
50 uint32 accessed
: 1; // = used
51 uint32 write_protect
: 1;
56 struct short_indirect_entry
{
58 uint32 addr
: 30; // address
59 uint32 type
: 2; // DT_*
63 - the top level page directory will be called "page root", (root or rtdir)
64 - the 2nd level will be "page directory" like on x86, (pgdir)
65 - the 3rd level is a "page table" as on x86. (pgtbl)
68 /* struct types suffixed with _s */
69 typedef struct short_page_directory_entry page_root_entry_s
;
70 typedef struct short_page_directory_entry page_directory_entry_s
;
71 typedef struct short_page_table_entry page_table_entry_s
;
72 typedef struct short_indirect_entry page_indirect_entry_s
;
74 /* scalar storage type that maps them */
75 typedef uint32 page_root_entry
;
76 typedef uint32 page_directory_entry
;
77 typedef uint32 page_table_entry
;
78 typedef uint32 page_indirect_entry
;
80 #define DT_ROOT DT_VALID_4
81 #define DT_DIR DT_VALID_4
82 //#define DT_PAGE DT_PAGE :)
83 #define DT_INDIRECT DT_VALID_4
87 /* those are valid for all entries */
88 #define M68K_PE_READONLY 0x00000004
89 #define M68K_PE_ACCESSED 0x00000008
91 #define M68K_PRE_READONLY T M68K_PE_READONLY
92 #define M68K_PRE_ACCESSED M68K_PE_ACCESSED
93 #define M68K_PRE_ADDRESS_MASK 0xfffffff0
95 #define M68K_PDE_READONLY M68K_PE_READONLY
96 #define M68K_PDE_ACCESSED M68K_PE_ACCESSED
97 #define M68K_PDE_ADDRESS_MASK 0xfffffff0
99 #define M68K_PTE_READONLY M68K_PE_READONLY
100 #define M68K_PTE_ACCESSED M68K_PE_ACCESSED
101 #define M68K_PTE_DIRTY 0x00000010
102 #define M68K_PTE_CACHE_MODE_MASK 0x00000060
103 #define M68K_PTE_CACHE_MODE_SHIFT 5
105 #define M68K_PTE_SUPERVISOR 0x00000080
106 #define M68K_PTE_UPA1 0x00000100
107 #define M68K_PTE_UPA0 0x00000200
108 #define M68K_PTE_GLOBAL 0x00000400
109 #define M68K_PTE_USER_RESERVED 0x00000800
110 #define M68K_PTE_ADDRESS_MASK 0xfffff000
113 #define M68K_PIE_ADDRESS_MASK 0xfffffffc
117 /* default scalar values for entries */
118 #define DFL_ROOTENT_VAL 0x00000000
119 #define DFL_DIRENT_VAL 0x00000000
120 #define DFL_PAGEENT_VAL 0x00000000
122 #define NUM_ROOTENT_PER_TBL 128
123 #define NUM_DIRENT_PER_TBL 128
124 #define NUM_PAGEENT_PER_TBL 64
126 /* unlike x86, the root/dir/page table sizes are different than B_PAGE_SIZE
127 * so we will have to fit more than one on a page to avoid wasting space.
128 * We will allocate a group of tables with the one we want inside, and
129 * add them from the aligned index needed, to make it easy to free them.
132 #define SIZ_ROOTTBL (NUM_ROOTENT_PER_TBL * sizeof(page_root_entry))
133 #define SIZ_DIRTBL (NUM_DIRENT_PER_TBL * sizeof(page_directory_entry))
134 #define SIZ_PAGETBL (NUM_PAGEENT_PER_TBL * sizeof(page_table_entry))
136 //#define NUM_ROOTTBL_PER_PAGE (B_PAGE_SIZE / SIZ_ROOTTBL)
137 #define NUM_DIRTBL_PER_PAGE (B_PAGE_SIZE / SIZ_DIRTBL)
138 #define NUM_PAGETBL_PER_PAGE (B_PAGE_SIZE / SIZ_PAGETBL)
140 /* macros to get the physical page or table number and address of tables from
146 // PO: page offset (offset of table in page)
147 // PI: page index (index of table relative to page start)
150 #define PRE_TYPE(e) ((e) & M68K_PE_DT_MASK)
151 #define PRE_TO_TA(e) (((uint32)(e)) & ~((1<<9)-1))
152 #define PRE_TO_PN(e) (((uint32)(e)) >> 12)
153 #define PRE_TO_PA(e) (((uint32)(e)) & ~((1<<12)-1))
154 //#define PRE_TO_PO(e) (((uint32)(e)) & ((1<<12)-1))
155 //#define PRE_TO_PI(e) ((((uint32)(e)) & ((1<<12)-1)) / SIZ_DIRTBL)
156 #define TA_TO_PREA(a) ((a) & M68K_PRE_ADDRESS_MASK)
158 // from a directory entry
159 #define PDE_TYPE(e) ((e) & M68K_PE_DT_MASK)
160 #define PDE_TO_TA(e) (((uint32)(e)) & ~((1<<8)-1))
161 #define PDE_TO_PN(e) (((uint32)(e)) >> 12)
162 #define PDE_TO_PA(e) (((uint32)(e)) & ~((1<<12)-1))
163 //#define PDE_TO_PO(e) (((uint32)(e)) & ((1<<12)-1))
164 //#define PDE_TO_PI(e) ((((uint32)(e)) & ((1<<12)-1)) / SIZ_PAGETBL)
165 #define TA_TO_PDEA(a) ((a) & M68K_PDE_ADDRESS_MASK)
167 // from a table entry
168 #define PTE_TYPE(e) ((e) & M68K_PE_DT_MASK)
169 #define PTE_TO_TA(e) (((uint32)(e)) & ~((1<<12)-1))
170 #define PTE_TO_PN(e) (((uint32)(e)) >> 12)
171 #define PTE_TO_PA(e) (((uint32)(e)) & ~((1<<12)-1))
172 #define TA_TO_PTEA(a) ((a) & M68K_PTE_ADDRESS_MASK)
174 // from an indirect entry
175 #define PIE_TYPE(e) ((e) & M68K_PE_DT_MASK)
176 #define PIE_TO_TA(e) (((uint32)(e)) & ~((1<<2)-1))
177 #define PIE_TO_PN(e) (((uint32)(e)) >> 12)
178 #define PIE_TO_PA(e) (((uint32)(e)) & ~((1<<12)-1))
179 #define PIE_TO_PO(e) (((uint32)(e)) & ((1<<12)-(1<<2)))
180 #define TA_TO_PIEA(a) ((a) & M68K_PIE_ADDRESS_MASK)
183 #define VADDR_TO_PRENT(va) (((va) / B_PAGE_SIZE) / (64*128))
184 #define VADDR_TO_PDENT(va) ((((va) / B_PAGE_SIZE) / 64) % 128)
185 #define VADDR_TO_PTENT(va) (((va) / B_PAGE_SIZE) % 64)
187 #endif /* _KERNEL_ARCH_M68K_040_MMU_H */