# HG changeset patch # User Louis Opter # Date 1325983894 -3600 # Node ID f43900ad7e663e2aa8237318041b2afa5dd6fd2e # Parent 9433dec37a52a0132f1fe24fb529dd3cf41a3443 Fold All The Patches on the LKM Sample diff -r 9433dec37a52 -r f43900ad7e66 e1000_rework_without_explicit_call.patch --- a/e1000_rework_without_explicit_call.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -# HG changeset patch -# Parent 1cfa6a46c673fae191ce982e2ebd471f9a53ee90 -rathaxes: initialize the e1000 sepcific code in an elegant implicit way - -diff -r 1cfa6a46c673 rathaxes/samples/lkm/e1000.blt ---- a/rathaxes/samples/lkm/e1000.blt Sun Jan 08 01:01:14 2012 +0100 -+++ b/rathaxes/samples/lkm/e1000.blt Sun Jan 08 01:02:13 2012 +0100 -@@ -27,9 +27,9 @@ - } - } - -- template sequence e1000::create() -+ template sequence e1000::create_device() - { -- chunk ::CALL -+ chunk Ethernet::create_device() - { - rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM); - if (pci_enable_device_mem(pdev)) -@@ -54,18 +54,25 @@ - ${Log::info("e1000::create: pci_ioremap_bar failed")}; - } - } -+ -+ chunk ::CALL -+ { -+ } - } - -- template sequence e1000::destroy() -+ template sequence e1000::destroy_device() - { -- chunk ::CALL -+ chunk Ethernet::destroy_device - { - // XXX: add a check in order to avoid freeing none allocated - // resources. - 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); -- pci_release_region(pdev, 0); -+ } -+ -+ chunk ::CALL -+ { - } - } - } -diff -r 1cfa6a46c673 rathaxes/samples/lkm/e1000.rti ---- a/rathaxes/samples/lkm/e1000.rti Sun Jan 08 01:01:14 2012 +0100 -+++ b/rathaxes/samples/lkm/e1000.rti Sun Jan 08 01:02:13 2012 +0100 -@@ -3,13 +3,15 @@ - provided type e1000::Context; - - /* Not sure if we need the argument */ -- provided sequence e1000::create() -+ provided sequence e1000::create_device() - { -+ provided chunk Ethernet::create_device; - provided chunk ::CALL; - } - -- provided sequence e1000::destroy() -+ provided sequence e1000::destroy_device() - { -+ provided chunk Ethernet::destroy_device; - provided chunk ::CALL; - } - } -diff -r 1cfa6a46c673 rathaxes/samples/lkm/ethernet.blt ---- a/rathaxes/samples/lkm/ethernet.blt Sun Jan 08 01:01:14 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.blt Sun Jan 08 01:02:13 2012 +0100 -@@ -173,6 +173,7 @@ - /* same problem as above with ${pdev} */ - //pci_set_drvdata(${pdev}, net_dev); - pci_set_drvdata(pdev, net_dev); -+ ${pointcut Ethernet::create_device}; - } - - chunk ::CALL -@@ -186,6 +187,8 @@ - { - struct net_device *net_dev = pci_get_drvdata(pdev); - -+ ${pointcut Ethernet::destroy_device}; -+ - unregister_netdev(net_dev); - /* - * If we had some cleanup todo with struct rtx_ether_ctx we would -diff -r 1cfa6a46c673 rathaxes/samples/lkm/ethernet.rti ---- a/rathaxes/samples/lkm/ethernet.rti Sun Jan 08 01:01:14 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.rti Sun Jan 08 01:02:13 2012 +0100 -@@ -33,6 +33,8 @@ - provided chunk LKM::data; - provided chunk PCI::pci_probe_hook; - provided chunk ::CALL; -+ -+ provided pointcut Ethernet::create_device; - } - - /* Likely extends PCI::remove */ -@@ -40,5 +42,7 @@ - { - provided chunk ::CALL; - provided chunk PCI::pci_remove_hook; -+ -+ provided pointcut Ethernet::destroy_device; - } - } -diff -r 1cfa6a46c673 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sun Jan 08 01:01:14 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sun Jan 08 01:02:13 2012 +0100 -@@ -20,30 +20,14 @@ - Log::info("We have one packet to transmit!"); - } - --// PCI::probe(PCI::Device dev) --// { --// Log::info("Probe the device"); --// Ethernet::init(dev); --// e1000::create(); --// } -- --// PCI::remove(PCI::Device dev) --// { --// Log::info("Remove the pci device"); --// e1000::destroy(); --// Ethernet::exit(dev); --// } -- - LKM::init() - { - Log::info("Hello this is LKM"); -- // PCI::register(); - } - - LKM::exit() - { - Log::info("Good bye this was LKM"); -- // PCI::unregister(); - } - } - diff -r 9433dec37a52 -r f43900ad7e66 ethernet_rework_without_explicit_call.patch --- a/ethernet_rework_without_explicit_call.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -# HG changeset patch -# Parent 4920b3a97ad6f031437c63ca3ae756678fde92a3 -rathaxes: initialize the ethernet subsystem in an elegant implicit way - -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/e1000.blt ---- a/rathaxes/samples/lkm/e1000.blt Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/e1000.blt Sun Jan 08 00:13:22 2012 +0100 -@@ -62,7 +62,6 @@ - { - // XXX: add a check in order to avoid freeing none allocated - // resources. -- struct net_device *net_dev = pci_get_drvdata(pdev); - 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); -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/ethernet.blt ---- a/rathaxes/samples/lkm/ethernet.blt Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.blt Sun Jan 08 00:13:22 2012 +0100 -@@ -125,7 +125,7 @@ - }; - } - -- chunk ::CALL -+ chunk PCI::pci_probe_hook() - { - /* - * This typedef is needed to workaround a bug in CNorm __std__ -@@ -174,12 +174,18 @@ - //pci_set_drvdata(${pdev}, net_dev); - pci_set_drvdata(pdev, net_dev); - } -+ -+ chunk ::CALL -+ { -+ } - } - - template sequence Ethernet::exit(PCI::Device pdev) - { -- chunk ::CALL -+ chunk PCI::pci_remove_hook() - { -+ struct net_device *net_dev = pci_get_drvdata(pdev); -+ - unregister_netdev(net_dev); - /* - * If we had some cleanup todo with struct rtx_ether_ctx we would -@@ -187,5 +193,10 @@ - */ - free_netdev(net_dev); - } -+ -+ chunk ::CALL -+ { -+ } - } - } -+ -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/ethernet.rti ---- a/rathaxes/samples/lkm/ethernet.rti Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.rti Sun Jan 08 00:13:22 2012 +0100 -@@ -28,10 +28,10 @@ - provided chunk LKM::code; - } - -- /* Kinda extends PCI::probe */ - provided sequence Ethernet::init(PCI::Device) - { - provided chunk LKM::data; -+ provided chunk PCI::pci_probe_hook; - provided chunk ::CALL; - } - -@@ -39,5 +39,6 @@ - provided sequence Ethernet::exit(PCI::Device) - { - provided chunk ::CALL; -+ provided chunk PCI::pci_remove_hook; - } - } -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sun Jan 08 00:13:22 2012 +0100 -@@ -20,19 +20,19 @@ - Log::info("We have one packet to transmit!"); - } - -- PCI::probe(PCI::Device dev) -- { -- Log::info("Probe the device"); -- Ethernet::init(dev); -- e1000::create(); -- } -+// PCI::probe(PCI::Device dev) -+// { -+// Log::info("Probe the device"); -+// Ethernet::init(dev); -+// e1000::create(); -+// } - -- PCI::remove(PCI::Device dev) -- { -- Log::info("Remove the pci device"); -- e1000::destroy(); -- Ethernet::exit(dev); -- } -+// PCI::remove(PCI::Device dev) -+// { -+// Log::info("Remove the pci device"); -+// e1000::destroy(); -+// Ethernet::exit(dev); -+// } - - LKM::init() - { -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/pci.blt ---- a/rathaxes/samples/lkm/pci.blt Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/pci.blt Sun Jan 08 00:13:22 2012 +0100 -@@ -53,7 +53,7 @@ - if (err < 0) - goto fail; - -- ${pointcut ::IMPLEMENTATION}; -+ ${pointcut PCI::pci_probe_hook}; - - return 0; - -@@ -61,6 +61,10 @@ - return err; - } - } -+ -+ chunk ::CALL -+ { -+ } - } - - template sequence PCI::remove(PCI::Device pdev) -@@ -74,11 +78,15 @@ - { - static void rtx_pci_remove(struct pci_dev *pdev) - { -- ${pointcut ::IMPLEMENTATION}; -+ ${pointcut PCI::pci_remove_hook}; - - pci_disable_device(pdev); - } - } -+ -+ chunk ::CALL() -+ { -+ } - } - - template sequence PCI::register() -diff -r 4920b3a97ad6 -r c3265ca219d5 rathaxes/samples/lkm/pci.rti ---- a/rathaxes/samples/lkm/pci.rti Sat Jan 07 23:09:24 2012 +0100 -+++ b/rathaxes/samples/lkm/pci.rti Sun Jan 08 00:13:22 2012 +0100 -@@ -23,15 +23,19 @@ - provided chunk LKM::deinit_bus_hook; - } - -- required sequence PCI::probe(PCI::Device) -+ provided sequence PCI::probe(PCI::Device) - { - provided chunk LKM::prototypes; - provided chunk LKM::code; -+ -+ provided pointcut PCI::pci_probe_hook; - } - -- required sequence PCI::remove(PCI::Device) -+ provided sequence PCI::remove(PCI::Device) - { - provided chunk LKM::prototypes; - provided chunk LKM::code; -+ -+ provided pointcut PCI::pci_remove_hook; - } - } diff -r 9433dec37a52 -r f43900ad7e66 pci_rework_without_explicit_call.patch --- a/pci_rework_without_explicit_call.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -# HG changeset patch -# Parent c5c98e265bb4cf5c3a9d775e56d6599ca73a4c73 -rathaxes: initialize the pci bus in an elegant implicit way - -diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.blt ---- a/rathaxes/samples/lkm/lkm.blt Sat Jan 07 22:45:07 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.blt Sat Jan 07 23:09:24 2012 +0100 -@@ -33,6 +33,7 @@ - static int __attribute__((__section__(".init.text"))) rtx_module_init(void) - { - ${pointcut ::IMPLEMENTATION}; -+ ${pointcut LKM::init_bus_hook}; - - return 0; - } -@@ -48,6 +49,7 @@ - static void __attribute__((__section__(".exit.text"))) rtx_module_exit(void) - { - ${pointcut ::IMPLEMENTATION}; -+ ${pointcut LKM::deinit_bus_hook}; - } - - module_exit(rtx_module_exit); -diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.rti ---- a/rathaxes/samples/lkm/lkm.rti Sat Jan 07 22:45:07 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rti Sat Jan 07 23:09:24 2012 +0100 -@@ -12,12 +12,14 @@ - - required sequence LKM::init() - { -- provided chunk LKM::includes; -- provided chunk LKM::code; -+ provided chunk LKM::includes; -+ provided chunk LKM::code; -+ provided pointcut LKM::init_bus_hook; - } - - required sequence LKM::exit() - { -- provided chunk LKM::code; -+ provided chunk LKM::code; -+ provided pointcut LKM::deinit_bus_hook; - } - } -diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 22:45:07 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 23:09:24 2012 +0100 -@@ -37,13 +37,13 @@ - LKM::init() - { - Log::info("Hello this is LKM"); -- PCI::register(); -+ // PCI::register(); - } - - LKM::exit() - { - Log::info("Good bye this was LKM"); -- PCI::unregister(); -+ // PCI::unregister(); - } - } - -diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/pci.blt ---- a/rathaxes/samples/lkm/pci.blt Sat Jan 07 22:45:07 2012 +0100 -+++ b/rathaxes/samples/lkm/pci.blt Sat Jan 07 23:09:24 2012 +0100 -@@ -102,7 +102,7 @@ - }; - } - -- chunk ::CALL -+ chunk LKM::init_bus_hook() - { - /* - * So how do we use the return value in the parent context? -@@ -116,13 +116,22 @@ - return error; - } - } -+ -+ chunk ::CALL() -+ { -+ // no implementation, we just need to instrument the lkm::bus_hook -+ } - } - - template sequence PCI::unregister() - { -- chunk ::CALL -+ chunk LKM::deinit_bus_hook() - { - pci_unregister_driver(&rtx_pci_driver); - } -+ -+ chunk ::CALL -+ { -+ } - } - } -diff -r c5c98e265bb4 -r 4920b3a97ad6 rathaxes/samples/lkm/pci.rti ---- a/rathaxes/samples/lkm/pci.rti Sat Jan 07 22:45:07 2012 +0100 -+++ b/rathaxes/samples/lkm/pci.rti Sat Jan 07 23:09:24 2012 +0100 -@@ -7,13 +7,20 @@ - - provided sequence PCI::register() - { -+ // it is impossible to provide a "dummy" sequence -+ // which just hook itself. The PCI:register juste -+ // inject its code in the module_init function -+ // in order to load the pci driver. -+ // Everything is done with the configuration. - provided chunk ::CALL; - provided chunk LKM::data; -+ provided chunk LKM::init_bus_hook; - } - - provided sequence PCI::unregister() - { - provided chunk ::CALL; -+ provided chunk LKM::deinit_bus_hook; - } - - required sequence PCI::probe(PCI::Device) diff -r 9433dec37a52 -r f43900ad7e66 rathaxes_add_a_linux_lkm.patch --- a/rathaxes_add_a_linux_lkm.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -# HG changeset patch -# Parent 9006ed3c5074b918e2f824b0053b494e2a82dbb8 -rathaxes: add a kernel module sample (for now Linux only) - -diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt ---- a/rathaxes/samples/CMakeLists.txt -+++ b/rathaxes/samples/CMakeLists.txt -@@ -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 -@@ -0,0 +1,3 @@ -+ADD_RATHAXES_SOURCES(lkm lkm.rtx -+ RTI log.rti lkm.rti -+ BLT log.blt lkm.blt) -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 -@@ -0,0 +1,47 @@ -+with LKM -+{ -+ ${pointcut LKM::includes}; -+ ${pointcut LKM::init}; -+ ${pointcut LKM::exit}; -+ -+ template sequence LKM::init() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ #include -+ typedef int lkm_headers_include_stamp; -+ -+ MODULE_DESCRIPTION(${config.description}); -+ MODULE_AUTHOR(${config.author}); -+ MODULE_LICENSE(${config.license}); -+ } -+ -+ chunk LKM::init() -+ { -+ /* -+ * Rathaxes doesn't yet support arbitrary "decorators" like __init -+ * or __exit. -+ */ -+ static int __attribute__((__section__(.init.text))) rtx_module_init(void) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ } -+ -+ module_init(rtx_module_init); -+ } -+ } -+ -+ template sequence LKM::exit() -+ { -+ chunk LKM::exit -+ { -+ static void __attribute((__section__(.exit.text))) rtx_module_exit(void) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ } -+ -+ module_exit(rtx_module_init); -+ } -+ } -+} -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 -@@ -0,0 +1,21 @@ -+interface LKM -+{ -+ provided pointcut LKM::includes; -+ provided pointcut LKM::init; -+ provided pointcut LKM::exit; -+ -+ required variable ::string LKM::author; -+ required variable ::string LKM::description; -+ required variable ::string LKM::license; -+ -+ required sequence LKM::init() -+ { -+ provided chunk LKM::includes; -+ provided chunk LKM::init; -+ } -+ -+ required sequence LKM::exit() -+ { -+ provided chunk LKM::exit; -+ } -+} -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,19 @@ -+device LKM use LKM, Log -+{ -+ LKM::init() -+ { -+ Log::info("Hello this is LKM"); -+ } -+ -+ LKM::exit() -+ { -+ Log::info("Good bye this was LKM"); -+ } -+} -+ -+configuration -+{ -+ LKM::author = "Rathaxes"; -+ LKM::description = "Hello World Loadable Kernel Module (LKM)"; -+ LKM::license = "BSD"; -+} -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 -@@ -0,0 +1,10 @@ -+with Log -+{ -+ template sequence Log::info(::string msg) -+ { -+ chunk ::CALL -+ { -+ pr_info("%s\n", ${msg}); -+ } -+ } -+} -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 -@@ -0,0 +1,7 @@ -+interface Log -+{ -+ provided sequence Log::info(::string) -+ { -+ provided chunk ::CALL; -+ } -+} diff -r 9433dec37a52 -r f43900ad7e66 rathaxes_add_lkm_ethernet_sample.patch --- a/rathaxes_add_lkm_ethernet_sample.patch Sun Jan 08 01:45:20 2012 +0100 +++ b/rathaxes_add_lkm_ethernet_sample.patch Sun Jan 08 01:51:34 2012 +0100 @@ -1,40 +1,120 @@ # HG changeset patch -# Parent a109185dcd773ae92b98a8195b7cc91f1c1cee47 +# Parent b995d8934956b83383c144303178f3eb383d0acf rathaxes: add the PCI/Ethernet part of a Linux Intel e1000 network card driver +diff --git a/rathaxes/samples/CMakeLists.txt b/rathaxes/samples/CMakeLists.txt +--- a/rathaxes/samples/CMakeLists.txt ++++ b/rathaxes/samples/CMakeLists.txt +@@ -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 +@@ -0,0 +1,7 @@ ++ADD_RATHAXES_SOURCES(lkm lkm.rtx ++ RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti ++ BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt) ++ ++# 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_hello lkm) diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt ---- a/rathaxes/samples/lkm/e1000.blt +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/e1000.blt -@@ -5,7 +5,7 @@ - chunk LKM::includes() - { - /* -- * Force the generation of the structure in the "headers part, we +@@ -0,0 +1,80 @@ ++with e1000, Ethernet, Socket, PCI, LKM, Log ++{ ++ template type e1000::Context() ++ { ++ chunk LKM::includes() ++ { ++ /* + * Force the generation of the structure in the "headers" part, we - * have to do this since we do not use the structure in this blt - * (we hacked a bit and used it in ethernet.blt directly). - */ -@@ -64,8 +64,10 @@ - { - chunk Ethernet::destroy_device - { -- // XXX: add a check in order to avoid freeing none allocated -- // resources. ++ * have to do this since we do not use the structure in this blt ++ * (we hacked a bit and used it in ethernet.blt directly). ++ */ ++ typedef int ${e1000::Context}; /* CNorm __std__ workaround */ ++ ${e1000::Context} force_declaration_in_includes; ++ } ++ ++ chunk ::decl() ++ { ++ struct rtx_e1000_ctx ++ { ++ int bars; ++ unsigned char /* __iomem */ *ioaddr; ++ }; ++ } ++ ++ map ++ { ++ } ++ } ++ ++ template sequence e1000::create_device() ++ { ++ chunk Ethernet::create_device() ++ { ++ rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM); ++ 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})) ++ { ++ ${Log::info("e1000::create: pci_request_selected_regions failed")}; ++ } ++ ++ if (${config.set_master}) ++ { ++ 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) ++ { ++ ${Log::info("e1000::create: pci_ioremap_bar failed")}; ++ } ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++ ++ template sequence e1000::destroy_device() ++ { ++ chunk Ethernet::destroy_device ++ { + /* + * 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); ++ 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); ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++} diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti ---- a/rathaxes/samples/lkm/e1000.rti +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/e1000.rti -@@ -2,7 +2,14 @@ - { - provided type e1000::Context; - -- /* Not sure if we need the argument */ +@@ -0,0 +1,24 @@ ++interface e1000 : Socket, Ethernet, PCI, LKM ++{ ++ provided type e1000::Context; ++ + /* + * 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 @@ -43,138 +123,561 @@ + * 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() - { - provided chunk Ethernet::create_device; ++ provided sequence e1000::create_device() ++ { ++ provided chunk Ethernet::create_device; ++ provided chunk ::CALL; ++ } ++ ++ provided sequence e1000::destroy_device() ++ { ++ provided chunk Ethernet::destroy_device; ++ provided chunk ::CALL; ++ } ++} diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt ---- a/rathaxes/samples/lkm/ethernet.blt +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/ethernet.blt -@@ -6,8 +6,6 @@ - { - #include - #include -- -- typedef int include_linux_net_system_stamp; - } - - chunk ::decl() -@@ -93,10 +91,9 @@ - template sequence Ethernet::interrupt_handler(Ethernet::Device dev) - { - /* -- * Why we can't use irqreturn_t here? (we are forced to use enum -- * irqreturn, which is the real type). +@@ -0,0 +1,207 @@ ++with Ethernet, PCI, LKM, Log ++{ ++ template type Ethernet::Device() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ #include ++ } ++ ++ chunk ::decl() ++ { ++ struct rtx_ethernet_dev ++ { ++ /* ++ * I think it's useless to use the ${PCI::Device} "abstraction" ++ * here, since we are already in a Linux specific context here. ++ */ ++ struct pci_dev *pci_dev; ++ struct net_device *net_dev; ++ ++ /* while waiting on issue #8 */ ++ struct rtx_e1000_ctx hw_ctx; ++ }; ++ } ++ ++ chunk ::init(net_dev) ++ { ++ ${self} = ${net_dev}; ++ } ++ ++ map ++ { ++ } ++ } ++ ++ template sequence Ethernet::open(Ethernet::Device dev) ++ { ++ chunk LKM::prototypes() ++ { ++ static int rtx_ethernet_open(struct net_device *); ++ } ++ ++ chunk LKM::code() ++ { ++ static int rtx_ethernet_open(struct net_device *dev) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ++ return 0; ++ } ++ } ++ } ++ ++ template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) ++ { ++ chunk LKM::prototypes() ++ { ++ static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev); ++ } ++ ++ chunk LKM::code() ++ { ++ static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ++ return 0; ++ } ++ } ++ } ++ ++ template sequence Ethernet::close(Ethernet::Device dev) ++ { ++ chunk LKM::prototypes() ++ { ++ static int rtx_ethernet_close(struct net_device *); ++ } ++ ++ chunk LKM::code() ++ { ++ static int rtx_ethernet_close(struct net_device *dev) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ++ return 0; ++ } ++ } ++ } ++ ++ template sequence Ethernet::interrupt_handler(Ethernet::Device dev) ++ { ++ /* + * We can't use the irqreturn_t type here because CNornm doesn't know + * it. - */ -- - chunk LKM::prototypes() - { - static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); -@@ -141,7 +138,12 @@ - if (net_dev == 0) - { - ${Log::info("Cannot allocate memory")}; -- // is it the thing to do? ++ */ ++ chunk LKM::prototypes() ++ { ++ static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); ++ } ++ ++ chunk LKM::code() ++ { ++ static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ++ return IRQ_NONE; ++ } ++ } ++ } ++ ++ template sequence Ethernet::init(PCI::Device pdev) ++ { ++ chunk LKM::data() ++ { ++ static const struct net_device_ops rtx_ether_ops = ++ { ++ .ndo_open = rtx_ethernet_open, ++ .ndo_stop = rtx_ethernet_close, ++ .ndo_start_xmit = rtx_ethernet_xmit, ++ }; ++ } ++ ++ chunk PCI::pci_probe_hook() ++ { ++ /* ++ * This typedef is needed to workaround a bug in CNorm __std__ ++ * dialect. ++ */ ++ typedef int ${Ethernet::Device}; ++ ${Ethernet::Device} *rtx_ether_ctx; ++ struct net_device *net_dev; ++ int error; ++ ++ error = 0; ++ net_dev = alloc_etherdev(sizeof(*rtx_ether_ctx)); ++ if (net_dev == 0) ++ { ++ ${Log::info("Cannot allocate memory")}; + /* + * Again, the error should be "raised" in the parent context. + * + * Here we know that we should return ENOMEM because *we* wrote + * the parent context. + */ - return -ENOMEM; - } - strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name)); -@@ -166,13 +168,13 @@ - if ((error = register_netdev(net_dev))) - { - ${Log::info("Cannot register the driver")}; -- // is it the thing to do? - return error; - } - - /* same problem as above with ${pdev} */ - //pci_set_drvdata(${pdev}, net_dev); - pci_set_drvdata(pdev, net_dev); ++ return -ENOMEM; ++ } ++ strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name)); ++ net_dev->irq = pdev->irq; ++ // Maybe we should try ${rtx_ether_ctx.init()} here: ++ rtx_ether_ctx = netdev_priv(net_dev); ++ //rtx_ether_ctx->pci_dev = ${pdev}; ++ rtx_ether_ctx->pci_dev = pdev; // In the meantime do it directly ++ rtx_ether_ctx->net_dev = net_dev; ++ ++ /* ++ * The substitution of ${pdev} fails here. I also tried to add a ++ * "substitute method" to the PCI::Device that was just doing ++ * "${self}" but it didn't work either (it was subsituted by a ++ * placeholder, e.g: _1). ++ * ++ * That's why we cheated a bit and named all the arguments pdev. ++ */ ++ //SET_NETDEV_DEV(net_dev, &${pdev}->dev); ++ SET_NETDEV_DEV(net_dev, &pdev->dev); ++ net_dev->netdev_ops = &rtx_ether_ops; ++ if ((error = register_netdev(net_dev))) ++ { ++ ${Log::info("Cannot register the driver")}; ++ return error; ++ } ++ ++ /* same problem as above with ${pdev} */ ++ //pci_set_drvdata(${pdev}, net_dev); ++ pci_set_drvdata(pdev, net_dev); + - ${pointcut Ethernet::create_device}; - } - ++ ${pointcut Ethernet::create_device}; ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++ ++ template sequence Ethernet::exit(PCI::Device pdev) ++ { ++ chunk PCI::pci_remove_hook() ++ { ++ struct net_device *net_dev = pci_get_drvdata(pdev); ++ ++ ${pointcut Ethernet::destroy_device}; ++ ++ 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); ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++} ++ diff --git a/rathaxes/samples/lkm/ethernet.rti b/rathaxes/samples/lkm/ethernet.rti ---- a/rathaxes/samples/lkm/ethernet.rti +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/ethernet.rti -@@ -37,7 +37,6 @@ - provided pointcut Ethernet::create_device; - } - -- /* Likely extends PCI::remove */ - provided sequence Ethernet::exit(PCI::Device) - { - provided chunk ::CALL; +@@ -0,0 +1,47 @@ ++interface Ethernet : Socket, PCI, LKM ++{ ++ provided type Ethernet::Device; ++ ++ required variable ::string Ethernet::ifname; ++ ++ required sequence Ethernet::open(Ethernet::Device) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ } ++ ++ required sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ } ++ ++ required sequence Ethernet::close(Ethernet::Device) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ } ++ ++ required sequence Ethernet::interrupt_handler(Ethernet::Device) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ } ++ ++ provided sequence Ethernet::init(PCI::Device) ++ { ++ provided chunk LKM::data; ++ provided chunk PCI::pci_probe_hook; ++ provided chunk ::CALL; ++ ++ provided pointcut Ethernet::create_device; ++ } ++ ++ provided sequence Ethernet::exit(PCI::Device) ++ { ++ provided chunk ::CALL; ++ provided chunk PCI::pci_remove_hook; ++ ++ provided pointcut Ethernet::destroy_device; ++ } ++} diff --git a/rathaxes/samples/lkm/lkm.blt b/rathaxes/samples/lkm/lkm.blt ---- a/rathaxes/samples/lkm/lkm.blt +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/lkm.blt -@@ -12,9 +12,6 @@ - { - #include - #include -- -- typedef int include_linux_module_stamp; -- typedef int include_linux_kernel_stamp; - } - - chunk LKM::data() +@@ -0,0 +1,55 @@ ++with LKM ++{ ++ /* Skel of the generated C file: */ ++ ${pointcut LKM::includes}; ++ ${pointcut LKM::prototypes}; ++ ${pointcut LKM::data}; ++ ${pointcut LKM::code}; ++ ++ template sequence LKM::init() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ #include ++ } ++ ++ chunk LKM::data() ++ { ++ MODULE_DESCRIPTION(${config.description}); ++ MODULE_AUTHOR(${config.author}); ++ MODULE_LICENSE(${config.license}); ++ } ++ ++ chunk LKM::code() ++ { ++ /* ++ * Rathaxes doesn't yet support arbitrary "decorators" like __init ++ * or __exit. ++ */ ++ static int __attribute__((__section__(".init.text"))) rtx_module_init(void) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ${pointcut LKM::init_bus_hook}; ++ ++ return 0; ++ } ++ ++ module_init(rtx_module_init); ++ } ++ } ++ ++ template sequence LKM::exit() ++ { ++ chunk LKM::code() ++ { ++ static void __attribute__((__section__(".exit.text"))) rtx_module_exit(void) ++ { ++ ${pointcut ::IMPLEMENTATION}; ++ ${pointcut LKM::deinit_bus_hook}; ++ } ++ ++ module_exit(rtx_module_exit); ++ } ++ } ++} +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 +@@ -0,0 +1,25 @@ ++interface LKM ++{ ++ provided pointcut LKM::includes; ++ /* maybe it should be possible to use chunk ::decl in sequence templates? */ ++ provided pointcut LKM::prototypes; ++ provided pointcut LKM::data; ++ provided pointcut LKM::code; ++ ++ required variable ::string LKM::author; ++ required variable ::string LKM::description; ++ required variable ::string LKM::license; ++ ++ required sequence LKM::init() ++ { ++ provided chunk LKM::includes; ++ provided chunk LKM::code; ++ provided pointcut LKM::init_bus_hook; ++ } ++ ++ required sequence LKM::exit() ++ { ++ provided chunk LKM::code; ++ provided pointcut LKM::deinit_bus_hook; ++ } ++} diff --git a/rathaxes/samples/lkm/lkm.rtx b/rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/lkm.rtx -@@ -1,4 +1,4 @@ --device LKM use LKM, PCI, Log +@@ -0,0 +1,46 @@ +device LKM use LKM, PCI, Ethernet, Log - { - Ethernet::open(Ethernet::Device dev) - { ++{ ++ Ethernet::open(Ethernet::Device dev) ++ { ++ Log::info("Open the device"); ++ } ++ ++ Ethernet::close(Ethernet::Device dev) ++ { ++ Log::info("Close the device"); ++ } ++ ++ Ethernet::interrupt_handler(Ethernet::Device dev) ++ { ++ Log::info("Got an interruption"); ++ } ++ ++ Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) ++ { ++ Log::info("We have one packet to transmit!"); ++ } ++ ++ LKM::init() ++ { ++ Log::info("Hello this is LKM"); ++ } ++ ++ LKM::exit() ++ { ++ Log::info("Good bye this was LKM"); ++ } ++} ++ ++configuration ++{ ++ LKM::name = "hello"; ++ LKM::author = "Rathaxes"; ++ LKM::description = "Hello World Loadable Kernel Module (LKM)"; ++ LKM::license = "GPL"; ++ ++ PCI::vendor_id = 0x8086; ++ PCI::product_id = 0x100f; ++ PCI::set_master = true; ++ ++ 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 +@@ -0,0 +1,10 @@ ++with Log ++{ ++ template sequence Log::info(::string msg) ++ { ++ chunk ::CALL ++ { ++ pr_info("%s\n", ${msg}); ++ } ++ } ++} +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 +@@ -0,0 +1,7 @@ ++interface Log ++{ ++ provided sequence Log::info(::string) ++ { ++ provided chunk ::CALL; ++ } ++} diff --git a/rathaxes/samples/lkm/pci.blt b/rathaxes/samples/lkm/pci.blt ---- a/rathaxes/samples/lkm/pci.blt +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/pci.blt -@@ -5,8 +5,6 @@ - chunk LKM::includes() - { - #include -- -- typedef int include_linux_pci_stamp; - } - - chunk ::decl() -@@ -24,16 +22,6 @@ - } - } - -- /* -- * The PCI::probe sequence is a "required" sequence which means that its -- * implementation will be done in the .rtx. Here we just define the context -- * were this implementation will be inserted. The implementation should be -- * able to access to the struct pci_dev (here marked as the "argument" -- * PCI::Device). How do we bind this PCI::Device argument with the pdev -- * struct pci_dev pointer defined in the LKM::code chunk? -- * -- * The only thing I can imagine is: ${pointcut ::IMPLEMENTATION(pdev)}; -- */ - template sequence PCI::probe(PCI::Device pdev) - { - chunk LKM::prototypes() -@@ -112,22 +100,32 @@ - - chunk LKM::init_bus_hook() - { -- /* -- * So how do we use the return value in the parent context? -- */ - int error; - if ((error = pci_register_driver(&rtx_pci_driver))) - { - ${Log::info("Cannot register pci driver")}; -- // should we return here. -- // error managmement procedure has to be determined ASAP. +@@ -0,0 +1,143 @@ ++with PCI, LKM, Log ++{ ++ template type PCI::Device() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ } ++ ++ chunk ::decl() ++ { ++ struct pci_dev; ++ } ++ ++ chunk ::init(pci_dev) ++ { ++ ${self} = ${pci_dev}; ++ } ++ ++ map ++ { ++ } ++ } ++ ++ template sequence PCI::probe(PCI::Device pdev) ++ { ++ chunk LKM::prototypes() ++ { ++ static int /* __devinit */ rtx_pci_probe(struct pci_dev *, ++ const struct pci_device_id *); ++ } ++ ++ chunk LKM::code() ++ { ++ static int /* __devinit */ rtx_pci_probe(struct pci_dev *pdev, ++ const struct pci_device_id *pdev_id) ++ { ++ int err; ++ ++ err = pci_enable_device(pdev); ++ if (err < 0) ++ goto fail; ++ ++ ${pointcut PCI::pci_probe_hook}; ++ ++ return 0; ++ ++ fail: ++ return err; ++ } ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++ ++ template sequence PCI::remove(PCI::Device pdev) ++ { ++ chunk LKM::prototypes() ++ { ++ static void rtx_pci_remove(struct pci_dev *); ++ } ++ ++ chunk LKM::code() ++ { ++ static void rtx_pci_remove(struct pci_dev *pdev) ++ { ++ ${pointcut PCI::pci_remove_hook}; ++ ++ pci_disable_device(pdev); ++ } ++ } ++ ++ chunk ::CALL() ++ { ++ } ++ } ++ ++ template sequence PCI::register() ++ { ++ chunk LKM::data() ++ { ++ /* ++ * CNorm doesn't seem to like "dynamic" arrays (i.e: you always ++ * have to specify the exact size). ++ */ ++ static struct pci_device_id rtx_pci_device_table[2] = { ++ { ${config.vendor_id}, ${config.product_id}, PCI_ANY_ID, PCI_ANY_ID }, ++ { 0, } ++ }; ++ ++ static struct pci_driver rtx_pci_driver = { ++ .name = ${config.name}, ++ .id_table = rtx_pci_device_table, ++ .probe = rtx_pci_probe, ++ .remove = rtx_pci_remove ++ }; ++ } ++ ++ chunk LKM::init_bus_hook() ++ { ++ int error; ++ if ((error = pci_register_driver(&rtx_pci_driver))) ++ { ++ ${Log::info("Cannot register pci driver")}; + /* + * So we catched the error but how do we return it to the + * parent context? @@ -183,13 +686,12 @@ + * a coincidence (and, in this case, *we* wrote the parent + * context). + */ - return error; - } - } - - chunk ::CALL() - { -- // no implementation, we just need to instrument the lkm::bus_hook ++ return error; ++ } ++ } ++ ++ chunk ::CALL() ++ { + /* + * The implementation of ::CALL is empty. This template sequence is + * actually not provided nor required. @@ -198,21 +700,100 @@ + * itself in the hook LKM::init_bus_hook for which this sequence + * has a chunk (see above chunk). + */ - } - } - ++ } ++ } ++ ++ template sequence PCI::unregister() ++ { ++ chunk LKM::deinit_bus_hook() ++ { ++ pci_unregister_driver(&rtx_pci_driver); ++ } ++ ++ chunk ::CALL ++ { ++ } ++ } ++} diff --git a/rathaxes/samples/lkm/pci.rti b/rathaxes/samples/lkm/pci.rti ---- a/rathaxes/samples/lkm/pci.rti +new file mode 100644 +--- /dev/null +++ b/rathaxes/samples/lkm/pci.rti -@@ -7,11 +7,6 @@ - - provided sequence PCI::register() - { -- // it is impossible to provide a "dummy" sequence -- // which just hook itself. The PCI:register juste -- // inject its code in the module_init function -- // in order to load the pci driver. -- // Everything is done with the configuration. - provided chunk ::CALL; - provided chunk LKM::data; - provided chunk LKM::init_bus_hook; +@@ -0,0 +1,36 @@ ++interface PCI : LKM ++{ ++ provided type PCI::Device; ++ ++ required variable ::number PCI::vendor_id; ++ required variable ::number PCI::product_id; ++ ++ provided sequence PCI::register() ++ { ++ provided chunk ::CALL; ++ provided chunk LKM::data; ++ provided chunk LKM::init_bus_hook; ++ } ++ ++ provided sequence PCI::unregister() ++ { ++ provided chunk ::CALL; ++ provided chunk LKM::deinit_bus_hook; ++ } ++ ++ provided sequence PCI::probe(PCI::Device) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ ++ provided pointcut PCI::pci_probe_hook; ++ } ++ ++ provided sequence PCI::remove(PCI::Device) ++ { ++ provided chunk LKM::prototypes; ++ provided chunk LKM::code; ++ ++ 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 +@@ -0,0 +1,27 @@ ++with Socket, LKM ++{ ++ template type Socket::SKBuff() ++ { ++ chunk LKM::includes() ++ { ++ #include ++ } ++ ++ chunk ::decl() ++ { ++ struct sk_buff; ++ } ++ ++ chunk ::init() ++ { ++ } ++ ++ map ++ { ++ // some work may have to be done here in order ++ // to access to some field of the sk_buff. ++ // We should determine if all the sk_buff managment ++ // can be abstracted from the user. ++ } ++ } ++} +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 +@@ -0,0 +1,4 @@ ++interface Socket : LKM ++{ ++ provided type Socket::SKBuff; ++} diff -r 9433dec37a52 -r f43900ad7e66 rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch --- a/rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,319 +0,0 @@ -# HG changeset patch -# Parent 6e00628ccba9fd82577a8a30fe4e730bc982e987 -rathaxes: start to implement the PCI registration part in the LKM sample - -diff -r 6e00628ccba9 rathaxes/samples/lkm/CMakeLists.txt ---- a/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 19:07:39 2012 +0100 -+++ b/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 19:10:21 2012 +0100 -@@ -1,3 +1,7 @@ - ADD_RATHAXES_SOURCES(lkm lkm.rtx -- RTI log.rti lkm.rti -- BLT log.blt lkm.blt) -+ RTI log.rti lkm.rti pci.rti -+ BLT log.blt lkm.blt pci.blt) -+ -+# 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_hello lkm) -diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.blt ---- a/rathaxes/samples/lkm/lkm.blt Sat Jan 07 19:07:39 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.blt Sat Jan 07 19:10:21 2012 +0100 -@@ -1,8 +1,10 @@ - with LKM - { -+ /* Skel of the generated C file: */ - ${pointcut LKM::includes}; -- ${pointcut LKM::init}; -- ${pointcut LKM::exit}; -+ ${pointcut LKM::prototypes}; -+ ${pointcut LKM::data}; -+ ${pointcut LKM::code}; - - template sequence LKM::init() - { -@@ -10,22 +12,29 @@ - { - #include - #include -- typedef int lkm_headers_include_stamp; - -+ typedef int include_linux_module_stamp; -+ typedef int include_linux_kernel_stamp; -+ } -+ -+ chunk LKM::data() -+ { - MODULE_DESCRIPTION(${config.description}); - MODULE_AUTHOR(${config.author}); - MODULE_LICENSE(${config.license}); - } - -- chunk LKM::init() -+ chunk LKM::code() - { - /* - * Rathaxes doesn't yet support arbitrary "decorators" like __init - * or __exit. - */ -- static int __attribute__((__section__(.init.text))) rtx_module_init(void) -+ static int __attribute__((__section__(".init.text"))) rtx_module_init(void) - { - ${pointcut ::IMPLEMENTATION}; -+ -+ return 0; - } - - module_init(rtx_module_init); -@@ -34,14 +43,14 @@ - - template sequence LKM::exit() - { -- chunk LKM::exit -+ chunk LKM::code() - { -- static void __attribute((__section__(.exit.text))) rtx_module_exit(void) -+ static void __attribute__((__section__(".exit.text"))) rtx_module_exit(void) - { - ${pointcut ::IMPLEMENTATION}; - } - -- module_exit(rtx_module_init); -+ module_exit(rtx_module_exit); - } - } - } -diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.rti ---- a/rathaxes/samples/lkm/lkm.rti Sat Jan 07 19:07:39 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rti Sat Jan 07 19:10:21 2012 +0100 -@@ -1,8 +1,10 @@ - interface LKM - { - provided pointcut LKM::includes; -- provided pointcut LKM::init; -- provided pointcut LKM::exit; -+ /* maybe it should be possible to use chunk ::decl in sequence templates? */ -+ provided pointcut LKM::prototypes; -+ provided pointcut LKM::data; -+ provided pointcut LKM::code; - - required variable ::string LKM::author; - required variable ::string LKM::description; -@@ -11,11 +13,11 @@ - required sequence LKM::init() - { - provided chunk LKM::includes; -- provided chunk LKM::init; -+ provided chunk LKM::code; - } - - required sequence LKM::exit() - { -- provided chunk LKM::exit; -+ provided chunk LKM::code; - } - } -diff -r 6e00628ccba9 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 19:07:39 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 19:10:21 2012 +0100 -@@ -1,19 +1,35 @@ --device LKM use LKM, Log -+device LKM use LKM, PCI, Log - { -+ PCI::probe(PCI::Device dev) -+ { -+ -+ } -+ -+ PCI::remove(PCI::Device dev) -+ { -+ -+ } -+ - LKM::init() - { - Log::info("Hello this is LKM"); -+ PCI::register(); - } - - LKM::exit() - { - Log::info("Good bye this was LKM"); -+ PCI::unregister(); - } - } - - configuration - { -+ LKM::name = "hello"; - LKM::author = "Rathaxes"; - LKM::description = "Hello World Loadable Kernel Module (LKM)"; - LKM::license = "BSD"; -+ -+ PCI::vendor_id = 0x8086; -+ PCI::product_id = 0x100f; - } -diff -r 6e00628ccba9 rathaxes/samples/lkm/pci.blt ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/pci.blt Sat Jan 07 19:10:21 2012 +0100 -@@ -0,0 +1,127 @@ -+with PCI, LKM, Log -+{ -+ template type PCI::Device() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ -+ typedef int include_linux_pci_stamp; -+ } -+ -+ chunk ::decl() -+ { -+ struct rtx_pci_device -+ { -+ struct pci_dev *pci_dev; -+ }; -+ } -+ -+ chunk ::init(pci_dev) -+ { -+ ${self}.pci_dev = pci_dev; -+ } -+ -+ map -+ { -+ } -+ } -+ -+ template sequence PCI::probe(PCI::Device dev) -+ { -+ chunk LKM::prototypes() -+ { -+ static int /* __devinit */ rtx_pci_probe(struct pci_dev *, -+ const struct pci_device_id *); -+ } -+ -+ chunk LKM::code() -+ { -+ static int /* __devinit */ rtx_pci_probe(struct pci_dev *pdev, -+ const struct pci_device_id *pdev_id) -+ { -+ /* workaround for CNorm __std__ dialect, shouldn't be here */ -+ typedef int ${PCI::Device}; -+ -+ int err; -+ ${PCI::Device} *dev = NULL; -+ -+ err = pci_enable_device(pdev); -+ if (err < 0) -+ goto fail; -+ -+ ${pointcut ::IMPLEMENTATION}; -+ -+ pci_set_drvdata(pdev, dev); -+ -+ return 0; -+ -+ fail: -+ return err; -+ } -+ } -+ } -+ -+ template sequence PCI::remove(PCI::Device dev) -+ { -+ chunk LKM::prototypes() -+ { -+ static void rtx_pci_remove(struct pci_dev *); -+ } -+ -+ chunk LKM::code() -+ { -+ static void rtx_pci_remove(struct pci_dev *pdev) -+ { -+ pci_disable_device(pdev); -+ -+ ${pointcut ::IMPLEMENTATION}; -+ } -+ } -+ } -+ -+ template sequence PCI::register() -+ { -+ chunk LKM::data() -+ { -+ /* -+ * CNorm doesn't seem to like "dynamic" arrays (i.e: you always -+ * have to specify the exact size). -+ */ -+ static struct pci_device_id rtx_pci_device_table[2] = { -+ { ${config.vendor_id}, ${config.product_id}, 0, PCI_ANY_ID, PCI_ANY_ID }, -+ { 0, } -+ }; -+ -+ static struct pci_driver rtx_pci_driver = { -+ .name = ${config.name}, -+ .id_table = rtx_pci_device_table, -+ .probe = rtx_pci_probe, -+ .remove = rtx_pci_remove -+ }; -+ } -+ -+ chunk ::CALL -+ { -+ /* -+ * So how do we use the return value in the parent context? -+ */ -+ int error; -+ if ((error = pci_register_driver(&rtx_pci_driver))) -+ { -+ ${Log::info("Cannot register pci driver")}; -+ // should we return here. -+ // error managmement procedure has to be determined ASAP. -+ return error; -+ } -+ } -+ } -+ -+ template sequence PCI::unregister() -+ { -+ chunk ::CALL -+ { -+ pci_unregister_driver(&rtx_pci_driver); -+ } -+ } -+} -diff -r 6e00628ccba9 rathaxes/samples/lkm/pci.rti ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/pci.rti Sat Jan 07 19:10:21 2012 +0100 -@@ -0,0 +1,30 @@ -+interface PCI : LKM -+{ -+ provided type PCI::Device; -+ -+ required variable ::number PCI::vendor_id; -+ required variable ::number PCI::product_id; -+ -+ provided sequence PCI::register() -+ { -+ provided chunk ::CALL; -+ provided chunk LKM::data; -+ } -+ -+ provided sequence PCI::unregister() -+ { -+ provided chunk ::CALL; -+ } -+ -+ required sequence PCI::probe(PCI::Device) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+ -+ required sequence PCI::remove(PCI::Device) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+} diff -r 9433dec37a52 -r f43900ad7e66 rathaxes_start_to_implement_sk_buff_in_the_lkm.patch --- a/rathaxes_start_to_implement_sk_buff_in_the_lkm.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -# HG changeset patch -# Parent 86594bdb2ed616f9cbbafe8d78bccc676f832f49 -rathaxes: add sk_buff abstraction and add the implementation of the xmit function for the ethernet system. We have a fully (empty) functionnal ethernet driver - -diff -r 86594bdb2ed6 rathaxes/samples/lkm/CMakeLists.txt ---- a/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 20:51:10 2012 +0100 -+++ b/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 20:51:27 2012 +0100 -@@ -1,6 +1,6 @@ - ADD_RATHAXES_SOURCES(lkm lkm.rtx -- RTI log.rti lkm.rti pci.rti ethernet.rti -- BLT log.blt lkm.blt pci.blt ethernet.blt) -+ RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti -+ BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt) - - # We can't name lkm since it's already used as the target name to generate the - # source (with ADD_RATHAXES_SOURCES). -diff -r 86594bdb2ed6 rathaxes/samples/lkm/e1000.blt ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/e1000.blt Sat Jan 07 20:51:27 2012 +0100 -@@ -0,0 +1,72 @@ -+with e1000, Ethernet, Socket, PCI, LKM, Log -+{ -+ template type e1000::Context() -+ { -+ chunk LKM::includes() -+ { -+ /* -+ * Force the generation of the structure in the "headers part, we -+ * have to do this since we do not use the structure in this blt -+ * (we hacked a bit and used it in ethernet.blt directly). -+ */ -+ typedef int ${e1000::Context}; /* CNorm __std__ workaround */ -+ ${e1000::Context} force_declaration_in_includes; -+ } -+ -+ chunk ::decl() -+ { -+ struct rtx_e1000_ctx -+ { -+ int bars; -+ unsigned char /* __iomem */ *ioaddr; -+ }; -+ } -+ -+ map -+ { -+ } -+ } -+ -+ template sequence e1000::create() -+ { -+ chunk ::CALL -+ { -+ rtx_ether_ctx->hw_ctx.bars = pci_select_bars(pdev, IORESOURCE_MEM); -+ 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})) -+ { -+ ${Log::info("e1000::create: pci_request_selected_regions failed")}; -+ } -+ -+ if (${config.set_master}) -+ { -+ 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) -+ { -+ ${Log::info("e1000::create: pci_ioremap_bar failed")}; -+ } -+ } -+ } -+ -+ template sequence e1000::destroy() -+ { -+ chunk ::CALL -+ { -+ // XXX: add a check in order to avoid freeing none allocated -+ // resources. -+ struct net_device *net_dev = pci_get_drvdata(pdev); -+ 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); -+ pci_release_region(pdev, 0); -+ } -+ } -+} -diff -r 86594bdb2ed6 rathaxes/samples/lkm/e1000.rti ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/e1000.rti Sat Jan 07 20:51:27 2012 +0100 -@@ -0,0 +1,15 @@ -+interface e1000 : Socket, Ethernet, PCI, LKM -+{ -+ provided type e1000::Context; -+ -+ /* Not sure if we need the argument */ -+ provided sequence e1000::create() -+ { -+ provided chunk ::CALL; -+ } -+ -+ provided sequence e1000::destroy() -+ { -+ provided chunk ::CALL; -+ } -+} -diff -r 86594bdb2ed6 rathaxes/samples/lkm/ethernet.blt ---- a/rathaxes/samples/lkm/ethernet.blt Sat Jan 07 20:51:10 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.blt Sat Jan 07 20:51:27 2012 +0100 -@@ -18,8 +18,11 @@ - * I think it's useless to use the ${PCI::Device} "abstraction" - * here, since we are already in a Linux specific context here. - */ -- struct pci_dev *pci_dev; -- struct net_device *net_dev; -+ struct pci_dev *pci_dev; -+ struct net_device *net_dev; -+ -+ /* while waiting on issue #8 */ -+ struct rtx_e1000_ctx hw_ctx; - }; - } - -@@ -51,6 +54,24 @@ - } - } - -+ template sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) -+ { -+ chunk LKM::prototypes() -+ { -+ static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev); -+ } -+ -+ chunk LKM::code() -+ { -+ static int rtx_ethernet_xmit(struct sk_buff* skb, struct net_device *dev) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ -+ return 0; -+ } -+ } -+ } -+ - template sequence Ethernet::close(Ethernet::Device dev) - { - chunk LKM::prototypes() -@@ -100,7 +121,7 @@ - { - .ndo_open = rtx_ethernet_open, - .ndo_stop = rtx_ethernet_close, -- .ndo_start_xmit = NULL, -+ .ndo_start_xmit = rtx_ethernet_xmit, - }; - } - -@@ -159,9 +180,6 @@ - { - chunk ::CALL - { -- struct net_device *net_dev; -- -- net_dev = pci_get_drvdata(pdev); // should be ${pdev}, see above - unregister_netdev(net_dev); - /* - * If we had some cleanup todo with struct rtx_ether_ctx we would -diff -r 86594bdb2ed6 rathaxes/samples/lkm/ethernet.rti ---- a/rathaxes/samples/lkm/ethernet.rti Sat Jan 07 20:51:10 2012 +0100 -+++ b/rathaxes/samples/lkm/ethernet.rti Sat Jan 07 20:51:27 2012 +0100 -@@ -1,4 +1,4 @@ --interface Ethernet : PCI, LKM -+interface Ethernet : Socket, PCI, LKM - { - provided type Ethernet::Device; - -@@ -10,6 +10,12 @@ - provided chunk LKM::code; - } - -+ required sequence Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+ - required sequence Ethernet::close(Ethernet::Device) - { - provided chunk LKM::prototypes; -diff -r 86594bdb2ed6 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 20:51:10 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 20:51:27 2012 +0100 -@@ -15,15 +15,22 @@ - Log::info("Got an interruption"); - } - -+ Ethernet::send(Ethernet::Device dev, Socket::SKBuff skb) -+ { -+ Log::info("We have one packet to transmit!"); -+ } -+ - PCI::probe(PCI::Device dev) - { - Log::info("Probe the device"); - Ethernet::init(dev); -+ e1000::create(); - } - - PCI::remove(PCI::Device dev) - { - Log::info("Remove the pci device"); -+ e1000::destroy(); - Ethernet::exit(dev); - } - -@@ -45,10 +52,11 @@ - LKM::name = "hello"; - LKM::author = "Rathaxes"; - LKM::description = "Hello World Loadable Kernel Module (LKM)"; -- LKM::license = "BSD"; -+ LKM::license = "GPL"; - - PCI::vendor_id = 0x8086; - PCI::product_id = 0x100f; -+ PCI::set_master = true; - - Ethernet::ifname = "rtx%d"; - } -diff -r 86594bdb2ed6 rathaxes/samples/lkm/socket.blt ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/socket.blt Sat Jan 07 20:51:27 2012 +0100 -@@ -0,0 +1,27 @@ -+with Socket, LKM -+{ -+ template type Socket::SKBuff() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ } -+ -+ chunk ::decl() -+ { -+ struct sk_buff; -+ } -+ -+ chunk ::init() -+ { -+ } -+ -+ map -+ { -+ // some work may have to be done here in order -+ // to access to some field of the sk_buff. -+ // We should determine if all the sk_buff managment -+ // can be abstracted from the user. -+ } -+ } -+} -diff -r 86594bdb2ed6 rathaxes/samples/lkm/socket.rti ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/socket.rti Sat Jan 07 20:51:27 2012 +0100 -@@ -0,0 +1,4 @@ -+interface Socket : LKM -+{ -+ provided type Socket::SKBuff; -+} diff -r 9433dec37a52 -r f43900ad7e66 rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch --- a/rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch Sun Jan 08 01:45:20 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,368 +0,0 @@ -# HG changeset patch -# Parent 53c073d05449cc4cd6130bd79eb02c07239dd8d8 -rathaxes: start to implement the Ethernet subsystem in linux LKM sample - -diff -r 53c073d05449 rathaxes/samples/lkm/CMakeLists.txt ---- a/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 19:10:21 2012 +0100 -+++ b/rathaxes/samples/lkm/CMakeLists.txt Sat Jan 07 19:18:24 2012 +0100 -@@ -1,6 +1,6 @@ - ADD_RATHAXES_SOURCES(lkm lkm.rtx -- RTI log.rti lkm.rti pci.rti -- BLT log.blt lkm.blt pci.blt) -+ RTI log.rti lkm.rti pci.rti ethernet.rti -+ BLT log.blt lkm.blt pci.blt ethernet.blt) - - # We can't name lkm since it's already used as the target name to generate the - # source (with ADD_RATHAXES_SOURCES). -diff -r 53c073d05449 rathaxes/samples/lkm/ethernet.blt ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/ethernet.blt Sat Jan 07 19:18:24 2012 +0100 -@@ -0,0 +1,173 @@ -+with Ethernet, PCI, LKM, Log -+{ -+ template type Ethernet::Device() -+ { -+ chunk LKM::includes() -+ { -+ #include -+ #include -+ -+ typedef int include_linux_net_system_stamp; -+ } -+ -+ chunk ::decl() -+ { -+ struct rtx_ethernet_dev -+ { -+ /* -+ * I think it's useless to use the ${PCI::Device} "abstraction" -+ * here, since we are already in a Linux specific context here. -+ */ -+ struct pci_dev *pci_dev; -+ struct net_device *net_dev; -+ }; -+ } -+ -+ chunk ::init(net_dev) -+ { -+ ${self} = ${net_dev}; -+ } -+ -+ map -+ { -+ } -+ } -+ -+ template sequence Ethernet::open(Ethernet::Device dev) -+ { -+ chunk LKM::prototypes() -+ { -+ static int rtx_ethernet_open(struct net_device *); -+ } -+ -+ chunk LKM::code() -+ { -+ static int rtx_ethernet_open(struct net_device *dev) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ -+ return 0; -+ } -+ } -+ } -+ -+ template sequence Ethernet::close(Ethernet::Device dev) -+ { -+ chunk LKM::prototypes() -+ { -+ static int rtx_ethernet_close(struct net_device *); -+ } -+ -+ chunk LKM::code() -+ { -+ static int rtx_ethernet_close(struct net_device *dev) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ -+ return 0; -+ } -+ } -+ } -+ -+ template sequence Ethernet::interrupt_handler(Ethernet::Device dev) -+ { -+ /* -+ * Why we can't use irqreturn_t here? (we are forced to use enum -+ * irqreturn, which is the real type). -+ */ -+ -+ chunk LKM::prototypes() -+ { -+ static enum irqreturn rtx_ethernet_interrupt_handler(int, void *); -+ } -+ -+ chunk LKM::code() -+ { -+ static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id) -+ { -+ ${pointcut ::IMPLEMENTATION}; -+ -+ return IRQ_NONE; -+ } -+ } -+ } -+ -+ template sequence Ethernet::init(PCI::Device pdev) -+ { -+ chunk LKM::data() -+ { -+ static const struct net_device_ops rtx_ether_ops = -+ { -+ .ndo_open = rtx_ethernet_open, -+ .ndo_stop = rtx_ethernet_close, -+ .ndo_start_xmit = NULL, -+ }; -+ } -+ -+ chunk ::CALL -+ { -+ /* -+ * This typedef is needed to workaround a bug in CNorm __std__ -+ * dialect. -+ */ -+ typedef int ${Ethernet::Device}; -+ ${Ethernet::Device} *rtx_ether_ctx; -+ struct net_device *net_dev; -+ int error; -+ -+ error = 0; -+ net_dev = alloc_etherdev(sizeof(*rtx_ether_ctx)); -+ if (net_dev == 0) -+ { -+ ${Log::info("Cannot allocate memory")}; -+ // is it the thing to do? -+ return -ENOMEM; -+ } -+ strlcpy(net_dev->name, ${config.ifname}, sizeof(net_dev->name)); -+ net_dev->irq = pdev->irq; -+ // Maybe we should try ${rtx_ether_ctx.init()} here: -+ rtx_ether_ctx = netdev_priv(net_dev); -+ //rtx_ether_ctx->pci_dev = ${pdev}; -+ rtx_ether_ctx->pci_dev = pdev; // In the meantime do it directly -+ rtx_ether_ctx->net_dev = net_dev; -+ -+ /* -+ * The substitution of ${pdev} fails here. I also tried to add a -+ * "substitute method" to the PCI::Device that was just doing -+ * "${self}" but it didn't work either (it was subsituted by a -+ * placeholder, e.g: _1). -+ * -+ * That's why we cheated a bit and named all the arguments pdev. -+ */ -+ //SET_NETDEV_DEV(net_dev, &${pdev}->dev); -+ SET_NETDEV_DEV(net_dev, &pdev->dev); -+ net_dev->netdev_ops = &rtx_ether_ops; -+ if ((error = register_netdev(net_dev))) -+ { -+ ${Log::info("Cannot register the driver")}; -+ // is it the thing to do? -+ return error; -+ } -+ -+ /* same problem as above with ${pdev} */ -+ //pci_set_drvdata(${pdev}, net_dev); -+ pci_set_drvdata(pdev, net_dev); -+ } -+ } -+ -+ template sequence Ethernet::exit(PCI::Device pdev) -+ { -+ chunk ::CALL -+ { -+ struct net_device *net_dev; -+ -+ net_dev = pci_get_drvdata(pdev); // should be ${pdev}, see above -+ 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); -+ } -+ } -+} -diff -r 53c073d05449 rathaxes/samples/lkm/ethernet.rti ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/rathaxes/samples/lkm/ethernet.rti Sat Jan 07 19:18:24 2012 +0100 -@@ -0,0 +1,37 @@ -+interface Ethernet : PCI, LKM -+{ -+ provided type Ethernet::Device; -+ -+ required variable ::string Ethernet::ifname; -+ -+ required sequence Ethernet::open(Ethernet::Device) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+ -+ required sequence Ethernet::close(Ethernet::Device) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+ -+ required sequence Ethernet::interrupt_handler(Ethernet::Device) -+ { -+ provided chunk LKM::prototypes; -+ provided chunk LKM::code; -+ } -+ -+ /* Kinda extends PCI::probe */ -+ provided sequence Ethernet::init(PCI::Device) -+ { -+ provided chunk LKM::data; -+ provided chunk ::CALL; -+ } -+ -+ /* Likely extends PCI::remove */ -+ provided sequence Ethernet::exit(PCI::Device) -+ { -+ provided chunk ::CALL; -+ } -+} -diff -r 53c073d05449 rathaxes/samples/lkm/lkm.rtx ---- a/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 19:10:21 2012 +0100 -+++ b/rathaxes/samples/lkm/lkm.rtx Sat Jan 07 19:18:24 2012 +0100 -@@ -1,13 +1,30 @@ - device LKM use LKM, PCI, Log - { -+ Ethernet::open(Ethernet::Device dev) -+ { -+ Log::info("Open the device"); -+ } -+ -+ Ethernet::close(Ethernet::Device dev) -+ { -+ Log::info("Close the device"); -+ } -+ -+ Ethernet::interrupt_handler(Ethernet::Device dev) -+ { -+ Log::info("Got an interruption"); -+ } -+ - PCI::probe(PCI::Device dev) - { -- -+ Log::info("Probe the device"); -+ Ethernet::init(dev); - } - - PCI::remove(PCI::Device dev) - { -- -+ Log::info("Remove the pci device"); -+ Ethernet::exit(dev); - } - - LKM::init() -@@ -32,4 +49,6 @@ - - PCI::vendor_id = 0x8086; - PCI::product_id = 0x100f; -+ -+ Ethernet::ifname = "rtx%d"; - } -diff -r 53c073d05449 rathaxes/samples/lkm/pci.blt ---- a/rathaxes/samples/lkm/pci.blt Sat Jan 07 19:10:21 2012 +0100 -+++ b/rathaxes/samples/lkm/pci.blt Sat Jan 07 19:18:24 2012 +0100 -@@ -11,15 +11,12 @@ - - chunk ::decl() - { -- struct rtx_pci_device -- { -- struct pci_dev *pci_dev; -- }; -+ struct pci_dev; - } - - chunk ::init(pci_dev) - { -- ${self}.pci_dev = pci_dev; -+ ${self} = ${pci_dev}; - } - - map -@@ -27,7 +24,17 @@ - } - } - -- template sequence PCI::probe(PCI::Device dev) -+ /* -+ * The PCI::probe sequence is a "required" sequence which means that its -+ * implementation will be done in the .rtx. Here we just define the context -+ * were this implementation will be inserted. The implementation should be -+ * able to access to the struct pci_dev (here marked as the "argument" -+ * PCI::Device). How do we bind this PCI::Device argument with the pdev -+ * struct pci_dev pointer defined in the LKM::code chunk? -+ * -+ * The only thing I can imagine is: ${pointcut ::IMPLEMENTATION(pdev)}; -+ */ -+ template sequence PCI::probe(PCI::Device pdev) - { - chunk LKM::prototypes() - { -@@ -40,11 +47,7 @@ - static int /* __devinit */ rtx_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *pdev_id) - { -- /* workaround for CNorm __std__ dialect, shouldn't be here */ -- typedef int ${PCI::Device}; -- - int err; -- ${PCI::Device} *dev = NULL; - - err = pci_enable_device(pdev); - if (err < 0) -@@ -52,8 +55,6 @@ - - ${pointcut ::IMPLEMENTATION}; - -- pci_set_drvdata(pdev, dev); -- - return 0; - - fail: -@@ -62,7 +63,7 @@ - } - } - -- template sequence PCI::remove(PCI::Device dev) -+ template sequence PCI::remove(PCI::Device pdev) - { - chunk LKM::prototypes() - { -@@ -73,9 +74,9 @@ - { - static void rtx_pci_remove(struct pci_dev *pdev) - { -+ ${pointcut ::IMPLEMENTATION}; -+ - pci_disable_device(pdev); -- -- ${pointcut ::IMPLEMENTATION}; - } - } - } -@@ -89,7 +90,7 @@ - * have to specify the exact size). - */ - static struct pci_device_id rtx_pci_device_table[2] = { -- { ${config.vendor_id}, ${config.product_id}, 0, PCI_ANY_ID, PCI_ANY_ID }, -+ { ${config.vendor_id}, ${config.product_id}, PCI_ANY_ID, PCI_ANY_ID }, - { 0, } - }; - diff -r 9433dec37a52 -r f43900ad7e66 series --- a/series Sun Jan 08 01:45:20 2012 +0100 +++ b/series Sun Jan 08 01:51:34 2012 +0100 @@ -1,10 +1,3 @@ doc_improve_first_steps.patch provided_pointcut_in_required_sequences_fail.patch -rathaxes_add_a_linux_lkm.patch -rathaxes_start_to_implement_pci_stuff_in_the_lkm.patch -rathaxes_start_to_implement_the_ethernet_subsystem_in_the_lkm.patch -rathaxes_start_to_implement_sk_buff_in_the_lkm.patch -pci_rework_without_explicit_call.patch -ethernet_rework_without_explicit_call.patch -e1000_rework_without_explicit_call.patch rathaxes_add_lkm_ethernet_sample.patch