[U-Boot] [PATCH 33/45] x86: Update mtrr functions to allow leaving cache alone

Simon Glass sjg at chromium.org
Mon Oct 1 18:22:37 UTC 2018


At present the mtrr functions disable the cache before making changes and
enable it again afterwards. This is fine in U-Boot, but does not work if
running in CAR (such as we are in SPL).

Update the functions so that the caller can request that caches be left
alone.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 arch/x86/cpu/mtrr.c         | 31 +++++++++++++++++++++++--------
 arch/x86/include/asm/mtrr.h |  6 ++++--
 cmd/x86/mtrr.c              |  8 ++++----
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 30940065621..0939736164d 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -11,6 +11,11 @@
  * System Programming
  */
 
+/*
+ * Note that any console output (e.g. debug()) in this file will likely fail
+ * since the MTRR registers are sometimes in flux.
+ */
+
 #include <common.h>
 #include <asm/io.h>
 #include <asm/msr.h>
@@ -19,27 +24,29 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /* Prepare to adjust MTRRs */
-void mtrr_open(struct mtrr_state *state)
+void mtrr_open(struct mtrr_state *state, bool do_caches)
 {
 	if (!gd->arch.has_mtrr)
 		return;
 
-	state->enable_cache = dcache_status();
+	if (do_caches) {
+		state->enable_cache = dcache_status();
 
-	if (state->enable_cache)
-		disable_caches();
+		if (state->enable_cache)
+			disable_caches();
+	}
 	state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
 	wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
 }
 
 /* Clean up after adjusting MTRRs, and enable them */
-void mtrr_close(struct mtrr_state *state)
+void mtrr_close(struct mtrr_state *state, bool do_caches)
 {
 	if (!gd->arch.has_mtrr)
 		return;
 
 	wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
-	if (state->enable_cache)
+	if (do_caches && state->enable_cache)
 		enable_caches();
 }
 
@@ -50,10 +57,14 @@ int mtrr_commit(bool do_caches)
 	uint64_t mask;
 	int i;
 
+	debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
+	      gd->arch.mtrr_req_count);
 	if (!gd->arch.has_mtrr)
 		return -ENOSYS;
 
-	mtrr_open(&state);
+	debug("open\n");
+	mtrr_open(&state, do_caches);
+	debug("open done\n");
 	for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
 		mask = ~(req->size - 1);
 		mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
@@ -62,9 +73,12 @@ int mtrr_commit(bool do_caches)
 	}
 
 	/* Clear the ones that are unused */
+	debug("clear\n");
 	for (; i < MTRR_COUNT; i++)
 		wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
-	mtrr_close(&state);
+	debug("close\n");
+	mtrr_close(&state, do_caches);
+	debug("mtrr done\n");
 
 	return 0;
 }
@@ -74,6 +88,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
 	struct mtrr_request *req;
 	uint64_t mask;
 
+	debug("%s: count=%d\n", __func__, gd->arch.mtrr_req_count);
 	if (!gd->arch.has_mtrr)
 		return -ENOSYS;
 
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 05cd7b7f17b..2d897f82ef7 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -77,8 +77,9 @@ struct mtrr_state {
  * possibly the cache.
  *
  * @state:	Empty structure to pass in to hold settings
+ * @do_caches:	true to disable caches before opening
  */
-void mtrr_open(struct mtrr_state *state);
+void mtrr_open(struct mtrr_state *state, bool do_caches);
 
 /**
  * mtrr_open() - Clean up after adjusting MTRRs, and enable them
@@ -86,8 +87,9 @@ void mtrr_open(struct mtrr_state *state);
  * This uses the structure containing information returned from mtrr_open().
  *
  * @state:	Structure from mtrr_open()
+ * @state:	true to restore cache state to that before mtrr_open()
  */
-void mtrr_close(struct mtrr_state *state);
+void mtrr_close(struct mtrr_state *state, bool do_caches);
 
 /**
  * mtrr_add_request() - Add a new MTRR request
diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
index 70f373a72a5..d3fd959235f 100644
--- a/cmd/x86/mtrr.c
+++ b/cmd/x86/mtrr.c
@@ -73,10 +73,10 @@ static int do_mtrr_set(uint reg, int argc, char * const argv[])
 		mask |= MTRR_PHYS_MASK_VALID;
 
 	printf("base=%llx, mask=%llx\n", base, mask);
-	mtrr_open(&state);
+	mtrr_open(&state, true);
 	wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
 	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
-	mtrr_close(&state);
+	mtrr_close(&state, true);
 
 	return 0;
 }
@@ -86,14 +86,14 @@ static int mtrr_set_valid(int reg, bool valid)
 	struct mtrr_state state;
 	uint64_t mask;
 
-	mtrr_open(&state);
+	mtrr_open(&state, true);
 	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);
+	mtrr_close(&state, true);
 
 	return 0;
 }
-- 
2.19.0.605.g01d371f741-goog



More information about the U-Boot mailing list