diff options
Diffstat (limited to 'xen/arch/x86/setup.c')
-rw-r--r-- | xen/arch/x86/setup.c | 254 |
1 files changed, 3 insertions, 251 deletions
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 0751594777..078d59d8fd 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -82,7 +82,8 @@ extern void init_IRQ(void); extern void trap_init(void); extern void time_init(void); extern void ac_timer_init(void); -extern void initialize_keytable(); +extern void initialize_keytable(void); +extern void early_cpu_init(void); extern unsigned long cpu0_stack[]; @@ -101,256 +102,6 @@ int acpi_disabled; int logical_proc_id[NR_CPUS]; -/* Standard macro to see if a specific flag is changeable. */ -static inline int flag_is_changeable_p(unsigned long flag) -{ - unsigned long f1, f2; - - asm("pushf\n\t" - "pushf\n\t" - "pop %0\n\t" - "mov %0,%1\n\t" - "xor %2,%0\n\t" - "push %0\n\t" - "popf\n\t" - "pushf\n\t" - "pop %0\n\t" - "popf\n\t" - : "=&r" (f1), "=&r" (f2) - : "ir" (flag)); - - return ((f1^f2) & flag) != 0; -} - -/* Probe for the CPUID instruction */ -static int __init have_cpuid_p(void) -{ - return flag_is_changeable_p(X86_EFLAGS_ID); -} - -void __init get_cpu_vendor(struct cpuinfo_x86 *c) -{ - char *v = c->x86_vendor_id; - - if (!strcmp(v, "GenuineIntel")) - c->x86_vendor = X86_VENDOR_INTEL; - else if (!strcmp(v, "AuthenticAMD")) - c->x86_vendor = X86_VENDOR_AMD; - else if (!strcmp(v, "CyrixInstead")) - c->x86_vendor = X86_VENDOR_CYRIX; - else if (!strcmp(v, "UMC UMC UMC ")) - c->x86_vendor = X86_VENDOR_UMC; - else if (!strcmp(v, "CentaurHauls")) - c->x86_vendor = X86_VENDOR_CENTAUR; - else if (!strcmp(v, "NexGenDriven")) - c->x86_vendor = X86_VENDOR_NEXGEN; - else if (!strcmp(v, "RiseRiseRise")) - c->x86_vendor = X86_VENDOR_RISE; - else if (!strcmp(v, "GenuineTMx86") || - !strcmp(v, "TransmetaCPU")) - c->x86_vendor = X86_VENDOR_TRANSMETA; - else - c->x86_vendor = X86_VENDOR_UNKNOWN; -} - -static void __init init_intel(struct cpuinfo_x86 *c) -{ - /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */ - if ( c->x86 == 6 && c->x86_model < 3 && c->x86_mask < 3 ) - clear_bit(X86_FEATURE_SEP, &c->x86_capability); - - if ( test_bit(X86_FEATURE_HT, &c->x86_capability) ) - { - u32 eax, ebx, ecx, edx; - int initial_apic_id, siblings, cpu = smp_processor_id(); - - cpuid(1, &eax, &ebx, &ecx, &edx); - ht_per_core = siblings = (ebx & 0xff0000) >> 16; - - if ( opt_noht ) - clear_bit(X86_FEATURE_HT, &c->x86_capability[0]); - - if ( siblings <= 1 ) - { - printk(KERN_INFO "CPU#%d: Hyper-Threading is disabled\n", cpu); - } - else if ( siblings > 2 ) - { - panic("We don't support more than two logical CPUs per package!"); - } - else - { - initial_apic_id = ebx >> 24 & 0xff; - phys_proc_id[cpu] = initial_apic_id >> 1; - logical_proc_id[cpu] = initial_apic_id & 1; - printk(KERN_INFO "CPU#%d: Physical ID: %d, Logical ID: %d\n", - cpu, phys_proc_id[cpu], logical_proc_id[cpu]); - } - } - -#ifdef CONFIG_VMX - start_vmx(); -#endif - -} - -static void __init init_amd(struct cpuinfo_x86 *c) -{ - /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; - 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ - clear_bit(0*32+31, &c->x86_capability); - - switch(c->x86) - { - case 5: - panic("AMD K6 is not supported.\n"); - case 6: /* An Athlon/Duron. We can trust the BIOS probably */ - break; - } -} - -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __init identify_cpu(struct cpuinfo_x86 *c) -{ - int i, cpu = smp_processor_id(); - u32 xlvl, tfms, junk; - - phys_proc_id[cpu] = cpu; - logical_proc_id[cpu] = 0; - - c->x86_vendor = X86_VENDOR_UNKNOWN; - c->cpuid_level = -1; /* CPUID not detected */ - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_vendor_id[0] = '\0'; /* Unset */ - memset(&c->x86_capability, 0, sizeof c->x86_capability); - - if ( !have_cpuid_p() ) - panic("Ancient processors not supported\n"); - - /* Get vendor name */ - cpuid(0x00000000, (unsigned int *)&c->cpuid_level, - (unsigned int *)&c->x86_vendor_id[0], - (unsigned int *)&c->x86_vendor_id[8], - (unsigned int *)&c->x86_vendor_id[4]); - - get_cpu_vendor(c); - - if ( c->cpuid_level == 0 ) - panic("Decrepit CPUID not supported\n"); - - cpuid(0x00000001, &tfms, &junk, &junk, - &c->x86_capability[0]); - c->x86 = (tfms >> 8) & 15; - c->x86_model = (tfms >> 4) & 15; - c->x86_mask = tfms & 15; - - /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) - c->x86_capability[1] = cpuid_edx(0x80000001); - } - - /* Transmeta-defined flags: level 0x80860001 */ - xlvl = cpuid_eax(0x80860000); - if ( (xlvl & 0xffff0000) == 0x80860000 ) { - if ( xlvl >= 0x80860001 ) - c->x86_capability[2] = cpuid_edx(0x80860001); - } - - printk("CPU%d: Before vendor init, caps: %08x %08x %08x, vendor = %d\n", - smp_processor_id(), - c->x86_capability[0], - c->x86_capability[1], - c->x86_capability[2], - c->x86_vendor); - - switch ( c->x86_vendor ) { - case X86_VENDOR_INTEL: - init_intel(c); - break; - case X86_VENDOR_AMD: - init_amd(c); - break; - case X86_VENDOR_UNKNOWN: /* Connectix Virtual PC reports this */ - break; - case X86_VENDOR_CENTAUR: - break; - default: - printk("Unknown CPU identifier (%d): continuing anyway, " - "but might fail.\n", c->x86_vendor); - } - - printk("CPU caps: %08x %08x %08x %08x\n", - c->x86_capability[0], - c->x86_capability[1], - c->x86_capability[2], - c->x86_capability[3]); - - /* - * On SMP, boot_cpu_data holds the common feature set between - * all CPUs; so make sure that we indicate which features are - * common between the CPUs. The first time this routine gets - * executed, c == &boot_cpu_data. - */ - if ( c != &boot_cpu_data ) { - /* AND the already accumulated flags with these */ - for ( i = 0 ; i < NCAPINTS ; i++ ) - boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; - } -} - -void __init print_cpu_info(struct cpuinfo_x86 *c) -{ - printk("booted.\n"); -} - -unsigned long cpu_initialized; -void __init cpu_init(void) -{ - int nr = smp_processor_id(); - struct tss_struct *t = &init_tss[nr]; - char gdt_load[10]; - - if ( test_and_set_bit(nr, &cpu_initialized) ) - panic("CPU#%d already initialized!!!\n", nr); - printk("Initializing CPU#%d\n", nr); - - *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE; - *(unsigned long *)(&gdt_load[2]) = GDT_VIRT_START(current); - __asm__ __volatile__ ( "lgdt %0" : "=m" (gdt_load) ); - - /* No nested task. */ - __asm__ __volatile__ ( "pushf ; andw $0xbfff,(%"__OP"sp) ; popf" ); - - /* Ensure FPU gets initialised for each domain. */ - stts(); - - /* Set up and load the per-CPU TSS and LDT. */ - t->bitmap = IOBMP_INVALID_OFFSET; -#if defined(CONFIG_X86_32) - t->ss0 = __HYPERVISOR_DS; - t->esp0 = get_stack_bottom(); -#elif defined(CONFIG_X86_64) - /* Bottom-of-stack must be 16-byte aligned or CPU will force it! :-o */ - BUG_ON((get_stack_bottom() & 15) != 0); - t->rsp0 = get_stack_bottom(); -#endif - set_tss_desc(nr,t); - load_TR(nr); - __asm__ __volatile__ ( "lldt %%ax" : : "a" (0) ); - - /* Clear all 6 debug registers. */ -#define CD(register) __asm__ ( "mov %0,%%db" #register : : "r" (0UL) ); - CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7); -#undef CD - - /* Install correct page table. */ - write_ptbase(current); -} - int acpi_force; char acpi_param[10] = ""; static void parse_acpi_param(char *s) @@ -415,6 +166,7 @@ static void __init start_of_day(void) virt_to_phys(gdt_table) >> PAGE_SHIFT, 1, PAGE_HYPERVISOR); /* Process CPU type information. */ + early_cpu_init(); identify_cpu(&boot_cpu_data); if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR); |