diff options
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/lib/bios.c | 14 | ||||
-rw-r--r-- | arch/x86/lib/cmd_hob.c | 18 | ||||
-rw-r--r-- | arch/x86/lib/cmd_mtrr.c | 138 | ||||
-rw-r--r-- | arch/x86/lib/init_helpers.c | 8 | ||||
-rw-r--r-- | arch/x86/lib/tsc_timer.c | 8 |
6 files changed, 170 insertions, 17 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 73262d7263..32d7b98fa6 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_HAVE_FSP) += cmd_hob.o obj-y += gcc.o obj-y += init_helpers.o obj-y += interrupts.o +obj-y += cmd_mtrr.o obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o obj-$(CONFIG_PCI) += pci_type1.o diff --git a/arch/x86/lib/bios.c b/arch/x86/lib/bios.c index d1f8933e12..1d75cfc263 100644 --- a/arch/x86/lib/bios.c +++ b/arch/x86/lib/bios.c @@ -207,12 +207,14 @@ static u8 vbe_get_mode_info(struct vbe_mode_info *mi) static u8 vbe_set_mode(struct vbe_mode_info *mi) { - debug("VBE: Setting VESA mode %#04x\n", mi->video_mode); + int video_mode = mi->video_mode; + + debug("VBE: Setting VESA mode %#04x\n", video_mode); /* request linear framebuffer mode */ - mi->video_mode |= (1 << 14); - /* request clearing of framebuffer */ - mi->video_mode &= ~(1 << 15); - realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode, + video_mode |= (1 << 14); + /* don't clear the framebuffer, we do that later */ + video_mode |= (1 << 15); + realmode_interrupt(0x10, VESA_SET_MODE, video_mode, 0x0000, 0x0000, 0x0000, 0x0000); return 0; @@ -236,6 +238,7 @@ static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info) return; } + mode_info->video_mode &= 0x3ff; vbe_set_mode(mode_info); } @@ -262,7 +265,6 @@ void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode, /* Make sure the code is placed. */ setup_realmode_code(); - disable_caches(); debug("Calling Option ROM at %lx, pci device %#x...", addr, num_dev); /* Option ROM entry point is at OPROM start + 3 */ diff --git a/arch/x86/lib/cmd_hob.c b/arch/x86/lib/cmd_hob.c index b552fe6c1b..a0ef037da1 100644 --- a/arch/x86/lib/cmd_hob.c +++ b/arch/x86/lib/cmd_hob.c @@ -28,20 +28,20 @@ static char *hob_type[] = { int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - union hob_pointers hob; - u16 type; + const struct hob_header *hdr; + uint type; char *desc; int i = 0; - hob.raw = (u8 *)gd->arch.hob_list; + hdr = gd->arch.hob_list; - printf("HOB list address: 0x%08x\n\n", (unsigned int)hob.raw); + printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr); printf("No. | Address | Type | Length in Bytes\n"); printf("----|----------|---------------------|----------------\n"); - while (!end_of_hob(hob)) { - printf("%-3d | %08x | ", i, (unsigned int)hob.raw); - type = get_hob_type(hob); + while (!end_of_hob(hdr)) { + printf("%-3d | %08x | ", i, (unsigned int)hdr); + type = hdr->type; if (type == HOB_TYPE_UNUSED) desc = "*Unused*"; else if (type == HOB_TYPE_EOH) @@ -50,8 +50,8 @@ int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) desc = hob_type[type]; else desc = "*Invalid Type*"; - printf("%-19s | %-15d\n", desc, get_hob_length(hob)); - hob.raw = get_next_hob(hob); + printf("%-19s | %-15d\n", desc, hdr->len); + hdr = get_next_hob(hdr); i++; } diff --git a/arch/x86/lib/cmd_mtrr.c b/arch/x86/lib/cmd_mtrr.c new file mode 100644 index 0000000000..7e0506b75d --- /dev/null +++ b/arch/x86/lib/cmd_mtrr.c @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/msr.h> +#include <asm/mtrr.h> + +static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = { + "Uncacheable", + "Combine", + "2", + "3", + "Through", + "Protect", + "Back", +}; + +static int do_mtrr_list(void) +{ + int i; + + printf("Reg Valid Write-type %-16s %-16s %-16s\n", "Base ||", + "Mask ||", "Size ||"); + for (i = 0; i < MTRR_COUNT; i++) { + const char *type = "Invalid"; + uint64_t base, mask, size; + bool valid; + + base = native_read_msr(MTRR_PHYS_BASE_MSR(i)); + mask = native_read_msr(MTRR_PHYS_MASK_MSR(i)); + size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1); + size |= (1 << 12) - 1; + size += 1; + valid = mask & MTRR_PHYS_MASK_VALID; + type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK]; + printf("%d %-5s %-12s %016llx %016llx %016llx\n", i, + valid ? "Y" : "N", type, base, mask, size); + } + + return 0; +} + +static int do_mtrr_set(uint reg, int argc, char * const argv[]) +{ + const char *typename = argv[0]; + struct mtrr_state state; + uint32_t start, size; + uint64_t base, mask; + int i, type = -1; + bool valid; + + if (argc < 3) + return CMD_RET_USAGE; + for (i = 0; i < MTRR_TYPE_COUNT; i++) { + if (*typename == *mtrr_type_name[i]) + type = i; + } + if (type == -1) { + printf("Invalid type name %s\n", typename); + return CMD_RET_USAGE; + } + start = simple_strtoul(argv[1], NULL, 16); + size = simple_strtoul(argv[2], NULL, 16); + + base = start | type; + valid = native_read_msr(MTRR_PHYS_MASK_MSR(reg)) & MTRR_PHYS_MASK_VALID; + mask = ~((uint64_t)size - 1); + mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1; + if (valid) + mask |= MTRR_PHYS_MASK_VALID; + + printf("base=%llx, mask=%llx\n", base, mask); + mtrr_open(&state); + wrmsrl(MTRR_PHYS_BASE_MSR(reg), base); + wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask); + mtrr_close(&state); + + return 0; +} + +static int mtrr_set_valid(int reg, bool valid) +{ + struct mtrr_state state; + uint64_t mask; + + mtrr_open(&state); + mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg)); + if (valid) + mask |= MTRR_PHYS_MASK_VALID; + else + mask &= ~MTRR_PHYS_MASK_VALID; + wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask); + mtrr_close(&state); + + return 0; +} + +static int do_mtrr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *cmd; + uint reg; + + cmd = argv[1]; + if (argc < 2 || *cmd == 'l') + return do_mtrr_list(); + argc -= 2; + argv += 2; + if (argc <= 0) + return CMD_RET_USAGE; + reg = simple_strtoul(argv[0], NULL, 16); + if (reg >= MTRR_COUNT) { + printf("Invalid register number\n"); + return CMD_RET_USAGE; + } + if (*cmd == 'e') + return mtrr_set_valid(reg, true); + else if (*cmd == 'd') + return mtrr_set_valid(reg, false); + else if (*cmd == 's') + return do_mtrr_set(reg, argc - 1, argv + 1); + else + return CMD_RET_USAGE; + + return 0; +} + +U_BOOT_CMD( + mtrr, 6, 1, do_mtrr, + "Use x86 memory type range registers (32-bit only)", + "[list] - list current registers\n" + "set <reg> <type> <start> <size> - set a register\n" + "\t<type> is Uncacheable, Combine, Through, Protect, Back\n" + "disable <reg> - disable a register\n" + "ensable <reg> - enable a register" +); diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index be4eb12c53..fc211d9d5c 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -7,6 +7,7 @@ #include <common.h> #include <fdtdec.h> #include <spi.h> +#include <asm/mtrr.h> #include <asm/sections.h> DECLARE_GLOBAL_DATA_PTR; @@ -66,6 +67,13 @@ int calculate_relocation_address(void) int init_cache_f_r(void) { +#if defined(CONFIG_X86_RESET_VECTOR) & !defined(CONFIG_HAVE_FSP) + int ret; + + ret = mtrr_commit(false); + if (ret) + return ret; +#endif /* Initialise the CPU cache(s) */ return init_cache(); } diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index fb9afed18f..7f5ba2ca6f 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -78,7 +78,7 @@ static int match_cpu(u8 family, u8 model) * * Returns the calibration value or 0 if MSR calibration failed. */ -static unsigned long try_msr_calibrate_tsc(void) +static unsigned long __maybe_unused try_msr_calibrate_tsc(void) { u32 lo, hi, ratio, freq_id, freq; unsigned long res; @@ -199,7 +199,7 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp, #define MAX_QUICK_PIT_MS 50 #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) -static unsigned long quick_pit_calibrate(void) +static unsigned long __maybe_unused quick_pit_calibrate(void) { int i; u64 tsc, delta; @@ -306,6 +306,9 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void) if (gd->arch.tsc_mhz) return gd->arch.tsc_mhz; +#ifdef CONFIG_TSC_CALIBRATION_BYPASS + fast_calibrate = CONFIG_TSC_FREQ_IN_MHZ; +#else fast_calibrate = try_msr_calibrate_tsc(); if (!fast_calibrate) { @@ -313,6 +316,7 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void) if (!fast_calibrate) panic("TSC frequency is ZERO"); } +#endif gd->arch.tsc_mhz = fast_calibrate; return fast_calibrate; |