@@ -21,9 +21,53 @@ static EFI_GUID gEfiLegacyRegion2ProtocolGuid = EFI_LEGACY_REGION2_PROTOCOL_GUID
2121#define PAM_LOCK_REG 0x80 /* Register containing PAM lock bit on newer Intel chipsets */
2222#define PAM_ENABLE 0x33 /* Value to enable read/write (0x30 for read, 0x03 for write) */
2323
24+
25+ /*
26+ * AMD MTRRs for Legacy Region
27+ * This is already here since AMD64
28+ */
29+ #define AMD_AP_MTRR_VARIABLE_BASE0 0x200
30+ #define AMD_AP_MTRR_VARIABLE_BASE6 0x20C
31+ #define AMD_AP_MTRR_FIX64k_00000 0x250
32+ #define AMD_AP_MTRR_FIX16k_80000 0x258
33+ #define AMD_AP_MTRR_FIX16k_A0000 0x259
34+ #define AMD_AP_MTRR_FIX4k_C0000 0x268
35+ #define AMD_AP_MTRR_FIX4k_C8000 0x269
36+ #define AMD_AP_MTRR_FIX4k_D0000 0x26A
37+ #define AMD_AP_MTRR_FIX4k_D8000 0x26B
38+ #define AMD_AP_MTRR_FIX4k_E0000 0x26C
39+ #define AMD_AP_MTRR_FIX4k_E8000 0x26D
40+ #define AMD_AP_MTRR_FIX4k_F0000 0x26E
41+ #define AMD_AP_MTRR_FIX4k_F8000 0x26F
42+
43+ #define AMD_MTRR_FIX64K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull
44+ #define AMD_MTRR_FIX64K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull
45+ #define AMD_MTRR_FIX64K_UC_DRAM 0x1818181818181818ull
46+ #define AMD_MTRR_FIX16K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull
47+ #define AMD_MTRR_FIX16K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull
48+ #define AMD_MTRR_FIX16K_UC_DRAM 0x1818181818181818ull
49+ #define AMD_MTRR_FIX4K_WB_DRAM 0x1E1E1E1E1E1E1E1Eull
50+ #define AMD_MTRR_FIX4K_WT_DRAM 0x1C1C1C1C1C1C1C1Cull
51+ #define AMD_MTRR_FIX4K_UC_DRAM 0x1818181818181818ull
52+
53+ #define MSR_SYS_CFG 0xC0010010ul
54+ #define SYS_CFG_MTRR_FIX_DRAM_EN (1 << 18) ///< Core::X86::Msr::SYS_CFG::MtrrFixDramEn.
55+ ///< MTRR fixed RdDram and WrDram attributes enable.
56+ #define SYS_CFG_MTRR_FIX_DRAM_MOD_EN (1 << 19) ///< Core::X86::Msr::SYS_CFG::MtrrFixDramModEn.
57+ ///< MTRR fixed RdDram and WrDram modification enable.
58+ #define SYS_CFG_MTRR_VAR_DRAM_EN (1 << 20) ///< Core::X86::Msr::SYS_CFG::MtrrVarDramEn.
59+ ///< MTRR variable DRAM enable.
60+ #define SYS_CFG_MTRR_TOM2_EN (1 << 21) ///< Core::X86::Msr::SYS_CFG::MtrrTom2En. MTRR
61+ ///< top of memory 2 enable.
62+ #define SYS_CFG_TOM2_FORCE_MEM_TYPE_WB (1 << 22) ///< Core::X86::Msr::SYS_CFG::Tom2ForceMemTypeWB.
63+ ///< top of memory 2 memory type write back.
64+
2465/* Intel PCI Vendor ID */
2566#define INTEL_VENDOR_ID 0x8086
2667
68+ /* AMD Vendor ID */
69+ #define AMD_VENDOR_ID 0x1022
70+
2771/**
2872 * Unlock BIOS memory region using the Legacy Region 2 Protocol
2973 *
@@ -155,6 +199,43 @@ int unlock_skylake_pam(void)
155199 return 0 ;
156200}
157201
202+ /**
203+ * Unlock BIOS region using fixed MTRR for AMD chipsets
204+ *
205+ * @return 0 on success, -1 on failure
206+ */
207+ int unlock_amd_mtrr (void )
208+ {
209+ uint64_t val ;
210+ printf ("Unlocking BIOS region with AMD MTRR\n" );
211+
212+ /* TODO: Investigate SMP impact */
213+ val = rdmsr (MSR_SYS_CFG );
214+ val |= SYS_CFG_MTRR_FIX_DRAM_MOD_EN ;
215+ wrmsr (MSR_SYS_CFG , val );
216+
217+ /* Set all to WB */
218+ wrmsr (AMD_AP_MTRR_FIX64k_00000 , AMD_MTRR_FIX64K_WB_DRAM );
219+ wrmsr (AMD_AP_MTRR_FIX16k_80000 , AMD_MTRR_FIX16K_WB_DRAM );
220+ /* A0000 map to UC IO */
221+ wrmsr (AMD_AP_MTRR_FIX16k_A0000 , 0x0 );
222+ wrmsr (AMD_AP_MTRR_FIX4k_C0000 , AMD_MTRR_FIX4K_WB_DRAM );
223+ wrmsr (AMD_AP_MTRR_FIX4k_C8000 , AMD_MTRR_FIX4K_WB_DRAM );
224+ wrmsr (AMD_AP_MTRR_FIX4k_D0000 , AMD_MTRR_FIX4K_WB_DRAM );
225+ wrmsr (AMD_AP_MTRR_FIX4k_D8000 , AMD_MTRR_FIX4K_WB_DRAM );
226+ wrmsr (AMD_AP_MTRR_FIX4k_E0000 , AMD_MTRR_FIX4K_WB_DRAM );
227+ wrmsr (AMD_AP_MTRR_FIX4k_E8000 , AMD_MTRR_FIX4K_WB_DRAM );
228+ wrmsr (AMD_AP_MTRR_FIX4k_F0000 , AMD_MTRR_FIX4K_WB_DRAM );
229+ wrmsr (AMD_AP_MTRR_FIX4k_F8000 , AMD_MTRR_FIX4K_WB_DRAM );
230+
231+ val = rdmsr (MSR_SYS_CFG );
232+ val &= ~SYS_CFG_MTRR_FIX_DRAM_MOD_EN ;
233+ val |= SYS_CFG_MTRR_FIX_DRAM_EN ;
234+ wrmsr (MSR_SYS_CFG , val );
235+
236+ return 0 ;
237+ }
238+
158239/**
159240 * Get information about the legacy region and display it
160241 *
@@ -276,6 +357,10 @@ int unlock_bios_region(void)
276357 break ;
277358 }
278359 break ;
360+ case AMD_VENDOR_ID :
361+ /* AMD chipsets */
362+ status = unlock_amd_mtrr ();
363+ break ;
279364 default :
280365 status = EFI_UNSUPPORTED ;
281366 printf ("Unknown chipset, unable to unlock BIOS region\n" );
0 commit comments