comparison rathaxes_add_lkm_ethernet_sample.patch @ 39:d761c8c625d3

Try to read a register on the card
author Louis Opter <louis@lse.epitech.net>
date Sun, 08 Jan 2012 14:47:03 +0100
parents f43900ad7e66
children 0ff39df29c46
comparison
equal deleted inserted replaced
38:f43900ad7e66 39:d761c8c625d3
12 diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt 12 diff --git a/rathaxes/samples/lkm/CMakeLists.txt b/rathaxes/samples/lkm/CMakeLists.txt
13 new file mode 100644 13 new file mode 100644
14 --- /dev/null 14 --- /dev/null
15 +++ b/rathaxes/samples/lkm/CMakeLists.txt 15 +++ b/rathaxes/samples/lkm/CMakeLists.txt
16 @@ -0,0 +1,7 @@ 16 @@ -0,0 +1,7 @@
17 +ADD_RATHAXES_SOURCES(lkm lkm.rtx 17 +ADD_RATHAXES_SOURCES(lkm_src lkm.rtx
18 + RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti 18 + RTI log.rti lkm.rti pci.rti socket.rti ethernet.rti e1000.rti
19 + BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt) 19 + BLT log.blt lkm.blt pci.blt socket.blt ethernet.blt e1000.blt)
20 + 20 +
21 +# We can't name lkm since it's already used as the target name to generate the 21 +# We can't name lkm since it's already used as the target name to generate the
22 +# source (with ADD_RATHAXES_SOURCES). 22 +# source (with ADD_RATHAXES_SOURCES).
23 +ADD_RATHAXES_LKM(lkm_hello lkm) 23 +ADD_RATHAXES_LKM(lkm lkm_src)
24 diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt 24 diff --git a/rathaxes/samples/lkm/e1000.blt b/rathaxes/samples/lkm/e1000.blt
25 new file mode 100644 25 new file mode 100644
26 --- /dev/null 26 --- /dev/null
27 +++ b/rathaxes/samples/lkm/e1000.blt 27 +++ b/rathaxes/samples/lkm/e1000.blt
28 @@ -0,0 +1,80 @@ 28 @@ -0,0 +1,170 @@
29 +with e1000, Ethernet, Socket, PCI, LKM, Log 29 +with e1000, Ethernet, Socket, PCI, LKM, Log
30 +{ 30 +{
31 + template type e1000::Context() 31 + template type e1000::Context()
32 + { 32 + {
33 + chunk LKM::includes() 33 + chunk LKM::includes()
36 + * Force the generation of the structure in the "headers" part, we 36 + * Force the generation of the structure in the "headers" part, we
37 + * have to do this since we do not use the structure in this blt 37 + * have to do this since we do not use the structure in this blt
38 + * (we hacked a bit and used it in ethernet.blt directly). 38 + * (we hacked a bit and used it in ethernet.blt directly).
39 + */ 39 + */
40 + typedef int ${e1000::Context}; /* CNorm __std__ workaround */ 40 + typedef int ${e1000::Context}; /* CNorm __std__ workaround */
41 + ${e1000::Context} force_declaration_in_includes; 41 + static const ${e1000::Context} force_struct_rtx_10000_ctx_decl;
42 + } 42 + }
43 + 43 +
44 + chunk ::decl() 44 + chunk ::decl()
45 + { 45 + {
46 + struct rtx_e1000_ctx 46 + struct rtx_e1000_ctx
48 + int bars; 48 + int bars;
49 + unsigned char /* __iomem */ *ioaddr; 49 + unsigned char /* __iomem */ *ioaddr;
50 + }; 50 + };
51 + } 51 + }
52 + 52 +
53 + chunk ::init(bars, ioaddr)
54 + {
55 + ${self}.bars = ${bars};
56 + ${self}.ioaddr = ${ioaddr};
57 + }
58 +
59 + map
60 + {
61 + }
62 + }
63 +
64 + template type e1000::Register()
65 + {
66 + chunk LKM::includes()
67 + {
68 + typedef int ${e1000::Register};
69 + static const ${e1000::Register} force_enum_rtx_e1000_registers_decl;
70 + }
71 +
72 + chunk ::decl()
73 + {
74 + enum rtx_e1000_registers
75 + {
76 + E1000_CTRL = 0x00000,
77 + E1000_CTRL_DUP = 0x00004,
78 + E1000_STATUS = 0x00008,
79 + E1000_EEPROM_FLASH = 0x00010,
80 + E1000_EEPROM_READ = 0x00014,
81 + E1000_CTRL_EXT = 0x00018,
82 + E1000_FLA = 0x0001C,
83 + E1000_MDIC = 0x00020,
84 + };
85 + }
86 +
87 + chunk ::init(value)
88 + {
89 + ${self} = ${value};
90 + }
91 +
53 + map 92 + map
54 + { 93 + {
55 + } 94 + }
56 + } 95 + }
57 + 96 +
79 + rtx_ether_ctx->hw_ctx.ioaddr = pci_ioremap_bar(pdev, 0); 118 + rtx_ether_ctx->hw_ctx.ioaddr = pci_ioremap_bar(pdev, 0);
80 + if (!rtx_ether_ctx->hw_ctx.ioaddr) 119 + if (!rtx_ether_ctx->hw_ctx.ioaddr)
81 + { 120 + {
82 + ${Log::info("e1000::create: pci_ioremap_bar failed")}; 121 + ${Log::info("e1000::create: pci_ioremap_bar failed")};
83 + } 122 + }
123 +
124 + /* Now we can reset the card and load its mac address */
125 +
126 + /*
127 + * We should have been able to do something along those lines, but
128 + * it didn't work so we made the call manually.
129 + *
130 + * Ideally:
131 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
132 + *
133 + * Ideally2, not sure about the syntax on the register parameter:
134 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, ${e1000::Register.E1000_STATUS})};
135 + *
136 + * "Acceptable":
137 + * typedef int ${e1000::Register}; // cnorm __std__ workaround
138 + * ${e1000::Register} reg_status;
139 + * ${e1000.init(E1000_STATUS); // didn't work, so we used the next line
140 + * reg_status = E1000_STATUS;
141 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, reg_status)};
142 + *
143 + */
144 +
145 + unsigned int status = rtx_e1000_register_read32(&rtx_ether_ctx->hw_ctx, E1000_STATUS);
146 +
147 + pr_info("Status of the e1000 card:\n");
148 + pr_info("\tStatus: %i\n", status);
149 + pr_info("\tMode: %s\n", (status & 1) ? "Full": "Half");
150 + pr_info("\tLink: %s\n", (status & 2) ? "UP" : "Down");
151 + pr_info("\tTransmission: %s\n", (status & 4) ? "Paused" : "Ok");
152 + pr_info("\tInterface: %s\n", (status & 3) == 3 ? "UP" : "Down");
84 + } 153 + }
85 + 154 +
86 + chunk ::CALL 155 + chunk ::CALL
87 + { 156 + {
88 + } 157 + }
103 + 172 +
104 + chunk ::CALL 173 + chunk ::CALL
105 + { 174 + {
106 + } 175 + }
107 + } 176 + }
177 +
178 + template sequence e1000::register_read32(e1000::Context ctx, e1000::Register reg_offset)
179 + {
180 + chunk LKM::prototypes()
181 + {
182 + static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *, unsigned int);
183 + }
184 +
185 + chunk LKM::code()
186 + {
187 + static unsigned int rtx_e1000_register_read32(struct rtx_e1000_ctx *ctx, unsigned int reg_offset)
188 + {
189 + return ioread32(ctx->ioaddr + reg_offset);
190 + }
191 + }
192 +
193 + chunk ::CALL()
194 + {
195 + rtx_e1000_register_read32(&${ctx}, ${reg_offset});
196 + }
197 + }
108 +} 198 +}
109 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti 199 diff --git a/rathaxes/samples/lkm/e1000.rti b/rathaxes/samples/lkm/e1000.rti
110 new file mode 100644 200 new file mode 100644
111 --- /dev/null 201 --- /dev/null
112 +++ b/rathaxes/samples/lkm/e1000.rti 202 +++ b/rathaxes/samples/lkm/e1000.rti
113 @@ -0,0 +1,24 @@ 203 @@ -0,0 +1,39 @@
114 +interface e1000 : Socket, Ethernet, PCI, LKM 204 +interface e1000 : Socket, Ethernet, PCI, LKM
115 +{ 205 +{
116 + provided type e1000::Context; 206 + provided type e1000::Context;
207 + provided type e1000::Register;
117 + 208 +
118 + /* 209 + /*
119 + * This sequence should receive an argument like Ethernet::Device, but it is 210 + * This sequence should receive an argument like Ethernet::Device, but it is
120 + * unclear about how this argument should be bound to a variable/argument in 211 + * unclear about how this argument should be bound to a variable/argument in
121 + * the instrumented C code. 212 + * the instrumented C code.
130 + } 221 + }
131 + 222 +
132 + provided sequence e1000::destroy_device() 223 + provided sequence e1000::destroy_device()
133 + { 224 + {
134 + provided chunk Ethernet::destroy_device; 225 + provided chunk Ethernet::destroy_device;
226 + provided chunk ::CALL;
227 + }
228 +
229 + /*
230 + * It should also take an e1000::Context argument as the first parameter.
231 + * But we weren't able to call the sequence afterwards, with expression
232 + * like:
233 + *
234 + * ${e1000::register_read32(rtx_ether_ctx->hw_ctx, E1000_STATUS)};
235 + */
236 + provided sequence e1000::register_read32(e1000::Context, e1000::Register)
237 + {
238 + provided chunk LKM::prototypes;
239 + provided chunk LKM::code;
135 + provided chunk ::CALL; 240 + provided chunk ::CALL;
136 + } 241 + }
137 +} 242 +}
138 diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt 243 diff --git a/rathaxes/samples/lkm/ethernet.blt b/rathaxes/samples/lkm/ethernet.blt
139 new file mode 100644 244 new file mode 100644