1/* $OpenBSD: cpufunc_asm_armv7.S,v 1.19 2022/12/08 01:25:44 guenther Exp $ */ 2/* 3 * Copyright (c) 2008 Dale Rahn <drahn@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <machine/asm.h> 19#include <arm/armreg.h> 20#include <arm/sysreg.h> 21 22ENTRY(armv7_cpu_sleep) 23 wfi 24 mov pc, lr 25 26ENTRY(armv7_drain_writebuf) 27 dsb sy 28 isb sy 29 mov pc, lr 30 31/* 32 * Function to read the MPCore base address 33 */ 34ENTRY(armv7_periphbase) 35 mrc CP15_CBAR(r0) 36 mov pc, lr 37 38/* Suitable default for a uniprocessor kernel. */ 39#define TTBR_DEFAULT (TTBR_IRGN_WBNWA | TTBR_RGN_WBNWA) 40 41/* 42 * Functions to set the MMU Translation Table Base register 43 */ 44ENTRY(armv7_setttb) 45 mcr CP15_ICIALLU /* Flush I cache */ 46 dsb sy 47 isb sy 48 49 orr r0, r0, #TTBR_DEFAULT 50 mcr CP15_TTBR0(r0) /* load new TTB */ 51 mcr CP15_TLBIALL(r0) /* invalidate unified TLB */ 52 dsb sy 53 isb sy 54 55 mov pc, lr 56 57/* 58 * TLB functions 59 */ 60ENTRY(armv7_tlb_flushID_SE) 61 mcr CP15_TLBIMVA(r0) /* flush unified tlb single entry */ 62 mcr CP15_BPIMVA /* flush va from BP */ 63 dsb sy 64 isb sy 65 mov pc, lr 66 67ENTRY(armv7_tlb_flushID) 68 mcr CP15_TLBIALL(r0) /* flush unified tlb */ 69 mcr CP15_BPIALL /* Flush BP cache */ 70 dsb sy 71 isb sy 72 mov pc, lr 73 74ENTRY(armv7_tlb_flushD_SE) 75 mcr CP15_TLBIMVA(r0) /* flush unified tlb single entry */ 76 dsb sy 77 isb sy 78 mov pc, lr 79 80ENTRY(armv7_tlb_flushD) 81 mcr CP15_TLBIALL(r0) /* flush unified tlb */ 82 dsb sy 83 isb sy 84 mov pc, lr 85 86 87/* 88 * Cache operations. For the entire cache we use the set/index 89 * operations. 90 */ 91.Larmv7_dcache_line_size: 92 .word arm_dcache_min_line_size 93.Larmv7_icache_line_size: 94 .word arm_icache_min_line_size 95.Larmv7_idcache_line_size: 96 .word arm_idcache_min_line_size 97 98 s_max .req r0 99 i_max .req r1 100 s_inc .req r2 101 i_inc .req r3 102ENTRY(armv7_icache_sync_range) 103 ldr ip, .Larmv7_icache_line_size 104 ldr ip, [ip] 105 sub r3, ip, #1 106 and r2, r0, r3 107 add r1, r1, r2 108 bic r0, r0, r3 1091: 110 mcr CP15_DCCMVAU(r0) /* Clean D cache SE with VA to PoU */ 111 mcr CP15_ICIMVAU(r0) /* Invalidate I cache SE with VA */ 112 add r0, r0, ip 113 subs r1, r1, ip 114 bhi 1b 115 mcr CP15_BPIALL /* Flush BP cache */ 116 dsb sy 117 isb sy 118 mov pc, lr 119 120ENTRY(armv7_icache_sync_all) 121.Larmv7_icache_sync_all: 122 /* 123 * We assume that the code here can never be out of sync with the 124 * dcache, so that we can safely flush the Icache and fall through 125 * into the Dcache cleaning code. 126 */ 127 mcr CP15_ICIALLU /* Flush I cache */ 128 isb sy 129 mov pc, lr 130 131ENTRY(armv7_dcache_wb_range) 132 ldr ip, .Larmv7_dcache_line_size 133 ldr ip, [ip] 134 sub r3, ip, #1 135 and r2, r0, r3 136 add r1, r1, r2 137 bic r0, r0, r3 1381: 139 mcr CP15_DCCMVAC(r0) /* Clean D cache SE with VA */ 140 add r0, r0, ip 141 subs r1, r1, ip 142 bhi 1b 143 dsb sy 144 isb sy 145 mov pc, lr 146 147ENTRY(armv7_idcache_wbinv_range) 148 ldr ip, .Larmv7_idcache_line_size 149 ldr ip, [ip] 150 sub r3, ip, #1 151 and r2, r0, r3 152 add r1, r1, r2 153 bic r0, r0, r3 1541: 155 mcr CP15_DCCMVAU(r0) /* Clean D cache SE with VA to PoU */ 156 mcr CP15_ICIMVAU(r0) /* Invalidate I cache SE with VA */ 157 mcr CP15_DCCIMVAC(r0) /* Purge D cache SE with VA */ 158 add r0, r0, ip 159 subs r1, r1, ip 160 bhi 1b 161 mcr CP15_BPIALL /* Flush BP cache */ 162 dsb sy 163 isb sy 164 mov pc, lr 165 166ENTRY(armv7_dcache_wbinv_range) 167 ldr ip, .Larmv7_dcache_line_size 168 ldr ip, [ip] 169 sub r3, ip, #1 170 and r2, r0, r3 171 add r1, r1, r2 172 bic r0, r0, r3 1731: 174 mcr CP15_DCCMVAU(r0) /* Clean D cache SE with VA to PoU */ 175 mcr CP15_ICIMVAU(r0) /* Invalidate I cache SE with VA */ 176 mcr CP15_DCCIMVAC(r0) /* Purge D cache SE with VA */ 177 add r0, r0, ip 178 subs r1, r1, ip 179 bhi 1b 180 dsb sy 181 isb sy 182 mov pc, lr 183 184ENTRY(armv7_dcache_inv_range) 185 ldr ip, .Larmv7_dcache_line_size 186 ldr ip, [ip] 187 sub r3, ip, #1 188 and r2, r0, r3 189 add r1, r1, r2 190 bic r0, r0, r3 1911: 192 mcr CP15_DCCMVAU(r0) /* Clean D cache SE with VA to PoU */ 193 mcr CP15_ICIMVAU(r0) /* Invalidate I cache SE with VA */ 194 mcr CP15_DCIMVAC(r0) /* Invalidate D cache SE with VA */ 195 add r0, r0, ip 196 subs r1, r1, ip 197 bhi 1b 198 dsb sy 199 isb sy 200 mov pc, lr 201 202 203/* 204 * BTB functions. 205 */ 206ENTRY(armv7_flush_bp) 207 mcr CP15_BPIALL 208 mov pc, lr 209 210ENTRY(cortex_a15_flush_bp) 211 mcr CP15_ICIALLU /* Heavy hammer; BPIALL is a no-op */ 212 mov pc, lr 213 214/* 215 * Context switch. 216 * 217 * These is the CPU-specific parts of the context switcher cpu_switch() 218 * These functions actually perform the TTB reload. 219 * 220 * NOTE: Special calling convention 221 * r1, r4-r13 must be preserved 222 */ 223ENTRY(armv7_context_switch) 224 /* 225 * We can assume that the caches will only contain kernel addresses 226 * at this point. So no need to flush them again. 227 */ 228 mcr CP15_ICIALLU /* Flush I cache */ 229 dsb sy 230 isb sy 231 232 orr r0, r0, #TTBR_DEFAULT 233 mcr CP15_TTBR0(r0) /* set the new TTB */ 234 mcr CP15_TLBIALL(r0) /* and flush the unified tlb */ 235 dsb sy 236 isb sy 237 mov pc, lr 238 239/* XXX The following macros should probably be moved to asm.h */ 240#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x: 241#define C_OBJECT(x) _DATA_OBJECT(x) 242 243 .align 2 244C_OBJECT(armv7_dcache_sets_max) 245 .word 0 246C_OBJECT(armv7_dcache_index_max) 247 .word 0 248C_OBJECT(armv7_dcache_sets_inc) 249 .word 0 250C_OBJECT(armv7_dcache_index_inc) 251 .word 0 252