2011年11月18日 星期五

MTRR


MTRR (Memory type range registers) 是CPU內的一組MSR (Model-specific registers) ,它作用為告訴CPU要如何最佳的存取各個記憶體區段,簡單來說是CPU要以哪種快取模式來進行存取。

通常MTRR的初始化是BIOS的任務。

在UEFI中可以使用EfiReadMsr, EfiWriteMsr, MsrRead64, MsrWrite64...等Function來存取,只要拉相對應的Header與Library就好。


IA32_MTRRCAP, Index: 0xFE, Read-Only.
  • VCNT (variable range registers count) bits 0 ~ 7 - 指出這個CPU支援幾組動態的MTRR,MTRR也是有數量的,也有機會被塞爆。
  • FIX (fixed range registers supported) flag, bit 8 - 指出是否支援Fixed range MTRRs (IA32_MTRR_FIX64K_00000 through IA32_MTRR_FIX4K_0F8000)。
  • WC (write combining) flag, bit 10 - 是否支援write-combining (WC) memory。
  • SMRR (System-Management Range Register) flag, bit 11 - 是否支援SMRR。


IA32_MTRR_DEF_TYPE, Index: 0x2FF.
  • Type field, bits 0 ~ 7 - 指出未涵蓋在MTRR所定義的記憶體該以何種Cache為預設值。
  • FE (fixed MTRRs enabled) flag, bit 10 - Enable或Disable Fixed-range MTRR。
  • E (MTRRs enabled) flag, bit 11 - Enable或Disable動態的MTRR。


Variable - Range Register Pair
一組MTRR有兩個Registers,Base與Mask,起始索引可參考EDK的定義:
#define EFI_CACHE_VARIABLE_MTRR_BASE 0x200

  • Type field, bits 0 ~ 7 - 此MTRR所定義的範圍該以何種Cache方式存取。
  • Valid field, bits 11 - 指出此組MTRR是否有效。
  • PhysBase field, bits 12 ~ (MAXPHYADDR-1) - 取12 ~ (MAXPHYADDR-1) bits,補上3個0,就是組MTRR的Base Address。
  • PhysMask field, bits 12 ~ (MAXPHYADDR-1) - 一樣只取12 ~ (MAXPHYADDR-1) bits,補上3個0,再做1的補數運算,即可算出此MTRR的長度,值得注意的是長度需為2的次方。
MAXPHYADD代表是CPU的定址能力,長度依CPU而定。

下表為各種存取方式對應到MTRR的Type:
Memory Type and MnemonicEncoding in MTRR
Uncacheable (UC)00h
Write Combining (WC)01h
Reserved*02h
Reserved*03h
Write-through (WT)04h
Write-protected (WP)05h
Writeback (WB)06h
Reserved*07h ~ FFh


範例:
MTRRIndexValueType/SizeRange
Base20000000006WriteBack
Mask201F800008002048MB0 ~ 7FFFFFFF
Base20280000006WriteBack
Mask203FC00008001024MB80000000 ~ BFFFFFFF
略...
Base206D8000000Uncacheable
Mask207FF8000800128MBD8000000 ~ DFFFFFFF
Base208D7000000Uncacheable
Mask209FFF00080016MBD7000000 ~ D7FFFFFF
略...

對於MTRR所需要注意的Type有沒有設定為正確的Type,還有MTRR有沒有被塞爆,可能導致某些要使用Cache的Memory區域會因沒有宣告Cacheable,造成效能低落...等。

2011年11月17日 星期四

Memory Map

上圖擷取自Intel Spec.
以下以Intel Platfrom為例。

左圖是實體記憶體大於4 GB以上,有Remap機制。
右圖是記憶體小於4 GB,無Remap機制發生。

每張圖都有提供兩種觀點,System View與Memory Controller View。
System View為整個系統可以存取的記憶體範圍。
Memory Controller View為實際上Physical Memory的整體分布。

通常TOLUD Base ~ 4 GB這段範圍都被PCI Resource Mapping,所以這塊記憶體位置就被占據了。
因此後來發展了Remap機制,把Reclaim Base ~ Reclaim Limit這段範圍的記憶體將它Mapping至實體記憶體4 GB以下OS invisible Reclaim的位置,以便回收利用那些被PCI Resource所佔據的記憶體。
※TOLUD: Top of Lower Usable DRAM
※TOUUD: Top of Upper Usable DRAM

以下為Reclaim的Pseudo-code:
IF (ADDRESS_IN[38:20] ≥ REMAP_BASE[35:20]) AND
(ADDRESS_IN[38:20] ≤ REMAP_LIMIT[35:20]) THEN

ADDRESS_OUT[38:20] = (ADDRESS_IN[38:20] – REMAP_BASE[35:20]) +
0000000b & TOLUD[31:20]

ADDRESS_OUT[19:0] = ADDRESS_IN[19:0]

ME Base = TOM(Top of Memory,實體記憶體總量)- ME UMA Size。
Reclaim Base = MAX (4GB, ME Base) 看何者為大。
Reclaim Limit = Remap Base + (PCI Resource Total Size - 1);
TOUUD Base = Reclaim Limit + 1。
而TOLUD Base在哪裡則是要看PCI Resource整體分配了多少的空間而定,還有Physical Memory Size而定。

由於Intel Graphics本身沒有獨立的記憶體,所以它使用了Physical Memory當成自己的記憶體,所以這部分並沒有辦法Reclaim回來,可見GFX Stolen與GFX GTT Stolen這兩塊,而T SEG也佔據下面那一塊。

OS存取Reclaim Base ~ Reclaim Limit這段範圍時,它其實是將資料儲存在Physical Memory中OS invisible Reclaim這個地方。
所以支援4 GB以上Memory的OS就可以使用被PCI Resource占據的Memory。
這也是預設的情況下,Windows 32-bit的OS常常只能用到3 GB甚至以下的記憶體。