[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