diff options
Diffstat (limited to 'arch/x86/kernel/apic')
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 29 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/probe_64.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 89 | 
6 files changed, 112 insertions, 31 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 3987e4408f7..6e29b2a77aa 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -581,7 +581,7 @@ calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)  		res = (((u64)(*deltatsc)) * pm_100ms);  		do_div(res, deltapm);  		apic_printk(APIC_VERBOSE, "TSC delta adjusted to " -					  "PM-Timer: %lu (%ld) \n", +					  "PM-Timer: %lu (%ld)\n",  					(unsigned long)res, *deltatsc);  		*deltatsc = (long)res;  	} @@ -1641,9 +1641,7 @@ int __init APIC_init_uniprocessor(void)  #endif  	enable_IR_x2apic(); -#ifdef CONFIG_X86_64  	default_setup_apic_routing(); -#endif  	verify_local_APIC();  	connect_bsp_APIC(); @@ -1891,21 +1889,6 @@ void __cpuinit generic_processor_info(int apicid, int version)  	if (apicid > max_physical_apicid)  		max_physical_apicid = apicid; -#ifdef CONFIG_X86_32 -	if (num_processors > 8) { -		switch (boot_cpu_data.x86_vendor) { -		case X86_VENDOR_INTEL: -			if (!APIC_XAPIC(version)) { -				def_to_bigsmp = 0; -				break; -			} -			/* If P4 and above fall through */ -		case X86_VENDOR_AMD: -			def_to_bigsmp = 1; -		} -	} -#endif -  #if defined(CONFIG_SMP) || defined(CONFIG_X86_64)  	early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;  	early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 53243ca7816..6bdd2c7ead7 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1647,7 +1647,7 @@ __apicdebuginit(void) print_IO_APIC(void)  	printk(KERN_DEBUG ".... IRQ redirection table:\n");  	printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" -			  " Stat Dmod Deli Vect:   \n"); +			  " Stat Dmod Deli Vect:\n");  	for (i = 0; i <= reg_01.bits.entries; i++) {  		struct IO_APIC_route_entry entry; diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 98c4665f251..47dd856708e 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -225,7 +225,7 @@ static void __init smp_read_mpc_oem(struct mpc_table *mpc)  	mpc_record = 0;  	printk(KERN_INFO -		"Found an OEM MPC table at %8p - parsing it ... \n", oemtable); +		"Found an OEM MPC table at %8p - parsing it...\n", oemtable);  	if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {  		printk(KERN_WARNING diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 1a6559f6768..99d2fe01608 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -52,7 +52,32 @@ static int __init print_ipi_mode(void)  }  late_initcall(print_ipi_mode); -void default_setup_apic_routing(void) +void __init default_setup_apic_routing(void) +{ +	int version = apic_version[boot_cpu_physical_apicid]; + +	if (num_possible_cpus() > 8) { +		switch (boot_cpu_data.x86_vendor) { +		case X86_VENDOR_INTEL: +			if (!APIC_XAPIC(version)) { +				def_to_bigsmp = 0; +				break; +			} +			/* If P4 and above fall through */ +		case X86_VENDOR_AMD: +			def_to_bigsmp = 1; +		} +	} + +#ifdef CONFIG_X86_BIGSMP +	generic_bigsmp_probe(); +#endif + +	if (apic->setup_apic_routing) +		apic->setup_apic_routing(); +} + +static void setup_apic_flat_routing(void)  {  #ifdef CONFIG_X86_IO_APIC  	printk(KERN_INFO @@ -103,7 +128,7 @@ struct apic apic_default = {  	.init_apic_ldr			= default_init_apic_ldr,  	.ioapic_phys_id_map		= default_ioapic_phys_id_map, -	.setup_apic_routing		= default_setup_apic_routing, +	.setup_apic_routing		= setup_apic_flat_routing,  	.multi_timer_check		= NULL,  	.apicid_to_node			= default_apicid_to_node,  	.cpu_to_logical_apicid		= default_cpu_to_logical_apicid, diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 450fe2064a1..83e9be4778e 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -67,7 +67,7 @@ void __init default_setup_apic_routing(void)  	}  #endif -	if (apic == &apic_flat && num_processors > 8) +	if (apic == &apic_flat && num_possible_cpus() > 8)  			apic = &apic_physflat;  	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 21db3cbea7d..3740c8a4eae 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -5,7 +5,7 @@   *   * SGI UV APIC functions (note: not an Intel compatible APIC)   * - * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.   */  #include <linux/cpumask.h>  #include <linux/hardirq.h> @@ -20,6 +20,8 @@  #include <linux/cpu.h>  #include <linux/init.h>  #include <linux/io.h> +#include <linux/pci.h> +#include <linux/kdebug.h>  #include <asm/uv/uv_mmrs.h>  #include <asm/uv/uv_hub.h> @@ -34,10 +36,13 @@  DEFINE_PER_CPU(int, x2apic_extra_bits); +#define PR_DEVEL(fmt, args...)	pr_devel("%s: " fmt, __func__, args) +  static enum uv_system_type uv_system_type;  static u64 gru_start_paddr, gru_end_paddr;  int uv_min_hub_revision_id;  EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); +static DEFINE_SPINLOCK(uv_nmi_lock);  static inline bool is_GRU_range(u64 start, u64 end)  { @@ -71,6 +76,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)  	if (!strcmp(oem_id, "SGI")) {  		nodeid = early_get_nodeid();  		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range; +		x86_platform.nmi_init = uv_nmi_init;  		if (!strcmp(oem_table_id, "UVL"))  			uv_system_type = UV_LEGACY_APIC;  		else if (!strcmp(oem_table_id, "UVX")) @@ -482,7 +488,7 @@ static void uv_heartbeat(unsigned long ignored)  static void __cpuinit uv_heartbeat_enable(int cpu)  { -	if (!uv_cpu_hub_info(cpu)->scir.enabled) { +	while (!uv_cpu_hub_info(cpu)->scir.enabled) {  		struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer;  		uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY); @@ -490,11 +496,10 @@ static void __cpuinit uv_heartbeat_enable(int cpu)  		timer->expires = jiffies + SCIR_CPU_HB_INTERVAL;  		add_timer_on(timer, cpu);  		uv_cpu_hub_info(cpu)->scir.enabled = 1; -	} -	/* check boot cpu */ -	if (!uv_cpu_hub_info(0)->scir.enabled) -		uv_heartbeat_enable(0); +		/* also ensure that boot cpu is enabled */ +		cpu = 0; +	}  }  #ifdef CONFIG_HOTPLUG_CPU @@ -553,6 +558,30 @@ late_initcall(uv_init_heartbeat);  #endif /* !CONFIG_HOTPLUG_CPU */ +/* Direct Legacy VGA I/O traffic to designated IOH */ +int uv_set_vga_state(struct pci_dev *pdev, bool decode, +		      unsigned int command_bits, bool change_bridge) +{ +	int domain, bus, rc; + +	PR_DEVEL("devfn %x decode %d cmd %x chg_brdg %d\n", +			pdev->devfn, decode, command_bits, change_bridge); + +	if (!change_bridge) +		return 0; + +	if ((command_bits & PCI_COMMAND_IO) == 0) +		return 0; + +	domain = pci_domain_nr(pdev->bus); +	bus = pdev->bus->number; + +	rc = uv_bios_set_legacy_vga_target(decode, domain, bus); +	PR_DEVEL("vga decode %d %x:%x, rc: %d\n", decode, domain, bus, rc); + +	return rc; +} +  /*   * Called on each cpu to initialize the per_cpu UV data area.   * FIXME: hotplug not supported yet @@ -569,6 +598,46 @@ void __cpuinit uv_cpu_init(void)  		set_x2apic_extra_bits(uv_hub_info->pnode);  } +/* + * When NMI is received, print a stack trace. + */ +int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) +{ +	if (reason != DIE_NMI_IPI) +		return NOTIFY_OK; +	/* +	 * Use a lock so only one cpu prints at a time +	 * to prevent intermixed output. +	 */ +	spin_lock(&uv_nmi_lock); +	pr_info("NMI stack dump cpu %u:\n", smp_processor_id()); +	dump_stack(); +	spin_unlock(&uv_nmi_lock); + +	return NOTIFY_STOP; +} + +static struct notifier_block uv_dump_stack_nmi_nb = { +	.notifier_call	= uv_handle_nmi +}; + +void uv_register_nmi_notifier(void) +{ +	if (register_die_notifier(&uv_dump_stack_nmi_nb)) +		printk(KERN_WARNING "UV NMI handler failed to register\n"); +} + +void uv_nmi_init(void) +{ +	unsigned int value; + +	/* +	 * Unmask NMI on all cpus +	 */ +	value = apic_read(APIC_LVT1) | APIC_DM_NMI; +	value &= ~APIC_LVT_MASKED; +	apic_write(APIC_LVT1, value); +}  void __init uv_system_init(void)  { @@ -634,8 +703,8 @@ void __init uv_system_init(void)  	}  	uv_bios_init(); -	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, -			    &sn_coherency_id, &sn_region_size); +	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, &sn_coherency_id, +			    &sn_region_size, &system_serial_number);  	uv_rtc_init();  	for_each_present_cpu(cpu) { @@ -690,5 +759,9 @@ void __init uv_system_init(void)  	uv_cpu_init();  	uv_scir_register_cpu_notifier(); +	uv_register_nmi_notifier();  	proc_mkdir("sgi_uv", NULL); + +	/* register Legacy VGA I/O redirection handler */ +	pci_register_set_vga_state(uv_set_vga_state);  }  |