Module: xenomai-forge
Branch: master
Commit: b24ecd4444a1be901b1f8fbb33778a662f3193e1
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=b24ecd4444a1be901b1f8fbb33778a662f3193e1

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sat Apr 13 22:05:01 2013 +0200

cobalt/x86: allow SMI control at run-time

Having to recompile the kernel when we want to change the settings regarding
SMI workaround is not really compatible with distributing pre-compiled kernels.
So we make the control possible with two kernel parameters. Allowing to compile
out the functionality did not save a lot of room anyway.

At this chance, suppress the PCI ids table which was a maintenance burden, any
Intel chipset with a PCI-ISA bridge is assumed to allow SMI workaround.

By default, the module detects the chipset but does nothing. Setting:
- xeno_hal.smi to -1 disables SMI detection
- xeno_hal.smi to 1 enables SMI workaround, the parameter xeno_hal.smi_mask
controls which bits are masked. If not set, the bit 0 is masked which means
SMI are globally disabled.

---

 include/asm-x86/smi.h           |   15 +--
 kernel/cobalt/arch/x86/Kconfig  |  135 -----------------------------
 kernel/cobalt/arch/x86/Makefile |    3 +-
 kernel/cobalt/arch/x86/smi.c    |  179 +++++++--------------------------------
 4 files changed, 36 insertions(+), 296 deletions(-)

diff --git a/include/asm-x86/smi.h b/include/asm-x86/smi.h
index 959f124..f382bbf 100644
--- a/include/asm-x86/smi.h
+++ b/include/asm-x86/smi.h
@@ -19,6 +19,9 @@
  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifndef _XENO_ASM_X86_SMI_H
+#define _XENO_ASM_X86_SMI_H
+
 #ifndef __KERNEL__
 #error "Pure kernel header included from user-space!"
 #endif
@@ -27,16 +30,8 @@
 #error "please don't include asm/smi.h directly"
 #endif
 
-#if defined(CONFIG_XENO_HW_SMI_DETECT) && 
defined(CONFIG_XENO_HW_SMI_WORKAROUND)
 void mach_x86_smi_disable(void);
 void mach_x86_smi_restore(void);
-#else /* !CONFIG_XENO_HW_SMI_DETECT || !CONFIG_XENO_HW_SMI_WORKAROUND */
-static inline void mach_x86_smi_disable(void) { }
-static inline void mach_x86_smi_restore(void) { }
-#endif /* !CONFIG_XENO_HW_SMI_DETECT || !CONFIG_XENO_HW_SMI_WORKAROUND */
-
-#ifdef CONFIG_XENO_HW_SMI_DETECT
 void mach_x86_smi_init(void);
-#else /* !CONFIG_XENO_HW_SMI_DETECT */
-static inline void mach_x86_smi_init(void) { }
-#endif /* CONFIG_XENO_HW_SMI_DETECT */
+
+#endif /* !_XENO_ASM_X86_SMI_64_H */
diff --git a/kernel/cobalt/arch/x86/Kconfig b/kernel/cobalt/arch/x86/Kconfig
index 9025fcf..0f5a0b2 100644
--- a/kernel/cobalt/arch/x86/Kconfig
+++ b/kernel/cobalt/arch/x86/Kconfig
@@ -14,141 +14,6 @@ config XENO_HW_FPU
        Float-Point Unit on the x86 platform at the following URL:
        http://www.intel.com/design/intarch/techinfo/Pentium/fpu.htm
 
-menu "SMI workaround"
-
-config XENO_HW_SMI_DETECT_DISABLE
-       bool "Disable SMI detection"
-       default n
-       help
-       SMI are System Management Interrupts, generated by Intel ICH
-       (I/O connector hubs) to allow handling of some specific events;
-       on systems where they exist, they are the highest priority
-       interrupts (even higher priority than NMIs). Common SMI sources
-       are power management, legacy devices emulation by BIOS, SMBus
-       and TCO watchdog.
-
-       SMI are problematic for Xenomai, because their handling may span
-       accross hundreds of microseconds, causing unacceptable interrupt
-       latency. Furthermore, their vectors are stored in some ROM,
-       and hence may not be altered.
-
-       For this reason, Xenomai contains code to detect chipsets using
-       SMIs and optionally activate some workarounds to stop SMIs.
-
-       Enabling this option prevents Xenomai from detecting whether
-       your hardware use SMIs. This option is mostly useful if you know
-       that your system does not use SMIs and really want to size Xenomai
-       modules down. The detection code has no run-time space overhead,
-       and a tiny memory footprint (<200 bytes on x86)
-
-config XENO_HW_SMI_DETECT
-       bool
-       depends on !XENO_HW_SMI_DETECT_DISABLE
-       default y
-
-config XENO_HW_SMI_WORKAROUND
-       depends on XENO_HW_SMI_DETECT
-       bool "Enable SMI workaround"
-       default n
-       help
-       SMI are System Management Interrupts, generated by Intel ICH
-       (I/O connector hubs) to allow handling of some specific events;
-       on systems where they exist, they are the highest priority
-       interrupts (even higher priority than NMIs). Common SMI sources
-       are power management, legacy devices emulation by BIOS, SMBus
-       and TCO watchdog.
-
-       SMI are problematic for Xenomai, because their handling may span
-       accross hundreds of microseconds, causing unacceptable interrupt
-       latency. Furthermore, their vectors are stored in some ROM,
-       and hence may not be altered.
-
-       For this reason, Xenomai contains code to detect chipsets using
-       SMIs and optionally activate some workarounds to stop SMIs.
-       Enabling this option cause those workarounds to be activated.
-
-if XENO_HW_SMI_WORKAROUND
-
-config XENO_HW_SMI_ALL
-       bool "Globally disable SMI"
-       default y
-       help
-       This option causes the SMIs to be globally disabled, which avoid
-       any jitter they could cause with a big drawback: any peripheral or
-       feature relying on them will stop working when Xenomai is running.
-
-       The alternative is to selectively enable the SMIs sources needed
-       by your peripherals. The main drawback is that the peripheral
-       which you need may be the one causing jitter, so that extensive
-       testing is needed when choosing to not disable SMI globally.
-       Another drawback is that other unknown SMI sources may exist which
-       Xenomai can not disable.
-
-       This option causes the SMIs to be globally disabled.
-
-config XENO_HW_SMI_INTEL_USB2
-       bool "Enable Intel-Specific USB2 SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables Intel-specific USB2 SMI logic to cause SMIs.
-
-config XENO_HW_SMI_LEGACY_USB2
-       bool "Enable legacy USB2 SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables legacy USB2 logic to cause SMIs.
-
-config XENO_HW_SMI_PERIODIC
-       bool "Enable periodic SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables the ICH to generate a periodic SMI.
-
-config XENO_HW_SMI_TCO
-       bool "Enable TCO SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables the TCO logic to generate SMIs.
-
-config XENO_HW_SMI_MC
-       bool "Enable microcontroller SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables the ICH to trap access to the
-       microcontroller range.
-
-config XENO_HW_SMI_APMC
-       bool "Enable APM SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables writes to the APM control register to
-       cause SMIs.
-
-config XENO_HW_SMI_LEGACY_USB
-       bool "Enable legacy USB SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables legacy USB circuit to cause SMIs.
-
-config XENO_HW_SMI_BIOS
-       bool "Enable ACPI BIOS SMI"
-       depends on !XENO_HW_SMI_ALL
-       default n
-       help
-       This options enables SMI to be used for communication
-       between ACPI software and BIOS software.
-
-endif
-
-endmenu
-
 endmenu
 
 source "kernel/xenomai/nucleus/Kconfig"
diff --git a/kernel/cobalt/arch/x86/Makefile b/kernel/cobalt/arch/x86/Makefile
index 2001b8e..998f65b 100644
--- a/kernel/cobalt/arch/x86/Makefile
+++ b/kernel/cobalt/arch/x86/Makefile
@@ -1,6 +1,5 @@
 
 obj-$(CONFIG_XENOMAI) += x86_hal.o
-x86_hal-y := machine.o mayday.o thread.o
-x86_hal-$(CONFIG_XENO_HW_SMI_DETECT) += smi.o
+x86_hal-y := machine.o mayday.o thread.o smi.o
 
 ccflags-y := -D__IN_XENOMAI__ -Iinclude/xenomai/cobalt -Iinclude/xenomai
diff --git a/kernel/cobalt/arch/x86/smi.c b/kernel/cobalt/arch/x86/smi.c
index c78317c..e06734a 100644
--- a/kernel/cobalt/arch/x86/smi.c
+++ b/kernel/cobalt/arch/x86/smi.c
@@ -29,95 +29,20 @@
 #include <asm-generic/xenomai/pci_ids.h>
 #include <asm/xenomai/machine.h>
 
-static struct pci_device_id smi_pci_tbl[] = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_5)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_LPC_MIN+7)},
-       {0,},
-};
+#define DEVFN          0xf8    /* device 31, function 0 */
+
+#define PMBASE_B0      0x40
+#define PMBASE_B1      0x41
+
+#define SMI_CTRL_ADDR  0x30
 
-/* FIXME: Probably crippled too, need to be checked :
-
-0x24dc 82801EB (ICH5) LPC Interface Bridge (not a real ID, but exists in the
-pci.ids database, ICH5-M ?)
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, PCI_ANY_ID, PCI_ANY_ID, 
},
-
-*/
-
-#define DEVFN        0xf8      /* device 31, function 0 */
-
-#ifdef CONFIG_XENO_HW_SMI_WORKAROUND
-
-#define PMBASE_B0    0x40
-#define PMBASE_B1    0x41
-
-#define SMI_CTRL_ADDR    0x30
-#define SMI_STATUS_ADDR  0x34
-#define SMI_MON_ADDR     0x40
-
-/* SMI_EN register: ICH[0](16 bits), ICH[2-5](32 bits) */
-#define INTEL_USB2_EN_BIT   (0x01 << 18)       /* ICH4, ... */
-#define LEGACY_USB2_EN_BIT  (0x01 << 17)       /* ICH4, ... */
-#define PERIODIC_EN_BIT     (0x01 << 14)       /* called 1MIN_ in ICH0 */
-#define TCO_EN_BIT          (0x01 << 13)
-#define MCSMI_EN_BIT        (0x01 << 11)
-#define SWSMI_TMR_EN_BIT    (0x01 << 6)
-#define APMC_EN_BIT         (0x01 << 5)
-#define SLP_EN_BIT          (0x01 << 4)
-#define LEGACY_USB_EN_BIT   (0x01 << 3)
-#define BIOS_EN_BIT         (0x01 << 2)
-#define GBL_SMI_EN_BIT      (0x01)     /* This is reset by a PCI reset event! 
*/
-
-static const unsigned smi_masked_bits =
-#ifdef CONFIG_XENO_HW_SMI_ALL
-    GBL_SMI_EN_BIT;
-#else /* !defined(CONFIG_XENO_HW_SMI_ALL) */
-    0
-#ifndef CONFIG_XENO_HW_SMI_INTEL_USB2
-    | INTEL_USB2_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_INTEL_USB2) */
-#ifndef CONFIG_XENO_HW_SMI_LEGACY_USB2
-    | LEGACY_USB2_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_LEGACY_USB2) */
-#ifndef CONFIG_XENO_HW_SMI_PERIODIC
-    | PERIODIC_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_PERIODC) */
-#ifndef CONFIG_XENO_HW_SMI_TCO
-    | TCO_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_TCO) */
-#ifndef CONFIG_XENO_HW_SMI_MC
-    | MCSMI_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_MCSMI) */
-#ifndef CONFIG_XENO_HW_SMI_APMC
-    | APMC_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_APMC) */
-#ifndef CONFIG_XENO_HW_SMI_LEGACY_USB
-    | LEGACY_USB_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_LEGACY_USB) */
-#ifndef CONFIG_XENO_HW_SMI_BIOS
-    | BIOS_EN_BIT
-#endif /* !defined(CONFIG_XENO_HW_SMI_BIOS) */
-    ;
-
-#endif /* !defined(CONFIG_XENO_HW_SMI_ALL) */
+static int smi_state;
+module_param_named(smi, smi_state, int, 0400);
+MODULE_PARM_DESC(smi, "SMI workaround: -1=disable, 0=detect only, 1=enable");
+
+static unsigned int smi_masked_bits = 1; /* Global disable bit */
+module_param_named(smi_mask, smi_masked_bits, int, 0400);
+MODULE_PARM_DESC(smi_mask, "Set of bits to mask in the SMI control register");
 
 static unsigned int smi_saved_bits;
 static unsigned short smi_en_addr;
@@ -142,7 +67,7 @@ static int smi_reboot(struct notifier_block *nb, ulong 
event, void *buf)
 
 void mach_x86_smi_disable(void)
 {
-       if (!smi_en_addr)
+       if (smi_en_addr == 0)
                return;
 
        smi_saved_bits = inl(smi_en_addr) & smi_masked_bits;
@@ -158,7 +83,7 @@ void mach_x86_smi_disable(void)
 
 void mach_x86_smi_restore(void)
 {
-       if (!smi_en_addr)
+       if (smi_en_addr == 0)
                return;
 
        printk("Xenomai: SMI configuration restored\n");
@@ -177,79 +102,35 @@ static unsigned short get_smi_en_addr(struct pci_dev *dev)
        return SMI_CTRL_ADDR + (((byte1 << 1) | (byte0 >> 7)) << 7);    // bits 
7-15
 }
 
-#endif /* CONFIG_XENO_HW_SMI_WORKAROUND */
-
 void mach_x86_smi_init(void)
 {
        struct pci_dev *dev = NULL;
-       struct pci_device_id *id;
+
+       if (smi_state < 0)
+               return;
 
        /*
         * Do not use pci_register_driver, pci_enable_device, ...
         * Just register the used ports.
         */
-       for (id = &smi_pci_tbl[0]; dev == NULL && id->vendor != 0; id++)
-               dev = pci_get_device(id->vendor, id->device, NULL);
+       dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+       if (dev == NULL || dev->bus->number || 
+           dev->devfn != DEVFN || dev->vendor != PCI_VENDOR_ID_INTEL) {
+               pci_dev_put(dev);
+               return;
+       }
 
-       if (dev == NULL || dev->bus->number || dev->devfn != DEVFN) {
+       if (smi_state == 0) {
+               printk("Xenomai: SMI-enabled chipset found, but SMI "
+                      "workaround disabled\n"
+                      "         (see xeno_hal.smi parameter). You may 
encounter\n"
+                      "         high interrupt latencies!\n");
                pci_dev_put(dev);
                return;
        }
-#ifdef CONFIG_XENO_HW_SMI_WORKAROUND
+
        printk("Xenomai: SMI-enabled chipset found\n");
        smi_en_addr = get_smi_en_addr(dev);
-#else /* ! CONFIG_XENO_HW_SMI_WORKAROUND */
-       printk
-           ("Xenomai: SMI-enabled chipset found, but SMI workaround disabled\n"
-            "         (check CONFIG_XENO_HW_SMI_WORKAROUND). You may 
encounter\n"
-            "         high interrupt latencies!\n");
-#endif /* ! CONFIG_XENO_HW_SMI_WORKAROUND */
 
        pci_dev_put(dev);
 }
-
-/*
-
-   FIXME: there are many more SMI sources than those of the SMI_EN
-   register. From http://www.intel.com/design/chipsets/datashts/252516.htm
-   there are at least the following other sources :
-
-   pages 377, 386, 388, 389; Power management
-       register GEN_PMCON1, bit SMI_LOCK, locks GLB_SMI_EN
-       bits PER_SMI_SEL, allow selection of the periodic SMI
-       registers PM1_STS, PM1_EN, PM1_CNT bit SCI_EN, if cleared generates SMI
-       for power management events.
-
-   pages 173, 381, 400; GPIOs
-       register GPI[0-15]_ROUT allow routing each GPIO to SMI or SCI
-       register ALT_GP_SMI_EN, ALT_GP_SMI_STS, allow masking SMIs for GPIOs
-
-   pages 184, 188, 402; legacy devices emulation (ATA, floppy, parallel, UARTs,
-       keyboard). I/O to specified ports may cause events, which can generate 
an
-       SMI, depending on registers configuration :
-       register DEVTRAP_EN, DEVTRAP_STS
-       BIG FAT WARNING : globally disabling SMI on a box with SATA disks and
-          SATA controller in "legacy" mode, probably prevents disks from
-          working.
-
-   pages 382, 383, 400; Monitors ?
-       seem to be a generic legacy device emulation (like previous), registers
-       MON[4-7]_FWD_EN, enables forwarding of I/O to LPC
-       MON[4-7]_TRP_RNG, address of the emulated devices
-       MON[4-7]_TRP_MSK and MON_SMI (registers MON[4-7]_TRAP_EN and
-                                    MON[4-7]_TRAP_STS)
-
-   page 407: TCO
-       register TCO1_CNT, bit NMI2SMI_EN, enables TCO to use SMI instead of 
NMI,
-       bit TCO_TMR_HLT, should be cleared to avoid being rebooted when the TCO
-       timer expires. Dangerous bit: TCO_LOCK locks the TCO timer until reboot.
-       register used by Linux drivers/char/watchdog/i8xx_tco.c
-
-   page 492, 493: USB EHCI legacy support and SPECIAL SMI, i.e Intel Specific
-       USB 2.0 SMI register.
-
-   page 520, SMBus
-       may be disabled by clearing register HOSTC, bit SMB_SMI_EN
-       register used by Linux driver drivers/i2c/busses/i2c-i801.c
-
-*/


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to