ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [컴퓨터구조] ARM - Exception Level
    공학/컴퓨터구조 2023. 2. 20. 21:39

    글의 참고

    - https://developer.arm.com/documentation/ddi0488/d/programmers-model/armv8-architecture-concepts/exception-levels

    - https://developer.arm.com/documentation/den0024/a/Fundamentals-of-ARMv8/Changing-execution-state

    - https://medium.com/@om.nara/aarch64-exception-levels-60d3a74280e6

    - https://blog.csdn.net/flyingnosky/article/details/127254602

    - Learn the architecture - AArch64 Exception Model


    글의 전제

    - 내가 글을 쓰다가 궁금한 점은 파란색 볼드체로 표현했다.

    - 밑줄로 작성된 글은 좀 더 긴 설명이 필요해서 친 것이다.


    글의 내용

    1. Overview

    " AArch64 Exception Model 에서는 ARMv8-A & ARMv9-A 관련해서 크게 2 가지 주제에 대해서 설명한다.

    1. exception model
     - different types of exceptions in the Arm architecture(arm 에서 사용하는 여러 가지 exceptions)
     - the behavior of the processor in relation to exceptions(각 exception 발생 시, processor 가 대처할 행동)
    2. privilege

     

     

     

    2. Privilege and Exception levels

    " `Learn the architecture - AArch64 Exception Model` 문서를 보면, 제일 처음 소개하는 개념이 2 가지 있다.

    1. Privilege - Privilege dictates which processor resources a software entity can see and control.
    2. Exception levels - The name for privilege in AArch64 is Exception level, often abbreviated to EL,

     

    " privilege 는 쉽게 `실행 권한` 이라고 생각하면 된다. software 가 더 강한 실행 권한을 가질 수 록, 더 많은 processour resources 에 accessible 할 수 있다는 뜻이다.

     

     

    2.1 Exception levles

    " AArch64 에서는 4 개의 exception levels 을 정의하고 있다. exception levels 은 간단하게 `실행 권한` 이라고 보면 된다. 즉, software 를 실행 권한에 따라 동작할 수 있는 등급을 나눠논 것이라 보면 된다. 실행 권한이 강한 순서대로 나열하면, `EL3 > EL2 > EL1 > EL0` 이다. 즉, 숫자가 높을 수 록, 더 강력한 실행 권한을 갖는다.

    - EL0 : EL0 은 흔히 `unprivileged execution` 이라고 불린다. 즉, 실행 권한이 거의 없는 exception level 이다. 일반적으로, 유저 스페이스에서 동작하는 응용 프로그램들은 반드시 이 레벨에서 동작해야 한다.

    - EL1 : 운영 체제는 EL1에서 동작한다. 어느 정도 권한이 있다고 보면 된다.

    - EL2 : Hypervisor가 여기에서 동작한다.

    - EL3 : `low-level firmware` 혹은 `Secure Monitor`가 여기에서 동작한다(Secure Monitor 는 `security gateway` 라고도 불린다). 

    Learn the architecture - AArch64 Exception Model

     

     

    " exception level 이 변경될 수 있는 경우는 다음 중 하나다.

    1. exception 이 발생했을 때 - exception 이 발생하면, EL 은 증가하거나 그대로 유지할 수 있다. 이 상황에서 익셉션 레벨이 감소할 수는 없다.

    2. exception 처리 후 복귀 시 - exception 처리 후 복귀 시, 익셉션 레벨은 감소하거나 그대로 유지할 수 있다. 이 상황에서 익셉션 레벨이 증가할 수는 없다.

    3. processor reset

    4. debug state 중일 때

    5. debug state 종료 시

     

    " 뒤에 3 개는 뒤에서 자세히 설명한다.

     

     

    2.1 Types of privilege

    " AArch64 Exception model 과 관련해서 2 가지 privilege types 이 존재한다.

    1. Privilege in the memory system
    2. Privilege from the point of view of accessing processor resources

     

     

    2.2.1 Memory privilege

    " ARM A-profile processor 에서는 virtual memory system 을 사용할 수 있게 설계되었다. 즉, MMU(Memory Management Unit) 는 software 가 특정 메모리 영역에 attributes 를 할당할 수 있도록 해준다. 예를 들어, attrubutes 에는 read / write permissions 등이 있으며, 이 permissions 들을 통해서 privileged / unprivileged accesses 를 구별한다. 

    - privileged access : EL1, EL2, EL3
    - unprivileged access : EL0

     

     

    2.2.2 Register access

    " arm architecture 에서 registers 를 크게 2 가지 카테고리로 분류할 수 있다.

    1. Registers that provide system control or status reporting
    2. Registers that are used in instruction processing, for example to accumulate a result, and in handling exceptions

     

    " AArch64 processors 를 설정한다는 것은 `system registers` 라고 불리는 여러 개의 registers 들을 설정한다는 말과 같다. 이 때, 특정 system registers 에 access 하기 위해서는 현재 processor exception level 이 접근하려는 system register 의 권한보다 높아야 한다.

     

    " 예를 들어, VBAR_EL1 은 `Vector Base Address Register` 라고 한다(이 레지스터의 자세한 설명은 뒤에서 다룬다). 뒤에 `_EL1` suffix 는 software 가 이 VBAR_EL1 레지스터에 access 하려면, 적어도 EL1 은 되야 한다는 뜻이다. 즉, EL2, EL3 는 당연히 access 가능하다는 뜻이 된다. 대개 ELx 접미사 붙는 레지스터는 system registers 라고 보면 된다.

     

    " 예를 들어, SCTLR 은 `System Control Register` 를 의미한다. 이 레지스터는 각 exception level 마다 존재하는 레지스터다. SCTLR_ELx 는 각 exception level 에 따른 MMU, caches, alignment 등을 설정할 수 있다(아래 보면, EL0 과 EL1 은 동일한 system configuration 을 사용한다고 볼 수 있다. 그러나, 사실 EL0 은 위에서도 보았다시피, unpriviledge access 다. 그러므로, SCTLR_EL0 은 존재하지 않으며, EL0 에서 system control 을 할 수 있다고 생각하면 안된다. system control 을 위해서는 processor exception level 이 최소 EL1 은 되어야 한다).

    1. SCTRL_EL1 - Top-level system control for EL0 and EL1
    2. SCTRL_EL2 - Top-level system control for EL2
    3. SCTRL_EL3 - Top-level system control for EL3

     

     

    " 상대적으로 더 높은 EL 은 더 낮은 EL 레지스터에 access 가 가능하다. 예를 들어, EL2 에서 SCTRL_EL1 에 access 가 가능하다. 그러나, 상대적으로 더 낮은 EL 에서 더 높은 EL 레지스터에는 access 가 불가능하다. 예를 들어, EL0 에서 SCTRL_EL1 레지스터에 access 가 불가능하다. 심지어, 이러한 시도들은 모두 fault exception 을 야기한다. AArch64 Exception mode 과 관련된 system registers 들은 다음과 같다.

     


    Learn the architecture - AArch64 Exception Model

     

     

     

    - Exception vector table

    " ARMv8에서 익셉션이 발생하면, 해당 익셉션을 처리 할 익셉션 핸들러가 호출되어야 한다. ARMv8은 익셉션이 발생했을 때, 대응하는 익셉션 핸들러를 어떻게 찾을까? ARMv8은 익셉션 벡터 테이블을 통해서 모든 익셉션들에 대한 핸들러를 저장하고 있다. 그래서 익셉션이 발생할 경우, 해당 익셉션에 대응하는 익셉션 벡터(익셉션 핸들러 주소 및 번호)를 찾아서 실행한다. 

     

    " ARMv8에서는 각 익셉션 레벨마다 익셉션 벡터 테이블이 존재한다. 즉, EL1, EL2, EL3 벡터 테이블이 존재한다는 소리다. EL0은 없나? 없다. 왜냐면, 권한이 없기 때문이다. 유저 레벨에게 익셉션을 처리할 권한을 주면 안된다. 각 익셉션 레벨 테이블의 가상 주소는 `VBAR_EL1, VBAR_EL2, VBAR_EL3(Vector Based Address Registers)`다.

     


    ARM Cortex-A Series Programmer’s Guide for ARMv8-A

     

     

     

    4.1.3 Exception-geneating instructions

    " code level 에서 `exception` 을 발생시킬 수 있는 arm instructions 이 존재한다. 그렇다면, 이러한 명령어들은 왜 필요한 것일까? 실행 권한이 낮은 software 가 실행 권한이 높은 software 에게 service 를 요청할 수 있도록 하기 위해서다. 그렇다면, 왜 실행 권한이 낮은 친구들은 실행 권한이 높은 친구들에게 service 를 요청할까? 자기들이 service 를 직접 실행할 수는 없을까? 실행 권한이, 즉, EL 이 더 높을 수 록, 더 많은 hardware resources 에 access 할 수 있기 때문이다. 예를 들어, user application(EL0) 은 hardwae services 를 받기 위해서 svc 명령어를 통해 OS(EL1) 에 services 를 요청할 수 있다.

     

    " arm architecture 는 위와 같은 사용 시나리오에 따라 각 EL 에 진입할 수 있는 명령어를 제공한다.

    1. svc -  The Supervisor Call (SVC) instruction enables a user program at EL0 to request an OS service at EL1

    2. hvc - The Hypervisor Call (HVC) instruction, available if the Virtualization Extensions are implemented, enables the OS to request hypervisor services at EL2

    3. smc - The Secure Monitor Call (SMC) instruction, available if the Security Extensions are implemented, enables the Normal world to request Secure world services from firmware at EL3

     

     

    " 예를 들어, PE 가 EL0 에서 동작중이면(즉, processor 가 user application 을 실행중일때), 직접적으로 EL2 에 있는 hypervisor 혹은 EL3 에 있는 Secure Monitor 를 호출할 수 없다. 왜냐면, EL2 나 EL3 는 EL1 혹은 EL1 보다 더 높은 EL 에서만 access 할 수 있기 때문이다. 그렇다면, user application 은 어떻게 해야 EL2 및 EL3 에서 제공하는 services 를 받을 수 있을까? EL0 에서 동작하는 user application 은 먼저 `svc` 명령어를 통해 kernel 을 호출한다. 그리고, kernel 이 더 높은 EL2 및 EL3 를 호출하는 방식으로 services 를 제공받게 된다. 아래 block diagram 은 각 exception instructions 에 따라 어떤 EL 로 진입할 수 있는지를 나타낸다.

     


    Learn the architecture - AArch64 Exception Model

     

    " 여기서 주의할 점이 있다. 사실, hypervisor 는 EL1 에 emulated system 을 제공한다. 즉, 물리적인 하드웨어 레벨의 시스템과 동일한 환경의 virtual machine 을 EL1 에게 제공한다는 뜻이다. 이러한 상황에서 guest OS 는 smc 명령어를 사용해서 EL3 에 있는 device firmware 를 직접적으로 호출할 수 가 없다. 대신, smc 명령어가 EL2 에서 traped 되서(hypervisor 에게 smc 명령어가 가로채진다), virtual machine 에서 제공하는 device firmware service 를 받게된다. 그렇다면, hypervisor 의 trap 은 하드웨어 레벨에서 자동으로 이루어질까? 그렇지 않다. `Hypervisor Configuratio Register` 에서 HCR_EL2.TSC 비트를 설정함으로써, hypervisor 가 smc 명령어를 trap 할 수 있게 된다.  

     

     

    - ARMv8 실행 상태의 변경

    " AArch64 실행 상태와 AArch32 실행 상태가 바뀌는 것을 `interprocessing`이라고 한다. `interprocessing` 용어는 중요하지 않다. 중요한 건 실행 상태가 변경되는 조건이다. 

     

    " 실행 상태의 변경은 오직 익셉션 레벨이 발생했을 때만 일어난다. 그런데, 우리는 위에서 익셉션 레벨이 발생하는 경우가 2가지 밖에 없다는 것을 공부했다. 즉, `실행 상태의 변경 조건 == 익셉션 레벨이 발생 조건`이 된다. 그 조건들은 아래와 같다. 그런데 중요한 내용

     

    " 그런데 또 주의 사항이 하나 더 있다. 예외가 발생하거나, 예외가 발생해서 복귀할 때 익셉션 레벨을 변경하지 않아도 된다고 했다. 익셉션 레벨을 변경하지 않았다? 당연히 실행 상태 또한 변경하지 못한다.

    1) 예외가 발생했을 때, 익셉션 레벨을 바꾸는 경우.
    2) 예외 처리 후 복귀 시, 익셉션 레벨을 바꾸는 경우.

     

     

    - 예외가 발생했을 때, 익셉션 레벨이 바뀌면 실행 상태는 2가지 경우의 수가 있다.

    1) 실행 상태를 바꾸지 않고 그대로 둔다.
    2) 실행 상태를  AArch32에서 AArch64로 변경한다.

     

    - 위에서 했던 내용을 떠올려 보면 익셉션 레벨도 예외가 발생했을 때는 그대로 이거나 증가한다는 것을 떠올려 보자.

     

     

    - 예외 처리 후 복귀 시, 익셉션 레벨이 바뀌면 실행 상태는 2가지 경우의 수가 있다.

    1) 실행 상태를 바꾸지 않고 그대로 둔다.
    2) 실행 상태를  AArch64에서 AArch32로 변경한다.

     

    - 위에서 했던 내용을 떠올려 보면 익셉션 레벨도 예외 처리 후 복귀 시, 그대로 이거나 감소한다는 것을 떠올려 보자.

     

     

    - 정리하면 다음과 같다.

    1) 실행 상태(AArch64) -> 예외 발생 -> 실행 상태 유지(AArch64) -> 예외 복귀 -> 실행 상태 유지(AArch64)
    2) 실행 상태(AArch32) -> 예외 발생 -> 실행 상태 유지(AArch32) -> 예외 복귀 -> 실행 상태 유지(AArch32)
    3) 실행 상태(AArch32) -> 예외 발생 -> 실행 상태 변경(AArch64) -> 예외 복귀 -> 실행 상태 유지(AArch64)

     

     

    - 익셉션 레벨이 바뀌지 않으면서 실행 상태만 변경을 어떻게 할까? 예제를 통해 알아 보자. 64-bit OS(Operating System)에 64-bit APP과 32-bit APP(Application)이 있다고 치자. 자 이제 AArch64 실행 상태를 AArch64로 바꾸는 절차는 아래와 같다.

    1) 32-bit APP이 `svc` 명령어를 실행한다.
    2) 시스템 콜 때문에 `예외가 발생`한다.
    3) OS가 해당 시스템 콜을 처리해야 하므로, 프로세서의 익셉션 레벨이 EL0 -> EL1으로 증가하고, 실행 상태 또한 OS에 맞춰서 64-bit로 변경된다.
    4) 그런 다음 OS가 시스템 콜을 모두 처리하고, 익셉션 레벨을 EL1에서 EL0으로 내린다. 근데, 실행 상태는 그대로 AArch64로 남겨둔다.

     

     

    - ARMv8 용어 정리

    - 익셉션 레벨 관련 용어

    3) 익센셥 레벨, 즉, ELn 에서 n의 값이 다른 익셉션 레벨보다 더 크다면 해당 익셉션 레벨을 `higher Exception level`이라고 명명한다.  예를 들어, EL3는 EL1 보다 higher Exception level이다.
     
    2) 익센셥 레벨, 즉, ELn 에서 n의 값이 다른 익셉션 레벨보다 더 작다면 해당 익셉션 레벨을 `lower Exception level`이라고 명명한다.  예를 들어, EL0는 EL1 보다 lower Exception level이다.

    3) AArch64 실행 상태에서 동작하는 익셉션 레벨을 `Using AArch64` 라고 명명한다.

    4) AArch32 실행 상태에서 동작하는 익셉션 레벨을 `Using AArch32` 라고 명명한다.

     

    - Interrupt handling ?

    : ARMv8에서는 2가지 `인터럽트 시그널`을 사용한다.

    1. IRQ : ARMv8 전까지는 `standard interrupt priority` 를 의미했다.
    2. FIQ : ARMv8 전까지는 `high interrupt priority` 를 의미했다.

     

    : 위의 2개의 핀은 CPU 코어의 입력 핀과 연관이 있다. 즉, IRQ와 FIQ는 실제 하드웨어와 관련이 있는 인터럽트다. 외부 디바이스가 `interrupt request line`을 트리거하면, 그에 대응하는 `exception type`이 발생한다. 즉, `IRQ`와 `FIQ`는 `exception type` 중에 하나가 된다. 그리고 IRQ와 FIQ는 소프트웨어적인 부분보다는 하드웨어와 관련이 있기 때문에, `asynchronous exception` 으로 분류된다.

     

     

    : 아래 그림은 ARMv8에서 C 코드를 통해서 `인터럽트 핸들링` 하는 모습을 보여준다. C 함수를 호출하는 이유는 드라이버 개발자에게 유연함을 제공하기 위해서다. 만약, 모든 인터럽트 처리 루틴이 어셈블리 코드로만 작성해야 한다면, 드라이버 개발자들은 모든 CPU 아키텍처 구조에 대해 어느정도 알고 있어야 한다. 이런 아키텍처 종속적인 부분을 해소하기 위해 C 코드로 작성하는 것이다.

    1. ASM IRQ Handler : 익셉션이 발생했을 때, CPU가 자동으로 처리해주는 작업은 아래와 같다.
     - PC->ELF_EL1
     - PSTATE->SPSR_EL1

    2. C Sub-routine : `ASM IRQ Handler`에서 실제 익셉션 핸들링 처리를 위해 `C 함수`를 호출하면, 자동으로 아래의 루틴이 실행된다.
     - PC->LR

     


    ARM Cortex-A Series Programmer’s Guide for ARMv8-A

     

    : 위에서 `corruptible registers`는 `r0 ~ r15` 레지스터를 의미한다.

Designed by Tistory.