Peter Stuge wrote:
Stefan Reinauer wrote:
Since we seem to have additional filter rules for every board, BIOS, SuperIO and chipset we support, I gave it a shot and prototyped a small "object oriented device model" for our filters. So each filter could run through all registered components for a board and run the filters suited for that hardware (and only those).
How does it work now? There's a single filter with lots of different rules for each component? I think this is a good improvement then!
Yes.. The same filter function right now catches the BMC calls on the Dell 1850 and the SuperIO serial port configuration on one of the two Winbond SuperIO chips of the Kontron 986LCD-M.... This works for 5 boards, but maybe not even that when people start using SerialICE more intensely.
function superio_smsc:new(o) o = o or { } -- create object if user does not provide one setmetatable(o, self) self.__index = self return o end
I think initializers should be generic and out of the way, if possible. It would be nice to avoid having fifteen new() that all look exactly the same.
Yes, absolutely. What about this... (see attachment)
There's also a lua class library and some more or less complex implementations mentioned at http://lua-users.org/wiki/ObjectOrientedProgramming.
Stefan
-- playground --
-- -------------------------------------------------------------------- -- serialice-tools.lua generic functions
require("bit")
function printf(s,...) return io.write(s:format(...)) end
function new(s, o) o = o or { } -- create object if user does not provide one setmetatable(o, s) s.__index = s return o end
components = nil
function add(c) components = { next = components, component = c } end
-- -------------------------------------------------------------------- -- SuperIO Winbond W83627 component
superio_w83627thg = { superio_base = 0x2e; catch_serial = false; }
function superio_w83627thg:new(o) return new(self, o) end
function superio_w83627thg:init(base, catch_serial) self.superio_base = base; end
function superio_w83627thg:IO_read_filter(a,b) printf("Filter: Winbond %x, %x\n", a, self.superio_base); end
-- -------------------------------------------------------------------- -- SuperIO SMSC something else component
superio_smsc = { superio_base = 0x2e; }
function superio_smsc:new(o) return new(self, o) end
function superio_smsc:init(base) self.superio_base = base; end
function superio_smsc:IO_read_filter(a,b) printf("Filter: SMSC %x, %x\n", a, self.superio_base); end
-- -------------------------------------------------------------------- -- of course 3 superios is stupid, but it's a simple example -- add them all to our components list
first_superio = superio_w83627thg:new{superio_base=0x62} add(first_superio)
second_superio = superio_smsc:new{} add(second_superio)
third_superio = superio_smsc:new{superio_base=0x4e} -- third_superio:init(0x48) add(third_superio)
-- -------------------------------------------------------------------- -- a filter could look like this
local current_component = components
while current_component do current_component.component:IO_read_filter(23, 14) current_component = current_component.next end
-- -------------------------------------------------------------------- -- sample output: -- -- Filter: SMSC 17, 4e -- Filter: SMSC 17, 2e -- Filter: Winbond 17, 62 --