x86: Add a way to reinit the cpu
We cannot init the CPU fully both than once during a boot. Add a new function which can be called to figure out the CPU identity, but which does not change anything. For x86_64, this is empty for now. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
		
							parent
							
								
									7b14023880
								
							
						
					
					
						commit
						c0069e9a8a
					
				|  | @ -309,13 +309,12 @@ u32 cpu_get_stepping(void) | |||
| 	return gd->arch.x86_mask; | ||||
| } | ||||
| 
 | ||||
| int x86_cpu_init_f(void) | ||||
| /* initialise FPU, reset EM, set MP and NE */ | ||||
| static void setup_cpu_features(void) | ||||
| { | ||||
| 	const u32 em_rst = ~X86_CR0_EM; | ||||
| 	const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE; | ||||
| 
 | ||||
| 	if (ll_boot_init()) { | ||||
| 		/* initialize FPU, reset EM, set MP and NE */ | ||||
| 	asm ("fninit\n" \ | ||||
| 	"movl %%cr0, %%eax\n" \ | ||||
| 	"andl %0, %%eax\n" \ | ||||
|  | @ -324,6 +323,8 @@ int x86_cpu_init_f(void) | |||
| 	: : "i" (em_rst), "i" (mp_ne_set) : "eax"); | ||||
| } | ||||
| 
 | ||||
| static void setup_identity(void) | ||||
| { | ||||
| 	/* identify CPU via cpuid and store the decoded info into gd->arch */ | ||||
| 	if (has_cpuid()) { | ||||
| 		struct cpu_device_id cpu; | ||||
|  | @ -339,12 +340,21 @@ int x86_cpu_init_f(void) | |||
| 
 | ||||
| 		gd->arch.has_mtrr = has_mtrr(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */ | ||||
| static void setup_pci_ram_top(void) | ||||
| { | ||||
| 	gd->pci_ram_top = 0x80000000U; | ||||
| } | ||||
| 
 | ||||
| static void setup_mtrr(void) | ||||
| { | ||||
| 	u64 mtrr_cap; | ||||
| 
 | ||||
| 	/* Configure fixed range MTRRs for some legacy regions */ | ||||
| 	if (gd->arch.has_mtrr) { | ||||
| 		u64 mtrr_cap; | ||||
| 	if (!gd->arch.has_mtrr) | ||||
| 		return; | ||||
| 
 | ||||
| 	mtrr_cap = native_read_msr(MTRR_CAP_MSR); | ||||
| 	if (mtrr_cap & MTRR_CAP_FIX) { | ||||
|  | @ -375,10 +385,25 @@ int x86_cpu_init_f(void) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_I8254_TIMER | ||||
| int x86_cpu_init_f(void) | ||||
| { | ||||
| 	if (ll_boot_init()) | ||||
| 		setup_cpu_features(); | ||||
| 	setup_identity(); | ||||
| 	setup_mtrr(); | ||||
| 	setup_pci_ram_top(); | ||||
| 
 | ||||
| 	/* Set up the i8254 timer if required */ | ||||
| 	if (IS_ENABLED(CONFIG_I8254_TIMER)) | ||||
| 		i8254_init(); | ||||
| #endif | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int x86_cpu_reinit_f(void) | ||||
| { | ||||
| 	setup_identity(); | ||||
| 	setup_pci_ram_top(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -61,3 +61,8 @@ int print_cpuinfo(void) | |||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int x86_cpu_reinit_f(void) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -13,7 +13,27 @@ extern char gdt_rom[]; | |||
| 
 | ||||
| /* cpu/.../cpu.c */ | ||||
| int arch_cpu_init(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * x86_cpu_init_f() - Set up basic features of the x86 CPU | ||||
|  * | ||||
|  * 0 on success, -ve on error | ||||
|  */ | ||||
| int x86_cpu_init_f(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * x86_cpu_reinit_f() - Set up the CPU a second time | ||||
|  * | ||||
|  * Once cpu_init_f() has been called (e.g. in SPL) we should not call it | ||||
|  * again (e.g. in U-Boot proper) since it sets up the state from scratch. | ||||
|  * Call this function in later phases of U-Boot instead. It reads the CPU | ||||
|  * identify so that CPU functions can be used correctly, but does not change | ||||
|  * anything. | ||||
|  * | ||||
|  * @return 0 (indicating success, to mimic cpu_init_f()) | ||||
|  */ | ||||
| int x86_cpu_reinit_f(void); | ||||
| 
 | ||||
| int cpu_init_f(void); | ||||
| void setup_gdt(struct global_data *id, u64 *gdt_addr); | ||||
| /*
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue