[RFC][Patch] IBM Real-Time "SMI Free" mode driver



This driver supports the Real-Time Linux (RTL) BIOS feature. The RTL
feature allows non-fatal System Management Interrupts (SMIs) to be
disabled on supported IBM platforms (LS21, LS22 and HS21xm blades).

This driver creates a simple sysfs interface to allow a simple entry and
exit from RTL mode in the BIOS.

Signed-off-by: Keith Mannthey <kmannth@xxxxxxxxxx>

---

diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/ibm_rtl.c linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/ibm_rtl.c
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/ibm_rtl.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/ibm_rtl.c 2009-02-10 13:58:21.000000000 -0500
@@ -0,0 +1,205 @@
+/*
+ * IBM Real Time Linux Mode Device Driver
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ *
+ * Author: Keith Mannthey <kmannth@xxxxxxxxxx>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include "rtl.h"
+
+static unsigned int table_addr;
+
+int ibm_rtl_write(u8 value)
+{
+ int ret = 0;
+ void __iomem *rtl;
+
+ /* only valid value is 0 and 1 */
+ if (value > 1) {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+ if (!rtl) {
+ printk(KERN_WARNING "Could not ioremap RTL table\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ if (readb(rtl+RTL_STATE) != value) {
+ if (value == 1)
+ writeb(1, (rtl+RTL_CMD));
+ else
+ writeb(2, (rtl+RTL_CMD));
+
+ /*write special command*/
+ outb(bios_to_value(rtl, RTL_CMD_PORT_VALUE),
+ bios_to_value(rtl, RTL_CMD_PORT_ADDR));
+
+ while (readb(rtl+RTL_CMD))
+ msleep(10);
+
+ if (readb(rtl+RTL_CMD_STATUS))
+ ret = -EIO;
+ }
+
+ iounmap(rtl);
+err_out:
+ return ret;
+}
+
+static ssize_t rtl_show_version(struct sysdev_class *dev, char * buf)
+{
+ int ret;
+ void __iomem *rtl;
+
+ rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+ if (!rtl) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+ ret = sprintf(buf, "%d\n", (int)readb(rtl+RTL_VERSION));
+
+ iounmap(rtl);
+err_out:
+ return ret;
+}
+
+static ssize_t rtl_show_state(struct sysdev_class *dev, char *buf)
+{
+ int ret;
+ void __iomem *rtl;
+
+ rtl = ioremap(table_addr, RTL_TABLE_SIZE);
+
+ if (!rtl) {
+ printk(KERN_WARNING "Could not ioremap RTL table\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+ ret = sprintf(buf, "%d\n", readb(rtl+RTL_STATE));
+
+ iounmap(rtl);
+err_out:
+ return ret;
+}
+
+static ssize_t rtl_set_state(struct sysdev_class *dev, const char *buf,
+ size_t size)
+{
+ ssize_t ret;
+ switch (buf[0]) {
+ case '0':
+ ret = ibm_rtl_write(0);
+ break;
+ case '1':
+ ret = ibm_rtl_write(1);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ if (ret >= 0)
+ ret = size;
+
+ return ret;
+}
+
+static struct sysdev_class class_rtl = {
+ .name = "ibm_rtl",
+};
+
+static SYSDEV_CLASS_ATTR(version, S_IRUGO, rtl_show_version, NULL);
+static SYSDEV_CLASS_ATTR(state, 0600, rtl_show_state, rtl_set_state);
+
+static struct sysdev_class_attribute *rtl_attributes[] = {
+ &attr_version,
+ &attr_state,
+ NULL
+};
+
+
+static int rtl_setup_sysfs(void)
+{
+ int ret, i;
+ ret = sysdev_class_register(&class_rtl);
+
+ if (!ret) {
+ for (i = 0; rtl_attributes[i]; i++)
+ sysdev_class_create_file(&class_rtl, rtl_attributes[i]);
+ }
+ return ret;
+}
+
+static void rtl_teardown_sysfs(void)
+{
+ int i;
+ for (i = 0; rtl_attributes[i]; i++)
+ sysdev_class_remove_file(&class_rtl, rtl_attributes[i]);
+ sysdev_class_unregister(&class_rtl);
+ return;
+}
+
+/* only allow the modules to load if the _RTL_ table can be found*/
+int init_module(void)
+{
+ unsigned long ebda_addr, ebda_size;
+ void __iomem *data, *d;
+ int ret, i;
+
+ /*get the address for the RTL table from the EBDA */
+ ebda_addr = *(unsigned short *)phys_to_virt(0x40E);
+ ebda_addr <<= 4;
+ ebda_size = 64*1024;
+
+ data = ioremap(ebda_addr, ebda_size);
+ d = data;
+ if (!data) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ for (i = 0 ; i < ebda_size/4; i++) {
+ unsigned int *tmp = (unsigned int *) data++;
+ if (*tmp == RTL_MAGIC_IDENT) {
+ table_addr = ebda_addr + i;
+ ret = rtl_setup_sysfs();
+ goto exit;
+ }
+ }
+
+ ret = -ENODEV;
+
+exit:
+ iounmap(d);
+ return ret;
+}
+
+void cleanup_module(void)
+{
+ rtl_teardown_sysfs();
+}
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/Makefile linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/Makefile
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/Makefile 2009-02-05 12:38:35.000000000 -0500
@@ -0,0 +1 @@
+obj-$(CONFIG_IBM_RTL) := ibm_rtl.o
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/rtl.h linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/rtl.h
--- linux-2.6.29-rc3-git7-orig/drivers/misc/ibmrtl/rtl.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/ibmrtl/rtl.h 2009-02-10 13:58:12.000000000 -0500
@@ -0,0 +1,49 @@
+/*
+ * IBM Real Time Linux Mode Device Driver
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) IBM Corporation, 2009
+ *
+ * Author: Keith Mannthey <kmannth@xxxxxxxxxx>
+ *
+ */
+
+#include <linux/io.h>
+
+/* The RTL table looks something like
+ u8 signature[5];
+ u8 version;
+ u8 RT_Status;
+ u8 Command;
+ u8 CommandStatus;
+ u8 CMDAddressType;
+ u8 CmdGranularity;
+ u8 CmdOffset;
+ u16 Reserve1;
+ u8 CmdPortAddress[4];
+ u8 CmdPortValue[4];
+*/
+#define RTL_TABLE_SIZE 0x16
+#define RTL_MAGIC_IDENT (('L'<<24)|('T'<<16)|('R'<<8)|'_')
+#define RTL_VERSION 0x5
+#define RTL_STATE 0x6
+#define RTL_CMD 0x7
+#define RTL_CMD_STATUS 0x8
+#define RTL_CMD_PORT_ADDR 0xE
+#define RTL_CMD_PORT_VALUE 0x12
+
+/*needed to decode CmdPortAddress and CmdPortValue*/
+#define bios_to_value(rtl, offset) (u32)((readb(rtl+(offset+1)) << 8) + \
+ readb(rtl+offset))
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/Kconfig linux-2.6.29-rc3-git7/drivers/misc/Kconfig
--- linux-2.6.29-rc3-git7-orig/drivers/misc/Kconfig 2009-02-05 12:29:22.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/Kconfig 2009-02-05 12:45:48.000000000 -0500
@@ -75,6 +75,21 @@
website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
information on the specific driver level and support statement
for your IBM server.
+config IBM_RTL
+ tristate "Device driver to enable IBM PRTL support"
+ depends on X86 && PCI && EXPERIMENTAL
+ ---help---
+ Enable support for IBM Preimium Real Time Mode (PRTM).
+ This module will allow you the enter and exit PRTM in the BIOS via
+ sysfs on platforms that support this feature. System in PRTM will
+ not recive cpu generated SMIs for recoverable errors. Use of this
+ feature without proper support may void your hardware warrenty.
+
+ If the proper bios support is found the driver will load and create
+ /sys/devices/system/ibm_rtl/. The "state" varable will indicate
+ weather or not the BIOS is in PRTM.
+ state = 0 (BIOS SMI's on)
+ state = 1 (BIOS SMI's off)

config PHANTOM
tristate "Sensable PHANToM (PCI)"
diff -urN linux-2.6.29-rc3-git7-orig/drivers/misc/Makefile linux-2.6.29-rc3-git7/drivers/misc/Makefile
--- linux-2.6.29-rc3-git7-orig/drivers/misc/Makefile 2009-02-05 12:29:22.000000000 -0500
+++ linux-2.6.29-rc3-git7/drivers/misc/Makefile 2009-02-05 12:39:54.000000000 -0500
@@ -3,6 +3,7 @@
#

obj-$(CONFIG_IBM_ASM) += ibmasm/
+obj-$(CONFIG_IBM_RTL) += ibmrtl/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • [PATCH] atl1c:Atheros L1C Gigabit Ethernet driver
    ... To compile this driver as a module, ... * under the terms of the GNU General Public License as published by the Free ... * @adapter: board private structure ... * @netdev: network interface device structure ...
    (Linux-Kernel)
  • [PATCH net-next] atl1e: Atheros L1E Gigabit Ethernet driver
    ... To compile this driver as a module, ... * under the terms of the GNU General Public License as published by the Free ... without even the implied warranty of MERCHANTABILITY or ... if not, write to the Free Software Foundation, Inc., 59 ...
    (Linux-Kernel)
  • [PATCH] This is the security processor driver for the Intel mid platform
    ... This is the driver for the Security Processor for the Intel MID Platform. ... new file mode 100644 ... * under the terms of the GNU General Public License as published by the Free ... without even the implied warranty of MERCHANTABILITY or ...
    (Linux-Kernel)
  • Kernel connector - userspace <-> kernelspace "linker".
    ... Connector driver adds possibility to connect various agents using ... * This program is free software; you can redistribute it and/or modify ... * GNU General Public License for more details. ...
    (Linux-Kernel)
  • [PATCH net-next] atl1e: Atheros L1E Gigabit Ethernet driver
    ... To compile this driver as a module, ... * under the terms of the GNU General Public License as published by the Free ... without even the implied warranty of MERCHANTABILITY or ... if not, write to the Free Software Foundation, Inc., 59 ...
    (Linux-Kernel)