版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第第頁(yè)電源管理入門(mén)-關(guān)機(jī)重啟基礎(chǔ)知識(shí)詳解當(dāng)我們接觸(電源管理)的時(shí)候,最簡(jiǎn)單的流程就是
關(guān)機(jī)重啟
,但是仔細(xì)分析其涉及的所有源代碼就會(huì)發(fā)現(xiàn),關(guān)機(jī)重啟雖然簡(jiǎn)單,但是“
麻雀雖小,五臟俱全
”,涉及到的軟件模塊非常的多,涉及的流程:(Linux)應(yīng)用(busybox)-》Linux內(nèi)核-》BL31-》SCP-》(PMIC)/CRU等(硬件)。所以是一個(gè)入門(mén)學(xué)習(xí),特別是還沒(méi)接觸過(guò)Linux內(nèi)核代碼的好機(jī)會(huì),下面進(jìn)入代碼的海洋遨游,
超級(jí)干貨
!
1.關(guān)機(jī)重啟軟件流程框圖
在Linux系統(tǒng)上的處理分為**用戶(hù)態(tài)**空間、**內(nèi)核**空間、**ATF**、**SCP**四個(gè)階段(ATF是(ARM)獨(dú)有的,SCP在復(fù)雜SoC上才有應(yīng)用)來(lái)處理:
BL31中smc異常觸發(fā)流程圖
執(zhí)行SMC指令后會(huì)觸發(fā)異常,進(jìn)入ATF的BL31中繼續(xù)執(zhí)行:
在Linux側(cè)調(diào)用smc異常之后,會(huì)根據(jù)中斷向量表觸發(fā)cpu的同步異常sync_exception_aarch64/32
然后跳轉(zhuǎn)執(zhí)行到handle_sync_exception->smc_handler64/32中
根據(jù)_RT_SVC_DESCS_START_+RT_SVC_DESC_HANDLE的位置,跳轉(zhuǎn)執(zhí)行rt_svc_desc_t結(jié)構(gòu)體保存的服務(wù)std_svc_smc_handler
執(zhí)行psci相關(guān)處理,找到psci_system_off和psci_system_rese處理函數(shù)。ATF直接處理如果是關(guān)機(jī)就執(zhí)行halt指令,重啟則通過(guò)設(shè)置gpio,或者轉(zhuǎn)送給SCP處理。
最后跳轉(zhuǎn)到el3_exit返回Linux側(cè)。
SMC異常觸發(fā)執(zhí)行流程:
(32*4)
//這個(gè).應(yīng)該是當(dāng)前位置-段的開(kāi)頭地址如果大于32條指令
.error"Vectorexceeds
32instructions"
//向量超過(guò)32條指令
.endif4.3
runtime服務(wù)程序初始化
bl31_entrypoint入口向下執(zhí)行首先是bl31_setup,然后是bl31_main
void
bl31_setup(u_register_targ0,u_register_targ1,u_register_targ2,
u_register_targ3)
{
/*Pe(rf)ormearly
platform-specificsetup*/
bl31_early_platform_setup2(arg0,arg1,arg2,arg3);
/*Performlate
platform-specificsetup*/
bl31_plat_arch_setup();bl31_main()函數(shù):
void
bl31_main(void)
{
NOTICE("BL31:%s",
version_string);
NOTICE("BL31:%s",
build_message);
bl31_platform_setup();
//通用和安全(時(shí)鐘)初始化,其他(芯片)相關(guān)功能初始化
bl31_lib_init();
//空函數(shù)
INFO("BL31:Initializing
runtimeservices");
runtime_svc_init();
//重點(diǎn)下面展開(kāi)分析
if(bl32_init){
INFO("BL31:
InitializingBL32");
(*bl32_init)();
}
bl31_prepare_next_image_entry();
//加載下一階段的入口地址
console_flush();
//控制臺(tái)刷新
bl31_plat_runtime_setup();
//空函數(shù)
}runtime_svc_init()函數(shù)
//注冊(cè)smc指令相關(guān)的服務(wù)
voidruntime_svc_init(void)
{
intrc=0;
unsignedintindex,start_idx,
end_idx;
/*Assertthenumberof
descriptorsdetectedarelessthan(maxim)umindices*/
//這句話表明
RT_SVC_DECS_NUM時(shí)當(dāng)前加載的服務(wù)數(shù)量
assert((RT_SVC_DESCS_END>=
RT_SVC_DESCS_START)
if(RT_SVC_DECS_NUM==0)
//如果沒(méi)有服務(wù)要注冊(cè)
return;
(mems)et(rt_svc_descs_indices,
-1,sizeof(rt_svc_descs_indices));//初始化rt_svc_descs_indices
rt_svc_descs=(rt_svc_desc_t
*)RT_SVC_DESCS_START;//建立一個(gè)注冊(cè)表結(jié)構(gòu)體
for(index=0;indexinit)
{
//該服務(wù)是否需要初始化
rc=
service->init();
//進(jìn)行初始化
if(rc){
//初始化是否成功
ERROR("Errorinitializingruntimeservice%s",
service->name);
continue;
}
}
start_idx=
get_unique_oen(rt_svc_descs[index].start_oen,
service->call_type);
//八位的id號(hào)
assert(start_idxcall_type);
//八位的id號(hào)
assert(end_idx(RAM)
#else
ro.:{
__RO_START__=.;
*bl31_entrypoint.o(.text*)
*(SORT_BY_ALIGNMENT(.text*))
*(SORT_BY_ALIGNMENT(.rodata*))
RODATA_COMMON在include/common/bl_common.ld.h中
#define
RODATA_COMMON
RT_SVC_DESCS
FCONF_POPULATOR
PMF_SVC_DESCS
PARSER_LIB_DESCS
CPU_OPS
GOT
BASE_XLAT_TABLE_RO
EL3_LP_DESCS
#defineRT_SVC_DESCS
.=ALIGN(STRUCT_ALIGN);
__RT_SVC_DESCS_START__=
.;
KEEP(*(rt_svc_descs))
__RT_SVC_DESCS_END__=.;rt_svc_descs段存放的內(nèi)容是通過(guò)DECLARE_RT_SVC宏來(lái)定義的:
//其中__setion("rt_svc_descs")的意思就是注冊(cè)到rt_svc_descs段中
#define
DECLARE_RT_SVC(_name,_start,_end,_type,
_setup,_smch)
staticconstrt_svc_desc_t
__svc_desc_##_name
__section("rt_svc_descs")__used={
.start_oen=
(_start),
.end_oen=
(_end),
.call_type=
(_type),
.name=#_name,
.init=
(_setup),
.handle=
(_smch)
}例如在services/std_svc/std_svc_setup.c中
/*
RegisterStandardServiceCallsasruntimeservice*/
DECLARE_RT_SVC(
std_svc,
OEN_STD_START,
OEN_STD_END,
SMC_TYPE_FAST,
std_svc_setup,
std_svc_smc_handler
);
#defineOEN_STD_START
U(4)
/*StandardService
Calls*/
#defineOEN_STD_END
U(4)
#defineSMC_TYPE_FAST
UL(1)
#defineSMC_TYPE_YIELD
UL(0)staticconstrt_svc_desc_t__svc_desc_std_svc服務(wù)。其服務(wù)id為SMC_TYPE_FASTinit()會(huì)執(zhí)行std_svc_setup()函數(shù)
->psci_setup((constpsci_lib_args_t*)svc_arg)
(void)plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep,
plat_setup_psci_ops()的定義根據(jù)平臺(tái),我們使用的是qemu,對(duì)應(yīng)plat/qemu/qemu_sbsa/sbsa_pm.c文件中:
*psci_ops=
static
constplat_psci_ops_tplat_qemu_psci_pm_ops={
.cpu_standby=
qemu_cpu_standby,
.pwr_domain_on=
qemu_pwr_domain_on,
.pwr_domain_off=
qemu_pwr_domain_off,
.pwr_domain_pwr_down_wfi=
qemu_pwr_domain_pwr_down_wfi,
.pwr_domain_suspend=qemu_pwr_domain_suspend,
.pwr_domain_on_finish=
qemu_pwr_domain_on_finish,
.pwr_domain_suspend_finish=
qemu_pwr_domain_suspend_finish,
.system_off=qemu_system_off,
.system_reset=
qemu_system_reset,
.validate_power_state=
qemu_validate_power_state
};
4.4SMC異常處理入口分析
SMC命令執(zhí)行后,CPU會(huì)根據(jù)異常向量表找到sync_exception_aarch64的入口
會(huì)執(zhí)行handle_sync_exception,在bl31/aarch64/runtime_exceptions.S中
/*
*Thismacrohandles
Synchronousexceptions.
*OnlySMCexceptionsare
supported.
*
*/
.macro
handle_sync_exception
#ifENABLE_RUNTIME_INSTRUMENTATION
/*
*Readthetimestampvalueand
storeitinper-cpudata.Thevalue
*willbeextractedfrom
per-cpudatabytheClevelSMChandlerand
*savedtothePMFtimestamp
region.
*///存放時(shí)間戳
mrs
x30,cntpct_el0
str
x29,[sp,#CTX_GPREGS_OFFSET+
CTX_GPREG_X29]
mrs
x29,tpidr_el3
str
x30,[x29,#CPU_DATA_PMF_TS0_OFFSET]
ldr
x29,[sp,#CTX_GPREGS_OFFSET+
CTX_GPREG_X29]
#endif
mrs
x30,esr_el3
//將esr_el3存入x30
//#defineESR_EC_SHIFTU(26)
#defineESR_EC_LENGTHU(6)
//相當(dāng)于保留x30的bit[31-26]并將這幾位提到bit[6-0]
ubfx
x30,x30,#ESR_EC_SHIFT,#ESR_EC_LENGTH
/*HandleSMCexceptions
separatelyfromothersynchronousexceptions*/
cmp
x30,#EC_AARCH32_SMC
b.eq
smc_handler32
cmp
x30,#EC_AARCH64_SMC
b.eq
sync_handler64
cmp
x30,#EC_AARCH64_SYS
b.eq
sync_handler64
/*Synchronousexceptionsother
thantheaboveareassumedtobeEA*/
ldr
x30,[sp,#CTX_GPREGS_OFFSET+
CTX_GPREG_LR]
b
enter_lower_el_sync_ea
.endm三種跳轉(zhuǎn)選項(xiàng)其中smc_handler32/64能夠正確觸發(fā)異常,report_unhand(led)_exception則是錯(cuò)誤的流程
#define
EC_AARCH32_SMC
U(0x13)
#defineEC_AARCH64_SVC
U(0x15)
#defineEC_AARCH64_HVC
U(0x16)
#defineEC_AARCH64_SMC
U(0x17)x30里面存儲(chǔ)的是esr_el3的26-32位,里面是什么判斷了smc64
當(dāng)前平臺(tái)架構(gòu)是aarch64的,看一下sync_handler64這個(gè)處理,在bl31/aarch64/runtime_exceptions.S中
/*Loaddescriptorindexfromarray
ofindices*/
//在runtime_svc_init()中會(huì)將所有的sectionrt_svc_descs段放入rt_svc_descs_indices數(shù)組,
//這里獲取該數(shù)組地址
adrp
x14,rt_svc_descs_indices
add
x14,x14,rt_svc_descs_indices
ldrb
w15,[x14,x16]//找到rt_svc在rt_svc_descs_indices數(shù)組中的index
/*
*Getthedescriptorusingthe
index
*x11=(base+off),w15=
index這個(gè)index就是rt_svc_descs結(jié)構(gòu)體數(shù)組下標(biāo)
*
*handler=(base+off)+
(index
?bit31決定是fastcall,還是stdcall(yield對(duì)應(yīng)的就是stdcall)
?bit30表示是以32位傳參,還是以64位傳參,注意我們看了optee在linux的driver,都是以32位方式
?bit29:24決定服務(wù)的類(lèi)型
?bit23:16reserved
?bit15:0每種call類(lèi)型下,表示range
這個(gè)地方值為4,
/*
RegisterStandardServiceCallsasruntimeservice*/
DECLARE_RT_SVC(
std_svc,
OEN_STD_START,
OEN_STD_END,
SMC_TYPE_FAST,
std_svc_setup,
std_svc_smc_handler
);
#defineOEN_STD_START
U(4)
/*StandardServiceCalls*/
#defineOEN_STD_END
U(4)
系統(tǒng)啟動(dòng)的時(shí)候會(huì)把index信息存入到rt_svc_descs_indices里面,根據(jù)4取出來(lái)就可以了。
start_idx
=(uint8_t)get_unique_oen(service->start_oen,service->call_type);
end_idx=
(uint8_t)get_unique_oen(service->end_oen,service->call_type);
assert(start_idxsystem_off!=NULL);
/*NotifytheSecurePayload
Dispatcher*/
if((psci_spd_pm!=NULL)
}
console_flush();
/*Calltheplatformspecific
hook*/
psci_plat_pm_ops->system_off();
/*Thisfunctiondoesnot
return.Weshouldnevergethere*/
}psci_print_power_domain_map()的打印再和設(shè)備重啟時(shí)的日志進(jìn)行對(duì)比,發(fā)現(xiàn)是一致的。
4.5
硬件平臺(tái)相關(guān)處理
在qemu平臺(tái)上的實(shí)現(xiàn)如下:
psci_plat_pm_ops系統(tǒng)初始化的時(shí)候會(huì)賦值
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年滬科新版九年級(jí)歷史上冊(cè)階段測(cè)試試卷含答案
- 2025年新世紀(jì)版必修二歷史上冊(cè)月考試卷
- 2025年青島版六三制新必修2地理下冊(cè)月考試卷含答案
- 2025年外研版2024高三生物上冊(cè)階段測(cè)試試卷
- 2025年浙教版選擇性必修3生物上冊(cè)月考試卷含答案
- 2025年度木材貿(mào)易代理服務(wù)合同范本2篇
- 2025賓館洗浴中心客戶(hù)滿意度提升與忠誠(chéng)度維護(hù)合同3篇
- 2025版農(nóng)業(yè)科技園區(qū)基礎(chǔ)設(shè)施建設(shè)合同7篇
- 2025年度店面多媒體展示系統(tǒng)設(shè)計(jì)與安裝承包合同4篇
- 2025年度擬上公司與會(huì)計(jì)事務(wù)所財(cái)務(wù)數(shù)據(jù)共享保密合同4篇
- 2025-2030年中國(guó)草莓市場(chǎng)競(jìng)爭(zhēng)格局及發(fā)展趨勢(shì)分析報(bào)告
- 第二章《有理數(shù)的運(yùn)算》單元備課教學(xué)實(shí)錄2024-2025學(xué)年人教版數(shù)學(xué)七年級(jí)上冊(cè)
- 華為智慧園區(qū)解決方案介紹
- 奕成玻璃基板先進(jìn)封裝中試線項(xiàng)目環(huán)評(píng)報(bào)告表
- 廣西壯族自治區(qū)房屋建筑和市政基礎(chǔ)設(shè)施全過(guò)程工程咨詢(xún)服務(wù)招標(biāo)文件范本(2020年版)修訂版
- 人教版八年級(jí)英語(yǔ)上冊(cè)期末專(zhuān)項(xiàng)復(fù)習(xí)-完形填空和閱讀理解(含答案)
- 2024新版有限空間作業(yè)安全大培訓(xùn)
- GB/T 44304-2024精細(xì)陶瓷室溫?cái)嗔炎枇υ囼?yàn)方法壓痕(IF)法
- 年度董事會(huì)工作計(jì)劃
- 《退休不褪色余熱亦生輝》學(xué)校退休教師歡送會(huì)
- 02R112拱頂油罐圖集
評(píng)論
0/150
提交評(píng)論