diff options
-rw-r--r-- | arch/x86_64/Kconfig | 18 | ||||
-rw-r--r-- | arch/x86_64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86_64/kernel/vsmp.c | 45 | ||||
-rw-r--r-- | include/asm-x86_64/system.h | 18 | ||||
-rw-r--r-- | include/linux/pci_ids.h | 3 |
5 files changed, 85 insertions, 0 deletions
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index ee053e32a721..2efc4be22709 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -79,6 +79,24 @@ source "init/Kconfig" | |||
79 | menu "Processor type and features" | 79 | menu "Processor type and features" |
80 | 80 | ||
81 | choice | 81 | choice |
82 | prompt "Subarchitecture Type" | ||
83 | default X86_PC | ||
84 | |||
85 | config X86_PC | ||
86 | bool "PC-compatible" | ||
87 | help | ||
88 | Choose this option if your computer is a standard PC or compatible. | ||
89 | |||
90 | config X86_VSMP | ||
91 | bool "Support for ScaleMP vSMP" | ||
92 | help | ||
93 | Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is | ||
94 | supposed to run on these EM64T-based machines. Only choose this option | ||
95 | if you have one of these machines. | ||
96 | |||
97 | endchoice | ||
98 | |||
99 | choice | ||
82 | prompt "Processor family" | 100 | prompt "Processor family" |
83 | default MK8 | 101 | default MK8 |
84 | 102 | ||
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 7df09edb36a1..72fe60c20d39 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o | |||
32 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | 32 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
33 | obj-$(CONFIG_KPROBES) += kprobes.o | 33 | obj-$(CONFIG_KPROBES) += kprobes.o |
34 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o | 34 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o |
35 | obj-$(CONFIG_X86_VSMP) += vsmp.o | ||
35 | 36 | ||
36 | obj-$(CONFIG_MODULES) += module.o | 37 | obj-$(CONFIG_MODULES) += module.o |
37 | 38 | ||
diff --git a/arch/x86_64/kernel/vsmp.c b/arch/x86_64/kernel/vsmp.c new file mode 100644 index 000000000000..92f70c74965f --- /dev/null +++ b/arch/x86_64/kernel/vsmp.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * vSMPowered(tm) systems specific initialization | ||
3 | * Copyright (C) 2005 ScaleMP Inc. | ||
4 | * | ||
5 | * Use of this code is subject to the terms and conditions of the | ||
6 | * GNU general public license version 2. See "COPYING" or | ||
7 | * http://www.gnu.org/licenses/gpl.html | ||
8 | * | ||
9 | * Ravikiran Thirumalai <kiran@scalemp.com>, | ||
10 | * Shai Fultheim <shai@scalemp.com> | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/pci_ids.h> | ||
15 | #include <linux/pci_regs.h> | ||
16 | #include <asm/pci-direct.h> | ||
17 | |||
18 | static int __init vsmp_init(void) | ||
19 | { | ||
20 | void *address; | ||
21 | unsigned int cap, ctl; | ||
22 | |||
23 | /* Check if we are running on a ScaleMP vSMP box */ | ||
24 | if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || | ||
25 | (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) | ||
26 | return 0; | ||
27 | |||
28 | /* set vSMP magic bits to indicate vSMP capable kernel */ | ||
29 | address = ioremap(read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0), 8); | ||
30 | cap = readl(address); | ||
31 | ctl = readl(address + 4); | ||
32 | printk("vSMP CTL: capabilities:0x%08x control:0x%08x\n", cap, ctl); | ||
33 | if (cap & ctl & (1 << 4)) { | ||
34 | /* Turn on vSMP IRQ fastpath handling (see system.h) */ | ||
35 | ctl &= ~(1 << 4); | ||
36 | writel(ctl, address + 4); | ||
37 | ctl = readl(address + 4); | ||
38 | printk("vSMP CTL: control set to:0x%08x\n", ctl); | ||
39 | } | ||
40 | |||
41 | iounmap(address); | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | core_initcall(vsmp_init); | ||
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index 80272190570e..38c1e8a69c9c 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h | |||
@@ -326,8 +326,25 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |||
326 | /* interrupt control.. */ | 326 | /* interrupt control.. */ |
327 | #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) | 327 | #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) |
328 | #define local_irq_restore(x) __asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc") | 328 | #define local_irq_restore(x) __asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc") |
329 | |||
330 | #ifdef CONFIG_X86_VSMP | ||
331 | /* Interrupt control for VSMP architecture */ | ||
332 | #define local_irq_disable() do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags & ~(1 << 9)) | (1 << 18)); } while (0) | ||
333 | #define local_irq_enable() do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags | (1 << 9)) & ~(1 << 18)); } while (0) | ||
334 | |||
335 | #define irqs_disabled() \ | ||
336 | ({ \ | ||
337 | unsigned long flags; \ | ||
338 | local_save_flags(flags); \ | ||
339 | (flags & (1<<18)) || !(flags & (1<<9)); \ | ||
340 | }) | ||
341 | |||
342 | /* For spinlocks etc */ | ||
343 | #define local_irq_save(x) do { local_save_flags(x); local_irq_restore((x & ~(1 << 9)) | (1 << 18)); } while (0) | ||
344 | #else /* CONFIG_X86_VSMP */ | ||
329 | #define local_irq_disable() __asm__ __volatile__("cli": : :"memory") | 345 | #define local_irq_disable() __asm__ __volatile__("cli": : :"memory") |
330 | #define local_irq_enable() __asm__ __volatile__("sti": : :"memory") | 346 | #define local_irq_enable() __asm__ __volatile__("sti": : :"memory") |
347 | |||
331 | /* used in the idle loop; sti takes one instruction cycle to complete */ | 348 | /* used in the idle loop; sti takes one instruction cycle to complete */ |
332 | #define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") | 349 | #define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") |
333 | /* used when interrupts are already enabled or to shutdown the processor */ | 350 | /* 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, | |||
342 | 359 | ||
343 | /* For spinlocks etc */ | 360 | /* For spinlocks etc */ |
344 | #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) | 361 | #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) |
362 | #endif | ||
345 | 363 | ||
346 | void cpu_idle_wait(void); | 364 | void cpu_idle_wait(void); |
347 | 365 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f55c98a68aa9..7fb397e3f2d3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2152,6 +2152,9 @@ | |||
2152 | #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 | 2152 | #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 |
2153 | #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 | 2153 | #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 |
2154 | 2154 | ||
2155 | #define PCI_VENDOR_ID_SCALEMP 0x8686 | ||
2156 | #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010 | ||
2157 | |||
2155 | #define PCI_VENDOR_ID_COMPUTONE 0x8e0e | 2158 | #define PCI_VENDOR_ID_COMPUTONE 0x8e0e |
2156 | #define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 | 2159 | #define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 |
2157 | #define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 | 2160 | #define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 |