changeset 63:b820c4604946

WIP on the e1000 sample
author Louis Opter <louis@lse.epitech.net>
date Sat, 18 Feb 2012 01:26:14 +0100
parents b43bed449cc2
children 8dc1a3bf372a
files rathaxes_correctly_use_chunk_and_template_sequences_parameters_in_e1000.patch
diffstat 1 files changed, 280 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/rathaxes_correctly_use_chunk_and_template_sequences_parameters_in_e1000.patch	Fri Feb 17 15:15:28 2012 +0100
+++ b/rathaxes_correctly_use_chunk_and_template_sequences_parameters_in_e1000.patch	Sat Feb 18 01:26:14 2012 +0100
@@ -1,8 +1,244 @@
 # HG changeset patch
-# Parent d759597ad67d463fa77467b2443120315980c70b
+# Parent 293f1b3181e2a2339e31d7cdb0637a019b96d3cc
 # User Louis Opter <louis@lse.epitech.net>, David Pineau <dav.pineau@gmail.com>
 rathaxes: correctly use chunk and template sequences parameters in the e1000 sample
 
+diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
+--- a/rathaxes/samples/e1000/e1000.blt
++++ b/rathaxes/samples/e1000/e1000.blt
+@@ -15,18 +15,20 @@
+ 
+         chunk   ::decl()
+         {
+-            struct rtx_e1000_ctx
++            /*
++             * Yes, this typedef looks ugly but read the remark about
++             * Ethernet::Device in ethernet.blt.
++             */
++            typedef struct rtx_e1000_ctx
+             {
+                 int                             bars;
+                 unsigned char /* __iomem */     *ioaddr;
+                 int                             irq;
+-            };
++            } *rtx_e1000_ctx_p;
+         }
+ 
+-        chunk   ::init(bars, ioaddr)
++        chunk   ::init()
+         {
+-            ${self}.bars = ${bars};
+-            ${self}.ioaddr = ${ioaddr};
+         }
+ 
+         map
+@@ -136,58 +138,74 @@
+ 
+     template sequence   e1000::create_device()
+     {
+-        chunk Ethernet::create_device()
++        chunk Ethernet::create_device(/* PCI::Device */ pdev, /* Ethernet::Device */ rtx_ether_ctx)
+         {
+-            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))
++            /*
++             * PCI init stuff:
++             *
++             * Some of that code should be moved in the PCI blts, also at some
++             * point maybe we could do that completely automatically in the PCI
++             * blts.
++             */
++
++            /*
++             * We could have used an init function here but since we can't init
++             * all the fields at once (see, ioaddr) and cannot call a C
++             * function within a placeholder (${}), it wasn't really worth it.
++             */
++            ${rtx_ether_ctx}->bars = pci_select_bars(${pdev}, IORESOURCE_MEM);
++            ${rtx_ether_ctx}->irq = ${pdev}->irq;
++
++            if (pci_enable_device_mem(${pdev}))
+             {
+                 ${Log::info("e1000::create: pci_enable_device_mem failed")};
+             }
+-
+-            if (pci_request_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars, ${config.name}))
++            if (pci_request_selected_regions(${pdev}, ${rtx_ether_ctx}->hw_ctx.bars, ${config.name}))
+             {
+                 ${Log::info("e1000::create: pci_request_selected_regions failed")};
+             }
+-
+             if (${config.set_master})
+             {
+-                pci_set_master(pdev);
++                pci_set_master(${pdev});
+             }
+ 
+             /* 0 here is for BAR_0: */
+-            rtx_ether_ctx->hw_ctx.ioaddr = pci_ioremap_bar(pdev, 0);
+-            if (!rtx_ether_ctx->hw_ctx.ioaddr)
++            ${rtx_ether_ctx}->hw_ctx.ioaddr = pci_ioremap_bar(${pdev}, 0);
++            if (!${rtx_ether_ctx}->hw_ctx.ioaddr)
+             {
+                 ${Log::info("e1000::create: pci_ioremap_bar failed")};
+             }
+ 
++            /*
++             * The really device specific algorithm starts here (so it should
++             * certainly be written in the frontend):
++             */
++
+             /* Reset the card */
+-            rtx_e1000_register_write32(&rtx_ether_ctx->hw_ctx, E1000_CTRL, E1000_CMD_RST);
++            rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_CTRL, E1000_CMD_RST);
+             udelay(10);
+ 
+-            /* Now we can load its mac address */
++            /* Now we can load its mac address (thanks minix code) */
+             int i = 0;
+-            for (i = 0 /* < this is not generated! */; i < 3; ++i)
++            for (i = 0 /* < this is not generated! (cnorm bug) */; i < 3; ++i)
+             {
+-                rtx_e1000_register_write32(&rtx_ether_ctx->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
++                rtx_e1000_register_write32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ, (i << 8) | 1);
+ 
+                 int value;
+-                /* Should be a do { } while(); but the compiler doesn't do { } while(); yet. */
+-                value = rtx_e1000_register_read32(&rtx_ether_ctx->hw_ctx, E1000_EEPROM_READ);
+-                while ((value & (1 << 4)) == 0)
+-                    value = rtx_e1000_register_read32(&rtx_ether_ctx->hw_ctx, E1000_EEPROM_READ);
++                do
++                    value = rtx_e1000_register_read32(&${rtx_ether_ctx}->hw_ctx, E1000_EEPROM_READ);
++                while ((value & (1 << 4)) == 0);
+                 value >>= 16;
+ 
+-                rtx_ether_ctx->net_dev->dev_addr[i * 2] = value & 0xff;
+-                rtx_ether_ctx->net_dev->dev_addr[i * 2 + 1] = (value >> 8) & 0xff;
++                ${rtx_ether_ctx}->net_dev->dev_addr[i * 2] = value & 0xff;
++                ${rtx_ether_ctx}->net_dev->dev_addr[i * 2 + 1] = (value >> 8) & 0xff;
+             }
+ 
+-            memcpy(rtx_ether_ctx->net_dev->perm_addr,
+-                   rtx_ether_ctx->net_dev->dev_addr,
+-                   rtx_ether_ctx->net_dev->addr_len);
++            memcpy(${rtx_ether_ctx}->net_dev->perm_addr,
++                   ${rtx_ether_ctx}->net_dev->dev_addr,
++                   ${rtx_ether_ctx}->net_dev->addr_len);
+ 
+-            { /* < mais lol. */
++            { /* < See #10 */
+                 ${Log::info("e1000::create: mac address loaded from the EEPROM")};
+             }
+         }
+@@ -199,15 +217,14 @@
+ 
+     template sequence   e1000::destroy_device()
+     {
+-        chunk   Ethernet::destroy_device
++        chunk   Ethernet::destroy_device(/* PCI::Device */ pdev, /* Ethernet::Device */ rtx_ether_ctx)
+         {
+             /*
+              * Here, we should have some checks to avoid to free resources that
+              * haven't been allocated. (e.g: in case of previous errors).
+              */
+-            struct rtx_ethernet_dev* rtx_ether_ctx = netdev_priv(net_dev);
+-            iounmap(rtx_ether_ctx->hw_ctx.ioaddr);
+-            pci_release_selected_regions(pdev, rtx_ether_ctx->hw_ctx.bars);
++            iounmap(${rtx_ether_ctx}->hw_ctx.ioaddr);
++            pci_release_selected_regions(${pdev}, ${rtx_ether_ctx}->hw_ctx.bars);
+         }
+ 
+         chunk   ::CALL
+@@ -275,7 +292,7 @@
+ 
+         chunk   ::CALL()
+         {
+-            rtx_e1000_register_read32(&${ctx}, ${reg_offset});
++            rtx_e1000_register_read32(${ctx}, ${reg_offset});
+         }
+     }
+ 
+@@ -296,7 +313,7 @@
+ 
+         chunk   ::CALL()
+         {
+-            rtx_e1000_register_write32(&${ctx}, ${reg_offset});
++            rtx_e1000_register_write32(${ctx}, ${reg_offset});
+         }
+     }
+ 
+@@ -320,7 +337,7 @@
+         }
+     }
+ 
+-    template sequence   e1000::setup_interrupt_handler()
++    template sequence   e1000::setup_interrupt_handler(Ethernet::Device ctx)
+     {
+         chunk   LKM::includes()
+         {
+@@ -352,13 +369,13 @@
+             }
+         }
+ 
+-        chunk   ::CALL()
++        chunk   ::CALL
+         {
+             // this is an hack for the scope
+             (void)1;
+             {
+                 int error;
+-                error = e1000_setup_interrupt_handler(rtx_ether_dev);
++                error = e1000_setup_interrupt_handler(${ctx});
+                 if (error)
+                 {
+                     return error;
+diff --git a/rathaxes/samples/e1000/e1000.rti b/rathaxes/samples/e1000/e1000.rti
+--- a/rathaxes/samples/e1000/e1000.rti
++++ b/rathaxes/samples/e1000/e1000.rti
+@@ -1,25 +1,22 @@
+ interface e1000 : Socket, Ethernet, PCI, LKM
+ {
+     provided type   e1000::Context;
++    /*
++     * These two types should actually be registers definitions in the frontend:
++     */
+     provided type   e1000::Register;
+     provided type   e1000::Commands;
+ 
+-    /*
+-     * This sequence should receive an argument like Ethernet::Device, but it is
+-     * unclear about how this argument should be bound to a variable/argument in
+-     * the instrumented C code.
+-     *
+-     * Here again, we rely on the fact that *we* wrote the parent context and
+-     * named the C variables we need/use with the same name everywhere.
+-     */
+     provided sequence   e1000::create_device()
+     {
++        /* should take PCI::Device and Ethernet::Device args: */
+         provided chunk  Ethernet::create_device;
+         provided chunk  ::CALL;
+     }
+ 
+     provided sequence   e1000::destroy_device()
+     {
++        /* should take PCI::Device and Ethernet::Device args: */
+         provided chunk  Ethernet::destroy_device;
+         provided chunk  ::CALL;
+     }
+@@ -35,9 +32,9 @@
+         provided chunk  ::CALL;
+     }
+ 
+-    provided sequence   e1000::setup_interrupt_handler()
++    provided sequence   e1000::setup_interrupt_handler(Ethernet::Device)
+     {
+-        provided chunk  LKM::includes; // work without this one
++        provided chunk  LKM::includes; // works without this one
+         provided chunk  LKM::prototypes;
+         provided chunk  LKM::code;
+         provided chunk  ::CALL;
 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt
 --- a/rathaxes/samples/e1000/ethernet.blt
 +++ b/rathaxes/samples/e1000/ethernet.blt
@@ -98,7 +334,7 @@
              net_dev = alloc_etherdev(sizeof(*rtx_ether_ctx));
              if (net_dev == 0)
              {
-@@ -152,53 +172,42 @@
+@@ -152,64 +172,54 @@
                  /*
                   * Again, the error should be "raised" in the parent context.
                   *
@@ -143,13 +379,14 @@
 -            pci_set_drvdata(pdev, net_dev);
 +            /* Initialize our context held by the net_device structure */
 +            ${rtx_ether_ctx.init(local.net_dev, pdev)};
-+
+ 
+-            ${pointcut Ethernet::create_device};
 +            pci_set_drvdata(${pdev}, net_dev);
- 
-             ${pointcut Ethernet::create_device};
++
++            ${pointcut Ethernet::create_device(pdev, local.rtx_ether_ctx)};
          }
  
-+        /* This chunk should be remove (see #26) */
++        /* This chunk should be removed (see #26) */
          chunk   ::CALL
          {
          }
@@ -162,22 +399,31 @@
 +        chunk   PCI::pci_remove_hook(/* PCI::Device */ pdev)
          {
 -            struct net_device *net_dev = pci_get_drvdata(pdev);
-+            struct net_device *net_dev = pci_get_drvdata(${pdev});
++            /* workaround for cnorm unstrict */
++            typedef int ${Ethernet::device};
  
-             ${pointcut Ethernet::destroy_device};
+-            ${pointcut Ethernet::destroy_device};
++            struct net_device *net_dev = pci_get_drvdata(${pdev});
++            ${Ethernet::device} rtx_ether_ctx = netdev_priv(net_dev);
++
++            ${pointcut Ethernet::destroy_device(pdev, local.rtx_ether_ctx)};
  
-@@ -210,6 +219,7 @@
+             unregister_netdev(net_dev);
+-            /*
+-             * If we had some cleanup todo with struct rtx_ether_ctx we would
+-             * do a netdev_priv(net_dev) here and do it.
+-             */
              free_netdev(net_dev);
          }
  
-+        /* This chunk should be remove (see #26) */
++        /* This chunk should be removed (see #26) */
          chunk ::CALL
          {
          }
 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
 --- a/rathaxes/samples/e1000/ethernet.rti
 +++ b/rathaxes/samples/e1000/ethernet.rti
-@@ -28,18 +28,16 @@
+@@ -28,19 +28,17 @@
          provided chunk  LKM::code;
      }
  
@@ -185,8 +431,9 @@
 +    provided sequence   Ethernet::init()
      {
          provided chunk  LKM::data;
-         provided chunk  PCI::pci_probe_hook;
+-        provided chunk  PCI::pci_probe_hook;
 -        provided chunk  ::CALL;
++        provided chunk  PCI::pci_probe_hook; /* should take a PCI::Device arg */
  
          provided pointcut   Ethernet::create_device;
      }
@@ -195,9 +442,23 @@
 +    provided sequence   Ethernet::exit()
      {
 -        provided chunk  ::CALL;
-         provided chunk  PCI::pci_remove_hook;
+-        provided chunk  PCI::pci_remove_hook;
++        provided chunk  PCI::pci_remove_hook; /* should take a PCI::Device arg */
  
          provided pointcut   Ethernet::destroy_device;
+     }
+diff --git a/rathaxes/samples/e1000/lkm.rtx b/rathaxes/samples/e1000/lkm.rtx
+--- a/rathaxes/samples/e1000/lkm.rtx
++++ b/rathaxes/samples/e1000/lkm.rtx
+@@ -3,7 +3,7 @@
+     Ethernet::open(Ethernet::Device dev)
+     {
+         Log::info("Open the device");
+-        e1000::setup_interrupt_handler();
++        e1000::setup_interrupt_handler(dev);
+         Log::info("Interrupt handler installed");
+         e1000::set_up_device();
+         e1000::activate_device_interruption();
 diff --git a/rathaxes/samples/e1000/pci.blt b/rathaxes/samples/e1000/pci.blt
 --- a/rathaxes/samples/e1000/pci.blt
 +++ b/rathaxes/samples/e1000/pci.blt
@@ -279,7 +540,7 @@
      {
          provided chunk  LKM::prototypes;
          provided chunk  LKM::code;
-@@ -26,7 +26,7 @@
+@@ -26,11 +26,11 @@
          provided pointcut   PCI::pci_probe_hook;
      }
  
@@ -288,3 +549,8 @@
      {
          provided chunk  LKM::prototypes;
          provided chunk  LKM::code;
+ 
+-        provided pointcut   PCI::pci_remove_hook;
++        provided pointcut   PCI::pci_remove_hook; /* Should take a PCI::Device arg */
+     }
+ }