diff --git a/kernel/include/kernel/PCI.h b/kernel/include/kernel/PCI.h index c787a87a..7cbba22f 100644 --- a/kernel/include/kernel/PCI.h +++ b/kernel/include/kernel/PCI.h @@ -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; diff --git a/kernel/kernel/PCI.cpp b/kernel/kernel/PCI.cpp index cd356d51..de7fdabf 100644 --- a/kernel/kernel/PCI.cpp +++ b/kernel/kernel/PCI.cpp @@ -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)); + } + } \ No newline at end of file