[PATCH 4/5] x86: Add support for more than 8 MTRRs
Simon Glass
sjg at chromium.org
Sun Sep 20 17:49:18 CEST 2020
At present the mtrr command only support 8 MTRRs. Some SoCs have more than
that. Update the implementation to support up to 10. Read the number of
MTRRs dynamically instead.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
arch/x86/cpu/mtrr.c | 12 +++++++-----
arch/x86/include/asm/mtrr.h | 15 ++++++++++++---
cmd/x86/mtrr.c | 9 +++++----
3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 2468d88a80a..aed4c411367 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -66,9 +66,10 @@ static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
void mtrr_read_all(struct mtrr_info *info)
{
+ int reg_count = mtrr_get_var_count();
int i;
- for (i = 0; i < MTRR_COUNT; i++) {
+ for (i = 0; i < reg_count; i++) {
info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
}
@@ -76,10 +77,11 @@ void mtrr_read_all(struct mtrr_info *info)
void mtrr_write_all(struct mtrr_info *info)
{
+ int reg_count = mtrr_get_var_count();
struct mtrr_state state;
int i;
- for (i = 0; i < MTRR_COUNT; i++) {
+ for (i = 0; i < reg_count; i++) {
mtrr_open(&state, true);
wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
@@ -144,7 +146,7 @@ int mtrr_commit(bool do_caches)
/* Clear the ones that are unused */
debug("clear\n");
- for (; i < MTRR_COUNT; i++)
+ for (; i < MTRR_MAX_COUNT; i++)
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
debug("close\n");
mtrr_close(&state, do_caches);
@@ -184,7 +186,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
return 0;
}
-static int get_var_mtrr_count(void)
+int mtrr_get_var_count(void)
{
return msr_read(MSR_MTRR_CAP_MSR).lo & MSR_MTRR_CAP_VCNT;
}
@@ -195,7 +197,7 @@ static int get_free_var_mtrr(void)
int vcnt;
int i;
- vcnt = get_var_mtrr_count();
+ vcnt = mtrr_get_var_count();
/* Identify the first var mtrr which is not valid */
for (i = 0; i < vcnt; i++) {
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 48db1dd82f7..3a98aacdef5 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -36,8 +36,8 @@
#define MTRR_BASE_TYPE_MASK 0x7
-/* Number of MTRRs supported */
-#define MTRR_COUNT 8
+/* Maximum number of MTRRs supported - see also mtrr_get_var_count() */
+#define MTRR_MAX_COUNT 10
#define NUM_FIXED_MTRRS 11
#define RANGES_PER_FIXED_MTRR 8
@@ -87,7 +87,7 @@ struct mtrr {
* @mtrr: Information about each mtrr
*/
struct mtrr_info {
- struct mtrr mtrr[MTRR_COUNT];
+ struct mtrr mtrr[MTRR_MAX_COUNT];
};
/**
@@ -180,6 +180,15 @@ int mtrr_set_valid(int cpu_select, int reg, bool valid);
*/
int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
+/**
+ * mtrr_get_var_count() - Get the number of variable MTRRs
+ *
+ * Some CPUs have more than 8 MTRRs. This function returns the actual number
+ *
+ * @return number of variable MTRRs
+ */
+int mtrr_get_var_count(void);
+
#endif
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 99efecb9d8e..fc61a549b02 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -27,7 +27,7 @@ static void read_mtrrs(void *arg)
mtrr_read_all(info);
}
-static int do_mtrr_list(int cpu_select)
+static int do_mtrr_list(int reg_count, int cpu_select)
{
struct mtrr_info info;
int ret;
@@ -39,7 +39,7 @@ static int do_mtrr_list(int cpu_select)
ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
if (ret)
return log_msg_ret("run", ret);
- for (i = 0; i < MTRR_COUNT; i++) {
+ for (i = 0; i < reg_count; i++) {
const char *type = "Invalid";
uint64_t base, mask, size;
bool valid;
@@ -98,6 +98,7 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
+ int reg_count = mtrr_get_var_count();
int cmd;
int cpu_select;
uint reg;
@@ -126,7 +127,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc < 2)
return CMD_RET_USAGE;
reg = simple_strtoul(argv[1], NULL, 16);
- if (reg >= MTRR_COUNT) {
+ if (reg >= reg_count) {
printf("Invalid register number\n");
return CMD_RET_USAGE;
}
@@ -145,7 +146,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
if (!first)
printf("\n");
printf("CPU %d:\n", i);
- ret = do_mtrr_list(i);
+ ret = do_mtrr_list(reg_count, i);
if (ret) {
printf("Failed to read CPU %d (err=%d)\n", i,
ret);
--
2.28.0.681.g6f77f65b4e-goog
More information about the U-Boot
mailing list