diff options
Diffstat (limited to 'utils/hwstub')
-rw-r--r-- | utils/hwstub/tools/Makefile | 5 | ||||
-rw-r--r-- | utils/hwstub/tools/hwstub_shell.cpp | 374 |
2 files changed, 224 insertions, 155 deletions
diff --git a/utils/hwstub/tools/Makefile b/utils/hwstub/tools/Makefile index f718300623..868ddcca79 100644 --- a/utils/hwstub/tools/Makefile +++ b/utils/hwstub/tools/Makefile | |||
@@ -2,9 +2,10 @@ CC=gcc | |||
2 | CXX=g++ | 2 | CXX=g++ |
3 | LD=g++ | 3 | LD=g++ |
4 | HWSTUB_LIB_DIR=../lib | 4 | HWSTUB_LIB_DIR=../lib |
5 | REGTOOLS_INCLUDE_DIR=../../regtools/include | ||
5 | REGTOOLS_LIB_DIR=../../regtools/lib | 6 | REGTOOLS_LIB_DIR=../../regtools/lib |
6 | CFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_LIB_DIR) `pkg-config --cflags lua5.2` | 7 | CFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_INCLUDE_DIR) `pkg-config --cflags lua5.2` |
7 | CXXFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_LIB_DIR) `pkg-config --cflags lua5.2` | 8 | CXXFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_INCLUDE_DIR) `pkg-config --cflags lua5.2` |
8 | LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs lua5.2` -lreadline -L$(HWSTUB_LIB_DIR) -L$(REGTOOLS_LIB_DIR) -lsocdesc -lhwstub `xml2-config --libs` | 9 | LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs lua5.2` -lreadline -L$(HWSTUB_LIB_DIR) -L$(REGTOOLS_LIB_DIR) -lsocdesc -lhwstub `xml2-config --libs` |
9 | EXEC=hwstub_shell hwstub_load | 10 | EXEC=hwstub_shell hwstub_load |
10 | SRC=$(wildcard *.c) | 11 | SRC=$(wildcard *.c) |
diff --git a/utils/hwstub/tools/hwstub_shell.cpp b/utils/hwstub/tools/hwstub_shell.cpp index f59ca8b82a..dd5c20b471 100644 --- a/utils/hwstub/tools/hwstub_shell.cpp +++ b/utils/hwstub/tools/hwstub_shell.cpp | |||
@@ -28,11 +28,14 @@ | |||
28 | #include <readline/history.h> | 28 | #include <readline/history.h> |
29 | #include <lua.hpp> | 29 | #include <lua.hpp> |
30 | #include <unistd.h> | 30 | #include <unistd.h> |
31 | #include "soc_desc_v1.hpp" | ||
31 | #include "soc_desc.hpp" | 32 | #include "soc_desc.hpp" |
32 | extern "C" { | 33 | extern "C" { |
33 | #include "prompt.h" | 34 | #include "prompt.h" |
34 | } | 35 | } |
35 | 36 | ||
37 | using namespace soc_desc_v1; | ||
38 | |||
36 | #if LUA_VERSION_NUM < 502 | 39 | #if LUA_VERSION_NUM < 502 |
37 | #warning You need at least lua 5.2 | 40 | #warning You need at least lua 5.2 |
38 | #endif | 41 | #endif |
@@ -51,6 +54,44 @@ struct hwstub_pp_desc_t g_hwdev_pp; | |||
51 | lua_State *g_lua; | 54 | lua_State *g_lua; |
52 | 55 | ||
53 | /** | 56 | /** |
57 | * debug | ||
58 | */ | ||
59 | |||
60 | void print_context(const std::string& file, const soc_desc::error_context_t& ctx) | ||
61 | { | ||
62 | for(size_t j = 0; j < ctx.count(); j++) | ||
63 | { | ||
64 | soc_desc::error_t e = ctx.get(j); | ||
65 | switch(e.level()) | ||
66 | { | ||
67 | case soc_desc::error_t::INFO: printf("[INFO]"); break; | ||
68 | case soc_desc::error_t::WARNING: printf("[WARN]"); break; | ||
69 | case soc_desc::error_t::FATAL: printf("[FATAL]"); break; | ||
70 | default: printf("[UNK]"); break; | ||
71 | } | ||
72 | if(e.location().size() != 0) | ||
73 | printf(" (%s) %s:", file.c_str(), e.location().c_str()); | ||
74 | printf(" %s\n", e.message().c_str()); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | void my_lua_print_stack(lua_State *state = 0, int up_to = 0) | ||
79 | { | ||
80 | if(state == 0) | ||
81 | state = g_lua; | ||
82 | up_to = lua_gettop(state) - up_to; | ||
83 | printf("stack:"); | ||
84 | for(int i = -1; i >= -up_to; i--) | ||
85 | { | ||
86 | if(lua_isstring(state, i)) | ||
87 | printf(" <%s>", lua_tostring(state, i)); | ||
88 | else | ||
89 | printf(" [%s]", lua_typename(state, lua_type(state, i))); | ||
90 | } | ||
91 | printf("\n"); | ||
92 | } | ||
93 | |||
94 | /** | ||
54 | * hw specific | 95 | * hw specific |
55 | */ | 96 | */ |
56 | 97 | ||
@@ -449,7 +490,7 @@ int my_lua_write_field(lua_State *state) | |||
449 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); | 490 | soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1)); |
450 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2)); | 491 | soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2)); |
451 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3)); | 492 | soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3)); |
452 | bool is_sct = lua_toboolean(state, lua_upvalueindex(5)); | 493 | char op = lua_tounsigned(state, lua_upvalueindex(5)); |
453 | 494 | ||
454 | soc_word_t value = mask; | 495 | soc_word_t value = mask; |
455 | if(n == 1) | 496 | if(n == 1) |
@@ -469,10 +510,17 @@ int my_lua_write_field(lua_State *state) | |||
469 | value &= mask; | 510 | value &= mask; |
470 | } | 511 | } |
471 | 512 | ||
472 | if(!is_sct) | 513 | soc_word_t old_value = hw_read32(state, addr); |
473 | value = value << shift | (hw_read32(state, addr) & ~(mask << shift)); | 514 | if(op == 'w') |
515 | value = value << shift | (old_value & ~(mask << shift)); | ||
516 | else if(op == 's') | ||
517 | value = old_value | value << shift; | ||
518 | else if(op == 'c') | ||
519 | value = old_value & ~(value << shift); | ||
520 | else if(op == 't') | ||
521 | value = old_value ^ (value << shift); | ||
474 | else | 522 | else |
475 | value <<= shift; | 523 | luaL_error(state, "write_field() internal error"); |
476 | 524 | ||
477 | hw_write32(state, addr, value); | 525 | hw_write32(state, addr, value); |
478 | return 0; | 526 | return 0; |
@@ -501,222 +549,240 @@ int my_lua_sct_reg(lua_State *state) | |||
501 | return 0; | 549 | return 0; |
502 | } | 550 | } |
503 | 551 | ||
504 | void my_lua_create_field(soc_addr_t addr, const soc_reg_field_t& field, bool sct) | 552 | /* lua stack on entry/exit: <reg table> */ |
553 | void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field) | ||
505 | { | 554 | { |
555 | soc_desc::field_t *f = field.get(); | ||
556 | /** create field table */ | ||
506 | lua_newtable(g_lua); | 557 | lua_newtable(g_lua); |
558 | /* lua stack: <field table> <reg table> */ | ||
507 | 559 | ||
508 | lua_pushstring(g_lua, field.name.c_str()); | 560 | /** create various characteristics */ |
561 | lua_pushstring(g_lua, f->name.c_str()); | ||
562 | /* lua stack: <name> <field table> ... */ | ||
509 | lua_setfield(g_lua, -2, "name"); | 563 | lua_setfield(g_lua, -2, "name"); |
564 | /* lua stack: <field table> ... */ | ||
510 | 565 | ||
511 | lua_pushunsigned(g_lua, addr); | 566 | lua_pushunsigned(g_lua, addr); |
567 | /* lua stack: <addr> <field table> ... */ | ||
512 | lua_setfield(g_lua, -2, "addr"); | 568 | lua_setfield(g_lua, -2, "addr"); |
569 | /* lua stack: <field table> ... */ | ||
513 | 570 | ||
514 | lua_pushboolean(g_lua, sct); | 571 | lua_pushunsigned(g_lua, f->pos); |
515 | lua_setfield(g_lua, -2, "sct"); | 572 | /* lua stack: <pos> <field table> ... */ |
516 | 573 | lua_setfield(g_lua, -2, "pos"); | |
517 | lua_pushunsigned(g_lua, field.first_bit); | 574 | /* lua stack: <field table> ... */ |
518 | lua_setfield(g_lua, -2, "first_bit"); | ||
519 | 575 | ||
520 | lua_pushunsigned(g_lua, field.last_bit); | 576 | lua_pushunsigned(g_lua, f->width); |
521 | lua_setfield(g_lua, -2, "last_bit"); | 577 | /* lua stack: <width> <field table> ... */ |
578 | lua_setfield(g_lua, -2, "width"); | ||
579 | /* lua stack: <field table> ... */ | ||
522 | 580 | ||
523 | lua_pushunsigned(g_lua, field.bitmask()); | 581 | lua_pushunsigned(g_lua, f->bitmask()); |
582 | /* lua stack: <bm> <field table> ... */ | ||
524 | lua_setfield(g_lua, -2, "bitmask"); | 583 | lua_setfield(g_lua, -2, "bitmask"); |
584 | /* lua stack: <field table> ... */ | ||
525 | 585 | ||
526 | soc_word_t local_bitmask = field.bitmask() >> field.first_bit; | 586 | soc_word_t local_bitmask = f->bitmask() >> f->pos; |
527 | lua_pushunsigned(g_lua, local_bitmask); | 587 | lua_pushunsigned(g_lua, local_bitmask); |
588 | /* lua stack: <local_bm> <field table> ... */ | ||
528 | lua_setfield(g_lua, -2, "local_bitmask"); | 589 | lua_setfield(g_lua, -2, "local_bitmask"); |
590 | /* lua stack: <field table> ... */ | ||
529 | 591 | ||
592 | /** create read routine */ | ||
530 | lua_pushunsigned(g_lua, addr); | 593 | lua_pushunsigned(g_lua, addr); |
531 | lua_pushunsigned(g_lua, field.first_bit); | 594 | lua_pushunsigned(g_lua, f->pos); |
532 | lua_pushunsigned(g_lua, local_bitmask); | 595 | lua_pushunsigned(g_lua, local_bitmask); |
596 | /* lua stack: <local_bm> <pos> <addr> <field table> ... */ | ||
533 | lua_pushcclosure(g_lua, my_lua_read_field, 3); | 597 | lua_pushcclosure(g_lua, my_lua_read_field, 3); |
598 | /* lua stack: <my_lua_read_field> <field table> ... */ | ||
534 | lua_setfield(g_lua, -2, "read"); | 599 | lua_setfield(g_lua, -2, "read"); |
600 | /* lua stack: <field table> ... */ | ||
535 | 601 | ||
536 | lua_pushunsigned(g_lua, addr); | 602 | /** create write/set/clr/tog routines */ |
537 | lua_pushunsigned(g_lua, field.first_bit); | 603 | static const char *name[] = {"write", "set", "clr", "tog"}; |
538 | lua_pushunsigned(g_lua, local_bitmask); | 604 | static const char arg[] = {'w', 's', 'c', 't'}; |
539 | lua_pushvalue(g_lua, -4); | 605 | for(int i = 0; i < 4; i++) |
540 | lua_pushboolean(g_lua, false); | ||
541 | lua_pushcclosure(g_lua, my_lua_write_field, 5); | ||
542 | lua_setfield(g_lua, -2, "write"); | ||
543 | |||
544 | if(sct) | ||
545 | { | 606 | { |
546 | lua_pushunsigned(g_lua, addr + 4); | 607 | lua_pushunsigned(g_lua, addr); |
547 | lua_pushunsigned(g_lua, field.first_bit); | 608 | lua_pushunsigned(g_lua, f->pos); |
548 | lua_pushunsigned(g_lua, local_bitmask); | 609 | lua_pushunsigned(g_lua, local_bitmask); |
610 | /* lua stack: <local_bm> <pos> <addr> <field table> ... */ | ||
549 | lua_pushvalue(g_lua, -4); | 611 | lua_pushvalue(g_lua, -4); |
550 | lua_pushboolean(g_lua, true); | 612 | /* lua stack: <field table> <local_bm> <pos> <addr> <field table> ... */ |
613 | lua_pushunsigned(g_lua, arg[i]); | ||
614 | /* lua stack: <'wsct'> <field table> <local_bm> <pos> <addr> <field table> ... */ | ||
551 | lua_pushcclosure(g_lua, my_lua_write_field, 5); | 615 | lua_pushcclosure(g_lua, my_lua_write_field, 5); |
552 | lua_setfield(g_lua, -2, "set"); | 616 | /* lua stack: <my_lua_write_field> <field table> ... */ |
553 | 617 | lua_setfield(g_lua, -2, name[i]); | |
554 | lua_pushunsigned(g_lua, addr + 8); | 618 | /* lua stack: <field table> ... */ |
555 | lua_pushunsigned(g_lua, field.first_bit); | ||
556 | lua_pushunsigned(g_lua, local_bitmask); | ||
557 | lua_pushvalue(g_lua, -4); | ||
558 | lua_pushboolean(g_lua, true); | ||
559 | lua_pushcclosure(g_lua, my_lua_write_field, 5); | ||
560 | lua_setfield(g_lua, -2, "clr"); | ||
561 | |||
562 | lua_pushunsigned(g_lua, addr + 12); | ||
563 | lua_pushunsigned(g_lua, field.first_bit); | ||
564 | lua_pushunsigned(g_lua, local_bitmask); | ||
565 | lua_pushvalue(g_lua, -4); | ||
566 | lua_pushboolean(g_lua, true); | ||
567 | lua_pushcclosure(g_lua, my_lua_write_field, 5); | ||
568 | lua_setfield(g_lua, -2, "tog"); | ||
569 | } | 619 | } |
570 | 620 | ||
571 | for(size_t i = 0; i < field.value.size(); i++) | 621 | /** create values */ |
622 | for(size_t i = 0; i < f->enum_.size(); i++) | ||
572 | { | 623 | { |
573 | lua_pushunsigned(g_lua, field.value[i].value); | 624 | lua_pushunsigned(g_lua, f->enum_[i].value); |
574 | lua_setfield(g_lua, -2, field.value[i].name.c_str()); | 625 | /* lua stack: <value> <field table> ... */ |
626 | lua_setfield(g_lua, -2, f->enum_[i].name.c_str()); | ||
627 | /* lua stack: <field table> ... */ | ||
575 | } | 628 | } |
629 | |||
630 | /** register field */ | ||
631 | lua_setfield(g_lua, -2, f->name.c_str()); | ||
632 | /* lua stack: <reg table> */ | ||
576 | } | 633 | } |
577 | 634 | ||
578 | void my_lua_create_reg(soc_addr_t addr, size_t index, const soc_reg_t& reg) | 635 | /* lua stack on entry/exit: <inst table> */ |
636 | void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg) | ||
579 | { | 637 | { |
580 | lua_newtable(g_lua); | 638 | if(!reg.valid()) |
581 | 639 | return; | |
582 | lua_pushstring(g_lua, reg.addr[index].name.c_str()); | 640 | /** create read/write routine */ |
583 | lua_setfield(g_lua, -2, "name"); | 641 | lua_pushunsigned(g_lua, addr); |
584 | 642 | /* lua stack: <addr> <inst table> */ | |
585 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | ||
586 | lua_setfield(g_lua, -2, "addr"); | ||
587 | |||
588 | lua_pushboolean(g_lua, !!(reg.flags & REG_HAS_SCT)); | ||
589 | lua_setfield(g_lua, -2, "sct"); | ||
590 | |||
591 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | ||
592 | lua_pushcclosure(g_lua, my_lua_read_reg, 1); | 643 | lua_pushcclosure(g_lua, my_lua_read_reg, 1); |
644 | /* lua stack: <my_lua_read_reg> <inst table> */ | ||
593 | lua_setfield(g_lua, -2, "read"); | 645 | lua_setfield(g_lua, -2, "read"); |
646 | /* lua stack: <inst table> */ | ||
594 | 647 | ||
595 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | 648 | lua_pushunsigned(g_lua, addr); |
649 | /* lua stack: <addr> <inst table> */ | ||
596 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); | 650 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); |
651 | /* lua stack: <my_lua_read_reg> <inst table> */ | ||
597 | lua_setfield(g_lua, -2, "write"); | 652 | lua_setfield(g_lua, -2, "write"); |
653 | /* lua stack: <inst table> */ | ||
598 | 654 | ||
599 | if(reg.flags & REG_HAS_SCT) | 655 | /** create set/clr/tog helpers */ |
656 | static const char *name[] = {"set", "clr", "tog"}; | ||
657 | static const char arg[] = {'s', 'c', 't'}; | ||
658 | for(int i = 0; i < 3; i++) | ||
600 | { | 659 | { |
601 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 4); | 660 | lua_pushunsigned(g_lua, addr); |
602 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); | 661 | /* lua stack: <addr> <inst table> */ |
603 | lua_setfield(g_lua, -2, "set"); | 662 | lua_pushunsigned(g_lua, arg[i]); |
663 | /* lua stack: <'s'/'c'/'t'> <addr> <inst table> */ | ||
664 | lua_pushcclosure(g_lua, my_lua_sct_reg, 2); | ||
665 | /* lua stack: <my_lua_sct_reg> <inst table> */ | ||
666 | lua_setfield(g_lua, -2, name[i]); | ||
667 | /* lua stack: <inst table> */ | ||
668 | } | ||
604 | 669 | ||
605 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 8); | 670 | /** create fields */ |
606 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); | 671 | std::vector< soc_desc::field_ref_t > fields = reg.fields(); |
607 | lua_setfield(g_lua, -2, "clr"); | 672 | for(size_t i = 0; i < fields.size(); i++) |
673 | my_lua_create_field(addr, fields[i]); | ||
674 | } | ||
608 | 675 | ||
609 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 12); | 676 | /* lua stack on entry/exit: <parent table> */ |
610 | lua_pushcclosure(g_lua, my_lua_write_reg, 1); | 677 | void my_lua_create_instances(const std::vector< soc_desc::node_inst_t >& inst) |
611 | lua_setfield(g_lua, -2, "tog"); | 678 | { |
612 | } | 679 | for(size_t i = 0; i < inst.size(); i++) |
613 | else | ||
614 | { | 680 | { |
615 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | 681 | /** if the instance is indexed, find the instance table, otherwise create it */ |
616 | lua_pushunsigned(g_lua, 's'); | 682 | if(inst[i].is_indexed()) |
617 | lua_pushcclosure(g_lua, my_lua_sct_reg, 2); | 683 | { |
618 | lua_setfield(g_lua, -2, "set"); | 684 | /** try to get the instance table, otherwise create it */ |
685 | lua_getfield(g_lua, -1, inst[i].name().c_str()); | ||
686 | /* lua stack: <index table> <parent table> */ | ||
687 | if(lua_isnil(g_lua, -1)) | ||
688 | { | ||
689 | lua_pop(g_lua, 1); | ||
690 | lua_newtable(g_lua); | ||
691 | /* lua stack: <index table> <parent table> */ | ||
692 | lua_pushvalue(g_lua, -1); | ||
693 | /* lua stack: <index table> <index table> <parent table> */ | ||
694 | lua_setfield(g_lua, -3, inst[i].name().c_str()); | ||
695 | /* lua stack: <index table> <parent table> */ | ||
696 | } | ||
697 | lua_pushinteger(g_lua, inst[i].index()); | ||
698 | /* lua stack: <index> <index table> <parent table> */ | ||
699 | } | ||
619 | 700 | ||
620 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | 701 | /** create a new table for the instance */ |
621 | lua_pushunsigned(g_lua, 'c'); | 702 | lua_newtable(g_lua); |
622 | lua_pushcclosure(g_lua, my_lua_sct_reg, 2); | 703 | /* lua stack: <instance table> [<index> <index table>] <parent table> */ |
623 | lua_setfield(g_lua, -2, "clr"); | ||
624 | 704 | ||
625 | lua_pushunsigned(g_lua, addr + reg.addr[index].addr); | 705 | /** create name and desc fields */ |
626 | lua_pushunsigned(g_lua, 't'); | 706 | lua_pushstring(g_lua, inst[i].node().get()->name.c_str()); |
627 | lua_pushcclosure(g_lua, my_lua_sct_reg, 2); | 707 | /* lua stack: <node name> <instance table> ... */ |
628 | lua_setfield(g_lua, -2, "tog"); | 708 | lua_setfield(g_lua, -2, "name"); |
629 | } | 709 | /* lua stack: <instance table> ... */ |
630 | 710 | ||
631 | for(size_t i = 0; i < reg.field.size(); i++) | 711 | lua_pushstring(g_lua, inst[i].node().get()->desc.c_str()); |
632 | { | 712 | /* lua stack: <node desc> <instance table> ... */ |
633 | my_lua_create_field(addr + reg.addr[index].addr, reg.field[i], | 713 | lua_setfield(g_lua, -2, "desc"); |
634 | reg.flags & REG_HAS_SCT); | 714 | /* lua stack: <instance table> ... */ |
635 | lua_setfield(g_lua, -2, reg.field[i].name.c_str()); | ||
636 | } | ||
637 | } | ||
638 | 715 | ||
639 | void my_lua_create_dev(size_t index, const soc_dev_t& dev) | 716 | lua_pushstring(g_lua, inst[i].node().get()->title.c_str()); |
640 | { | 717 | /* lua stack: <node title> <instance table> ... */ |
641 | lua_newtable(g_lua); | 718 | lua_setfield(g_lua, -2, "title"); |
719 | /* lua stack: <instance table> ... */ | ||
642 | 720 | ||
643 | lua_pushstring(g_lua, dev.addr[index].name.c_str()); | 721 | lua_pushunsigned(g_lua, inst[i].addr()); |
644 | lua_setfield(g_lua, -2, "name"); | 722 | /* lua stack: <node addr> <instance table> ... */ |
723 | lua_setfield(g_lua, -2, "addr"); | ||
724 | /* lua stack: <instance table> ... */ | ||
645 | 725 | ||
646 | lua_pushunsigned(g_lua, dev.addr[index].addr); | 726 | /** create register */ |
647 | lua_setfield(g_lua, -2, "addr"); | 727 | my_lua_create_reg(inst[i].addr(), inst[i].node().reg()); |
648 | 728 | ||
649 | for(size_t i = 0; i < dev.reg.size(); i++) | 729 | /** create subinstances */ |
650 | { | 730 | my_lua_create_instances(inst[i].children()); |
651 | bool table = dev.reg[i].addr.size() > 1; | 731 | /* lua stack: <instance table> [<index> <index table>] <parent table> */ |
652 | if(table) | ||
653 | lua_newtable(g_lua); | ||
654 | else | ||
655 | lua_pushnil(g_lua); | ||
656 | 732 | ||
657 | for(size_t k = 0; k < dev.reg[i].addr.size(); k++) | 733 | if(inst[i].is_indexed()) |
658 | { | 734 | { |
659 | my_lua_create_reg(dev.addr[index].addr, k, dev.reg[i]); | 735 | /* lua stack: <instance table> <index> <index table> <parent table> */ |
660 | if(table) | 736 | lua_settable(g_lua, -3); |
661 | { | 737 | /* lua stack: <index table> <parent table> */ |
662 | lua_pushinteger(g_lua, k); | 738 | lua_pop(g_lua, 1); |
663 | lua_pushvalue(g_lua, -2); | ||
664 | lua_settable(g_lua, -4); | ||
665 | } | ||
666 | lua_setfield(g_lua, -3, dev.reg[i].addr[k].name.c_str()); | ||
667 | } | 739 | } |
668 | |||
669 | if(table) | ||
670 | lua_setfield(g_lua, -2, dev.reg[i].name.c_str()); | ||
671 | else | 740 | else |
672 | lua_pop(g_lua, 1); | 741 | { |
742 | /* lua stack: <instance table> <parent table> */ | ||
743 | lua_setfield(g_lua, -2, inst[i].name().c_str()); | ||
744 | } | ||
745 | /* lua stack: <parent table> */ | ||
673 | } | 746 | } |
674 | } | 747 | } |
675 | 748 | ||
676 | bool my_lua_import_soc(const soc_t& soc) | 749 | bool my_lua_import_soc(soc_desc::soc_t& soc) |
677 | { | 750 | { |
751 | /** remember old stack index to check for unbalanced stack at the end */ | ||
678 | int oldtop = lua_gettop(g_lua); | 752 | int oldtop = lua_gettop(g_lua); |
679 | 753 | ||
754 | /** find hwstub.soc table */ | ||
680 | lua_getglobal(g_lua, "hwstub"); | 755 | lua_getglobal(g_lua, "hwstub"); |
756 | /* lua stack: <hwstub table> */ | ||
681 | lua_getfield(g_lua, -1, "soc"); | 757 | lua_getfield(g_lua, -1, "soc"); |
758 | /* lua stack: <hwstub.soc table> <hwstub table> */ | ||
682 | 759 | ||
760 | /** create a new table for the soc */ | ||
683 | lua_newtable(g_lua); | 761 | lua_newtable(g_lua); |
762 | /* lua stack: <soc table> <hwstub.soc table> <hwstub table> */ | ||
684 | 763 | ||
764 | /** create name and desc fields */ | ||
685 | lua_pushstring(g_lua, soc.name.c_str()); | 765 | lua_pushstring(g_lua, soc.name.c_str()); |
766 | /* lua stack: <soc name> <soc table> <hwstub.soc table> <hwstub table> */ | ||
686 | lua_setfield(g_lua, -2, "name"); | 767 | lua_setfield(g_lua, -2, "name"); |
768 | /* lua stack: <soc table> <hwstub.soc table> <hwstub table> */ | ||
687 | 769 | ||
688 | lua_pushstring(g_lua, soc.desc.c_str()); | 770 | lua_pushstring(g_lua, soc.desc.c_str()); |
771 | /* lua stack: <soc desc> <soc table> <hwstub.soc table> <hwstub table> */ | ||
689 | lua_setfield(g_lua, -2, "desc"); | 772 | lua_setfield(g_lua, -2, "desc"); |
773 | /* lua stack: <soc table> <hwstub.soc table> <hwstub table> */ | ||
690 | 774 | ||
691 | for(size_t i = 0; i < soc.dev.size(); i++) | 775 | /** create instances */ |
692 | { | 776 | soc_desc::soc_ref_t rsoc(&soc); |
693 | bool table = soc.dev[i].addr.size() > 1; | 777 | my_lua_create_instances(rsoc.root_inst().children()); |
694 | if(table) | 778 | /* lua stack: <soc table> <hwstub.soc table> <hwstub table> */ |
695 | lua_newtable(g_lua); | ||
696 | else | ||
697 | lua_pushnil(g_lua); | ||
698 | |||
699 | for(size_t k = 0; k < soc.dev[i].addr.size(); k++) | ||
700 | { | ||
701 | my_lua_create_dev(k, soc.dev[i]); | ||
702 | if(table) | ||
703 | { | ||
704 | lua_pushinteger(g_lua, k + 1); | ||
705 | lua_pushvalue(g_lua, -2); | ||
706 | lua_settable(g_lua, -4); | ||
707 | } | ||
708 | lua_setfield(g_lua, -3, soc.dev[i].addr[k].name.c_str()); | ||
709 | } | ||
710 | |||
711 | if(table) | ||
712 | lua_setfield(g_lua, -2, soc.dev[i].name.c_str()); | ||
713 | else | ||
714 | lua_pop(g_lua, 1); | ||
715 | } | ||
716 | 779 | ||
780 | /** put soc table at hwstub.soc.<soc name> */ | ||
717 | lua_setfield(g_lua, -2, soc.name.c_str()); | 781 | lua_setfield(g_lua, -2, soc.name.c_str()); |
782 | /* lua stack: <hwstub.soc table> <hwstub table> */ | ||
718 | 783 | ||
719 | lua_pop(g_lua, 2); | 784 | lua_pop(g_lua, 2); |
785 | /* lua stack: <> */ | ||
720 | 786 | ||
721 | if(lua_gettop(g_lua) != oldtop) | 787 | if(lua_gettop(g_lua) != oldtop) |
722 | { | 788 | { |
@@ -726,7 +792,7 @@ bool my_lua_import_soc(const soc_t& soc) | |||
726 | return true; | 792 | return true; |
727 | } | 793 | } |
728 | 794 | ||
729 | bool my_lua_import_soc(const std::vector< soc_t >& socs) | 795 | bool my_lua_import_soc(std::vector< soc_desc::soc_t >& socs) |
730 | { | 796 | { |
731 | for(size_t i = 0; i < socs.size(); i++) | 797 | for(size_t i = 0; i < socs.size(); i++) |
732 | { | 798 | { |
@@ -803,15 +869,17 @@ int main(int argc, char **argv) | |||
803 | } | 869 | } |
804 | 870 | ||
805 | // load register descriptions | 871 | // load register descriptions |
806 | std::vector< soc_t > socs; | 872 | std::vector< soc_desc::soc_t > socs; |
807 | for(int i = optind; i < argc; i++) | 873 | for(int i = optind; i < argc; i++) |
808 | { | 874 | { |
809 | socs.push_back(soc_t()); | 875 | socs.push_back(soc_desc::soc_t()); |
810 | if(!soc_desc_parse_xml(argv[i], socs[socs.size() - 1])) | 876 | soc_desc::error_context_t ctx; |
877 | if(!soc_desc::parse_xml(argv[i], socs[socs.size() - 1], ctx)) | ||
811 | { | 878 | { |
812 | printf("Cannot load description '%s'\n", argv[i]); | 879 | printf("Cannot load description file '%s'\n", argv[i]); |
813 | return 2; | 880 | socs.pop_back(); |
814 | } | 881 | } |
882 | print_context(argv[i], ctx); | ||
815 | } | 883 | } |
816 | 884 | ||
817 | // create usb context | 885 | // create usb context |