1、std_svc_setup (主要關(guān)注設(shè)置psci操作集)--有服務(wù)
std_svc_setup //services/std_svc/std_svc_setup.c
- >psci_setup //lib/psci/psci_setup.c
- >plat_setup_psci_ops //設(shè)置平臺(tái)的psci操作 調(diào)用平臺(tái)的plat_setup_psci_ops函數(shù)去設(shè)置psci操作 eg:qemu平臺(tái)
- >*psci_ops = &plat_qemu_psci_pm_ops;
208 static const plat_psci_ops_t plat_qemu_psci_pm_ops = {
209 .cpu_standby = qemu_cpu_standby,
210 .pwr_domain_on = qemu_pwr_domain_on,
211 .pwr_domain_off = qemu_pwr_domain_off,
212 .pwr_domain_suspend = qemu_pwr_domain_suspend,
213 .pwr_domain_on_finish = qemu_pwr_domain_on_finish,
214 .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish,
215 .system_off = qemu_system_off,
216 .system_reset = qemu_system_reset,
217 .validate_power_state = qemu_validate_power_state,
218 .validate_ns_entrypoint = qemu_validate_ns_entrypoint
219 };
在遍歷每一個(gè)注冊(cè)的運(yùn)行時(shí)服務(wù)的時(shí)候,會(huì)導(dǎo)致std_svc_setup調(diào)用,其中會(huì)做psci操作集的設(shè)置,操作集中我們可以看到對(duì)核電源的管理的接口如:核上電,下電,掛起等,我們主要關(guān)注上電 .pwr_domain_on = qemu_pwr_domain_on,這個(gè)接口當(dāng)我們主處理器boot從處理器的時(shí)候會(huì)用到。
2、運(yùn)行時(shí)服務(wù)觸發(fā)和處理--來(lái)請(qǐng)求
smc指令觸發(fā)進(jìn)入el3異常向量表:
runtime_exceptions //el3的異常向量表
- >sync_exception_aarch64
- >handle_sync_exception
- >smc_handler64
- > |* Populate the parameters for the SMC handler.
|* We already have x0-x4 in place. x5 will point to a cookie (not used
|* now). x6 will point to the context structure (SP_EL3) and x7 will
|* contain flags we need to pass to the handler Hence save x5-x7.
|*
|* Note: x4 only needs to be preserved for AArch32 callers but we do it
|* for AArch64 callers as well for convenience
|*/
stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] //保存x4-x7到棧
stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
/* Save rest of the gpregs and sp_el0*/
save_x18_to_x29_sp_el0
mov x5, xzr //x5清零
mov x6, sp //sp保存在x6
/* Get the unique owning entity number */ //獲得唯一的入口編號(hào)
ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
/* Load descriptor index from array of indices */
adr x14, rt_svc_descs_indices //獲得服務(wù)描述 標(biāo)識(shí)數(shù)組
ldrb w15, [x14, x16] //根據(jù)唯一的入口編號(hào) 找到處理函數(shù)的 地址
/*
|* Restore the saved C runtime stack value which will become the new
|* SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context'
|* structure prior to the last ERET from EL3.
|*/
ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
/*
|* Any index greater than 127 is invalid. Check bit 7 for
|* a valid index
|*/
tbnz w15, 7, smc_unknown
/* Switch to SP_EL0 */
msr spsel, #0
/*
|* Get the descriptor using the index
|* x11 = (base + off), x15 = index
|*
|* handler = (base + off) + (index < < log2(size))
|*/
lsl w10, w15, #RT_SVC_SIZE_LOG2
ldr x15, [x11, w10, uxtw]
/*
|* Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world
|* switch during SMC handling.
|* TODO: Revisit if all system registers can be saved later.
|*/
mrs x16, spsr_el3 //spsr_el3保存在x16
mrs x17, elr_el3 //elr_el3保存在x17
mrs x18, scr_el3 //scr_el3保存在x18
stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] / x16, x17/保存在棧
str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] //x18保存到棧
/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
bfi x7, x18, #0, #1
mov sp, x12
/*
|* Call the Secure Monitor Call handler and then drop directly into
|* el3_exit() which will program any remaining architectural state
|* prior to issuing the ERET to the desired lower EL.
|*/
#if DEBUG
cbz x15, rt_svc_fw_critical_error
#endif
blr x15 //跳轉(zhuǎn)到處理函數(shù)
b el3_exit //從el3退出 會(huì)eret 回到el1 (后面會(huì)講到)
3、找到對(duì)應(yīng)handler--請(qǐng)求匹配處理函數(shù)
上面其實(shí)主要的是找到服務(wù)例程,然后跳轉(zhuǎn)執(zhí)行 下面是跳轉(zhuǎn)的處理函數(shù):
std_svc_smc_handler //services/std_svc/std_svc_setup.c
- >ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
| cookie, handle, flags)
...
480 } else {
481 /* 64-bit PSCI function */
482
483 switch (smc_fid) {
484 case PSCI_CPU_SUSPEND_AARCH64:
485 ret = (u_register_t)
486 psci_cpu_suspend((unsigned int)x1, x2, x3);
487 break;
488
489 case PSCI_CPU_ON_AARCH64:
490 ret = (u_register_t)psci_cpu_on(x1, x2, x3);
491 break;
492
...
}
-
cpu
+關(guān)注
關(guān)注
68文章
10911瀏覽量
213144 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9335瀏覽量
86133 -
SMP
+關(guān)注
關(guān)注
0文章
76瀏覽量
19758 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4346瀏覽量
63015
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
AliOS Things SMP系統(tǒng)及其在esp32上實(shí)現(xiàn)示例
ARM電源管理中的PSCI是什么意思呢
記錄學(xué)習(xí)ARM Linux的多核啟動(dòng)過(guò)程
ARM64 SMP多核啟動(dòng)相關(guān)資料推薦(下)
介紹在ARM64架構(gòu)下啟動(dòng)多核的兩種方式
ARM64 SMP多核啟動(dòng)(上)—spin-table
![ARM64 <b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>啟動(dòng)</b>(上)—spin-table](https://file1.elecfans.com/web2/M00/89/66/wKgaomSCxjmAUMrsAAEbsYxMHlI187.jpg)
ARM64 SMP多核啟動(dòng)(下)—PSCI
![ARM64 <b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>啟動(dòng)</b>(下)—<b class='flag-5'>PSCI</b>](https://file1.elecfans.com/web2/M00/89/66/wKgaomSCxymAMT8RAAEl_qxJBsY504.jpg)
多核CPU的啟動(dòng)方式
SMP是什么?多核芯片(SMP)的啟動(dòng)方法
![<b class='flag-5'>SMP</b>是什么?<b class='flag-5'>多核</b>芯片(<b class='flag-5'>SMP</b>)的<b class='flag-5'>啟動(dòng)</b>方法](https://file1.elecfans.com/web2/M00/8D/CD/wKgZomTAdmSAUhL7AAEiLn9UGVs698.png)
SMP是什么 啟動(dòng)方式介紹
SMP多核啟動(dòng)cpu操作函數(shù)
![<b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>啟動(dòng)</b>cpu操作函數(shù)](https://file1.elecfans.com/web2/M00/B4/71/wKgZomVu12OAJXJZAAGW5cqGuKU424.jpg)
psci接口規(guī)范介紹
內(nèi)核中的psci驅(qū)動(dòng)是什么
![內(nèi)核中的<b class='flag-5'>psci</b>驅(qū)動(dòng)是什么](https://file1.elecfans.com/web2/M00/B2/AF/wKgaomVu5Q2APT6ZAAGUCF-LhVY534.jpg)
SMP多核secondary cpu啟動(dòng)流程
![<b class='flag-5'>SMP</b><b class='flag-5'>多核</b>secondary cpu<b class='flag-5'>啟動(dòng)</b>流程](https://file1.elecfans.com/web2/M00/B2/B1/wKgaomVu7qGADZyPAAFcIeh24do321.jpg)
評(píng)論