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