summaryrefslogtreecommitdiffstats
path: root/include/asm-i386/smp.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /include/asm-i386/smp.h
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'include/asm-i386/smp.h')
-rw-r--r--include/asm-i386/smp.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
new file mode 100644
index 000000000..ff0caafe0
--- /dev/null
+++ b/include/asm-i386/smp.h
@@ -0,0 +1,258 @@
+#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
+ */
+
+/*
+ * Per process x86 parameters
+ */
+
+struct cpuinfo_x86
+{
+ char hard_math;
+ char x86;
+ char x86_model;
+ char x86_mask;
+ char x86_vendor_id[16];
+ int x86_capability;
+ int fdiv_bug;
+ int have_cpuid;
+ char wp_works_ok;
+ char hlt_works_ok;
+ unsigned long udelay_val;
+};
+
+
+extern struct cpuinfo_x86 cpu_data[NR_CPUS];
+
+/*
+ * 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 *apic_reg;
+extern unsigned char *kernel_stacks[NR_CPUS];
+extern unsigned char boot_cpu_id;
+extern unsigned long cpu_present_map;
+extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int cpu_logical_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 volatile unsigned long kernel_counter;
+extern volatile unsigned long syscall_count;
+
+/*
+ * 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 volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */
+extern volatile unsigned long 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"
+ */
+
+extern __inline void apic_write(unsigned long reg, unsigned long v)
+{
+ *((volatile unsigned long *)(apic_reg+reg))=v;
+}
+
+extern __inline unsigned long apic_read(unsigned long reg)
+{
+ return *((volatile unsigned long *)(apic_reg+reg));
+}
+
+/*
+ * This function is needed by all SMP systems. It must _always_ be valid from the initial
+ * startup. This may require magic on some systems (in the i86 case we dig out the boot
+ * cpu id from the config and set up a fake apic_reg pointer so that before we activate
+ * the apic we get the right answer). Hopefully other processors are more sensible 8)
+ */
+
+extern __inline int smp_processor_id(void)
+{
+ return GET_APIC_ID(apic_read(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
+
+#endif
+#endif