Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | #ifndef __ASM_SMP_H #define __ASM_SMP_H #ifdef __SMP__ #ifndef ASSEMBLY #include <asm/i82489.h> #include <asm/bitops.h> #include <linux/tasks.h> #include <linux/ptrace.h> /* * Support definitions for SMP machines following the intel multiprocessing * specification */ /* * This tag identifies where the SMP configuration * information is. */ #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') struct intel_mp_floating { char mpf_signature[4]; /* "_MP_" */ unsigned long mpf_physptr; /* Configuration table address */ unsigned char mpf_length; /* Our length (paragraphs) */ unsigned char mpf_specification;/* Specification version */ unsigned char mpf_checksum; /* Checksum (makes sum 0) */ unsigned char mpf_feature1; /* Standard or configuration ? */ unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ unsigned char mpf_feature3; /* Unused (0) */ unsigned char mpf_feature4; /* Unused (0) */ unsigned char mpf_feature5; /* Unused (0) */ }; struct mp_config_table { char mpc_signature[4]; #define MPC_SIGNATURE "PCMP" unsigned short mpc_length; /* Size of table */ char mpc_spec; /* 0x01 */ char mpc_checksum; char mpc_oem[8]; char mpc_productid[12]; unsigned long mpc_oemptr; /* 0 if not present */ unsigned short mpc_oemsize; /* 0 if not present */ unsigned short mpc_oemcount; unsigned long mpc_lapic; /* APIC address */ unsigned long reserved; }; /* Followed by entries */ #define MP_PROCESSOR 0 #define MP_BUS 1 #define MP_IOAPIC 2 #define MP_INTSRC 3 #define MP_LINTSRC 4 struct mpc_config_processor { unsigned char mpc_type; unsigned char mpc_apicid; /* Local APIC number */ unsigned char mpc_apicver; /* Its versions */ unsigned char mpc_cpuflag; #define CPU_ENABLED 1 /* Processor is available */ #define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ unsigned long mpc_cpufeature; #define CPU_STEPPING_MASK 0x0F #define CPU_MODEL_MASK 0xF0 #define CPU_FAMILY_MASK 0xF00 unsigned long mpc_featureflag; /* CPUID feature value */ unsigned long mpc_reserved[2]; }; struct mpc_config_bus { unsigned char mpc_type; unsigned char mpc_busid; unsigned char mpc_bustype[6] __attribute((packed)); }; #define BUSTYPE_EISA "EISA" #define BUSTYPE_ISA "ISA" #define BUSTYPE_INTERN "INTERN" /* Internal BUS */ #define BUSTYPE_MCA "MCA" #define BUSTYPE_VL "VL" /* Local bus */ #define BUSTYPE_PCI "PCI" #define BUSTYPE_PCMCIA "PCMCIA" /* We don't understand the others */ struct mpc_config_ioapic { unsigned char mpc_type; unsigned char mpc_apicid; unsigned char mpc_apicver; unsigned char mpc_flags; #define MPC_APIC_USABLE 0x01 unsigned long mpc_apicaddr; }; struct mpc_config_intsrc { unsigned char mpc_type; unsigned char mpc_irqtype; unsigned short mpc_irqflag; unsigned char mpc_srcbus; unsigned char mpc_srcbusirq; unsigned char mpc_dstapic; unsigned char mpc_dstirq; }; #define MP_INT_VECTORED 0 #define MP_INT_NMI 1 #define MP_INT_SMI 2 #define MP_INT_EXTINT 3 #define MP_IRQDIR_DEFAULT 0 #define MP_IRQDIR_HIGH 1 #define MP_IRQDIR_LOW 3 struct mpc_config_intlocal { unsigned char mpc_type; unsigned char mpc_irqtype; unsigned short mpc_irqflag; unsigned char mpc_srcbusid; unsigned char mpc_srcbusirq; unsigned char mpc_destapic; #define MP_APIC_ALL 0xFF unsigned char mpc_destapiclint; }; /* * Default configurations * * 1 2 CPU ISA 82489DX * 2 2 CPU EISA 82489DX no IRQ 8 or timer chaining * 3 2 CPU EISA 82489DX * 4 2 CPU MCA 82489DX * 5 2 CPU ISA+PCI * 6 2 CPU EISA+PCI * 7 2 CPU MCA+PCI */ /* * Private routines/data */ extern int smp_found_config; extern int smp_scan_config(unsigned long, unsigned long); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; extern volatile int cpu_number_map[NR_CPUS]; extern volatile unsigned long smp_invalidate_needed; extern void smp_flush_tlb(void); extern volatile unsigned long kernel_flag, kernel_counter; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern volatile unsigned char active_kernel_processor; extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); extern unsigned long ipi_count; extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void smp_local_timer_interrupt(struct pt_regs * regs); extern void (*mtrr_hook) (void); extern void setup_APIC_clock (void); extern volatile int __cpu_logical_map[NR_CPUS]; extern inline int cpu_logical_map(int cpu) { return __cpu_logical_map[cpu]; } /* * General functions that each host system must provide. */ extern void smp_callin(void); extern void smp_boot_cpus(void); extern void smp_store_cpu_info(int id); /* Store per cpu info (like the initial udelay numbers */ extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ extern volatile int smp_process_available; /* * APIC handlers: Note according to the Intel specification update * you should put reads between APIC writes. * Intel Pentium processor specification update [11AP, pg 64] * "Back to Back Assertions of HOLD May Cause Lost APIC Write Cycle" */ #define APIC_BASE ((char *)0xFEE00000) extern __inline void apic_write(unsigned long reg, unsigned long v) { *((volatile unsigned long *)(APIC_BASE+reg))=v; } extern __inline unsigned long apic_read(unsigned long reg) { return *((volatile unsigned long *)(APIC_BASE+reg)); } /* * This function is needed by all SMP systems. It must _always_ be valid * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ #define smp_processor_id() (current->processor) extern __inline int hard_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); } #endif /* !ASSEMBLY */ #define NO_PROC_ID 0xFF /* No processor magic marker */ /* * This magic constant controls our willingness to transfer * a process across CPUs. Such a transfer incurs misses on the L1 * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My * gut feeling is this will vary by board in value. For a board * with separate L2 cache it probably depends also on the RSS, and * for a board with shared L2 cache it ought to decay fast as other * processes are run. */ #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ #define SMP_FROM_INT 1 #define SMP_FROM_SYSCALL 2 #else #ifndef ASSEMBLY extern inline int cpu_logical_map(int cpu) { return cpu; } #endif #endif #endif |