1/* $NetBSD: cache.S,v 1.2 2018/09/07 17:30:32 jmcneill Exp $ */ 2 3/*- 4 * Copyright (c) 2014 Robin Randhawa 5 * Copyright (c) 2015 The FreeBSD Foundation 6 * All rights reserved. 7 * 8 * Portions of this software were developed by Andrew Turner 9 * under sponsorship from the FreeBSD Foundation 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $FreeBSD: head/sys/arm64/arm64/cpufunc_asm.S 313347 2017-02-06 17:50:09Z andrew $ 33 */ 34 35#include <aarch64/asm.h> 36 37#define SCTLR_M (1<<0) 38#define SCTLR_C (1<<2) 39 40 .text 41 .align 2 42 43/* 44 * Macro to handle the cache. This takes the start address in x0, length 45 * in x1. It will corrupt x0, x1, x2, and x3. 46 */ 47.macro cache_handle_range dcop = 0, ic = 0, icop = 0 48.if \ic == 0 49 mrs x3, ctr_el0 50 ubfx x3, x3, #16, #4 /* x3 = D cache shift */ 51 mov x2, #4 /* size of word */ 52 lsl x3, x2, x3 /* x3 = D cache line size */ 53.else 54 mrs x3, ctr_el0 55 ubfx x2, x3, #16, #4 /* x2 = D cache shift */ 56 and x3, x3, #15 /* x3 = I cache shift */ 57 cmp x3, x2 58 bcs 1f 59 mov x3, x2 601: /* x3 = MAX(IcacheShift,DcacheShift) */ 61 mov x2, #4 /* size of word */ 62 lsl x3, x2, x3 /* x3 = cache line size */ 63.endif 64 sub x4, x3, #1 /* Get the address mask */ 65 and x2, x0, x4 /* Get the low bits of the address */ 66 add x1, x1, x2 /* Add these to the size */ 67 bic x0, x0, x4 /* Clear the low bit of the address */ 681: 69 dc \dcop, x0 70 dsb ish 71.if \ic != 0 72 ic \icop, x0 73 dsb ish 74.endif 75 add x0, x0, x3 /* Move to the next line */ 76 subs x1, x1, x3 /* Reduce the size */ 77 b.hi 1b /* Check if we are done */ 78.if \ic != 0 79 isb 80.endif 81 ret 82.endm 83 84 85/* 86 * void aarch64_dcache_wbinv_range(vaddr_t, vsize_t) 87 */ 88ENTRY(aarch64_dcache_wbinv_range) 89 cache_handle_range dcop = civac 90END(aarch64_dcache_wbinv_range) 91 92/* 93 * void aarch64_icache_inv_all(void) 94 */ 95ENTRY(aarch64_icache_inv_all) 96 dsb ish 97 ic ialluis 98 dsb ish 99 isb 100 ret 101END(aarch64_icache_inv_all) 102 103/* 104 * void aarch64_exec_kernel(paddr_t entry, paddr_t dtb) 105 */ 106ENTRY(aarch64_exec_kernel) 107 mov x20, x0 /* kernel entry point */ 108 mov x21, x1 /* dtb address */ 109 110 mrs x0, CurrentEL 111 lsr x0, x0, #2 112 cmp x0, #0x2 113 b.eq 1f 114 115 /* Disable MMU and dcache, CurrentEL = EL1 */ 116 mrs x0, sctlr_el1 117 bic x0, x0, #SCTLR_M 118 bic x0, x0, #SCTLR_C 119 msr sctlr_el1, x0 120 isb 121 b 2f 1221: 123 /* Disable MMU and dcache, CurrentEL = EL2 */ 124 mrs x0, sctlr_el2 125 bic x0, x0, #SCTLR_M 126 bic x0, x0, #SCTLR_C 127 msr sctlr_el2, x0 128 isb 1292: 130 131 /* Jump to kernel */ 132 mov x0, x21 133 mov x1, xzr 134 mov x2, xzr 135 mov x3, xzr 136 br x20 137 138END(aarch64_exec_kernel) 139