The Pedigree Project 0.1
DeviceHashTree.cc
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#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/machine/Device.h"
22#include "pedigree/kernel/machine/DeviceHashTree.h"
23#include "pedigree/kernel/utilities/Cord.h"
24#include "pedigree/kernel/utilities/StaticString.h"
25#include "pedigree/kernel/utilities/sha1/sha1.h"
26#include "pedigree/kernel/utilities/utility.h"
27
28DeviceHashTree DeviceHashTree::m_Instance;
29
30DeviceHashTree::DeviceHashTree() : m_bInitialised(false), m_DeviceTree() {}
31
32DeviceHashTree::~DeviceHashTree() {}
33
34static Device* testDevice(Device* p) {
35 if (p->getType() != Device::Root)
36 DeviceHashTree::instance().add(p);
37
38 return p;
39}
40
42 Device::foreach (testDevice, root);
43
44 m_bInitialised = true;
45}
46
48 size_t hash = getHash(p);
49 if (m_DeviceTree.lookup(hash))
50 return;
51
52 String dump;
53 p->dump(dump);
54
55 NOTICE("Device hash for `" << dump << "' is: " << hash << ".");
56 m_DeviceTree.insert(hash, p);
57}
58
60 if (!m_bInitialised)
61 return 0;
62 else
63 return m_DeviceTree.lookup(hash);
64}
65
67 if (!m_bInitialised)
68 return 0;
69 else {
70 uint32_t inthash = StringToUnsignedLong(static_cast<const char*>(hash), 0, 16);
71 return m_DeviceTree.lookup(inthash);
72 }
73}
74
76 static SHA1 mySha1;
77
78 // Grab the device information
79 String name, dump;
80 pChild->getName(name);
81 pChild->dump(dump);
82 uint32_t bus = pChild->getPciBusPosition();
83 uint32_t dev = pChild->getPciDevicePosition();
84 uint32_t func = pChild->getPciFunctionNumber();
85
86 TinyStaticString busStr, devStr, funcStr;
87 busStr.append(bus);
88 devStr.append(dev);
89 funcStr.append(func);
90
91 // Build the string to be hashed
92 Cord hashBuild;
93 hashBuild.append(name);
94 hashBuild.append("-");
95 hashBuild.append(dump);
96 hashBuild.append("-");
97 hashBuild.append(busStr);
98 hashBuild.append(".");
99 hashBuild.append(devStr);
100 hashBuild.append(".");
101 hashBuild.append(funcStr);
102
103 // Hash the string
104 mySha1.Reset();
105 for (auto it = hashBuild.segbegin(); it != hashBuild.segend(); ++it) {
106 mySha1.Input(it.ptr(), it.length());
107 }
108 unsigned int digest[5];
109 mySha1.Result(digest);
110
111 // Only use 4 bytes of the hash
112 return digest[0];
113}
Definition Cord.h:33
void fill(Device *root=0)
Device * getDevice(uint32_t hash)
size_t getHash(Device *p)
void add(Device *p)
uint32_t getPciFunctionNumber()
Definition Device.h:239
uint32_t getPciDevicePosition()
Definition Device.h:235
static void foreach(Callback callback, Device *root=0)
Definition Device.cc:95
virtual void dump(String &str)
Definition Device.h:244
@ Root
The device is the root of the device tree.
Definition Device.h:69
virtual void getName(String &str)
Definition Device.cc:118
virtual Type getType()
Definition Device.h:173
uint32_t getPciBusPosition()
Definition Device.h:231
E lookup(const K &key) const
Definition Tree.h:193
void insert(const K &key, const E &value)
Definition Tree.h:149