diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-02-07 21:46:58 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-04-08 19:38:18 +0200 |
commit | f6c61eb11a13f7a5141a980f56b9a14b3309c449 (patch) | |
tree | d1c4a4d992f88e40eacb65d5e046b595fdcb512a | |
parent | a2f4c5201d78b9f351834b0512623eeac622280f (diff) | |
download | rockbox-f6c61eb11a13f7a5141a980f56b9a14b3309c449.tar.gz rockbox-f6c61eb11a13f7a5141a980f56b9a14b3309c449.zip |
hwstub: port hwstub_shell to the new library
Also use this opportunity to cleanup support for multiple devices: the shell
now supports dynamic changes in the device and will call init() everytime
a new device is selected, to prepare a new environment. The shell now
honors register width on register read/write. The shell also provides access
to variants as follows by creating a subtable under the register using the
variant type in UPPER case and having the same layout as a register.
For example if register HW.GPIO.DIR has variants "set" and "clr", those can
be used like this:
HW.GPIO.DIR.SET.write(0xff)
HW.GPIO.DIR.CLR.write(0xff00)
Change-Id: I943947fa98bce875de0cba4338e8b7196a4c1165
-rw-r--r-- | utils/hwstub/tools/hwstub_shell.cpp | 723 | ||||
-rw-r--r-- | utils/hwstub/tools/init.lua | 86 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/atj.lua | 5 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/help.lua | 60 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/jz.lua | 26 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/load.lua | 32 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/pp.lua | 25 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/rk27xx.lua | 7 | ||||
-rw-r--r-- | utils/hwstub/tools/lua/stmp.lua | 42 |
9 files changed, 740 insertions, 266 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 | } |
diff --git a/utils/hwstub/tools/init.lua b/utils/hwstub/tools/init.lua index 323f36957d..8ab69c890a 100644 --- a/utils/hwstub/tools/init.lua +++ b/utils/hwstub/tools/init.lua | |||
@@ -1,71 +1,11 @@ | |||
1 | -- init code for hwstub_tools | 1 | -- init code for hwstub_tools |
2 | 2 | ||
3 | -- | 3 | -- |
4 | -- HELP | ||
5 | -- | ||
6 | HELP = hwstub.help | ||
7 | |||
8 | function HELP:create_topic(name) | ||
9 | self[name] = { create_topic = HELP.create_topic, add = HELP.add, get_topic = HELP.get_topic } | ||
10 | return self[name] | ||
11 | end | ||
12 | |||
13 | function HELP:get_topic(name) | ||
14 | return self[name] | ||
15 | end | ||
16 | |||
17 | function HELP:add(text) | ||
18 | table.insert(self, text) | ||
19 | end | ||
20 | |||
21 | do | ||
22 | local h = HELP:create_topic("hwstub") | ||
23 | h:add("This tool uses a number of well-defined namespaces (tables) to organise its features.") | ||
24 | h:add("The hwstub table contains a number of information and functions related to the tool itself.") | ||
25 | h:add("Of particular interest are") | ||
26 | h:add("* hwstub.host which holds host specific information.") | ||
27 | h:add("* hwstub.dev which holds device specific information. See DEV") | ||
28 | h:add("* hwstub.help (aka HELP) which holds the help. See HELP."); | ||
29 | h:add("* hwstub.soc which holds soc specific information. See HW"); | ||
30 | |||
31 | h = HELP:create_topic("HELP"); | ||
32 | h:add("This variable redirects to hwstub.help and provides access to the help system."); | ||
33 | h:add("You can enhance the help using the following methods on any topic (including HELP itself)."); | ||
34 | h:add("* t:create_topic(s) to create a new subtopic named s under topic t"); | ||
35 | h:add("* t:add(s) to add a help line to topic t"); | ||
36 | h:add("* t:get_topic(s) to get the subtopic s under topic t"); | ||
37 | |||
38 | h = HELP:create_topic("DEV"); | ||
39 | h:add("This variable redirects to hwstub.dev and provides direct access to the device."); | ||
40 | h:add("It contains some information about the device and the following methods."); | ||
41 | h:add("* read8/16/32(a) reads a 8/16/32-bit integer at address a atomically"); | ||
42 | h:add("* write8/16/32(a, v) writes the 8/16/32-bit integer v at address a atomically"); | ||
43 | h:add("* jump(a) jump to specified address"); | ||
44 | h:add("* call(a) call function at specified address and return to hwstub"); | ||
45 | h:add("* print_log() prints the device log"); | ||
46 | |||
47 | h = HELP:create_topic("HW"); | ||
48 | h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only."); | ||
49 | h:add("The complete register tree can be found under HW in a well organised fashion."); | ||
50 | h:add("* HW.dev points to device dev"); | ||
51 | h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses."); | ||
52 | h:add("* HW.dev.reg points to the register reg under dev"); | ||
53 | h:add("* HW.dev.reg[i] points to the register regi if there are several copies."); | ||
54 | h:add("* HW.dev.reg.f points to the field f under register reg."); | ||
55 | h:add("* HW.dev.reg.f.v gives the value of named value v of field f."); | ||
56 | h:add("* All registers can be read using HW.dev.reg.read() and written using HW.dev.reg.write(v)."); | ||
57 | h:add("* Register with a SCT variant also implement HW.dev.reg.set/clr/tog(v)."); | ||
58 | h:add("* All register field can be read using HW.dev.reg.f.read() and written using HW.dev.reg.f.write(v)."); | ||
59 | h:add("* Field writes can either give a integer or a named value to write(v)."); | ||
60 | h:add("* Register with a SCT variant also implement HW.dev.reg.f.set/clr/tog(v) with the same properties."); | ||
61 | h:add("* All devices, registers and fields also have descriptions available such as addresses."); | ||
62 | end | ||
63 | |||
64 | -- | ||
65 | -- INFO | 4 | -- INFO |
66 | -- | 5 | -- |
67 | 6 | ||
68 | if not hwstub.options.quiet then | 7 | function hwstub.info() |
8 | --- if not hwstub.options.quiet then | ||
69 | print("information") | 9 | print("information") |
70 | print(" hwstub") | 10 | print(" hwstub") |
71 | print(" version: " .. string.format("%d.%d", hwstub.host.version.major, | 11 | print(" version: " .. string.format("%d.%d", hwstub.host.version.major, |
@@ -87,6 +27,20 @@ if not hwstub.options.quiet then | |||
87 | hwstub.dev.layout.stack.size, hwstub.dev.layout.stack.start)) | 27 | hwstub.dev.layout.stack.size, hwstub.dev.layout.stack.start)) |
88 | print(" buffer: " .. string.format("%#x bytes @ %#x", | 28 | print(" buffer: " .. string.format("%#x bytes @ %#x", |
89 | hwstub.dev.layout.buffer.size, hwstub.dev.layout.buffer.start)) | 29 | hwstub.dev.layout.buffer.size, hwstub.dev.layout.buffer.start)) |
30 | if hwstub.dev.target.id == hwstub.dev.target.STMP then | ||
31 | print(" stmp") | ||
32 | print(" chipid: " .. string.format("%x", hwstub.dev.stmp.chipid)) | ||
33 | print(" rev: " .. string.format("%d", hwstub.dev.stmp.rev)) | ||
34 | print(" package: " .. string.format("%d", hwstub.dev.stmp.package)) | ||
35 | elseif hwstub.dev.target.id == hwstub.dev.target.PP then | ||
36 | print(" pp") | ||
37 | print(" chipid: " .. string.format("%x", hwstub.dev.pp.chipid)) | ||
38 | print(" rev: " .. string.format("%d", hwstub.dev.pp.rev)) | ||
39 | elseif hwstub.dev.target.id == hwstub.dev.target.JZ then | ||
40 | print(" jz") | ||
41 | print(" chipid: " .. string.format("%x", hwstub.dev.jz.chipid)) | ||
42 | print(" revision: " .. string.format("%c", hwstub.dev.jz.rev)) | ||
43 | end | ||
90 | end | 44 | end |
91 | 45 | ||
92 | -- | 46 | -- |
@@ -111,4 +65,12 @@ function hwstub.mdelay(msec) | |||
111 | hwstub.udelay(msec * 1000) | 65 | hwstub.udelay(msec * 1000) |
112 | end | 66 | end |
113 | 67 | ||
68 | require "lua/help" | ||
114 | require "lua/load" | 69 | require "lua/load" |
70 | |||
71 | function init() | ||
72 | LOAD.init() | ||
73 | end | ||
74 | |||
75 | -- first time init | ||
76 | init() | ||
diff --git a/utils/hwstub/tools/lua/atj.lua b/utils/hwstub/tools/lua/atj.lua index a1ad0c7505..16d2639f3a 100644 --- a/utils/hwstub/tools/lua/atj.lua +++ b/utils/hwstub/tools/lua/atj.lua | |||
@@ -4,7 +4,10 @@ | |||
4 | 4 | ||
5 | ATJ = {} | 5 | ATJ = {} |
6 | 6 | ||
7 | hwstub.soc:select("atj213x") | 7 | function ATJ.init() |
8 | hwstub.soc:select("atj213x") | ||
9 | end | ||
10 | |||
8 | require "atj/gpio" | 11 | require "atj/gpio" |
9 | require "atj/lcm" | 12 | require "atj/lcm" |
10 | require "atj/dsp" | 13 | require "atj/dsp" |
diff --git a/utils/hwstub/tools/lua/help.lua b/utils/hwstub/tools/lua/help.lua new file mode 100644 index 0000000000..280382eb61 --- /dev/null +++ b/utils/hwstub/tools/lua/help.lua | |||
@@ -0,0 +1,60 @@ | |||
1 | -- | ||
2 | -- HELP | ||
3 | -- | ||
4 | HELP = hwstub.help | ||
5 | |||
6 | function HELP:create_topic(name) | ||
7 | self[name] = { create_topic = HELP.create_topic, add = HELP.add, get_topic = HELP.get_topic } | ||
8 | return self[name] | ||
9 | end | ||
10 | |||
11 | function HELP:get_topic(name) | ||
12 | return self[name] | ||
13 | end | ||
14 | |||
15 | function HELP:add(text) | ||
16 | table.insert(self, text) | ||
17 | end | ||
18 | |||
19 | do | ||
20 | local h = HELP:create_topic("hwstub") | ||
21 | h:add("This tool uses a number of well-defined namespaces (tables) to organise its features.") | ||
22 | h:add("The hwstub table contains a number of information and functions related to the tool itself.") | ||
23 | h:add("Of particular interest are") | ||
24 | h:add("* hwstub.host which holds host specific information.") | ||
25 | h:add("* hwstub.dev which holds device specific information. See DEV") | ||
26 | h:add("* hwstub.help (aka HELP) which holds the help. See HELP."); | ||
27 | h:add("* hwstub.soc which holds soc specific information. See HW"); | ||
28 | |||
29 | h = HELP:create_topic("HELP"); | ||
30 | h:add("This variable redirects to hwstub.help and provides access to the help system."); | ||
31 | h:add("You can enhance the help using the following methods on any topic (including HELP itself)."); | ||
32 | h:add("* t:create_topic(s) to create a new subtopic named s under topic t"); | ||
33 | h:add("* t:add(s) to add a help line to topic t"); | ||
34 | h:add("* t:get_topic(s) to get the subtopic s under topic t"); | ||
35 | |||
36 | h = HELP:create_topic("DEV"); | ||
37 | h:add("This variable redirects to hwstub.dev and provides direct access to the device."); | ||
38 | h:add("It contains some information about the device and the following methods."); | ||
39 | h:add("* read8/16/32(a) reads a 8/16/32-bit integer at address a atomically"); | ||
40 | h:add("* write8/16/32(a, v) writes the 8/16/32-bit integer v at address a atomically"); | ||
41 | h:add("* jump(a) jump to specified address"); | ||
42 | h:add("* call(a) call function at specified address and return to hwstub"); | ||
43 | h:add("* print_log() prints the device log"); | ||
44 | |||
45 | h = HELP:create_topic("HW"); | ||
46 | h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only."); | ||
47 | h:add("The complete register tree can be found under HW in a well organised fashion."); | ||
48 | h:add("* HW.dev points to device dev"); | ||
49 | h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses."); | ||
50 | h:add("* HW.dev.reg points to the register reg under dev"); | ||
51 | h:add("* HW.dev.reg[i] points to the register regi if there are several copies."); | ||
52 | h:add("* HW.dev.reg.f points to the field f under register reg."); | ||
53 | h:add("* HW.dev.reg.f.v gives the value of named value v of field f."); | ||
54 | h:add("* All registers can be read using HW.dev.reg.read() and written using HW.dev.reg.write(v)."); | ||
55 | h:add("* Register with a SCT variant also implement HW.dev.reg.set/clr/tog(v)."); | ||
56 | h:add("* All register field can be read using HW.dev.reg.f.read() and written using HW.dev.reg.f.write(v)."); | ||
57 | h:add("* Field writes can either give a integer or a named value to write(v)."); | ||
58 | h:add("* Register with a SCT variant also implement HW.dev.reg.f.set/clr/tog(v) with the same properties."); | ||
59 | h:add("* All devices, registers and fields also have descriptions available such as addresses."); | ||
60 | end | ||
diff --git a/utils/hwstub/tools/lua/jz.lua b/utils/hwstub/tools/lua/jz.lua new file mode 100644 index 0000000000..ab2cb8658f --- /dev/null +++ b/utils/hwstub/tools/lua/jz.lua | |||
@@ -0,0 +1,26 @@ | |||
1 | --- | ||
2 | --- Chip Identification | ||
3 | --- | ||
4 | JZ = { info = {} } | ||
5 | |||
6 | local h = HELP:create_topic("JZ") | ||
7 | h:add("This table contains the abstraction of the different device blocks for the JZ.") | ||
8 | h:add("It allows one to use higher-level primitives rather than poking at register directly.") | ||
9 | |||
10 | hh = h:create_topic("debug") | ||
11 | hh:add("STMP.debug(...) prints some debug output if JZ.debug_on is true and does nothing otherwise.") | ||
12 | |||
13 | JZ.debug_on = false | ||
14 | |||
15 | function STMP.debug(...) | ||
16 | if STMP.debug_on then print(...) end | ||
17 | end | ||
18 | |||
19 | -- init | ||
20 | function JZ.init() | ||
21 | local desc = string.format("jz%04x%c", hwstub.dev.jz.chipid, hwstub.dev.jz.rev) | ||
22 | desc = desc:lower() | ||
23 | if not hwstub.soc:select(desc) then | ||
24 | print("Looking for soc " .. desc .. ": not found. Please load a soc by hand.") | ||
25 | end | ||
26 | end | ||
diff --git a/utils/hwstub/tools/lua/load.lua b/utils/hwstub/tools/lua/load.lua index f636360c4c..cafa82751e 100644 --- a/utils/hwstub/tools/lua/load.lua +++ b/utils/hwstub/tools/lua/load.lua | |||
@@ -1,14 +1,24 @@ | |||
1 | package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path | 1 | package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path |
2 | 2 | require "stmp" | |
3 | if hwstub.dev.target.id == hwstub.dev.target.STMP then | 3 | require "pp" |
4 | require "stmp" | 4 | require "rk27xx" |
5 | elseif hwstub.dev.target.id == hwstub.dev.target.PP then | 5 | require "atj" |
6 | require "pp" | 6 | require "jz" |
7 | elseif hwstub.dev.target.id == hwstub.dev.target.RK27 then | ||
8 | require "rk27xx" | ||
9 | elseif hwstub.dev.target.id == hwstub.dev.target.ATJ then | ||
10 | require "atj" | ||
11 | end | ||
12 | |||
13 | require "hwlib" | 7 | require "hwlib" |
14 | require "dumper" | 8 | require "dumper" |
9 | |||
10 | LOAD = {} | ||
11 | |||
12 | function LOAD.init() | ||
13 | if hwstub.dev.target.id == hwstub.dev.target.STMP then | ||
14 | STMP.init() | ||
15 | elseif hwstub.dev.target.id == hwstub.dev.target.PP then | ||
16 | PP.init() | ||
17 | elseif hwstub.dev.target.id == hwstub.dev.target.RK27 then | ||
18 | RK27XX.init() | ||
19 | elseif hwstub.dev.target.id == hwstub.dev.target.ATJ then | ||
20 | ATJ.init() | ||
21 | elseif hwstub.dev.target.id == hwstub.dev.target.JZ then | ||
22 | JZ.init() | ||
23 | end | ||
24 | end \ No newline at end of file | ||
diff --git a/utils/hwstub/tools/lua/pp.lua b/utils/hwstub/tools/lua/pp.lua index f9234780e5..38a4c1d0a2 100644 --- a/utils/hwstub/tools/lua/pp.lua +++ b/utils/hwstub/tools/lua/pp.lua | |||
@@ -42,16 +42,6 @@ function PP.is_pp500x() | |||
42 | return hwstub.dev.pp.chipid >= 0x5000 and hwstub.dev.pp.chipid < 0x5010 | 42 | return hwstub.dev.pp.chipid >= 0x5000 and hwstub.dev.pp.chipid < 0x5010 |
43 | end | 43 | end |
44 | 44 | ||
45 | if PP.is_pp611x() then | ||
46 | identify("PP611x (aka GoForce6110)", "pp6110", "pp6110") | ||
47 | elseif PP.is_pp502x() then | ||
48 | identify("PP502x", "pp502x", "pp502x") | ||
49 | elseif PP.is_pp500x() then | ||
50 | identify("PP500x", "pp500x", "pp500x") | ||
51 | else | ||
52 | print(string.format("Unable to identify this chip as a PP: chipid=0x%x", hwstub.dev.pp.chipid)); | ||
53 | end | ||
54 | |||
55 | hh = h:create_topic("debug") | 45 | hh = h:create_topic("debug") |
56 | hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does nothing otherwise.") | 46 | hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does nothing otherwise.") |
57 | 47 | ||
@@ -66,6 +56,17 @@ hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does n | |||
66 | 56 | ||
67 | PP.debug_on = false | 57 | PP.debug_on = false |
68 | 58 | ||
69 | if PP.info.chip ~= nil then | 59 | -- init |
70 | require "pp/gpio" | 60 | function PP.init() |
61 | if PP.is_pp611x() then | ||
62 | identify("PP611x (aka GoForce6110)", "pp6110", "pp6110") | ||
63 | elseif PP.is_pp502x() then | ||
64 | identify("PP502x", "pp502x", "pp502x") | ||
65 | elseif PP.is_pp500x() then | ||
66 | identify("PP500x", "pp500x", "pp500x") | ||
67 | else | ||
68 | print(string.format("Unable to identify this chip as a PP: chipid=0x%x", hwstub.dev.pp.chipid)); | ||
69 | end | ||
71 | end | 70 | end |
71 | |||
72 | require "pp/gpio" | ||
diff --git a/utils/hwstub/tools/lua/rk27xx.lua b/utils/hwstub/tools/lua/rk27xx.lua index 2a5bb9287c..f7f1f7a60f 100644 --- a/utils/hwstub/tools/lua/rk27xx.lua +++ b/utils/hwstub/tools/lua/rk27xx.lua | |||
@@ -4,5 +4,8 @@ | |||
4 | 4 | ||
5 | RK27XX = {} | 5 | RK27XX = {} |
6 | 6 | ||
7 | hwstub.soc:select("rk27xx") | 7 | function RK27XX.init() |
8 | require 'rk27xx/lcdif' | 8 | hwstub.soc:select("rk27xx") |
9 | end | ||
10 | |||
11 | require 'rk27xx/lradc' | ||
diff --git a/utils/hwstub/tools/lua/stmp.lua b/utils/hwstub/tools/lua/stmp.lua index 807c18df8d..ea1cde9c6d 100644 --- a/utils/hwstub/tools/lua/stmp.lua +++ b/utils/hwstub/tools/lua/stmp.lua | |||
@@ -1,7 +1,6 @@ | |||
1 | --- | 1 | --- |
2 | --- Chip Identification | 2 | --- Chip Identification |
3 | --- | 3 | --- |
4 | |||
5 | STMP = { info = {} } | 4 | STMP = { info = {} } |
6 | 5 | ||
7 | local h = HELP:create_topic("STMP") | 6 | local h = HELP:create_topic("STMP") |
@@ -49,18 +48,6 @@ function STMP.is_stmp3600() | |||
49 | return hwstub.dev.stmp.chipid >= 0x3600 and hwstub.dev.stmp.chipid < 0x3700 | 48 | return hwstub.dev.stmp.chipid >= 0x3600 and hwstub.dev.stmp.chipid < 0x3700 |
50 | end | 49 | end |
51 | 50 | ||
52 | if STMP.is_imx233() then | ||
53 | identify("STMP3780 (aka i.MX233)", "imx233", "imx233") | ||
54 | elseif STMP.is_stmp3700() then | ||
55 | identify("STMP3700", "stmp3700", "stmp3700") | ||
56 | elseif STMP.is_stmp3770() then | ||
57 | identify("STMP3770", "stmp3770", "stmp3700") | ||
58 | elseif STMP.is_stmp3600() then | ||
59 | identify("STMP3600", "stmp3600", "stmp3600") | ||
60 | else | ||
61 | print(string.format("Unable to identify this chip as a STMP: chipid=0x%x", hwstub.dev.stmp.chipid)); | ||
62 | end | ||
63 | |||
64 | hh = h:create_topic("debug") | 51 | hh = h:create_topic("debug") |
65 | hh:add("STMP.debug(...) prints some debug output if STMP.debug_on is true and does nothing otherwise.") | 52 | hh:add("STMP.debug(...) prints some debug output if STMP.debug_on is true and does nothing otherwise.") |
66 | 53 | ||
@@ -70,11 +57,24 @@ function STMP.debug(...) | |||
70 | if STMP.debug_on then print(...) end | 57 | if STMP.debug_on then print(...) end |
71 | end | 58 | end |
72 | 59 | ||
73 | if STMP.info.chip ~= nil then | 60 | -- init |
74 | require "stmp/digctl" | 61 | function STMP.init() |
75 | require "stmp/pinctrl" | 62 | if STMP.is_imx233() then |
76 | require "stmp/lcdif" | 63 | identify("STMP3780 (aka i.MX233)", "imx233", "imx233") |
77 | require "stmp/pwm" | 64 | elseif STMP.is_stmp3700() then |
78 | require "stmp/clkctrl" | 65 | identify("STMP3700", "stmp3700", "stmp3700") |
79 | require "stmp/i2c" | 66 | elseif STMP.is_stmp3770() then |
80 | end \ No newline at end of file | 67 | identify("STMP3770", "stmp3770", "stmp3700") |
68 | elseif STMP.is_stmp3600() then | ||
69 | identify("STMP3600", "stmp3600", "stmp3600") | ||
70 | else | ||
71 | print(string.format("Unable to identify this chip as a STMP: chipid=0x%x", hwstub.dev.stmp.chipid)); | ||
72 | end | ||
73 | end | ||
74 | |||
75 | require "stmp/digctl" | ||
76 | require "stmp/pinctrl" | ||
77 | require "stmp/lcdif" | ||
78 | require "stmp/pwm" | ||
79 | require "stmp/clkctrl" | ||
80 | require "stmp/i2c" \ No newline at end of file | ||