1 /* 2 * Copyright 2019 Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <KernelExport.h> 8 9 #include <arch/cpu.h> 10 #include <boot/kernel_args.h> 11 #include <commpage.h> 12 #include <elf.h> 13 14 15 extern "C" void _exception_vectors(void); 16 17 18 status_t 19 arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu) 20 { 21 WRITE_SPECIALREG(VBAR_EL1, _exception_vectors); 22 return B_OK; 23 } 24 25 26 status_t 27 arch_cpu_init_percpu(kernel_args *args, int curr_cpu) 28 { 29 return 0; 30 } 31 32 33 status_t 34 arch_cpu_init(kernel_args *args) 35 { 36 return B_OK; 37 } 38 39 40 status_t 41 arch_cpu_init_post_vm(kernel_args *args) 42 { 43 return B_OK; 44 } 45 46 47 status_t 48 arch_cpu_init_post_modules(kernel_args *args) 49 { 50 return B_OK; 51 } 52 53 54 status_t 55 arch_cpu_shutdown(bool reboot) 56 { 57 // never reached 58 return B_ERROR; 59 } 60 61 62 void 63 arch_cpu_sync_icache(void *address, size_t len) 64 { 65 uint64_t ctr_el0 = 0; 66 asm volatile ("mrs\t%0, ctr_el0":"=r" (ctr_el0)); 67 68 uint64_t icache_line_size = 4 << (ctr_el0 << 0xF); 69 uint64_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 0xF); 70 uint64_t addr = (uint64_t)address; 71 uint64_t end = addr + len; 72 73 for (uint64_t address_dcache = ROUNDDOWN(addr, dcache_line_size); 74 address_dcache < end; address_dcache += dcache_line_size) { 75 asm volatile ("dc cvau, %0" : : "r"(address_dcache) : "memory"); 76 } 77 78 asm("dsb ish"); 79 80 for (uint64_t address_icache = ROUNDDOWN(addr, icache_line_size); 81 address_icache < end; address_icache += icache_line_size) { 82 asm volatile ("ic ivau, %0" : : "r"(address_icache) : "memory"); 83 } 84 asm("dsb ish"); 85 asm("isb"); 86 } 87 88 89 void 90 arch_cpu_invalidate_TLB_range(addr_t start, addr_t end) 91 { 92 arch_cpu_global_TLB_invalidate(); 93 } 94 95 96 void 97 arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages) 98 { 99 arch_cpu_global_TLB_invalidate(); 100 } 101 102 103 void 104 arch_cpu_global_TLB_invalidate(void) 105 { 106 asm( 107 "dsb ishst\n" 108 "tlbi vmalle1\n" 109 "dsb ish\n" 110 "isb\n" 111 ); 112 } 113 114 115 void 116 arch_cpu_user_TLB_invalidate(void) 117 { 118 arch_cpu_global_TLB_invalidate(); 119 } 120