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_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 19enum _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 33struct 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 41struct 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 */ 56struct 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/* struct types suffixed with _s */ 69typedef struct short_page_directory_entry page_root_entry_s; 70typedef struct short_page_directory_entry page_directory_entry_s; 71typedef struct short_page_table_entry page_table_entry_s; 72typedef struct short_indirect_entry page_indirect_entry_s; 73 74/* scalar storage type that maps them */ 75typedef uint32 page_root_entry; 76typedef uint32 page_directory_entry; 77typedef uint32 page_table_entry; 78typedef uint32 page_indirect_entry; 79 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 84 85/* bitmask access */ 86 87/* those are valid for all entries */ 88#define M68K_PE_READONLY 0x00000004 89#define M68K_PE_ACCESSED 0x00000008 90 91#define M68K_PRE_READONLY T M68K_PE_READONLY 92#define M68K_PRE_ACCESSED M68K_PE_ACCESSED 93#define M68K_PRE_ADDRESS_MASK 0xfffffff0 94 95#define M68K_PDE_READONLY M68K_PE_READONLY 96#define M68K_PDE_ACCESSED M68K_PE_ACCESSED 97#define M68K_PDE_ADDRESS_MASK 0xfffffff0 98 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 104 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 111 112 113#define M68K_PIE_ADDRESS_MASK 0xfffffffc 114 115 116 117/* default scalar values for entries */ 118#define DFL_ROOTENT_VAL 0x00000000 119#define DFL_DIRENT_VAL 0x00000000 120#define DFL_PAGEENT_VAL 0x00000000 121 122#define NUM_ROOTENT_PER_TBL 128 123#define NUM_DIRENT_PER_TBL 128 124#define NUM_PAGEENT_PER_TBL 64 125 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. 130 */ 131 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)) 135 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) 139 140/* macros to get the physical page or table number and address of tables from 141 * descriptors */ 142 143// TA: table address 144// PN: page number 145// PA: page address 146// PO: page offset (offset of table in page) 147// PI: page index (index of table relative to page start) 148 149// from a root entry 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) 157 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) 166 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) 173 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) 181 182/* 7/7/6 split */ 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) 186 187#endif /* _KERNEL_ARCH_M68K_040_MMU_H */ 188