TF-A代码阅读: SP_EL3栈内存-cpu_data内存的介绍(cpu_context介绍)
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
說明:
代碼導讀而已,都是些比較難找的答案
思考:
cpu_context到底存在哪里呢?
不同core之間的cpu_context呢?
不同security之間的cpu_context
在哪里設置SP_EL3指向cpu_context的呢
1、TF-A中的的cpu_data
在編譯的時候,定義一個cpu_data類型的數組: percpu_data:
_cpu_data_by_index函數返回 percpu_data[x]數組
init_cpu_data_ptr函數調用時(該函數在boot或cpu_on的時候會被調用),將 percpu_data[x] 寫入到了 tpidr_el3中
(trusted-firmware-a/lib/el3_runtime/aarch64/cpu_data.S)func init_cpu_data_ptrmov x10, x30bl plat_my_core_posbl _cpu_data_by_indexmsr tpidr_el3, x0ret x10 endfunc init_cpu_data_ptr_cpu_data(void) 函數則從 tpidr_el3讀取數據返回,正是 percpu_data[x]數組
相應的下面這種宏,也是返回cpu_context
- #define get_cpu_data(_m) _cpu_data()->_m
- #define set_cpu_data(_m, _v) _cpu_data()->_m = (_v)
- #define get_cpu_data_by_index(_ix, _m) _cpu_data_by_index(_ix)->_m
- #define set_cpu_data_by_index(_ix, _m, _v) _cpu_data_by_index(_ix)->_m = (_v)
補充小知識:tpidr_el3 就說給我們軟件使用的,用于臨時存放一些數據
再來看cpu_data結構體,里面包含了下標為2的cpu_context數組, 其中cpu_context[0]是給non-secure準備的,cpu_context[1]是給secure準備的。
2、小小總結
- 編譯的時候,定義了一個全局數組percpu_data,數組中的每一個元素代表一個cpu_data
初始化core的時候,將對應cpu_data寫入到了該core的tpidr_el3寄存器中 - 每個cpu_data中有兩個cpu_context,[0]表示secure側用的,[1]表示給non-secure側用的
- 使用類似如下這樣的宏或函數,即可獲取當前cpu、當前security的cpu_context
get_cpu_data(cpu_context[security_state])
注意:該宏底層會讀取tpidr,security_state為SECURE或NON-SECURE
總結中的總結:
其實就是在ATF中定義了一個全局數組,里面用于存放每一個cpu每一種security狀態的cpu_context。例如開了8個core,那么就有16個cpu_context,8個是給non-secure,8個是給secure的。然后ATF在提供一些API給其它程序,用于獲取當前cpu指定security的cpu_context
3、設置sp_el3指向cpu_context
ATF的軟件架是有一些要求的,例如要求:當PE切換到ATF時,SP_EL3需指向cpu_context結構體。那么是在哪里設置sp_el3的呢?
其實就說在EL3退出的時候cm_prepare_el3_exit(uint32_t security_state) 會調用cm_set_next_eret_context(security_state), 最終調用到cm_set_next_context, 在該函數中會將SP_EL3指向該core該security的cpu_context
/******************************************************************************** This function is used to program the context that's used for exception* return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for* the required security state******************************************************************************/ void cm_set_next_eret_context(uint32_t security_state) {cpu_context_t *ctx;ctx = cm_get_context(security_state);assert(ctx != NULL);cm_set_next_context(ctx); } static inline void cm_set_next_context(void *context) { #if ENABLE_ASSERTIONSuint64_t sp_mode;/** Check that this function is called with SP_EL0 as the stack* pointer*/__asm__ volatile("mrs %0, SPSel\n": "=r" (sp_mode));assert(sp_mode == MODE_SP_EL0); #endif /* ENABLE_ASSERTIONS */__asm__ volatile("msr spsel, #1\n""mov sp, %0\n""msr spsel, #0\n": : "r" (context)); }總結
以上是生活随笔為你收集整理的TF-A代码阅读: SP_EL3栈内存-cpu_data内存的介绍(cpu_context介绍)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TF-A代码阅读: 双系统切换时是如何保
- 下一篇: 思想解读:TF-A(ATF)中栈指针和栈