2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
12 #include "virt/vdevice.h"
17 typedef Hw::Pci::Config Config;
21 * \brief Generic virtual PCI device.
22 * This class provides the basic functionality for a device on a
23 * virtual PCI bus. Implementations may provide proxy access to a real PCI
24 * device or a completely virtualized PCI device.
29 void operator = (Pci_dev const &);
30 Pci_dev(Pci_dev const &);
33 typedef Hw::Pci::Cfg_width Cfg_width;
38 unsigned char trigger;
39 unsigned char polarity;
43 virtual int cfg_read(int reg, l4_uint32_t *v, Cfg_width) = 0;
44 virtual int cfg_write(int reg, l4_uint32_t v, Cfg_width) = 0;
45 virtual int irq_enable(Irq_info *irq) = 0;
46 virtual bool is_same_device(Pci_dev const *o) const = 0;
47 virtual ~Pci_dev() = 0;
55 * \brief A basic really virtualized PCI device.
57 class Pci_virtual_dev : public Pci_dev, public Dev_feature
62 l4_uint32_t vendor_device;
65 l4_uint32_t class_rev;
70 } __attribute__((packed));
72 Pci_cfg_header *cfg_hdr() { return (Pci_cfg_header*)_h; }
73 Pci_cfg_header const *cfg_hdr() const { return (Pci_cfg_header const *)_h; }
75 int cfg_read(int reg, l4_uint32_t *v, Cfg_width);
76 int cfg_write(int reg, l4_uint32_t v, Cfg_width);
77 bool is_same_device(Pci_dev const *o) const { return o == this; }
79 ~Pci_virtual_dev() = 0;
83 void set_host(Device *d) { _host = d; }
84 Device *host() const { return _host; }
94 Pci_virtual_dev::~Pci_virtual_dev()
100 * \brief A virtual PCI proxy for a real PCI device.
102 class Pci_proxy_dev : public Pci_dev, public virtual Dev_feature
106 Pci_proxy_dev(Hw::Pci::If *hwf);
108 int cfg_read(int reg, l4_uint32_t *v, Cfg_width);
109 int cfg_write(int reg, l4_uint32_t v, Cfg_width);
110 int irq_enable(Irq_info *irq);
112 l4_uint32_t read_bar(int bar);
113 void write_bar(int bar, l4_uint32_t v);
115 l4_uint32_t read_rom() const { return _rom; }
116 void write_rom(l4_uint32_t v);
118 int vbus_dispatch(l4_umword_t, l4_uint32_t, L4::Ipc::Iostream &)
119 { return -L4_ENOSYS; }
121 Hw::Pci::If *hwf() const { return _hwf; }
124 bool is_same_device(Pci_dev const *o) const
126 if (Pci_proxy_dev const *op = dynamic_cast<Pci_proxy_dev const *>(o))
127 return (hwf()->bus_nr() == op->hwf()->bus_nr())
128 && (hwf()->device_nr() == op->hwf()->device_nr());
132 bool match_hw_feature(const Hw::Dev_feature *f) const
133 { return f == _hwf; }
135 int dispatch(l4_umword_t, l4_uint32_t, L4::Ipc::Iostream&)
136 { return -L4_ENOSYS; }
138 void set_host(Device *d) { _host = d; }
139 Device *host() const { return _host; }
145 l4_uint32_t _vbars[6];
148 int _do_status_cmd_write(l4_uint32_t mask, l4_uint32_t value);
149 void _do_cmd_write(unsigned mask,unsigned value);
151 int _do_rom_bar_write(l4_uint32_t mask, l4_uint32_t value);
157 * \brief a basic virtual PCI bridge.
158 * This class is the base for virtual Host-to-PCI bridges,
159 * for virtual PCI-to-PCI bridges, and also for this such as
160 * virtual PCI-to-Cardbus brdiges.
162 class Pci_bridge : public Device
176 bool empty() const { return !_fns[0]; }
177 void add_fn(Pci_dev *f);
180 Pci_dev *fn(unsigned f) const { return _fns[f]; }
181 void fn(unsigned f, Pci_dev *fn) { _fns[f] = fn; }
182 bool cmp(Pci_dev const *od) const
187 return _fns[0]->is_same_device(od);
200 Dev const *dev(unsigned slot) const { return &_devs[slot]; }
201 Dev *dev(unsigned slot) { return &_devs[slot]; }
203 void add_fn(Pci_dev *d, int slot = -1);
206 Pci_bridge() : _free_dev(0), _primary(0), _secondary(0), _subordinate(0) {}
215 l4_uint32_t _primary:8;
216 l4_uint32_t _secondary:8;
217 l4_uint32_t _subordinate:8;
220 l4_uint32_t _bus_config;
225 void primary(unsigned char v) { _primary = v; }
226 void secondary(unsigned char v) { _secondary = v; }
227 void subordinate(unsigned char v) { _subordinate = v; }
228 bool child_dev(unsigned bus, unsigned char dev, unsigned char fn, Pci_dev **rd);
229 void add_child(Device *d);
230 void add_child_fixed(Device *d, Pci_dev *vp, unsigned dn, unsigned fn);
232 Pci_bridge *find_bridge(unsigned bus);
234 void finalize_setup();