etherbone: add dissector from ohwr.org
This commit is contained in:
parent
31bdc48a57
commit
1de3bccfc8
|
@ -0,0 +1,264 @@
|
||||||
|
-- value-string maps for the protocol fields
|
||||||
|
|
||||||
|
local bit = require("bit")
|
||||||
|
|
||||||
|
local VALS_BAR = {[0x11] = "Whiskey", [0x12] = "Rum", [0x13] =
|
||||||
|
"Vodka", [0x14] = "Gin"}
|
||||||
|
local VALS_BOOL = {[0] = "False", [1] = "True"}
|
||||||
|
local VALS_RES = {[0] = "not set", [1] = "set, bad data?"}
|
||||||
|
local VALS_SIZE = {
|
||||||
|
[0x00] = "Bad Value",
|
||||||
|
[0x01] = "8 bit",
|
||||||
|
[0x02] = "16 bit",
|
||||||
|
[0x03] = "16,8 bit",
|
||||||
|
[0x04] = "32 bit",
|
||||||
|
[0x05] = "32,8 bit",
|
||||||
|
[0x06] = "32,16 bit",
|
||||||
|
[0x07] = "32,16,8 bit",
|
||||||
|
[0x08] = "64 bit",
|
||||||
|
[0x09] = "64,8 bit",
|
||||||
|
[0x0A] = "64,16 bit",
|
||||||
|
[0x0B] = "64,16,8 bit",
|
||||||
|
[0x0C] = "64,32 bit",
|
||||||
|
[0x0D] = "64,32,8 bit",
|
||||||
|
[0x0E] = "64,32,16 bit",
|
||||||
|
[0x0F] = "64,32,16,8 bit",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Returns HEX representation of num
|
||||||
|
function num2hex(num)
|
||||||
|
local hexstr = '0123456789abcdef'
|
||||||
|
local s = ''
|
||||||
|
while num > 0 do
|
||||||
|
local mod = math.fmod(num, 16)
|
||||||
|
s = string.sub(hexstr, mod+1, mod+1) .. s
|
||||||
|
num = math.floor(num / 16)
|
||||||
|
end
|
||||||
|
if s == '' then s = '0' end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function max(a, b)
|
||||||
|
if a > b then
|
||||||
|
return a
|
||||||
|
else
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Declare protocol
|
||||||
|
proto_eb = Proto("eb", "Etherbone")
|
||||||
|
|
||||||
|
|
||||||
|
-- Declare its fields
|
||||||
|
local eb = proto_eb.fields
|
||||||
|
eb.hdr = ProtoField.uint32("eb.hdr", "Header", base.HEX)
|
||||||
|
eb.rec = ProtoField.bytes("eb.rec", "Record ", base.HEX)
|
||||||
|
|
||||||
|
eb.hdr_magic = ProtoField.uint16("eb.hdr.magic", "Magic ", base.HEX, nil, 0xFFFF)
|
||||||
|
eb.hdr_ver = ProtoField.uint16("eb.hdr.ver", "Version ", base.DEC, nil, 0xF000)
|
||||||
|
eb.hdr_noreads = ProtoField.uint16("eb.hdr.noreads", "No Reads ", base.DEC, VALS_BOOL, 0x0400)
|
||||||
|
eb.hdr_proberep = ProtoField.uint16("eb.hdr.proberes", "Probe Reply ", base.DEC, VALS_BOOL, 0x0200)
|
||||||
|
eb.hdr_probereq = ProtoField.uint16("eb.hdr.probereq", "Probe Flag ", base.DEC, VALS_BOOL, 0x0100)
|
||||||
|
eb.hdr_adrs = ProtoField.uint16("eb.hdr.adrw", "Address Width ", base.DEC, VALS_SIZE , 0x00F0)
|
||||||
|
eb.hdr_ports = ProtoField.uint16("eb.hdr.portw", "Port Width ", base.DEC, VALS_SIZE , 0x000F)
|
||||||
|
|
||||||
|
eb.rec_hdr = ProtoField.uint32("eb.rec.hdr", "Header ", base.HEX)
|
||||||
|
eb.rec_writes = ProtoField.bytes("eb.rec.writes", "Writes ", base.HEX)
|
||||||
|
eb.rec_reads = ProtoField.bytes("eb.rec.reads", "Reads ", base.HEX)
|
||||||
|
|
||||||
|
eb.rec_hdr_flags = ProtoField.uint8("eb.rec.hdr.flags", "Flags ", base.HEX)
|
||||||
|
eb.rec_hdr_select = ProtoField.uint8("eb.rec.hdr.select", "Select ", base.HEX)
|
||||||
|
eb.rec_hdr_wr = ProtoField.uint8("eb.rec.hdr.wr", "Writes ", base.DEC)
|
||||||
|
eb.rec_hdr_rd = ProtoField.uint8("eb.rec.hdr.rd", "Reads ", base.DEC)
|
||||||
|
|
||||||
|
eb.rec_hdr_flags_adrcfg = ProtoField.uint8("eb.rec.hdr.flags.adrcfg", "ReplyToCfgSpace ", base.DEC, VALS_BOOL, 0x80)
|
||||||
|
eb.rec_hdr_flags_rbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFromCfgSpace ", base.DEC, VALS_BOOL, 0x40)
|
||||||
|
eb.rec_hdr_flags_rdfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "ReadFIFO ", base.DEC, VALS_BOOL, 0x20)
|
||||||
|
eb.rec_hdr_flags_dropcyc= ProtoField.uint8("eb.rec.hdr.adrcfg", "DropCycle ", base.DEC, VALS_BOOL, 0x08)
|
||||||
|
eb.rec_hdr_flags_wbacfg = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteToCfgSpace ", base.DEC, VALS_BOOL, 0x04)
|
||||||
|
eb.rec_hdr_flags_wrfifo = ProtoField.uint8("eb.rec.hdr.adrcfg", "WriteFIFO ", base.DEC, VALS_BOOL, 0x02)
|
||||||
|
|
||||||
|
eb.rec_wrsadr8 = ProtoField.uint8("eb.rec.wrsadr8", "BaseAddr8 ", base.HEX)
|
||||||
|
eb.rec_wrsadr16 = ProtoField.uint16("eb.rec.wrsadr16", "BaseAddr16 ", base.HEX)
|
||||||
|
eb.rec_wrsadr32 = ProtoField.uint32("eb.rec.wrsadr32", "BaseAddr32 ", base.HEX)
|
||||||
|
eb.rec_wrsadr64 = ProtoField.uint64("eb.rec.wrsadr64", "BaseAddr64 ", base.HEX)
|
||||||
|
eb.rec_wrdata8 = ProtoField.uint8("eb.rec.wrdata8", "Value8 ", base.HEX)
|
||||||
|
eb.rec_wrdata16 = ProtoField.uint16("eb.rec.wrdata16", "Value16 ", base.HEX)
|
||||||
|
eb.rec_wrdata32 = ProtoField.uint32("eb.rec.wrdata32", "Value32 ", base.HEX)
|
||||||
|
eb.rec_wrdata64 = ProtoField.uint64("eb.rec.wrdata64", "Value64 ", base.HEX)
|
||||||
|
|
||||||
|
eb.rec_rdbadr8 = ProtoField.uint8("eb.rec.rdbadr8", "ReplyAddr8 ", base.HEX)
|
||||||
|
eb.rec_rdbadr16 = ProtoField.uint16("eb.rec.rdbadr16", "ReplyAddr16 ", base.HEX)
|
||||||
|
eb.rec_rdbadr32 = ProtoField.uint32("eb.rec.rdbadr32", "ReplyAddr32 ", base.HEX)
|
||||||
|
eb.rec_rdbadr64 = ProtoField.uint64("eb.rec.rdbadr64", "ReplyAddr64 ", base.HEX)
|
||||||
|
eb.rec_rddata8 = ProtoField.uint8("eb.rec.rddata8", "Address8 ", base.HEX)
|
||||||
|
eb.rec_rddata16 = ProtoField.uint16("eb.rec.rddata16", "Address16 ", base.HEX)
|
||||||
|
eb.rec_rddata32 = ProtoField.uint32("eb.rec.rddata32", "Address32 ", base.HEX)
|
||||||
|
eb.rec_rddata64 = ProtoField.uint64("eb.rec.rddata64", "Address64 ", base.HEX)
|
||||||
|
|
||||||
|
-- Define the dissector
|
||||||
|
function proto_eb.dissector(buf, pinfo, tree)
|
||||||
|
|
||||||
|
-- min length, 4 for eb hdr with probe
|
||||||
|
local EXPECTED_LENGTH = 4
|
||||||
|
|
||||||
|
|
||||||
|
if (buf:len() < EXPECTED_LENGTH) then
|
||||||
|
-- not ours, let it go to default Data dissector
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local mylen = buf:len()
|
||||||
|
pinfo.cols.protocol = "eb"
|
||||||
|
|
||||||
|
-- add our packet to the tree root...we'll add fields to its subtree
|
||||||
|
local t = tree:add( proto_eb, buf(0, mylen) )
|
||||||
|
local t_hdr = t:add( eb.hdr, buf(0,4) ) -- hdr
|
||||||
|
|
||||||
|
local magic = num2hex(tonumber(buf(0,2):uint()))
|
||||||
|
if(magic == "4e6f") then -- is this a valid etherbone packet ?
|
||||||
|
|
||||||
|
t_hdr:add( eb.hdr_magic, buf(0,2)) -- magic
|
||||||
|
t_hdr:add( eb.hdr_ver, buf(2,2)) -- version
|
||||||
|
t_hdr:add( eb.hdr_noreads, buf(2,2)) -- no reads
|
||||||
|
t_hdr:add( eb.hdr_proberep, buf(2,2)) -- probe response
|
||||||
|
t_hdr:add( eb.hdr_probereq, buf(2,2)) -- probe request
|
||||||
|
|
||||||
|
t_hdr:add( eb.hdr_adrs, buf(2,2)) -- supported addr size
|
||||||
|
t_hdr:add( eb.hdr_ports, buf(2,2)) -- supported port size
|
||||||
|
|
||||||
|
local probe = tonumber(buf(2,1):uint()) % 4
|
||||||
|
if (probe == 0) then
|
||||||
|
local widths = tonumber(buf(3,1):uint())
|
||||||
|
local data_width = widths % 16
|
||||||
|
local addr_width = (widths - data_width) / 16
|
||||||
|
local alignment = max(max(addr_width, data_width), 2)
|
||||||
|
|
||||||
|
local record_alignment = max(alignment, 4)
|
||||||
|
local offset = max(alignment, 4)
|
||||||
|
|
||||||
|
--local t_foo = t:add( "Addr "..tostring(addr_width), buf(4,4))
|
||||||
|
--local t_foo = t:add( "Data "..tostring(data_width), buf(4,4))
|
||||||
|
--local t_foo = t:add( "Value Alignment "..tostring(alignment), buf(4,4))
|
||||||
|
--local t_foo = t:add( "Record Alignment "..tostring(record_alignment), buf(4,4))
|
||||||
|
|
||||||
|
local recordcnt = 0
|
||||||
|
while (offset < buf:len()) do
|
||||||
|
local wr = tonumber(buf(offset+2,1):uint())
|
||||||
|
local rd = tonumber(buf(offset+3,1):uint())
|
||||||
|
|
||||||
|
local rdadr = 0
|
||||||
|
local wradr = 0
|
||||||
|
if(rd > 0) then
|
||||||
|
rdadr = 1
|
||||||
|
end
|
||||||
|
if(wr > 0) then
|
||||||
|
wradr = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- t_rec = t:add(wr)
|
||||||
|
-- t_rec = t:add(rd)
|
||||||
|
-- t_rec = t:add(offset)
|
||||||
|
-- t_rec = t:add((1+rd+wr+rdadr+wradr)*4)
|
||||||
|
if((wr == 0) and (rd == 0)) then
|
||||||
|
offset = offset + record_alignment
|
||||||
|
else
|
||||||
|
local t_rec = t:add( "Record "..tostring(recordcnt).." (W"..tostring(wr).." R"..tostring(rd)..")", buf(offset, (record_alignment+(rd+wr+rdadr+wradr)*alignment)))
|
||||||
|
recordcnt = recordcnt + 1
|
||||||
|
|
||||||
|
local t_rec_hdr = t_rec:add( eb.rec_hdr, buf(offset,4))
|
||||||
|
local t_rec_hdr_flags = t_rec_hdr:add( eb.rec_hdr_flags, buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_adrcfg, buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_rbacfg, buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_rdfifo, buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_dropcyc , buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_wbacfg , buf(offset,1))
|
||||||
|
t_rec_hdr_flags:add( eb.rec_hdr_flags_wrfifo, buf(offset,1))
|
||||||
|
t_rec_hdr:add( eb.rec_hdr_select, buf(offset+1,1))
|
||||||
|
t_rec_hdr:add( eb.rec_hdr_wr, buf(offset+2,1))
|
||||||
|
t_rec_hdr:add( eb.rec_hdr_rd, buf(offset+3,1))
|
||||||
|
offset = offset + record_alignment
|
||||||
|
local tmp_offset
|
||||||
|
|
||||||
|
if(wr > 0) then
|
||||||
|
local t_writes = t_rec:add( eb.rec_writes, buf(offset,(1+wr)*alignment))
|
||||||
|
|
||||||
|
if addr_width==1 then t_writes:add(eb.rec_wrsadr8, buf(offset+alignment-1, 1))
|
||||||
|
elseif addr_width==2 then t_writes:add(eb.rec_wrsadr16, buf(offset+alignment-2, 2))
|
||||||
|
elseif addr_width==4 then t_writes:add(eb.rec_wrsadr32, buf(offset+alignment-4, 4))
|
||||||
|
elseif addr_width==8 then t_writes:add(eb.rec_wrsadr64, buf(offset+alignment-8, 8))
|
||||||
|
end
|
||||||
|
offset = offset + alignment
|
||||||
|
|
||||||
|
tmp_offset = offset
|
||||||
|
while (tmp_offset < offset+wr*alignment) do
|
||||||
|
if data_width==1 then t_writes:add( eb.rec_wrdata8, buf(tmp_offset+alignment-1, 1))
|
||||||
|
elseif data_width==2 then t_writes:add( eb.rec_wrdata16, buf(tmp_offset+alignment-2, 2))
|
||||||
|
elseif data_width==4 then t_writes:add( eb.rec_wrdata32, buf(tmp_offset+alignment-4, 4))
|
||||||
|
elseif data_width==8 then t_writes:add( eb.rec_wrdata64, buf(tmp_offset+alignment-8, 8))
|
||||||
|
end
|
||||||
|
tmp_offset = tmp_offset + alignment
|
||||||
|
end
|
||||||
|
offset = tmp_offset
|
||||||
|
end
|
||||||
|
|
||||||
|
if(rd > 0) then
|
||||||
|
local t_reads = t_rec:add( eb.rec_reads, buf(offset,(1+rd)*alignment))
|
||||||
|
|
||||||
|
if addr_width==1 then t_reads:add( eb.rec_rdbadr8, buf(offset+alignment-1, 1))
|
||||||
|
elseif addr_width==2 then t_reads:add( eb.rec_rdbadr16, buf(offset+alignment-2, 2))
|
||||||
|
elseif addr_width==4 then t_reads:add( eb.rec_rdbadr32, buf(offset+alignment-4, 4))
|
||||||
|
elseif addr_width==8 then t_reads:add( eb.rec_rdbadr64, buf(offset+alignment-8, 8))
|
||||||
|
end
|
||||||
|
offset = offset + alignment
|
||||||
|
|
||||||
|
tmp_offset = offset
|
||||||
|
while (tmp_offset < offset+rd*alignment) do
|
||||||
|
if addr_width==1 then t_reads:add( eb.rec_rddata8, buf(tmp_offset+alignment-1, 1))
|
||||||
|
elseif addr_width==2 then t_reads:add( eb.rec_rddata16, buf(tmp_offset+alignment-2, 2))
|
||||||
|
elseif addr_width==4 then t_reads:add( eb.rec_rddata32, buf(tmp_offset+alignment-4, 4))
|
||||||
|
elseif addr_width==8 then t_reads:add( eb.rec_rddata64, buf(tmp_offset+alignment-8, 8))
|
||||||
|
end
|
||||||
|
tmp_offset = tmp_offset + alignment
|
||||||
|
end
|
||||||
|
offset = tmp_offset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- local offset = 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- while offset <= mylen do
|
||||||
|
|
||||||
|
|
||||||
|
-- local rec = buf(offset,4)
|
||||||
|
|
||||||
|
-- if (buf:len() < EXPECTED_LENGTH + 4) then
|
||||||
|
--not ours, let it go to default Data dissector
|
||||||
|
-- return 0
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register eb protocol on UDP port 22222
|
||||||
|
local tab = DissectorTable.get("udp.port")
|
||||||
|
tab:add(60368, proto_eb)
|
||||||
|
tab:add(8183, proto_eb)
|
Loading…
Reference in New Issue