The Pedigree Project 0.1
Device.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef MACHINE_DEVICE_H
21#define MACHINE_DEVICE_H
22#include "pedigree/kernel/compiler.h"
23#include "pedigree/kernel/processor/types.h"
24#include "pedigree/kernel/utilities/String.h"
25#include "pedigree/kernel/utilities/Vector.h"
26
27#include <config.h>
28#if THREADS
29#include "pedigree/kernel/LockGuard.h"
30#include "pedigree/kernel/process/Mutex.h"
31#endif
32#include "pedigree/kernel/machine/Pci.h"
33#include "pedigree/kernel/utilities/utility.h"
34
35class IoBase;
36
41class EXPORTED_PUBLIC Device {
42 public:
43 typedef Device* (*Callback)(Device*);
44
47 public:
49#if THREADS
51#endif
52 }
53
55#if THREADS
57#endif
58 }
59
60 private:
61 TreeLockGuard(const TreeLockGuard&) = delete;
62 TreeLockGuard& operator=(const TreeLockGuard&) = delete;
63 };
64
68 static bool treeLockHeldByCurrentThread();
69
72 enum Type {
76 Bus,
78 Display,
83 Mouse,
89 UsbContainer,
91 };
94 class Address {
95 public:
98 Address(const String& n, uintptr_t a, size_t s, bool io, size_t pad = 1);
99 ~Address();
101 void map(size_t forcedSize = 0, bool bUser = false, bool bWriteCombine = false,
102 bool bWriteThrough = false);
107 uintptr_t m_Address;
109 size_t m_Size;
118 size_t m_Padding;
119
120 private:
121 Address(const Address&);
122 Address& operator=(const Address&);
123
124 bool m_bMapped;
125 };
126
127 Device();
133 Device(Device* p);
134 virtual ~Device();
135
158 static void foreach (Callback callback, Device* root = 0);
159 template <class F, class... Args>
160 static void foreach (pedigree_std::Callable<F>& callback, Device * root, Args... args);
161
163 static void addToRoot(Device* device);
164
166 inline Device* getParent() const {
167 return m_pParent;
168 }
170 inline void setParent(Device* p) {
171 m_pParent = p;
172 }
173
175 virtual void getName(String& str);
176
178 virtual Type getType() {
179 return Root;
180 }
181
183 virtual const String& getSpecificType() {
184 return m_SpecificType;
185 }
187 virtual void setSpecificType(String str) {
188 m_SpecificType = pedigree_std::move(str);
189 }
190
192 void setPciPosition(uint32_t bus, uint32_t device, uint32_t func) {
193 m_PciBusPos = bus;
194 m_PciDevicePos = device;
195 m_PciFunctionNum = func;
196 }
199 void setPciIdentifiers(uint8_t classCode, uint8_t subclassCode, uint16_t vendorId,
200 uint16_t deviceId, uint8_t progIf) {
201 m_ClassCode = classCode;
202 m_SubclassCode = subclassCode;
203 m_VendorId = vendorId;
204 m_DeviceId = deviceId;
205 m_ProgInterface = progIf;
206 }
209 m_ConfigHeader = space;
210 }
213 return m_ConfigHeader;
214 }
216 inline uint8_t getPciClassCode() {
217 return m_ClassCode;
218 }
220 inline uint8_t getPciSubclassCode() {
221 return m_SubclassCode;
222 }
224 inline uint16_t getPciVendorId() {
225 return m_VendorId;
226 }
228 inline uint16_t getPciDeviceId() {
229 return m_DeviceId;
230 }
232 inline uint8_t getPciProgInterface() {
233 return m_ProgInterface;
234 }
236 inline uint32_t getPciBusPosition() {
237 return m_PciBusPos;
238 }
240 inline uint32_t getPciDevicePosition() {
241 return m_PciDevicePos;
242 }
244 inline uint32_t getPciFunctionNumber() {
245 return m_PciFunctionNum;
246 }
247
248 Device* getPhysicalFunction() const {
249 return m_PhysicalFunction;
250 }
251 size_t getVirtualFunctionIndex() const {
252 return m_VirtualFunctionIndex;
253 }
255 void setVirtualFunction(Device* physicalFunction, size_t index) {
256 m_PhysicalFunction = physicalFunction;
257 m_VirtualFunctionIndex = index;
258 }
259
261 virtual void dump(String& str) {
262 str.assign("Abstract Device", 16);
263 }
264
267 return m_Addresses;
268 }
269
271 virtual uintptr_t getInterruptNumber() {
272 return m_InterruptNumber;
273 }
274
276 virtual void setInterruptNumber(uintptr_t n) {
277 m_InterruptNumber = n;
278 }
279
282 void addChild(Device* pDevice);
283
286 Device* getChild(size_t n);
287
289 size_t getNumChildren();
290
293 void removeChild(size_t n);
294
296 void removeChild(Device* d);
297
302 void replaceChild(Device* src, Device* dest);
303
305 static void searchByVendorId(uint16_t vendorId, void (*callback)(Device*), Device* root = 0);
306 static void searchByVendorIdAndDeviceId(uint16_t vendorId, uint16_t deviceId,
307 void (*callback)(Device*), Device* root = 0);
308 static void searchByClass(uint16_t classCode, void (*callback)(Device*), Device* root = 0);
309 static void searchByClassAndSubclass(uint16_t classCode, uint16_t subclassCode,
310 void (*callback)(Device*), Device* root = 0);
311 static void searchByClassSubclassAndProgInterface(uint16_t classCode, uint16_t subclassCode,
312 uint8_t progInterface,
313 void (*callback)(Device*), Device* root = 0);
314
315 private:
317 static void foreachInternal(Callback callback, Device* root);
318 template <class F, class... Args>
319 static void foreachInternal(pedigree_std::Callable<F>& callback, Device* root, Args... args);
321 static void searchByVendorIdInternal(uint16_t vendorId, void (*callback)(Device*), Device* root);
322 static void searchByVendorIdAndDeviceIdInternal(uint16_t vendorId, uint16_t deviceId,
323 void (*callback)(Device*), Device* root);
324 static void searchByClassInternal(uint16_t classCode, void (*callback)(Device*), Device* root);
325 static void searchByClassAndSubclassInternal(uint16_t classCode, uint16_t subclassCode,
326 void (*callback)(Device*), Device* root);
327 static void searchByClassSubclassAndProgInterfaceInternal(uint16_t classCode,
328 uint16_t subclassCode,
329 uint8_t progInterface,
330 void (*callback)(Device*),
331 Device* root);
332
335 void removeIoMappings();
336
337 protected:
338 NOT_COPYABLE_OR_ASSIGNABLE(Device);
339
344 static Device& root() {
345 return m_Root;
346 }
347
354 Device* m_PhysicalFunction;
355 size_t m_VirtualFunctionIndex;
365 uint8_t m_ClassCode;
369 uint16_t m_VendorId;
371 uint16_t m_DeviceId;
374
376 uint32_t m_PciBusPos;
381#if THREADS
384#endif
385};
386
387template <class F, class... Args>
388void Device::foreach (pedigree_std::Callable<F>& callback, Device * root, Args... args) {
389#if THREADS
391#endif
392
393 if (!root) {
394 root = &Device::root();
395 }
396
397 foreachInternal(callback, root, args...);
398}
399
400template <class F, class... Args>
401void Device::foreachInternal(pedigree_std::Callable<F>& callback, Device* root, Args... args) {
402 for (size_t i = 0; i < root->getNumChildren();) {
403 // Provide the callback for this child.
404 Device* child = root->getChild(i);
405 Device* result = callback(child, args...);
406 if (!result) {
407 // Remove & skip traversal.
408 root->removeChild(i);
409 delete child;
410 continue;
411 } else if (result != child) {
412 // Replace, but we can still traverse the child.
413 root->replaceChild(child, result);
414 delete child;
415 child = result;
416 }
417
418 // Traverse this child's tree.
419 foreachInternal(callback, child, args...);
420
421 ++i;
422 }
423}
424
425#endif
Definition Bus.h:31
IoBase * m_Io
Definition Device.h:115
size_t m_Size
Definition Device.h:109
size_t m_Padding
Definition Device.h:118
String m_Name
Definition Device.h:104
uintptr_t m_Address
Definition Device.h:107
bool m_IsIoSpace
Definition Device.h:112
uint16_t getPciDeviceId()
Definition Device.h:228
size_t getNumChildren()
Definition Device.cc:143
Device * getChild(size_t n)
Definition Device.cc:139
uint16_t getPciVendorId()
Definition Device.h:224
uint32_t getPciFunctionNumber()
Definition Device.h:244
uint32_t getPciDevicePosition()
Definition Device.h:240
uint8_t m_ClassCode
Definition Device.h:365
static void foreach(Callback callback, Device *root=0)
Definition Device.cc:107
void setPciConfigHeader(const PciBus::ConfigSpace &space)
Definition Device.h:208
virtual Vector< Address * > & addresses()
Definition Device.h:266
void setPciIdentifiers(uint8_t classCode, uint8_t subclassCode, uint16_t vendorId, uint16_t deviceId, uint8_t progIf)
Definition Device.h:199
static void foreachInternal(Callback callback, Device *root)
virtual void dump(String &str)
Definition Device.h:261
@ Generic
The device type is not covered by any other value.
Definition Device.h:73
@ Sound
A device that can play sounds.
Definition Device.h:81
@ Console
A keyboard-like human interface device.
Definition Device.h:82
@ Root
The device is the root of the device tree.
Definition Device.h:74
@ Network
A communication device.
Definition Device.h:80
@ UsbController
Same as Controller, but exposes USB devices.
Definition Device.h:87
@ Disk
A disk device - a block device in UNIX terms.
Definition Device.h:75
@ UsbGeneric
Same as Generic, but for USB devices.
Definition Device.h:88
virtual void setInterruptNumber(uintptr_t n)
Definition Device.h:276
uint8_t getPciClassCode()
Definition Device.h:216
virtual void setSpecificType(String str)
Definition Device.h:187
virtual const String & getSpecificType()
Definition Device.h:183
Vector< Address * > m_Addresses
Definition Device.h:349
uint16_t m_VendorId
Definition Device.h:369
PciBus::ConfigSpace getPciConfigHeader() const
Definition Device.h:212
static Mutex m_TreeLock
Definition Device.h:383
uint8_t getPciSubclassCode()
Definition Device.h:220
uintptr_t m_InterruptNumber
Definition Device.h:359
PciBus::ConfigSpace m_ConfigHeader
Definition Device.h:363
uint16_t m_DeviceId
Definition Device.h:371
Device * m_pParent
Definition Device.h:353
uint8_t getPciProgInterface()
Definition Device.h:232
Vector< Device * > m_Children
Definition Device.h:351
void setVirtualFunction(Device *physicalFunction, size_t index)
Definition Device.h:255
Device * getParent() const
Definition Device.h:166
virtual Type getType()
Definition Device.h:178
uint8_t m_ProgInterface
Definition Device.h:373
virtual uintptr_t getInterruptNumber()
Definition Device.h:271
uint8_t m_SubclassCode
Definition Device.h:367
uint32_t getPciBusPosition()
Definition Device.h:236
void setParent(Device *p)
Definition Device.h:170
static Device & root()
Definition Device.h:344
uint32_t m_PciDevicePos
Definition Device.h:378
void removeChild(size_t n)
Definition Device.cc:147
void replaceChild(Device *src, Device *dest)
Definition Device.cc:166
void setPciPosition(uint32_t bus, uint32_t device, uint32_t func)
Definition Device.h:192
String m_SpecificType
Definition Device.h:361
static Device m_Root
Definition Device.h:357
uint32_t m_PciBusPos
Definition Device.h:376
uint32_t m_PciFunctionNum
Definition Device.h:380
Abstrace base class for hardware I/O capabilities.
Definition IoBase.h:32
Definition Mutex.h:56
void release(size_t n=1)
Definition Semaphore.cc:549
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
Definition Semaphore.cc:355
A vector / dynamic array.
Definition Vector.h:33