| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | #include <linux/threads.h>
 | 
					
						
							|  |  |  | #include <linux/cpumask.h>
 | 
					
						
							|  |  |  | #include <linux/string.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/ctype.h>
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							| 
									
										
										
										
											2008-07-21 22:08:21 -07:00
										 |  |  | #include <linux/dmar.h>
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | #include <linux/cpu.h>
 | 
					
						
							| 
									
										
										
										
											2008-07-21 22:08:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | #include <asm/smp.h>
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:50 -07:00
										 |  |  | #include <asm/x2apic.h>
 | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-11 12:55:26 +05:30
										 |  |  | static DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | static DEFINE_PER_CPU(cpumask_var_t, cpus_in_cluster); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | static DEFINE_PER_CPU(cpumask_var_t, ipi_mask); | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-12 11:44:11 +02:00
										 |  |  | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 
					
						
							| 
									
										
										
										
											2008-07-21 22:08:21 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-21 14:23:21 -08:00
										 |  |  | 	return x2apic_enabled(); | 
					
						
							| 
									
										
										
										
											2008-07-21 22:08:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | static inline u32 x2apic_cluster(int cpu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return per_cpu(x86_cpu_to_logical_apicid, cpu) >> 16; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | static void | 
					
						
							|  |  |  | __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 	struct cpumask *cpus_in_cluster_ptr; | 
					
						
							|  |  |  | 	struct cpumask *ipi_mask_ptr; | 
					
						
							|  |  |  | 	unsigned int cpu, this_cpu; | 
					
						
							| 
									
										
										
										
											2009-01-28 15:42:24 +01:00
										 |  |  | 	unsigned long flags; | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 	u32 dest; | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-17 10:16:54 -08:00
										 |  |  | 	x2apic_wrmsr_fence(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 	local_irq_save(flags); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	this_cpu = smp_processor_id(); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * We are to modify mask, so we need an own copy | 
					
						
							|  |  |  | 	 * and be sure it's manipulated with irq off. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	ipi_mask_ptr = __raw_get_cpu_var(ipi_mask); | 
					
						
							|  |  |  | 	cpumask_copy(ipi_mask_ptr, mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The idea is to send one IPI per cluster. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	for_each_cpu(cpu, ipi_mask_ptr) { | 
					
						
							|  |  |  | 		unsigned long i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cpus_in_cluster_ptr = per_cpu(cpus_in_cluster, cpu); | 
					
						
							|  |  |  | 		dest = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Collect cpus in cluster. */ | 
					
						
							|  |  |  | 		for_each_cpu_and(i, ipi_mask_ptr, cpus_in_cluster_ptr) { | 
					
						
							|  |  |  | 			if (apic_dest == APIC_DEST_ALLINC || i != this_cpu) | 
					
						
							|  |  |  | 				dest |= per_cpu(x86_cpu_to_logical_apicid, i); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!dest) | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		__x2apic_send_IPI_dest(dest, vector, apic->dest_logical); | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Cluster sibling cpus should be discared now so | 
					
						
							|  |  |  | 		 * we would not send IPI them second time. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		cpumask_andnot(ipi_mask_ptr, ipi_mask_ptr, cpus_in_cluster_ptr); | 
					
						
							| 
									
										
										
										
											2009-01-28 15:42:24 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-28 15:42:24 +01:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2012-06-05 13:23:15 +02:00
										 |  |  | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); | 
					
						
							| 
									
										
										
										
											2008-12-16 17:33:52 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-16 17:33:52 -08:00
										 |  |  | static void x2apic_send_IPI_allbutself(int vector) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLBUT); | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void x2apic_send_IPI_all(int vector) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:47 -07:00
										 |  |  | 	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-07 15:15:59 +02:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2009-01-28 15:20:18 +01:00
										 |  |  | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 
					
						
							| 
									
										
										
										
											2012-06-07 15:15:59 +02:00
										 |  |  | 			      const struct cpumask *andmask, | 
					
						
							|  |  |  | 			      unsigned int *apicid) | 
					
						
							| 
									
										
										
										
											2008-12-16 17:33:54 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | 	u32 dest = 0; | 
					
						
							|  |  |  | 	u16 cluster; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2008-12-16 17:33:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | 	for_each_cpu_and(i, cpumask, andmask) { | 
					
						
							|  |  |  | 		if (!cpumask_test_cpu(i, cpu_online_mask)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		dest = per_cpu(x86_cpu_to_logical_apicid, i); | 
					
						
							|  |  |  | 		cluster = x2apic_cluster(i); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-01-28 15:20:18 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | 	if (!dest) | 
					
						
							| 
									
										
										
										
											2012-06-07 15:15:59 +02:00
										 |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for_each_cpu_and(i, cpumask, andmask) { | 
					
						
							|  |  |  | 		if (!cpumask_test_cpu(i, cpu_online_mask)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		if (cluster != x2apic_cluster(i)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		dest |= per_cpu(x86_cpu_to_logical_apicid, i); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-07 15:15:59 +02:00
										 |  |  | 	*apicid = dest; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2008-12-16 17:33:54 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | static void init_x2apic_ldr(void) | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned int this_cpu = smp_processor_id(); | 
					
						
							|  |  |  | 	unsigned int cpu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	per_cpu(x86_cpu_to_logical_apicid, this_cpu) = apic_read(APIC_LDR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	__cpu_set(this_cpu, per_cpu(cpus_in_cluster, this_cpu)); | 
					
						
							|  |  |  | 	for_each_online_cpu(cpu) { | 
					
						
							|  |  |  | 		if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		__cpu_set(this_cpu, per_cpu(cpus_in_cluster, cpu)); | 
					
						
							|  |  |  | 		__cpu_set(cpu, per_cpu(cpus_in_cluster, this_cpu)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  /*
 | 
					
						
							|  |  |  |   * At CPU state changes, update the x2apic cluster sibling info. | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | static int __cpuinit | 
					
						
							|  |  |  | update_clusterinfo(struct notifier_block *nfb, unsigned long action, void *hcpu) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int this_cpu = (unsigned long)hcpu; | 
					
						
							|  |  |  | 	unsigned int cpu; | 
					
						
							|  |  |  | 	int err = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (action) { | 
					
						
							|  |  |  | 	case CPU_UP_PREPARE: | 
					
						
							|  |  |  | 		if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, this_cpu), | 
					
						
							|  |  |  | 					GFP_KERNEL)) { | 
					
						
							|  |  |  | 			err = -ENOMEM; | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 		} else if (!zalloc_cpumask_var(&per_cpu(ipi_mask, this_cpu), | 
					
						
							|  |  |  | 					       GFP_KERNEL)) { | 
					
						
							|  |  |  | 			free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu)); | 
					
						
							|  |  |  | 			err = -ENOMEM; | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case CPU_UP_CANCELED: | 
					
						
							|  |  |  | 	case CPU_UP_CANCELED_FROZEN: | 
					
						
							|  |  |  | 	case CPU_DEAD: | 
					
						
							|  |  |  | 		for_each_online_cpu(cpu) { | 
					
						
							|  |  |  | 			if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu)) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			__cpu_clear(this_cpu, per_cpu(cpus_in_cluster, cpu)); | 
					
						
							|  |  |  | 			__cpu_clear(cpu, per_cpu(cpus_in_cluster, this_cpu)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu)); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 		free_cpumask_var(per_cpu(ipi_mask, this_cpu)); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return notifier_from_errno(err); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct notifier_block __refdata x2apic_cpu_notifier = { | 
					
						
							|  |  |  | 	.notifier_call = update_clusterinfo, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int x2apic_init_cpu_notifier(void) | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	int cpu = smp_processor_id(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 	zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 	zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:49 -07:00
										 |  |  | 	BUG_ON(!per_cpu(cpus_in_cluster, cpu) || !per_cpu(ipi_mask, cpu)); | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	__cpu_set(cpu, per_cpu(cpus_in_cluster, cpu)); | 
					
						
							|  |  |  | 	register_hotcpu_notifier(&x2apic_cpu_notifier); | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:46 -07:00
										 |  |  | static int x2apic_cluster_probe(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:48 -07:00
										 |  |  | 	if (x2apic_mode) | 
					
						
							|  |  |  | 		return x2apic_init_cpu_notifier(); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:46 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-25 13:38:29 -07:00
										 |  |  | static const struct cpumask *x2apic_cluster_target_cpus(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return cpu_all_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Each x2apic cluster is an allocation domain. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-06-25 13:38:28 -07:00
										 |  |  | static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask, | 
					
						
							|  |  |  | 					     const struct cpumask *mask) | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-25 13:38:29 -07:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * To minimize vector pressure, default case of boot, device bringup | 
					
						
							|  |  |  | 	 * etc will use a single cpu for the interrupt destination. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * On explicit migration requests coming from irqbalance etc, | 
					
						
							|  |  |  | 	 * interrupts will be routed to the x2apic cluster (cluster-id | 
					
						
							|  |  |  | 	 * derived from the first cpu in the mask) members specified | 
					
						
							|  |  |  | 	 * in the mask. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (mask == x2apic_cluster_target_cpus()) | 
					
						
							|  |  |  | 		cpumask_copy(retmask, cpumask_of(cpu)); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		cpumask_and(retmask, mask, per_cpu(cpus_in_cluster, cpu)); | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-20 17:51:20 -07:00
										 |  |  | static struct apic apic_x2apic_cluster = { | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	.name				= "cluster x2apic", | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:46 -07:00
										 |  |  | 	.probe				= x2apic_cluster_probe, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check, | 
					
						
							| 
									
										
										
										
											2012-03-16 20:25:35 +01:00
										 |  |  | 	.apic_id_valid			= x2apic_apic_id_valid, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.apic_id_registered		= x2apic_apic_id_registered, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-28 04:02:31 +01:00
										 |  |  | 	.irq_delivery_mode		= dest_LowestPrio, | 
					
						
							| 
									
										
										
										
											2009-01-28 05:13:04 +01:00
										 |  |  | 	.irq_dest_mode			= 1, /* logical */ | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-25 13:38:29 -07:00
										 |  |  | 	.target_cpus			= x2apic_cluster_target_cpus, | 
					
						
							| 
									
										
										
										
											2009-01-28 05:08:44 +01:00
										 |  |  | 	.disable_esr			= 0, | 
					
						
							| 
									
										
										
										
											2009-01-28 05:29:25 +01:00
										 |  |  | 	.dest_logical			= APIC_DEST_LOGICAL, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.check_apicid_used		= NULL, | 
					
						
							|  |  |  | 	.check_apicid_present		= NULL, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-21 16:58:02 -07:00
										 |  |  | 	.vector_allocation_domain	= cluster_vector_allocation_domain, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.init_apic_ldr			= init_x2apic_ldr, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.ioapic_phys_id_map		= NULL, | 
					
						
							|  |  |  | 	.setup_apic_routing		= NULL, | 
					
						
							|  |  |  | 	.multi_timer_check		= NULL, | 
					
						
							| 
									
										
										
										
											2009-01-28 06:50:47 +01:00
										 |  |  | 	.cpu_present_to_apicid		= default_cpu_present_to_apicid, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.apicid_to_cpu_present		= NULL, | 
					
						
							|  |  |  | 	.setup_portio_remap		= NULL, | 
					
						
							| 
									
										
										
										
											2009-01-28 12:43:18 +01:00
										 |  |  | 	.check_phys_apicid_present	= default_check_phys_apicid_present, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.enable_apic_mode		= NULL, | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:50 -07:00
										 |  |  | 	.phys_pkg_id			= x2apic_phys_pkg_id, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.mps_oem_check			= NULL, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-19 16:45:50 -07:00
										 |  |  | 	.get_apic_id			= x2apic_get_apic_id, | 
					
						
							|  |  |  | 	.set_apic_id			= x2apic_set_apic_id, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.apic_id_mask			= 0xFFFFFFFFu, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.cpu_mask_to_apicid_and		= x2apic_cpu_mask_to_apicid_and, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.send_IPI_mask			= x2apic_send_IPI_mask, | 
					
						
							|  |  |  | 	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself, | 
					
						
							|  |  |  | 	.send_IPI_allbutself		= x2apic_send_IPI_allbutself, | 
					
						
							|  |  |  | 	.send_IPI_all			= x2apic_send_IPI_all, | 
					
						
							|  |  |  | 	.send_IPI_self			= x2apic_send_IPI_self, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-28 16:15:16 +01:00
										 |  |  | 	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW, | 
					
						
							|  |  |  | 	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH, | 
					
						
							| 
									
										
										
										
											2009-01-28 02:37:01 +01:00
										 |  |  | 	.wait_for_init_deassert		= NULL, | 
					
						
							|  |  |  | 	.smp_callin_clear_local_apic	= NULL, | 
					
						
							|  |  |  | 	.inquire_remote_apic		= NULL, | 
					
						
							| 
									
										
										
										
											2009-02-16 23:02:14 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	.read				= native_apic_msr_read, | 
					
						
							|  |  |  | 	.write				= native_apic_msr_write, | 
					
						
							| 
									
										
										
										
											2012-05-16 19:03:58 +03:00
										 |  |  | 	.eoi_write			= native_apic_msr_eoi_write, | 
					
						
							| 
									
										
										
										
											2009-02-16 23:02:14 -08:00
										 |  |  | 	.icr_read			= native_x2apic_icr_read, | 
					
						
							|  |  |  | 	.icr_write			= native_x2apic_icr_write, | 
					
						
							|  |  |  | 	.wait_icr_idle			= native_x2apic_wait_icr_idle, | 
					
						
							|  |  |  | 	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle, | 
					
						
							| 
									
										
										
										
											2008-07-10 11:16:54 -07:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2011-05-20 17:51:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | apic_driver(apic_x2apic_cluster); |