mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-30 08:30:50 +09:00
x86: Add support for more than 8 MTRRs
At present the mtrr command only support 8 MTRRs. Some SoCs have more than that. Update the implementation to support up to 10. Read the number of MTRRs dynamically instead. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
51af144eb7
commit
29d2d64ed5
@ -67,9 +67,10 @@ static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
|
|||||||
|
|
||||||
void mtrr_read_all(struct mtrr_info *info)
|
void mtrr_read_all(struct mtrr_info *info)
|
||||||
{
|
{
|
||||||
|
int reg_count = mtrr_get_var_count();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MTRR_COUNT; i++) {
|
for (i = 0; i < reg_count; i++) {
|
||||||
info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
|
info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
|
||||||
info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
|
info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
|
||||||
}
|
}
|
||||||
@ -77,10 +78,11 @@ void mtrr_read_all(struct mtrr_info *info)
|
|||||||
|
|
||||||
void mtrr_write_all(struct mtrr_info *info)
|
void mtrr_write_all(struct mtrr_info *info)
|
||||||
{
|
{
|
||||||
|
int reg_count = mtrr_get_var_count();
|
||||||
struct mtrr_state state;
|
struct mtrr_state state;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MTRR_COUNT; i++) {
|
for (i = 0; i < reg_count; i++) {
|
||||||
mtrr_open(&state, true);
|
mtrr_open(&state, true);
|
||||||
wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
|
wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
|
||||||
wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
|
wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
|
||||||
@ -156,7 +158,7 @@ int mtrr_commit(bool do_caches)
|
|||||||
|
|
||||||
/* Clear the ones that are unused */
|
/* Clear the ones that are unused */
|
||||||
debug("clear\n");
|
debug("clear\n");
|
||||||
for (; i < MTRR_COUNT; i++)
|
for (; i < MTRR_MAX_COUNT; i++)
|
||||||
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
|
wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
|
||||||
debug("close\n");
|
debug("close\n");
|
||||||
mtrr_close(&state, do_caches);
|
mtrr_close(&state, do_caches);
|
||||||
@ -196,7 +198,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_var_mtrr_count(void)
|
int mtrr_get_var_count(void)
|
||||||
{
|
{
|
||||||
return msr_read(MSR_MTRR_CAP_MSR).lo & MSR_MTRR_CAP_VCNT;
|
return msr_read(MSR_MTRR_CAP_MSR).lo & MSR_MTRR_CAP_VCNT;
|
||||||
}
|
}
|
||||||
@ -207,7 +209,7 @@ static int get_free_var_mtrr(void)
|
|||||||
int vcnt;
|
int vcnt;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vcnt = get_var_mtrr_count();
|
vcnt = mtrr_get_var_count();
|
||||||
|
|
||||||
/* Identify the first var mtrr which is not valid */
|
/* Identify the first var mtrr which is not valid */
|
||||||
for (i = 0; i < vcnt; i++) {
|
for (i = 0; i < vcnt; i++) {
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
|
|
||||||
#define MTRR_BASE_TYPE_MASK 0x7
|
#define MTRR_BASE_TYPE_MASK 0x7
|
||||||
|
|
||||||
/* Number of MTRRs supported */
|
/* Maximum number of MTRRs supported - see also mtrr_get_var_count() */
|
||||||
#define MTRR_COUNT 8
|
#define MTRR_MAX_COUNT 10
|
||||||
|
|
||||||
#define NUM_FIXED_MTRRS 11
|
#define NUM_FIXED_MTRRS 11
|
||||||
#define RANGES_PER_FIXED_MTRR 8
|
#define RANGES_PER_FIXED_MTRR 8
|
||||||
@ -87,7 +87,7 @@ struct mtrr {
|
|||||||
* @mtrr: Information about each mtrr
|
* @mtrr: Information about each mtrr
|
||||||
*/
|
*/
|
||||||
struct mtrr_info {
|
struct mtrr_info {
|
||||||
struct mtrr mtrr[MTRR_COUNT];
|
struct mtrr mtrr[MTRR_MAX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,6 +180,15 @@ int mtrr_set_valid(int cpu_select, int reg, bool valid);
|
|||||||
*/
|
*/
|
||||||
int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
|
int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mtrr_get_var_count() - Get the number of variable MTRRs
|
||||||
|
*
|
||||||
|
* Some CPUs have more than 8 MTRRs. This function returns the actual number
|
||||||
|
*
|
||||||
|
* @return number of variable MTRRs
|
||||||
|
*/
|
||||||
|
int mtrr_get_var_count(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
|
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
|
||||||
|
@ -27,7 +27,7 @@ static void read_mtrrs(void *arg)
|
|||||||
mtrr_read_all(info);
|
mtrr_read_all(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_mtrr_list(int cpu_select)
|
static int do_mtrr_list(int reg_count, int cpu_select)
|
||||||
{
|
{
|
||||||
struct mtrr_info info;
|
struct mtrr_info info;
|
||||||
int ret;
|
int ret;
|
||||||
@ -39,7 +39,7 @@ static int do_mtrr_list(int cpu_select)
|
|||||||
ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
|
ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("run", ret);
|
return log_msg_ret("run", ret);
|
||||||
for (i = 0; i < MTRR_COUNT; i++) {
|
for (i = 0; i < reg_count; i++) {
|
||||||
const char *type = "Invalid";
|
const char *type = "Invalid";
|
||||||
uint64_t base, mask, size;
|
uint64_t base, mask, size;
|
||||||
bool valid;
|
bool valid;
|
||||||
@ -98,6 +98,7 @@ static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
|
|||||||
static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
|
static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
char *const argv[])
|
char *const argv[])
|
||||||
{
|
{
|
||||||
|
int reg_count = mtrr_get_var_count();
|
||||||
int cmd;
|
int cmd;
|
||||||
int cpu_select;
|
int cpu_select;
|
||||||
uint reg;
|
uint reg;
|
||||||
@ -126,7 +127,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
reg = simple_strtoul(argv[1], NULL, 16);
|
reg = simple_strtoul(argv[1], NULL, 16);
|
||||||
if (reg >= MTRR_COUNT) {
|
if (reg >= reg_count) {
|
||||||
printf("Invalid register number\n");
|
printf("Invalid register number\n");
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
}
|
}
|
||||||
@ -145,7 +146,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||||||
if (!first)
|
if (!first)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("CPU %d:\n", i);
|
printf("CPU %d:\n", i);
|
||||||
ret = do_mtrr_list(i);
|
ret = do_mtrr_list(reg_count, i);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Failed to read CPU %d (err=%d)\n", i,
|
printf("Failed to read CPU %d (err=%d)\n", i,
|
||||||
ret);
|
ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user