1/* 2 * Copyright (c) 2009-2013,2016 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <kernel.h> 11 12#include <barrelfish_kpi/arm_core_data.h> 13#include <cp15.h> 14#include <paging_kernel_arch.h> 15 16#define MSG(format, ...) printk( LOG_NOTE, "ARMv7-A: "format, ## __VA_ARGS__ ) 17 18bool paging_mmu_enabled(void) 19{ 20 return false; 21} 22 23union arm_l1_entry l1_low [ARM_L1_MAX_ENTRIES] 24 __attribute__((aligned(ARM_L1_ALIGN), section(".boot.tables"))); 25union arm_l1_entry l1_high[ARM_L1_MAX_ENTRIES] 26 __attribute__((aligned(ARM_L1_ALIGN), section(".boot.tables"))); 27union arm_l2_entry l2_vec[ARM_L2_MAX_ENTRIES] 28 __attribute__((aligned(ARM_L2_ALIGN), section(".boot.tables"))); 29 30static void map_kernel_section_lo(lvaddr_t va, union arm_l1_entry l1) 31{ 32 assert( va < MEMORY_OFFSET ); 33 l1_low[ARM_L1_OFFSET(va)] = l1; 34} 35 36static void map_kernel_section_hi(lvaddr_t va, union arm_l1_entry l1) 37{ 38 assert( va >= MEMORY_OFFSET ); 39 l1_high[ARM_L1_OFFSET(va)] = l1; 40} 41 42/* These are initialised by the linker, so we know where the boot driver code 43 * is. */ 44extern char boot_start, boot_end; 45 46/** 47 * /brief Return an L1 page table entry to map a 1MB 'section' of 48 * device memory located at physical address 'pa'. 49 */ 50static union arm_l1_entry make_dev_section(lpaddr_t pa) 51{ 52 union arm_l1_entry l1; 53 54 l1.raw = 0; 55 l1.section.type = L1_TYPE_SECTION_ENTRY; 56 // l1.section.tex = 1; 57 l1.section.bufferable = 0; 58 l1.section.cacheable = 0; 59 l1.section.ap10 = 3; // prev value: 3 // RW/NA RW/RW 60 // l1.section.ap10 = 1; // RW/NA 61 l1.section.ap2 = 0; 62 l1.section.base_address = ARM_L1_SECTION_NUMBER(pa); 63 return l1; 64} 65 66/** 67 * /brief Return an L1 page table entry to map a 1MB 'section' of RAM 68 * located at physical address 'pa'. 69 */ 70static union arm_l1_entry make_ram_section(lpaddr_t pa) 71{ 72 // Must be in the 1GB RAM region. 73 assert(pa >= phys_memory_start && pa < (phys_memory_start + 0x40000000)); 74 union arm_l1_entry l1; 75 76 l1.raw = 0; 77 l1.section.type = L1_TYPE_SECTION_ENTRY; 78 79 /* The next three fields (tex,b,c) don't mean quite what their names 80 suggest. This setting gives inner and outer write-back, write-allocate 81 cacheable memory. See ARMv7 ARM Table B3-10. */ 82 l1.section.tex = 1; 83 l1.section.cacheable = 1; 84 l1.section.bufferable = 1; 85 86 l1.section.execute_never = 0; /* XXX - We may want to revisit this. */ 87 88 l1.section.not_global = 0; /* Kernel mappings are global. */ 89 l1.section.shareable = 1; /* Cache coherent. */ 90 91 l1.section.ap10 = 1; /* Kernel RW, no user access. */ 92 l1.section.ap2 = 0; 93 94 l1.section.base_address = ARM_L1_SECTION_NUMBER(pa); 95 return l1; 96} 97 98/** 99 * Create kernel page tables. 100 * 101 * We use 1MB (ARM_L1_SECTION_BYTES) pages (sections) with a single-level table. 102 * This allows 1MB*4k (ARM_L1_MAX_ENTRIES) = 4G per pagetable. 103 * 104 * Hardware details can be found in: 105 * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition 106 * B3: Virtual Memory System Architecture (VMSA) 107 */ 108void paging_init(lpaddr_t ram_base, size_t ram_size, 109 struct arm_core_data *boot_core_data) 110{ 111 /** 112 * Make sure our page tables are correctly aligned in memory 113 */ 114 assert(ROUND_UP((lpaddr_t)l1_low, ARM_L1_ALIGN) == (lpaddr_t)l1_low); 115 assert(ROUND_UP((lpaddr_t)l1_high, ARM_L1_ALIGN) == (lpaddr_t)l1_high); 116 117 MSG("Initialising kernel paging, using RAM at %08x-%08x\n", 118 ram_base, ram_base + (ram_size - 1)); 119 120 /** 121 * On many ARMv7-A platforms, physical RAM (phys_memory_start) is the same 122 * as the offset of mapped physical memory within virtual address space 123 * (phys_memory_start). Some platforms (such as the Zynq) break this 124 * rule, and thus we need to be very careful about how we enable the MMU. 125 */ 126 if(MEMORY_OFFSET != phys_memory_start && 127 (lpaddr_t)&boot_end >= MEMORY_OFFSET) { 128 /* If the init code's physical addresses overlap the kernel window, 129 * they must be unchanged when we map those virtual addresses to RAM. 130 * Otherwise our code will suddenly vanish. This means that on 131 * platforms with RAM somewhere other than 80000000, all 132 * initialisation code should be allocated together, somewhere in the 133 * first 2GB. */ 134 panic("The kernel memory window must either be 1-1, or init code\n" 135 "must lie entirely outside it.\n"); 136 } 137 138 /** 139 * Zero the page tables: this has the effect of marking every PTE 140 * as invalid. 141 */ 142 memset(&l1_low, 0, sizeof(l1_low)); 143 memset(&l1_high, 0, sizeof(l1_high)); 144 memset(&l2_vec, 0, sizeof(l2_vec)); 145 146 /* Pass the addresses of the page tables to the CPU driver. */ 147 boot_core_data->kernel_l1_low= (lpaddr_t)l1_low; 148 boot_core_data->kernel_l1_high= (lpaddr_t)l1_high; 149 boot_core_data->kernel_l2_vec= (lpaddr_t)l2_vec; 150 151 /** 152 * Now we lay out the kernel's virtual address space. 153 * 154 * 00000000-7FFFFFFFF: 1-1 mappings (hardware we have not mapped 155 * into high kernel space yet, and the init 156 * code that is currently executing, in case 157 * RAM doesn't start at 80000000). 158 * 80000000-BFFFFFFFF: 1-1 mappings (this is 1GB of RAM). 159 * C0000000-FEFFFFFFF: On-demand mappings of hardware devices, 160 * allocated descending from DEVICE_OFFSET. 161 * FF000000-FFEFFFFFF: Unallocated. 162 * FFF00000-FFFFFFFFF: L2 table, containing: 163 * FFF00000-FFFEFFFF: Unallocated 164 * FFFF0000-FFFFFFFF: Exception vectors 165 */ 166 lvaddr_t vbase; 167 lpaddr_t pbase; 168 size_t i; 169 /* Map the first 2GB 1-1. */ 170 vbase= 0; pbase= 0; 171 for (i=0; i < ARM_L1_MAX_ENTRIES/2; i++) { 172 map_kernel_section_lo(vbase, make_dev_section(pbase)); 173 vbase += ARM_L1_SECTION_BYTES; 174 pbase += ARM_L1_SECTION_BYTES; 175 } 176 /* Map the next 1GB to the first 1GB of RAM. */ 177 vbase= MEMORY_OFFSET; pbase= phys_memory_start; 178 for (i=0; i < ARM_L1_MAX_ENTRIES/4; i++) { 179 map_kernel_section_hi(vbase, make_ram_section(pbase)); 180 vbase += ARM_L1_SECTION_BYTES; 181 pbase += ARM_L1_SECTION_BYTES; 182 } 183} 184 185void enable_mmu(lpaddr_t ttbr0, lpaddr_t ttbr1) 186{ 187 /** 188 * TTBCR: Translation Table Base Control register. 189 * TTBCR.N is bits[2:0] 190 * In a TLB miss TTBCR.N determines whether TTBR0 or TTBR1 is used as the 191 * base address for the translation table walk in memory: 192 * N == 0 -> always use TTBR0 193 * N > 0 -> if VA[31:32-N] > 0 use TTBR1 else use TTBR0 194 * 195 * TTBR0 is typically used for processes-specific addresses 196 * TTBR1 is typically used for OS addresses that do not change on context 197 * switch 198 * 199 * set TTBCR.N = 1 to use TTBR1 for VAs >= MEMORY_OFFSET (=2GB) 200 */ 201 uint32_t sctlr= cp15_read_sctlr(); 202 MSG(" MMU is currently "); 203 if(sctlr & BIT(2)) { 204 printf("enabled.\n"); 205 panic("MMU is enabled.\n"); 206 } 207 else printf("disabled.\n"); 208 MSG(" Alignment checking is currently "); 209 if(sctlr & BIT(1)) printf("enabled.\n"); 210 else printf("disabled.\n"); 211 MSG(" Caches are currently "); 212 if(sctlr & BIT(0)) { 213 printf("enabled.\n"); 214 panic("Caches are enabled.\n"); 215 } 216 else printf("disabled.\n"); 217 218 /* Force all outstanding operations to complete. */ 219 dsb(); isb(); 220 221 /* Ensure that the local caches and TLBs have no stale data. */ 222 invalidate_data_caches_pouu(false); 223 invalidate_instruction_cache(); 224 invalidate_tlb(); 225 226 /* Install the new tables. */ 227 cp15_write_ttbr1(ttbr1); 228 cp15_write_ttbr0(ttbr0); 229 230 /* Set TTBR0&1 to each map 2GB. */ 231 #define TTBCR_N 1 232 uint32_t ttbcr = cp15_read_ttbcr(); 233 ttbcr = (ttbcr & ~MASK(3)) | TTBCR_N; 234 cp15_write_ttbcr(ttbcr); 235 STATIC_ASSERT(1UL<<(32-TTBCR_N) == MEMORY_OFFSET, ""); 236 #undef TTBCR_N 237 238 /* Ensure all memory accesses have completed. */ 239 dsb(); 240 241 /* All 16 domains are set to 'client', and otherwise unused. */ 242 cp15_write_dacr(0x55555555); 243 244 /* Start in ASID 0. */ 245 cp15_write_contextidr(0); 246 247 /* Enable caches and the MMU. 248 If RAM on this platform starts at 80000000, then this is quite simple, 249 and we'll just keep executing without any trouble. If RAM is somewhere 250 else (say 0), then we've just created a duplicate mapping to the code 251 that we're running, inside the kernel window, and we'll continue 252 executing using the uncached device mappings we just created, until we 253 call arch_init_2() at its kernel-window address. This relies on having 254 position-independent code. 255 */ 256 sctlr= cp15_read_sctlr(); 257 sctlr|= BIT(12); /* I-Cache enabled. */ 258 sctlr|= BIT(11); /* Branch prediction enabled. */ 259 sctlr|= BIT(2); /* D-Cache and unified caches enabled. */ 260 sctlr&= ~BIT(1); /* Alignment faults disabled. */ 261 sctlr|= BIT(0); /* Level 1 MMU enabled. */ 262 cp15_write_sctlr(sctlr); 263 264 /* Synchronise control register changes. */ 265 isb(); 266 267 /* We're now executing either through the new, cached kernel window 268 * mappings, or through the uncached device mappings. In either case, no 269 * addresses have changed yet. The one wrinkle is that the UART may have 270 * just disappeared, if its physical address was >80000000. Thus it's not 271 * safe to print until we're definitely executing in the kernel window, 272 * and have remapped it. */ 273 274 /* Any TLB entries will be stale, although there shouldn't be any. */ 275 invalidate_tlb(); 276 277 /* Ensure no memory accesses or instruction fetches occur before the MMU 278 * is fully enabled. */ 279 dsb(); 280} 281