xref: /haiku/headers/private/kernel/arch/m68k/arch_040_mmu.h (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
1 /*
2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the OpenBeOS License.
4 */
5 #ifndef _KERNEL_ARCH_M68K_040_MMU_H
6 #define _KERNEL_ARCH_M68K_040_MMU_H
7 
8 
9 #include <SupportDefs.h>
10 #include <string.h>
11 
12 #include <arch_mmu.h>
13 
14 // global pages only available on 040/060
15 // check this
16 #define MMU_HAS_GLOBAL_PAGES
17 
18 
19 enum _mmu040_cache_mode {
20 	CM_CACHABLE_WRITETHROUGH,
21 	CM_CACHABLE_COPYBACK,
22 	CM_DISABLED_SERIALIZED,
23 	CM_DISABLED,
24 };
25 
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.
30  */
31 											// = names in MC user's manual
32 											// or comments
33 struct short_page_directory_entry {
34 	// upper 32 bits
35 	uint32 addr : 28;						// address
36 	uint32 accessed : 1;					// = used
37 	uint32 write_protect : 1;
38 	uint32 type : 2;						// DT_*
39 };
40 
41 struct short_page_table_entry {
42 	uint32 addr : 20;						// address
43 	uint32 user_reserved : 1;
44 	uint32 global : 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;
52 	uint32 type : 2;
53 };
54 
55 /* rarely used */
56 struct short_indirect_entry {
57 	// upper 32 bits
58 	uint32 addr : 30;						// address
59 	uint32 type : 2;						// DT_*
60 };
61 
62 /* for clarity:
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)
66 */
67 
68 typedef struct short_page_directory_entry page_root_entry;
69 typedef struct short_page_directory_entry page_directory_entry;
70 typedef struct short_page_table_entry page_table_entry;
71 typedef struct short_indirect_entry page_indirect_entry;
72 
73 /* scalar storage type that maps them */
74 typedef uint32 page_root_entry_scalar;
75 typedef uint32 page_directory_entry_scalar;
76 typedef uint32 page_table_entry_scalar;
77 typedef uint32 page_indirect_entry_scalar;
78 
79 #define DT_ROOT DT_VALID_4
80 #define DT_DIR DT_VALID_4
81 //#define DT_PAGE DT_PAGE :)
82 #define DT_INDIRECT DT_VALID_4
83 
84 /* default scalar values for entries */
85 #define DFL_ROOTENT_VAL 0x00000000
86 #define DFL_DIRENT_VAL 0x00000000
87 #define DFL_PAGEENT_VAL 0x00000000
88 
89 #define NUM_ROOTENT_PER_TBL 128
90 #define NUM_DIRENT_PER_TBL 128
91 #define NUM_PAGEENT_PER_TBL 64
92 
93 /* unlike x86, the root/dir/page table sizes are different than B_PAGE_SIZE
94  * so we will have to fit more than one on a page to avoid wasting space.
95  * We will allocate a group of tables with the one we want inside, and
96  * add them from the aligned index needed, to make it easy to free them.
97  */
98 
99 #define SIZ_ROOTTBL (NUM_ROOTENT_PER_TBL * sizeof(page_root_entry))
100 #define SIZ_DIRTBL (NUM_DIRENT_PER_TBL * sizeof(page_directory_entry))
101 #define SIZ_PAGETBL (NUM_PAGEENT_PER_TBL * sizeof(page_table_entry))
102 
103 //#define NUM_ROOTTBL_PER_PAGE (B_PAGE_SIZE / SIZ_ROOTTBL)
104 #define NUM_DIRTBL_PER_PAGE (B_PAGE_SIZE / SIZ_DIRTBL)
105 #define NUM_PAGETBL_PER_PAGE (B_PAGE_SIZE / SIZ_PAGETBL)
106 
107 /* macros to get the physical page or table number and address of tables from
108  * descriptors */
109 
110 // TA: table address
111 // PN: page number
112 // PA: page address
113 // PO: page offset (offset of table in page)
114 // PI: page index (index of table relative to page start)
115 
116 // from a root entry
117 #define PRE_TO_TA(a) ((*(uint32 *)(&(a))) & ~((1<<9)-1))
118 #define PRE_TO_PN(e) ((*(uint32 *)(&(e))) >> 12)
119 #define PRE_TO_PA(e) ((*(uint32 *)(&(e))) & ~((1<<12)-1))
120 //#define PRE_TO_PO(e) ((*(uint32 *)(&(e))) & ((1<<12)-1))
121 //#define PRE_TO_PI(e) (((*(uint32 *)(&(e))) & ((1<<12)-1)) / SIZ_DIRTBL)
122 #define TA_TO_PREA(a) ((a) >> 4)
123 // from a directory entry
124 #define PDE_TO_TA(a) ((*(uint32 *)(&(a))) & ~((1<<8)-1))
125 #define PDE_TO_PN(e) ((*(uint32 *)(&(e))) >> 12)
126 #define PDE_TO_PA(e) ((*(uint32 *)(&(e))) & ~((1<<12)-1))
127 //#define PDE_TO_PO(e) ((*(uint32 *)(&(e))) & ((1<<12)-1))
128 //#define PDE_TO_PI(e) (((*(uint32 *)(&(e))) & ((1<<12)-1)) / SIZ_PAGETBL)
129 #define TA_TO_PDEA(a) ((a) >> 4)
130 // from a table entry
131 #define PTE_TO_TA(a) ((*((uint32 *)(&(a)))) & ~((1<<12)-1))
132 #define PTE_TO_PN(e) ((*((uint32 *)(&(e)))) >> 12)
133 #define PTE_TO_PA(e) ((*((uint32 *)(&(e)))) & ~((1<<12)-1))
134 #define TA_TO_PTEA(a) ((a) >> 12)
135 // from an indirect entry
136 #define PIE_TO_TA(a) ((*((uint32 *)(&(a)))) & ~((1<<2)-1))
137 #define PIE_TO_PN(e) ((*((uint32 *)(&(e)))) >> 12)
138 #define PIE_TO_PA(e) ((*((uint32 *)(&(e)))) & ~((1<<12)-1))
139 #define PIE_TO_PO(e) ((*((uint32 *)(&(e)))) & ((1<<12)-(1<<2)))
140 #define TA_TO_PIEA(a) ((a) >> 2)
141 
142 /* 7/7/6 split */
143 #define VADDR_TO_PRENT(va) (((va) / B_PAGE_SIZE) / (64*128))
144 #define VADDR_TO_PDENT(va) ((((va) / B_PAGE_SIZE) / 64) % 128)
145 #define VADDR_TO_PTENT(va) (((va) / B_PAGE_SIZE) % 64)
146 
147 #endif	/* _KERNEL_ARCH_M68K_040_MMU_H */
148