1*599f30f9SFrançois Revol /* 2*599f30f9SFrançois Revol * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3*599f30f9SFrançois Revol * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de. 4*599f30f9SFrançois Revol * Distributed under the terms of the MIT License. 5*599f30f9SFrançois Revol * 6*599f30f9SFrançois Revol * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 7*599f30f9SFrançois Revol * Distributed under the terms of the NewOS License. 8*599f30f9SFrançois Revol */ 9*599f30f9SFrançois Revol #ifndef _KERNEL_ARCH_M68K_PAGING_040_PAGING_H 10*599f30f9SFrançois Revol #define _KERNEL_ARCH_M68K_PAGING_040_PAGING_H 11*599f30f9SFrançois Revol 12*599f30f9SFrançois Revol 13*599f30f9SFrançois Revol #include <SupportDefs.h> 14*599f30f9SFrançois Revol 15*599f30f9SFrançois Revol #include <int.h> 16*599f30f9SFrançois Revol #include <kernel.h> 17*599f30f9SFrançois Revol 18*599f30f9SFrançois Revol #include <arch_040_mmu.h> 19*599f30f9SFrançois Revol 20*599f30f9SFrançois Revol /* (mmu_man) Implementation details on 68030 and others: 21*599f30f9SFrançois Revol 22*599f30f9SFrançois Revol Unlike on x86 we can't just switch the context to another team by just 23*599f30f9SFrançois Revol setting a register to another page directory, since we only have one 24*599f30f9SFrançois Revol page table containing both kernel and user address mappings. 25*599f30f9SFrançois Revol The 030 supports arbitrary layout of the page directory tree, including 26*599f30f9SFrançois Revol a 1-bit first level (2 entries top level table) that would map kernel 27*599f30f9SFrançois Revol and user land at a single place. But 040 and later only support a fixed 28*599f30f9SFrançois Revol splitting of 7/7/6 for 4K pages. 29*599f30f9SFrançois Revol 30*599f30f9SFrançois Revol Since 68k SMP hardware is rare enough we don't want to support them, we 31*599f30f9SFrançois Revol can take some shortcuts. 32*599f30f9SFrançois Revol 33*599f30f9SFrançois Revol As we don't want a separate user and kernel space, we'll use a single 34*599f30f9SFrançois Revol table. With the 7/7/6 split the 2nd level would require 32KB of tables, 35*599f30f9SFrançois Revol which is small enough to not want to use the list hack from x86. 36*599f30f9SFrançois Revol XXX: we use the hack for now, check later 37*599f30f9SFrançois Revol 38*599f30f9SFrançois Revol Since page directories/tables don't fit exactly a page, we stuff more 39*599f30f9SFrançois Revol than one per page, and allocate them all at once, and add them at the 40*599f30f9SFrançois Revol same time to the tree. So we guarantee all higher-level entries modulo 41*599f30f9SFrançois Revol the number of tables/page are either invalid or present. 42*599f30f9SFrançois Revol */ 43*599f30f9SFrançois Revol 44*599f30f9SFrançois Revol // 4 MB of iospace 45*599f30f9SFrançois Revol ////#define IOSPACE_SIZE (4*1024*1024) 46*599f30f9SFrançois Revol //#define IOSPACE_SIZE (16*1024*1024) 47*599f30f9SFrançois Revol // 256K = 2^6*4K 48*599f30f9SFrançois Revol //#define IOSPACE_CHUNK_SIZE (NUM_PAGEENT_PER_TBL*B_PAGE_SIZE) 49*599f30f9SFrançois Revol 50*599f30f9SFrançois Revol #define PAGE_INVALIDATE_CACHE_SIZE 64 51*599f30f9SFrançois Revol 52*599f30f9SFrançois Revol #define FIRST_USER_PGROOT_ENT (VADDR_TO_PRENT(USER_BASE)) 53*599f30f9SFrançois Revol #define FIRST_USER_PGDIR_ENT (VADDR_TO_PDENT(USER_BASE)) 54*599f30f9SFrançois Revol #define NUM_USER_PGROOT_ENTS (VADDR_TO_PRENT(ROUNDUP(USER_SIZE, B_PAGE_SIZE * 64 * 128))) 55*599f30f9SFrançois Revol #define NUM_USER_PGDIR_ENTS (VADDR_TO_PDENT(ROUNDUP(USER_SIZE, B_PAGE_SIZE * 64))) 56*599f30f9SFrançois Revol #define FIRST_KERNEL_PGROOT_ENT (VADDR_TO_PRENT(KERNEL_BASE)) 57*599f30f9SFrançois Revol #define FIRST_KERNEL_PGDIR_ENT (VADDR_TO_PDENT(KERNEL_BASE)) 58*599f30f9SFrançois Revol #define NUM_KERNEL_PGROOT_ENTS (VADDR_TO_PRENT(KERNEL_SIZE)) 59*599f30f9SFrançois Revol #define NUM_KERNEL_PGDIR_ENTS (VADDR_TO_PDENT(KERNEL_SIZE)) 60*599f30f9SFrançois Revol //#define IS_KERNEL_MAP(map) (map->arch_data->rtdir_phys == sKernelPhysicalPageRoot) 61*599f30f9SFrançois Revol 62*599f30f9SFrançois Revol 63*599f30f9SFrançois Revol // page tables are allocated as groups, so better use them all. 64*599f30f9SFrançois Revol static const size_t kPageTableAlignment = B_PAGE_SIZE 65*599f30f9SFrançois Revol * NUM_PAGETBL_PER_PAGE * NUM_PAGEENT_PER_TBL; 66*599f30f9SFrançois Revol 67*599f30f9SFrançois Revol static const size_t kPageDirAlignment = B_PAGE_SIZE 68*599f30f9SFrançois Revol * NUM_PAGEENT_PER_TBL 69*599f30f9SFrançois Revol * NUM_DIRTBL_PER_PAGE * NUM_DIRENT_PER_TBL; 70*599f30f9SFrançois Revol 71*599f30f9SFrançois Revol 72*599f30f9SFrançois Revol 73*599f30f9SFrançois Revol #if 0 74*599f30f9SFrançois Revol 75*599f30f9SFrançois Revol #define VADDR_TO_PDENT(va) (((va) / B_PAGE_SIZE) / 1024) 76*599f30f9SFrançois Revol #define VADDR_TO_PTENT(va) (((va) / B_PAGE_SIZE) % 1024) 77*599f30f9SFrançois Revol 78*599f30f9SFrançois Revol 79*599f30f9SFrançois Revol // page directory entry bits 80*599f30f9SFrançois Revol #define M68K_PDE_PRESENT 0x00000001 81*599f30f9SFrançois Revol #define M68K_PDE_WRITABLE 0x00000002 82*599f30f9SFrançois Revol #define M68K_PDE_USER 0x00000004 83*599f30f9SFrançois Revol #define M68K_PDE_WRITE_THROUGH 0x00000008 84*599f30f9SFrançois Revol #define M68K_PDE_CACHING_DISABLED 0x00000010 85*599f30f9SFrançois Revol #define M68K_PDE_ACCESSED 0x00000020 86*599f30f9SFrançois Revol #define M68K_PDE_IGNORED1 0x00000040 87*599f30f9SFrançois Revol #define M68K_PDE_RESERVED1 0x00000080 88*599f30f9SFrançois Revol #define M68K_PDE_IGNORED2 0x00000100 89*599f30f9SFrançois Revol #define M68K_PDE_IGNORED3 0x00000200 90*599f30f9SFrançois Revol #define M68K_PDE_IGNORED4 0x00000400 91*599f30f9SFrançois Revol #define M68K_PDE_IGNORED5 0x00000800 92*599f30f9SFrançois Revol #define M68K_PDE_ADDRESS_MASK 0xfffff000 93*599f30f9SFrançois Revol 94*599f30f9SFrançois Revol // page table entry bits 95*599f30f9SFrançois Revol #define M68K_PTE_PRESENT 0x00000001 96*599f30f9SFrançois Revol #define M68K_PTE_WRITABLE 0x00000002 97*599f30f9SFrançois Revol #define M68K_PTE_USER 0x00000004 98*599f30f9SFrançois Revol #define M68K_PTE_WRITE_THROUGH 0x00000008 99*599f30f9SFrançois Revol #define M68K_PTE_CACHING_DISABLED 0x00000010 100*599f30f9SFrançois Revol #define M68K_PTE_ACCESSED 0x00000020 101*599f30f9SFrançois Revol #define M68K_PTE_DIRTY 0x00000040 102*599f30f9SFrançois Revol #define M68K_PTE_PAT 0x00000080 103*599f30f9SFrançois Revol #define M68K_PTE_GLOBAL 0x00000100 104*599f30f9SFrançois Revol #define M68K_PTE_IGNORED1 0x00000200 105*599f30f9SFrançois Revol #define M68K_PTE_IGNORED2 0x00000400 106*599f30f9SFrançois Revol #define M68K_PTE_IGNORED3 0x00000800 107*599f30f9SFrançois Revol #define M68K_PTE_ADDRESS_MASK 0xfffff000 108*599f30f9SFrançois Revol #define M68K_PTE_PROTECTION_MASK (M68K_PTE_WRITABLE | M68K_PTE_USER) 109*599f30f9SFrançois Revol #define M68K_PTE_MEMORY_TYPE_MASK (M68K_PTE_WRITE_THROUGH \ 110*599f30f9SFrançois Revol | M68K_PTE_CACHING_DISABLED) 111*599f30f9SFrançois Revol 112*599f30f9SFrançois Revol #define FIRST_USER_PGDIR_ENT (VADDR_TO_PDENT(USER_BASE)) 113*599f30f9SFrançois Revol #define NUM_USER_PGDIR_ENTS (VADDR_TO_PDENT(ROUNDUP(USER_SIZE, \ 114*599f30f9SFrançois Revol B_PAGE_SIZE * 1024))) 115*599f30f9SFrançois Revol #define FIRST_KERNEL_PGDIR_ENT (VADDR_TO_PDENT(KERNEL_BASE)) 116*599f30f9SFrançois Revol #define NUM_KERNEL_PGDIR_ENTS (VADDR_TO_PDENT(KERNEL_SIZE)) 117*599f30f9SFrançois Revol 118*599f30f9SFrançois Revol 119*599f30f9SFrançois Revol static const size_t kPageTableAlignment = 1024 * B_PAGE_SIZE; 120*599f30f9SFrançois Revol 121*599f30f9SFrançois Revol 122*599f30f9SFrançois Revol typedef uint32 page_table_entry; 123*599f30f9SFrançois Revol typedef uint32 page_directory_entry; 124*599f30f9SFrançois Revol 125*599f30f9SFrançois Revol #endif // 0 126*599f30f9SFrançois Revol 127*599f30f9SFrançois Revol #endif // _KERNEL_ARCH_M68K_PAGING_040_PAGING_H 128