1*f5478dedSAntonio Nino Diaz/* 2*f5478dedSAntonio Nino Diaz * Copyright (c) 2013-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(_type) \ 19*f5478dedSAntonio Nino Diaz tlbi _type; \ 20*f5478dedSAntonio Nino Diaz dsb ish; \ 21*f5478dedSAntonio Nino Diaz tlbi _type 22*f5478dedSAntonio Nino Diaz#else 23*f5478dedSAntonio Nino Diaz#define TLB_INVALIDATE(_type) \ 24*f5478dedSAntonio Nino Diaz tlbi _type 25*f5478dedSAntonio Nino Diaz#endif 26*f5478dedSAntonio Nino Diaz 27*f5478dedSAntonio Nino Diaz 28*f5478dedSAntonio Nino Diaz .macro func_prologue 29*f5478dedSAntonio Nino Diaz stp x29, x30, [sp, #-0x10]! 30*f5478dedSAntonio Nino Diaz mov x29,sp 31*f5478dedSAntonio Nino Diaz .endm 32*f5478dedSAntonio Nino Diaz 33*f5478dedSAntonio Nino Diaz .macro func_epilogue 34*f5478dedSAntonio Nino Diaz ldp x29, x30, [sp], #0x10 35*f5478dedSAntonio Nino Diaz .endm 36*f5478dedSAntonio Nino Diaz 37*f5478dedSAntonio Nino Diaz 38*f5478dedSAntonio Nino Diaz .macro dcache_line_size reg, tmp 39*f5478dedSAntonio Nino Diaz mrs \tmp, ctr_el0 40*f5478dedSAntonio Nino Diaz ubfx \tmp, \tmp, #16, #4 41*f5478dedSAntonio Nino Diaz mov \reg, #4 42*f5478dedSAntonio Nino Diaz lsl \reg, \reg, \tmp 43*f5478dedSAntonio Nino Diaz .endm 44*f5478dedSAntonio Nino Diaz 45*f5478dedSAntonio Nino Diaz 46*f5478dedSAntonio Nino Diaz .macro icache_line_size reg, tmp 47*f5478dedSAntonio Nino Diaz mrs \tmp, ctr_el0 48*f5478dedSAntonio Nino Diaz and \tmp, \tmp, #0xf 49*f5478dedSAntonio Nino Diaz mov \reg, #4 50*f5478dedSAntonio Nino Diaz lsl \reg, \reg, \tmp 51*f5478dedSAntonio Nino Diaz .endm 52*f5478dedSAntonio Nino Diaz 53*f5478dedSAntonio Nino Diaz 54*f5478dedSAntonio Nino Diaz .macro smc_check label 55*f5478dedSAntonio Nino Diaz mrs x0, esr_el3 56*f5478dedSAntonio Nino Diaz ubfx x0, x0, #ESR_EC_SHIFT, #ESR_EC_LENGTH 57*f5478dedSAntonio Nino Diaz cmp x0, #EC_AARCH64_SMC 58*f5478dedSAntonio Nino Diaz b.ne $label 59*f5478dedSAntonio Nino Diaz .endm 60*f5478dedSAntonio Nino Diaz 61*f5478dedSAntonio Nino Diaz /* 62*f5478dedSAntonio Nino Diaz * Declare the exception vector table, enforcing it is aligned on a 63*f5478dedSAntonio Nino Diaz * 2KB boundary, as required by the ARMv8 architecture. 64*f5478dedSAntonio Nino Diaz * Use zero bytes as the fill value to be stored in the padding bytes 65*f5478dedSAntonio Nino Diaz * so that it inserts illegal AArch64 instructions. This increases 66*f5478dedSAntonio Nino Diaz * security, robustness and potentially facilitates debugging. 67*f5478dedSAntonio Nino Diaz */ 68*f5478dedSAntonio Nino Diaz .macro vector_base label, section_name=.vectors 69*f5478dedSAntonio Nino Diaz .section \section_name, "ax" 70*f5478dedSAntonio Nino Diaz .align 11, 0 71*f5478dedSAntonio Nino Diaz \label: 72*f5478dedSAntonio Nino Diaz .endm 73*f5478dedSAntonio Nino Diaz 74*f5478dedSAntonio Nino Diaz /* 75*f5478dedSAntonio Nino Diaz * Create an entry in the exception vector table, enforcing it is 76*f5478dedSAntonio Nino Diaz * aligned on a 128-byte boundary, as required by the ARMv8 architecture. 77*f5478dedSAntonio Nino Diaz * Use zero bytes as the fill value to be stored in the padding bytes 78*f5478dedSAntonio Nino Diaz * so that it inserts illegal AArch64 instructions. This increases 79*f5478dedSAntonio Nino Diaz * security, robustness and potentially facilitates debugging. 80*f5478dedSAntonio Nino Diaz */ 81*f5478dedSAntonio Nino Diaz .macro vector_entry label, section_name=.vectors 82*f5478dedSAntonio Nino Diaz .cfi_sections .debug_frame 83*f5478dedSAntonio Nino Diaz .section \section_name, "ax" 84*f5478dedSAntonio Nino Diaz .align 7, 0 85*f5478dedSAntonio Nino Diaz .type \label, %function 86*f5478dedSAntonio Nino Diaz .cfi_startproc 87*f5478dedSAntonio Nino Diaz \label: 88*f5478dedSAntonio Nino Diaz .endm 89*f5478dedSAntonio Nino Diaz 90*f5478dedSAntonio Nino Diaz /* 91*f5478dedSAntonio Nino Diaz * Add the bytes until fill the full exception vector, whose size is always 92*f5478dedSAntonio Nino Diaz * 32 instructions. If there are more than 32 instructions in the 93*f5478dedSAntonio Nino Diaz * exception vector then an error is emitted. 94*f5478dedSAntonio Nino Diaz */ 95*f5478dedSAntonio Nino Diaz .macro end_vector_entry label 96*f5478dedSAntonio Nino Diaz .cfi_endproc 97*f5478dedSAntonio Nino Diaz .fill \label + (32 * 4) - . 98*f5478dedSAntonio Nino Diaz .endm 99*f5478dedSAntonio Nino Diaz 100*f5478dedSAntonio Nino Diaz /* 101*f5478dedSAntonio Nino Diaz * This macro calculates the base address of the current CPU's MP stack 102*f5478dedSAntonio Nino Diaz * using the plat_my_core_pos() index, the name of the stack storage 103*f5478dedSAntonio Nino Diaz * and the size of each stack 104*f5478dedSAntonio Nino Diaz * Out: X0 = physical address of stack base 105*f5478dedSAntonio Nino Diaz * Clobber: X30, X1, X2 106*f5478dedSAntonio Nino Diaz */ 107*f5478dedSAntonio Nino Diaz .macro get_my_mp_stack _name, _size 108*f5478dedSAntonio Nino Diaz bl plat_my_core_pos 109*f5478dedSAntonio Nino Diaz adrp x2, (\_name + \_size) 110*f5478dedSAntonio Nino Diaz add x2, x2, :lo12:(\_name + \_size) 111*f5478dedSAntonio Nino Diaz mov x1, #\_size 112*f5478dedSAntonio Nino Diaz madd x0, x0, x1, x2 113*f5478dedSAntonio Nino Diaz .endm 114*f5478dedSAntonio Nino Diaz 115*f5478dedSAntonio Nino Diaz /* 116*f5478dedSAntonio Nino Diaz * This macro calculates the base address of a UP stack using the 117*f5478dedSAntonio Nino Diaz * name of the stack storage and the size of the stack 118*f5478dedSAntonio Nino Diaz * Out: X0 = physical address of stack base 119*f5478dedSAntonio Nino Diaz */ 120*f5478dedSAntonio Nino Diaz .macro get_up_stack _name, _size 121*f5478dedSAntonio Nino Diaz adrp x0, (\_name + \_size) 122*f5478dedSAntonio Nino Diaz add x0, x0, :lo12:(\_name + \_size) 123*f5478dedSAntonio Nino Diaz .endm 124*f5478dedSAntonio Nino Diaz 125*f5478dedSAntonio Nino Diaz /* 126*f5478dedSAntonio Nino Diaz * Helper macro to generate the best mov/movk combinations according 127*f5478dedSAntonio Nino Diaz * the value to be moved. The 16 bits from '_shift' are tested and 128*f5478dedSAntonio Nino Diaz * if not zero, they are moved into '_reg' without affecting 129*f5478dedSAntonio Nino Diaz * other bits. 130*f5478dedSAntonio Nino Diaz */ 131*f5478dedSAntonio Nino Diaz .macro _mov_imm16 _reg, _val, _shift 132*f5478dedSAntonio Nino Diaz .if (\_val >> \_shift) & 0xffff 133*f5478dedSAntonio Nino Diaz .if (\_val & (1 << \_shift - 1)) 134*f5478dedSAntonio Nino Diaz movk \_reg, (\_val >> \_shift) & 0xffff, LSL \_shift 135*f5478dedSAntonio Nino Diaz .else 136*f5478dedSAntonio Nino Diaz mov \_reg, \_val & (0xffff << \_shift) 137*f5478dedSAntonio Nino Diaz .endif 138*f5478dedSAntonio Nino Diaz .endif 139*f5478dedSAntonio Nino Diaz .endm 140*f5478dedSAntonio Nino Diaz 141*f5478dedSAntonio Nino Diaz /* 142*f5478dedSAntonio Nino Diaz * Helper macro to load arbitrary values into 32 or 64-bit registers 143*f5478dedSAntonio Nino Diaz * which generates the best mov/movk combinations. Many base addresses 144*f5478dedSAntonio Nino Diaz * are 64KB aligned the macro will eliminate updating bits 15:0 in 145*f5478dedSAntonio Nino Diaz * that case 146*f5478dedSAntonio Nino Diaz */ 147*f5478dedSAntonio Nino Diaz .macro mov_imm _reg, _val 148*f5478dedSAntonio Nino Diaz .if (\_val) == 0 149*f5478dedSAntonio Nino Diaz mov \_reg, #0 150*f5478dedSAntonio Nino Diaz .else 151*f5478dedSAntonio Nino Diaz _mov_imm16 \_reg, (\_val), 0 152*f5478dedSAntonio Nino Diaz _mov_imm16 \_reg, (\_val), 16 153*f5478dedSAntonio Nino Diaz _mov_imm16 \_reg, (\_val), 32 154*f5478dedSAntonio Nino Diaz _mov_imm16 \_reg, (\_val), 48 155*f5478dedSAntonio Nino Diaz .endif 156*f5478dedSAntonio Nino Diaz .endm 157*f5478dedSAntonio Nino Diaz 158*f5478dedSAntonio Nino Diaz /* 159*f5478dedSAntonio Nino Diaz * Macro to mark instances where we're jumping to a function and don't 160*f5478dedSAntonio Nino Diaz * expect a return. To provide the function being jumped to with 161*f5478dedSAntonio Nino Diaz * additional information, we use 'bl' instruction to jump rather than 162*f5478dedSAntonio Nino Diaz * 'b'. 163*f5478dedSAntonio Nino Diaz * 164*f5478dedSAntonio Nino Diaz * Debuggers infer the location of a call from where LR points to, which 165*f5478dedSAntonio Nino Diaz * is usually the instruction after 'bl'. If this macro expansion 166*f5478dedSAntonio Nino Diaz * happens to be the last location in a function, that'll cause the LR 167*f5478dedSAntonio Nino Diaz * to point a location beyond the function, thereby misleading debugger 168*f5478dedSAntonio Nino Diaz * back trace. We therefore insert a 'nop' after the function call for 169*f5478dedSAntonio Nino Diaz * debug builds, unless 'skip_nop' parameter is non-zero. 170*f5478dedSAntonio Nino Diaz */ 171*f5478dedSAntonio Nino Diaz .macro no_ret _func:req, skip_nop=0 172*f5478dedSAntonio Nino Diaz bl \_func 173*f5478dedSAntonio Nino Diaz#if DEBUG 174*f5478dedSAntonio Nino Diaz .ifeq \skip_nop 175*f5478dedSAntonio Nino Diaz nop 176*f5478dedSAntonio Nino Diaz .endif 177*f5478dedSAntonio Nino Diaz#endif 178*f5478dedSAntonio Nino Diaz .endm 179*f5478dedSAntonio Nino Diaz 180*f5478dedSAntonio Nino Diaz /* 181*f5478dedSAntonio Nino Diaz * Reserve space for a spin lock in assembly file. 182*f5478dedSAntonio Nino Diaz */ 183*f5478dedSAntonio Nino Diaz .macro define_asm_spinlock _name:req 184*f5478dedSAntonio Nino Diaz .align SPINLOCK_ASM_ALIGN 185*f5478dedSAntonio Nino Diaz \_name: 186*f5478dedSAntonio Nino Diaz .space SPINLOCK_ASM_SIZE 187*f5478dedSAntonio Nino Diaz .endm 188*f5478dedSAntonio Nino Diaz 189*f5478dedSAntonio Nino Diaz#if RAS_EXTENSION 190*f5478dedSAntonio Nino Diaz .macro esb 191*f5478dedSAntonio Nino Diaz .inst 0xd503221f 192*f5478dedSAntonio Nino Diaz .endm 193*f5478dedSAntonio Nino Diaz#endif 194*f5478dedSAntonio Nino Diaz 195*f5478dedSAntonio Nino Diaz#endif /* ASM_MACROS_S */ 196