25 #if CONFIG(X86_AMD_FIXED_MTRRS)
26 #define MTRR_FIXED_WRBACK_BITS (MTRR_READ_MEM | MTRR_WRITE_MEM)
28 #define MTRR_FIXED_WRBACK_BITS 0
38 #define NUM_MTRR_STATIC_STORAGE 16
48 "MTRRs detected (%d) > NUM_MTRR_STATIC_STORAGE (%d)\n",
67 if (!
CONFIG(X86_AMD_FIXED_MTRRS))
79 if (!
CONFIG(X86_AMD_FIXED_MTRRS))
97 #define MTRR_VERBOSE_LEVEL BIOS_NEVER
100 #define RANGE_SHIFT 12
101 #define ADDR_SHIFT_TO_RANGE_SHIFT(x) \
102 (((x) > RANGE_SHIFT) ? ((x) - RANGE_SHIFT) : RANGE_SHIFT)
103 #define PHYS_TO_RANGE_ADDR(x) ((x) >> RANGE_SHIFT)
104 #define RANGE_TO_PHYS_ADDR(x) (((resource_t)(x)) << RANGE_SHIFT)
105 #define NUM_FIXED_MTRRS (NUM_FIXED_RANGES / RANGES_PER_FIXED_MTRR)
108 #define RANGE_1MB PHYS_TO_RANGE_ADDR(1ULL << 20)
109 #define RANGE_4GB (1ULL << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))
111 #define MTRR_ALGO_SHIFT (8)
112 #define MTRR_TAG_MASK ((1 << MTRR_ALGO_SHIFT) - 1)
144 const char *identifier)
156 "0x%016llx - 0x%016llx size 0x%08llx type %ld\n",
164 static struct memranges addr_space_storage;
169 if (addr_space ==
NULL) {
173 addr_space = &addr_space_storage;
232 static int fixed_mtrr_types_initialized;
241 if (fixed_mtrr_types_initialized)
274 "MTRR addr 0x%x-0x%x set to %d type @ %d\n",
285 fixed_mtrr_types_initialized = 1;
300 memset(&fixed_msrs, 0,
sizeof(fixed_msrs));
313 fixed_msrs[msr_num].
lo |=
315 fixed_msrs[msr_num].
lo |=
317 fixed_msrs[msr_num].
lo |=
319 fixed_msrs[msr_num].
lo |=
321 fixed_msrs[msr_num].
hi |=
323 fixed_msrs[msr_num].
hi |=
325 fixed_msrs[msr_num].
hi |=
327 fixed_msrs[msr_num].
hi |=
338 msr_index[i], fixed_msrs[i].hi, fixed_msrs[i].lo);
342 wrmsr(msr_index[i], fixed_msrs[i]);
388 msr_t msr = { .
lo = 0, .hi = 0 };
396 return CONFIG(RESERVE_MTRRS_FOR_OS) ? 2 : 0;
408 printk(
BIOS_ERR,
"Not enough MTRRs available! MTRR index is %d with %d MTRRs in total.\n",
429 rsize = rsize &
mask;
432 var_state->
mtrr_index, rbase, rsize, mtrr_type);
436 regs->base.lo = rbase;
437 regs->base.lo |= mtrr_type;
438 regs->base.hi = rbase >> 32;
440 regs->mask.lo = rsize;
442 regs->mask.hi = rsize >> 32;
481 size_msb =
fms64(size);
486 if (addr_lsb > size_msb)
487 mtrr_size = 1ULL << size_msb;
489 mtrr_size = 1ULL << addr_lsb;
503 const int carve_hole)
523 const int dont_care = 0;
526 unsigned int align, best_count;
534 for (align =
fls(hole) + 1; align <=
fms(hole); ++align) {
536 if (hole_end > limit)
541 &var_state,
base, hole_end -
base, dont_care);
544 &var_state, hole, hole_end - hole, dont_care);
560 int mtrr_type, carve_hole;
644 if (carve_hole && b2 != b1) {
651 int above4gb,
int address_bits,
652 int *num_def_wb_mtrrs,
int *num_def_uc_mtrrs)
654 int wb_deftype_count;
655 int uc_deftype_count;
667 wb_deftype_count = 0;
668 uc_deftype_count = 0;
700 *num_def_wb_mtrrs = wb_deftype_count;
701 *num_def_uc_mtrrs = uc_deftype_count;
707 int wb_deftype_count = 0;
708 int uc_deftype_count = 0;
714 if (wb_deftype_count > bios_mtrrs && uc_deftype_count > bios_mtrrs) {
716 "WB/UC MTRR counts: %d/%d > %d.\n",
717 wb_deftype_count, uc_deftype_count, bios_mtrrs);
721 &wb_deftype_count, &uc_deftype_count);
725 wb_deftype_count, uc_deftype_count);
727 if (wb_deftype_count < uc_deftype_count) {
773 for (i = 0; i < sol->
num_used; i++) {
798 !!above4gb, address_bits, sol);
874 const int above4gb = 1;
900 memset(&sol, 0,
sizeof(sol));
904 above4gb, address_bits, &sol);
907 printk(
BIOS_WARNING,
"Unable to insert temporary MTRR range: 0x%016llx - 0x%016llx size 0x%08llx type %d\n",
908 (
long long)begin, (
long long)begin + size - 1,
909 (
long long)size,
type);
#define SYSCFG_MSR_MtrrFixDramModEn
void * memset(void *dstpp, int c, size_t len)
#define printk(level,...)
static void prep_var_mtrr(struct var_mtrr_state *var_state, uint64_t base, uint64_t size, int mtrr_type)
static uint32_t fms64(uint64_t x)
static bool put_back_original_solution
void fixed_mtrrs_hide_amd_rwdram(void)
static uint64_t optimize_var_mtrr_hole(const uint64_t base, const uint64_t hole, const uint64_t limit, const int carve_hole)
static uint8_t fixed_mtrr_types[NUM_FIXED_RANGES]
void enable_fixed_mtrr(void)
#define MTRR_VERBOSE_LEVEL
void need_restore_mtrr(void)
void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb)
static void __calc_var_mtrrs(struct memranges *addr_space, int above4gb, int address_bits, int *num_def_wb_mtrrs, int *num_def_uc_mtrrs)
static void detect_var_mtrrs(void)
static int calc_var_mtrrs(struct memranges *addr_space, int above4gb, int address_bits)
void x86_mtrr_check(void)
static void prepare_var_mtrrs(struct memranges *addr_space, int def_type, int above4gb, int address_bits, struct var_mtrr_solution *sol)
void mtrr_use_temp_range(uintptr_t begin, size_t size, int type)
static int commit_var_mtrrs(const struct var_mtrr_solution *sol)
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, remove_temp_solution, NULL)
static uint64_t range_entry_base_mtrr_addr(struct range_entry *r)
static int get_os_reserved_mtrrs(void)
static void calc_fixed_mtrrs(void)
static void remove_temp_solution(void *unused)
void x86_setup_mtrrs_with_detect_no_above_4gb(void)
static void commit_fixed_mtrrs(void)
static int filter_vga_wrcomb(struct device *dev, struct resource *res)
#define RANGE_TO_PHYS_ADDR(x)
void x86_setup_fixed_mtrrs_no_enable(void)
static uint64_t range_entry_end_mtrr_addr(struct range_entry *r)
static int range_entry_mtrr_type(struct range_entry *r)
void x86_setup_mtrrs_with_detect(void)
static struct var_mtrr_solution mtrr_global_solution
#define MTRR_FIXED_WRBACK_BITS
#define PHYS_TO_RANGE_ADDR(x)
static void calc_var_mtrrs_with_hole(struct var_mtrr_state *var_state, struct range_entry *r)
#define NUM_MTRR_STATIC_STORAGE
static uint32_t fls64(uint64_t x)
void fixed_mtrrs_expose_amd_rwdram(void)
static void enable_var_mtrr(unsigned char deftype)
void x86_setup_mtrrs(void)
static struct memranges * get_physical_address_space(void)
static void clear_var_mtrr(int index)
static void print_physical_address_space(const struct memranges *addr_space, const char *identifier)
void x86_setup_fixed_mtrrs(void)
static void calc_var_mtrr_range(struct var_mtrr_state *var_state, uint64_t base, uint64_t size, int mtrr_type)
static void _x86_setup_mtrrs(unsigned int above4gb)
int cpu_phys_address_size(void)
static __always_inline void enable_cache(void)
static __always_inline void disable_cache(void)
static __always_inline msr_t rdmsr(unsigned int index)
static __always_inline void wrmsr(unsigned int index, msr_t msr)
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
static resource_t range_entry_base(const struct range_entry *r)
void memranges_fill_holes_up_to(struct memranges *ranges, resource_t limit, unsigned long tag)
static resource_t range_entry_end(const struct range_entry *r)
void memranges_update_tag(struct memranges *ranges, unsigned long old_tag, unsigned long new_tag)
#define memranges_each_entry(r, ranges)
static unsigned long range_entry_tag(const struct range_entry *r)
void memranges_teardown(struct memranges *ranges)
void memranges_insert(struct memranges *ranges, resource_t base, resource_t size, unsigned long tag)
#define memranges_init_empty(__ranges, __free, __num_free)
struct range_entry * memranges_next_entry(struct memranges *ranges, const struct range_entry *r)
static resource_t range_entry_size(const struct range_entry *r)
#define memranges_init(__ranges, __mask, __match, __tag)
void memranges_add_resources(struct memranges *ranges, unsigned long mask, unsigned long match, unsigned long tag)
void memranges_add_resources_filter(struct memranges *ranges, unsigned long mask, unsigned long match, unsigned long tag, memrange_filter_t filter)
#define PCI_CLASS_DISPLAY_VGA
#define IORESOURCE_CACHEABLE
#define IORESOURCE_PREFETCH
unsigned long long uint64_t
enum device_path_type type
struct range_entry * next
struct var_mtrr_regs regs[NUM_MTRR_STATIC_STORAGE]
struct memranges * addr_space
struct var_mtrr_regs * regs
static struct am335x_pinmux_regs * regs
#define MTRR_FIX_64K_00000
#define RANGES_PER_FIXED_MTRR
static unsigned int fms(unsigned int x)
#define MTRR_PHYS_BASE(reg)
static unsigned int fls(unsigned int x)
#define MTRR_PHYS_MASK(reg)
static int get_var_mtrr_count(void)
#define MTRR_DEF_TYPE_FIX_EN
#define MTRR_FIX_4K_C0000
#define MTRR_TYPE_UNCACHEABLE
#define MTRR_FIX_16K_80000
#define MTRR_DEF_TYPE_MSR
#define MTRR_PHYS_MASK_VALID