coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
earlymtrr.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>
8 
9 void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
10 {
11  ctx->upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
13  ctx->used_var_mtrrs = 0;
14  ctx->arg = arg;
15 }
16 
17 int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size,
18  int type, void (*callback)(const struct var_mtrr_context *ctx,
19  uintptr_t base_addr, size_t size,
20  msr_t base, msr_t mask))
21 {
22  /* Utilize additional MTRRs if the specified size is greater than the
23  base address alignment. */
24  while (size != 0) {
25  uint32_t addr_lsb;
26  uint32_t size_msb;
27  uint32_t mtrr_size;
28  msr_t base;
29  msr_t mask;
30 
31  if (ctx->used_var_mtrrs >= ctx->max_var_mtrrs) {
32  printk(BIOS_ERR, "No more variable MTRRs: %d\n",
33  ctx->max_var_mtrrs);
34  return -1;
35  }
36 
37  addr_lsb = fls(addr);
38  size_msb = fms(size);
39 
40  /* All MTRR entries need to have their base aligned to the mask
41  size. The maximum size is calculated by a function of the
42  min base bit set and maximum size bit set. */
43  if (addr_lsb > size_msb)
44  mtrr_size = 1 << size_msb;
45  else
46  mtrr_size = 1 << addr_lsb;
47 
48  base.hi = (uint64_t)addr >> 32;
49  base.lo = addr | type;
50  mask.hi = ctx->upper_mask;
51  mask.lo = ~(mtrr_size - 1) | MTRR_PHYS_MASK_VALID;
52  callback(ctx, addr, mtrr_size, base, mask);
53  ctx->used_var_mtrrs++;
54 
55  size -= mtrr_size;
56  addr += mtrr_size;
57  }
58 
59  return 0;
60 }
61 
62 static void set_mtrr(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size,
64 {
65  int i = var_mtrr_context_current_mtrr(ctx);
66 
69 }
70 
71 int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
72 {
73  return var_mtrr_set_with_cb(ctx, addr, size, type, set_mtrr);
74 }
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
int cpu_phys_address_size(void)
Definition: cpu_common.c:46
void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
Definition: earlymtrr.c:9
static void set_mtrr(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size, msr_t base, msr_t mask)
Definition: earlymtrr.c:62
int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type, void(*callback)(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size, msr_t base, msr_t mask))
Definition: earlymtrr.c:17
int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
Definition: earlymtrr.c:71
static __always_inline void wrmsr(unsigned int index, msr_t msr)
Definition: msr.h:157
struct bootblock_arg arg
Definition: decompressor.c:22
unsigned int type
Definition: edid.c:57
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
uintptr_t base
Definition: uart.c:17
static const int mask[4]
Definition: gpio.c:308
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
int max_var_mtrrs
Definition: mtrr.h:123
void * arg
Definition: mtrr.h:125
int used_var_mtrrs
Definition: mtrr.h:124
uint32_t upper_mask
Definition: mtrr.h:122
static unsigned int fms(unsigned int x)
Definition: mtrr.h:156
#define MTRR_PHYS_BASE(reg)
Definition: mtrr.h:39
static unsigned int fls(unsigned int x)
Definition: mtrr.h:168
#define MTRR_PHYS_MASK(reg)
Definition: mtrr.h:40
static int get_var_mtrr_count(void)
Definition: mtrr.h:105
static int var_mtrr_context_current_mtrr(const struct var_mtrr_context *ctx)
Definition: mtrr.h:130
#define MTRR_PHYS_MASK_VALID
Definition: mtrr.h:41