이번에는 HCR_EL2 레지스터를 읽는 예시 코드를 소개합니다. 다음은 XEN 하이퍼바이저에서 호출되는 _show_registers 함수의 어셈블리 명령어입니다.
01 0x25c550 <_show_registers.isra.14>:
02 0x25c550: stp x19, x20, [sp, #-96]!
03 0x25c554: and w20, w2, #0xff
...
04 0x25c62c: mrs x1, hcr_el2
05 0x25c630: adrp x0, 284000 <symbols_token_index+0x9700>
06 0x25c634: add x0, x0, #0x908
07 0x25c638: bl 0x23bee0 <printk>
먼저 04번째 줄에 있는 'mrs x1, hcr_el2' 명령어를 분석하겠습니다. 이것은 HCR_EL2 레지스터의 값을 x1 레지스터에 로딩하는 동작입니다. 07번째 줄은 printk 함수를 호출해 HCR_EL2 레지스터의 값을 저장한 x1 레지스터를 출력합니다.
이번에는 HCR_EL2 레지스터를 설정하는 예제 코드를 소개합니다. 다음은 XEN 하이퍼바이저가 부팅할 때 호출되는 init_traps 함수의 어셈블리 명령어입니다.
01 0x25c8a0 <init_traps>:
02 0x25c8a0: adrp x0, 0x26a000 <guest_irq_compat+0x70>
03 0x25c8a4: add x0, x0, #0x800
04 0x25c8a8: msr vbar_el2, x0
...
05 0x25c8c8: mov x0, #0x38 // #56
06 0x25c8cc: msr hcr_el2, x0
07 0x25c8d0: isb
08 0x25c8d4: ret
먼저 05번째 줄을 보겠습니다. 0x38이란 값을 x0 레지스터에 이동하는 동작입니다. 06번째 줄은 x0 레지스터의 값을 hcr_el2 레지스터에 설정하는 명령어입니다.
---
[중요] HCR_EL2 레지스터에 설정하는 0x38의 정체는?
위 코드에서 0x38은 무엇을 의미할까요? 0x38을 2진수인 0b111000으로 표기할 수 있는데, 이는 HCR_EL2 레지스터를 구성하는 비트 필드에 대응됩니다.
HCR_EL2의 3번째 비트는 FMO, 4번째 비트는 IMO, 그리고 5번째 비트는 AMO인데, 이를 이진수로 0b111000으로 표기할 수 있습니다. 해당 비트 필드를 1로 설정하면 비트 필드의 기능을 활성화하게 됩니다. 이 방식으로 HCR_EL2 레지스터를 설정합니다.
참고로 HCR_EL2.IMO와 HCR_EL2.FMO는 IRQ와 FIQ를 가상 인터럽트로 설정하는 비트 필드입니다. HCR_EL2.IMO와 HCR_EL2.FMO 비트 필드인데 1로 설정되면 EL2나 EL1에서 IRQ나 FIQ가 유발되면 EL2에 존재하는 익셉션 핸들러(VBAR_EL2)가 받아 처리합니다. 또한 HCR_EL2.AMO는 EL1 혹은 EL2에서 SError가 유발되면 EL2에서 받아 처리할 수 있는 기능을 제공합니다.
정리하면 HCR_EL2 레지스터에 존재하는 IMO, FMO, AMO 비트 필드는 EL1에서 인터럽트나 SError가 유발되면 EL2에 라우팅되도록 설정하는 기능을 제공합니다.
이번에는 앞에서 소개한 어셈블리 명령어에 대응하는 C 코드를 보겠습니다.
출처: https://github.com/xen-project/xen/blob/stable-4.15/xen/arch/arm/traps.c
01 void init_traps(void)
02 {
...
03 /*
04 * Configure HCR_EL2 with the bare minimum to run Xen until a guest
05 * is scheduled. {A,I,F}MO bits are set to allow EL2 receiving
06 * interrupts.
07 */
08 WRITE_SYSREG(HCR_AMO | HCR_FMO | HCR_IMO, HCR_EL2);
09 isb();
10 }
08번째 줄을 봅시다. WRITE_SYSREG 매크로 함수를 사용해 HCR_AMO, HCR_FMO, HCR_IMO를 비트 OR 연산한 결과를 HCR_EL2 레지스터에 쓰는 동작입니다.
HCR_EL2 시스템 레지스터 이외의 다른 시스템 레지스터도 이와 유사한 방식으로 설정합니다.
---
< '시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리' 저자>
