diff options
Diffstat (limited to 'utils/hwstub/tools/hwstub_shell.cpp')
-rw-r--r-- | utils/hwstub/tools/hwstub_shell.cpp | 723 |
1 files changed, 566 insertions, 157 deletions
diff --git a/utils/hwstub/tools/hwstub_shell.cpp b/utils/hwstub/tools/hwstub_shell.cpp index dd5c20b471..88cb1231fb 100644 --- a/utils/hwstub/tools/hwstub_shell.cpp +++ b/utils/hwstub/tools/hwstub_shell.cpp | |||
@@ -18,23 +18,31 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "hwstub.h" | ||
22 | #include <stdio.h> | 21 | #include <stdio.h> |
23 | #include <stdlib.h> | 22 | #include <stdlib.h> |
24 | #include <string.h> | 23 | #include <string.h> |
25 | #include <getopt.h> | 24 | #include <getopt.h> |
26 | #include <stdbool.h> | 25 | #include <stdbool.h> |
26 | #include <sstream> | ||
27 | #include <iomanip> | ||
28 | #include <iostream> | ||
27 | #include <readline/readline.h> | 29 | #include <readline/readline.h> |
28 | #include <readline/history.h> | 30 | #include <readline/history.h> |
29 | #include <lua.hpp> | 31 | #include <lua.hpp> |
30 | #include <unistd.h> | 32 | #include <unistd.h> |
33 | #include <signal.h> | ||
34 | #include <dirent.h> | ||
31 | #include "soc_desc_v1.hpp" | 35 | #include "soc_desc_v1.hpp" |
32 | #include "soc_desc.hpp" | 36 | #include "soc_desc.hpp" |
37 | #include "hwstub.hpp" | ||
38 | #include "hwstub_usb.hpp" | ||
39 | #include "hwstub_uri.hpp" | ||
33 | extern "C" { | 40 | extern "C" { |
34 | #include "prompt.h" | 41 | #include "prompt.h" |
35 | } | 42 | } |
36 | 43 | ||
37 | using namespace soc_desc_v1; | 44 | using namespace soc_desc_v1; |
45 | using namespace hwstub; | ||
38 | 46 | ||
39 | #if LUA_VERSION_NUM < 502 | 47 | #if LUA_VERSION_NUM < 502 |
40 | #warning You need at least lua 5.2 | 48 | #warning You need at least lua 5.2 |
@@ -45,12 +53,17 @@ using namespace soc_desc_v1; | |||
45 | */ | 53 | */ |
46 | bool g_quiet = false; | 54 | bool g_quiet = false; |
47 | bool g_exit = false; | 55 | bool g_exit = false; |
48 | struct hwstub_device_t *g_hwdev; | 56 | bool g_print_mem_rw = false; |
57 | std::shared_ptr<context> g_hwctx; | ||
58 | std::shared_ptr<handle> g_hwdev; | ||
49 | struct hwstub_version_desc_t g_hwdev_ver; | 59 | struct hwstub_version_desc_t g_hwdev_ver; |
50 | struct hwstub_layout_desc_t g_hwdev_layout; | 60 | struct hwstub_layout_desc_t g_hwdev_layout; |
51 | struct hwstub_target_desc_t g_hwdev_target; | 61 | struct hwstub_target_desc_t g_hwdev_target; |
52 | struct hwstub_stmp_desc_t g_hwdev_stmp; | 62 | struct hwstub_stmp_desc_t g_hwdev_stmp; |
63 | struct hwstub_jz_desc_t g_hwdev_jz; | ||
53 | struct hwstub_pp_desc_t g_hwdev_pp; | 64 | struct hwstub_pp_desc_t g_hwdev_pp; |
65 | std::vector<std::shared_ptr<device>> g_devlist; | ||
66 | |||
54 | lua_State *g_lua; | 67 | lua_State *g_lua; |
55 | 68 | ||
56 | /** | 69 | /** |
@@ -95,13 +108,14 @@ void my_lua_print_stack(lua_State *state = 0, int up_to = 0) | |||
95 | * hw specific | 108 | * hw specific |
96 | */ | 109 | */ |
97 | 110 | ||
98 | void print_log(struct hwstub_device_t *hwdev) | 111 | void print_log(std::shared_ptr<handle> hwdev) |
99 | { | 112 | { |
100 | do | 113 | do |
101 | { | 114 | { |
102 | char buffer[128]; | 115 | char buffer[128]; |
103 | int length = hwstub_get_log(hwdev, buffer, sizeof(buffer) - 1); | 116 | size_t length = sizeof(buffer) - 1; |
104 | if(length <= 0) | 117 | error err = hwdev->get_log(buffer, length); |
118 | if(err != error::SUCCESS || length == 0) | ||
105 | break; | 119 | break; |
106 | buffer[length] = 0; | 120 | buffer[length] = 0; |
107 | printf("%s", buffer); | 121 | printf("%s", buffer); |
@@ -188,46 +202,70 @@ typedef void (*hw_writen_fn_t)(lua_State *state, soc_addr_t addr, soc_word_t val | |||
188 | soc_word_t hw_read8(lua_State *state, soc_addr_t addr) | 202 | soc_word_t hw_read8(lua_State *state, soc_addr_t addr) |
189 | { | 203 | { |
190 | uint8_t u; | 204 | uint8_t u; |
191 | if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 205 | size_t sz = sizeof(u); |
206 | error ret = g_hwdev->read(addr, &u, sz, true); | ||
207 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
192 | luaL_error(state, "fail to read8 @ %p", addr); | 208 | luaL_error(state, "fail to read8 @ %p", addr); |
209 | if(g_print_mem_rw) | ||
210 | printf("[read8 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
193 | return u; | 211 | return u; |
194 | } | 212 | } |
195 | 213 | ||
196 | soc_word_t hw_read16(lua_State *state, soc_addr_t addr) | 214 | soc_word_t hw_read16(lua_State *state, soc_addr_t addr) |
197 | { | 215 | { |
198 | uint16_t u; | 216 | uint16_t u; |
199 | if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 217 | size_t sz = sizeof(u); |
218 | error ret = g_hwdev->read(addr, &u, sz, true); | ||
219 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
200 | luaL_error(state, "fail to read16 @ %p", addr); | 220 | luaL_error(state, "fail to read16 @ %p", addr); |
221 | if(g_print_mem_rw) | ||
222 | printf("[read16 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
201 | return u; | 223 | return u; |
202 | } | 224 | } |
203 | 225 | ||
204 | soc_word_t hw_read32(lua_State *state, soc_addr_t addr) | 226 | soc_word_t hw_read32(lua_State *state, soc_addr_t addr) |
205 | { | 227 | { |
206 | uint32_t u; | 228 | uint32_t u; |
207 | if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 229 | size_t sz = sizeof(u); |
230 | error ret = g_hwdev->read(addr, &u, sz, true); | ||
231 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
208 | luaL_error(state, "fail to read32 @ %p", addr); | 232 | luaL_error(state, "fail to read32 @ %p", addr); |
233 | if(g_print_mem_rw) | ||
234 | printf("[read32 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
209 | return u; | 235 | return u; |
210 | } | 236 | } |
211 | 237 | ||
212 | void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val) | 238 | void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val) |
213 | { | 239 | { |
214 | uint8_t u = val; | 240 | uint8_t u = val; |
215 | if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 241 | size_t sz = sizeof(u); |
242 | error ret = g_hwdev->write(addr, &u, sz, true); | ||
243 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
216 | luaL_error(state, "fail to write8 @ %p", addr); | 244 | luaL_error(state, "fail to write8 @ %p", addr); |
245 | if(g_print_mem_rw) | ||
246 | printf("[write8 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
217 | } | 247 | } |
218 | 248 | ||
219 | void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val) | 249 | void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val) |
220 | { | 250 | { |
221 | uint16_t u = val; | 251 | uint16_t u = val; |
222 | if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 252 | size_t sz = sizeof(u); |
253 | error ret = g_hwdev->write(addr, &u, sz, true); | ||
254 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
223 | luaL_error(state, "fail to write16 @ %p", addr); | 255 | luaL_error(state, "fail to write16 @ %p", addr); |
256 | if(g_print_mem_rw) | ||
257 | printf("[write16 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
224 | } | 258 | } |
225 | 259 | ||
226 | void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val) | 260 | void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val) |
227 | { | 261 | { |
228 | uint32_t u = val; | 262 | uint32_t u = val; |
229 | if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 263 | size_t sz = sizeof(u); |
264 | error ret = g_hwdev->write(addr, &u, sz, true); | ||
265 | if(ret != error::SUCCESS || sz != sizeof(u)) | ||
230 | luaL_error(state, "fail to write32 @ %p", addr); | 266 | luaL_error(state, "fail to write32 @ %p", addr); |
267 | if(g_print_mem_rw) | ||
268 | printf("[write32 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u); | ||
231 | } | 269 | } |
232 | 270 | ||
233 | int my_lua_readn(lua_State *state) | 271 | int my_lua_readn(lua_State *state) |
@@ -256,7 +294,7 @@ int my_lua_call(lua_State *state) | |||
256 | if(n != 1) | 294 | if(n != 1) |
257 | luaL_error(state, "call takes target address argument"); | 295 | luaL_error(state, "call takes target address argument"); |
258 | 296 | ||
259 | hwstub_call(g_hwdev, luaL_checkunsigned(state, 1)); | 297 | g_hwdev->exec(luaL_checkunsigned(state, 1), HWSTUB_EXEC_CALL); |
260 | return 0; | 298 | return 0; |
261 | } | 299 | } |
262 | 300 | ||
@@ -266,7 +304,7 @@ int my_lua_jump(lua_State *state) | |||
266 | if(n != 1) | 304 | if(n != 1) |
267 | luaL_error(state, "jump takes target address argument"); | 305 | luaL_error(state, "jump takes target address argument"); |
268 | 306 | ||
269 | hwstub_jump(g_hwdev, luaL_checkunsigned(state, 1)); | 307 | g_hwdev->exec(luaL_checkunsigned(state, 1), HWSTUB_EXEC_JUMP); |
270 | return 0; | 308 | return 0; |
271 | } | 309 | } |
272 | 310 | ||
@@ -276,6 +314,54 @@ int my_lua_printlog(lua_State *state) | |||
276 | return 0; | 314 | return 0; |
277 | } | 315 | } |
278 | 316 | ||
317 | std::string get_dev_name(std::shared_ptr<device> dev) | ||
318 | { | ||
319 | std::ostringstream name; | ||
320 | usb::device *udev = dynamic_cast<usb::device*>(dev.get()); | ||
321 | if(udev) | ||
322 | { | ||
323 | name << "USB Bus " << (unsigned)udev->get_bus_number() << | ||
324 | " Device " << std::setw(2) << std::hex << (unsigned)udev->get_address() << ": "; | ||
325 | } | ||
326 | // try to open device | ||
327 | std::shared_ptr<handle> h; | ||
328 | error ret = dev->open(h); | ||
329 | if(ret != error::SUCCESS) | ||
330 | { | ||
331 | name << "<cannot open dev>"; | ||
332 | return name.str(); | ||
333 | } | ||
334 | // get target information | ||
335 | hwstub_target_desc_t desc; | ||
336 | ret = h->get_target_desc(desc); | ||
337 | if(ret !=error::SUCCESS) | ||
338 | { | ||
339 | name << "<cannot get name: " << error_string(ret) << ">"; | ||
340 | return name.str(); | ||
341 | } | ||
342 | name << desc.bName; | ||
343 | return name.str(); | ||
344 | } | ||
345 | |||
346 | int my_lua_get_dev_list(lua_State *state) | ||
347 | { | ||
348 | error ret = g_hwctx->get_device_list(g_devlist); | ||
349 | if(ret != error::SUCCESS) | ||
350 | { | ||
351 | printf("Cannot device list\n"); | ||
352 | return -1; | ||
353 | } | ||
354 | |||
355 | printf("=== Available device list ===\n"); | ||
356 | for(size_t i = 0; i < g_devlist.size(); i++) | ||
357 | { | ||
358 | std::string name = get_dev_name(g_devlist[i]); | ||
359 | printf("%zu: %s%s\n", i, name.c_str(), | ||
360 | g_devlist[i] == g_hwdev->get_device() ? " <--" : ""); | ||
361 | } | ||
362 | return 0; | ||
363 | } | ||
364 | |||
279 | int my_lua_quit(lua_State *state) | 365 | int my_lua_quit(lua_State *state) |
280 | { | 366 | { |
281 | g_exit = true; | 367 | g_exit = true; |
@@ -292,6 +378,256 @@ int my_lua_udelay(lua_State *state) | |||
292 | return 0; | 378 | return 0; |
293 | } | 379 | } |
294 | 380 | ||
381 | int my_lua_mdelay(lua_State *state) | ||
382 | { | ||
383 | int n = lua_gettop(state); | ||
384 | if(n != 1) | ||
385 | luaL_error(state, "mdelay takes one argument"); | ||
386 | long usec = lua_tointeger(state, -1); | ||
387 | usleep(usec * 1000); | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | int fetch_dev_info() | ||
392 | { | ||
393 | // get memory layout information | ||
394 | error ret = g_hwdev->get_layout_desc(g_hwdev_layout); | ||
395 | if(ret != error::SUCCESS) | ||
396 | { | ||
397 | printf("Cannot get layout descriptor: %s\n", error_string(ret).c_str()); | ||
398 | goto Lerr; | ||
399 | } | ||
400 | // get hwstub information | ||
401 | ret = g_hwdev->get_version_desc(g_hwdev_ver); | ||
402 | if(ret != error::SUCCESS) | ||
403 | { | ||
404 | printf("Cannot get version descriptor: %s\n", error_string(ret).c_str()); | ||
405 | goto Lerr; | ||
406 | } | ||
407 | // get target | ||
408 | ret = g_hwdev->get_target_desc(g_hwdev_target); | ||
409 | if(ret != error::SUCCESS) | ||
410 | { | ||
411 | printf("Cannot get target descriptor: %s\n", error_string(ret).c_str()); | ||
412 | goto Lerr; | ||
413 | } | ||
414 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
415 | ret = g_hwdev->get_stmp_desc(g_hwdev_stmp); | ||
416 | // get PP specific information | ||
417 | else if(g_hwdev_target.dID == HWSTUB_TARGET_PP) | ||
418 | ret = g_hwdev->get_pp_desc(g_hwdev_pp); | ||
419 | // get JZ specific information | ||
420 | else if(g_hwdev_target.dID == HWSTUB_TARGET_JZ) | ||
421 | ret = g_hwdev->get_jz_desc(g_hwdev_jz); | ||
422 | if(ret != error::SUCCESS) | ||
423 | { | ||
424 | printf("Cannot get soc specific descriptor: %s\n", error_string(ret).c_str()); | ||
425 | goto Lerr; | ||
426 | } | ||
427 | return 0; | ||
428 | Lerr: | ||
429 | return -1; | ||
430 | } | ||
431 | |||
432 | int update_dev_lua_state(lua_State *state) | ||
433 | { | ||
434 | // fetch info before starting to mess with the lua state | ||
435 | int ret = fetch_dev_info(); | ||
436 | if(ret < 0) | ||
437 | return ret; | ||
438 | // hwstub | ||
439 | lua_getglobal(state, "hwstub"); | ||
440 | // hwstub.dev | ||
441 | lua_getfield(state, -1, "dev"); | ||
442 | |||
443 | // hwstub.dev.version | ||
444 | lua_getfield(state, -1, "version"); | ||
445 | |||
446 | // hwstub.dev.version.major = g_hwdev_ver.bMajor | ||
447 | lua_pushstring(state, "major"); | ||
448 | lua_pushinteger(state, g_hwdev_ver.bMajor); | ||
449 | lua_settable(state, -3); | ||
450 | |||
451 | // hwstub.dev.version.minor = g_hwdev_ver.bMinor | ||
452 | lua_pushstring(state, "minor"); | ||
453 | lua_pushinteger(state, g_hwdev_ver.bMinor); | ||
454 | lua_settable(state, -3); | ||
455 | lua_pop(state, 1); | ||
456 | |||
457 | // hwstub.dev.layout | ||
458 | lua_getfield(state, -1, "layout"); | ||
459 | |||
460 | // hwstub.dev.layout.code | ||
461 | lua_getfield(state, -1, "code"); | ||
462 | |||
463 | // hwstub.dev.layout.code.start = g_hwdev_layout.dCodeStart | ||
464 | lua_pushstring(state, "start"); | ||
465 | lua_pushinteger(state, g_hwdev_layout.dCodeStart); | ||
466 | lua_settable(state, -3); | ||
467 | |||
468 | // hwstub.dev.layout.code.size = g_hwdev_layout.dCodeSize | ||
469 | lua_pushstring(state, "size"); | ||
470 | lua_pushinteger(state, g_hwdev_layout.dCodeSize); | ||
471 | lua_settable(state, -3); | ||
472 | |||
473 | // hwstub.dev.layout | ||
474 | lua_pop(state, 1); | ||
475 | |||
476 | // hwstub.dev.layout.stack | ||
477 | lua_getfield(state, -1, "stack"); | ||
478 | |||
479 | // hwstub.dev.layout.stack.start = g_hwdev_layout.dStackStart | ||
480 | lua_pushstring(state, "start"); | ||
481 | lua_pushinteger(state, g_hwdev_layout.dStackStart); | ||
482 | lua_settable(state, -3); | ||
483 | |||
484 | // hwstub.dev.layout.stack.size = g_hwdev_layout.dStackSize | ||
485 | lua_pushstring(state, "size"); | ||
486 | lua_pushinteger(state, g_hwdev_layout.dStackSize); | ||
487 | lua_settable(state, -3); | ||
488 | |||
489 | // hwstub.dev.layout | ||
490 | lua_pop(state, 1); | ||
491 | |||
492 | // hwstub.dev.layout.buffer | ||
493 | lua_getfield(state, -1, "buffer"); | ||
494 | |||
495 | // hwstub.dev.layout.buffer.start = g_hwdev_layout.dBufferStart | ||
496 | lua_pushstring(state, "start"); | ||
497 | lua_pushinteger(state, g_hwdev_layout.dBufferStart); | ||
498 | lua_settable(state, -3); | ||
499 | |||
500 | // hwstub.dev.layout.buffer.size = g_hwdev_layout.dBufferSize | ||
501 | lua_pushstring(state, "size"); | ||
502 | lua_pushinteger(state, g_hwdev_layout.dBufferSize); | ||
503 | lua_settable(state, -3); | ||
504 | |||
505 | // hwstub.dev | ||
506 | lua_pop(state, 2); | ||
507 | |||
508 | // hwstub.dev.target | ||
509 | lua_getfield(state, -1, "target"); | ||
510 | |||
511 | // hwstub.dev.target.id = g_hwdev_target.dID | ||
512 | lua_pushstring(state, "id"); | ||
513 | lua_pushinteger(state, g_hwdev_target.dID); | ||
514 | lua_settable(state, -3); | ||
515 | |||
516 | // hwstub.dev.target.name = g_hwdev_target.bName | ||
517 | lua_pushstring(state, "name"); | ||
518 | lua_pushstring(state, g_hwdev_target.bName); | ||
519 | lua_settable(state, -3); | ||
520 | |||
521 | // hwstub.dev | ||
522 | lua_pop(state, 1); | ||
523 | |||
524 | // get STMP specific information | ||
525 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
526 | { | ||
527 | // hwstub.dev.stmp | ||
528 | lua_getfield(state, -1, "stmp"); | ||
529 | |||
530 | // hwstub.dev.stmp.chipid = g_hwdev_stmp.wChipID | ||
531 | lua_pushstring(state, "chipid"); | ||
532 | lua_pushinteger(state, g_hwdev_stmp.wChipID); | ||
533 | lua_settable(state, -3); | ||
534 | |||
535 | // hwstub.dev.stmp.rev = g_hwdev_stmp.bRevision | ||
536 | lua_pushstring(state, "rev"); | ||
537 | lua_pushinteger(state, g_hwdev_stmp.bRevision); | ||
538 | lua_settable(state, -3); | ||
539 | |||
540 | // hwstub.dev.stmp.package = g_hwdev_stmp.bPackage | ||
541 | lua_pushstring(state, "package"); | ||
542 | lua_pushinteger(state, g_hwdev_stmp.bPackage); | ||
543 | lua_settable(state, -3); | ||
544 | |||
545 | // hwstub.dev | ||
546 | lua_pop(state, 1); | ||
547 | } | ||
548 | // get PP specific information | ||
549 | else if(g_hwdev_target.dID == HWSTUB_TARGET_PP) | ||
550 | { | ||
551 | // hwstub.dev.pp | ||
552 | lua_getfield(state, -1, "pp"); | ||
553 | |||
554 | // hwstub.dev.pp.chipid = g_hwdev_pp.wChipID | ||
555 | lua_pushstring(state, "chipid"); | ||
556 | lua_pushinteger(state, g_hwdev_pp.wChipID); | ||
557 | lua_settable(state, -3); | ||
558 | |||
559 | // hwstub.dev.pp.rev = g_hwdev_pp.bRevision | ||
560 | lua_pushstring(state, "rev"); | ||
561 | lua_pushlstring(state, (const char *)g_hwdev_pp.bRevision, 2); | ||
562 | lua_settable(state, -3); | ||
563 | |||
564 | // hwstub.dev | ||
565 | lua_pop(state, 1); | ||
566 | } | ||
567 | // get JZ specific information | ||
568 | else if(g_hwdev_target.dID == HWSTUB_TARGET_JZ) | ||
569 | { | ||
570 | // hwstub.dev.jz | ||
571 | lua_getfield(state, -1, "jz"); | ||
572 | |||
573 | // hwstub.dev.jz.chipid = g_hwdev_jz.wChipID | ||
574 | lua_pushstring(state, "chipid"); | ||
575 | lua_pushinteger(state, g_hwdev_jz.wChipID); | ||
576 | lua_settable(state, -3); | ||
577 | |||
578 | // hwstub.dev.jz.rev = g_hwdev_jz.bRevision | ||
579 | lua_pushstring(state, "rev"); | ||
580 | lua_pushinteger(state, g_hwdev_jz.bRevision); | ||
581 | lua_settable(state, -3); | ||
582 | |||
583 | // hwstub.dev | ||
584 | lua_pop(state, 1); | ||
585 | } | ||
586 | // pop all globals (hwstub.dev) | ||
587 | lua_pop(state, 2); | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | int my_lua_dev_open(lua_State *state) | ||
592 | { | ||
593 | int n = lua_gettop(state); | ||
594 | if(n != 1) | ||
595 | luaL_error(state, "open_dev takes one argument"); | ||
596 | int32_t id = lua_tointeger(state, -1); | ||
597 | if(id < 0 || (size_t)id >= g_devlist.size()) | ||
598 | luaL_error(state, "invalid device id"); | ||
599 | std::shared_ptr<handle> h; | ||
600 | error ret = g_devlist[id]->open(h); | ||
601 | if(ret != error::SUCCESS) | ||
602 | luaL_error(state, "Cannot open device: %s. The current device was NOT changed.\n", error_string(ret).c_str()); | ||
603 | else | ||
604 | g_hwdev = h; | ||
605 | if(update_dev_lua_state(state) < 0) | ||
606 | return -1; | ||
607 | if(luaL_dostring(state, "init()")) | ||
608 | luaL_error(state, "error in init: %s\n", lua_tostring(state, -1)); | ||
609 | lua_pop(state, lua_gettop(state)); | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | int my_lua_dev_close(lua_State *state) | ||
614 | { | ||
615 | int n = lua_gettop(state); | ||
616 | if(n != 0) | ||
617 | luaL_error(state, "close_dev takes no argument"); | ||
618 | std::shared_ptr<device> dev; | ||
619 | error ret = g_hwctx->get_dummy_device(dev); | ||
620 | if(ret != error::SUCCESS) | ||
621 | luaL_error(state, "Cannot get dummy device: %s. The current device was NOT closed.\n", error_string(ret).c_str()); | ||
622 | std::shared_ptr<handle> h; | ||
623 | ret = dev->open(h); | ||
624 | if(ret != error::SUCCESS) | ||
625 | luaL_error(state, "Cannot open dummy device: %s. The current device was NOT changed.\n", error_string(ret).c_str()); | ||
626 | else | ||
627 | g_hwdev = h; | ||
628 | return update_dev_lua_state(state); | ||
629 | } | ||
630 | |||
295 | bool my_lua_import_hwstub() | 631 | bool my_lua_import_hwstub() |
296 | { | 632 | { |
297 | int oldtop = lua_gettop(g_lua); | 633 | int oldtop = lua_gettop(g_lua); |
@@ -349,28 +685,30 @@ bool my_lua_import_hwstub() | |||
349 | lua_setfield(g_lua, -2, "RK27"); | 685 | lua_setfield(g_lua, -2, "RK27"); |
350 | lua_pushinteger(g_lua, HWSTUB_TARGET_ATJ); | 686 | lua_pushinteger(g_lua, HWSTUB_TARGET_ATJ); |
351 | lua_setfield(g_lua, -2, "ATJ"); | 687 | lua_setfield(g_lua, -2, "ATJ"); |
688 | lua_pushinteger(g_lua, HWSTUB_TARGET_JZ); | ||
689 | lua_setfield(g_lua, -2, "JZ"); | ||
352 | lua_setfield(g_lua, -2, "target"); | 690 | lua_setfield(g_lua, -2, "target"); |
353 | 691 | ||
354 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) | 692 | lua_newtable(g_lua); // stmp |
355 | { | 693 | lua_pushinteger(g_lua, 0); |
356 | lua_newtable(g_lua); // stmp | 694 | lua_setfield(g_lua, -2, "chipid"); |
357 | lua_pushinteger(g_lua, g_hwdev_stmp.wChipID); | 695 | lua_pushinteger(g_lua, 0); |
358 | lua_setfield(g_lua, -2, "chipid"); | 696 | lua_setfield(g_lua, -2, "rev"); |
359 | lua_pushinteger(g_lua, g_hwdev_stmp.bRevision); | 697 | lua_pushinteger(g_lua, 0); |
360 | lua_setfield(g_lua, -2, "rev"); | 698 | lua_setfield(g_lua, -2, "package"); |
361 | lua_pushinteger(g_lua, g_hwdev_stmp.bPackage); | 699 | lua_setfield(g_lua, -2, "stmp"); |
362 | lua_setfield(g_lua, -2, "package"); | 700 | |
363 | lua_setfield(g_lua, -2, "stmp"); | 701 | lua_newtable(g_lua); // pp |
364 | } | 702 | lua_pushinteger(g_lua, 0); |
365 | else if(g_hwdev_target.dID == HWSTUB_TARGET_PP) | 703 | lua_setfield(g_lua, -2, "chipid"); |
366 | { | 704 | lua_pushstring(g_lua, ""); |
367 | lua_newtable(g_lua); // pp | 705 | lua_setfield(g_lua, -2, "rev"); |
368 | lua_pushinteger(g_lua, g_hwdev_pp.wChipID); | 706 | lua_setfield(g_lua, -2, "pp"); |
369 | lua_setfield(g_lua, -2, "chipid"); | 707 | |
370 | lua_pushlstring(g_lua, (const char *)g_hwdev_pp.bRevision, 2); | 708 | lua_newtable(g_lua); // jz |
371 | lua_setfield(g_lua, -2, "rev"); | 709 | lua_pushinteger(g_lua, 0); |
372 | lua_setfield(g_lua, -2, "pp"); | 710 | lua_setfield(g_lua, -2, "chipid"); |
373 | } | 711 | lua_setfield(g_lua, -2, "jz"); |
374 | 712 | ||
375 | lua_pushlightuserdata(g_lua, (void *)&hw_read8); | 713 | lua_pushlightuserdata(g_lua, (void *)&hw_read8); |
376 | lua_pushcclosure(g_lua, my_lua_readn, 1); | 714 | lua_pushcclosure(g_lua, my_lua_readn, 1); |
@@ -414,7 +752,7 @@ bool my_lua_import_hwstub() | |||
414 | 752 | ||
415 | lua_newtable(g_lua); // help | 753 | lua_newtable(g_lua); // help |
416 | lua_pushinteger(g_lua, 1); | 754 | lua_pushinteger(g_lua, 1); |
417 | lua_pushstring(g_lua, "This is the help for hwstub_tool. This tools uses Lua to interpret commands."); | 755 | lua_pushstring(g_lua, "This is the help for tool. This tools uses Lua to interpret commands."); |
418 | lua_settable(g_lua, -3); | 756 | lua_settable(g_lua, -3); |
419 | lua_pushinteger(g_lua, 2); | 757 | lua_pushinteger(g_lua, 2); |
420 | lua_pushstring(g_lua, "You can get help by running help(). Help is organised in topics and subtopics and so on."); | 758 | lua_pushstring(g_lua, "You can get help by running help(). Help is organised in topics and subtopics and so on."); |
@@ -430,6 +768,18 @@ bool my_lua_import_hwstub() | |||
430 | lua_pushcclosure(g_lua, my_lua_udelay, 0); | 768 | lua_pushcclosure(g_lua, my_lua_udelay, 0); |
431 | lua_setfield(g_lua, -2, "udelay"); | 769 | lua_setfield(g_lua, -2, "udelay"); |
432 | 770 | ||
771 | lua_pushcclosure(g_lua, my_lua_mdelay, 0); | ||
772 | lua_setfield(g_lua, -2, "mdelay"); | ||
773 | |||
774 | lua_pushcfunction(g_lua, my_lua_get_dev_list); | ||
775 | lua_setfield(g_lua, -2, "get_dev_list"); | ||
776 | |||
777 | lua_pushcclosure(g_lua, my_lua_dev_open, 0); | ||
778 | lua_setfield(g_lua, -2, "open_dev"); | ||
779 | |||
780 | lua_pushcclosure(g_lua, my_lua_dev_close, 0); | ||
781 | lua_setfield(g_lua, -2, "close_dev"); | ||
782 | |||
433 | lua_setglobal(g_lua, "hwstub"); | 783 | lua_setglobal(g_lua, "hwstub"); |
434 | 784 | ||
435 | lua_pushcfunction(g_lua, my_lua_help); | 785 | lua_pushcfunction(g_lua, my_lua_help); |
@@ -441,6 +791,8 @@ bool my_lua_import_hwstub() | |||
441 | lua_pushcfunction(g_lua, my_lua_quit); | 791 | lua_pushcfunction(g_lua, my_lua_quit); |
442 | lua_setglobal(g_lua, "quit"); | 792 | lua_setglobal(g_lua, "quit"); |
443 | 793 | ||
794 | update_dev_lua_state(g_lua); | ||
795 | |||
444 | if(lua_gettop(g_lua) != oldtop) | 796 | if(lua_gettop(g_lua) != oldtop) |
445 | { | 797 | { |
446 | printf("internal error: unbalanced my_lua_import_soc\n"); | 798 | printf("internal error: unbalanced my_lua_import_soc\n"); |
@@ -449,13 +801,36 @@ bool my_lua_import_hwstub() | |||
449 | return true; | 801 | return true; |
450 | } | 802 | } |
451 | 803 | ||
804 | soc_word_t hw_readn(lua_State *state, unsigned width, soc_word_t addr) | ||
805 | { | ||
806 | switch(width) | ||
807 | { | ||
808 | case 8: return hw_read8(state, addr); break; | ||
809 | case 16: return hw_read16(state, addr); break; | ||
810 | case 32: return hw_read32(state, addr); break; | ||
811 | default: luaL_error(state, "read() has invalid width"); return 0xdeadbeef; | ||
812 | } | ||
813 | } | ||
814 | |||
815 | void hw_writen(lua_State *state, unsigned width, soc_word_t addr, soc_word_t val) | ||
816 | { | ||
817 | switch(width) | ||
818 | { | ||
819 | case 8: hw_write8(state, addr, val); break; | ||
820 | case 16: hw_write16(state, addr, val); break; | ||
821 | case 32: hw_write32(state, addr, val); break; | ||
822 | default: luaL_error(state, "write() has invalid width"); | ||
823 | } | ||
824 | } | ||
825 | |||
452 | int my_lua_read_reg(lua_State *state) | 826 | int my_lua_read_reg(lua_State *state) |
453 | { | 827 | { |
454 | int n = lua_gettop(state); | 828 | int n = lua_gettop(state); |
455 | if(n != 0) | 829 | if(n != 0) |
456 | luaL_error(state, "read() takes no argument"); | 830 | luaL_error(state, "read() takes no argument"); |
457 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 831 | unsigned width = lua_tounsigned(state, lua_upvalueindex(1)); |
458 | lua_pushunsigned(state, hw_read32(state, addr)); | 832 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2)); |
833 | lua_pushunsigned(state, hw_readn(state, width, addr)); | ||
459 | return 1; | 834 | return 1; |
460 | } | 835 | } |
461 | 836 | ||
@@ -465,8 +840,9 @@ int my_lua_write_reg(lua_State *state) | |||
465 | if(n != 1) | 840 | if(n != 1) |
466 | luaL_error(state, "write() takes one argument"); | 841 | luaL_error(state, "write() takes one argument"); |
467 | soc_word_t val = luaL_checkunsigned(state, 1); | 842 | soc_word_t val = luaL_checkunsigned(state, 1); |
468 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 843 | unsigned width = lua_tounsigned(state, lua_upvalueindex(1)); |
469 | hw_write32(state, addr, val); | 844 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2)); |
845 | hw_writen(state, width, addr, val); | ||
470 | return 0; | 846 | return 0; |
471 | } | 847 | } |
472 | 848 | ||
@@ -475,10 +851,11 @@ int my_lua_read_field(lua_State *state) | |||
475 | int n = lua_gettop(state); | 851 | int n = lua_gettop(state); |
476 | if(n != 0) | 852 | if(n != 0) |
477 | luaL_error(state, "read() takes no argument"); | 853 | luaL_error(state, "read() takes no argument"); |
478 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 854 | unsigned width = lua_tounsigned(state, lua_upvalueindex(1)); |
479 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2)); | 855 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2)); |
480 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3)); | 856 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(3)); |
481 | lua_pushunsigned(state, (hw_read32(state, addr) >> shift) & mask); | 857 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(4)); |
858 | lua_pushunsigned(state, (hw_readn(state, width, addr) >> shift) & mask); | ||
482 | return 1; | 859 | return 1; |
483 | } | 860 | } |
484 | 861 | ||
@@ -487,17 +864,18 @@ int my_lua_write_field(lua_State *state) | |||
487 | int n = lua_gettop(state); | 864 | int n = lua_gettop(state); |
488 | if(n != 0 && n!= 1) | 865 | if(n != 0 && n!= 1) |
489 | luaL_error(state, "write() takes one or no argument"); | 866 | luaL_error(state, "write() takes one or no argument"); |
490 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 867 | unsigned width = lua_tounsigned(state, lua_upvalueindex(1)); |
491 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2)); | 868 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2)); |
492 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3)); | 869 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(3)); |
493 | char op = lua_tounsigned(state, lua_upvalueindex(5)); | 870 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(4)); |
871 | char op = lua_tounsigned(state, lua_upvalueindex(6)); | ||
494 | 872 | ||
495 | soc_word_t value = mask; | 873 | soc_word_t value = mask; |
496 | if(n == 1) | 874 | if(n == 1) |
497 | { | 875 | { |
498 | if(!lua_isnumber(state, 1) && lua_isstring(state, 1)) | 876 | if(!lua_isnumber(state, 1) && lua_isstring(state, 1)) |
499 | { | 877 | { |
500 | lua_pushvalue(state, lua_upvalueindex(4)); | 878 | lua_pushvalue(state, lua_upvalueindex(5)); |
501 | lua_pushvalue(state, 1); | 879 | lua_pushvalue(state, 1); |
502 | lua_gettable(state, -2); | 880 | lua_gettable(state, -2); |
503 | if(lua_isnil(state, -1)) | 881 | if(lua_isnil(state, -1)) |
@@ -510,7 +888,7 @@ int my_lua_write_field(lua_State *state) | |||
510 | value &= mask; | 888 | value &= mask; |
511 | } | 889 | } |
512 | 890 | ||
513 | soc_word_t old_value = hw_read32(state, addr); | 891 | soc_word_t old_value = hw_readn(state, width, addr); |
514 | if(op == 'w') | 892 | if(op == 'w') |
515 | value = value << shift | (old_value & ~(mask << shift)); | 893 | value = value << shift | (old_value & ~(mask << shift)); |
516 | else if(op == 's') | 894 | else if(op == 's') |
@@ -522,7 +900,7 @@ int my_lua_write_field(lua_State *state) | |||
522 | else | 900 | else |
523 | luaL_error(state, "write_field() internal error"); | 901 | luaL_error(state, "write_field() internal error"); |
524 | 902 | ||
525 | hw_write32(state, addr, value); | 903 | hw_writen(state, width, addr, value); |
526 | return 0; | 904 | return 0; |
527 | } | 905 | } |
528 | 906 | ||
@@ -531,8 +909,9 @@ int my_lua_sct_reg(lua_State *state) | |||
531 | int n = lua_gettop(state); | 909 | int n = lua_gettop(state); |
532 | if(n != 1) | 910 | if(n != 1) |
533 | luaL_error(state, "sct() takes one argument"); | 911 | luaL_error(state, "sct() takes one argument"); |
534 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 912 | unsigned width = lua_tounsigned(state, lua_upvalueindex(1)); |
535 | char op = lua_tounsigned(state, lua_upvalueindex(2)); | 913 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2)); |
914 | char op = lua_tounsigned(state, lua_upvalueindex(3)); | ||
536 | 915 | ||
537 | soc_word_t mask = luaL_checkunsigned(state, 1); | 916 | soc_word_t mask = luaL_checkunsigned(state, 1); |
538 | soc_word_t value = hw_read32(state, addr); | 917 | soc_word_t value = hw_read32(state, addr); |
@@ -545,7 +924,7 @@ int my_lua_sct_reg(lua_State *state) | |||
545 | else | 924 | else |
546 | luaL_error(state, "sct() internal error"); | 925 | luaL_error(state, "sct() internal error"); |
547 | 926 | ||
548 | hw_write32(state, addr, value); | 927 | hw_writen(state, width, addr, value); |
549 | return 0; | 928 | return 0; |
550 | } | 929 | } |
551 | 930 | ||
@@ -590,11 +969,12 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field) | |||
590 | /* lua stack: <field table> ... */ | 969 | /* lua stack: <field table> ... */ |
591 | 970 | ||
592 | /** create read routine */ | 971 | /** create read routine */ |
972 | lua_pushunsigned(g_lua, field.reg().get()->width); | ||
593 | lua_pushunsigned(g_lua, addr); | 973 | lua_pushunsigned(g_lua, addr); |
594 | lua_pushunsigned(g_lua, f->pos); | 974 | lua_pushunsigned(g_lua, f->pos); |
595 | lua_pushunsigned(g_lua, local_bitmask); | 975 | lua_pushunsigned(g_lua, local_bitmask); |
596 | /* lua stack: <local_bm> <pos> <addr> <field table> ... */ | 976 | /* lua stack: <local_bm> <pos> <addr> <width> <field table> ... */ |
597 | lua_pushcclosure(g_lua, my_lua_read_field, 3); | 977 | lua_pushcclosure(g_lua, my_lua_read_field, 4); |
598 | /* lua stack: <my_lua_read_field> <field table> ... */ | 978 | /* lua stack: <my_lua_read_field> <field table> ... */ |
599 | lua_setfield(g_lua, -2, "read"); | 979 | lua_setfield(g_lua, -2, "read"); |
600 | /* lua stack: <field table> ... */ | 980 | /* lua stack: <field table> ... */ |
@@ -604,15 +984,16 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field) | |||
604 | static const char arg[] = {'w', 's', 'c', 't'}; | 984 | static const char arg[] = {'w', 's', 'c', 't'}; |
605 | for(int i = 0; i < 4; i++) | 985 | for(int i = 0; i < 4; i++) |
606 | { | 986 | { |
987 | lua_pushunsigned(g_lua, field.reg().get()->width); | ||
607 | lua_pushunsigned(g_lua, addr); | 988 | lua_pushunsigned(g_lua, addr); |
608 | lua_pushunsigned(g_lua, f->pos); | 989 | lua_pushunsigned(g_lua, f->pos); |
609 | lua_pushunsigned(g_lua, local_bitmask); | 990 | lua_pushunsigned(g_lua, local_bitmask); |
610 | /* lua stack: <local_bm> <pos> <addr> <field table> ... */ | 991 | /* lua stack: <local_bm> <pos> <addr> <width> <field table> ... */ |
611 | lua_pushvalue(g_lua, -4); | 992 | lua_pushvalue(g_lua, -5); |
612 | /* lua stack: <field table> <local_bm> <pos> <addr> <field table> ... */ | 993 | /* lua stack: <field table> <local_bm> <pos> <addr> <width> <field table> ... */ |
613 | lua_pushunsigned(g_lua, arg[i]); | 994 | lua_pushunsigned(g_lua, arg[i]); |
614 | /* lua stack: <'wsct'> <field table> <local_bm> <pos> <addr> <field table> ... */ | 995 | /* lua stack: <'wsct'> <field table> <local_bm> <pos> <addr> <width> <field table> ... */ |
615 | lua_pushcclosure(g_lua, my_lua_write_field, 5); | 996 | lua_pushcclosure(g_lua, my_lua_write_field, 6); |
616 | /* lua stack: <my_lua_write_field> <field table> ... */ | 997 | /* lua stack: <my_lua_write_field> <field table> ... */ |
617 | lua_setfield(g_lua, -2, name[i]); | 998 | lua_setfield(g_lua, -2, name[i]); |
618 | /* lua stack: <field table> ... */ | 999 | /* lua stack: <field table> ... */ |
@@ -633,22 +1014,25 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field) | |||
633 | } | 1014 | } |
634 | 1015 | ||
635 | /* lua stack on entry/exit: <inst table> */ | 1016 | /* lua stack on entry/exit: <inst table> */ |
636 | void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg) | 1017 | void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg, |
1018 | bool in_variant = false) | ||
637 | { | 1019 | { |
638 | if(!reg.valid()) | 1020 | if(!reg.valid()) |
639 | return; | 1021 | return; |
640 | /** create read/write routine */ | 1022 | /** create read/write routine */ |
1023 | lua_pushunsigned(g_lua, reg.get()->width); | ||
641 | lua_pushunsigned(g_lua, addr); | 1024 | lua_pushunsigned(g_lua, addr); |
642 | /* lua stack: <addr> <inst table> */ | 1025 | /* lua stack: <addr> <width> <inst table> */ |
643 | lua_pushcclosure(g_lua, my_lua_read_reg, 1); | 1026 | lua_pushcclosure(g_lua, my_lua_read_reg, 2); |
644 | /* lua stack: <my_lua_read_reg> <inst table> */ | 1027 | /* lua stack: <my_lua_read_reg> <inst table> */ |
645 | lua_setfield(g_lua, -2, "read"); | 1028 | lua_setfield(g_lua, -2, "read"); |
646 | /* lua stack: <inst table> */ | 1029 | /* lua stack: <inst table> */ |
647 | 1030 | ||
1031 | lua_pushunsigned(g_lua, reg.get()->width); | ||
648 | lua_pushunsigned(g_lua, addr); | 1032 | lua_pushunsigned(g_lua, addr); |
649 | /* lua stack: <addr> <inst table> */ | 1033 | /* lua stack: <addr> <width> <inst table> */ |
650 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); | 1034 | lua_pushcclosure(g_lua, my_lua_write_reg, 2); |
651 | /* lua stack: <my_lua_read_reg> <inst table> */ | 1035 | /* lua stack: <my_lua_write_reg> <inst table> */ |
652 | lua_setfield(g_lua, -2, "write"); | 1036 | lua_setfield(g_lua, -2, "write"); |
653 | /* lua stack: <inst table> */ | 1037 | /* lua stack: <inst table> */ |
654 | 1038 | ||
@@ -657,16 +1041,36 @@ void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg) | |||
657 | static const char arg[] = {'s', 'c', 't'}; | 1041 | static const char arg[] = {'s', 'c', 't'}; |
658 | for(int i = 0; i < 3; i++) | 1042 | for(int i = 0; i < 3; i++) |
659 | { | 1043 | { |
1044 | lua_pushunsigned(g_lua, reg.get()->width); | ||
660 | lua_pushunsigned(g_lua, addr); | 1045 | lua_pushunsigned(g_lua, addr); |
661 | /* lua stack: <addr> <inst table> */ | 1046 | /* lua stack: <addr> <width> <inst table> */ |
662 | lua_pushunsigned(g_lua, arg[i]); | 1047 | lua_pushunsigned(g_lua, arg[i]); |
663 | /* lua stack: <'s'/'c'/'t'> <addr> <inst table> */ | 1048 | /* lua stack: <'s'/'c'/'t'> <addr> <width> <inst table> */ |
664 | lua_pushcclosure(g_lua, my_lua_sct_reg, 2); | 1049 | lua_pushcclosure(g_lua, my_lua_sct_reg, 3); |
665 | /* lua stack: <my_lua_sct_reg> <inst table> */ | 1050 | /* lua stack: <my_lua_sct_reg> <inst table> */ |
666 | lua_setfield(g_lua, -2, name[i]); | 1051 | lua_setfield(g_lua, -2, name[i]); |
667 | /* lua stack: <inst table> */ | 1052 | /* lua stack: <inst table> */ |
668 | } | 1053 | } |
669 | 1054 | ||
1055 | /** create variants */ | ||
1056 | if(!in_variant) | ||
1057 | { | ||
1058 | for(auto v : reg.variants()) | ||
1059 | { | ||
1060 | /** create a new table */ | ||
1061 | lua_newtable(g_lua); | ||
1062 | /* lua stack: <instance table> <parent table> */ | ||
1063 | /** create register */ | ||
1064 | my_lua_create_reg(addr + v.offset(), reg, true); | ||
1065 | /** register table */ | ||
1066 | /* lua stack: <instance table> <parent table> */ | ||
1067 | std::string varname = v.type(); | ||
1068 | for(size_t i = 0; i < varname.size(); i++) | ||
1069 | varname[i] = toupper(varname[i]); | ||
1070 | lua_setfield(g_lua, -2, varname.c_str()); | ||
1071 | } | ||
1072 | } | ||
1073 | |||
670 | /** create fields */ | 1074 | /** create fields */ |
671 | std::vector< soc_desc::field_ref_t > fields = reg.fields(); | 1075 | std::vector< soc_desc::field_ref_t > fields = reg.fields(); |
672 | for(size_t i = 0; i < fields.size(); i++) | 1076 | for(size_t i = 0; i < fields.size(); i++) |
@@ -810,38 +1214,88 @@ bool my_lua_import_soc(std::vector< soc_desc::soc_t >& socs) | |||
810 | 1214 | ||
811 | void usage(void) | 1215 | void usage(void) |
812 | { | 1216 | { |
813 | printf("hwstub_tool, compiled with hwstub protocol %d.%d\n", | 1217 | printf("shell, compiled with hwstub protocol %d.%d\n", |
814 | HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR); | 1218 | HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR); |
815 | printf("\n"); | 1219 | printf("\n"); |
816 | printf("usage: hwstub_tool [options] <soc desc files>\n"); | 1220 | printf("usage: shell [options] <soc desc files>\n"); |
817 | printf("options:\n"); | 1221 | printf("options:\n"); |
818 | printf(" --help/-? Display this help\n"); | 1222 | printf(" --help/-? Display this help\n"); |
819 | printf(" --quiet/-q Quiet non-command messages\n"); | 1223 | printf(" --quiet/-q Quiet non-command messages\n"); |
820 | printf(" -i <init> Set lua init file (default is init.lua)\n"); | 1224 | printf(" --verbose/-v Verbose output\n"); |
821 | printf(" -e <cmd> Execute <cmd> at startup\n"); | 1225 | printf(" -i <init> Set lua init file (default is init.lua)\n"); |
822 | printf(" -f <file> Execute <file> at startup\n"); | 1226 | printf(" -e <cmd> Execute <cmd> at startup\n"); |
1227 | printf(" -f <file> Execute <file> at startup\n"); | ||
1228 | printf(" --dev/-d <uri> Device URI\n"); | ||
1229 | printf(" --debug-rw Print read/write\n"); | ||
823 | printf("Relative order of -e and -f commands are preserved.\n"); | 1230 | printf("Relative order of -e and -f commands are preserved.\n"); |
824 | printf("They are executed after init file.\n"); | 1231 | printf("Unless specified, the shell will load soc desc in regtools/desc/\n"); |
1232 | //usage_uri(stdout); | ||
825 | exit(1); | 1233 | exit(1); |
826 | } | 1234 | } |
827 | 1235 | ||
828 | enum exec_type { exec_cmd, exec_file }; | 1236 | enum exec_type { exec_cmd, exec_file }; |
829 | 1237 | ||
1238 | void do_signal(int sig) | ||
1239 | { | ||
1240 | g_exit = true; | ||
1241 | } | ||
1242 | |||
1243 | void load_std_desc(std::vector< soc_desc::soc_t >& socs) | ||
1244 | { | ||
1245 | std::string path = "../../regtools/desc/"; | ||
1246 | DIR *dir = opendir(path.c_str()); | ||
1247 | if(dir == nullptr) | ||
1248 | return; | ||
1249 | struct dirent *entry; | ||
1250 | while((entry = readdir(dir)) != nullptr) | ||
1251 | { | ||
1252 | /* only match regs-*.xml files but not regs-*-v1.xml */ | ||
1253 | std::string file = entry->d_name; | ||
1254 | if(file.size() < 5 || file.substr(0, 5) != "regs-") | ||
1255 | continue; | ||
1256 | if(file.substr(file.size() - 4) != ".xml") | ||
1257 | continue; | ||
1258 | if(file.substr(file.size() - 7) == "-v1.xml") | ||
1259 | continue; | ||
1260 | /* prepend path */ | ||
1261 | file = path + "/" + file; | ||
1262 | socs.push_back(soc_desc::soc_t()); | ||
1263 | soc_desc::error_context_t ctx; | ||
1264 | if(!soc_desc::parse_xml(file, socs[socs.size() - 1], ctx)) | ||
1265 | { | ||
1266 | printf("Cannot load description file '%s'\n", file.c_str()); | ||
1267 | socs.pop_back(); | ||
1268 | } | ||
1269 | print_context(file, ctx); | ||
1270 | } | ||
1271 | closedir(dir); | ||
1272 | } | ||
1273 | |||
830 | int main(int argc, char **argv) | 1274 | int main(int argc, char **argv) |
831 | { | 1275 | { |
1276 | const char *dev_uri = hwstub::uri::default_uri().full_uri().c_str(); | ||
1277 | bool verbose = false; | ||
1278 | |||
832 | const char *lua_init = "init.lua"; | 1279 | const char *lua_init = "init.lua"; |
833 | std::vector< std::pair< exec_type, std::string > > startup_cmds; | 1280 | std::vector< std::pair< exec_type, std::string > > startup_cmds; |
834 | // parse command line | 1281 | // parse command line |
835 | while(1) | 1282 | while(1) |
836 | { | 1283 | { |
1284 | enum { OPT_DBG_RW = 256 }; | ||
837 | static struct option long_options[] = | 1285 | static struct option long_options[] = |
838 | { | 1286 | { |
839 | {"help", no_argument, 0, '?'}, | 1287 | {"help", no_argument, 0, '?'}, |
840 | {"quiet", no_argument, 0, 'q'}, | 1288 | {"quiet", no_argument, 0, 'q'}, |
1289 | {"init", required_argument, 0, 'i'}, | ||
1290 | {"startcmd", required_argument, 0, 'e'}, | ||
1291 | {"startfile", required_argument, 0, 'f'}, | ||
1292 | {"dev", required_argument, 0, 'd'}, | ||
1293 | {"verbose", no_argument, 0, 'v'}, | ||
1294 | {"debug-rw", no_argument, 0, OPT_DBG_RW}, | ||
841 | {0, 0, 0, 0} | 1295 | {0, 0, 0, 0} |
842 | }; | 1296 | }; |
843 | 1297 | ||
844 | int c = getopt_long(argc, argv, "?qi:e:f:", long_options, NULL); | 1298 | int c = getopt_long(argc, argv, "?qi:e:f:d:v", long_options, NULL); |
845 | if(c == -1) | 1299 | if(c == -1) |
846 | break; | 1300 | break; |
847 | switch(c) | 1301 | switch(c) |
@@ -863,6 +1317,15 @@ int main(int argc, char **argv) | |||
863 | case 'f': | 1317 | case 'f': |
864 | startup_cmds.push_back(std::make_pair(exec_file, std::string(optarg))); | 1318 | startup_cmds.push_back(std::make_pair(exec_file, std::string(optarg))); |
865 | break; | 1319 | break; |
1320 | case 'd': | ||
1321 | dev_uri = optarg; | ||
1322 | break; | ||
1323 | case 'v': | ||
1324 | verbose = true; | ||
1325 | break; | ||
1326 | case OPT_DBG_RW: | ||
1327 | g_print_mem_rw = true; | ||
1328 | break; | ||
866 | default: | 1329 | default: |
867 | abort(); | 1330 | abort(); |
868 | } | 1331 | } |
@@ -881,97 +1344,39 @@ int main(int argc, char **argv) | |||
881 | } | 1344 | } |
882 | print_context(argv[i], ctx); | 1345 | print_context(argv[i], ctx); |
883 | } | 1346 | } |
1347 | /* load standard desc files */ | ||
1348 | load_std_desc(socs); | ||
884 | 1349 | ||
885 | // create usb context | 1350 | /* create usb context */ |
886 | libusb_context *ctx; | 1351 | std::string errstr; |
887 | libusb_init(&ctx); | 1352 | g_hwctx = uri::create_context(uri::uri(dev_uri), &errstr); |
888 | libusb_set_debug(ctx, 3); | 1353 | if(!g_hwctx) |
889 | |||
890 | // look for device | ||
891 | if(!g_quiet) | ||
892 | printf("Looking for hwstub device ...\n"); | ||
893 | // open first device | ||
894 | libusb_device **list; | ||
895 | ssize_t cnt = hwstub_get_device_list(ctx, &list); | ||
896 | if(cnt <= 0) | ||
897 | { | 1354 | { |
898 | printf("No device found\n"); | 1355 | printf("Cannot create context: %s\n", errstr.c_str()); |
899 | return 1; | 1356 | return 1; |
900 | } | 1357 | } |
901 | libusb_device_handle *handle; | 1358 | if(verbose) |
902 | if(libusb_open(list[0], &handle) != 0) | 1359 | g_hwctx->set_debug(std::cout); |
1360 | std::vector<std::shared_ptr<device>> list; | ||
1361 | error ret = g_hwctx->get_device_list(list); | ||
1362 | if(ret != error::SUCCESS) | ||
903 | { | 1363 | { |
904 | printf("Cannot open device\n"); | 1364 | printf("Cannot get device list: %s\n", error_string(ret).c_str()); |
905 | return 1; | 1365 | return 1; |
906 | } | 1366 | } |
907 | libusb_free_device_list(list, 1); | 1367 | if(list.size() == 0) |
908 | |||
909 | // admin stuff | ||
910 | libusb_device *mydev = libusb_get_device(handle); | ||
911 | if(!g_quiet) | ||
912 | { | ||
913 | printf("device found at %d:%d\n", | ||
914 | libusb_get_bus_number(mydev), | ||
915 | libusb_get_device_address(mydev)); | ||
916 | } | ||
917 | g_hwdev = hwstub_open(handle); | ||
918 | if(g_hwdev == NULL) | ||
919 | { | 1368 | { |
920 | printf("Cannot open device!\n"); | 1369 | printf("No hwstub device detected!\n"); |
921 | return 1; | 1370 | return 1; |
922 | } | 1371 | } |
923 | 1372 | /* open first device */ | |
924 | // get hwstub information | 1373 | ret = list[0]->open(g_hwdev); |
925 | int ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver)); | 1374 | if(ret != error::SUCCESS) |
926 | if(ret != sizeof(g_hwdev_ver)) | ||
927 | { | ||
928 | printf("Cannot get version!\n"); | ||
929 | goto Lerr; | ||
930 | } | ||
931 | if(g_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || g_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) | ||
932 | { | ||
933 | printf("Warning: this tool is possibly incompatible with your device:\n"); | ||
934 | printf("Device version: %d.%d.%d\n", g_hwdev_ver.bMajor, g_hwdev_ver.bMinor, g_hwdev_ver.bRevision); | ||
935 | printf("Host version: %d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR); | ||
936 | } | ||
937 | |||
938 | // get memory layout information | ||
939 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout)); | ||
940 | if(ret != sizeof(g_hwdev_layout)) | ||
941 | { | ||
942 | printf("Cannot get layout: %d\n", ret); | ||
943 | goto Lerr; | ||
944 | } | ||
945 | |||
946 | // get target | ||
947 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_TARGET, &g_hwdev_target, sizeof(g_hwdev_target)); | ||
948 | if(ret != sizeof(g_hwdev_target)) | ||
949 | { | ||
950 | printf("Cannot get target: %d\n", ret); | ||
951 | goto Lerr; | ||
952 | } | ||
953 | |||
954 | // get STMP specific information | ||
955 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
956 | { | 1375 | { |
957 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp)); | 1376 | printf("Cannot open device: %s\n", error_string(ret).c_str()); |
958 | if(ret != sizeof(g_hwdev_stmp)) | 1377 | return 1; |
959 | { | ||
960 | printf("Cannot get stmp: %d\n", ret); | ||
961 | goto Lerr; | ||
962 | } | ||
963 | } | 1378 | } |
964 | 1379 | ||
965 | // get PP specific information | ||
966 | if(g_hwdev_target.dID == HWSTUB_TARGET_PP) | ||
967 | { | ||
968 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_PP, &g_hwdev_pp, sizeof(g_hwdev_pp)); | ||
969 | if(ret != sizeof(g_hwdev_pp)) | ||
970 | { | ||
971 | printf("Cannot get pp: %d\n", ret); | ||
972 | goto Lerr; | ||
973 | } | ||
974 | } | ||
975 | /** Init lua */ | 1380 | /** Init lua */ |
976 | 1381 | ||
977 | // create lua state | 1382 | // create lua state |
@@ -996,7 +1401,10 @@ int main(int argc, char **argv) | |||
996 | 1401 | ||
997 | /** start interactive mode */ | 1402 | /** start interactive mode */ |
998 | if(!g_quiet) | 1403 | if(!g_quiet) |
1404 | { | ||
999 | printf("Starting interactive lua session. Type 'help()' to get some help\n"); | 1405 | printf("Starting interactive lua session. Type 'help()' to get some help\n"); |
1406 | luaL_dostring(g_lua, "hwstub.info()"); | ||
1407 | } | ||
1000 | 1408 | ||
1001 | /** run startup commands */ | 1409 | /** run startup commands */ |
1002 | for(size_t i = 0; i < startup_cmds.size(); i++) | 1410 | for(size_t i = 0; i < startup_cmds.size(); i++) |
@@ -1012,14 +1420,15 @@ int main(int argc, char **argv) | |||
1012 | printf("error: %s\n", lua_tostring(g_lua, -1)); | 1420 | printf("error: %s\n", lua_tostring(g_lua, -1)); |
1013 | } | 1421 | } |
1014 | 1422 | ||
1423 | /* intercept CTRL+C */ | ||
1424 | signal(SIGINT, do_signal); | ||
1015 | // start interactive shell | 1425 | // start interactive shell |
1016 | luap_enter(g_lua, &g_exit); | 1426 | luap_enter(g_lua, &g_exit); |
1427 | lua_close(g_lua); | ||
1017 | 1428 | ||
1018 | Lerr: | ||
1019 | // display log if handled | 1429 | // display log if handled |
1020 | if(!g_quiet) | 1430 | if(!g_quiet) |
1021 | printf("Device log:\n"); | 1431 | printf("Device log:\n"); |
1022 | print_log(g_hwdev); | 1432 | print_log(g_hwdev); |
1023 | hwstub_release(g_hwdev); | ||
1024 | return 1; | 1433 | return 1; |
1025 | } | 1434 | } |