CAR是Cache As RAM的縮寫,是以CPU的Cache作為RAM為PEI階段的C提供memory資源,以便EFI盡早進入C語言環境。
相關知識儲備:
MTRR——Memory Type Range Register,(which is a part of MSRs), 可以通過指令RDMSR和WRMSR進行讀寫操作。
MTRR由三個重要組成部分構成:IA32_MTRR_DEF_TYPE MSR、Fixed Range MTRRs 和 Variable Range MTRRs。
IA32_MTRR_DEF_TYPE MSR
長64bit。其中,bit0-7為Type field,其值作為default memory type;bit10作為fixed MTRRs enabled的標志位;而bit11則作為MTRRs enabled的標志位。當bit11置0時,所有memory type為UC;當其置1時,沒有被 fixed or variable MTRR設定的物理空間的memory type取設定的default值。
Fixed Range MTRRs 共有11個固定的寄存器,其將0-FFFFFH的1M空間划分為1個512-KByte address range ,2個128-KByte address ranges與8個32-KByte address ranges,且各個address ranges又分別划分為8個sub_ranges。
Variable Range MTRRs 作為Non_Fixed-Range MTRRs,利用8組IA32_MTRR_PHYSBASE和IA32_MTRR_PHYSMASK來設定所對應物理地址空間的具體起始位置和大小。
需注意其IA32_MTRR_PHYSBASE不僅定義了base address,其bit0-7定義了該address range的memory type。而Fixed Range MTRRs的64bit分別表示其八個sub_ranges的memory type。
以上各寄存器均為64bit長度,且均用指令RDMSR和WRMSR進行讀寫操作。三個參數中,ECX傳入各寄存器對應的MSR地址;EDX和EAX分別表示高32位與低32位數據。
Memrory Type:
UC—Uncacheable (00H)
WC—Write Combining(01H)
WT—Write Through (04H)
This type of cache-control is appropriate for frame buffers or when there are devices on the system bus that access system memory, but do not perform snooping of memory accesses. It enforces coherency between caches in the processors and system memory
WP—Write Protected (05H)
Reads come from cache lines when possible, and read misses cause cache fills. Writes are propagated to the system bus and cause corresponding cache lines on all processors on the bus to be invalidated.
WB—Write Back(06H)
This type of cache-control provides the best performance, but it requires that all devices that access system memory on the system bus be able to snoop memory accesses to insure system memory and cache coherency
實現Cache as RAM的方法步驟(ProcessorStartupCore.asm):
1,MTRR初始化之后,對MTRR_DEF_TYPE進行設置
mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index rdmsr and eax, NOT (00000CFFh) ; Clear the enable bits and def type UC. Wrmsr
2,Clear e flag(bit 11),UC memory type將適用於所有物理內存。
UC memory type下,memory的位置全為可見的。通常應用於內存映射的IO設備。
3,通過CPUID將MTRR_PHYS_MASK_HIGH的高32位置為0000000fh。
4,利用MTRR_PHYS_BAS_0/1與MTRR_PHYS_MASK_0/1來設定DataStack與code region的base address、length及memory type。
5,MTRR_DEF_TYPE MSR E flag置1
6,啟動BSP,執行INVD,將CR0的CD位及NW位清0.
INVD:使所有進入內部cache的命令及數據無效,並發出信號給外部cache使其同樣無效。
7,開啟NEM
8,TEST,其過程通過對建好的CAR進行寫和讀,然后將數據進行比較來進行,詳見這段CODE:
; Finished with cache configuration ; Optionally Test the Region... ; Test area by writing and reading cld mov edi, DATA_STACK_BASE_ADDRESS mov ecx, DATA_STACK_SIZE / 4 mov eax, DWORD PTR CACHE_TEST_VALUE TestDataStackArea: stosd cmp eax, DWORD PTR [edi-4] jnz DataStackTestFail loop TestDataStackArea jmp DataStackTestPass
如果產生錯誤,將error code傳送到Port80()。
實現Cache as RAM的原理:
設置data stack的memory type為WB, 利用WB的特征,限制cache與memory之間的數據傳輸,使數據僅停留在cache中,以實現Cache as RAM。
“The write-back memory type reduces bus traffic by eliminating many unnecessary writes to system memory. Writes to a cache line are not immediately forwarded to system memory; instead, they are accumulated in the cache.
The modified cache lines are written to system memory later, when a write-back operation is performed.”
BSP 與APs是由硬件決定的。在進行cache as RAM時,首先要確定的是已進入保護模式,其次便是確定,對於Multiple-processor系統而言,有且只有一個的BSP。此時,只有BSP在工作,APs都處於睡眠狀態,且時刻等待着被SIPI喚醒。因此,在我們開始初始化MTRR之前,應確保所有的APs都保持在睡眠狀態,一旦發現其被喚醒,便通過廣播INIT IPI使其重新進入睡眠狀態。
在cache as RAM過程中,我們還會遇到關於 NO-Evict MODE 概念的理解。從字面可理解為禁止逐出模式。在此模式下,CPU處理的數據僅停留在cache中,不會從cache逐出到memory
是滴...
No Eviction是CAR的精神必要所在.
正常的Cache是時常有機會會被數據替換(swapping),而CAR是不允許Eviction發生的.
預防Cache evict的發生要注意幾個重點,
1. 不用的MTRRs必須都關閉(initial to zero...)
2. Code region及Data Stack region的大小總和不能大於Cache size(L2 cache)
3. 過程中不可以有任何cache flush指令(INVD,WINVD,...)
4. Disable pagging from CR0 (bit31)
