1. ARM Trusted Firmware-A

 

https://github.com/ARM-software/arm-trusted-firmware

 

ARM-software/arm-trusted-firmware

Read-only mirror of Trusted Firmware-A. Contribute to ARM-software/arm-trusted-firmware development by creating an account on GitHub.

github.com

Secure Monitor(EL3) 역할을 수행하며 ARM Trusted Firmware-A(BL31)를 통해 BL32 OPTEE OS를 구동함. 

아래의 세부 기능을 포함.

 

각 기능들은 SMC Calling Convention에 의거하여 구동되며, OPTEE로의 SMC 전달은 Runtime Services Framework - Secure-EL1 Payload Dispatcher(SPD) service를 통해 처리. (Standard service calls - ex) PSCI, Secure-EL1 Payload Dispatcher service, CPU implementation service등)

 

ARM Trusted Firmware Design에 대한 문서는 원문 참고.

원문 : https://chromium.googlesource.com/chromiumos/third_party/arm-trusted-firmware/+/factory-strago-7458.B/docs/firmware-design.md

 

ARM Trusted Firmware Design

ARM Trusted Firmware Design Contents : IntroductionCold bootEL3 runtime services frameworkPower State Coordination InterfaceSecure-EL1 Payloads and DispatchersCrash Reporting in BL3-1Guidelines for Reset HandlersCPU specific operations frameworkMemory layo

chromium.googlesource.com

부팅은 5단계에 의해 진행 - AArch64 case.

  • Boot Loader stage 1 (BL1) AP Trusted ROM
  • Boot Loader stage 2 (BL2) Trusted Boot Firmware
  • Boot Loader stage 3-1 (BL3-1) EL3 Runtime Firmware
  • Boot Loader stage 3-2 (BL3-2) Secure-EL1 Payload (optional)
  • Boot Loader stage 3-3 (BL3-3) Non-trusted Firmware

 

2. SMC Calling Convention

 

ARM에서는 SMC Call / HVC Call에 대한 규약을 미리 정해두었음. 

 

원문 : http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf

불러오는 중입니다...

여기에 따라 Function identifier 값, Argument Passing 방법을 수행.

 

SMC는 2가지 종류로 구분 - Fast SMC, Standard SMC or yield SMC /

Atomic operation을 제공하느냐 여부로 구분되는데, 이는 결국 Interrupt masking을 통해 결정.

 

 

'OPTEE with Rasberry Pi 3B' 카테고리의 다른 글

SMC Call Sequence  (0) 2019.09.30
OPTEE Log Level  (0) 2019.09.18
NFS boot  (0) 2019.09.17
Rasberry Pi 3B vs 3B+  (0) 2019.09.04
OP-TEE Build for Rasberry Pi 3B  (0) 2019.09.03

1. SMC call in normal world.

 

SMC와 HVC(Hypervisor call) 가 정의되고 Export 됨.

 

1) smc, hvc call function 정의

 

2) export function

 

3) Wrapping function

 

4) 3번의 함수들을 OPTEE에서 함수로 제공

 

 

2. SMC Call in secure world - OPTEE

 

1) Init 과정에서 SMC Handler를 등록.

(중략)

미리 선언한 핸들러를 각 Thread에 mapping 시킴.

 

 

 

2) Vector table 에 등록되어있으므로, SMC 발생시 해당 함수가 실행.

 

초기화 과정에서 thread_std_smc_handler_ptr이 tee_entry_std이므로 아래 함수가 실행.

 

 

'OPTEE with Rasberry Pi 3B' 카테고리의 다른 글

ARM Trusted Firmware-A  (0) 2019.10.10
OPTEE Log Level  (0) 2019.09.18
NFS boot  (0) 2019.09.17
Rasberry Pi 3B vs 3B+  (0) 2019.09.04
OP-TEE Build for Rasberry Pi 3B  (0) 2019.09.03

1. arch/arm64/kernel/entry.s

ARM 64bit Exception Handler는 Exception level마다 분기를 하게 되어 있으며, Vector table에 의거 해서 Jump 수행

 

.macro kernel_ventry, el, label, regsize = 64
.align 7
.....
b el\()\el\()_\label
.endm

 

Vector table은 같은 파일 내에 선언.

 

.align 11
ENTRY(vectors)
    kernel_ventry 1, sync_invalid // Synchronous EL1t
    kernel_ventry 1, irq_invalid // IRQ EL1t
    kernel_ventry 1, fiq_invalid // FIQ EL1t
    kernel_ventry 1, error_invalid // Error EL1t

    kernel_ventry 1, sync // Synchronous EL1h
    kernel_ventry 1, irq // IRQ EL1h
    kernel_ventry 1, fiq_invalid // FIQ EL1h
    kernel_ventry 1, error_invalid // Error EL1h

    kernel_ventry 0, sync // Synchronous 64-bit EL0
    kernel_ventry 0, irq // IRQ 64-bit EL0
    kernel_ventry 0, fiq_invalid // FIQ 64-bit EL0
    kernel_ventry 0, error_invalid // Error 64-bit EL0

#ifdef CONFIG_COMPAT
    kernel_ventry 0, sync_compat, 32 // Synchronous 32-bit EL0
    kernel_ventry 0, irq_compat, 32 // IRQ 32-bit EL0
    kernel_ventry 0, fiq_invalid_compat, 32 // FIQ 32-bit EL0
    kernel_ventry 0, error_invalid_compat, 32 // Error 32-bit EL0
#else
    kernel_ventry 0, sync_invalid, 32 // Synchronous 32-bit EL0
    kernel_ventry 0, irq_invalid, 32 // IRQ 32-bit EL0
    kernel_ventry 0, fiq_invalid, 32 // FIQ 32-bit EL0
    kernel_ventry 0, error_invalid, 32 // Error 32-bit EL0
#endif
END(vectors)

 

ELn Handler 역시 같은 파일 내 선언

 

/* * EL1 mode handlers. */
    .align 6
el1_sync:
    kernel_entry 1
    mrs x1, esr_el1 // read the syndrome register
    lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class
    cmp x24, #ESR_ELx_EC_DABT_CUR // data abort in EL1
    b.eq el1_da
    cmp x24, #ESR_ELx_EC_IABT_CUR // instruction abort in EL1
    b.eq el1_ia
    cmp x24, #ESR_ELx_EC_SYS64 // configurable trap
    b.eq el1_undef
    cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception
    b.eq el1_sp_pc
    cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception
    b.eq el1_sp_pc
    cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL1
    b.eq el1_undef
    cmp x24, #ESR_ELx_EC_BREAKPT_CUR // debug exception in EL1
    b.ge el1_dbg
    b el1_inv

...

el1_da:
    /*
     * Data abort handling
     */
    mrs x3, far_el1
    enable_dbg // re-enable interrupts if they were enabled in the aborted context
    tbnz x23, #7, 1f // PSR_I_BIT
    enable_irq
1:
    clear_address_tag x0, x3
    mov x2, sp // struct pt_regs
    bl do_mem_abort

    // disable interrupts before pulling preserved data off the stack
    disable_irq
    kernel_exit 1

...

/* * EL0 mode handlers. */
    .align 6
el0_sync:
    kernel_entry 0
    mrs x25, esr_el1 // read the syndrome register
    lsr x24, x25, #ESR_ELx_EC_SHIFT // exception class
    cmp x24, #ESR_ELx_EC_SVC64 // SVC in 64-bit state
    b.eq el0_svc
    cmp x24, #ESR_ELx_EC_DABT_LOW // data abort in EL0
    b.eq el0_da
    cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0
    b.eq el0_ia
    cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access
    b.eq el0_fpsimd_acc
    cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception
    b.eq el0_fpsimd_exc
    cmp x24, #ESR_ELx_EC_SYS64 // configurable trap
    b.eq el0_sys
    cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception
    b.eq el0_sp_pc
    cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception
    b.eq el0_sp_pc
    cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL0
    b.eq el0_undef
    cmp x24, #ESR_ELx_EC_BREAKPT_LOW // debug exception in EL0
    b.ge el0_dbg
    b el0_inv

....

el0_da:
    /*
     * Data abort handling
     */
    mrs x26, far_el1
    // enable interrupts before calling the main handler
    enable_dbg_and_irq
    ct_user_exit clear_address_tag x0, x26
    mov x1, x25
    mov x2, sp
    bl do_mem_abort
    b ret_to_user

모든 레벨에서 Data abort 발생시 do_mem_abort를 수행.

 

 

2. arch/arm64/mm/fault.c

 

fault_info structure에 선언되어 있는 엔트리를 얻어와  function을 수행.

/*
 * Dispatch a data abort to the relevant handler.
 */
asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
                             struct pt_regs *regs)
{
    const struct fault_info *inf = esr_to_fault_info(esr);
    struct siginfo info;

    if (!inf->fn(addr, esr, regs))
        return;

    pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr);

    mem_abort_decode(esr);

    info.si_signo = inf->sig;
    info.si_errno = 0;
    info.si_code = inf->code;
    info.si_addr = (void __user *)addr;
    arm64_notify_die("", regs, &info, esr);
}

 

같은 파일 내에 해당 구조체 선언되어 있으며, do_bad, do_translation_fault, do_page_fault, do_alignment_fault 함수가 실행.

 

static const struct fault_info fault_info[] = {
    { do_bad, SIGBUS, 0, "ttbr address size fault" },
    { do_bad, SIGBUS, 0, "level 1 address size fault" },
    { do_bad, SIGBUS, 0, "level 2 address size fault" },
    { do_bad, SIGBUS, 0, "level 3 address size fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 0 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
    { do_bad, SIGBUS, 0, "unknown 8" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
    { do_bad, SIGBUS, 0, "unknown 12" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
    { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
    { do_sea, SIGBUS, 0, "synchronous external abort" },
    ..................
}

 

+ Recent posts