summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-02-07 21:46:58 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2016-04-08 19:38:18 +0200
commitf6c61eb11a13f7a5141a980f56b9a14b3309c449 (patch)
treed1c4a4d992f88e40eacb65d5e046b595fdcb512a
parenta2f4c5201d78b9f351834b0512623eeac622280f (diff)
downloadrockbox-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.cpp723
-rw-r--r--utils/hwstub/tools/init.lua86
-rw-r--r--utils/hwstub/tools/lua/atj.lua5
-rw-r--r--utils/hwstub/tools/lua/help.lua60
-rw-r--r--utils/hwstub/tools/lua/jz.lua26
-rw-r--r--utils/hwstub/tools/lua/load.lua32
-rw-r--r--utils/hwstub/tools/lua/pp.lua25
-rw-r--r--utils/hwstub/tools/lua/rk27xx.lua7
-rw-r--r--utils/hwstub/tools/lua/stmp.lua42
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 @@
* KIND, either express or implied.
*
****************************************************************************/
-#include "hwstub.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdbool.h>
+#include <sstream>
+#include <iomanip>
+#include <iostream>
#include <readline/readline.h>
#include <readline/history.h>
#include <lua.hpp>
#include <unistd.h>
+#include <signal.h>
+#include <dirent.h>
#include "soc_desc_v1.hpp"
#include "soc_desc.hpp"
+#include "hwstub.hpp"
+#include "hwstub_usb.hpp"
+#include "hwstub_uri.hpp"
extern "C" {
#include "prompt.h"
}
using namespace soc_desc_v1;
+using namespace hwstub;
#if LUA_VERSION_NUM < 502
#warning You need at least lua 5.2
@@ -45,12 +53,17 @@ using namespace soc_desc_v1;
*/
bool g_quiet = false;
bool g_exit = false;
-struct hwstub_device_t *g_hwdev;
+bool g_print_mem_rw = false;
+std::shared_ptr<context> g_hwctx;
+std::shared_ptr<handle> g_hwdev;
struct hwstub_version_desc_t g_hwdev_ver;
struct hwstub_layout_desc_t g_hwdev_layout;
struct hwstub_target_desc_t g_hwdev_target;
struct hwstub_stmp_desc_t g_hwdev_stmp;
+struct hwstub_jz_desc_t g_hwdev_jz;
struct hwstub_pp_desc_t g_hwdev_pp;
+std::vector<std::shared_ptr<device>> g_devlist;
+
lua_State *g_lua;
/**
@@ -95,13 +108,14 @@ void my_lua_print_stack(lua_State *state = 0, int up_to = 0)
* hw specific
*/
-void print_log(struct hwstub_device_t *hwdev)
+void print_log(std::shared_ptr<handle> hwdev)
{
do
{
char buffer[128];
- int length = hwstub_get_log(hwdev, buffer, sizeof(buffer) - 1);
- if(length <= 0)
+ size_t length = sizeof(buffer) - 1;
+ error err = hwdev->get_log(buffer, length);
+ if(err != error::SUCCESS || length == 0)
break;
buffer[length] = 0;
printf("%s", buffer);
@@ -188,46 +202,70 @@ typedef void (*hw_writen_fn_t)(lua_State *state, soc_addr_t addr, soc_word_t val
soc_word_t hw_read8(lua_State *state, soc_addr_t addr)
{
uint8_t u;
- if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->read(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to read8 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[read8 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
return u;
}
soc_word_t hw_read16(lua_State *state, soc_addr_t addr)
{
uint16_t u;
- if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->read(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to read16 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[read16 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
return u;
}
soc_word_t hw_read32(lua_State *state, soc_addr_t addr)
{
uint32_t u;
- if(hwstub_rw_mem_atomic(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->read(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to read32 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[read32 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
return u;
}
void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val)
{
uint8_t u = val;
- if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->write(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to write8 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[write8 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
}
void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val)
{
uint16_t u = val;
- if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->write(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to write16 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[write16 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
}
void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val)
{
uint32_t u = val;
- if(hwstub_rw_mem_atomic(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
+ size_t sz = sizeof(u);
+ error ret = g_hwdev->write(addr, &u, sz, true);
+ if(ret != error::SUCCESS || sz != sizeof(u))
luaL_error(state, "fail to write32 @ %p", addr);
+ if(g_print_mem_rw)
+ printf("[write32 @ %#lx = %#lx]\n", (unsigned long)addr, (unsigned long)u);
}
int my_lua_readn(lua_State *state)
@@ -256,7 +294,7 @@ int my_lua_call(lua_State *state)
if(n != 1)
luaL_error(state, "call takes target address argument");
- hwstub_call(g_hwdev, luaL_checkunsigned(state, 1));
+ g_hwdev->exec(luaL_checkunsigned(state, 1), HWSTUB_EXEC_CALL);
return 0;
}
@@ -266,7 +304,7 @@ int my_lua_jump(lua_State *state)
if(n != 1)
luaL_error(state, "jump takes target address argument");
- hwstub_jump(g_hwdev, luaL_checkunsigned(state, 1));
+ g_hwdev->exec(luaL_checkunsigned(state, 1), HWSTUB_EXEC_JUMP);
return 0;
}
@@ -276,6 +314,54 @@ int my_lua_printlog(lua_State *state)
return 0;
}
+std::string get_dev_name(std::shared_ptr<device> dev)
+{
+ std::ostringstream name;
+ usb::device *udev = dynamic_cast<usb::device*>(dev.get());
+ if(udev)
+ {
+ name << "USB Bus " << (unsigned)udev->get_bus_number() <<
+ " Device " << std::setw(2) << std::hex << (unsigned)udev->get_address() << ": ";
+ }
+ // try to open device
+ std::shared_ptr<handle> h;
+ error ret = dev->open(h);
+ if(ret != error::SUCCESS)
+ {
+ name << "<cannot open dev>";
+ return name.str();
+ }
+ // get target information
+ hwstub_target_desc_t desc;
+ ret = h->get_target_desc(desc);
+ if(ret !=error::SUCCESS)
+ {
+ name << "<cannot get name: " << error_string(ret) << ">";
+ return name.str();
+ }
+ name << desc.bName;
+ return name.str();
+}
+
+int my_lua_get_dev_list(lua_State *state)
+{
+ error ret = g_hwctx->get_device_list(g_devlist);
+ if(ret != error::SUCCESS)
+ {
+ printf("Cannot device list\n");
+ return -1;
+ }
+
+ printf("=== Available device list ===\n");
+ for(size_t i = 0; i < g_devlist.size(); i++)
+ {
+ std::string name = get_dev_name(g_devlist[i]);
+ printf("%zu: %s%s\n", i, name.c_str(),
+ g_devlist[i] == g_hwdev->get_device() ? " <--" : "");
+ }
+ return 0;
+}
+
int my_lua_quit(lua_State *state)
{
g_exit = true;
@@ -292,6 +378,256 @@ int my_lua_udelay(lua_State *state)
return 0;
}
+int my_lua_mdelay(lua_State *state)
+{
+ int n = lua_gettop(state);
+ if(n != 1)
+ luaL_error(state, "mdelay takes one argument");
+ long usec = lua_tointeger(state, -1);
+ usleep(usec * 1000);
+ return 0;
+}
+
+int fetch_dev_info()
+{
+ // get memory layout information
+ error ret = g_hwdev->get_layout_desc(g_hwdev_layout);
+ if(ret != error::SUCCESS)
+ {
+ printf("Cannot get layout descriptor: %s\n", error_string(ret).c_str());
+ goto Lerr;
+ }
+ // get hwstub information
+ ret = g_hwdev->get_version_desc(g_hwdev_ver);
+ if(ret != error::SUCCESS)
+ {
+ printf("Cannot get version descriptor: %s\n", error_string(ret).c_str());
+ goto Lerr;
+ }
+ // get target
+ ret = g_hwdev->get_target_desc(g_hwdev_target);
+ if(ret != error::SUCCESS)
+ {
+ printf("Cannot get target descriptor: %s\n", error_string(ret).c_str());
+ goto Lerr;
+ }
+ if(g_hwdev_target.dID == HWSTUB_TARGET_STMP)
+ ret = g_hwdev->get_stmp_desc(g_hwdev_stmp);
+ // get PP specific information
+ else if(g_hwdev_target.dID == HWSTUB_TARGET_PP)
+ ret = g_hwdev->get_pp_desc(g_hwdev_pp);
+ // get JZ specific information
+ else if(g_hwdev_target.dID == HWSTUB_TARGET_JZ)
+ ret = g_hwdev->get_jz_desc(g_hwdev_jz);
+ if(ret != error::SUCCESS)
+ {
+ printf("Cannot get soc specific descriptor: %s\n", error_string(ret).c_str());
+ goto Lerr;
+ }
+ return 0;
+Lerr:
+ return -1;
+}
+
+int update_dev_lua_state(lua_State *state)
+{
+ // fetch info before starting to mess with the lua state
+ int ret = fetch_dev_info();
+ if(ret < 0)
+ return ret;
+ // hwstub
+ lua_getglobal(state, "hwstub");
+ // hwstub.dev
+ lua_getfield(state, -1, "dev");
+
+ // hwstub.dev.version
+ lua_getfield(state, -1, "version");
+
+ // hwstub.dev.version.major = g_hwdev_ver.bMajor
+ lua_pushstring(state, "major");
+ lua_pushinteger(state, g_hwdev_ver.bMajor);
+ lua_settable(state, -3);
+
+ // hwstub.dev.version.minor = g_hwdev_ver.bMinor
+ lua_pushstring(state, "minor");
+ lua_pushinteger(state, g_hwdev_ver.bMinor);
+ lua_settable(state, -3);
+ lua_pop(state, 1);
+
+ // hwstub.dev.layout
+ lua_getfield(state, -1, "layout");
+
+ // hwstub.dev.layout.code
+ lua_getfield(state, -1, "code");
+
+ // hwstub.dev.layout.code.start = g_hwdev_layout.dCodeStart
+ lua_pushstring(state, "start");
+ lua_pushinteger(state, g_hwdev_layout.dCodeStart);
+ lua_settable(state, -3);
+
+ // hwstub.dev.layout.code.size = g_hwdev_layout.dCodeSize
+ lua_pushstring(state, "size");
+ lua_pushinteger(state, g_hwdev_layout.dCodeSize);
+ lua_settable(state, -3);
+
+ // hwstub.dev.layout
+ lua_pop(state, 1);
+
+ // hwstub.dev.layout.stack
+ lua_getfield(state, -1, "stack");
+
+ // hwstub.dev.layout.stack.start = g_hwdev_layout.dStackStart
+ lua_pushstring(state, "start");
+ lua_pushinteger(state, g_hwdev_layout.dStackStart);
+ lua_settable(state, -3);
+
+ // hwstub.dev.layout.stack.size = g_hwdev_layout.dStackSize
+ lua_pushstring(state, "size");
+ lua_pushinteger(state, g_hwdev_layout.dStackSize);
+ lua_settable(state, -3);
+
+ // hwstub.dev.layout
+ lua_pop(state, 1);
+
+ // hwstub.dev.layout.buffer
+ lua_getfield(state, -1, "buffer");
+
+ // hwstub.dev.layout.buffer.start = g_hwdev_layout.dBufferStart
+ lua_pushstring(state, "start");
+ lua_pushinteger(state, g_hwdev_layout.dBufferStart);
+ lua_settable(state, -3);
+
+ // hwstub.dev.layout.buffer.size = g_hwdev_layout.dBufferSize
+ lua_pushstring(state, "size");
+ lua_pushinteger(state, g_hwdev_layout.dBufferSize);
+ lua_settable(state, -3);
+
+ // hwstub.dev
+ lua_pop(state, 2);
+
+ // hwstub.dev.target
+ lua_getfield(state, -1, "target");
+
+ // hwstub.dev.target.id = g_hwdev_target.dID
+ lua_pushstring(state, "id");
+ lua_pushinteger(state, g_hwdev_target.dID);
+ lua_settable(state, -3);
+
+ // hwstub.dev.target.name = g_hwdev_target.bName
+ lua_pushstring(state, "name");
+ lua_pushstring(state, g_hwdev_target.bName);
+ lua_settable(state, -3);
+
+ // hwstub.dev
+ lua_pop(state, 1);
+
+ // get STMP specific information
+ if(g_hwdev_target.dID == HWSTUB_TARGET_STMP)
+ {
+ // hwstub.dev.stmp
+ lua_getfield(state, -1, "stmp");
+
+ // hwstub.dev.stmp.chipid = g_hwdev_stmp.wChipID
+ lua_pushstring(state, "chipid");
+ lua_pushinteger(state, g_hwdev_stmp.wChipID);
+ lua_settable(state, -3);
+
+ // hwstub.dev.stmp.rev = g_hwdev_stmp.bRevision
+ lua_pushstring(state, "rev");
+ lua_pushinteger(state, g_hwdev_stmp.bRevision);
+ lua_settable(state, -3);
+
+ // hwstub.dev.stmp.package = g_hwdev_stmp.bPackage
+ lua_pushstring(state, "package");
+ lua_pushinteger(state, g_hwdev_stmp.bPackage);
+ lua_settable(state, -3);
+
+ // hwstub.dev
+ lua_pop(state, 1);
+ }
+ // get PP specific information
+ else if(g_hwdev_target.dID == HWSTUB_TARGET_PP)
+ {
+ // hwstub.dev.pp
+ lua_getfield(state, -1, "pp");
+
+ // hwstub.dev.pp.chipid = g_hwdev_pp.wChipID
+ lua_pushstring(state, "chipid");
+ lua_pushinteger(state, g_hwdev_pp.wChipID);
+ lua_settable(state, -3);
+
+ // hwstub.dev.pp.rev = g_hwdev_pp.bRevision
+ lua_pushstring(state, "rev");
+ lua_pushlstring(state, (const char *)g_hwdev_pp.bRevision, 2);
+ lua_settable(state, -3);
+
+ // hwstub.dev
+ lua_pop(state, 1);
+ }
+ // get JZ specific information
+ else if(g_hwdev_target.dID == HWSTUB_TARGET_JZ)
+ {
+ // hwstub.dev.jz
+ lua_getfield(state, -1, "jz");
+
+ // hwstub.dev.jz.chipid = g_hwdev_jz.wChipID
+ lua_pushstring(state, "chipid");
+ lua_pushinteger(state, g_hwdev_jz.wChipID);
+ lua_settable(state, -3);
+
+ // hwstub.dev.jz.rev = g_hwdev_jz.bRevision
+ lua_pushstring(state, "rev");
+ lua_pushinteger(state, g_hwdev_jz.bRevision);
+ lua_settable(state, -3);
+
+ // hwstub.dev
+ lua_pop(state, 1);
+ }
+ // pop all globals (hwstub.dev)
+ lua_pop(state, 2);
+ return 0;
+}
+
+int my_lua_dev_open(lua_State *state)
+{
+ int n = lua_gettop(state);
+ if(n != 1)
+ luaL_error(state, "open_dev takes one argument");
+ int32_t id = lua_tointeger(state, -1);
+ if(id < 0 || (size_t)id >= g_devlist.size())
+ luaL_error(state, "invalid device id");
+ std::shared_ptr<handle> h;
+ error ret = g_devlist[id]->open(h);
+ if(ret != error::SUCCESS)
+ luaL_error(state, "Cannot open device: %s. The current device was NOT changed.\n", error_string(ret).c_str());
+ else
+ g_hwdev = h;
+ if(update_dev_lua_state(state) < 0)
+ return -1;
+ if(luaL_dostring(state, "init()"))
+ luaL_error(state, "error in init: %s\n", lua_tostring(state, -1));
+ lua_pop(state, lua_gettop(state));
+ return 0;
+}
+
+int my_lua_dev_close(lua_State *state)
+{
+ int n = lua_gettop(state);
+ if(n != 0)
+ luaL_error(state, "close_dev takes no argument");
+ std::shared_ptr<device> dev;
+ error ret = g_hwctx->get_dummy_device(dev);
+ if(ret != error::SUCCESS)
+ luaL_error(state, "Cannot get dummy device: %s. The current device was NOT closed.\n", error_string(ret).c_str());
+ std::shared_ptr<handle> h;
+ ret = dev->open(h);
+ if(ret != error::SUCCESS)
+ luaL_error(state, "Cannot open dummy device: %s. The current device was NOT changed.\n", error_string(ret).c_str());
+ else
+ g_hwdev = h;
+ return update_dev_lua_state(state);
+}
+
bool my_lua_import_hwstub()
{
int oldtop = lua_gettop(g_lua);
@@ -349,28 +685,30 @@ bool my_lua_import_hwstub()
lua_setfield(g_lua, -2, "RK27");
lua_pushinteger(g_lua, HWSTUB_TARGET_ATJ);
lua_setfield(g_lua, -2, "ATJ");
+ lua_pushinteger(g_lua, HWSTUB_TARGET_JZ);
+ lua_setfield(g_lua, -2, "JZ");
lua_setfield(g_lua, -2, "target");
- if(g_hwdev_target.dID == HWSTUB_TARGET_STMP)
- {
- lua_newtable(g_lua); // stmp
- lua_pushinteger(g_lua, g_hwdev_stmp.wChipID);
- lua_setfield(g_lua, -2, "chipid");
- lua_pushinteger(g_lua, g_hwdev_stmp.bRevision);
- lua_setfield(g_lua, -2, "rev");
- lua_pushinteger(g_lua, g_hwdev_stmp.bPackage);
- lua_setfield(g_lua, -2, "package");
- lua_setfield(g_lua, -2, "stmp");
- }
- else if(g_hwdev_target.dID == HWSTUB_TARGET_PP)
- {
- lua_newtable(g_lua); // pp
- lua_pushinteger(g_lua, g_hwdev_pp.wChipID);
- lua_setfield(g_lua, -2, "chipid");
- lua_pushlstring(g_lua, (const char *)g_hwdev_pp.bRevision, 2);
- lua_setfield(g_lua, -2, "rev");
- lua_setfield(g_lua, -2, "pp");
- }
+ lua_newtable(g_lua); // stmp
+ lua_pushinteger(g_lua, 0);
+ lua_setfield(g_lua, -2, "chipid");
+ lua_pushinteger(g_lua, 0);
+ lua_setfield(g_lua, -2, "rev");
+ lua_pushinteger(g_lua, 0);
+ lua_setfield(g_lua, -2, "package");
+ lua_setfield(g_lua, -2, "stmp");
+
+ lua_newtable(g_lua); // pp
+ lua_pushinteger(g_lua, 0);
+ lua_setfield(g_lua, -2, "chipid");
+ lua_pushstring(g_lua, "");
+ lua_setfield(g_lua, -2, "rev");
+ lua_setfield(g_lua, -2, "pp");
+
+ lua_newtable(g_lua); // jz
+ lua_pushinteger(g_lua, 0);
+ lua_setfield(g_lua, -2, "chipid");
+ lua_setfield(g_lua, -2, "jz");
lua_pushlightuserdata(g_lua, (void *)&hw_read8);
lua_pushcclosure(g_lua, my_lua_readn, 1);
@@ -414,7 +752,7 @@ bool my_lua_import_hwstub()
lua_newtable(g_lua); // help
lua_pushinteger(g_lua, 1);
- lua_pushstring(g_lua, "This is the help for hwstub_tool. This tools uses Lua to interpret commands.");
+ lua_pushstring(g_lua, "This is the help for tool. This tools uses Lua to interpret commands.");
lua_settable(g_lua, -3);
lua_pushinteger(g_lua, 2);
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()
lua_pushcclosure(g_lua, my_lua_udelay, 0);
lua_setfield(g_lua, -2, "udelay");
+ lua_pushcclosure(g_lua, my_lua_mdelay, 0);
+ lua_setfield(g_lua, -2, "mdelay");
+
+ lua_pushcfunction(g_lua, my_lua_get_dev_list);
+ lua_setfield(g_lua, -2, "get_dev_list");
+
+ lua_pushcclosure(g_lua, my_lua_dev_open, 0);
+ lua_setfield(g_lua, -2, "open_dev");
+
+ lua_pushcclosure(g_lua, my_lua_dev_close, 0);
+ lua_setfield(g_lua, -2, "close_dev");
+
lua_setglobal(g_lua, "hwstub");
lua_pushcfunction(g_lua, my_lua_help);
@@ -441,6 +791,8 @@ bool my_lua_import_hwstub()
lua_pushcfunction(g_lua, my_lua_quit);
lua_setglobal(g_lua, "quit");
+ update_dev_lua_state(g_lua);
+
if(lua_gettop(g_lua) != oldtop)
{
printf("internal error: unbalanced my_lua_import_soc\n");
@@ -449,13 +801,36 @@ bool my_lua_import_hwstub()
return true;
}
+soc_word_t hw_readn(lua_State *state, unsigned width, soc_word_t addr)
+{
+ switch(width)
+ {
+ case 8: return hw_read8(state, addr); break;
+ case 16: return hw_read16(state, addr); break;
+ case 32: return hw_read32(state, addr); break;
+ default: luaL_error(state, "read() has invalid width"); return 0xdeadbeef;
+ }
+}
+
+void hw_writen(lua_State *state, unsigned width, soc_word_t addr, soc_word_t val)
+{
+ switch(width)
+ {
+ case 8: hw_write8(state, addr, val); break;
+ case 16: hw_write16(state, addr, val); break;
+ case 32: hw_write32(state, addr, val); break;
+ default: luaL_error(state, "write() has invalid width");
+ }
+}
+
int my_lua_read_reg(lua_State *state)
{
int n = lua_gettop(state);
if(n != 0)
luaL_error(state, "read() takes no argument");
- soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
- lua_pushunsigned(state, hw_read32(state, addr));
+ unsigned width = lua_tounsigned(state, lua_upvalueindex(1));
+ soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2));
+ lua_pushunsigned(state, hw_readn(state, width, addr));
return 1;
}
@@ -465,8 +840,9 @@ int my_lua_write_reg(lua_State *state)
if(n != 1)
luaL_error(state, "write() takes one argument");
soc_word_t val = luaL_checkunsigned(state, 1);
- soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
- hw_write32(state, addr, val);
+ unsigned width = lua_tounsigned(state, lua_upvalueindex(1));
+ soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2));
+ hw_writen(state, width, addr, val);
return 0;
}
@@ -475,10 +851,11 @@ int my_lua_read_field(lua_State *state)
int n = lua_gettop(state);
if(n != 0)
luaL_error(state, "read() takes no argument");
- soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
- soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2));
- soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3));
- lua_pushunsigned(state, (hw_read32(state, addr) >> shift) & mask);
+ unsigned width = lua_tounsigned(state, lua_upvalueindex(1));
+ soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2));
+ soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(3));
+ soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(4));
+ lua_pushunsigned(state, (hw_readn(state, width, addr) >> shift) & mask);
return 1;
}
@@ -487,17 +864,18 @@ int my_lua_write_field(lua_State *state)
int n = lua_gettop(state);
if(n != 0 && n!= 1)
luaL_error(state, "write() takes one or no argument");
- soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
- soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2));
- soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3));
- char op = lua_tounsigned(state, lua_upvalueindex(5));
+ unsigned width = lua_tounsigned(state, lua_upvalueindex(1));
+ soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2));
+ soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(3));
+ soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(4));
+ char op = lua_tounsigned(state, lua_upvalueindex(6));
soc_word_t value = mask;
if(n == 1)
{
if(!lua_isnumber(state, 1) && lua_isstring(state, 1))
{
- lua_pushvalue(state, lua_upvalueindex(4));
+ lua_pushvalue(state, lua_upvalueindex(5));
lua_pushvalue(state, 1);
lua_gettable(state, -2);
if(lua_isnil(state, -1))
@@ -510,7 +888,7 @@ int my_lua_write_field(lua_State *state)
value &= mask;
}
- soc_word_t old_value = hw_read32(state, addr);
+ soc_word_t old_value = hw_readn(state, width, addr);
if(op == 'w')
value = value << shift | (old_value & ~(mask << shift));
else if(op == 's')
@@ -522,7 +900,7 @@ int my_lua_write_field(lua_State *state)
else
luaL_error(state, "write_field() internal error");
- hw_write32(state, addr, value);
+ hw_writen(state, width, addr, value);
return 0;
}
@@ -531,8 +909,9 @@ int my_lua_sct_reg(lua_State *state)
int n = lua_gettop(state);
if(n != 1)
luaL_error(state, "sct() takes one argument");
- soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
- char op = lua_tounsigned(state, lua_upvalueindex(2));
+ unsigned width = lua_tounsigned(state, lua_upvalueindex(1));
+ soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(2));
+ char op = lua_tounsigned(state, lua_upvalueindex(3));
soc_word_t mask = luaL_checkunsigned(state, 1);
soc_word_t value = hw_read32(state, addr);
@@ -545,7 +924,7 @@ int my_lua_sct_reg(lua_State *state)
else
luaL_error(state, "sct() internal error");
- hw_write32(state, addr, value);
+ hw_writen(state, width, addr, value);
return 0;
}
@@ -590,11 +969,12 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field)
/* lua stack: <field table> ... */
/** create read routine */
+ lua_pushunsigned(g_lua, field.reg().get()->width);
lua_pushunsigned(g_lua, addr);
lua_pushunsigned(g_lua, f->pos);
lua_pushunsigned(g_lua, local_bitmask);
- /* lua stack: <local_bm> <pos> <addr> <field table> ... */
- lua_pushcclosure(g_lua, my_lua_read_field, 3);
+ /* lua stack: <local_bm> <pos> <addr> <width> <field table> ... */
+ lua_pushcclosure(g_lua, my_lua_read_field, 4);
/* lua stack: <my_lua_read_field> <field table> ... */
lua_setfield(g_lua, -2, "read");
/* lua stack: <field table> ... */
@@ -604,15 +984,16 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field)
static const char arg[] = {'w', 's', 'c', 't'};
for(int i = 0; i < 4; i++)
{
+ lua_pushunsigned(g_lua, field.reg().get()->width);
lua_pushunsigned(g_lua, addr);
lua_pushunsigned(g_lua, f->pos);
lua_pushunsigned(g_lua, local_bitmask);
- /* lua stack: <local_bm> <pos> <addr> <field table> ... */
- lua_pushvalue(g_lua, -4);
- /* lua stack: <field table> <local_bm> <pos> <addr> <field table> ... */
+ /* lua stack: <local_bm> <pos> <addr> <width> <field table> ... */
+ lua_pushvalue(g_lua, -5);
+ /* lua stack: <field table> <local_bm> <pos> <addr> <width> <field table> ... */
lua_pushunsigned(g_lua, arg[i]);
- /* lua stack: <'wsct'> <field table> <local_bm> <pos> <addr> <field table> ... */
- lua_pushcclosure(g_lua, my_lua_write_field, 5);
+ /* lua stack: <'wsct'> <field table> <local_bm> <pos> <addr> <width> <field table> ... */
+ lua_pushcclosure(g_lua, my_lua_write_field, 6);
/* lua stack: <my_lua_write_field> <field table> ... */
lua_setfield(g_lua, -2, name[i]);
/* lua stack: <field table> ... */
@@ -633,22 +1014,25 @@ void my_lua_create_field(soc_addr_t addr, soc_desc::field_ref_t field)
}
/* lua stack on entry/exit: <inst table> */
-void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg)
+void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg,
+ bool in_variant = false)
{
if(!reg.valid())
return;
/** create read/write routine */
+ lua_pushunsigned(g_lua, reg.get()->width);
lua_pushunsigned(g_lua, addr);
- /* lua stack: <addr> <inst table> */
- lua_pushcclosure(g_lua, my_lua_read_reg, 1);
+ /* lua stack: <addr> <width> <inst table> */
+ lua_pushcclosure(g_lua, my_lua_read_reg, 2);
/* lua stack: <my_lua_read_reg> <inst table> */
lua_setfield(g_lua, -2, "read");
/* lua stack: <inst table> */
+ lua_pushunsigned(g_lua, reg.get()->width);
lua_pushunsigned(g_lua, addr);
- /* lua stack: <addr> <inst table> */
- lua_pushcclosure(g_lua, my_lua_write_reg, 1);
- /* lua stack: <my_lua_read_reg> <inst table> */
+ /* lua stack: <addr> <width> <inst table> */
+ lua_pushcclosure(g_lua, my_lua_write_reg, 2);
+ /* lua stack: <my_lua_write_reg> <inst table> */
lua_setfield(g_lua, -2, "write");
/* lua stack: <inst table> */
@@ -657,16 +1041,36 @@ void my_lua_create_reg(soc_addr_t addr, soc_desc::register_ref_t reg)
static const char arg[] = {'s', 'c', 't'};
for(int i = 0; i < 3; i++)
{
+ lua_pushunsigned(g_lua, reg.get()->width);
lua_pushunsigned(g_lua, addr);
- /* lua stack: <addr> <inst table> */
+ /* lua stack: <addr> <width> <inst table> */
lua_pushunsigned(g_lua, arg[i]);
- /* lua stack: <'s'/'c'/'t'> <addr> <inst table> */
- lua_pushcclosure(g_lua, my_lua_sct_reg, 2);
+ /* lua stack: <'s'/'c'/'t'> <addr> <width> <inst table> */
+ lua_pushcclosure(g_lua, my_lua_sct_reg, 3);
/* lua stack: <my_lua_sct_reg> <inst table> */
lua_setfield(g_lua, -2, name[i]);
/* lua stack: <inst table> */
}
+ /** create variants */
+ if(!in_variant)
+ {
+ for(auto v : reg.variants())
+ {
+ /** create a new table */
+ lua_newtable(g_lua);
+ /* lua stack: <instance table> <parent table> */
+ /** create register */
+ my_lua_create_reg(addr + v.offset(), reg, true);
+ /** register table */
+ /* lua stack: <instance table> <parent table> */
+ std::string varname = v.type();
+ for(size_t i = 0; i < varname.size(); i++)
+ varname[i] = toupper(varname[i]);
+ lua_setfield(g_lua, -2, varname.c_str());
+ }
+ }
+
/** create fields */
std::vector< soc_desc::field_ref_t > fields = reg.fields();
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)
void usage(void)
{
- printf("hwstub_tool, compiled with hwstub protocol %d.%d\n",
+ printf("shell, compiled with hwstub protocol %d.%d\n",
HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR);
printf("\n");
- printf("usage: hwstub_tool [options] <soc desc files>\n");
+ printf("usage: shell [options] <soc desc files>\n");
printf("options:\n");
- printf(" --help/-? Display this help\n");
- printf(" --quiet/-q Quiet non-command messages\n");
- printf(" -i <init> Set lua init file (default is init.lua)\n");
- printf(" -e <cmd> Execute <cmd> at startup\n");
- printf(" -f <file> Execute <file> at startup\n");
+ printf(" --help/-? Display this help\n");
+ printf(" --quiet/-q Quiet non-command messages\n");
+ printf(" --verbose/-v Verbose output\n");
+ printf(" -i <init> Set lua init file (default is init.lua)\n");
+ printf(" -e <cmd> Execute <cmd> at startup\n");
+ printf(" -f <file> Execute <file> at startup\n");
+ printf(" --dev/-d <uri> Device URI\n");
+ printf(" --debug-rw Print read/write\n");
printf("Relative order of -e and -f commands are preserved.\n");
- printf("They are executed after init file.\n");
+ printf("Unless specified, the shell will load soc desc in regtools/desc/\n");
+ //usage_uri(stdout);
exit(1);
}
enum exec_type { exec_cmd, exec_file };
+void do_signal(int sig)
+{
+ g_exit = true;
+}
+
+void load_std_desc(std::vector< soc_desc::soc_t >& socs)
+{
+ std::string path = "../../regtools/desc/";
+ DIR *dir = opendir(path.c_str());
+ if(dir == nullptr)
+ return;
+ struct dirent *entry;
+ while((entry = readdir(dir)) != nullptr)
+ {
+ /* only match regs-*.xml files but not regs-*-v1.xml */
+ std::string file = entry->d_name;
+ if(file.size() < 5 || file.substr(0, 5) != "regs-")
+ continue;
+ if(file.substr(file.size() - 4) != ".xml")
+ continue;
+ if(file.substr(file.size() - 7) == "-v1.xml")
+ continue;
+ /* prepend path */
+ file = path + "/" + file;
+ socs.push_back(soc_desc::soc_t());
+ soc_desc::error_context_t ctx;
+ if(!soc_desc::parse_xml(file, socs[socs.size() - 1], ctx))
+ {
+ printf("Cannot load description file '%s'\n", file.c_str());
+ socs.pop_back();
+ }
+ print_context(file, ctx);
+ }
+ closedir(dir);
+}
+
int main(int argc, char **argv)
{
+ const char *dev_uri = hwstub::uri::default_uri().full_uri().c_str();
+ bool verbose = false;
+
const char *lua_init = "init.lua";
std::vector< std::pair< exec_type, std::string > > startup_cmds;
// parse command line
while(1)
{
+ enum { OPT_DBG_RW = 256 };
static struct option long_options[] =
{
{"help", no_argument, 0, '?'},
{"quiet", no_argument, 0, 'q'},
+ {"init", required_argument, 0, 'i'},
+ {"startcmd", required_argument, 0, 'e'},
+ {"startfile", required_argument, 0, 'f'},
+ {"dev", required_argument, 0, 'd'},
+ {"verbose", no_argument, 0, 'v'},
+ {"debug-rw", no_argument, 0, OPT_DBG_RW},
{0, 0, 0, 0}
};
- int c = getopt_long(argc, argv, "?qi:e:f:", long_options, NULL);
+ int c = getopt_long(argc, argv, "?qi:e:f:d:v", long_options, NULL);
if(c == -1)
break;
switch(c)
@@ -863,6 +1317,15 @@ int main(int argc, char **argv)
case 'f':
startup_cmds.push_back(std::make_pair(exec_file, std::string(optarg)));
break;
+ case 'd':
+ dev_uri = optarg;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case OPT_DBG_RW:
+ g_print_mem_rw = true;
+ break;
default:
abort();
}
@@ -881,97 +1344,39 @@ int main(int argc, char **argv)
}
print_context(argv[i], ctx);
}
+ /* load standard desc files */
+ load_std_desc(socs);
- // create usb context
- libusb_context *ctx;
- libusb_init(&ctx);
- libusb_set_debug(ctx, 3);
-
- // look for device
- if(!g_quiet)
- printf("Looking for hwstub device ...\n");
- // open first device
- libusb_device **list;
- ssize_t cnt = hwstub_get_device_list(ctx, &list);
- if(cnt <= 0)
+ /* create usb context */
+ std::string errstr;
+ g_hwctx = uri::create_context(uri::uri(dev_uri), &errstr);
+ if(!g_hwctx)
{
- printf("No device found\n");
+ printf("Cannot create context: %s\n", errstr.c_str());
return 1;
}
- libusb_device_handle *handle;
- if(libusb_open(list[0], &handle) != 0)
+ if(verbose)
+ g_hwctx->set_debug(std::cout);
+ std::vector<std::shared_ptr<device>> list;
+ error ret = g_hwctx->get_device_list(list);
+ if(ret != error::SUCCESS)
{
- printf("Cannot open device\n");
+ printf("Cannot get device list: %s\n", error_string(ret).c_str());
return 1;
}
- libusb_free_device_list(list, 1);
-
- // admin stuff
- libusb_device *mydev = libusb_get_device(handle);
- if(!g_quiet)
- {
- printf("device found at %d:%d\n",
- libusb_get_bus_number(mydev),
- libusb_get_device_address(mydev));
- }
- g_hwdev = hwstub_open(handle);
- if(g_hwdev == NULL)
+ if(list.size() == 0)
{
- printf("Cannot open device!\n");
+ printf("No hwstub device detected!\n");
return 1;
}
-
- // get hwstub information
- int ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver));
- if(ret != sizeof(g_hwdev_ver))
- {
- printf("Cannot get version!\n");
- goto Lerr;
- }
- if(g_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || g_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR)
- {
- printf("Warning: this tool is possibly incompatible with your device:\n");
- printf("Device version: %d.%d.%d\n", g_hwdev_ver.bMajor, g_hwdev_ver.bMinor, g_hwdev_ver.bRevision);
- printf("Host version: %d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR);
- }
-
- // get memory layout information
- ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout));
- if(ret != sizeof(g_hwdev_layout))
- {
- printf("Cannot get layout: %d\n", ret);
- goto Lerr;
- }
-
- // get target
- ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_TARGET, &g_hwdev_target, sizeof(g_hwdev_target));
- if(ret != sizeof(g_hwdev_target))
- {
- printf("Cannot get target: %d\n", ret);
- goto Lerr;
- }
-
- // get STMP specific information
- if(g_hwdev_target.dID == HWSTUB_TARGET_STMP)
+ /* open first device */
+ ret = list[0]->open(g_hwdev);
+ if(ret != error::SUCCESS)
{
- ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp));
- if(ret != sizeof(g_hwdev_stmp))
- {
- printf("Cannot get stmp: %d\n", ret);
- goto Lerr;
- }
+ printf("Cannot open device: %s\n", error_string(ret).c_str());
+ return 1;
}
- // get PP specific information
- if(g_hwdev_target.dID == HWSTUB_TARGET_PP)
- {
- ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_PP, &g_hwdev_pp, sizeof(g_hwdev_pp));
- if(ret != sizeof(g_hwdev_pp))
- {
- printf("Cannot get pp: %d\n", ret);
- goto Lerr;
- }
- }
/** Init lua */
// create lua state
@@ -996,7 +1401,10 @@ int main(int argc, char **argv)
/** start interactive mode */
if(!g_quiet)
+ {
printf("Starting interactive lua session. Type 'help()' to get some help\n");
+ luaL_dostring(g_lua, "hwstub.info()");
+ }
/** run startup commands */
for(size_t i = 0; i < startup_cmds.size(); i++)
@@ -1012,14 +1420,15 @@ int main(int argc, char **argv)
printf("error: %s\n", lua_tostring(g_lua, -1));
}
+ /* intercept CTRL+C */
+ signal(SIGINT, do_signal);
// start interactive shell
luap_enter(g_lua, &g_exit);
+ lua_close(g_lua);
- Lerr:
// display log if handled
if(!g_quiet)
printf("Device log:\n");
print_log(g_hwdev);
- hwstub_release(g_hwdev);
return 1;
}
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 @@
-- init code for hwstub_tools
--
--- HELP
---
-HELP = hwstub.help
-
-function HELP:create_topic(name)
- self[name] = { create_topic = HELP.create_topic, add = HELP.add, get_topic = HELP.get_topic }
- return self[name]
-end
-
-function HELP:get_topic(name)
- return self[name]
-end
-
-function HELP:add(text)
- table.insert(self, text)
-end
-
-do
- local h = HELP:create_topic("hwstub")
- h:add("This tool uses a number of well-defined namespaces (tables) to organise its features.")
- h:add("The hwstub table contains a number of information and functions related to the tool itself.")
- h:add("Of particular interest are")
- h:add("* hwstub.host which holds host specific information.")
- h:add("* hwstub.dev which holds device specific information. See DEV")
- h:add("* hwstub.help (aka HELP) which holds the help. See HELP.");
- h:add("* hwstub.soc which holds soc specific information. See HW");
-
- h = HELP:create_topic("HELP");
- h:add("This variable redirects to hwstub.help and provides access to the help system.");
- h:add("You can enhance the help using the following methods on any topic (including HELP itself).");
- h:add("* t:create_topic(s) to create a new subtopic named s under topic t");
- h:add("* t:add(s) to add a help line to topic t");
- h:add("* t:get_topic(s) to get the subtopic s under topic t");
-
- h = HELP:create_topic("DEV");
- h:add("This variable redirects to hwstub.dev and provides direct access to the device.");
- h:add("It contains some information about the device and the following methods.");
- h:add("* read8/16/32(a) reads a 8/16/32-bit integer at address a atomically");
- h:add("* write8/16/32(a, v) writes the 8/16/32-bit integer v at address a atomically");
- h:add("* jump(a) jump to specified address");
- h:add("* call(a) call function at specified address and return to hwstub");
- h:add("* print_log() prints the device log");
-
- h = HELP:create_topic("HW");
- h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only.");
- h:add("The complete register tree can be found under HW in a well organised fashion.");
- h:add("* HW.dev points to device dev");
- h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses.");
- h:add("* HW.dev.reg points to the register reg under dev");
- h:add("* HW.dev.reg[i] points to the register regi if there are several copies.");
- h:add("* HW.dev.reg.f points to the field f under register reg.");
- h:add("* HW.dev.reg.f.v gives the value of named value v of field f.");
- h:add("* All registers can be read using HW.dev.reg.read() and written using HW.dev.reg.write(v).");
- h:add("* Register with a SCT variant also implement HW.dev.reg.set/clr/tog(v).");
- h:add("* All register field can be read using HW.dev.reg.f.read() and written using HW.dev.reg.f.write(v).");
- h:add("* Field writes can either give a integer or a named value to write(v).");
- h:add("* Register with a SCT variant also implement HW.dev.reg.f.set/clr/tog(v) with the same properties.");
- h:add("* All devices, registers and fields also have descriptions available such as addresses.");
-end
-
---
-- INFO
--
-if not hwstub.options.quiet then
+function hwstub.info()
+--- if not hwstub.options.quiet then
print("information")
print(" hwstub")
print(" version: " .. string.format("%d.%d", hwstub.host.version.major,
@@ -87,6 +27,20 @@ if not hwstub.options.quiet then
hwstub.dev.layout.stack.size, hwstub.dev.layout.stack.start))
print(" buffer: " .. string.format("%#x bytes @ %#x",
hwstub.dev.layout.buffer.size, hwstub.dev.layout.buffer.start))
+ if hwstub.dev.target.id == hwstub.dev.target.STMP then
+ print(" stmp")
+ print(" chipid: " .. string.format("%x", hwstub.dev.stmp.chipid))
+ print(" rev: " .. string.format("%d", hwstub.dev.stmp.rev))
+ print(" package: " .. string.format("%d", hwstub.dev.stmp.package))
+ elseif hwstub.dev.target.id == hwstub.dev.target.PP then
+ print(" pp")
+ print(" chipid: " .. string.format("%x", hwstub.dev.pp.chipid))
+ print(" rev: " .. string.format("%d", hwstub.dev.pp.rev))
+ elseif hwstub.dev.target.id == hwstub.dev.target.JZ then
+ print(" jz")
+ print(" chipid: " .. string.format("%x", hwstub.dev.jz.chipid))
+ print(" revision: " .. string.format("%c", hwstub.dev.jz.rev))
+ end
end
--
@@ -111,4 +65,12 @@ function hwstub.mdelay(msec)
hwstub.udelay(msec * 1000)
end
+require "lua/help"
require "lua/load"
+
+function init()
+ LOAD.init()
+end
+
+-- first time init
+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 @@
ATJ = {}
-hwstub.soc:select("atj213x")
+function ATJ.init()
+ hwstub.soc:select("atj213x")
+end
+
require "atj/gpio"
require "atj/lcm"
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 @@
+--
+-- HELP
+--
+HELP = hwstub.help
+
+function HELP:create_topic(name)
+ self[name] = { create_topic = HELP.create_topic, add = HELP.add, get_topic = HELP.get_topic }
+ return self[name]
+end
+
+function HELP:get_topic(name)
+ return self[name]
+end
+
+function HELP:add(text)
+ table.insert(self, text)
+end
+
+do
+ local h = HELP:create_topic("hwstub")
+ h:add("This tool uses a number of well-defined namespaces (tables) to organise its features.")
+ h:add("The hwstub table contains a number of information and functions related to the tool itself.")
+ h:add("Of particular interest are")
+ h:add("* hwstub.host which holds host specific information.")
+ h:add("* hwstub.dev which holds device specific information. See DEV")
+ h:add("* hwstub.help (aka HELP) which holds the help. See HELP.");
+ h:add("* hwstub.soc which holds soc specific information. See HW");
+
+ h = HELP:create_topic("HELP");
+ h:add("This variable redirects to hwstub.help and provides access to the help system.");
+ h:add("You can enhance the help using the following methods on any topic (including HELP itself).");
+ h:add("* t:create_topic(s) to create a new subtopic named s under topic t");
+ h:add("* t:add(s) to add a help line to topic t");
+ h:add("* t:get_topic(s) to get the subtopic s under topic t");
+
+ h = HELP:create_topic("DEV");
+ h:add("This variable redirects to hwstub.dev and provides direct access to the device.");
+ h:add("It contains some information about the device and the following methods.");
+ h:add("* read8/16/32(a) reads a 8/16/32-bit integer at address a atomically");
+ h:add("* write8/16/32(a, v) writes the 8/16/32-bit integer v at address a atomically");
+ h:add("* jump(a) jump to specified address");
+ h:add("* call(a) call function at specified address and return to hwstub");
+ h:add("* print_log() prints the device log");
+
+ h = HELP:create_topic("HW");
+ h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only.");
+ h:add("The complete register tree can be found under HW in a well organised fashion.");
+ h:add("* HW.dev points to device dev");
+ h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses.");
+ h:add("* HW.dev.reg points to the register reg under dev");
+ h:add("* HW.dev.reg[i] points to the register regi if there are several copies.");
+ h:add("* HW.dev.reg.f points to the field f under register reg.");
+ h:add("* HW.dev.reg.f.v gives the value of named value v of field f.");
+ h:add("* All registers can be read using HW.dev.reg.read() and written using HW.dev.reg.write(v).");
+ h:add("* Register with a SCT variant also implement HW.dev.reg.set/clr/tog(v).");
+ h:add("* All register field can be read using HW.dev.reg.f.read() and written using HW.dev.reg.f.write(v).");
+ h:add("* Field writes can either give a integer or a named value to write(v).");
+ h:add("* Register with a SCT variant also implement HW.dev.reg.f.set/clr/tog(v) with the same properties.");
+ h:add("* All devices, registers and fields also have descriptions available such as addresses.");
+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 @@
+---
+--- Chip Identification
+---
+JZ = { info = {} }
+
+local h = HELP:create_topic("JZ")
+h:add("This table contains the abstraction of the different device blocks for the JZ.")
+h:add("It allows one to use higher-level primitives rather than poking at register directly.")
+
+hh = h:create_topic("debug")
+hh:add("STMP.debug(...) prints some debug output if JZ.debug_on is true and does nothing otherwise.")
+
+JZ.debug_on = false
+
+function STMP.debug(...)
+ if STMP.debug_on then print(...) end
+end
+
+-- init
+function JZ.init()
+ local desc = string.format("jz%04x%c", hwstub.dev.jz.chipid, hwstub.dev.jz.rev)
+ desc = desc:lower()
+ if not hwstub.soc:select(desc) then
+ print("Looking for soc " .. desc .. ": not found. Please load a soc by hand.")
+ end
+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 @@
package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path
-
-if hwstub.dev.target.id == hwstub.dev.target.STMP then
- require "stmp"
-elseif hwstub.dev.target.id == hwstub.dev.target.PP then
- require "pp"
-elseif hwstub.dev.target.id == hwstub.dev.target.RK27 then
- require "rk27xx"
-elseif hwstub.dev.target.id == hwstub.dev.target.ATJ then
- require "atj"
-end
-
+require "stmp"
+require "pp"
+require "rk27xx"
+require "atj"
+require "jz"
require "hwlib"
require "dumper"
+
+LOAD = {}
+
+function LOAD.init()
+ if hwstub.dev.target.id == hwstub.dev.target.STMP then
+ STMP.init()
+ elseif hwstub.dev.target.id == hwstub.dev.target.PP then
+ PP.init()
+ elseif hwstub.dev.target.id == hwstub.dev.target.RK27 then
+ RK27XX.init()
+ elseif hwstub.dev.target.id == hwstub.dev.target.ATJ then
+ ATJ.init()
+ elseif hwstub.dev.target.id == hwstub.dev.target.JZ then
+ JZ.init()
+ end
+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()
return hwstub.dev.pp.chipid >= 0x5000 and hwstub.dev.pp.chipid < 0x5010
end
-if PP.is_pp611x() then
- identify("PP611x (aka GoForce6110)", "pp6110", "pp6110")
-elseif PP.is_pp502x() then
- identify("PP502x", "pp502x", "pp502x")
-elseif PP.is_pp500x() then
- identify("PP500x", "pp500x", "pp500x")
-else
- print(string.format("Unable to identify this chip as a PP: chipid=0x%x", hwstub.dev.pp.chipid));
-end
-
hh = h:create_topic("debug")
hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does nothing otherwise.")
@@ -66,6 +56,17 @@ hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does n
PP.debug_on = false
-if PP.info.chip ~= nil then
- require "pp/gpio"
+-- init
+function PP.init()
+ if PP.is_pp611x() then
+ identify("PP611x (aka GoForce6110)", "pp6110", "pp6110")
+ elseif PP.is_pp502x() then
+ identify("PP502x", "pp502x", "pp502x")
+ elseif PP.is_pp500x() then
+ identify("PP500x", "pp500x", "pp500x")
+ else
+ print(string.format("Unable to identify this chip as a PP: chipid=0x%x", hwstub.dev.pp.chipid));
+ end
end
+
+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 @@
RK27XX = {}
-hwstub.soc:select("rk27xx")
-require 'rk27xx/lcdif'
+function RK27XX.init()
+ hwstub.soc:select("rk27xx")
+end
+
+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 @@
---
--- Chip Identification
---
-
STMP = { info = {} }
local h = HELP:create_topic("STMP")
@@ -49,18 +48,6 @@ function STMP.is_stmp3600()
return hwstub.dev.stmp.chipid >= 0x3600 and hwstub.dev.stmp.chipid < 0x3700
end
-if STMP.is_imx233() then
- identify("STMP3780 (aka i.MX233)", "imx233", "imx233")
-elseif STMP.is_stmp3700() then
- identify("STMP3700", "stmp3700", "stmp3700")
-elseif STMP.is_stmp3770() then
- identify("STMP3770", "stmp3770", "stmp3700")
-elseif STMP.is_stmp3600() then
- identify("STMP3600", "stmp3600", "stmp3600")
-else
- print(string.format("Unable to identify this chip as a STMP: chipid=0x%x", hwstub.dev.stmp.chipid));
-end
-
hh = h:create_topic("debug")
hh:add("STMP.debug(...) prints some debug output if STMP.debug_on is true and does nothing otherwise.")
@@ -70,11 +57,24 @@ function STMP.debug(...)
if STMP.debug_on then print(...) end
end
-if STMP.info.chip ~= nil then
- require "stmp/digctl"
- require "stmp/pinctrl"
- require "stmp/lcdif"
- require "stmp/pwm"
- require "stmp/clkctrl"
- require "stmp/i2c"
-end \ No newline at end of file
+-- init
+function STMP.init()
+ if STMP.is_imx233() then
+ identify("STMP3780 (aka i.MX233)", "imx233", "imx233")
+ elseif STMP.is_stmp3700() then
+ identify("STMP3700", "stmp3700", "stmp3700")
+ elseif STMP.is_stmp3770() then
+ identify("STMP3770", "stmp3770", "stmp3700")
+ elseif STMP.is_stmp3600() then
+ identify("STMP3600", "stmp3600", "stmp3600")
+ else
+ print(string.format("Unable to identify this chip as a STMP: chipid=0x%x", hwstub.dev.stmp.chipid));
+ end
+end
+
+require "stmp/digctl"
+require "stmp/pinctrl"
+require "stmp/lcdif"
+require "stmp/pwm"
+require "stmp/clkctrl"
+require "stmp/i2c" \ No newline at end of file