x86: Test mtrr support flag before accessing mtrr msr
authorBin Meng <bmeng.cn@gmail.com>
Thu, 22 Jan 2015 03:29:41 +0000 (11:29 +0800)
committerSimon Glass <sjg@chromium.org>
Sat, 24 Jan 2015 00:24:55 +0000 (17:24 -0700)
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@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/mtrr.c
arch/x86/include/asm/mtrr.h
arch/x86/lib/init_helpers.c

index ac8765f3cf2e17ece077f9463c9838c697793b9c..5d36b3e0204d63cd9a15d2829cd9c96d48100fe2 100644 (file)
@@ -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++];
index 3c1174043cf6f1c62c60db6cdce5d13ec6d887b3..fda4eae10d8f1262a67ed46aae5e6656b679bba2 100644 (file)
@@ -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);
 
index fc211d9d5c4924e6ed924154777e534c60177322..5097ca274a147f0965fc0935db69301945bc092a 100644 (file)
@@ -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) */