[PATCH] x86_64: Inclusion of ScaleMP vSMP architecture patches - vsmp_arch
authorRavikiran G Thirumalai <kiran@scalex86.org>
Wed, 11 Jan 2006 21:46:18 +0000 (22:46 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 12 Jan 2006 03:05:01 +0000 (19:05 -0800)
Introduce vSMP arch to the kernel.

This patch:
1. Adds CONFIG_X86_VSMP
2. Adds machine specific macros for local_irq_disabled, local_irq_enabled
   and irqs_disabled
3. Writes to the vSMP CTL device to indicate kernel compiled with CONFIG_VSMP

Signed-off-by: Ravikiran Thirumalai <kiran@scalemp.com>
Signed-off-by: Shai Fultheim <shai@scalemp.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/x86_64/Kconfig
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/vsmp.c [new file with mode: 0644]
include/asm-x86_64/system.h
include/linux/pci_ids.h

index ee053e3..2efc4be 100644 (file)
@@ -79,6 +79,24 @@ source "init/Kconfig"
 menu "Processor type and features"
 
 choice
+       prompt "Subarchitecture Type"
+       default X86_PC
+
+config X86_PC
+       bool "PC-compatible"
+       help
+         Choose this option if your computer is a standard PC or compatible.
+
+config X86_VSMP
+       bool "Support for ScaleMP vSMP"
+        help
+         Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
+         supposed to run on these EM64T-based machines.  Only choose this option
+         if you have one of these machines.
+
+endchoice
+
+choice
        prompt "Processor family"
        default MK8
 
index 7df09ed..72fe60c 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_GART_IOMMU)      += pci-gart.o aperture.o
 obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_X86_PM_TIMER)     += pmtimer.o
+obj-$(CONFIG_X86_VSMP)         += vsmp.o
 
 obj-$(CONFIG_MODULES)          += module.o
 
diff --git a/arch/x86_64/kernel/vsmp.c b/arch/x86_64/kernel/vsmp.c
new file mode 100644 (file)
index 0000000..92f70c7
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * vSMPowered(tm) systems specific initialization
+ * Copyright (C) 2005 ScaleMP Inc.
+ *
+ * Use of this code is subject to the terms and conditions of the
+ * GNU general public license version 2. See "COPYING" or
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Ravikiran Thirumalai <kiran@scalemp.com>,
+ * Shai Fultheim <shai@scalemp.com>
+ */
+
+#include <linux/init.h>
+#include <linux/pci_ids.h>
+#include <linux/pci_regs.h>
+#include <asm/pci-direct.h>
+
+static int __init vsmp_init(void)
+{
+       void *address;
+       unsigned int cap, ctl;
+
+       /* Check if we are running on a ScaleMP vSMP box */
+       if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) ||
+           (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
+               return 0;
+
+       /* set vSMP magic bits to indicate vSMP capable kernel */
+       address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8);
+       cap = readl(address);
+       ctl = readl(address + 4);
+       printk("vSMP CTL: capabilities:0x%08x  control:0x%08x\n", cap, ctl);
+       if (cap & ctl & (1 << 4)) {
+               /* Turn on vSMP IRQ fastpath handling (see system.h) */
+               ctl &= ~(1 << 4);
+               writel(ctl, address + 4);
+               ctl = readl(address + 4);
+               printk("vSMP CTL: control set to:0x%08x\n", ctl);
+       }
+
+       iounmap(address);
+       return 0;
+}
+
+core_initcall(vsmp_init);
index 8027219..38c1e8a 100644 (file)
@@ -326,8 +326,25 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 /* interrupt control.. */
 #define local_save_flags(x)    do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags \n\t pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
 #define local_irq_restore(x)   __asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
+
+#ifdef CONFIG_X86_VSMP
+/* Interrupt control for VSMP  architecture */
+#define local_irq_disable()    do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags & ~(1 << 9)) | (1 << 18)); } while (0)
+#define local_irq_enable()     do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags | (1 << 9)) & ~(1 << 18)); } while (0)
+
+#define irqs_disabled()                                        \
+({                                                     \
+       unsigned long flags;                            \
+       local_save_flags(flags);                        \
+       (flags & (1<<18)) || !(flags & (1<<9));         \
+})
+
+/* For spinlocks etc */
+#define local_irq_save(x)      do { local_save_flags(x); local_irq_restore((x & ~(1 << 9)) | (1 << 18)); } while (0)
+#else  /* CONFIG_X86_VSMP */
 #define local_irq_disable()    __asm__ __volatile__("cli": : :"memory")
 #define local_irq_enable()     __asm__ __volatile__("sti": : :"memory")
+
 /* used in the idle loop; sti takes one instruction cycle to complete */
 #define safe_halt()            __asm__ __volatile__("sti; hlt": : :"memory")
 /* used when interrupts are already enabled or to shutdown the processor */
@@ -342,6 +359,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 
 /* For spinlocks etc */
 #define local_irq_save(x)      do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save \n\t pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
+#endif
 
 void cpu_idle_wait(void);
 
index f55c98a..7fb397e 100644 (file)
 #define PCI_DEVICE_ID_INTEL_IXP2800    0x9004
 #define PCI_DEVICE_ID_INTEL_S21152BB   0xb152
 
+#define PCI_VENDOR_ID_SCALEMP          0x8686
+#define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010
+
 #define PCI_VENDOR_ID_COMPUTONE                0x8e0e
 #define PCI_DEVICE_ID_COMPUTONE_IP2EX  0x0291
 #define PCI_DEVICE_ID_COMPUTONE_PG     0x0302