diff options
Diffstat (limited to 'arch/x86/cpu/i386/cpu.c')
-rw-r--r-- | arch/x86/cpu/i386/cpu.c | 113 |
1 files changed, 69 insertions, 44 deletions
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index 3bde44ebf5..90b546e741 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -309,21 +309,22 @@ 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" \ - "orl %1, %%eax\n" \ - "movl %%eax, %%cr0\n" \ - : : "i" (em_rst), "i" (mp_ne_set) : "eax"); - } + asm ("fninit\n" \ + "movl %%cr0, %%eax\n" \ + "andl %0, %%eax\n" \ + "orl %1, %%eax\n" \ + "movl %%eax, %%cr0\n" \ + : : "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,46 +340,70 @@ 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 */ +} + +/* 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; - - mtrr_cap = native_read_msr(MTRR_CAP_MSR); - if (mtrr_cap & MTRR_CAP_FIX) { - /* Mark the VGA RAM area as uncacheable */ - native_write_msr(MTRR_FIX_16K_A0000_MSR, - MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE), - MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE)); - - /* - * Mark the PCI ROM area as cacheable to improve ROM - * execution performance. - */ - native_write_msr(MTRR_FIX_4K_C0000_MSR, - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); - native_write_msr(MTRR_FIX_4K_C8000_MSR, - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); - native_write_msr(MTRR_FIX_4K_D0000_MSR, - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); - native_write_msr(MTRR_FIX_4K_D8000_MSR, - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), - MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); - - /* Enable the fixed range MTRRs */ - msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN); - } + if (!gd->arch.has_mtrr) + return; + + mtrr_cap = native_read_msr(MTRR_CAP_MSR); + if (mtrr_cap & MTRR_CAP_FIX) { + /* Mark the VGA RAM area as uncacheable */ + native_write_msr(MTRR_FIX_16K_A0000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE), + MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE)); + + /* + * Mark the PCI ROM area as cacheable to improve ROM + * execution performance. + */ + native_write_msr(MTRR_FIX_4K_C0000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_C8000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_D0000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_D8000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + + /* Enable the fixed range MTRRs */ + msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN); } +} + +int x86_cpu_init_f(void) +{ + if (ll_boot_init()) + setup_cpu_features(); + setup_identity(); + setup_mtrr(); + setup_pci_ram_top(); -#ifdef CONFIG_I8254_TIMER /* Set up the i8254 timer if required */ - i8254_init(); -#endif + if (IS_ENABLED(CONFIG_I8254_TIMER)) + i8254_init(); + + return 0; +} + +int x86_cpu_reinit_f(void) +{ + setup_identity(); + setup_pci_ram_top(); return 0; } |