1 /* pgtsun4c.h: Sun4c specific pgtable.h defines and code. 2 * 3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 */ 5 #ifndef _SPARC_PGTSUN4C_H 6 #define _SPARC_PGTSUN4C_H 7 8 #define SUN4C_PAGE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */ 9 10 /* NOTE: Now we put the free page pool and the page structures 11 * up in high memory above the kernel image which itself 12 * starts at KERNBASE. Also note PAGE_OFFSET in page.h 13 * This is just like what Linus does on the ALPHA. 14 */ 15 16 /* PMD_SHIFT determines the size of the area a second-level page table can map */ 17 #define SUN4C_PMD_SHIFT 22 18 #define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT) 19 #define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1)) 20 #define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK) 21 22 /* PGDIR_SHIFT determines what a third-level page table entry can map */ 23 #define SUN4C_PGDIR_SHIFT 22 24 #define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT) 25 #define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1)) 26 #define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK) 27 28 /* To make sun4c_paging_init() happy, I provide the following macros. */ 29 #define SUN4C_REAL_PGDIR_SHIFT 18 30 #define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT) 31 #define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1)) 32 #define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK) 33 34 /* 35 * To be efficient, and not have to worry about allocating such 36 * a huge pgd, we make the kernel sun4c tables each hold 1024 37 * entries and the pgd similarly. 38 */ 39 40 #define SUN4C_PTRS_PER_PTE 1024 41 #define SUN4C_PTRS_PER_PMD 1 42 #define SUN4C_PTRS_PER_PGD 1024 43 44 /* Just any arbitrary offset to the start of the vmalloc VM area: the 45 * current 8MB value just means that there will be a 8MB "hole" after the 46 * physical memory until the kernel virtual memory starts. That means that 47 * any out-of-bounds memory accesses will hopefully be caught. 48 * The vmalloc() routines leaves a hole of 4kB between each vmalloced 49 * area for the same reason. ;) 50 */ 51 #define SUN4C_VMALLOC_OFFSET (8*1024*1024) 52 #define SUN4C_VMALLOC_START ((high_memory + SUN4C_VMALLOC_OFFSET) & ~(SUN4C_VMALLOC_OFFSET-1)) 53 54 /* 55 * Sparc SUN4C page table fields. (for now, basically the same as the i386) 56 */ 57 58 #define _SUN4C_PAGE_VALID 0x80000000 /* valid page */ 59 #define _SUN4C_PAGE_WRITE 0x40000000 /* can be written to */ 60 #define _SUN4C_PAGE_USER 0x00000000 /* User page */ 61 #define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */ 62 #define _SUN4C_PAGE_PRIV 0x20000000 /* bit to signify privileged page */ 63 #define _SUN4C_PAGE_REF 0x02000000 /* Page has been accessed/referenced */ 64 #define _SUN4C_PAGE_DIRTY 0x01000000 /* Page has been modified, is dirty */ 65 #define _SUN4C_PAGE_COW 0x00800000 /* COW page */ 66 67 /* Sparc sun4c mmu has only a writable bit. Thus if a page is valid it can be 68 * read in a load, and executed as code automatically. Although, the memory 69 * fault hardware does make a distinction between data-read faults and 70 * insn-read faults which is determined by which trap happened plus magic 71 * sync/async fault register values which must be checked in the actual 72 * fault handler. 73 */ 74 75 #define _SUN4C_PFN_MASK 0x0000ffff /* just the page frame number */ 76 #define _SUN4C_MMU_MASK 0xffff0000 /* just the non-page pte bits */ 77 78 /* The following are for pgd/pmd's */ 79 #define _SUN4C_PGD_PFN_MASK 0x00ffffff /* bits to hold page tables address */ 80 #define _SUN4C_PGD_MMU_MASK 0xff000000 /* pgd/pfn protection bits */ 81 #define _SUN4C_PGD_PAGE_SHIFT 8 /* bits to shift to obtain address */ 82 83 /* We want the swapper not to swap out page tables, thus dirty and writable 84 * so that the kernel can change the entries as needed. Also valid for 85 * obvious reasons. 86 */ 87 #define _SUN4C_PAGE_TABLE (_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | _SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY | _SUN4C_PAGE_PRIV | _SUN4C_PAGE_NOCACHE) /* No cache for now */ 88 #define _SUN4C_PAGE_CHG_MASK (_SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY | _SUN4C_PFN_MASK) 89 #define _SUN4C_PGD_CHG_MASK (_SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY | _SUN4C_PGD_PFN_MASK) 90 91 #define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_REF) 92 #define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | _SUN4C_PAGE_REF) 93 #define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_REF | _SUN4C_PAGE_COW) 94 #define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_REF) 95 #define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_WRITE | _SUN4C_PAGE_PRIV | _SUN4C_PAGE_REF | _SUN4C_PAGE_DIRTY | _SUN4C_PAGE_NOCACHE) 96 #define SUN4C_PAGE_INVALID __pgprot(0) 97 98 #define _SUN4C_PAGE_NORMAL(x) __pgprot(_SUN4C_PAGE_VALID | _SUN4C_PAGE_REF | (x)) 99 100 /* The Sun4c mmu physical segment map allocation data structure. 101 * For each physical segmap available on the mmu we have one entry, 102 * 127 on the sun4c (except SparcStation 2's which seem to have 255) 103 * and 512 on the sun4. Each segmap can be in various stages of 104 * allocation. 105 */ 106 #define PSEG_ENTRIES 513 /* We allocate 513 entries for simplicity */ 107 extern unsigned int phys_seg_map[PSEG_ENTRIES]; 108 extern unsigned int phys_seg_life[PSEG_ENTRIES]; 109 110 /* for phys_seg_map entries */ 111 #define PSEG_AVL 0x0 /* Physical segment is available/free */ 112 #define PSEG_USED 0x1 /* A segmap currently being used */ 113 #define PSEG_RSV 0x2 /* This segmap is reserved (used for proms addr space) */ 114 #define PSEG_KERNEL 0x3 /* This is a kernel hard segment, cannot deallocate */ 115 116 /* for phys_seg_life entries */ 117 /* The idea is, every call to update_mmu_cache we increment all the life 118 * counters. When we re-allocate or allocate a physical segment for the 119 * first time we set the phys_seg_life entry to PSEG_BORN. Also, when we 120 * fill a pte for a segment already loaded we *decrease* the life count 121 * by two for that segment. We'll see how this works. 122 */ 123 #define PSEG_BORN 0x00 /* Just allocated */ 124 125 #endif /* !(_SPARC_PGTSUN4C_H) */