mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
etherbone: clean up ohwr dissector, Python model checked against it
This commit is contained in:
parent
5728f61f3a
commit
02bfc0a5a8
3 changed files with 320 additions and 101 deletions
260
liteeth/core/etherbone/dissector/bit.lua
Normal file
260
liteeth/core/etherbone/dissector/bit.lua
Normal file
|
@ -0,0 +1,260 @@
|
|||
--[[---------------
|
||||
LuaBit v0.4
|
||||
-------------------
|
||||
a bitwise operation lib for lua.
|
||||
|
||||
http://luaforge.net/projects/bit/
|
||||
|
||||
How to use:
|
||||
-------------------
|
||||
bit.bnot(n) -- bitwise not (~n)
|
||||
bit.band(m, n) -- bitwise and (m & n)
|
||||
bit.bor(m, n) -- bitwise or (m | n)
|
||||
bit.bxor(m, n) -- bitwise xor (m ^ n)
|
||||
bit.brshift(n, bits) -- right shift (n >> bits)
|
||||
bit.blshift(n, bits) -- left shift (n << bits)
|
||||
bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)
|
||||
|
||||
Please note that bit.brshift and bit.blshift only support number within
|
||||
32 bits.
|
||||
|
||||
2 utility functions are provided too:
|
||||
bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
|
||||
-- high bits first
|
||||
bit.tonumb(bit_tbl) -- convert a bit table into a number
|
||||
-------------------
|
||||
|
||||
Under the MIT license.
|
||||
|
||||
copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
|
||||
--]]---------------
|
||||
|
||||
do
|
||||
|
||||
------------------------
|
||||
-- bit lib implementions
|
||||
|
||||
local function check_int(n)
|
||||
-- checking not float
|
||||
if(n - math.floor(n) > 0) then
|
||||
error("trying to use bitwise operation on non-integer!")
|
||||
end
|
||||
end
|
||||
|
||||
local function to_bits(n)
|
||||
check_int(n)
|
||||
if(n < 0) then
|
||||
-- negative
|
||||
return to_bits(bit.bnot(math.abs(n)) + 1)
|
||||
end
|
||||
-- to bits table
|
||||
local tbl = {}
|
||||
local cnt = 1
|
||||
while (n > 0) do
|
||||
local last = math.mod(n,2)
|
||||
if(last == 1) then
|
||||
tbl[cnt] = 1
|
||||
else
|
||||
tbl[cnt] = 0
|
||||
end
|
||||
n = (n-last)/2
|
||||
cnt = cnt + 1
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function tbl_to_number(tbl)
|
||||
local n = table.getn(tbl)
|
||||
|
||||
local rslt = 0
|
||||
local power = 1
|
||||
for i = 1, n do
|
||||
rslt = rslt + tbl[i]*power
|
||||
power = power*2
|
||||
end
|
||||
|
||||
return rslt
|
||||
end
|
||||
|
||||
local function expand(tbl_m, tbl_n)
|
||||
local big = {}
|
||||
local small = {}
|
||||
if(table.getn(tbl_m) > table.getn(tbl_n)) then
|
||||
big = tbl_m
|
||||
small = tbl_n
|
||||
else
|
||||
big = tbl_n
|
||||
small = tbl_m
|
||||
end
|
||||
-- expand small
|
||||
for i = table.getn(small) + 1, table.getn(big) do
|
||||
small[i] = 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function bit_or(m, n)
|
||||
local tbl_m = to_bits(m)
|
||||
local tbl_n = to_bits(n)
|
||||
expand(tbl_m, tbl_n)
|
||||
|
||||
local tbl = {}
|
||||
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
||||
for i = 1, rslt do
|
||||
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
|
||||
tbl[i] = 0
|
||||
else
|
||||
tbl[i] = 1
|
||||
end
|
||||
end
|
||||
|
||||
return tbl_to_number(tbl)
|
||||
end
|
||||
|
||||
local function bit_and(m, n)
|
||||
local tbl_m = to_bits(m)
|
||||
local tbl_n = to_bits(n)
|
||||
expand(tbl_m, tbl_n)
|
||||
|
||||
local tbl = {}
|
||||
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
||||
for i = 1, rslt do
|
||||
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
|
||||
tbl[i] = 0
|
||||
else
|
||||
tbl[i] = 1
|
||||
end
|
||||
end
|
||||
|
||||
return tbl_to_number(tbl)
|
||||
end
|
||||
|
||||
local function bit_not(n)
|
||||
|
||||
local tbl = to_bits(n)
|
||||
local size = math.max(table.getn(tbl), 32)
|
||||
for i = 1, size do
|
||||
if(tbl[i] == 1) then
|
||||
tbl[i] = 0
|
||||
else
|
||||
tbl[i] = 1
|
||||
end
|
||||
end
|
||||
return tbl_to_number(tbl)
|
||||
end
|
||||
|
||||
local function bit_xor(m, n)
|
||||
local tbl_m = to_bits(m)
|
||||
local tbl_n = to_bits(n)
|
||||
expand(tbl_m, tbl_n)
|
||||
|
||||
local tbl = {}
|
||||
local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
|
||||
for i = 1, rslt do
|
||||
if(tbl_m[i] ~= tbl_n[i]) then
|
||||
tbl[i] = 1
|
||||
else
|
||||
tbl[i] = 0
|
||||
end
|
||||
end
|
||||
|
||||
--table.foreach(tbl, print)
|
||||
|
||||
return tbl_to_number(tbl)
|
||||
end
|
||||
|
||||
local function bit_rshift(n, bits)
|
||||
check_int(n)
|
||||
|
||||
local high_bit = 0
|
||||
if(n < 0) then
|
||||
-- negative
|
||||
n = bit_not(math.abs(n)) + 1
|
||||
high_bit = 2147483648 -- 0x80000000
|
||||
end
|
||||
|
||||
for i=1, bits do
|
||||
n = n/2
|
||||
n = bit_or(math.floor(n), high_bit)
|
||||
end
|
||||
return math.floor(n)
|
||||
end
|
||||
|
||||
-- logic rightshift assures zero filling shift
|
||||
local function bit_logic_rshift(n, bits)
|
||||
check_int(n)
|
||||
if(n < 0) then
|
||||
-- negative
|
||||
n = bit_not(math.abs(n)) + 1
|
||||
end
|
||||
for i=1, bits do
|
||||
n = n/2
|
||||
end
|
||||
return math.floor(n)
|
||||
end
|
||||
|
||||
local function bit_lshift(n, bits)
|
||||
check_int(n)
|
||||
|
||||
if(n < 0) then
|
||||
-- negative
|
||||
n = bit_not(math.abs(n)) + 1
|
||||
end
|
||||
|
||||
for i=1, bits do
|
||||
n = n*2
|
||||
end
|
||||
return bit_and(n, 4294967295) -- 0xFFFFFFFF
|
||||
end
|
||||
|
||||
local function bit_xor2(m, n)
|
||||
local rhs = bit_or(bit_not(m), bit_not(n))
|
||||
local lhs = bit_or(m, n)
|
||||
local rslt = bit_and(lhs, rhs)
|
||||
return rslt
|
||||
end
|
||||
|
||||
--------------------
|
||||
-- bit lib interface
|
||||
|
||||
bit = {
|
||||
-- bit operations
|
||||
bnot = bit_not,
|
||||
band = bit_and,
|
||||
bor = bit_or,
|
||||
bxor = bit_xor,
|
||||
brshift = bit_rshift,
|
||||
blshift = bit_lshift,
|
||||
bxor2 = bit_xor2,
|
||||
blogic_rshift = bit_logic_rshift,
|
||||
|
||||
-- utility func
|
||||
tobits = to_bits,
|
||||
tonumb = tbl_to_number,
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
--[[
|
||||
for i = 1, 100 do
|
||||
for j = 1, 100 do
|
||||
if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
|
||||
error("bit.xor failed.")
|
||||
end
|
||||
end
|
||||
end
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
-- value-string maps for the protocol fields
|
||||
-- Etherbone Dissector
|
||||
-- Copyright 2013 OHWR.org
|
||||
-- Copyright 2015 EnjoyDigital (global clean up)
|
||||
|
||||
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 = {
|
||||
|
@ -25,7 +25,6 @@ local VALS_SIZE = {
|
|||
[0x0F] = "64,32,16,8 bit",
|
||||
}
|
||||
|
||||
--- Returns HEX representation of num
|
||||
function num2hex(num)
|
||||
local hexstr = '0123456789abcdef'
|
||||
local s = ''
|
||||
|
@ -46,11 +45,10 @@ function max(a, b)
|
|||
end
|
||||
end
|
||||
|
||||
-- Declare protocol
|
||||
-- declare protocol
|
||||
proto_eb = Proto("eb", "Etherbone")
|
||||
|
||||
|
||||
-- Declare its fields
|
||||
-- declare fields
|
||||
local eb = proto_eb.fields
|
||||
eb.hdr = ProtoField.uint32("eb.hdr", "Header", base.HEX)
|
||||
eb.rec = ProtoField.bytes("eb.rec", "Record ", base.HEX)
|
||||
|
@ -97,28 +95,21 @@ eb.rec_rddata16 = ProtoField.uint16("eb.rec.rddata16", "Address16 ", base.H
|
|||
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
|
||||
-- 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
|
||||
if (buf:len() < 4) then
|
||||
return 0 -- too short, go to default protocol
|
||||
end
|
||||
|
||||
|
||||
local mylen = buf:len()
|
||||
pinfo.cols.protocol = "eb"
|
||||
|
||||
-- add our packet to the tree root...we'll add fields to its subtree
|
||||
-- add packet to the tree root, fields will be added to subtree
|
||||
local t = tree:add( proto_eb, buf(0, mylen) )
|
||||
local t_hdr = t:add( eb.hdr, buf(0,4) ) -- hdr
|
||||
local t_hdr = t:add( eb.hdr, buf(0,4) )
|
||||
|
||||
local magic = num2hex(tonumber(buf(0,2):uint()))
|
||||
if(magic == "4e6f") then -- is this a valid etherbone packet ?
|
||||
if(magic == "4e6f") then
|
||||
|
||||
t_hdr:add( eb.hdr_magic, buf(0,2)) -- magic
|
||||
t_hdr:add( eb.hdr_ver, buf(2,2)) -- version
|
||||
|
@ -139,11 +130,6 @@ function proto_eb.dissector(buf, pinfo, tree)
|
|||
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())
|
||||
|
@ -158,11 +144,6 @@ function proto_eb.dissector(buf, pinfo, tree)
|
|||
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
|
||||
|
@ -235,30 +216,8 @@ function proto_eb.dissector(buf, pinfo, tree)
|
|||
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
|
||||
-- register eb protocol on UDP port 20000
|
||||
local tab = DissectorTable.get("udp.port")
|
||||
tab:add(60368, proto_eb)
|
||||
tab:add(8183, proto_eb)
|
||||
tab:add(20000, proto_eb)
|
|
@ -262,7 +262,7 @@ if __name__ == "__main__":
|
|||
# Send packet over UDP to check against Wireshark dissector
|
||||
import socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.sendto(bytes(packet), ("192.168.1.1", 60368))
|
||||
sock.sendto(bytes(packet), ("192.168.1.1", 20000))
|
||||
|
||||
packet = EtherbonePacket(packet)
|
||||
packet.decode()
|
||||
|
|
Loading…
Reference in a new issue