日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

optee3.14中的异常向量表解读--中断处理解读

發(fā)布時(shí)間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 optee3.14中的异常向量表解读--中断处理解读 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

optee3.14中的異常向量表、VBAR_EL1、中斷實(shí)現(xiàn)的介紹

★★★ 個(gè)人博客導(dǎo)讀首頁(yè)—點(diǎn)擊此處 ★★★
.
說(shuō)明:
在默認(rèn)情況下,本文講述的都是ARMV8-aarch64架構(gòu),optee3.14版本, 未開(kāi)啟FF-A

文章目錄

        • 1、armv8-aarch64的異常向量表介紹
        • 2、armv8的VBAR_ELx寄存器
        • 3、optee異常向量表的實(shí)現(xiàn)
        • 4、optee異常向量表基地址的定義
        • 5、elx_irq和elx_fiq

1、armv8-aarch64的異常向量表介紹


我們可以看出,實(shí)際上有四組表,每組表有四個(gè)異常入口,分別對(duì)應(yīng)同步異常,IRQ,FIQ和serror。

  • 如果發(fā)生異常后并沒(méi)有exception level切換,并且發(fā)生異常之前使用的棧指針是SP_EL0,那么使用第一組異常向量表。
  • 如果發(fā)生異常后并沒(méi)有exception level切換,并且發(fā)生異常之前使用的棧指針是SP_EL1/2/3,那么使用第二組異常向量表。
  • 如果發(fā)生異常導(dǎo)致了exception level切換,并且發(fā)生異常之前的exception
    level運(yùn)行在AARCH64模式,那么使用第三組異常向量表。
  • 如果發(fā)生異常導(dǎo)致了exception level切換,并且發(fā)生異常之前的exception
    level運(yùn)行在AARCH32模式,那么使用第四組異常向量表。

另外我們還可以看到的一點(diǎn)是,每一個(gè)異常入口不再僅僅占用4bytes的空間,而是占用0x80 bytes空間,也就是說(shuō),每一個(gè)異常入口可以放置多條指令,而不僅僅是一條跳轉(zhuǎn)指令

2、armv8的VBAR_ELx寄存器

armv8定義了VBAR_EL1、VBAR_EL2、VBAR_EL3三個(gè)基地址寄存器

3、optee異常向量表的實(shí)現(xiàn)

(optee_os/core/arch/arm/kernel/thread_a64.S)#define INV_INSN 0 FUNC thread_excp_vect , : align=2048/* -----------------------------------------------------* EL1 with SP0 : 0x0 - 0x180* -----------------------------------------------------*/.balign 128, INV_INSN el1_sync_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b el1_sync_abortcheck_vector_size el1_sync_sp0.balign 128, INV_INSN el1_irq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_irqcheck_vector_size el1_irq_sp0.balign 128, INV_INSN el1_fiq_sp0:store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3b elx_fiqcheck_vector_size el1_fiq_sp0.balign 128, INV_INSN el1_serror_sp0:b el1_serror_sp0check_vector_size el1_serror_sp0/* -----------------------------------------------------* Current EL with SP1: 0x200 - 0x380* -----------------------------------------------------*/.balign 128, INV_INSN el1_sync_sp1:b el1_sync_sp1check_vector_size el1_sync_sp1.balign 128, INV_INSN el1_irq_sp1:b el1_irq_sp1check_vector_size el1_irq_sp1.balign 128, INV_INSN el1_fiq_sp1:b el1_fiq_sp1check_vector_size el1_fiq_sp1.balign 128, INV_INSN el1_serror_sp1:b el1_serror_sp1check_vector_size el1_serror_sp1/* -----------------------------------------------------* Lower EL using AArch64 : 0x400 - 0x580* -----------------------------------------------------*/.balign 128, INV_INSN el0_sync_a64:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH64_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a64.balign 128, INV_INSN el0_irq_a64:restore_mappingb elx_irqcheck_vector_size el0_irq_a64.balign 128, INV_INSN el0_fiq_a64:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a64.balign 128, INV_INSN el0_serror_a64:b el0_serror_a64check_vector_size el0_serror_a64/* -----------------------------------------------------* Lower EL using AArch32 : 0x0 - 0x180* -----------------------------------------------------*/.balign 128, INV_INSN el0_sync_a32:restore_mappingmrs x2, esr_el1mrs x3, sp_el0lsr x2, x2, #ESR_EC_SHIFTcmp x2, #ESR_EC_AARCH32_SVCb.eq el0_svcb el0_sync_abortcheck_vector_size el0_sync_a32.balign 128, INV_INSN el0_irq_a32:restore_mappingb elx_irqcheck_vector_size el0_irq_a32.balign 128, INV_INSN el0_fiq_a32:restore_mappingb elx_fiqcheck_vector_size el0_fiq_a32.balign 128, INV_INSN el0_serror_a32:b el0_serror_a32check_vector_size el0_serror_a32

(1)、check_vector_size
check_vector_size其實(shí)就是檢查異常向量中的指令size,不能草果32*4=128字節(jié),因?yàn)閍rmv8-arch64定義的異常向量每一個(gè)offset中的地址范圍是128字節(jié)

.macro check_vector_size since.if (. - \since) > (32 * 4).error "Vector exceeds 32 instructions".endif.endm

(2)、128字節(jié)對(duì)其的異常向量
balign 128就是告訴匯編代碼,接下來(lái)的函數(shù)定義是128字節(jié)對(duì)其的。這也和armv8-arch64定義的異常向量的地址范圍一致

.balign 128, INV_INSN

(3)、異常向量實(shí)現(xiàn)的總結(jié)

組異常向量處理的函數(shù)判定是否實(shí)現(xiàn)
第一組el1_sync_sp0b el1_sync_abortY
第一組el1_irq_sp0b elx_irqY
第一組el1_fiq_sp0b elx_fiqY
第一組el1_serror_sp0b el1_serror_sp0
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第二組el1_sync_sp1b el1_sync_sp1
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第二組el1_irq_sp1b el1_irq_sp1
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第二組el1_fiq_sp1b el1_fiq_sp1
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第二組el1_serror_sp1b el1_serror_sp1
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第三組el0_sync_a64b el0_sync_abortY
第三組el0_irq_a64b elx_irqY
第三組el0_fiq_a64b elx_fiqY
第三組el0_serror_a64b el0_serror_a64
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N
第四組el0_sync_a32b el0_svcY
第四組el0_irq_a32b elx_irqY
第四組el0_fiq_a32b elx_fiqY
第四組el0_serror_a32b el0_serror_a32
自己跳轉(zhuǎn)到自己,相當(dāng)于死循環(huán)
N

總結(jié)一下也是很好理解:

  • 在optee os中,使用的sp_el0棧,同時(shí)支持aarch32、aarch64的user程序,所以實(shí)現(xiàn)了第一、三、四組異常向量,另外optee不處理serror異常,所以serror也不實(shí)現(xiàn)。
  • 在Linux kernel中,使用sp_el1棧,同時(shí)支持aarch32、aarch64的user程序,所以實(shí)現(xiàn)了第二、三、四組異常向量.
    注:雖然Linux Kernel實(shí)現(xiàn)了FIQ向量,但該向量下的邏輯最終跳轉(zhuǎn)到panic()函數(shù),也就是如果觸發(fā)了target到Linux Kernel的FIQ,將發(fā)生panic.

(4)、elx_irq和elx_fiq
以irq/fiq為例,我們還可以發(fā)現(xiàn),無(wú)論是哪種分組異常,最終跳轉(zhuǎn)的都是同一類函數(shù):elx_irq和elx_fiq,即無(wú)論是下面哪種情況,跳轉(zhuǎn)的都是elx_irq和elx_fiq函數(shù)。

  • PE在optee os特權(quán)級(jí)(S-EL1)執(zhí)行時(shí),來(lái)了一個(gè)irq/fiq中斷
  • PE在userspace非特權(quán)級(jí)(S-EL0)執(zhí)行aarch64時(shí),來(lái)了一個(gè)irq/fiq中斷
  • PE在userspace非特權(quán)級(jí)(S-user mode)執(zhí)行aarch32時(shí),來(lái)了一個(gè)irq/fiq中斷

4、optee異常向量表基地址的定義

從上文的異常向量表的實(shí)現(xiàn)中可以發(fā)現(xiàn),異常向量定義在了thread_excp_vect函數(shù)中, 那么該函數(shù)(異常向量)是如何布局到內(nèi)存的? 該函數(shù)的基地址又是如何寫入到VBAR_EL1的?

FUNC thread_excp_vect , : align=2048


thread_init_vbar(vaddr_t addr)將addr寫入到vbar_el1

(optee_os/core/arch/arm/kernel/thread_a64.S)FUNC thread_init_vbar , :msr vbar_el1, x0ret END_FUNC thread_init_vbar

get_excp_vect()返回異常向量表基地址(當(dāng)然是虛擬地址)

(optee_os/core/arch/arm/kernel/thread.c)static vaddr_t get_excp_vect(void) { #ifdef CFG_CORE_WORKAROUND_SPECTRE_BP_SECuint32_t midr = read_midr();if (get_midr_implementer(midr) != MIDR_IMPLEMENTER_ARM)return (vaddr_t)thread_excp_vect;switch (get_midr_primary_part(midr)) { #ifdef ARM32case CORTEX_A8_PART_NUM:case CORTEX_A9_PART_NUM:case CORTEX_A17_PART_NUM: #endifcase CORTEX_A57_PART_NUM:case CORTEX_A72_PART_NUM:case CORTEX_A73_PART_NUM:case CORTEX_A75_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround); #ifdef ARM32case CORTEX_A15_PART_NUM:return select_vector((vaddr_t)thread_excp_vect_workaround_a15); #endifdefault:return (vaddr_t)thread_excp_vect;} #endif /*CFG_CORE_WORKAROUND_SPECTRE_BP_SEC*/return (vaddr_t)thread_excp_vect; }

關(guān)于從cpu的啟動(dòng)(從cpu啟動(dòng)時(shí)設(shè)置VBAR_EL1):

  • 如果在整個(gè)系統(tǒng)中有實(shí)現(xiàn)ATF,則CFG_WITH_ARM_TRUSTED_FW宏是打開(kāi)的,那么從cpu是從boot_cpu_on_handler啟動(dòng),也就是從ATF調(diào)來(lái)的。
  • 如果在整個(gè)系統(tǒng)中沒(méi)有實(shí)現(xiàn)ATF,則CFG_WITH_ARM_TRUSTED_FW宏是關(guān)閉的,那么從cpu是從reset_secondary---->boot_init_secondary調(diào)用過(guò)來(lái)的
(optee_os/core/arch/arm/kernel/boot.c)#if defined(CFG_WITH_ARM_TRUSTED_FW) unsigned long boot_cpu_on_handler(unsigned long a0 __maybe_unused,unsigned long a1 __unused) {init_secondary_helper(PADDR_INVALID);return 0; } #else void boot_init_secondary(unsigned long nsec_entry) {init_secondary_helper(nsec_entry); } #endif

細(xì)心的同學(xué)看代碼可以發(fā)現(xiàn):

  • armv8-aarch64架構(gòu)都是有實(shí)現(xiàn)ATF,一般情況下CFG_WITH_ARM_TRUSTED_FW宏也都是打開(kāi)的
  • 在optee的aarch64體系中,是沒(méi)有調(diào)用boot_init_secondary函數(shù)的,僅僅在optee_os/core/arch/arm/kernel/entry_a32.S中的reset_secondary中進(jìn)行了調(diào)用boot_init_secondary()

5、elx_irq和elx_fiq

gicv3/gicv2有著不同的處理

  • 如果是gicv2,則會(huì)將irq視為外系統(tǒng)中斷,fiq視為本系統(tǒng)中斷;
  • 如果是gicv3,恰好相反,將fiq視為外系統(tǒng)中斷,irq視為本系統(tǒng)中斷.

(注從optee中斷軟件的視角來(lái)看,gic可以分為兩類,gicv2、非gicv2, 這里說(shuō)說(shuō)的gicv3其實(shí)就是非gicv2,如果你使用的是gicv4,那么也會(huì)定義CFG_ARM_GICV3宏)

本系統(tǒng)中斷和外部系統(tǒng)中斷的處理:

  • 如果是本系統(tǒng)中斷,則調(diào)用native_intr_handler
  • 如果是外部系統(tǒng)中斷則調(diào)用foreign_intr_handler
(optee_os/core/arch/arm/kernel/thread_a64.S)LOCAL_FUNC elx_irq , :#if defined(CFG_ARM_GICV3)native_intr_handler irq#elseforeign_intr_handler irq#endifEND_FUNC elx_irqLOCAL_FUNC elx_fiq , :#if defined(CFG_ARM_GICV3)foreign_intr_handler fiq#elsenative_intr_handler fiq#endifEND_FUNC elx_fiq

總結(jié)

以上是生活随笔為你收集整理的optee3.14中的异常向量表解读--中断处理解读的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。