Kernel: add more functionality to PCI

This commit is contained in:
Bananymous 2023-07-09 23:04:11 +03:00
parent 3840fbf957
commit 19dab08275
2 changed files with 55 additions and 0 deletions

View File

@ -14,6 +14,8 @@ namespace Kernel
uint16_t read_word(uint8_t) const;
uint8_t read_byte(uint8_t) const;
void write_dword(uint8_t, uint32_t) const;
uint8_t bus() const { return m_bus; }
uint8_t dev() const { return m_dev; }
uint8_t func() const { return m_func; }
@ -22,6 +24,15 @@ namespace Kernel
uint8_t subclass() const { return m_subclass; }
uint8_t prog_if() const { return m_prog_if; }
void enable_bus_mastering() const;
void disable_bus_mastering() const;
void enable_memory_space() const;
void disable_memory_space() const;
void enable_pin_interrupts() const;
void disable_pin_interrupts() const;
private:
uint8_t m_bus;
uint8_t m_dev;

View File

@ -33,6 +33,13 @@ namespace Kernel
return IO::inl(CONFIG_DATA);
}
static void write_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint32_t value)
{
uint32_t config_addr = 0x80000000 | ((uint32_t)bus << 16) | ((uint32_t)dev << 11) | ((uint32_t)func << 8) | offset;
IO::outl(CONFIG_ADDRESS, config_addr);
IO::outl(CONFIG_DATA, value);
}
static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func)
{
uint32_t dword = read_config_dword(bus, dev, func, 0x00);
@ -112,4 +119,41 @@ namespace Kernel
return (uint8_t)(dword >> (8 * (offset & 0x03)));
}
void PCIDevice::write_dword(uint8_t offset, uint32_t value) const
{
ASSERT((offset & 0x03) == 0);
write_config_dword(m_bus, m_dev, m_func, offset, value);
}
void PCIDevice::enable_bus_mastering() const
{
write_dword(0x04, read_dword(0x04) | 1u << 2);
}
void PCIDevice::disable_bus_mastering() const
{
write_dword(0x04, read_dword(0x04) & ~(1u << 2));
}
void PCIDevice::enable_memory_space() const
{
write_dword(0x04, read_dword(0x04) | 1u << 1);
}
void PCIDevice::disable_memory_space() const
{
write_dword(0x04, read_dword(0x04) & ~(1u << 1));
}
void PCIDevice::enable_pin_interrupts() const
{
write_dword(0x04, read_dword(0x04) | 1u << 10);
}
void PCIDevice::disable_pin_interrupts() const
{
write_dword(0x04, read_dword(0x04) & ~(1u << 10));
}
}