[U-Boot] [PATCH v2 3/3] x86: Test mtrr support flag before accessing mtrr msr

Bin Meng bmeng.cn at gmail.com
Thu Jan 22 04:29:41 CET 2015


On some x86 processors (like Intel Quark) the MTRR registers are not
supported. This is reflected by the CPUID (EAX 01H) result EDX[12].
Accessing the MTRR registers on such processors will cause #GP so we
must test the support flag before accessing MTRR MSRs.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>

---

Changes in v2:
- Return -ENOSYS in mtrr_commit() and mtrr_add_request() when MTRR MSR
  is not implemented in the processor
- Add return value description of mtrr_commit() and mtrr_add_request()
- Ignore -ENOSYS in init_cache_f_r() in arch/x86/lib/init_helpers.c

 arch/x86/cpu/mtrr.c         | 12 ++++++++++++
 arch/x86/include/asm/mtrr.h |  5 ++++-
 arch/x86/lib/init_helpers.c |  4 +++-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index ac8765f..5d36b3e 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -22,6 +22,9 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Prepare to adjust MTRRs */
 void mtrr_open(struct mtrr_state *state)
 {
+	if (!gd->arch.has_mtrr)
+		return;
+
 	state->enable_cache = dcache_status();
 
 	if (state->enable_cache)
@@ -33,6 +36,9 @@ void mtrr_open(struct mtrr_state *state)
 /* Clean up after adjusting MTRRs, and enable them */
 void mtrr_close(struct mtrr_state *state)
 {
+	if (!gd->arch.has_mtrr)
+		return;
+
 	wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
 	if (state->enable_cache)
 		enable_caches();
@@ -45,6 +51,9 @@ int mtrr_commit(bool do_caches)
 	uint64_t mask;
 	int i;
 
+	if (!gd->arch.has_mtrr)
+		return -ENOSYS;
+
 	mtrr_open(&state);
 	for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
 		mask = ~(req->size - 1);
@@ -66,6 +75,9 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
 	struct mtrr_request *req;
 	uint64_t mask;
 
+	if (!gd->arch.has_mtrr)
+		return -ENOSYS;
+
 	if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
 		return -ENOSPC;
 	req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++];
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 3c11740..fda4eae 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -65,7 +65,6 @@ void mtrr_open(struct mtrr_state *state);
  *
  * @state:	Structure from mtrr_open()
  */
-/*  */
 void mtrr_close(struct mtrr_state *state);
 
 /**
@@ -76,6 +75,8 @@ void mtrr_close(struct mtrr_state *state);
  * @type:	Requested type (MTRR_TYPE_)
  * @start:	Start address
  * @size:	Size
+ *
+ * @return:	0 on success, non-zero on failure
  */
 int mtrr_add_request(int type, uint64_t start, uint64_t size);
 
@@ -86,6 +87,8 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size);
  * It must be called with caches disabled.
  *
  * @do_caches:	true if caches are currently on
+ *
+ * @return:	0 on success, non-zero on failure
  */
 int mtrr_commit(bool do_caches);
 
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index fc211d9..5097ca2 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/errno.h>
 #include <asm/mtrr.h>
 #include <asm/sections.h>
 
@@ -71,7 +72,8 @@ int init_cache_f_r(void)
 	int ret;
 
 	ret = mtrr_commit(false);
-	if (ret)
+	/* If MTRR MSR is not implemented by the processor, just ignore it */
+	if (ret && ret != -ENOSYS)
 		return ret;
 #endif
 	/* Initialise the CPU cache(s) */
-- 
1.8.2.1



More information about the U-Boot mailing list