Lab3: Switch from EL2 to EL0

First exception

Exception class (EC)

  • 0x15: Synchronous External abort on translation table walk or hardware update of translation table, level 1.
  • 0x3C: BRK instruction execution in AArch64 state.

Ref: Arm Armv8-A Architecture Registers

Example code

1
2
3
4
5
6
7
8
9
10
void exception_handler(unsigned long type, unsigned long esr, unsigned long elr, unsigned long spsr, unsigned long far){
unsigned int ec, iss;
ec = (esr>>26) & ((1<<6)-1);
iss = esr&((1<<24) - 1);
uart_printf("Type: %d\n", type);
uart_printf("Exception return address 0x%h\n", elr);
uart_printf("Exception class (EC) 0x%h\n", ec);
uart_printf("Instruction specific synfrome (ISS) 0x%h\n", iss);
while(1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Simple vector table
.align 11 // vector table should be aligned to 0x800
.global exception_table
exception_table:
b exception_handler // branch to a handler function.
.align 7 // entry size is 0x80, .align will pad 0
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7

mov x0, #0
mrs x1, esr_el2
mrs x2, elr_el2
mrs x3, spsr_el2
mrs x4, far_el2
b exception_handler
.align 7
mov x0, #1
mrs x1, esr_el2
mrs x2, elr_el2
mrs x3, spsr_el2
mrs x4, far_el2
b exception_handler
.align 7
mov x0, #2
mrs x1, esr_el2
mrs x2, elr_el2
mrs x3, spsr_el2
mrs x4, far_el2
b exception_handler
.align 7
mov x0, #3
mrs x1, esr_el2
mrs x2, elr_el2
mrs x3, spsr_el2
mrs x4, far_el2
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7
b exception_handler
.align 7

Ref: AArch64 Exception and Interrupt Handling

Switch from EL2 to EL0

在 EL2 時要設定 HCR_EL2 的 RW 和 IMO 欄位:

  • RW, bit[31]

    • 0b0: Lower levels are all AArch32.
    • 0b1: The Execution state for EL1 is AArch64. The Execution state for EL0 is determined by the current value of PSTATE.nRW when executing at EL0.

    我們希望 EL1 & EL0 跑在 AArch64 所以設 1。

  • IMO, bit[4]

    • 0b0
      • When executing at Exception levels below EL2, and EL2 is enabled in the current Security state:
        • When the value of HCR_EL2.TGE is 0, Physical IRQ interrupts are not taken to EL2.
        • When the value of HCR_EL2.TGE is 1, Physical IRQ interrupts are taken to EL2 unless they are routed to EL3.
        • Virtual IRQ interrupts are disabled.

    不希望 Interrupt 被導向 EL2,所以設 0。

Reference: Arm Architecture Reference Manual for A-profile architecture

SPSR_EL1 & SPSR_EL2

Ref: SPSR_EL1, Saved Program Status Register (EL1), Page 709 of AArch64-Reference-Manual.

SPSR_EL1 的目的是發生 EL1 Exception 時,存下原本的 process state,在返回時使用 eret 復原 process state。M[3:0] 分別為:

  • 0b0000: EL0t.
  • 0b0100: EL1t.
  • 0b0101: EL1h.

t 代表使用 SP0 作為 stack pointer,h 是使用 SPx,參考 Stack Pointer selection

SPSR_EL1SPSR_EL2 同樣作用,但 SPSR_EL2M[3:0] 有更多選擇

  • 0b0000: EL0t
  • 0b0100: EL1t
  • 0b0101: EL1h
  • 0b1000: EL2t
  • 0b1001: EL2h

初始化時,依序以 EL2→EL1→EL0 順序切換:

  • EL2→EL1
    • SPSR_EL2EL1h ,使用 SP1 作為 stack pointer,EL=1
  • EL1→EL0
    • SPSR_EL1EL0t ,使用 SP0 作為 stack pointer,EL=0

CPACR_EL1

參考 kaiiiz 在 EL0 和 EL1 啟用 SIMD 和 Floating point 功能而不被攔截

CPACR_EL1.FPEN

  • 0b11: This control does not cause execution of any instructions to be trapped.