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) | ||||
| { | ||||
| 	int reg_count = mtrr_get_var_count(); | ||||
| 	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].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) | ||||
| { | ||||
| 	int reg_count = mtrr_get_var_count(); | ||||
| 	struct mtrr_state state; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < MTRR_COUNT; i++) { | ||||
| 	for (i = 0; i < reg_count; i++) { | ||||
| 		mtrr_open(&state, true); | ||||
| 		wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base); | ||||
| 		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 */ | ||||
| 	debug("clear\n"); | ||||
| 	for (; i < MTRR_COUNT; i++) | ||||
| 	for (; i < MTRR_MAX_COUNT; i++) | ||||
| 		wrmsrl(MTRR_PHYS_MASK_MSR(i), 0); | ||||
| 	debug("close\n"); | ||||
| 	mtrr_close(&state, do_caches); | ||||
|  | @ -196,7 +198,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size) | |||
| 	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; | ||||
| } | ||||
|  | @ -207,7 +209,7 @@ static int get_free_var_mtrr(void) | |||
| 	int vcnt; | ||||
| 	int i; | ||||
| 
 | ||||
| 	vcnt = get_var_mtrr_count(); | ||||
| 	vcnt = mtrr_get_var_count(); | ||||
| 
 | ||||
| 	/* Identify the first var mtrr which is not valid */ | ||||
| 	for (i = 0; i < vcnt; i++) { | ||||
|  |  | |||
|  | @ -36,8 +36,8 @@ | |||
| 
 | ||||
| #define MTRR_BASE_TYPE_MASK	0x7 | ||||
| 
 | ||||
| /* Number of MTRRs supported */ | ||||
| #define MTRR_COUNT		8 | ||||
| /* Maximum number of MTRRs supported - see also mtrr_get_var_count() */ | ||||
| #define MTRR_MAX_COUNT		10 | ||||
| 
 | ||||
| #define NUM_FIXED_MTRRS		11 | ||||
| #define RANGES_PER_FIXED_MTRR	8 | ||||
|  | @ -87,7 +87,7 @@ struct mtrr { | |||
|  * @mtrr: Information about each mtrr | ||||
|  */ | ||||
| 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); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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 | ||||
| 
 | ||||
| #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); | ||||
| } | ||||
| 
 | ||||
| static int do_mtrr_list(int cpu_select) | ||||
| static int do_mtrr_list(int reg_count, int cpu_select) | ||||
| { | ||||
| 	struct mtrr_info info; | ||||
| 	int ret; | ||||
|  | @ -39,7 +39,7 @@ static int do_mtrr_list(int cpu_select) | |||
| 	ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info); | ||||
| 	if (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"; | ||||
| 		uint64_t base, mask, size; | ||||
| 		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, | ||||
| 		   char *const argv[]) | ||||
| { | ||||
| 	int reg_count = mtrr_get_var_count(); | ||||
| 	int cmd; | ||||
| 	int cpu_select; | ||||
| 	uint reg; | ||||
|  | @ -126,7 +127,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc, | |||
| 		if (argc < 2) | ||||
| 			return CMD_RET_USAGE; | ||||
| 		reg = simple_strtoul(argv[1], NULL, 16); | ||||
| 		if (reg >= MTRR_COUNT) { | ||||
| 		if (reg >= reg_count) { | ||||
| 			printf("Invalid register number\n"); | ||||
| 			return CMD_RET_USAGE; | ||||
| 		} | ||||
|  | @ -145,7 +146,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc, | |||
| 			if (!first) | ||||
| 				printf("\n"); | ||||
| 			printf("CPU %d:\n", i); | ||||
| 			ret = do_mtrr_list(i); | ||||
| 			ret = do_mtrr_list(reg_count, i); | ||||
| 			if (ret) { | ||||
| 				printf("Failed to read CPU %d (err=%d)\n", i, | ||||
| 				       ret); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue