[U-Boot] [PATCH v2 22/22] x86: Add an 'mtrr' command to list and adjust MTRRs
Bin Meng
bmeng.cn at gmail.com
Sun Jan 4 05:13:31 CET 2015
On Fri, Jan 2, 2015 at 7:18 AM, Simon Glass <sjg at chromium.org> wrote:
> It is useful to be able to see the MTRR setup in U-Boot. Add a command
> to list the state of the variable MTRR registers and allow them to be
> changed.
>
> Update the documentation to list some of the available commands.
>
> This does not support fixed MTRRs as yet.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> Changes in v2:
> - Move cmd_mtrr to arch/x86/lib
> - Correct 'platform' typo
>
> arch/x86/lib/Makefile | 1 +
> arch/x86/lib/cmd_mtrr.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++
> doc/README.x86 | 18 ++++++-
> 3 files changed, 156 insertions(+), 1 deletion(-)
> create mode 100644 arch/x86/lib/cmd_mtrr.c
>
> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> index 73262d7..32d7b98 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/cmd_mtrr.c b/arch/x86/lib/cmd_mtrr.c
> new file mode 100644
> index 0000000..7e0506b
> --- /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/doc/README.x86 b/doc/README.x86
> index 5fab044..b474161 100644
> --- a/doc/README.x86
> +++ b/doc/README.x86
> @@ -110,9 +110,25 @@ be turned on. Not every device on the board is configured via devie tree, but
> more and more devices will be added as time goes by. Check out the directory
> arch/x86/dts/ for these device tree source files.
>
> +Useful Commands
> +---------------
> +
> +In keeping with the U-Boot philosophy of providing functions to check and
> +adjust internal settings, there are several x86-specific commands that may be
> +useful:
> +
> +hob - Display information about Firmware Support Package (FSP) Hand-off
> + Block. This is only available on platforms which use FSP, mostly
> + Atom.
> +iod - Display I/O memory
> +iow - Write I/O memory
> +mtrr - List and set the Memory Type Range Registers (MTRR). These are used to
> + tell the CPU whether memory is cacheable and if so the cache write
> + mode to use. U-Boot sets up some reasonable values but you can
> + adjust then with this command.
> +
> TODO List
> ---------
> -- MTRR support (for performance)
> - Audio
> - Chrome OS verified boot
> - SMI and ACPI support, to provide platform info and facilities to Linux
> --
Tested-by: Bin Meng <bmeng.cn at gmail.com>
More information about the U-Boot
mailing list