Skip to content

Commit af17a97

Browse files
committed
Implement unlock_region for AMD
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
1 parent 2e58add commit af17a97

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/io.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,17 @@ static inline void pciConfigWriteDWord(unsigned int bus, unsigned int slot,
242242
outl(PCI_CONFIG_DATA, data);
243243
}
244244

245+
static inline uint64_t rdmsr(uint32_t index)
246+
{
247+
uint64_t ret;
248+
asm ("rdmsr" : "=A"(ret) : "c"(index));
249+
return ret;
250+
}
251+
252+
static inline void wrmsr(uint32_t index, uint64_t val)
253+
{
254+
asm volatile ("wrmsr" : : "c"(index), "A"(val));
255+
}
256+
245257

246258
#endif

src/unlock_region.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)