diff options
author | Simon Glass <sjg@chromium.org> | 2018-10-01 12:22:37 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2018-10-09 04:40:27 -0600 |
commit | 590cee8315e94e729493d2ecd8a604bcfbfa7d0e (patch) | |
tree | 2ac3eacb5e1a1274da1efd3fe34a893d8d978d65 /arch/x86 | |
parent | 6f1c0430e88396abc8e6a91ab3cc78882c76cb7c (diff) | |
download | u-boot-590cee8315e94e729493d2ecd8a604bcfbfa7d0e.zip u-boot-590cee8315e94e729493d2ecd8a604bcfbfa7d0e.tar.gz u-boot-590cee8315e94e729493d2ecd8a604bcfbfa7d0e.tar.bz2 |
x86: Update mtrr functions to allow leaving cache alone
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@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/cpu/coreboot/coreboot.c | 4 | ||||
-rw-r--r-- | arch/x86/cpu/mtrr.c | 31 | ||||
-rw-r--r-- | arch/x86/include/asm/mtrr.h | 6 |
3 files changed, 29 insertions, 12 deletions
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c index a6fd3a8..aaf0d07 100644 --- a/arch/x86/cpu/coreboot/coreboot.c +++ b/arch/x86/cpu/coreboot/coreboot.c @@ -55,10 +55,10 @@ static void board_final_cleanup(void) if (top_type == MTRR_TYPE_WRPROT) { struct mtrr_state state; - mtrr_open(&state); + mtrr_open(&state, true); wrmsrl(MTRR_PHYS_BASE_MSR(top_mtrr), 0); wrmsrl(MTRR_PHYS_MASK_MSR(top_mtrr), 0); - mtrr_close(&state); + mtrr_close(&state, true); } if (!fdtdec_get_config_bool(gd->fdt_blob, "u-boot,no-apm-finalize")) { diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c index 3094006..0939736 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 05cd7b7..2d897f8 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 |