1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <cpu/x86/msr.h>
6 #include <cpu/x86/mtrr.h>
9 static const char *display_mtrr_type(uint32_t type
)
12 default: return "reserved";
22 static void display_mtrr_fixed_types(msr_t msr_data
,
23 uint32_t starting_address
, uint32_t memory_size
)
25 uint32_t base_address
;
27 uint32_t next_address
;
31 type
= msr_data
.raw
& MTRR_DEF_TYPE_MASK
;
32 base_address
= starting_address
;
33 next_address
= base_address
;
34 for (index
= 0; index
< 64; index
+= 8) {
35 next_address
= starting_address
+ (memory_size
*
37 next_type
= (msr_data
.raw
>> index
) & MTRR_DEF_TYPE_MASK
;
38 if (next_type
!= type
) {
39 printk(BIOS_DEBUG
, " 0x%08x - 0x%08x: %s\n",
40 base_address
, next_address
- 1,
41 display_mtrr_type(type
));
42 base_address
= next_address
;
46 if (base_address
!= next_address
)
47 printk(BIOS_DEBUG
, " 0x%08x - 0x%08x: %s\n",
48 base_address
, next_address
- 1,
49 display_mtrr_type(type
));
52 static void display_4k_mtrr(uint32_t msr_reg
, uint32_t starting_address
,
55 const msr_t msr
= rdmsr(msr_reg
);
56 printk(BIOS_DEBUG
, "0x%016llx: %s\n", msr
.raw
, name
);
57 display_mtrr_fixed_types(msr
, starting_address
, 0x1000);
60 static void display_16k_mtrr(uint32_t msr_reg
, uint32_t starting_address
,
63 const msr_t msr
= rdmsr(msr_reg
);
64 printk(BIOS_DEBUG
, "0x%016llx: %s\n", msr
.raw
, name
);
65 display_mtrr_fixed_types(msr
, starting_address
, 0x4000);
68 static void display_64k_mtrr(void)
70 const msr_t msr
= rdmsr(MTRR_FIX_64K_00000
);
71 printk(BIOS_DEBUG
, "0x%016llx: IA32_MTRR_FIX64K_00000\n", msr
.raw
);
72 display_mtrr_fixed_types(msr
, 0, 0x10000);
75 static void display_mtrrcap(void)
77 const msr_t msr
= rdmsr(MTRR_CAP_MSR
);
79 "0x%08x%08x: IA32_MTRRCAP: %s%s%s%s%u variable MTRRs\n",
81 (msr
.lo
& MTRR_CAP_PRMRR
) ? "PRMRR, " : "",
82 (msr
.lo
& MTRR_CAP_SMRR
) ? "SMRR, " : "",
83 (msr
.lo
& MTRR_CAP_WC
) ? "WC, " : "",
84 (msr
.lo
& MTRR_CAP_FIX
) ? "FIX, " : "",
85 msr
.lo
& MTRR_CAP_VCNT
);
88 static void display_mtrr_def_type(void)
90 const msr_t msr
= rdmsr(MTRR_DEF_TYPE_MSR
);
91 printk(BIOS_DEBUG
, "0x%016llx: IA32_MTRR_DEF_TYPE:%s%s %s\n",
93 (msr
.raw
& MTRR_DEF_TYPE_EN
) ? " E," : "",
94 (msr
.raw
& MTRR_DEF_TYPE_FIX_EN
) ? " FE," : "",
95 display_mtrr_type((uint32_t)(msr
.raw
&
96 MTRR_DEF_TYPE_MASK
)));
99 static void display_variable_mtrr(int index
, uint64_t address_mask
)
101 uint64_t base_address
;
104 const msr_t msr_base
= rdmsr(MTRR_PHYS_BASE(index
));
105 const msr_t msr_mask
= rdmsr(MTRR_PHYS_MASK(index
));
107 if (msr_mask
.raw
& MTRR_PHYS_MASK_VALID
) {
108 base_address
= (msr_base
.raw
& 0xfffffffffffff000ULL
)
111 "0x%016llx: PHYBASE%d: Address = 0x%016llx, %s\n",
112 msr_base
.raw
, index
, base_address
,
113 display_mtrr_type(msr_base
.raw
& MTRR_DEF_TYPE_MASK
));
114 mask
= (msr_mask
.raw
& 0xfffffffffffff000ULL
) & address_mask
;
115 length
= (~mask
& address_mask
) + 1;
117 "0x%016llx: PHYMASK%d: Length = 0x%016llx, Valid\n",
118 msr_mask
.raw
, index
, length
);
120 printk(BIOS_DEBUG
, "0x%016llx: PHYBASE%d\n", msr_base
.raw
, index
);
121 printk(BIOS_DEBUG
, "0x%016llx: PHYMASK%d: Disabled\n",
122 msr_mask
.raw
, index
);
126 static void _display_mtrrs(void)
128 uint32_t address_bits
;
129 uint64_t address_mask
;
133 /* Display the fixed MTRRs */
135 display_mtrr_def_type();
137 display_16k_mtrr(MTRR_FIX_16K_80000
, 0x80000, "IA32_MTRR_FIX16K_80000");
138 display_16k_mtrr(MTRR_FIX_16K_A0000
, 0xa0000, "IA32_MTRR_FIX16K_A0000");
139 display_4k_mtrr(MTRR_FIX_4K_C0000
, 0xc0000, "IA32_MTRR_FIX4K_C0000");
140 display_4k_mtrr(MTRR_FIX_4K_C8000
, 0xc8000, "IA32_MTRR_FIX4K_C8000");
141 display_4k_mtrr(MTRR_FIX_4K_D0000
, 0xd0000, "IA32_MTRR_FIX4K_D0000");
142 display_4k_mtrr(MTRR_FIX_4K_D8000
, 0xd8000, "IA32_MTRR_FIX4K_D8000");
143 display_4k_mtrr(MTRR_FIX_4K_E0000
, 0xe0000, "IA32_MTRR_FIX4K_E0000");
144 display_4k_mtrr(MTRR_FIX_4K_E8000
, 0xe8000, "IA32_MTRR_FIX4K_E8000");
145 display_4k_mtrr(MTRR_FIX_4K_F0000
, 0xf0000, "IA32_MTRR_FIX4K_F0000");
146 display_4k_mtrr(MTRR_FIX_4K_F8000
, 0xf8000, "IA32_MTRR_FIX4K_F8000");
147 address_bits
= cpu_phys_address_size();
148 address_mask
= (1ULL << address_bits
) - 1;
150 /* Display the variable MTRRs */
151 variable_mtrrs
= get_var_mtrr_count();
152 for (i
= 0; i
< variable_mtrrs
; i
++)
153 display_variable_mtrr(i
, address_mask
);
156 asmlinkage
void display_mtrrs(void)
158 if (CONFIG(DISPLAY_MTRRS
))