forked from len0rd/rockbox
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
This commit is contained in:
parent
a2f4c5201d
commit
f6c61eb11a
9 changed files with 740 additions and 266 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,71 +1,11 @@
|
||||||
-- init code for hwstub_tools
|
-- 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
|
-- INFO
|
||||||
--
|
--
|
||||||
|
|
||||||
if not hwstub.options.quiet then
|
function hwstub.info()
|
||||||
|
--- if not hwstub.options.quiet then
|
||||||
print("information")
|
print("information")
|
||||||
print(" hwstub")
|
print(" hwstub")
|
||||||
print(" version: " .. string.format("%d.%d", hwstub.host.version.major,
|
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))
|
hwstub.dev.layout.stack.size, hwstub.dev.layout.stack.start))
|
||||||
print(" buffer: " .. string.format("%#x bytes @ %#x",
|
print(" buffer: " .. string.format("%#x bytes @ %#x",
|
||||||
hwstub.dev.layout.buffer.size, hwstub.dev.layout.buffer.start))
|
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
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -111,4 +65,12 @@ function hwstub.mdelay(msec)
|
||||||
hwstub.udelay(msec * 1000)
|
hwstub.udelay(msec * 1000)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require "lua/help"
|
||||||
require "lua/load"
|
require "lua/load"
|
||||||
|
|
||||||
|
function init()
|
||||||
|
LOAD.init()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- first time init
|
||||||
|
init()
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
ATJ = {}
|
ATJ = {}
|
||||||
|
|
||||||
hwstub.soc:select("atj213x")
|
function ATJ.init()
|
||||||
|
hwstub.soc:select("atj213x")
|
||||||
|
end
|
||||||
|
|
||||||
require "atj/gpio"
|
require "atj/gpio"
|
||||||
require "atj/lcm"
|
require "atj/lcm"
|
||||||
require "atj/dsp"
|
require "atj/dsp"
|
||||||
|
|
60
utils/hwstub/tools/lua/help.lua
Normal file
60
utils/hwstub/tools/lua/help.lua
Normal file
|
@ -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
|
26
utils/hwstub/tools/lua/jz.lua
Normal file
26
utils/hwstub/tools/lua/jz.lua
Normal file
|
@ -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
|
|
@ -1,14 +1,24 @@
|
||||||
package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path
|
package.path = string.sub(string.gsub(debug.getinfo(1).source, "load.lua", "?.lua"),2) .. ";" .. package.path
|
||||||
|
require "stmp"
|
||||||
if hwstub.dev.target.id == hwstub.dev.target.STMP then
|
require "pp"
|
||||||
require "stmp"
|
require "rk27xx"
|
||||||
elseif hwstub.dev.target.id == hwstub.dev.target.PP then
|
require "atj"
|
||||||
require "pp"
|
require "jz"
|
||||||
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 "hwlib"
|
require "hwlib"
|
||||||
require "dumper"
|
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
|
|
@ -42,16 +42,6 @@ function PP.is_pp500x()
|
||||||
return hwstub.dev.pp.chipid >= 0x5000 and hwstub.dev.pp.chipid < 0x5010
|
return hwstub.dev.pp.chipid >= 0x5000 and hwstub.dev.pp.chipid < 0x5010
|
||||||
end
|
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 = h:create_topic("debug")
|
||||||
hh:add("PP.debug(...) prints some debug output if PP.debug_on is true and does nothing otherwise.")
|
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
|
PP.debug_on = false
|
||||||
|
|
||||||
if PP.info.chip ~= nil then
|
-- init
|
||||||
require "pp/gpio"
|
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
|
end
|
||||||
|
|
||||||
|
require "pp/gpio"
|
||||||
|
|
|
@ -4,5 +4,8 @@
|
||||||
|
|
||||||
RK27XX = {}
|
RK27XX = {}
|
||||||
|
|
||||||
hwstub.soc:select("rk27xx")
|
function RK27XX.init()
|
||||||
require 'rk27xx/lcdif'
|
hwstub.soc:select("rk27xx")
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'rk27xx/lradc'
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
--- Chip Identification
|
--- Chip Identification
|
||||||
---
|
---
|
||||||
|
|
||||||
STMP = { info = {} }
|
STMP = { info = {} }
|
||||||
|
|
||||||
local h = HELP:create_topic("STMP")
|
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
|
return hwstub.dev.stmp.chipid >= 0x3600 and hwstub.dev.stmp.chipid < 0x3700
|
||||||
end
|
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 = h:create_topic("debug")
|
||||||
hh:add("STMP.debug(...) prints some debug output if STMP.debug_on is true and does nothing otherwise.")
|
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
|
if STMP.debug_on then print(...) end
|
||||||
end
|
end
|
||||||
|
|
||||||
if STMP.info.chip ~= nil then
|
-- init
|
||||||
require "stmp/digctl"
|
function STMP.init()
|
||||||
require "stmp/pinctrl"
|
if STMP.is_imx233() then
|
||||||
require "stmp/lcdif"
|
identify("STMP3780 (aka i.MX233)", "imx233", "imx233")
|
||||||
require "stmp/pwm"
|
elseif STMP.is_stmp3700() then
|
||||||
require "stmp/clkctrl"
|
identify("STMP3700", "stmp3700", "stmp3700")
|
||||||
require "stmp/i2c"
|
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
|
end
|
||||||
|
|
||||||
|
require "stmp/digctl"
|
||||||
|
require "stmp/pinctrl"
|
||||||
|
require "stmp/lcdif"
|
||||||
|
require "stmp/pwm"
|
||||||
|
require "stmp/clkctrl"
|
||||||
|
require "stmp/i2c"
|
Loading…
Add table
Add a link
Reference in a new issue