blob: 2b346c4d4175eca0d49b846895434f01ca554e24 [file] [log] [blame]
Furquan Shaikh635b45d2014-08-27 12:16:16 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * lib_helpers.h: All library function prototypes and macros are defined in this
30 * file.
31 */
32
33#ifndef __ARCH_LIB_HELPERS_H__
34#define __ARCH_LIB_HELPERS_H__
35
Furquan Shaikh4c2cb162014-08-27 15:57:47 -070036#ifdef __ASSEMBLY__
37
38/* Macro to switch to label based on current el */
39.macro switch_el xreg label1 label2 label3
40 mrs \xreg, CurrentEL
41 /* Currently at EL1 */
42 cmp \xreg, 0x4
43 b.eq \label1
44 /* Currently at EL2 */
45 cmp \xreg, 0x8
46 b.eq \label2
47 /* Currently at EL3 */
48 cmp \xreg, 0xc
49 b.eq \label3
50.endm
51
52/* Macro to read sysreg at current EL
53 xreg - reg in which read value needs to be stored
54 sysreg - system reg that is to be read
55*/
56.macro read_current xreg sysreg
57 switch_el \xreg, 101f, 102f, 103f
58101:
59 mrs \xreg, \sysreg\()_el1
60 b 104f
61102:
62 mrs \xreg, \sysreg\()_el2
63 b 104f
64103:
65 mrs \xreg, \sysreg\()_el3
66 b 104f
67104:
68.endm
69
70/* Macro to write sysreg at current EL
71 xreg - reg from which value needs to be written
72 sysreg - system reg that is to be written
73 temp - temp reg that can be used to read current EL
74*/
75.macro write_current sysreg xreg temp
76 switch_el \temp, 101f, 102f, 103f
77101:
78 msr \sysreg\()_el1, \xreg
79 b 104f
80102:
81 msr \sysreg\()_el2, \xreg
82 b 104f
83103:
84 msr \sysreg\()_el3, \xreg
85 b 104f
86104:
87.endm
88
89#else
90
Furquan Shaikh635b45d2014-08-27 12:16:16 -070091#define EL0 0
92#define EL1 1
93#define EL2 2
94#define EL3 3
95
96#define CURRENT_EL_MASK 0x3
97#define CURRENT_EL_SHIFT 2
98
HC Yen11e743c2015-01-13 11:36:14 +080099#include <stdint.h>
100
Elyes HAOUAS70083a12017-06-27 21:51:20 +0200101#define DAIF_DBG_BIT (1 << 3)
102#define DAIF_ABT_BIT (1 << 2)
103#define DAIF_IRQ_BIT (1 << 1)
104#define DAIF_FIQ_BIT (1 << 0)
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700105
HC Yen11e743c2015-01-13 11:36:14 +0800106#define SWITCH_CASE_READ(func, var, type, el) do { \
107 type var = -1; \
108 switch (el) { \
109 case EL1: \
110 var = func##_el1(); \
111 break; \
112 case EL2: \
113 var = func##_el2(); \
114 break; \
115 case EL3: \
116 var = func##_el3(); \
117 break; \
118 } \
119 return var; \
120 } while (0)
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700121
HC Yen11e743c2015-01-13 11:36:14 +0800122#define SWITCH_CASE_WRITE(func, var, el) do { \
123 switch (el) { \
124 case EL1: \
125 func##_el1(var); \
126 break; \
127 case EL2: \
128 func##_el2(var); \
129 break; \
130 case EL3: \
131 func##_el3(var); \
132 break; \
133 } \
134 } while (0)
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700135
HC Yen11e743c2015-01-13 11:36:14 +0800136#define SWITCH_CASE_TLBI(func, el) do { \
137 switch (el) { \
138 case EL1: \
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700139 func##_el1(); \
140 break; \
HC Yen11e743c2015-01-13 11:36:14 +0800141 case EL2: \
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700142 func##_el2(); \
143 break; \
HC Yen11e743c2015-01-13 11:36:14 +0800144 case EL3: \
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700145 func##_el3(); \
146 break; \
147 } \
HC Yen11e743c2015-01-13 11:36:14 +0800148 } while (0)
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700149
150/* PSTATE and special purpose register access functions */
151uint32_t raw_read_current_el(void);
152uint32_t get_current_el(void);
153uint32_t raw_read_daif(void);
154void raw_write_daif(uint32_t daif);
155void enable_debug_exceptions(void);
156void enable_serror_exceptions(void);
157void enable_irq(void);
158void enable_fiq(void);
159void disable_debug_exceptions(void);
160void disable_serror_exceptions(void);
161void disable_irq(void);
162void disable_fiq(void);
163uint64_t raw_read_dlr_el0(void);
164void raw_write_dlr_el0(uint64_t dlr_el0);
165uint64_t raw_read_dspsr_el0(void);
166void raw_write_dspsr_el0(uint64_t dspsr_el0);
167uint64_t raw_read_elr_el1(void);
168void raw_write_elr_el1(uint64_t elr_el1);
169uint64_t raw_read_elr_el2(void);
170void raw_write_elr_el2(uint64_t elr_el2);
171uint64_t raw_read_elr_el3(void);
172void raw_write_elr_el3(uint64_t elr_el3);
173uint64_t raw_read_elr_current(void);
174void raw_write_elr_current(uint64_t elr);
HC Yen11e743c2015-01-13 11:36:14 +0800175uint64_t raw_read_elr(uint32_t el);
176void raw_write_elr(uint64_t elr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700177uint32_t raw_read_fpcr(void);
178void raw_write_fpcr(uint32_t fpcr);
179uint32_t raw_read_fpsr(void);
180void raw_write_fpsr(uint32_t fpsr);
181uint32_t raw_read_nzcv(void);
182void raw_write_nzcv(uint32_t nzcv);
183uint64_t raw_read_sp_el0(void);
184void raw_write_sp_el0(uint64_t sp_el0);
185uint64_t raw_read_sp_el1(void);
186void raw_write_sp_el1(uint64_t sp_el1);
187uint64_t raw_read_sp_el2(void);
188void raw_write_sp_el2(uint64_t sp_el2);
189uint32_t raw_read_spsel(void);
190void raw_write_spsel(uint32_t spsel);
191uint64_t raw_read_sp_el3(void);
192void raw_write_sp_el3(uint64_t sp_el3);
193uint32_t raw_read_spsr_abt(void);
194void raw_write_spsr_abt(uint32_t spsr_abt);
195uint32_t raw_read_spsr_el1(void);
196void raw_write_spsr_el1(uint32_t spsr_el1);
197uint32_t raw_read_spsr_el2(void);
198void raw_write_spsr_el2(uint32_t spsr_el2);
199uint32_t raw_read_spsr_el3(void);
200void raw_write_spsr_el3(uint32_t spsr_el3);
201uint32_t raw_read_spsr_current(void);
202void raw_write_spsr_current(uint32_t spsr);
HC Yen11e743c2015-01-13 11:36:14 +0800203uint32_t raw_read_spsr(uint32_t el);
204void raw_write_spsr(uint32_t spsr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700205uint32_t raw_read_spsr_fiq(void);
206void raw_write_spsr_fiq(uint32_t spsr_fiq);
207uint32_t raw_read_spsr_irq(void);
208void raw_write_spsr_irq(uint32_t spsr_irq);
209uint32_t raw_read_spsr_und(void);
210void raw_write_spsr_und(uint32_t spsr_und);
211
212/* System control register access */
213uint32_t raw_read_actlr_el1(void);
214void raw_write_actlr_el1(uint32_t actlr_el1);
215uint32_t raw_read_actlr_el2(void);
216void raw_write_actlr_el2(uint32_t actlr_el2);
217uint32_t raw_read_actlr_el3(void);
218void raw_write_actlr_el3(uint32_t actlr_el3);
219uint32_t raw_read_actlr_current(void);
220void raw_write_actlr_current(uint32_t actlr);
HC Yen11e743c2015-01-13 11:36:14 +0800221uint32_t raw_read_actlr(uint32_t el);
222void raw_write_actlr(uint32_t actlr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700223uint32_t raw_read_afsr0_el1(void);
224void raw_write_afsr0_el1(uint32_t afsr0_el1);
225uint32_t raw_read_afsr0_el2(void);
226void raw_write_afsr0_el2(uint32_t afsr0_el2);
227uint32_t raw_read_afsr0_el3(void);
228void raw_write_afsr0_el3(uint32_t afsr0_el3);
229uint32_t raw_read_afsr0_current(void);
230void raw_write_afsr0_current(uint32_t afsr0);
HC Yen11e743c2015-01-13 11:36:14 +0800231uint32_t raw_read_afsr0(uint32_t el);
232void raw_write_afsr0(uint32_t afsr0, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700233uint32_t raw_read_afsr1_el1(void);
234void raw_write_afsr1_el1(uint32_t afsr1_el1);
235uint32_t raw_read_afsr1_el2(void);
236void raw_write_afsr1_el2(uint32_t afsr1_el2);
237uint32_t raw_read_afsr1_el3(void);
238void raw_write_afsr1_el3(uint32_t afsr1_el3);
239uint32_t raw_read_afsr1_current(void);
240void raw_write_afsr1_current(uint32_t afsr1);
HC Yen11e743c2015-01-13 11:36:14 +0800241uint32_t raw_read_afsr1(uint32_t el);
242void raw_write_afsr1(uint32_t afsr1, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700243uint32_t raw_read_aidr_el1(void);
244uint64_t raw_read_amair_el1(void);
245void raw_write_amair_el1(uint64_t amair_el1);
246uint64_t raw_read_amair_el2(void);
247void raw_write_amair_el2(uint64_t amair_el2);
248uint64_t raw_read_amair_el3(void);
249void raw_write_amair_el3(uint64_t amair_el3);
250uint64_t raw_read_amair_current(void);
251void raw_write_amair_current(uint64_t amair);
HC Yen11e743c2015-01-13 11:36:14 +0800252uint64_t raw_read_amair(uint32_t el);
253void raw_write_amair(uint64_t amair, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700254uint32_t raw_read_ccsidr_el1(void);
255uint32_t raw_read_clidr_el1(void);
256uint32_t raw_read_cpacr_el1(void);
257void raw_write_cpacr_el1(uint32_t cpacr_el1);
258uint32_t raw_read_cptr_el2(void);
259void raw_write_cptr_el2(uint32_t cptr_el2);
260uint32_t raw_read_cptr_el3(void);
261void raw_write_cptr_el3(uint32_t cptr_el3);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700262uint32_t raw_read_csselr_el1(void);
263void raw_write_csselr_el1(uint32_t csselr_el1);
264uint32_t raw_read_ctr_el0(void);
265uint32_t raw_read_esr_el1(void);
266void raw_write_esr_el1(uint32_t esr_el1);
267uint32_t raw_read_esr_el2(void);
268void raw_write_esr_el2(uint32_t esr_el2);
269uint32_t raw_read_esr_el3(void);
270void raw_write_esr_el3(uint32_t esr_el3);
271uint32_t raw_read_esr_current(void);
272void raw_write_esr_current(uint32_t esr);
HC Yen11e743c2015-01-13 11:36:14 +0800273uint32_t raw_read_esr(uint32_t el);
274void raw_write_esr(uint32_t esr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700275uint64_t raw_read_far_el1(void);
276void raw_write_far_el1(uint64_t far_el1);
277uint64_t raw_read_far_el2(void);
278void raw_write_far_el2(uint64_t far_el2);
279uint64_t raw_read_far_el3(void);
280void raw_write_far_el3(uint64_t far_el3);
281uint64_t raw_read_far_current(void);
282void raw_write_far_current(uint64_t far);
HC Yen11e743c2015-01-13 11:36:14 +0800283uint64_t raw_read_far(uint32_t el);
284void raw_write_far(uint64_t far, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700285uint64_t raw_read_hcr_el2(void);
286void raw_write_hcr_el2(uint64_t hcr_el2);
287uint64_t raw_read_aa64pfr0_el1(void);
288uint64_t raw_read_mair_el1(void);
289void raw_write_mair_el1(uint64_t mair_el1);
290uint64_t raw_read_mair_el2(void);
291void raw_write_mair_el2(uint64_t mair_el2);
292uint64_t raw_read_mair_el3(void);
293void raw_write_mair_el3(uint64_t mair_el3);
294uint64_t raw_read_mair_current(void);
295void raw_write_mair_current(uint64_t mair);
HC Yen11e743c2015-01-13 11:36:14 +0800296uint64_t raw_read_mair(uint32_t el);
297void raw_write_mair(uint64_t mair, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700298uint64_t raw_read_mpidr_el1(void);
299uint32_t raw_read_rmr_el1(void);
300void raw_write_rmr_el1(uint32_t rmr_el1);
301uint32_t raw_read_rmr_el2(void);
302void raw_write_rmr_el2(uint32_t rmr_el2);
303uint32_t raw_read_rmr_el3(void);
304void raw_write_rmr_el3(uint32_t rmr_el3);
305uint32_t raw_read_rmr_current(void);
306void raw_write_rmr_current(uint32_t rmr);
HC Yen11e743c2015-01-13 11:36:14 +0800307uint32_t raw_read_rmr(uint32_t el);
308void raw_write_rmr(uint32_t rmr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700309uint64_t raw_read_rvbar_el1(void);
310void raw_write_rvbar_el1(uint64_t rvbar_el1);
311uint64_t raw_read_rvbar_el2(void);
312void raw_write_rvbar_el2(uint64_t rvbar_el2);
313uint64_t raw_read_rvbar_el3(void);
314void raw_write_rvbar_el3(uint64_t rvbar_el3);
315uint64_t raw_read_rvbar_current(void);
316void raw_write_rvbar_current(uint64_t rvbar);
HC Yen11e743c2015-01-13 11:36:14 +0800317uint64_t raw_read_rvbar(uint32_t el);
318void raw_write_rvbar(uint64_t rvbar, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700319uint32_t raw_read_scr_el3(void);
320void raw_write_scr_el3(uint32_t scr_el3);
321uint32_t raw_read_sctlr_el1(void);
322void raw_write_sctlr_el1(uint32_t sctlr_el1);
323uint32_t raw_read_sctlr_el2(void);
324void raw_write_sctlr_el2(uint32_t sctlr_el2);
325uint32_t raw_read_sctlr_el3(void);
326void raw_write_sctlr_el3(uint32_t sctlr_el3);
327uint32_t raw_read_sctlr_current(void);
328void raw_write_sctlr_current(uint32_t sctlr);
HC Yen11e743c2015-01-13 11:36:14 +0800329uint32_t raw_read_sctlr(uint32_t el);
330void raw_write_sctlr(uint32_t sctlr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700331uint64_t raw_read_tcr_el1(void);
332void raw_write_tcr_el1(uint64_t tcr_el1);
333uint32_t raw_read_tcr_el2(void);
334void raw_write_tcr_el2(uint32_t tcr_el2);
335uint32_t raw_read_tcr_el3(void);
336void raw_write_tcr_el3(uint32_t tcr_el3);
Furquan Shaikhc10e7f22014-09-04 15:03:48 -0700337uint64_t raw_read_tcr_current(void);
338void raw_write_tcr_current(uint64_t tcr);
HC Yen11e743c2015-01-13 11:36:14 +0800339uint64_t raw_read_tcr(uint32_t el);
340void raw_write_tcr(uint64_t tcr, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700341uint64_t raw_read_ttbr0_el1(void);
342void raw_write_ttbr0_el1(uint64_t ttbr0_el1);
343uint64_t raw_read_ttbr0_el2(void);
344void raw_write_ttbr0_el2(uint64_t ttbr0_el2);
345uint64_t raw_read_ttbr0_el3(void);
346void raw_write_ttbr0_el3(uint64_t ttbr0_el3);
347uint64_t raw_read_ttbr0_current(void);
348void raw_write_ttbr0_current(uint64_t ttbr0);
HC Yen11e743c2015-01-13 11:36:14 +0800349uint64_t raw_read_ttbr0(uint32_t el);
350void raw_write_ttbr0(uint64_t ttbr0, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700351uint64_t raw_read_ttbr1_el1(void);
352void raw_write_ttbr1_el1(uint64_t ttbr1_el1);
353uint64_t raw_read_vbar_el1(void);
354void raw_write_vbar_el1(uint64_t vbar_el1);
355uint64_t raw_read_vbar_el2(void);
356void raw_write_vbar_el2(uint64_t vbar_el2);
357uint64_t raw_read_vbar_el3(void);
358void raw_write_vbar_el3(uint64_t vbar_el3);
359uint64_t raw_read_vbar_current(void);
360void raw_write_vbar_current(uint64_t vbar);
HC Yen11e743c2015-01-13 11:36:14 +0800361uint64_t raw_read_vbar(uint32_t el);
362void raw_write_vbar(uint64_t vbar, uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700363
364/* Cache maintenance system instructions */
365void dccisw(uint64_t cisw);
366void dccivac(uint64_t civac);
367void dccsw(uint64_t csw);
368void dccvac(uint64_t cvac);
369void dccvau(uint64_t cvau);
370void dcisw(uint64_t isw);
371void dcivac(uint64_t ivac);
372void dczva(uint64_t zva);
373void iciallu(void);
374void icialluis(void);
375void icivau(uint64_t ivau);
376
377/* TLB maintenance instructions */
378void tlbiall_el1(void);
379void tlbiall_el2(void);
380void tlbiall_el3(void);
381void tlbiall_current(void);
HC Yen11e743c2015-01-13 11:36:14 +0800382void tlbiall(uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700383void tlbiallis_el1(void);
384void tlbiallis_el2(void);
385void tlbiallis_el3(void);
386void tlbiallis_current(void);
HC Yen11e743c2015-01-13 11:36:14 +0800387void tlbiallis(uint32_t el);
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700388void tlbivaa_el1(uint64_t va);
389
390/* Memory barrier */
391/* data memory barrier */
392#define dmb_opt(opt) asm volatile ("dmb " #opt : : : "memory")
393/* data sync barrier */
394#define dsb_opt(opt) asm volatile ("dsb " #opt : : : "memory")
395/* instruction sync barrier */
396#define isb_opt(opt) asm volatile ("isb " #opt : : : "memory")
397
398#define dmb() dmb_opt(sy)
399#define dsb() dsb_opt(sy)
400#define isb() isb_opt()
401
402/* Clock */
403void set_cntfrq(uint32_t freq);
404
Furquan Shaikh4c2cb162014-08-27 15:57:47 -0700405#endif // __ASSEMBLY__
406
Furquan Shaikh635b45d2014-08-27 12:16:16 -0700407#endif //__ARCH_LIB_HELPERS_H__