| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef __ASM_MACH_APIC_H | 
|  | 2 | #define __ASM_MACH_APIC_H | 
|  | 3 |  | 
|  | 4 | #include <asm/io.h> | 
|  | 5 | #include <linux/mmzone.h> | 
|  | 6 | #include <linux/nodemask.h> | 
|  | 7 |  | 
|  | 8 | #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER) | 
|  | 9 |  | 
|  | 10 | static inline cpumask_t target_cpus(void) | 
|  | 11 | { | 
|  | 12 | return CPU_MASK_ALL; | 
|  | 13 | } | 
|  | 14 |  | 
|  | 15 | #define TARGET_CPUS (target_cpus()) | 
|  | 16 |  | 
|  | 17 | #define NO_BALANCE_IRQ (1) | 
|  | 18 | #define esr_disable (1) | 
|  | 19 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | #define INT_DELIVERY_MODE dest_LowestPrio | 
|  | 21 | #define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */ | 
|  | 22 |  | 
|  | 23 | #define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap) | 
|  | 24 | #define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map) | 
|  | 25 | #define apicid_cluster(apicid) (apicid & 0xF0) | 
|  | 26 |  | 
|  | 27 | static inline int apic_id_registered(void) | 
|  | 28 | { | 
|  | 29 | return 1; | 
|  | 30 | } | 
|  | 31 |  | 
|  | 32 | static inline void init_apic_ldr(void) | 
|  | 33 | { | 
|  | 34 | /* Already done in NUMA-Q firmware */ | 
|  | 35 | } | 
|  | 36 |  | 
| Ingo Molnar | 3c43f03 | 2007-05-02 19:27:04 +0200 | [diff] [blame] | 37 | static inline void setup_apic_routing(void) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | { | 
|  | 39 | printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n", | 
|  | 40 | "NUMA-Q", nr_ioapics); | 
|  | 41 | } | 
|  | 42 |  | 
|  | 43 | /* | 
|  | 44 | * Skip adding the timer int on secondary nodes, which causes | 
|  | 45 | * a small but painful rift in the time-space continuum. | 
|  | 46 | */ | 
|  | 47 | static inline int multi_timer_check(int apic, int irq) | 
|  | 48 | { | 
|  | 49 | return apic != 0 && irq == 0; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) | 
|  | 53 | { | 
|  | 54 | /* We don't have a good way to do this yet - hack */ | 
|  | 55 | return physids_promote(0xFUL); | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | /* Mapping from cpu number to logical apicid */ | 
|  | 59 | extern u8 cpu_2_logical_apicid[]; | 
|  | 60 | static inline int cpu_to_logical_apicid(int cpu) | 
|  | 61 | { | 
|  | 62 | if (cpu >= NR_CPUS) | 
|  | 63 | return BAD_APICID; | 
|  | 64 | return (int)cpu_2_logical_apicid[cpu]; | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | /* | 
|  | 68 | * Supporting over 60 cpus on NUMA-Q requires a locality-dependent | 
|  | 69 | * cpu to APIC ID relation to properly interact with the intelligent | 
|  | 70 | * mode of the cluster controller. | 
|  | 71 | */ | 
|  | 72 | static inline int cpu_present_to_apicid(int mps_cpu) | 
|  | 73 | { | 
|  | 74 | if (mps_cpu < 60) | 
|  | 75 | return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3)); | 
|  | 76 | else | 
|  | 77 | return BAD_APICID; | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | static inline int generate_logical_apicid(int quad, int phys_apicid) | 
|  | 81 | { | 
|  | 82 | return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); | 
|  | 83 | } | 
|  | 84 |  | 
|  | 85 | static inline int apicid_to_node(int logical_apicid) | 
|  | 86 | { | 
|  | 87 | return logical_apicid >> 4; | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | static inline physid_mask_t apicid_to_cpu_present(int logical_apicid) | 
|  | 91 | { | 
|  | 92 | int node = apicid_to_node(logical_apicid); | 
|  | 93 | int cpu = __ffs(logical_apicid & 0xf); | 
|  | 94 |  | 
|  | 95 | return physid_mask_of_physid(cpu + 4*node); | 
|  | 96 | } | 
|  | 97 |  | 
| Alexey Starikovskiy | 8642050 | 2008-03-17 22:08:55 +0300 | [diff] [blame] | 98 | struct mpc_config_translation { | 
|  | 99 | unsigned char mpc_type; | 
|  | 100 | unsigned char trans_len; | 
|  | 101 | unsigned char trans_type; | 
|  | 102 | unsigned char trans_quad; | 
|  | 103 | unsigned char trans_global; | 
|  | 104 | unsigned char trans_local; | 
|  | 105 | unsigned short trans_reserved; | 
|  | 106 | }; | 
|  | 107 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 108 | static inline int mpc_apic_id(struct mpc_config_processor *m, | 
|  | 109 | struct mpc_config_translation *translation_record) | 
|  | 110 | { | 
|  | 111 | int quad = translation_record->trans_quad; | 
|  | 112 | int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); | 
|  | 113 |  | 
| Thomas Gleixner | 64883ab | 2008-01-30 13:30:35 +0100 | [diff] [blame] | 114 | printk("Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", | 
|  | 115 | m->mpc_apicid, | 
|  | 116 | (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, | 
|  | 117 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, | 
|  | 118 | m->mpc_apicver, quad, logical_apicid); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 119 | return logical_apicid; | 
|  | 120 | } | 
|  | 121 |  | 
| Andi Kleen | c7e844f | 2008-02-04 16:48:03 +0100 | [diff] [blame] | 122 | extern void *xquad_portio; | 
|  | 123 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 124 | static inline void setup_portio_remap(void) | 
|  | 125 | { | 
|  | 126 | int num_quads = num_online_nodes(); | 
|  | 127 |  | 
|  | 128 | if (num_quads <= 1) | 
|  | 129 | return; | 
|  | 130 |  | 
|  | 131 | printk("Remapping cross-quad port I/O for %d quads\n", num_quads); | 
|  | 132 | xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD); | 
|  | 133 | printk("xquad_portio vaddr 0x%08lx, len %08lx\n", | 
|  | 134 | (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); | 
|  | 135 | } | 
|  | 136 |  | 
|  | 137 | static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) | 
|  | 138 | { | 
|  | 139 | return (1); | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | static inline void enable_apic_mode(void) | 
|  | 143 | { | 
|  | 144 | } | 
|  | 145 |  | 
|  | 146 | /* | 
|  | 147 | * We use physical apicids here, not logical, so just return the default | 
|  | 148 | * physical broadcast to stop people from breaking us | 
|  | 149 | */ | 
|  | 150 | static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) | 
|  | 151 | { | 
|  | 152 | return (int) 0xF; | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ | 
|  | 156 | static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) | 
|  | 157 | { | 
|  | 158 | return cpuid_apic >> index_msb; | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | #endif /* __ASM_MACH_APIC_H */ |