1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/arch/alpha/mm/init.c 4 * 5 * Copyright (C) 1995 Linus Torvalds 6 */ 7 8 /* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea@suse.de> */ 9 10 #include <linux/pagemap.h> 11 #include <linux/signal.h> 12 #include <linux/sched.h> 13 #include <linux/kernel.h> 14 #include <linux/errno.h> 15 #include <linux/string.h> 16 #include <linux/types.h> 17 #include <linux/ptrace.h> 18 #include <linux/mman.h> 19 #include <linux/mm.h> 20 #include <linux/swap.h> 21 #include <linux/init.h> 22 #include <linux/memblock.h> /* max_low_pfn */ 23 #include <linux/vmalloc.h> 24 #include <linux/gfp.h> 25 26 #include <linux/uaccess.h> 27 #include <asm/pgalloc.h> 28 #include <asm/hwrpb.h> 29 #include <asm/dma.h> 30 #include <asm/mmu_context.h> 31 #include <asm/console.h> 32 #include <asm/tlb.h> 33 #include <asm/setup.h> 34 #include <asm/sections.h> 35 36 #include "../kernel/proto.h" 37 38 static struct pcb_struct original_pcb; 39 40 pgd_t * 41 pgd_alloc(struct mm_struct *mm) 42 { 43 pgd_t *ret, *init; 44 45 ret = __pgd_alloc(mm, 0); 46 init = pgd_offset(&init_mm, 0UL); 47 if (ret) { 48 #ifdef CONFIG_ALPHA_LARGE_VMALLOC 49 memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 50 (PTRS_PER_PGD - USER_PTRS_PER_PGD - 1)*sizeof(pgd_t)); 51 #else 52 pgd_val(ret[PTRS_PER_PGD-2]) = pgd_val(init[PTRS_PER_PGD-2]); 53 #endif 54 55 /* The last PGD entry is the VPTB self-map. */ 56 pgd_val(ret[PTRS_PER_PGD-1]) 57 = pte_val(mk_pte(virt_to_page(ret), PAGE_KERNEL)); 58 } 59 return ret; 60 } 61 62 63 static inline unsigned long 64 load_PCB(struct pcb_struct *pcb) 65 { 66 register unsigned long sp __asm__("$30"); 67 pcb->ksp = sp; 68 return __reload_thread(pcb); 69 } 70 71 /* Set up initial PCB, VPTB, and other such nicities. */ 72 73 static inline void 74 switch_to_system_map(void) 75 { 76 unsigned long newptbr; 77 unsigned long original_pcb_ptr; 78 79 /* Initialize the kernel's page tables. Linux puts the vptb in 80 the last slot of the L1 page table. */ 81 memset(swapper_pg_dir, 0, PAGE_SIZE); 82 newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT; 83 pgd_val(swapper_pg_dir[1023]) = 84 (newptbr << 32) | pgprot_val(PAGE_KERNEL); 85 86 /* Set the vptb. This is often done by the bootloader, but 87 shouldn't be required. */ 88 if (hwrpb->vptb != 0xfffffffe00000000UL) { 89 wrvptptr(0xfffffffe00000000UL); 90 hwrpb->vptb = 0xfffffffe00000000UL; 91 hwrpb_update_checksum(hwrpb); 92 } 93 94 /* Also set up the real kernel PCB while we're at it. */ 95 init_thread_info.pcb.ptbr = newptbr; 96 init_thread_info.pcb.flags = 1; /* set FEN, clear everything else */ 97 original_pcb_ptr = load_PCB(&init_thread_info.pcb); 98 tbia(); 99 100 /* Save off the contents of the original PCB so that we can 101 restore the original console's page tables for a clean reboot. 102 103 Note that the PCB is supposed to be a physical address, but 104 since KSEG values also happen to work, folks get confused. 105 Check this here. */ 106 107 if (original_pcb_ptr < PAGE_OFFSET) { 108 original_pcb_ptr = (unsigned long) 109 phys_to_virt(original_pcb_ptr); 110 } 111 original_pcb = *(struct pcb_struct *) original_pcb_ptr; 112 } 113 114 int callback_init_done; 115 116 void * __init 117 callback_init(void * kernel_end) 118 { 119 struct crb_struct * crb; 120 pgd_t *pgd; 121 p4d_t *p4d; 122 pud_t *pud; 123 pmd_t *pmd; 124 void *two_pages; 125 126 /* Starting at the HWRPB, locate the CRB. */ 127 crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset); 128 129 if (alpha_using_srm) { 130 /* Tell the console whither it is to be remapped. */ 131 if (srm_fixup(VMALLOC_START, (unsigned long)hwrpb)) 132 __halt(); /* "We're boned." --Bender */ 133 134 /* Edit the procedure descriptors for DISPATCH and FIXUP. */ 135 crb->dispatch_va = (struct procdesc_struct *) 136 (VMALLOC_START + (unsigned long)crb->dispatch_va 137 - crb->map[0].va); 138 crb->fixup_va = (struct procdesc_struct *) 139 (VMALLOC_START + (unsigned long)crb->fixup_va 140 - crb->map[0].va); 141 } 142 143 switch_to_system_map(); 144 145 /* Allocate one PGD and one PMD. In the case of SRM, we'll need 146 these to actually remap the console. There is an assumption 147 here that only one of each is needed, and this allows for 8MB. 148 On systems with larger consoles, additional pages will be 149 allocated as needed during the mapping process. 150 151 In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC, 152 we need to allocate the PGD we use for vmalloc before we start 153 forking other tasks. */ 154 155 two_pages = (void *) 156 (((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK); 157 kernel_end = two_pages + 2*PAGE_SIZE; 158 memset(two_pages, 0, 2*PAGE_SIZE); 159 160 pgd = pgd_offset_k(VMALLOC_START); 161 p4d = p4d_offset(pgd, VMALLOC_START); 162 pud = pud_offset(p4d, VMALLOC_START); 163 pud_set(pud, (pmd_t *)two_pages); 164 pmd = pmd_offset(pud, VMALLOC_START); 165 pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE)); 166 167 if (alpha_using_srm) { 168 static struct vm_struct console_remap_vm; 169 unsigned long nr_pages = 0; 170 unsigned long vaddr; 171 unsigned long i, j; 172 173 /* calculate needed size */ 174 for (i = 0; i < crb->map_entries; ++i) 175 nr_pages += crb->map[i].count; 176 177 /* register the vm area */ 178 console_remap_vm.flags = VM_ALLOC; 179 console_remap_vm.size = nr_pages << PAGE_SHIFT; 180 vm_area_register_early(&console_remap_vm, PAGE_SIZE); 181 182 vaddr = (unsigned long)console_remap_vm.addr; 183 184 /* Set up the third level PTEs and update the virtual 185 addresses of the CRB entries. */ 186 for (i = 0; i < crb->map_entries; ++i) { 187 unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT; 188 crb->map[i].va = vaddr; 189 for (j = 0; j < crb->map[i].count; ++j) { 190 /* Newer consoles (especially on larger 191 systems) may require more pages of 192 PTEs. Grab additional pages as needed. */ 193 if (pmd != pmd_offset(pud, vaddr)) { 194 memset(kernel_end, 0, PAGE_SIZE); 195 pmd = pmd_offset(pud, vaddr); 196 pmd_set(pmd, (pte_t *)kernel_end); 197 kernel_end += PAGE_SIZE; 198 } 199 set_pte(pte_offset_kernel(pmd, vaddr), 200 pfn_pte(pfn, PAGE_KERNEL)); 201 pfn++; 202 vaddr += PAGE_SIZE; 203 } 204 } 205 } 206 207 callback_init_done = 1; 208 return kernel_end; 209 } 210 211 void __init arch_zone_limits_init(unsigned long *max_zone_pfn) 212 { 213 unsigned long dma_pfn; 214 215 dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 216 max_pfn = max_low_pfn; 217 218 max_zone_pfn[ZONE_DMA] = dma_pfn; 219 max_zone_pfn[ZONE_NORMAL] = max_pfn; 220 } 221 222 /* 223 * paging_init() initializes the kernel's ZERO_PGE. 224 */ 225 void __init paging_init(void) 226 { 227 memset(absolute_pointer(ZERO_PGE), 0, PAGE_SIZE); 228 } 229 230 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) 231 void 232 srm_paging_stop (void) 233 { 234 /* Move the vptb back to where the SRM console expects it. */ 235 swapper_pg_dir[1] = swapper_pg_dir[1023]; 236 tbia(); 237 wrvptptr(0x200000000UL); 238 hwrpb->vptb = 0x200000000UL; 239 hwrpb_update_checksum(hwrpb); 240 241 /* Reload the page tables that the console had in use. */ 242 load_PCB(&original_pcb); 243 tbia(); 244 } 245 #endif 246 247 static const pgprot_t protection_map[16] = { 248 [VM_NONE] = _PAGE_P(_PAGE_FOE | _PAGE_FOW | 249 _PAGE_FOR), 250 [VM_READ] = _PAGE_P(_PAGE_FOE | _PAGE_FOW), 251 [VM_WRITE] = _PAGE_P(_PAGE_FOE), 252 [VM_WRITE | VM_READ] = _PAGE_P(_PAGE_FOE), 253 [VM_EXEC] = _PAGE_P(_PAGE_FOW | _PAGE_FOR), 254 [VM_EXEC | VM_READ] = _PAGE_P(_PAGE_FOW), 255 [VM_EXEC | VM_WRITE] = _PAGE_P(0), 256 [VM_EXEC | VM_WRITE | VM_READ] = _PAGE_P(0), 257 [VM_SHARED] = _PAGE_S(_PAGE_FOE | _PAGE_FOW | 258 _PAGE_FOR), 259 [VM_SHARED | VM_READ] = _PAGE_S(_PAGE_FOE | _PAGE_FOW), 260 [VM_SHARED | VM_WRITE] = _PAGE_S(_PAGE_FOE), 261 [VM_SHARED | VM_WRITE | VM_READ] = _PAGE_S(_PAGE_FOE), 262 [VM_SHARED | VM_EXEC] = _PAGE_S(_PAGE_FOW | _PAGE_FOR), 263 [VM_SHARED | VM_EXEC | VM_READ] = _PAGE_S(_PAGE_FOW), 264 [VM_SHARED | VM_EXEC | VM_WRITE] = _PAGE_S(0), 265 [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = _PAGE_S(0) 266 }; 267 DECLARE_VM_GET_PAGE_PROT 268