Merge branch 'master' of git://git.denx.de/u-boot-net
[platform/kernel/u-boot.git] / arch / x86 / cpu / mtrr.c
index ac8765f..0939736 100644 (file)
@@ -1,8 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2014 Google, Inc
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * Memory Type Range Regsters - these are used to tell the CPU whether
  * memory is cacheable and if so the cache write mode to use.
  *
  * 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>
 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)
 {
-       state->enable_cache = dcache_status();
+       if (!gd->arch.has_mtrr)
+               return;
+
+       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();
 }
 
@@ -45,7 +57,14 @@ int mtrr_commit(bool do_caches)
        uint64_t mask;
        int i;
 
-       mtrr_open(&state);
+       debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
+             gd->arch.mtrr_req_count);
+       if (!gd->arch.has_mtrr)
+               return -ENOSYS;
+
+       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;
@@ -54,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;
 }
@@ -66,6 +88,10 @@ 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;
+
        if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
                return -ENOSPC;
        req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++];