coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mtrrlib.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cpu/cpu.h>
4 #include <cpu/x86/mtrr.h>
5 #include <cpu/x86/msr.h>
6 #include <console/console.h>
7 
8 /* Get first available variable MTRR.
9  * Returns var# if available, else returns -1.
10  */
12 {
13  msr_t maskm;
14  int vcnt;
15  int i;
16 
17  vcnt = get_var_mtrr_count();
18 
19  /* Identify the first var mtrr which is not valid. */
20  for (i = 0; i < vcnt; i++) {
21  maskm = rdmsr(MTRR_PHYS_MASK(i));
22  if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
23  return i;
24  }
25 
26  /* No free var mtrr. */
27  return -1;
28 }
29 
31  unsigned int reg, unsigned int base, unsigned int size, unsigned int type)
32 {
33  /* Bit 32-35 of MTRRphysMask should be set to 1 */
34  /* FIXME: It only support 4G less range */
35  msr_t basem, maskm;
36 
37  if (!IS_POWER_OF_2(size))
38  printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size);
39  if (size < 4 * KiB)
40  printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size);
41  if (base % size != 0)
42  printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base,
43  size);
44 
45  basem.lo = base | type;
46  basem.hi = 0;
47  wrmsr(MTRR_PHYS_BASE(reg), basem);
48  maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
49  maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1;
50  wrmsr(MTRR_PHYS_MASK(reg), maskm);
51 }
52 
54 {
55  msr_t mtrr = {0, 0};
56  int vcnt;
57  int i;
58 
59  vcnt = get_var_mtrr_count();
60 
61  for (i = 0; i < vcnt; i++) {
62  wrmsr(MTRR_PHYS_MASK(i), mtrr);
63  wrmsr(MTRR_PHYS_BASE(i), mtrr);
64  }
65 }
#define IS_POWER_OF_2(x)
Definition: helpers.h:50
#define KiB
Definition: helpers.h:75
#define printk(level,...)
Definition: stdlib.h:16
int cpu_phys_address_size(void)
Definition: cpu_common.c:46
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
static __always_inline void wrmsr(unsigned int index, msr_t msr)
Definition: msr.h:157
unsigned int type
Definition: edid.c:57
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
int get_free_var_mtrr(void)
Definition: mtrrlib.c:11
void clear_all_var_mtrr(void)
Definition: mtrrlib.c:53
void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, unsigned int type)
Definition: mtrrlib.c:30
uintptr_t base
Definition: uart.c:17
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
#define MTRR_PHYS_BASE(reg)
Definition: mtrr.h:39
#define MTRR_PHYS_MASK(reg)
Definition: mtrr.h:40
static int get_var_mtrr_count(void)
Definition: mtrr.h:105
#define MTRR_PHYS_MASK_VALID
Definition: mtrr.h:41