changeset 45:bab559e0392b

rathaxes: enable irq + handle it
author Thomas Sanchez <thomas.sanchz@gmail.com>
date Mon, 09 Jan 2012 22:17:12 +0100
parents 258319759ba3
children 1cf60e316d19
files rathaxes_add_lkm_ethernet_sample.patch
diffstat 1 files changed, 256 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/rathaxes_add_lkm_ethernet_sample.patch	Sun Jan 08 17:04:01 2012 +0100
+++ b/rathaxes_add_lkm_ethernet_sample.patch	Mon Jan 09 22:17:12 2012 +0100
@@ -1,10 +1,10 @@
 # HG changeset patch
-# Parent b995d8934956b83383c144303178f3eb383d0acf
+# Parent 6d6b478219da142368f4e458b8a348f4d87867d9
 rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver
 
-diff --git a/maintainers/CMakeScripts/UseRathaxes.cmake b/maintainers/CMakeScripts/UseRathaxes.cmake
---- a/maintainers/CMakeScripts/UseRathaxes.cmake
-+++ b/maintainers/CMakeScripts/UseRathaxes.cmake
+diff -r 6d6b478219da maintainers/CMakeScripts/UseRathaxes.cmake
+--- a/maintainers/CMakeScripts/UseRathaxes.cmake	Mon Jan 09 19:24:10 2012 +0100
++++ b/maintainers/CMakeScripts/UseRathaxes.cmake	Mon Jan 09 22:16:54 2012 +0100
 @@ -193,6 +193,8 @@
  
          SET(KERNEL_OBJECT_NAME "${RATHAXES_SOURCE}_${SYSTEM}.ko")
@@ -14,17 +14,16 @@
                             # The linux Makefile to build kernel module is quite
                             # picky about file location and its own name. Let's
                             # copy our source side by side with the Makefile:
-diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt
---- a/rathaxes/samples/CMakeLists.txt
-+++ b/rathaxes/samples/CMakeLists.txt
+diff -r 6d6b478219da rathaxes/samples/CMakeLists.txt
+--- a/rathaxes/samples/CMakeLists.txt	Mon Jan 09 19:24:10 2012 +0100
++++ b/rathaxes/samples/CMakeLists.txt	Mon Jan 09 22:16:54 2012 +0100
 @@ -1,2 +1,3 @@
  ADD_SUBDIRECTORY(helloworld)
 +ADD_SUBDIRECTORY(lkm)
  ADD_SUBDIRECTORY(syntax)
-diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/CMakeLists.txt
+diff -r 6d6b478219da rathaxes/samples/lkm/CMakeLists.txt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/CMakeLists.txt	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,7 @@
 +ADD_RATHAXES_SOURCES(lkm_src lkm.rtx
 +                     RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti
@@ -33,11 +32,10 @@
 +# We can't name lkm since it's already used as the target name to generate the
 +# source (with ADD_RATHAXES_SOURCES).
 +ADD_RATHAXES_LKM(lkm lkm_src)
-diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/e1000.blt
-@@ -0,0 +1,289 @@
+diff -r 6d6b478219da rathaxes/samples/lkm/e1000.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/e1000.blt	Mon Jan 09 22:16:54 2012 +0100
+@@ -0,0 +1,435 @@
 +with e1000, Ethernet, Socket, PCI, LKM, Log
 +{
 +    template type   e1000::Context()
@@ -59,6 +57,7 @@
 +            {
 +                int                             bars;
 +                unsigned char /* __iomem */     *ioaddr;
++                int                             irq;
 +            };
 +        }
 +
@@ -92,7 +91,10 @@
 +                E1000_EEPROM_READ   = 0x00014, /* EEPROM Read - RW */
 +                E1000_CTRL_EXT      = 0x00018, /* Extended Device Control - RW */
 +                E1000_FLA           = 0x0001C, /* Flash Access - RW */
-+                E1000_MDIC          = 0x00020  /* MDI Control - RW */
++                E1000_MDIC          = 0x00020, /* MDI Control - RW */
++                E1000_IMS           = 0x000D0, /* Interrupt Mask Set */
++                E1000_IMC           = 0x000D8, /* Interrupt Mask Clear */
++                E1000_ICR           = 0x000C0  /* Interrupt Cause Read - R/clr */
 +            };
 +        }
 +
@@ -153,7 +155,16 @@
 +                E1000_CMD_RTE                   = 0x20000000, /* Routing tag enable */
 +                E1000_CMD_VME                   = 0x40000000, /* IEEE VLAN mode enable */
 +                E1000_CMD_PHY_RST               = 0x80000000, /* PHY Reset */
-+                E1000_CMD_SW2FW_INT             = 0x02000000  /* Initiate an interrupt to manageability engine */
++                E1000_CMD_SW2FW_INT             = 0x02000000, /* Initiate an interrupt to manageability engine */
++                E1000_INTR_TXDW                 = 0x00000001, /* Transmit desc written back */
++                E1000_INTR_TXQE                 = 0x00000002, /* Transmit Queue empty */
++                E1000_INTR_LSC                  = 0x00000004, /* Link Status Change */
++                E1000_INTR_RXSEQ                = 0x00000008, /* rx sequence error */
++                E1000_INTR_RXDMT0               = 0x00000010, /* rx desc min. threshold (0) */
++                E1000_INTR_RXO                  = 0x00000040, /* rx overrun */
++                E1000_INTR_RXT0                 = 0x00000080, /* rx timer intr (ring 0) */
++                E1000_INTR_MDAC                 = 0x00000200 /* MDIO access complete */
++
 +            };
 +        }
 +
@@ -166,6 +177,7 @@
 +    {
 +        chunk Ethernet::create_device()
 +        {
++            rtx_ether_ctx->hw_ctx.irq = pdev->irq;
 +            rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM);
 +            if (pci_enable_device_mem(pdev))
 +            {
@@ -326,12 +338,143 @@
 +            rtx_e1000_register_write32(&${ctx}, ${reg_offset});
 +        }
 +    }
++
++    template sequence   e1000::register_set32(e1000::Context ctx, e1000::Register reg_offset, ::number value)
++    {
++        chunk   LKM::prototypes()
++        {
++            static void rtx_e1000_register_set32(struct rtx_e1000_ctx *, unsigned int, unsigned int);
++        }
++
++        chunk   LKM::code()
++        {
++            static void rtx_e1000_register_set32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset, unsigned int value)
++            {
++                iowrite32(rtx_e1000_register_read32(ctx, reg_offset) | value, ctx->ioaddr + reg_offset);
++            }
++        }
++
++        chunk   ::CALL()
++        {
++        }
++    }
++
++    template sequence   e1000::setup_interrupt_handler()
++    {
++        chunk   LKM::includes()
++        {
++            #include <linux/interrupt.h>
++        }
++        chunk   LKM::prototypes()
++        {
++            static int e1000_setup_interrupt_handler(struct rtx_ethernet_dev *);
++        }
++
++        chunk   LKM::code()
++        {
++            static int e1000_setup_interrupt_handler(struct rtx_ethernet_dev *ethernet_ctx)
++            {
++                int error;
++
++                error = request_irq(ethernet_ctx->hw_ctx.irq,
++                        rtx_ethernet_interrupt_handler,
++                        IRQF_SHARED,
++                        ${config.name},
++                        ethernet_ctx);
++
++                if (error)
++                {
++                    ${Log::info("Cannot register the interruption")};
++                }
++
++                return error;
++            }
++        }
++
++        chunk   ::CALL()
++        {
++            // this is an hack for the scope
++            (void)1;
++            {
++                int error;
++                error = e1000_setup_interrupt_handler(rtx_ether_dev);
++                if (error)
++                {
++                    return error;
++                }
++            }
++        }
++    }
++
++    template sequence   e1000::free_interrupt_handler()
++    {
++        chunk   LKM::prototypes()
++        {
++            static void e1000_free_interrupt_handler(struct rtx_ethernet_dev *ethernet_ctx);
++        }
++
++        chunk LKM::code()
++        {
++            static void e1000_free_interrupt_handler(struct rtx_ethernet_dev *ethernet_ctx)
++            {
++
++                free_irq(ethernet_ctx->hw_ctx.irq, ethernet_ctx);
++            }
++        }
++
++        chunk ::CALL()
++        {
++            e1000_free_interrupt_handler(rtx_ether_dev);
++        }
++    }
++
++    template sequence   e1000::activate_device_interruption()
++    {
++        chunk  ::CALL()
++        {
++            rtx_e1000_register_write32(ctx, E1000_IMS,
++                    E1000_INTR_TXDW |
++                    E1000_INTR_TXQE |
++                    E1000_INTR_LSC  |
++                    E1000_INTR_RXO  |
++                    E1000_INTR_RXT0);
++        }
++    }
++
++    template sequence   e1000::set_up_device()
++    {
++        chunk  ::CALL()
++        {
++            rtx_e1000_register_set32(ctx, E1000_CTRL, E1000_CMD_ASDE
++                    | E1000_CMD_SLU
++                    | E1000_CMD_LRST
++                    | E1000_CMD_PHY_RST);
++        }
++    }
++
++    template sequence   e1000::handle_intr()
++    {
++        chunk   ::CALL()
++        {
++            int intr;
++
++            intr = rtx_e1000_register_read32(ctx, E1000_ICR);
++            if (intr & E1000_INTR_LSC)
++            {
++                ${Log::info("Link status changed")};
++            }
++
++            if (intr)
++            {
++                return IRQ_HANDLED;
++            }
++        }
++    }
 +}
-diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/e1000.rti
-@@ -0,0 +1,51 @@
+diff -r 6d6b478219da rathaxes/samples/lkm/e1000.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/e1000.rti	Mon Jan 09 22:16:54 2012 +0100
+@@ -0,0 +1,89 @@
 +interface e1000 : Socket, Ethernet, PCI, LKM
 +{
 +    provided type   e1000::Context;
@@ -369,6 +512,37 @@
 +        provided chunk  ::CALL;
 +    }
 +
++    provided sequence   e1000::setup_interrupt_handler()
++    {
++        provided chunk  LKM::includes; // work without this one
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++        provided chunk  ::CALL;
++    }
++
++    provided sequence   e1000::free_interrupt_handler()
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++        provided chunk  ::CALL;
++    }
++
++    provided sequence   e1000::activate_device_interruption()
++    {
++        provided chunk  ::CALL;
++    }
++
++    provided sequence   e1000::set_up_device()
++    {
++        provided chunk  ::CALL;
++    }
++
++    provided sequence   e1000::handle_intr()
++    {
++        provided chunk  ::CALL;
++    }
++
++
 +    provided sequence   e1000::register_read32(e1000::Context, e1000::Register)
 +    {
 +        provided chunk  LKM::prototypes;
@@ -382,12 +556,18 @@
 +        provided chunk  LKM::code;
 +        provided chunk  ::CALL;
 +    }
++
++    provided sequence   e1000::register_set32(e1000::Context, e1000::Register, ::number)
++    {
++        provided chunk  LKM::prototypes;
++        provided chunk  LKM::code;
++        provided chunk  ::CALL;
++    }
 +}
-diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/ethernet.blt
-@@ -0,0 +1,207 @@
+diff -r 6d6b478219da rathaxes/samples/lkm/ethernet.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/ethernet.blt	Mon Jan 09 22:16:54 2012 +0100
+@@ -0,0 +1,218 @@
 +with Ethernet, PCI, LKM, Log
 +{
 +    template type   Ethernet::Device()
@@ -435,6 +615,9 @@
 +        {
 +            static int  rtx_ethernet_open(struct net_device *dev)
 +            {
++                struct rtx_ethernet_dev* rtx_ether_dev =  netdev_priv(dev);
++                struct rtx_e1000_ctx* ctx = &rtx_ether_dev->hw_ctx;
++
 +                ${pointcut ::IMPLEMENTATION};
 +
 +                return 0;
@@ -471,6 +654,9 @@
 +        {
 +            static int  rtx_ethernet_close(struct net_device *dev)
 +            {
++                struct rtx_ethernet_dev* rtx_ether_dev =  netdev_priv(dev);
++                struct rtx_e1000_ctx* ctx = &rtx_ether_dev->hw_ctx;
++
 +                ${pointcut ::IMPLEMENTATION};
 +
 +                return 0;
@@ -493,6 +679,11 @@
 +        {
 +            static enum irqreturn   rtx_ethernet_interrupt_handler(int irq, void *dev_id)
 +            {
++                struct rtx_ethernet_dev* rtx_ether_dev;
++                struct rtx_e1000_ctx* ctx;
++
++                rtx_ether_dev = dev_id;
++                ctx = &rtx_ether_dev->hw_ctx;
 +                ${pointcut ::IMPLEMENTATION};
 +
 +                return IRQ_NONE;
@@ -595,10 +786,9 @@
 +    }
 +}
 +
-diff --git a/rathaxes/samples/lkm/ethernet.rti b/rathaxes/samples/lkm/ethernet.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/ethernet.rti
+diff -r 6d6b478219da rathaxes/samples/lkm/ethernet.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/ethernet.rti	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,47 @@
 +interface Ethernet : Socket, PCI, LKM
 +{
@@ -647,10 +837,9 @@
 +        provided pointcut   Ethernet::destroy_device;
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/lkm.blt b/rathaxes/samples/lkm/lkm.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.blt
+diff -r 6d6b478219da rathaxes/samples/lkm/lkm.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/lkm.blt	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,55 @@
 +with LKM
 +{
@@ -707,10 +896,9 @@
 +        }
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/lkm.rti b/rathaxes/samples/lkm/lkm.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.rti
+diff -r 6d6b478219da rathaxes/samples/lkm/lkm.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/lkm.rti	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,25 @@
 +interface LKM
 +{
@@ -737,26 +925,31 @@
 +        provided pointcut   LKM::deinit_bus_hook;
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/lkm.rtx b/rathaxes/samples/lkm/lkm.rtx
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/lkm.rtx
-@@ -0,0 +1,46 @@
+diff -r 6d6b478219da rathaxes/samples/lkm/lkm.rtx
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/lkm.rtx	Mon Jan 09 22:16:54 2012 +0100
+@@ -0,0 +1,52 @@
 +device LKM use LKM, PCI, Ethernet, Log
 +{
 +    Ethernet::open(Ethernet::Device dev)
 +    {
 +        Log::info("Open the device");
++        e1000::setup_interrupt_handler();
++        Log::info("Interrupt handler installed");
++        e1000::set_up_device();
++        e1000::activate_device_interruption();
 +    }
 +
 +    Ethernet::close(Ethernet::Device dev)
 +    {
 +        Log::info("Close the device");
++        e1000::free_interrupt_handler();
 +    }
 +
 +    Ethernet::interrupt_handler(Ethernet::Device dev)
 +    {
 +        Log::info("Got an interruption");
++        e1000::handle_intr();
 +    }
 +
 +    Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb)
@@ -788,10 +981,9 @@
 +
 +    Ethernet::ifname = "rtx%d";
 +}
-diff --git a/rathaxes/samples/lkm/log.blt b/rathaxes/samples/lkm/log.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/log.blt
+diff -r 6d6b478219da rathaxes/samples/lkm/log.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/log.blt	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,10 @@
 +with Log
 +{
@@ -803,10 +995,9 @@
 +        }
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/log.rti b/rathaxes/samples/lkm/log.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/log.rti
+diff -r 6d6b478219da rathaxes/samples/lkm/log.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/log.rti	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,7 @@
 +interface Log
 +{
@@ -815,10 +1006,9 @@
 +        provided chunk  ::CALL;
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/pci.blt b/rathaxes/samples/lkm/pci.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/pci.blt
+diff -r 6d6b478219da rathaxes/samples/lkm/pci.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/pci.blt	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,143 @@
 +with PCI, LKM, Log
 +{
@@ -963,10 +1153,9 @@
 +        }
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/pci.rti b/rathaxes/samples/lkm/pci.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/pci.rti
+diff -r 6d6b478219da rathaxes/samples/lkm/pci.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/pci.rti	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,36 @@
 +interface PCI : LKM
 +{
@@ -1004,10 +1193,9 @@
 +        provided pointcut   PCI::pci_remove_hook;
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/socket.blt b/rathaxes/samples/lkm/socket.blt
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/socket.blt
+diff -r 6d6b478219da rathaxes/samples/lkm/socket.blt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/socket.blt	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,27 @@
 +with Socket, LKM
 +{
@@ -1036,10 +1224,9 @@
 +        }
 +    }
 +}
-diff --git a/rathaxes/samples/lkm/socket.rti b/rathaxes/samples/lkm/socket.rti
-new file mode 100644
---- /dev/null
-+++ b/rathaxes/samples/lkm/socket.rti
+diff -r 6d6b478219da rathaxes/samples/lkm/socket.rti
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/rathaxes/samples/lkm/socket.rti	Mon Jan 09 22:16:54 2012 +0100
 @@ -0,0 +1,4 @@
 +interface Socket : LKM
 +{