4 %include <lua_typemap.i>
5 %include "std_string.i"
6 %include "lua_typeinfo.i"
10 #include "virt/vdevice.h"
11 #include "virt/vbus_factory.h"
12 #include "hw_device.h"
15 static int is_lua_propval(lua_State *L, int idx)
17 if (lua_isnumber(L, idx))
19 if (lua_isstring(L, idx))
24 static Hw::Device::Prop_val to_lua_propval(lua_State *L, int idx)
26 if (lua_isnumber(L, idx))
27 return Hw::Device::Prop_val(lua_tointeger(L, idx));
28 else if (lua_isstring(L, idx))
29 return Hw::Device::Prop_val(lua_tostring(L, idx));
33 int luaopen_Io(lua_State *);
34 int add_vbus(Vi::Device *dev);
35 void dump_devs(Device *d);
39 %apply SWIG_BIGUINT { Resource::Addr }
40 %apply SWIG_BIGINT { Resource::Size }
42 %typemap(in,checkfn="is_lua_propval") Hw::Device::Prop_val
43 %{$1 = to_lua_propval(L, $input); %}
45 %typemap(in, checkfn="is_lua_propval") Hw::Device::Prop_val const & (Hw::Device::Prop_val tmp)
46 %{tmp = to_lua_propval(L, $input); $1 = &tmp; %}
48 %ignore Resource_space;
49 %ignore Resource_list;
50 %ignore Resource_provider;
51 %ignore Root_resource;
52 %ignore Vi::Dev_feature;
53 %ignore Hw::Dev_feature;
57 %apply SWIGTYPE *DISOWN { Hw::Device *disown };
58 %apply SWIGTYPE *DISOWN { Vi::Device *disown };
59 %apply SWIGTYPE *DISOWN { Resource *disown };
62 %rename(Vi_dev_factory) Vi::Dev_factory;
63 %rename(Vi_device) Vi::Device;
64 %rename(Hw_dev_factory) Hw::Device_factory;
65 %rename(Hw_device) Hw::Device;
67 %nodefaultdtor Vi::Dev_factory;
68 %nodefaultdtor Hw::Device_factory;
73 class Generic_device : public Device
76 void add_resource(Resource *disown);
79 %extend Generic_device
81 int nresources() const
83 return self->resources()->size();
86 Resource *resource(int idx) const
88 return self->resources()->at(idx);
94 class Device : public Generic_device
97 void add_child(Device *disown);
98 void name(char const *);
99 char const *name() const;
100 Device *parent() const;
101 Device *children() const;
102 Device *next() const;
104 int add_filter(cxx::String const &, cxx::String const &);
105 int add_filter(cxx::String const &, unsigned long long);
106 int add_filter(cxx::String const &, unsigned long long, unsigned long long);
108 void dump(int) const;
114 virtual Device *vcreate() = 0;
115 virtual Device *do_match(Hw::Device *f) = 0;
117 static Device *create(std::string const &_class);
118 static Device *create(Hw::Device *f);
124 void set_name(char const *name) { self->name(name); }
128 class Device : public Generic_device
132 int set_property(char const *prop, Prop_val const &val);
133 void add_child(Device *disown);
134 void add_cid(char const *);
135 void set_name(char const *);
136 char const *name() const;
137 bool match_cid(char const *cid) const;
138 Device *parent() const;
139 Device *children() const;
140 Device *next() const;
144 void dump(int) const;
150 virtual Device *create() = 0;
151 static Device *create(char const *name);
158 Hw::Device *find_by_name(std::string const &name) const
160 for (Hw::Device::iterator c = self->begin(0);
161 c != self->end(); ++c)
162 if (name == (*c)->name())
168 Hw::Device *__getitem(std::string const &name) const
170 for (Hw::Device::iterator c = self->begin(0);
171 c != self->end(); ++c)
172 if (name == (*c)->name())
178 void __setitem(std::string const &name, Hw::Device *dev)
181 self->add_child(dev);
182 if (self->parent() || self == system_bus())
187 Hw::Device *system_bus();
188 void dump_devs(Device *d);
189 int add_vbus(Vi::Device *dev);
192 class Gpio_resource : public Resource
195 explicit Gpio_resource(Hw::Device *dev, unsigned start, unsigned end)
201 local function check_device(dev, depth, err)
202 if not Io.swig_instance_of(dev, "Generic_device *") then
203 local e = err or "expected device, got: " .. tostring(dev);
211 function Io.Res.io(start, _end, flags)
213 return Io.Resource(Io.Resource_Io_res, f, start, _end or start)
216 function Io.Res.mmio(start, _end, flags)
218 return Io.Resource(Io.Resource_Mmio_res, f, start, _end or start)
221 function Io.Res.irq(start, flags)
224 if type(start) == "table" then
231 return Io.Resource(Io.Resource_Irq_res, f, s, e)
236 function Io.Dt.add_child(parent, name, dev, idx)
237 parent:add_child(dev)
238 if dev.plugin and (parent:parent() or swig_equals(parent, Io.system_bus())) then
241 if type(name) == "string" then
243 name = name .. '[' .. idx ..']'
249 function Io.Dt.add_children(parent, bus_func)
250 check_device(parent, 2);
251 if type(bus_func) == "function" then
253 local my_env = getfenv(1)
254 local old_ENV = my_env._ENV;
256 setmetatable(d, { __index = my_env })
259 my_env._ENV = old_ENV;
260 Io.Dt.add_device_data(parent, d)
265 function Io.Dt.iterator(dev, max_depth)
266 local max_d = (max_depth or 0) + dev:depth()
276 local cc = c:children()
277 if max_d > cd and cc then
287 if (not p) or swig_equals(p, start) then
299 function Io.Dt.match_cids(self, ...)
301 for _, v in ipairs{...} do
302 if self:match_cid(v) then
321 Io.Dt.MAX_DEPTH = 1000
323 function Io.Dt.Range(start, stop)
324 return { range = true, start, stop }
327 function Io.Dt.match(self, ...)
329 for t,v in pairs(Io.Dt.PCI_cc) do
330 for i, cid in ipairs(cids) do
331 cids[i] = cid:gsub("(PCI/"..t..")", "PCI/" .. v)
336 for d in self:devices(Io.Dt.MAX_DEPTH) do
337 if d:match_cids(unpack(cids)) then
344 function Io.Dt.device(self, path)
345 for i in string.gmatch(path, "([^%./]+)%.*") do
346 self = self:find_by_name(i)
354 function Io.Dt.resources(self)
355 local n = self:nresources()
358 if c >= n then return nil end
360 return self:resource(c - 1)
364 local hwfn = Io.swig_class("Hw_device")[".fn"]
365 local vifn = Io.swig_class("Vi_device")[".fn"]
369 resources = Io.Dt.resources,
370 devices = Io.Dt.iterator,
371 match_cids = Io.Dt.match_cids,
373 device = Io.Dt.device
376 for name, func in pairs(dev_fns) do
381 function vifn:add_filter_val(tag, value)
382 if type(value) == "table" and value.range then
383 return self:add_filter(tag, value[1], value[2])
384 elseif type(value) == "table" then
385 for _, v in ipairs(value) do
386 local res = self:add_filter_val(tag, v)
393 return self:add_filter(tag, value)
397 local add_child = Io.Dt.add_child
399 local function handle_device_member(dev, val, name)
400 if name == "compatible" then
401 if type(val) == "table" then
402 for k, v in ipairs(val) do
405 elseif type(val) == "string" then
409 elseif type(val) == "table" then
410 for i, v in pairs(val) do
411 handle_device_member(dev, v, name .. '[' .. i .. ']')
414 elseif Io.swig_instance_of(val, "Resource *") then
416 dev:add_resource(val)
418 elseif Io.swig_instance_of(val, "Generic_device *") then
419 add_child(dev, name, val)
422 local sp = dev.set_property
423 if type(sp) == "function" then
428 print("ERROR: cannot handle device member: " .. tostring(name) .. ": " .. tostring(val))
431 function Io.Dt.add_resource(dev, res)
432 if not Io.swig_instance_of(dev, "Generic_device *") then
433 error("expected a device got: " .. tostring(dev), 2)
435 if not Io.swig_instance_of(res, "Resource *") then
436 error("expected a resource got: " .. tostring(res), 2)
438 dev:add_resource(res)
441 function Io.Dt.add_device_data(dev, data)
443 for i, v in ipairs(data) do
444 handle_device_member(dev, v, i)
447 for k, v in pairs(data) do
448 if (type(k) ~= "number") or (k > maxi) then
449 handle_device_member(dev, v, k)
454 local set_dev_data = Io.Dt.add_device_data
455 local add_children = Io.Dt.add_children
459 setmetatable(Io.Hw, { __index = function (self, t)
460 return function (data)
461 local b = check_device(Io.Hw_dev_factory_create(t), 3, "could not create device: " .. t)
462 if type(data) == "function" then
463 add_children(b, data)
464 elseif type(data) == "table" then
465 set_dev_data(b, data)
471 function Io.hw_add_devices(data)
472 local sb = Io.system_bus()
473 local dtype = type(data)
474 if dtype == 'function' then
475 Io.Dt.add_children(sb, data)
476 elseif dtype == 'table' then
477 for n, dev in pairs(data) do
478 if type(n) == "string" then
479 dev:set_property("name", n)
490 setmetatable(Io.Vi, { __index = function (self, t)
491 return function (data)
492 local b = Io.Vi_dev_factory_create(t)
493 if type(data) == "function" then
494 add_children(b, data)
495 elseif type(data) == "table" then
496 set_dev_data(b, data)
502 function wrap(devs_, filter)
504 if type(devs_) ~= "table" then
508 for _, d in ipairs(devs) do
509 local vd = Io.Vi_dev_factory_create(d)
511 if type(filter) == "table" then
512 for tag, val in pairs(filter) do
513 local res = vd:add_filter_val(tag, val)
515 print("ERROR: applying filter expression: "..tag.."=...", debug.traceback(2))
529 local add_vbus = Io.add_vbus
531 function Io.add_vbus(name, bus)
536 function Io.add_vbusses(busses)
537 for name, bus in pairs(busses) do
538 Io.add_vbus(name, bus)