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.
18 * \brief Generic virtual PCI device.
19 * This class provides the basic functionality for a device on a
20 * virtual PCI bus. Implementations may provide proxy access to a real PCI
21 * device or a completely virtualized PCI device.
26 void operator = (Pci_dev const &);
27 Pci_dev(Pci_dev const &);
30 typedef Hw::Pci::Cfg_width Cfg_width;
35 unsigned char trigger;
36 unsigned char polarity;
40 virtual int cfg_read(int reg, l4_uint32_t *v, Cfg_width) = 0;
41 virtual int cfg_write(int reg, l4_uint32_t v, Cfg_width) = 0;
42 virtual int irq_enable(Irq_info *irq) = 0;
43 virtual bool is_same_device(Pci_dev const *o) const = 0;
44 virtual ~Pci_dev() = 0;
52 * \brief A basic really virtualized PCI device.
54 class Pci_virtual_dev : public Pci_dev, public Dev_feature
59 l4_uint32_t vendor_device;
62 l4_uint32_t class_rev;
67 } __attribute__((packed));
69 Pci_cfg_header *cfg_hdr() { return (Pci_cfg_header*)_h; }
70 Pci_cfg_header const *cfg_hdr() const { return (Pci_cfg_header const *)_h; }
72 int cfg_read(int reg, l4_uint32_t *v, Cfg_width);
73 int cfg_write(int reg, l4_uint32_t v, Cfg_width);
74 bool is_same_device(Pci_dev const *o) const { return o == this; }
76 ~Pci_virtual_dev() = 0;
87 Pci_virtual_dev::~Pci_virtual_dev()
93 * \brief A virtual PCI proxy for a real PCI device.
95 class Pci_proxy_dev : public Pci_dev, public virtual Dev_feature
99 Pci_proxy_dev(Hw::Pci::If *hwf);
101 int cfg_read(int reg, l4_uint32_t *v, Cfg_width);
102 int cfg_write(int reg, l4_uint32_t v, Cfg_width);
103 int irq_enable(Irq_info *irq);
104 int bridge_cfg_read(unsigned, l4_uint32_t, int, l4_uint32_t *, Cfg_width)
105 { return -L4_ENODEV; }
107 int bridge_cfg_write(unsigned, l4_uint32_t, int, l4_uint32_t, Cfg_width)
108 { return -L4_ENODEV; }
110 l4_uint32_t read_bar(int bar);
111 void write_bar(int bar, l4_uint32_t v);
113 l4_uint32_t read_rom() const { return _rom; }
114 void write_rom(l4_uint32_t v);
116 int vbus_dispatch(l4_umword_t, l4_uint32_t, L4::Ipc_iostream &)
117 { return -L4_ENOSYS; }
119 Hw::Pci::If *hwf() const { return _hwf; }
122 bool is_same_device(Pci_dev const *o) const
124 if (Pci_proxy_dev const *op = dynamic_cast<Pci_proxy_dev const *>(o))
125 return (hwf()->bus_nr() == op->hwf()->bus_nr())
126 && ((hwf()->host()->adr() >> 16) == (op->hwf()->host()->adr() >> 16));
130 bool match_hw_feature(const Hw::Dev_feature *f) const
131 { return f == _hwf; }
133 int dispatch(l4_umword_t, l4_uint32_t, L4::Ipc_iostream&)
134 { return -L4_ENOSYS; }
139 l4_uint32_t _vbars[6];
146 * \brief a basic virtual PCI bridge.
147 * This class is the base for virtual Host-to-PCI bridges,
148 * for virtual PCI-to-PCI bridges, and also for this such as
149 * virtual PCI-to-Cardbus brdiges.
151 class Pci_bridge : public Device
165 bool empty() const { return !_fns[0]; }
166 void add_fn(Pci_dev *f);
169 Pci_dev *fn(unsigned f) const { return _fns[f]; }
170 void fn(unsigned f, Pci_dev *fn) { _fns[f] = fn; }
171 bool cmp(Pci_dev const *od) const
176 return _fns[0]->is_same_device(od);
189 Dev const *dev(unsigned slot) const { return &_devs[slot]; }
190 Dev *dev(unsigned slot) { return &_devs[slot]; }
192 void add_fn(Pci_dev *d, int slot = -1);
195 Pci_bridge() : _free_dev(0), _primary(0), _secondary(0), _subordinate(0) {}
204 l4_uint32_t _primary:8;
205 l4_uint32_t _secondary:8;
206 l4_uint32_t _subordinate:8;
209 l4_uint32_t _bus_config;
214 void primary(unsigned char v) { _primary = v; }
215 void secondary(unsigned char v) { _secondary = v; }
216 void subordinate(unsigned char v) { _subordinate = v; }
217 bool child_dev(unsigned bus, unsigned char dev, unsigned char fn, Pci_dev **rd);
218 void add_child(Device *d);
219 void add_child_fixed(Device *d, Pci_dev *vp, unsigned dn, unsigned fn);
221 Pci_bridge *find_bridge(unsigned bus);
223 void finalize_setup();