forked from Bananymous/banan-os
Kernel: PCIDevice is now class with getters and constructor
This commit is contained in:
parent
b4ce438ca7
commit
a9acf1f6dc
|
@ -8,22 +8,35 @@ namespace Kernel
|
||||||
class PCIDevice
|
class PCIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const uint8_t bus;
|
PCIDevice(uint8_t, uint8_t, uint8_t);
|
||||||
const uint8_t dev;
|
|
||||||
const uint8_t func;
|
|
||||||
|
|
||||||
const uint8_t class_code;
|
|
||||||
const uint8_t subclass;
|
|
||||||
|
|
||||||
uint32_t read_dword(uint8_t) const;
|
uint32_t read_dword(uint8_t) const;
|
||||||
uint16_t read_word(uint8_t) const;
|
uint16_t read_word(uint8_t) const;
|
||||||
uint8_t read_byte(uint8_t) const;
|
uint8_t read_byte(uint8_t) const;
|
||||||
|
|
||||||
|
uint8_t bus() const { return m_bus; }
|
||||||
|
uint8_t dev() const { return m_dev; }
|
||||||
|
uint8_t func() const { return m_func; }
|
||||||
|
|
||||||
|
uint8_t class_code() const { return m_class_code; }
|
||||||
|
uint8_t subclass() const { return m_subclass; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_bus;
|
||||||
|
uint8_t m_dev;
|
||||||
|
uint8_t m_func;
|
||||||
|
|
||||||
|
uint8_t m_class_code;
|
||||||
|
uint8_t m_subclass;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PCI
|
class PCI
|
||||||
{
|
{
|
||||||
|
BAN_NON_COPYABLE(PCI);
|
||||||
|
BAN_NON_MOVABLE(PCI);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool initialize();
|
static void initialize();
|
||||||
static PCI& get();
|
static PCI& get();
|
||||||
|
|
||||||
const BAN::Vector<PCIDevice>& devices() const { return m_devices; }
|
const BAN::Vector<PCIDevice>& devices() const { return m_devices; }
|
||||||
|
|
|
@ -35,10 +35,10 @@ namespace Kernel
|
||||||
// Initialize all storage controllers
|
// Initialize all storage controllers
|
||||||
for (auto& device : PCI::get().devices())
|
for (auto& device : PCI::get().devices())
|
||||||
{
|
{
|
||||||
if (device.class_code != 0x01)
|
if (device.class_code() != 0x01)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (device.subclass)
|
switch (device.subclass())
|
||||||
{
|
{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
dwarnln("unsupported SCSI Bus Controller");
|
dwarnln("unsupported SCSI Bus Controller");
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include <kernel/Debug.h>
|
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
#include <kernel/PCI.h>
|
#include <kernel/PCI.h>
|
||||||
|
|
||||||
|
@ -11,15 +10,14 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
PCI* s_instance = nullptr;
|
static PCI* s_instance = nullptr;
|
||||||
|
|
||||||
bool PCI::initialize()
|
void PCI::initialize()
|
||||||
{
|
{
|
||||||
ASSERT(s_instance == nullptr);
|
ASSERT(s_instance == nullptr);
|
||||||
s_instance = new PCI();
|
s_instance = new PCI();
|
||||||
ASSERT(s_instance);
|
ASSERT(s_instance);
|
||||||
s_instance->check_all_buses();
|
s_instance->check_all_buses();
|
||||||
return !s_instance->m_devices.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCI& PCI::get()
|
PCI& PCI::get()
|
||||||
|
@ -49,32 +47,23 @@ namespace Kernel
|
||||||
|
|
||||||
void PCI::check_function(uint8_t bus, uint8_t dev, uint8_t func)
|
void PCI::check_function(uint8_t bus, uint8_t dev, uint8_t func)
|
||||||
{
|
{
|
||||||
uint32_t type = read_config_dword(bus, dev, func, 0x08);
|
MUST(m_devices.emplace_back(bus, dev, func));
|
||||||
PCIDevice device {
|
auto& device = m_devices.back();
|
||||||
bus,
|
if (device.class_code() == 0x06 && device.subclass() == 0x04)
|
||||||
dev,
|
check_bus(device.read_byte(0x19));
|
||||||
func,
|
|
||||||
(uint8_t)(type >> 24),
|
|
||||||
(uint8_t)(type >> 16),
|
|
||||||
};
|
|
||||||
MUST(m_devices.push_back(BAN::move(device)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCI::check_device(uint8_t bus, uint8_t dev)
|
void PCI::check_device(uint8_t bus, uint8_t dev)
|
||||||
{
|
{
|
||||||
if (get_vendor_id(bus, dev, 0) == INVALID)
|
if (get_vendor_id(bus, dev, 0) == INVALID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
check_function(bus, dev, 0);
|
||||||
if (get_header_type(bus, dev, 0) & MULTI_FUNCTION)
|
if (get_header_type(bus, dev, 0) & MULTI_FUNCTION)
|
||||||
{
|
for (uint8_t func = 1; func < 8; func++)
|
||||||
for (uint8_t func = 0; func < 8; func++)
|
|
||||||
if (get_vendor_id(bus, dev, func) != INVALID)
|
if (get_vendor_id(bus, dev, func) != INVALID)
|
||||||
check_function(bus, dev, func);
|
check_function(bus, dev, func);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
check_function(bus, dev, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCI::check_bus(uint8_t bus)
|
void PCI::check_bus(uint8_t bus)
|
||||||
{
|
{
|
||||||
|
@ -86,8 +75,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
if (get_header_type(0, 0, 0) & MULTI_FUNCTION)
|
if (get_header_type(0, 0, 0) & MULTI_FUNCTION)
|
||||||
{
|
{
|
||||||
for (int func = 0; func < 8; func++)
|
for (int func = 0; func < 8 && get_vendor_id(0, 0, func) != INVALID; func++)
|
||||||
if (get_vendor_id(0, 0, func) != INVALID)
|
|
||||||
check_bus(func);
|
check_bus(func);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -96,23 +84,31 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCIDevice::PCIDevice(uint8_t bus, uint8_t dev, uint8_t func)
|
||||||
|
: m_bus(bus), m_dev(dev), m_func(func)
|
||||||
|
{
|
||||||
|
uint32_t type = read_word(0x0A);
|
||||||
|
m_class_code = (uint8_t)(type >> 8);
|
||||||
|
m_subclass = (uint8_t)(type);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t PCIDevice::read_dword(uint8_t offset) const
|
uint32_t PCIDevice::read_dword(uint8_t offset) const
|
||||||
{
|
{
|
||||||
ASSERT((offset & 0x03) == 0);
|
ASSERT((offset & 0x03) == 0);
|
||||||
return read_config_dword(bus, dev, func, offset);
|
return read_config_dword(m_bus, m_dev, m_func, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PCIDevice::read_word(uint8_t offset) const
|
uint16_t PCIDevice::read_word(uint8_t offset) const
|
||||||
{
|
{
|
||||||
ASSERT((offset & 0x01) == 0);
|
ASSERT((offset & 0x01) == 0);
|
||||||
uint32_t dword = read_config_dword(bus, dev, func, offset & 0xFC);
|
uint32_t dword = read_config_dword(m_bus, m_dev, m_func, offset & 0xFC);
|
||||||
return (uint16_t)(dword >> (offset & 0x03));
|
return (uint16_t)(dword >> (8 * (offset & 0x03)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PCIDevice::read_byte(uint8_t offset) const
|
uint8_t PCIDevice::read_byte(uint8_t offset) const
|
||||||
{
|
{
|
||||||
uint32_t dword = read_config_dword(bus, dev, func, offset & 0xFC);
|
uint32_t dword = read_config_dword(m_bus, m_dev, m_func, offset & 0xFC);
|
||||||
return (uint8_t)(dword >> (offset & 0x03));
|
return (uint8_t)(dword >> (8 * (offset & 0x03)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -254,6 +254,13 @@ argument_done:
|
||||||
IO::outb(0x64, 0xFE);
|
IO::outb(0x64, 0xFE);
|
||||||
asm volatile("cli; hlt");
|
asm volatile("cli; hlt");
|
||||||
}
|
}
|
||||||
|
else if (arguments.front() == "lspci")
|
||||||
|
{
|
||||||
|
if (arguments.size() != 1)
|
||||||
|
return TTY_PRINTLN("'lspci' does not support command line arguments");
|
||||||
|
for (auto& device : PCI::get().devices())
|
||||||
|
TTY_PRINTLN("{2H}:{2H}.{2H} {2H}", device.bus(), device.dev(), device.func(), device.class_code());
|
||||||
|
}
|
||||||
else if (arguments.front() == "ls")
|
else if (arguments.front() == "ls")
|
||||||
{
|
{
|
||||||
if (!VirtualFileSystem::is_initialized())
|
if (!VirtualFileSystem::is_initialized())
|
||||||
|
|
|
@ -86,6 +86,9 @@ extern "C" void kernel_main()
|
||||||
MMU::intialize();
|
MMU::intialize();
|
||||||
dprintln("MMU initialized");
|
dprintln("MMU initialized");
|
||||||
|
|
||||||
|
PCI::initialize();
|
||||||
|
dprintln("PCI initialized");
|
||||||
|
|
||||||
TerminalDriver* terminal_driver = VesaTerminalDriver::create();
|
TerminalDriver* terminal_driver = VesaTerminalDriver::create();
|
||||||
ASSERT(terminal_driver);
|
ASSERT(terminal_driver);
|
||||||
dprintln("VESA initialized");
|
dprintln("VESA initialized");
|
||||||
|
@ -97,10 +100,6 @@ extern "C" void kernel_main()
|
||||||
PIT::initialize();
|
PIT::initialize();
|
||||||
dprintln("PIT initialized");
|
dprintln("PIT initialized");
|
||||||
|
|
||||||
if (!PCI::initialize())
|
|
||||||
Kernel::panic("Could not initialize PCI");
|
|
||||||
dprintln("PCI initialized");
|
|
||||||
|
|
||||||
if (!Input::initialize())
|
if (!Input::initialize())
|
||||||
dprintln("Could not initialize input drivers");
|
dprintln("Could not initialize input drivers");
|
||||||
dprintln("Input initialized");
|
dprintln("Input initialized");
|
||||||
|
|
Loading…
Reference in New Issue