12 static bool valid(uint8_t device, uint8_t function, uint16_t offset, uint8_t width) {
13 return device < 32 && function < 8 && (width == 1 || width == 2 || width == 4) &&
14 offset <= 256 - width && !(offset & (width - 1));
16 bool read(uint8_t bus, uint8_t device, uint8_t function, uint16_t offset, uint8_t width,
18 if (!valid(device, function, offset, width))
21 select(bus, device, function, offset);
22 value = readData(offset, width);
25 bool write(uint8_t bus, uint8_t device, uint8_t function, uint16_t offset, uint8_t width,
27 if (!valid(device, function, offset, width))
30 select(bus, device, function, offset);
31 writeData(offset, width, value);
34 bool updateCommand(uint8_t bus, uint8_t device, uint8_t function, uint16_t clearBits,
36 if (!valid(device, function, 4, 2))
39 select(bus, device, function, 4);
40 const uint16_t desired = (m_Io.read16(4) & ~clearBits) | setBits;
41 m_Io.write16(desired, 4);
42 return m_Io.read16(4) == desired;
48 explicit Guard(Lock& value) : lock(value) {
55 void select(uint8_t bus, uint8_t device, uint8_t function, uint16_t offset) {
56 m_Io.write32(0x80000000U | (uint32_t{bus} << 16) | (uint32_t{device} << 11) |
57 (uint32_t{function} << 8) | (offset & ~3U),
60 uint32_t readData(uint16_t offset, uint8_t width) {
61 const uint8_t port = 4 + (offset & 3);
63 return m_Io.read8(port);
65 return m_Io.read16(port);
66 return m_Io.read32(port);
68 void writeData(uint16_t offset, uint8_t width, uint32_t value) {
69 const uint8_t port = 4 + (offset & 3);
71 m_Io.write8(value, port);
73 m_Io.write16(value, port);
75 m_Io.write32(value, port);