coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
transition.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __ARCH_ARM64_TRANSITION_H__
4 #define __ARCH_ARM64_TRANSITION_H__
5 
6 /* ======================== Transition Library =================================
7  * Transition library provides two main functionalities:
8  * 1) It allows any program X to be executed at EL Y using the state Z. It
9  * provides struct exc_state which holds the state of the EL to which we want to
10  * execute X at. Before performing an eret to the entry point of the program X,
11  * it initializes required registers using this exc_state structure. Here, X0 =
12  * args to the program X. IMP!!! : We do not initialize SP_EL0 for the program
13  * X, the program will have to handle that on its own. This is because while
14  * performing an eret to X, we could make SP_EL0 point to regs structure which
15  * then follows common exception exit path.
16  * 2) It serves as a common mechanism for handling exception entry and exit at
17  * any given EL. On entry to an exception, SP_ELx is selected by default. The
18  * exc entry routine stores all xregs and jumps to exc_entry which
19  * saves ELR, SPSR, EL, Mode and other information about the state from which
20  * exception was generated. On exit, xregs are restored by unwinding of SP_ELx.
21  * =============================================================================
22  */
23 
24 /* Macros for EL mode in SPSR */
25 #define STACK_POP_BYTES 16
26 #define STACK_PUSH_BYTES -16
27 
28 #define EXC_VID_CUR_SP_EL0_SYNC 0
29 #define EXC_VID_CUR_SP_EL0_IRQ 1
30 #define EXC_VID_CUR_SP_EL0_FIRQ 2
31 #define EXC_VID_CUR_SP_EL0_SERR 3
32 #define EXC_VID_CUR_SP_ELX_SYNC 4
33 #define EXC_VID_CUR_SP_ELX_IRQ 5
34 #define EXC_VID_CUR_SP_ELX_FIQ 6
35 #define EXC_VID_CUR_SP_ELX_SERR 7
36 #define EXC_VID_LOW64_SYNC 8
37 #define EXC_VID_LOW64_IRQ 9
38 #define EXC_VID_LOW64_FIQ 10
39 #define EXC_VID_LOW64_SERR 11
40 #define EXC_VID_LOW32_SYNC 12
41 #define EXC_VID_LOW32_IRQ 13
42 #define EXC_VID_LOW32_FIQ 14
43 #define EXC_VID_LOW32_SERR 15
44 #define NUM_EXC_VIDS 16
45 
46 #ifndef __ASSEMBLER__
47 
48 #include <stdint.h>
49 #include <arch/lib_helpers.h>
50 
51 #define XI_INDEX(i) X##i##_INDEX = i
52 
53 enum {
55  XI_INDEX(1),
56  XI_INDEX(2),
57  XI_INDEX(3),
58  XI_INDEX(4),
59  XI_INDEX(5),
60  XI_INDEX(6),
61  XI_INDEX(7),
62  XI_INDEX(8),
63  XI_INDEX(9),
64  XI_INDEX(10),
65  XI_INDEX(11),
66  XI_INDEX(12),
67  XI_INDEX(13),
68  XI_INDEX(14),
69  XI_INDEX(15),
70  XI_INDEX(16),
71  XI_INDEX(17),
72  XI_INDEX(18),
73  XI_INDEX(19),
74  XI_INDEX(20),
75  XI_INDEX(21),
76  XI_INDEX(22),
77  XI_INDEX(23),
78  XI_INDEX(24),
79  XI_INDEX(25),
80  XI_INDEX(26),
81  XI_INDEX(27),
82  XI_INDEX(28),
83  XI_INDEX(29),
84  XI_INDEX(30),
86 };
87 
88 /*
89  * Important: Any changes made to the two structures below should reflect in the
90  * exc_prologue and exc_exit routines in transition_asm.S
91  */
92 struct regs {
94  uint64_t x[31];
95 };
96 
97 struct elx_state {
102 };
103 
104 struct exc_state {
105  struct elx_state elx;
106  struct regs regs;
107 };
108 
109 /*
110  * get_eret_EL returns the value of the exception state to which we will be
111  * returning. This value is saved in SPSR before performing an eret.
112  *
113  * Exception mode is defined by M[3:0] bits in SPSR:
114  * ( M[3:2] = EL, M[1] = unused, M[0] = t/h mode for stack
115  *
116  * 0b0000 EL0t
117  * 0b0100 EL1t
118  * 0b0101 EL1h
119  * 0b1000 EL2t
120  * 0b1001 EL2h
121  * 0b1100 EL3t
122  * 0b1101 EL3h
123  */
124 
125 static inline uint8_t get_eret_el(uint8_t el, uint8_t l_or_h)
126 {
127  uint8_t el_mode = el << CURRENT_EL_SHIFT;
128 
129  el_mode |= l_or_h;
130 
131  return el_mode;
132 }
133 
134 static inline uint8_t get_el_from_spsr(uint64_t spsr)
135 {
136  return ((spsr >> CURRENT_EL_SHIFT) & CURRENT_EL_MASK);
137 }
138 
140 {
141  return (spsr & SPSR_L_H_MASK);
142 }
143 
144 /* Transitions supported are:
145  * 1. elx --> elx - 1
146  * 2. Transitions to aarch64 state
147  *
148  * Other than this, if any transition needs to be supported, relevant changes
149  * need to be done to hcr/scr registers.
150  */
151 
152 /*
153  * Transitions to EL2 with given entry point and argument in X0. SPSR can be
154  * partially configured, but the exception level given must be EL2.
155  */
156 void transition_to_el2(void *entry, void *arg, uint64_t spsr);
157 
158 /*
159  * exc_exit it called while returning from an exception. It expects pointer to
160  * the regs structure on stack so that it can unwind the used stack.
161  */
162 void exc_exit(struct regs *regs);
163 /*
164  * trans_switch is called by the non-exception path i.e. transition C code
165  * while making a transition to lower EL. It select L mode so that SP_EL0 is
166  * used during the unwinding in exc_exit.
167  */
168 void trans_switch(struct regs *regs);
169 /* exc_set_vbar sets up the vbar for exception vectors. */
170 void exc_set_vbar(void);
171 
172 /* exc_dispatch is the user-defined exception handler. */
173 void exc_dispatch(struct exc_state *exc_state, uint64_t id);
174 /*
175  * exc_entry is the C based component of the exception entry before we
176  * jump to user-defined handler. This initializes all the regs in elx_state and
177  * also sets the sp value in regs structure.
178  */
179 void exc_entry(struct exc_state *exc_state, uint64_t id);
180 
181 #endif /* __ASSEMBLER__ */
182 
183 #endif /* __ARCH_ARM64_TRANSITION_H__ */
struct bootblock_arg arg
Definition: decompressor.c:22
#define CURRENT_EL_MASK
Definition: lib_helpers.h:15
#define SPSR_L_H_MASK
Definition: lib_helpers.h:20
#define CURRENT_EL_SHIFT
Definition: lib_helpers.h:16
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
uint64_t spsr
Definition: transition.h:98
uint64_t sp_el0
Definition: transition.h:99
uint64_t sp_elx
Definition: transition.h:100
uint64_t elr
Definition: transition.h:101
struct elx_state elx
Definition: transition.h:105
uint64_t x[31]
Definition: transition.h:94
uint64_t sp
Definition: transition.h:93
@ XMAX_INDEX
Definition: transition.h:85
void exc_set_vbar(void)
static uint8_t get_eret_el(uint8_t el, uint8_t l_or_h)
Definition: transition.h:125
void trans_switch(struct regs *regs)
void transition_to_el2(void *entry, void *arg, uint64_t spsr)
Definition: transition.c:33
static uint8_t get_mode_from_spsr(uint64_t spsr)
Definition: transition.h:139
void exc_dispatch(struct exc_state *exc_state, uint64_t id)
Definition: exception.c:141
static uint8_t get_el_from_spsr(uint64_t spsr)
Definition: transition.h:134
void exc_entry(struct exc_state *exc_state, uint64_t id)
Definition: transition.c:14
void exc_exit(struct regs *regs)
#define XI_INDEX(i)
Definition: transition.h:51