mirror of
https://github.com/linux-sunxi/u-boot-sunxi.git
synced 2024-02-12 11:16:03 +08:00
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>
This commit is contained in:
@ -55,10 +55,10 @@ static void board_final_cleanup(void)
|
|||||||
if (top_type == MTRR_TYPE_WRPROT) {
|
if (top_type == MTRR_TYPE_WRPROT) {
|
||||||
struct mtrr_state state;
|
struct mtrr_state state;
|
||||||
|
|
||||||
mtrr_open(&state);
|
mtrr_open(&state, true);
|
||||||
wrmsrl(MTRR_PHYS_BASE_MSR(top_mtrr), 0);
|
wrmsrl(MTRR_PHYS_BASE_MSR(top_mtrr), 0);
|
||||||
wrmsrl(MTRR_PHYS_MASK_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")) {
|
if (!fdtdec_get_config_bool(gd->fdt_blob, "u-boot,no-apm-finalize")) {
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
* System Programming
|
* 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 <common.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
@ -19,27 +24,29 @@
|
|||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/* Prepare to adjust MTRRs */
|
/* 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)
|
if (!gd->arch.has_mtrr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
state->enable_cache = dcache_status();
|
if (do_caches) {
|
||||||
|
state->enable_cache = dcache_status();
|
||||||
|
|
||||||
if (state->enable_cache)
|
if (state->enable_cache)
|
||||||
disable_caches();
|
disable_caches();
|
||||||
|
}
|
||||||
state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
|
state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
|
||||||
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
|
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up after adjusting MTRRs, and enable them */
|
/* 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)
|
if (!gd->arch.has_mtrr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
|
wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
|
||||||
if (state->enable_cache)
|
if (do_caches && state->enable_cache)
|
||||||
enable_caches();
|
enable_caches();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,10 +57,14 @@ int mtrr_commit(bool do_caches)
|
|||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
|
||||||
|
gd->arch.mtrr_req_count);
|
||||||
if (!gd->arch.has_mtrr)
|
if (!gd->arch.has_mtrr)
|
||||||
return -ENOSYS;
|
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++) {
|
for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
|
||||||
mask = ~(req->size - 1);
|
mask = ~(req->size - 1);
|
||||||
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
||||||
@ -62,9 +73,12 @@ int mtrr_commit(bool do_caches)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the ones that are unused */
|
/* Clear the ones that are unused */
|
||||||
|
debug("clear\n");
|
||||||
for (; i < MTRR_COUNT; i++)
|
for (; i < MTRR_COUNT; i++)
|
||||||
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
|
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
|
||||||
mtrr_close(&state);
|
debug("close\n");
|
||||||
|
mtrr_close(&state, do_caches);
|
||||||
|
debug("mtrr done\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -74,6 +88,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
|
|||||||
struct mtrr_request *req;
|
struct mtrr_request *req;
|
||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
|
|
||||||
|
debug("%s: count=%d\n", __func__, gd->arch.mtrr_req_count);
|
||||||
if (!gd->arch.has_mtrr)
|
if (!gd->arch.has_mtrr)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
|
@ -77,8 +77,9 @@ struct mtrr_state {
|
|||||||
* possibly the cache.
|
* possibly the cache.
|
||||||
*
|
*
|
||||||
* @state: Empty structure to pass in to hold settings
|
* @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
|
* 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().
|
* This uses the structure containing information returned from mtrr_open().
|
||||||
*
|
*
|
||||||
* @state: Structure 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
|
* mtrr_add_request() - Add a new MTRR request
|
||||||
|
@ -73,10 +73,10 @@ static int do_mtrr_set(uint reg, int argc, char * const argv[])
|
|||||||
mask |= MTRR_PHYS_MASK_VALID;
|
mask |= MTRR_PHYS_MASK_VALID;
|
||||||
|
|
||||||
printf("base=%llx, mask=%llx\n", base, mask);
|
printf("base=%llx, mask=%llx\n", base, mask);
|
||||||
mtrr_open(&state);
|
mtrr_open(&state, true);
|
||||||
wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
|
wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
|
||||||
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
||||||
mtrr_close(&state);
|
mtrr_close(&state, true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -86,14 +86,14 @@ static int mtrr_set_valid(int reg, bool valid)
|
|||||||
struct mtrr_state state;
|
struct mtrr_state state;
|
||||||
uint64_t mask;
|
uint64_t mask;
|
||||||
|
|
||||||
mtrr_open(&state);
|
mtrr_open(&state, true);
|
||||||
mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
|
mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
|
||||||
if (valid)
|
if (valid)
|
||||||
mask |= MTRR_PHYS_MASK_VALID;
|
mask |= MTRR_PHYS_MASK_VALID;
|
||||||
else
|
else
|
||||||
mask &= ~MTRR_PHYS_MASK_VALID;
|
mask &= ~MTRR_PHYS_MASK_VALID;
|
||||||
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
|
||||||
mtrr_close(&state);
|
mtrr_close(&state, true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user