1*f5478dedSAntonio Nino Diaz/* 2*f5478dedSAntonio Nino Diaz * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. 3*f5478dedSAntonio Nino Diaz * 4*f5478dedSAntonio Nino Diaz * SPDX-License-Identifier: BSD-3-Clause 5*f5478dedSAntonio Nino Diaz */ 6*f5478dedSAntonio Nino Diaz#ifndef ASM_MACROS_S 7*f5478dedSAntonio Nino Diaz#define ASM_MACROS_S 8*f5478dedSAntonio Nino Diaz 9*f5478dedSAntonio Nino Diaz#include <arch.h> 10*f5478dedSAntonio Nino Diaz#include <asm_macros_common.S> 11*f5478dedSAntonio Nino Diaz#include <spinlock.h> 12*f5478dedSAntonio Nino Diaz 13*f5478dedSAntonio Nino Diaz/* 14*f5478dedSAntonio Nino Diaz * TLBI instruction with type specifier that implements the workaround for 15*f5478dedSAntonio Nino Diaz * errata 813419 of Cortex-A57. 16*f5478dedSAntonio Nino Diaz */ 17*f5478dedSAntonio Nino Diaz#if ERRATA_A57_813419 18*f5478dedSAntonio Nino Diaz#define TLB_INVALIDATE(_reg, _coproc) \ 19*f5478dedSAntonio Nino Diaz stcopr _reg, _coproc; \ 20*f5478dedSAntonio Nino Diaz dsb ish; \ 21*f5478dedSAntonio Nino Diaz stcopr _reg, _coproc 22*f5478dedSAntonio Nino Diaz#else 23*f5478dedSAntonio Nino Diaz#define TLB_INVALIDATE(_reg, _coproc) \ 24*f5478dedSAntonio Nino Diaz stcopr _reg, _coproc 25*f5478dedSAntonio Nino Diaz#endif 26*f5478dedSAntonio Nino Diaz 27*f5478dedSAntonio Nino Diaz#define WORD_SIZE 4 28*f5478dedSAntonio Nino Diaz 29*f5478dedSAntonio Nino Diaz /* 30*f5478dedSAntonio Nino Diaz * Co processor register accessors 31*f5478dedSAntonio Nino Diaz */ 32*f5478dedSAntonio Nino Diaz .macro ldcopr reg, coproc, opc1, CRn, CRm, opc2 33*f5478dedSAntonio Nino Diaz mrc \coproc, \opc1, \reg, \CRn, \CRm, \opc2 34*f5478dedSAntonio Nino Diaz .endm 35*f5478dedSAntonio Nino Diaz 36*f5478dedSAntonio Nino Diaz .macro ldcopr16 reg1, reg2, coproc, opc1, CRm 37*f5478dedSAntonio Nino Diaz mrrc \coproc, \opc1, \reg1, \reg2, \CRm 38*f5478dedSAntonio Nino Diaz .endm 39*f5478dedSAntonio Nino Diaz 40*f5478dedSAntonio Nino Diaz .macro stcopr reg, coproc, opc1, CRn, CRm, opc2 41*f5478dedSAntonio Nino Diaz mcr \coproc, \opc1, \reg, \CRn, \CRm, \opc2 42*f5478dedSAntonio Nino Diaz .endm 43*f5478dedSAntonio Nino Diaz 44*f5478dedSAntonio Nino Diaz .macro stcopr16 reg1, reg2, coproc, opc1, CRm 45*f5478dedSAntonio Nino Diaz mcrr \coproc, \opc1, \reg1, \reg2, \CRm 46*f5478dedSAntonio Nino Diaz .endm 47*f5478dedSAntonio Nino Diaz 48*f5478dedSAntonio Nino Diaz /* Cache line size helpers */ 49*f5478dedSAntonio Nino Diaz .macro dcache_line_size reg, tmp 50*f5478dedSAntonio Nino Diaz ldcopr \tmp, CTR 51*f5478dedSAntonio Nino Diaz ubfx \tmp, \tmp, #CTR_DMINLINE_SHIFT, #CTR_DMINLINE_WIDTH 52*f5478dedSAntonio Nino Diaz mov \reg, #WORD_SIZE 53*f5478dedSAntonio Nino Diaz lsl \reg, \reg, \tmp 54*f5478dedSAntonio Nino Diaz .endm 55*f5478dedSAntonio Nino Diaz 56*f5478dedSAntonio Nino Diaz .macro icache_line_size reg, tmp 57*f5478dedSAntonio Nino Diaz ldcopr \tmp, CTR 58*f5478dedSAntonio Nino Diaz and \tmp, \tmp, #CTR_IMINLINE_MASK 59*f5478dedSAntonio Nino Diaz mov \reg, #WORD_SIZE 60*f5478dedSAntonio Nino Diaz lsl \reg, \reg, \tmp 61*f5478dedSAntonio Nino Diaz .endm 62*f5478dedSAntonio Nino Diaz 63*f5478dedSAntonio Nino Diaz /* 64*f5478dedSAntonio Nino Diaz * Declare the exception vector table, enforcing it is aligned on a 65*f5478dedSAntonio Nino Diaz * 32 byte boundary. 66*f5478dedSAntonio Nino Diaz */ 67*f5478dedSAntonio Nino Diaz .macro vector_base label 68*f5478dedSAntonio Nino Diaz .section .vectors, "ax" 69*f5478dedSAntonio Nino Diaz .align 5 70*f5478dedSAntonio Nino Diaz \label: 71*f5478dedSAntonio Nino Diaz .endm 72*f5478dedSAntonio Nino Diaz 73*f5478dedSAntonio Nino Diaz /* 74*f5478dedSAntonio Nino Diaz * This macro calculates the base address of the current CPU's multi 75*f5478dedSAntonio Nino Diaz * processor(MP) stack using the plat_my_core_pos() index, the name of 76*f5478dedSAntonio Nino Diaz * the stack storage and the size of each stack. 77*f5478dedSAntonio Nino Diaz * Out: r0 = physical address of stack base 78*f5478dedSAntonio Nino Diaz * Clobber: r14, r1, r2 79*f5478dedSAntonio Nino Diaz */ 80*f5478dedSAntonio Nino Diaz .macro get_my_mp_stack _name, _size 81*f5478dedSAntonio Nino Diaz bl plat_my_core_pos 82*f5478dedSAntonio Nino Diaz ldr r2, =(\_name + \_size) 83*f5478dedSAntonio Nino Diaz mov r1, #\_size 84*f5478dedSAntonio Nino Diaz mla r0, r0, r1, r2 85*f5478dedSAntonio Nino Diaz .endm 86*f5478dedSAntonio Nino Diaz 87*f5478dedSAntonio Nino Diaz /* 88*f5478dedSAntonio Nino Diaz * This macro calculates the base address of a uniprocessor(UP) stack 89*f5478dedSAntonio Nino Diaz * using the name of the stack storage and the size of the stack 90*f5478dedSAntonio Nino Diaz * Out: r0 = physical address of stack base 91*f5478dedSAntonio Nino Diaz */ 92*f5478dedSAntonio Nino Diaz .macro get_up_stack _name, _size 93*f5478dedSAntonio Nino Diaz ldr r0, =(\_name + \_size) 94*f5478dedSAntonio Nino Diaz .endm 95*f5478dedSAntonio Nino Diaz 96*f5478dedSAntonio Nino Diaz#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 97*f5478dedSAntonio Nino Diaz /* 98*f5478dedSAntonio Nino Diaz * ARMv7 cores without Virtualization extension do not support the 99*f5478dedSAntonio Nino Diaz * eret instruction. 100*f5478dedSAntonio Nino Diaz */ 101*f5478dedSAntonio Nino Diaz .macro eret 102*f5478dedSAntonio Nino Diaz movs pc, lr 103*f5478dedSAntonio Nino Diaz .endm 104*f5478dedSAntonio Nino Diaz#endif 105*f5478dedSAntonio Nino Diaz 106*f5478dedSAntonio Nino Diaz#if (ARM_ARCH_MAJOR == 7) 107*f5478dedSAntonio Nino Diaz /* ARMv7 does not support stl instruction */ 108*f5478dedSAntonio Nino Diaz .macro stl _reg, _write_lock 109*f5478dedSAntonio Nino Diaz dmb 110*f5478dedSAntonio Nino Diaz str \_reg, \_write_lock 111*f5478dedSAntonio Nino Diaz dsb 112*f5478dedSAntonio Nino Diaz .endm 113*f5478dedSAntonio Nino Diaz#endif 114*f5478dedSAntonio Nino Diaz 115*f5478dedSAntonio Nino Diaz /* 116*f5478dedSAntonio Nino Diaz * Helper macro to generate the best mov/movw/movt combinations 117*f5478dedSAntonio Nino Diaz * according to the value to be moved. 118*f5478dedSAntonio Nino Diaz */ 119*f5478dedSAntonio Nino Diaz .macro mov_imm _reg, _val 120*f5478dedSAntonio Nino Diaz .if ((\_val) & 0xffff0000) == 0 121*f5478dedSAntonio Nino Diaz mov \_reg, #(\_val) 122*f5478dedSAntonio Nino Diaz .else 123*f5478dedSAntonio Nino Diaz movw \_reg, #((\_val) & 0xffff) 124*f5478dedSAntonio Nino Diaz movt \_reg, #((\_val) >> 16) 125*f5478dedSAntonio Nino Diaz .endif 126*f5478dedSAntonio Nino Diaz .endm 127*f5478dedSAntonio Nino Diaz 128*f5478dedSAntonio Nino Diaz /* 129*f5478dedSAntonio Nino Diaz * Macro to mark instances where we're jumping to a function and don't 130*f5478dedSAntonio Nino Diaz * expect a return. To provide the function being jumped to with 131*f5478dedSAntonio Nino Diaz * additional information, we use 'bl' instruction to jump rather than 132*f5478dedSAntonio Nino Diaz * 'b'. 133*f5478dedSAntonio Nino Diaz * 134*f5478dedSAntonio Nino Diaz * Debuggers infer the location of a call from where LR points to, which 135*f5478dedSAntonio Nino Diaz * is usually the instruction after 'bl'. If this macro expansion 136*f5478dedSAntonio Nino Diaz * happens to be the last location in a function, that'll cause the LR 137*f5478dedSAntonio Nino Diaz * to point a location beyond the function, thereby misleading debugger 138*f5478dedSAntonio Nino Diaz * back trace. We therefore insert a 'nop' after the function call for 139*f5478dedSAntonio Nino Diaz * debug builds, unless 'skip_nop' parameter is non-zero. 140*f5478dedSAntonio Nino Diaz */ 141*f5478dedSAntonio Nino Diaz .macro no_ret _func:req, skip_nop=0 142*f5478dedSAntonio Nino Diaz bl \_func 143*f5478dedSAntonio Nino Diaz#if DEBUG 144*f5478dedSAntonio Nino Diaz .ifeq \skip_nop 145*f5478dedSAntonio Nino Diaz nop 146*f5478dedSAntonio Nino Diaz .endif 147*f5478dedSAntonio Nino Diaz#endif 148*f5478dedSAntonio Nino Diaz .endm 149*f5478dedSAntonio Nino Diaz 150*f5478dedSAntonio Nino Diaz /* 151*f5478dedSAntonio Nino Diaz * Reserve space for a spin lock in assembly file. 152*f5478dedSAntonio Nino Diaz */ 153*f5478dedSAntonio Nino Diaz .macro define_asm_spinlock _name:req 154*f5478dedSAntonio Nino Diaz .align SPINLOCK_ASM_ALIGN 155*f5478dedSAntonio Nino Diaz \_name: 156*f5478dedSAntonio Nino Diaz .space SPINLOCK_ASM_SIZE 157*f5478dedSAntonio Nino Diaz .endm 158*f5478dedSAntonio Nino Diaz 159*f5478dedSAntonio Nino Diaz /* 160*f5478dedSAntonio Nino Diaz * Helper macro to OR the bottom 32 bits of `_val` into `_reg_l` 161*f5478dedSAntonio Nino Diaz * and the top 32 bits of `_val` into `_reg_h`. If either the bottom 162*f5478dedSAntonio Nino Diaz * or top word of `_val` is zero, the corresponding OR operation 163*f5478dedSAntonio Nino Diaz * is skipped. 164*f5478dedSAntonio Nino Diaz */ 165*f5478dedSAntonio Nino Diaz .macro orr64_imm _reg_l, _reg_h, _val 166*f5478dedSAntonio Nino Diaz .if (\_val >> 32) 167*f5478dedSAntonio Nino Diaz orr \_reg_h, \_reg_h, #(\_val >> 32) 168*f5478dedSAntonio Nino Diaz .endif 169*f5478dedSAntonio Nino Diaz .if (\_val & 0xffffffff) 170*f5478dedSAntonio Nino Diaz orr \_reg_l, \_reg_l, #(\_val & 0xffffffff) 171*f5478dedSAntonio Nino Diaz .endif 172*f5478dedSAntonio Nino Diaz .endm 173*f5478dedSAntonio Nino Diaz 174*f5478dedSAntonio Nino Diaz /* 175*f5478dedSAntonio Nino Diaz * Helper macro to bitwise-clear bits in `_reg_l` and 176*f5478dedSAntonio Nino Diaz * `_reg_h` given a 64 bit immediate `_val`. The set bits 177*f5478dedSAntonio Nino Diaz * in the bottom word of `_val` dictate which bits from 178*f5478dedSAntonio Nino Diaz * `_reg_l` should be cleared. Similarly, the set bits in 179*f5478dedSAntonio Nino Diaz * the top word of `_val` dictate which bits from `_reg_h` 180*f5478dedSAntonio Nino Diaz * should be cleared. If either the bottom or top word of 181*f5478dedSAntonio Nino Diaz * `_val` is zero, the corresponding BIC operation is skipped. 182*f5478dedSAntonio Nino Diaz */ 183*f5478dedSAntonio Nino Diaz .macro bic64_imm _reg_l, _reg_h, _val 184*f5478dedSAntonio Nino Diaz .if (\_val >> 32) 185*f5478dedSAntonio Nino Diaz bic \_reg_h, \_reg_h, #(\_val >> 32) 186*f5478dedSAntonio Nino Diaz .endif 187*f5478dedSAntonio Nino Diaz .if (\_val & 0xffffffff) 188*f5478dedSAntonio Nino Diaz bic \_reg_l, \_reg_l, #(\_val & 0xffffffff) 189*f5478dedSAntonio Nino Diaz .endif 190*f5478dedSAntonio Nino Diaz .endm 191*f5478dedSAntonio Nino Diaz 192*f5478dedSAntonio Nino Diaz#endif /* ASM_MACROS_S */ 193