1/* SPDX-License-Identifier: BSD-2-Clause */ 2/* 3 * Copyright (c) 2015, Linaro Limited 4 */ 5 6 .altmacro 7 8 /* 9 * This helper macro concatenates instr_prefix, instr_suffix, to 10 * create a ldp/stp instruction. It also selects register name x/w 11 * based on reg_bytes. 12 */ 13 .macro __do_dregs instr_prefix, instr_suffix, reg_bytes, base_reg, \ 14 base_offs, reg0, reg1 15 .if \reg_bytes == 8 16 \instr_prefix\instr_suffix \ 17 x\reg0, x\reg1, [\base_reg, #\base_offs] 18 .else 19 \instr_prefix\instr_suffix \ 20 w\reg0, w\reg1, [\base_reg, #\base_offs] 21 .endif 22 .endm 23 24 /* 25 * This helper macro concatenates instr_prefix, instr_suffix, to 26 * create a ldr/str instruction. It also selects register name x/w 27 * based on reg_bytes. 28 */ 29 .macro __do_reg instr_prefix, instr_suffix, reg_bytes, base_reg, \ 30 base_offs, reg 31 .if \reg_bytes == 8 32 \instr_prefix\instr_suffix \ 33 x\reg, [\base_reg, #\base_offs] 34 .else 35 \instr_prefix\instr_suffix \ 36 w\reg, [\base_reg, #\base_offs] 37 .endif 38 .endm 39 40 /* 41 * This helper macro uses recursion to create a loop which will 42 * start with generating instructions for register pairs and if 43 * it's an odd number of registers end with a single load/store. 44 */ 45 .macro _do_regs instr_prefix, reg_bytes, base_reg, base_offs, \ 46 from_regnum, to_regnum 47 .if (\to_regnum - \from_regnum + 1) >= 2 48 __do_dregs \instr_prefix, p, \reg_bytes, \base_reg, \ 49 \base_offs, \from_regnum, %(\from_regnum + 1) 50 .else 51 __do_reg \instr_prefix, r, \reg_bytes, \base_reg, \ 52 \base_offs, \from_regnum 53 .endif 54 .if (\to_regnum - \from_regnum + 1) > 2 55 _do_regs \instr_prefix, \reg_bytes, \base_reg, \ 56 %(\base_offs + 2 * \reg_bytes), \ 57 %(\from_regnum + 2), \to_regnum 58 .endif 59 .endm 60 61 /* 62 * Stores registers x[from_regnum]..x[to_regnum] at 63 * [base_reg, #base_offs] 64 */ 65 .macro store_xregs base_reg, base_offs, from_regnum, to_regnum 66 _do_regs st 8 \base_reg, \base_offs, \from_regnum, \to_regnum 67 .endm 68 69 /* 70 * Stores registers w[from_regnum]..w[to_regnum] at 71 * [base_reg, #base_offs] 72 */ 73 .macro store_wregs base_reg, base_offs, from_regnum, to_regnum 74 _do_regs st 4 \base_reg, \base_offs, \from_regnum, \to_regnum 75 .endm 76 77 /* 78 * Loads registers x[from_regnum]..x[to_regnum] at 79 * [base_reg, #base_offs] 80 */ 81 .macro load_xregs base_reg, base_offs, from_regnum, to_regnum 82 _do_regs ld 8 \base_reg, \base_offs, \from_regnum, \to_regnum 83 .endm 84 85 /* 86 * Loads registers w[from_regnum]..w[to_regnum] at 87 * [base_reg, #base_offs] 88 */ 89 .macro load_wregs base_reg, base_offs, from_regnum, to_regnum 90 _do_regs ld 4 \base_reg, \base_offs, \from_regnum, \to_regnum 91 .endm 92 93 94 /* Push register pair on stack */ 95 .macro push, r1, r2 96 stp \r1, \r2, [sp, #-16]! 97 .endm 98 99 /* Pop register pair from stack */ 100 .macro pop, r1, r2 101 ldp \r1, \r2, [sp], #16 102 .endm 103 104 .macro mov_imm _reg, _val 105 .if (((\_val) >> 31) == 0 || ((\_val) >> 31) == 0x1ffffffff) 106 movz \_reg, :abs_g1_s:\_val 107 .else 108 .if (((\_val) >> 47) == 0 || ((\_val) >> 47) == 0x1ffff) 109 movz \_reg, :abs_g2_s:\_val 110 .else 111 movz \_reg, :abs_g3:\_val 112 movk \_reg, :abs_g2_nc:\_val 113 .endif 114 movk \_reg, :abs_g1_nc:\_val 115 .endif 116 movk \_reg, :abs_g0_nc:\_val 117 .endm 118 119 .macro add_imm _reg, _val 120 .if ((\_val) > 0xfff) 121 add \_reg, \_reg, ((\_val) >> 12), LSL #12 122 .endif 123 .if (((\_val) & 0xfff) > 0) 124 add \_reg, \_reg, ((\_val) & 0xfff) 125 .endif 126 .endm 127 128 .macro sub_imm _reg, _val 129 .if ((\_val) > 0xfff) 130 sub \_reg, \_reg, ((\_val) >> 12), LSL #12 131 .endif 132 .if (((\_val) & 0xfff) > 0) 133 sub \_reg, \_reg, ((\_val) & 0xfff) 134 .endif 135 .endm 136 137 /* 138 * Load address of <sym> into <reg>, <sym> being in the range 139 * +/- 4GB of the PC (note that 'adr reg, sym' is limited to +/- 1MB). 140 */ 141 .macro adr_l reg, sym 142 adrp \reg, \sym 143 add \reg, \reg, :lo12:\sym 144 .endm 145 146 .macro panic_at_smc_return 147#if defined(CFG_TEE_CORE_DEBUG) 148 bl __panic_at_smc_return 149#else 150 b . 151#endif 152 .endm 153 154 .macro read_apiakeylo reg 155 mrs \reg, S3_0_c2_c1_0 156 .endm 157 158 .macro read_apiakeyhi reg 159 mrs \reg, S3_0_c2_c1_1 160 .endm 161 162 .macro write_apiakeylo reg 163 msr S3_0_c2_c1_0, \reg 164 .endm 165 166 .macro write_apiakeyhi reg 167 msr S3_0_c2_c1_1, \reg 168 .endm 169 170 .macro write_pan reg 171 /* msr pan, \reg */ 172 msr S3_0_c4_c2_3, \reg 173 .endm 174 175 .macro write_pan_enable 176 /* msr pan, #1 */ 177 msr S0_0_c4_c1_4, xzr 178 .endm 179 180 .macro write_pan_disable 181 /* msr pan, #0 */ 182 msr S0_0_c4_c0_4, xzr 183 .endm 184