summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2015-01-22 11:29:41 +0800
committerSimon Glass <sjg@chromium.org>2015-01-23 17:24:55 -0700
commit3b621ccabdccb34891bb58865a9654a09c2b7279 (patch)
tree8c9321d4657a4154867bd77d92d4d5dad851dbc3
parent49491669065c1c718d8dc0b0ebc151b3d010c17b (diff)
downloadu-boot-imx-3b621ccabdccb34891bb58865a9654a09c2b7279.zip
u-boot-imx-3b621ccabdccb34891bb58865a9654a09c2b7279.tar.gz
u-boot-imx-3b621ccabdccb34891bb58865a9654a09c2b7279.tar.bz2
x86: Test mtrr support flag before accessing mtrr msr
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>
-rw-r--r--arch/x86/cpu/mtrr.c12
-rw-r--r--arch/x86/include/asm/mtrr.h5
-rw-r--r--arch/x86/lib/init_helpers.c4
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) */