[ATF]-ARM级别/异常/状态切回时候的寄存器保存与恢复
文章目錄
- 1、save/restore函數(shù)的定義
- (1)、el1_sysregs_context_save //保存系統(tǒng)寄存器
- (2)、el1_sysregs_context_restore //恢復(fù)系統(tǒng)寄存器
- (3)、restore_gp_registers_eret //保存通用寄存器
- (4)、save_gp_registers //恢復(fù)通用寄存器
- (5)、fpregs_context_save //保存浮點(diǎn)型寄存器
- (6)、fpregs_context_restore //恢復(fù)浮點(diǎn)型寄存器
- 2、sava/restore函數(shù)的應(yīng)用場(chǎng)景
- (1)、sync_exception_aarch64 //同步異常,調(diào)用smc指令后將進(jìn)入這里
- (2)、irq_aarch64 //atf中的同步異常
★★★ 友情鏈接 : 個(gè)人博客導(dǎo)讀首頁(yè)—點(diǎn)擊此處 ★★★
1、save/restore函數(shù)的定義
(1)、el1_sysregs_context_save //保存系統(tǒng)寄存器
/* -----------------------------------------------------* The following function strictly follows the AArch64* PCS to use x9-x17 (temporary caller-saved registers)* to save EL1 system register context. It assumes that* 'x0' is pointing to a 'el1_sys_regs' structure where* the register context will be saved.* -----------------------------------------------------*/ func el1_sysregs_context_savemrs x9, spsr_el1mrs x10, elr_el1stp x9, x10, [x0, #CTX_SPSR_EL1]mrs x11, spsr_abtmrs x12, spsr_undstp x11, x12, [x0, #CTX_SPSR_ABT]mrs x13, spsr_irqmrs x14, spsr_fiqstp x13, x14, [x0, #CTX_SPSR_IRQ]mrs x15, sctlr_el1mrs x16, actlr_el1stp x15, x16, [x0, #CTX_SCTLR_EL1]mrs x17, cpacr_el1mrs x9, csselr_el1stp x17, x9, [x0, #CTX_CPACR_EL1]mrs x10, sp_el1mrs x11, esr_el1stp x10, x11, [x0, #CTX_SP_EL1]mrs x12, ttbr0_el1mrs x13, ttbr1_el1stp x12, x13, [x0, #CTX_TTBR0_EL1]mrs x14, mair_el1mrs x15, amair_el1stp x14, x15, [x0, #CTX_MAIR_EL1]mrs x16, tcr_el1mrs x17, tpidr_el1stp x16, x17, [x0, #CTX_TCR_EL1]mrs x9, tpidr_el0mrs x10, tpidrro_el0stp x9, x10, [x0, #CTX_TPIDR_EL0] #if !STPUmrs x11, dacr32_el2mrs x12, ifsr32_el2stp x11, x12, [x0, #CTX_DACR32_EL2] #endifmrs x13, par_el1mrs x14, far_el1stp x13, x14, [x0, #CTX_PAR_EL1]mrs x15, afsr0_el1mrs x16, afsr1_el1stp x15, x16, [x0, #CTX_AFSR0_EL1]mrs x17, contextidr_el1mrs x9, vbar_el1stp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]/* Save NS timer registers if the build has instructed so */ #if NS_TIMER_SWITCHmrs x10, cntp_ctl_el0mrs x11, cntp_cval_el0stp x10, x11, [x0, #CTX_CNTP_CTL_EL0]mrs x12, cntv_ctl_el0mrs x13, cntv_cval_el0stp x12, x13, [x0, #CTX_CNTV_CTL_EL0]mrs x14, cntkctl_el1str x14, [x0, #CTX_CNTKCTL_EL1] #endif#if !STPUmrs x15, fpexc32_el2str x15, [x0, #CTX_FP_FPEXC32_EL2] #endifret endfunc el1_sysregs_context_save(2)、el1_sysregs_context_restore //恢復(fù)系統(tǒng)寄存器
/* -----------------------------------------------------* The following function strictly follows the AArch64* PCS to use x9-x17 (temporary caller-saved registers)* to restore EL1 system register context. It assumes* that 'x0' is pointing to a 'el1_sys_regs' structure* from where the register context will be restored* -----------------------------------------------------*/ func el1_sysregs_context_restoreldp x9, x10, [x0, #CTX_SPSR_EL1]msr spsr_el1, x9msr elr_el1, x10ldp x11, x12, [x0, #CTX_SPSR_ABT]msr spsr_abt, x11msr spsr_und, x12ldp x13, x14, [x0, #CTX_SPSR_IRQ]msr spsr_irq, x13msr spsr_fiq, x14ldp x15, x16, [x0, #CTX_SCTLR_EL1]msr sctlr_el1, x15msr actlr_el1, x16ldp x17, x9, [x0, #CTX_CPACR_EL1]msr cpacr_el1, x17msr csselr_el1, x9ldp x10, x11, [x0, #CTX_SP_EL1]msr sp_el1, x10msr esr_el1, x11ldp x12, x13, [x0, #CTX_TTBR0_EL1]msr ttbr0_el1, x12msr ttbr1_el1, x13ldp x14, x15, [x0, #CTX_MAIR_EL1]msr mair_el1, x14msr amair_el1, x15ldp x16, x17, [x0, #CTX_TCR_EL1]msr tcr_el1, x16msr tpidr_el1, x17ldp x9, x10, [x0, #CTX_TPIDR_EL0]msr tpidr_el0, x9msr tpidrro_el0, x10#if !STPUldp x11, x12, [x0, #CTX_DACR32_EL2]msr dacr32_el2, x11msr ifsr32_el2, x12 #endifldp x13, x14, [x0, #CTX_PAR_EL1]msr par_el1, x13msr far_el1, x14ldp x15, x16, [x0, #CTX_AFSR0_EL1]msr afsr0_el1, x15msr afsr1_el1, x16ldp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]msr contextidr_el1, x17msr vbar_el1, x9/* Restore NS timer registers if the build has instructed so */ #if NS_TIMER_SWITCHldp x10, x11, [x0, #CTX_CNTP_CTL_EL0]msr cntp_ctl_el0, x10msr cntp_cval_el0, x11ldp x12, x13, [x0, #CTX_CNTV_CTL_EL0]msr cntv_ctl_el0, x12msr cntv_cval_el0, x13ldr x14, [x0, #CTX_CNTKCTL_EL1]msr cntkctl_el1, x14 #endif/* No explict ISB required here as ERET covers it */ret endfunc el1_sysregs_context_restore(3)、restore_gp_registers_eret //保存通用寄存器
func restore_gp_registers_eretldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]b restore_gp_registers_callee_eret endfunc restore_gp_registers_eretfunc restore_gp_registers_callee_eretldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]ldp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]ldp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]ldp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]ldp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]ldp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]ldp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]ldp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]ldp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]ldp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]ldp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]ldp x30, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]msr sp_el0, x17ldp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]eret endfunc restore_gp_registers_callee_eret(4)、save_gp_registers //恢復(fù)通用寄存器
/* -----------------------------------------------------* The following functions are used to save and restore* all the general purpose registers. Ideally we would* only save and restore the callee saved registers when* a world switch occurs but that type of implementation* is more complex. So currently we will always save and* restore these registers on entry and exit of EL3.* These are not macros to ensure their invocation fits* within the 32 instructions per exception vector.* clobbers: x18* -----------------------------------------------------*/ func save_gp_registersstp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]stp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]stp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]stp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]stp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]stp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]stp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]stp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]stp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]stp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]stp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]mrs x18, sp_el0str x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]ret endfunc save_gp_registers(5)、fpregs_context_save //保存浮點(diǎn)型寄存器
注意:搜索整個(gè)ATF代碼,fpregs_context_save/fpregs_context_restore 并沒(méi)有使用到
/* -----------------------------------------------------* The following function follows the aapcs_64 strictly* to use x9-x17 (temporary caller-saved registers* according to AArch64 PCS) to save floating point* register context. It assumes that 'x0' is pointing to* a 'fp_regs' structure where the register context will* be saved.** Access to VFP registers will trap if CPTR_EL3.TFP is* set. However currently we don't use VFP registers* nor set traps in Trusted Firmware, and assume it's* cleared** TODO: Revisit when VFP is used in secure world* -----------------------------------------------------*/ #if CTX_INCLUDE_FPREGS func fpregs_context_savestp q0, q1, [x0, #CTX_FP_Q0]stp q2, q3, [x0, #CTX_FP_Q2]stp q4, q5, [x0, #CTX_FP_Q4]stp q6, q7, [x0, #CTX_FP_Q6]stp q8, q9, [x0, #CTX_FP_Q8]stp q10, q11, [x0, #CTX_FP_Q10]stp q12, q13, [x0, #CTX_FP_Q12]stp q14, q15, [x0, #CTX_FP_Q14]stp q16, q17, [x0, #CTX_FP_Q16]stp q18, q19, [x0, #CTX_FP_Q18]stp q20, q21, [x0, #CTX_FP_Q20]stp q22, q23, [x0, #CTX_FP_Q22]stp q24, q25, [x0, #CTX_FP_Q24]stp q26, q27, [x0, #CTX_FP_Q26]stp q28, q29, [x0, #CTX_FP_Q28]stp q30, q31, [x0, #CTX_FP_Q30]mrs x9, fpsrstr x9, [x0, #CTX_FP_FPSR]mrs x10, fpcrstr x10, [x0, #CTX_FP_FPCR]ret endfunc fpregs_context_save(6)、fpregs_context_restore //恢復(fù)浮點(diǎn)型寄存器
注意:搜索整個(gè)ATF代碼,fpregs_context_save/fpregs_context_restore 并沒(méi)有使用到
/* -----------------------------------------------------* The following function follows the aapcs_64 strictly* to use x9-x17 (temporary caller-saved registers* according to AArch64 PCS) to restore floating point* register context. It assumes that 'x0' is pointing to* a 'fp_regs' structure from where the register context* will be restored.** Access to VFP registers will trap if CPTR_EL3.TFP is* set. However currently we don't use VFP registers* nor set traps in Trusted Firmware, and assume it's* cleared** TODO: Revisit when VFP is used in secure world* -----------------------------------------------------*/ func fpregs_context_restoreldp q0, q1, [x0, #CTX_FP_Q0]ldp q2, q3, [x0, #CTX_FP_Q2]ldp q4, q5, [x0, #CTX_FP_Q4]ldp q6, q7, [x0, #CTX_FP_Q6]ldp q8, q9, [x0, #CTX_FP_Q8]ldp q10, q11, [x0, #CTX_FP_Q10]ldp q12, q13, [x0, #CTX_FP_Q12]ldp q14, q15, [x0, #CTX_FP_Q14]ldp q16, q17, [x0, #CTX_FP_Q16]ldp q18, q19, [x0, #CTX_FP_Q18]ldp q20, q21, [x0, #CTX_FP_Q20]ldp q22, q23, [x0, #CTX_FP_Q22]ldp q24, q25, [x0, #CTX_FP_Q24]ldp q26, q27, [x0, #CTX_FP_Q26]ldp q28, q29, [x0, #CTX_FP_Q28]ldp q30, q31, [x0, #CTX_FP_Q30]ldr x9, [x0, #CTX_FP_FPSR]msr fpsr, x9ldr x10, [x0, #CTX_FP_FPCR]msr fpcr, x10/** No explict ISB required here as ERET to* switch to secure EL1 or non-secure world* covers it*/ret endfunc fpregs_context_restore #endif /* CTX_INCLUDE_FPREGS */2、sava/restore函數(shù)的應(yīng)用場(chǎng)景
(1)、sync_exception_aarch64 //同步異常,調(diào)用smc指令后將進(jìn)入這里
sync_exception_aarch64—>handle_sync_exception—>smc_handler64—>opteed_smc_handler
a . 先(僅僅)保存了x4-x7, x18, sp_el0
stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]/* Save rest of the gpregs and sp_el0*/ save_x18_to_x29_sp_el0b. 保存一個(gè)os的系統(tǒng)寄存器,恢復(fù)另外一個(gè)os的系統(tǒng)寄存器
在opteed_smc_handler中:
如果是ATF----->TEE:
cm_el1_sysregs_context_save(NON_SECURE); cm_el1_sysregs_context_restore(SECURE);如果是ATF----->REE:
cm_el1_sysregs_context_save(SECURE); cm_el1_sysregs_context_restore(NON_SECURE);c. 恢復(fù)通用寄存器
在opteed_smc_handler處理完畢后,再回到smc_handler64,調(diào)用el3_exit
在el3_exit中,先恢復(fù)gp寄存器,再eret恢復(fù)pc/pstate,返回到執(zhí)行smc觸發(fā)同步異常的地方
restore_gp_registers_eret(2)、irq_aarch64 //atf中的同步異常
irq_aarch64 —>handle_interrupt_exception----->中斷函數(shù)處理—>el3_exit
先調(diào)用save_gp_registers保存通用寄存器,然后進(jìn)行中斷函數(shù)處理
再在el3_exit中調(diào)用restore_gp_registers_eret恢復(fù)通用寄存器
總結(jié)
以上是生活随笔為你收集整理的[ATF]-ARM级别/异常/状态切回时候的寄存器保存与恢复的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux和optee双系统中1020-
- 下一篇: android指纹fingerprint