diff options
author | Liav A <liavalb@gmail.com> | 2020-02-02 01:52:51 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-02 00:57:13 +0100 |
commit | 583e9ad372388a88a82474dff0fcb1f30a153d21 (patch) | |
tree | 2a322e26330d4ec37029560d3cf88ca732047a9b /Kernel | |
parent | 60715695b285f8d74711e925300d22346ca838d2 (diff) | |
download | serenity-583e9ad372388a88a82474dff0fcb1f30a153d21.zip |
Kernel: Detect devices when enumerating the PCI bus
Instead of making each driver to enumerate the PCI bus itself,
PCI::Initializer will call detect_devices() to do one enumeration
of the bus.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/E1000NetworkAdapter.cpp | 20 | ||||
-rw-r--r-- | Kernel/Net/E1000NetworkAdapter.h | 2 | ||||
-rw-r--r-- | Kernel/Net/RTL8139NetworkAdapter.cpp | 20 | ||||
-rw-r--r-- | Kernel/Net/RTL8139NetworkAdapter.h | 2 | ||||
-rw-r--r-- | Kernel/PCI/Access.cpp | 10 | ||||
-rw-r--r-- | Kernel/PCI/Access.h | 2 | ||||
-rw-r--r-- | Kernel/PCI/Definitions.h | 5 | ||||
-rw-r--r-- | Kernel/PCI/Initializer.cpp | 22 | ||||
-rw-r--r-- | Kernel/PCI/Initializer.h | 3 | ||||
-rw-r--r-- | Kernel/init.cpp | 28 |
10 files changed, 64 insertions, 50 deletions
diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index 128009d220..a62fe622c3 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -119,20 +119,16 @@ #define STATUS_SPEED_1000MB1 0x80 #define STATUS_SPEED_1000MB2 0xC0 -OwnPtr<E1000NetworkAdapter> E1000NetworkAdapter::autodetect() +void E1000NetworkAdapter::detect(const PCI::Address& address) { + if (address.is_null()) + return; static const PCI::ID qemu_bochs_vbox_id = { 0x8086, 0x100e }; - PCI::Address found_address; - PCI::enumerate_all([&](const PCI::Address& address, PCI::ID id) { - if (id == qemu_bochs_vbox_id) { - found_address = address; - return; - } - }); - if (found_address.is_null()) - return nullptr; - u8 irq = PCI::get_interrupt_line(found_address); - return make<E1000NetworkAdapter>(found_address, irq); + const PCI::ID id = PCI::get_id(address); + if (id != qemu_bochs_vbox_id) + return; + u8 irq = PCI::get_interrupt_line(address); + new E1000NetworkAdapter(address, irq); } E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 irq) diff --git a/Kernel/Net/E1000NetworkAdapter.h b/Kernel/Net/E1000NetworkAdapter.h index 2999b8803c..f1b8667ee7 100644 --- a/Kernel/Net/E1000NetworkAdapter.h +++ b/Kernel/Net/E1000NetworkAdapter.h @@ -34,7 +34,7 @@ class E1000NetworkAdapter final : public NetworkAdapter , public IRQHandler { public: - static OwnPtr<E1000NetworkAdapter> autodetect(); + static void detect(const PCI::Address&); E1000NetworkAdapter(PCI::Address, u8 irq); virtual ~E1000NetworkAdapter() override; diff --git a/Kernel/Net/RTL8139NetworkAdapter.cpp b/Kernel/Net/RTL8139NetworkAdapter.cpp index 18a08d81c7..4ea4a6d4e4 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.cpp +++ b/Kernel/Net/RTL8139NetworkAdapter.cpp @@ -123,20 +123,16 @@ #define RX_BUFFER_SIZE 32768 #define TX_BUFFER_SIZE PACKET_SIZE_MAX -OwnPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::autodetect() +void RTL8139NetworkAdapter::detect(const PCI::Address& address) { + if (address.is_null()) + return; static const PCI::ID rtl8139_id = { 0x10EC, 0x8139 }; - PCI::Address found_address; - PCI::enumerate_all([&](const PCI::Address& address, PCI::ID id) { - if (id == rtl8139_id) { - found_address = address; - return; - } - }); - if (found_address.is_null()) - return nullptr; - u8 irq = PCI::get_interrupt_line(found_address); - return make<RTL8139NetworkAdapter>(found_address, irq); + PCI::ID id = PCI::get_id(address); + if (id != rtl8139_id) + return; + u8 irq = PCI::get_interrupt_line(address); + new RTL8139NetworkAdapter(address, irq); } RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 irq) diff --git a/Kernel/Net/RTL8139NetworkAdapter.h b/Kernel/Net/RTL8139NetworkAdapter.h index 31403c7d25..0f05512dfa 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.h +++ b/Kernel/Net/RTL8139NetworkAdapter.h @@ -36,7 +36,7 @@ class RTL8139NetworkAdapter final : public NetworkAdapter , public IRQHandler { public: - static OwnPtr<RTL8139NetworkAdapter> autodetect(); + static void detect(const PCI::Address&); RTL8139NetworkAdapter(PCI::Address, u8 irq); virtual ~RTL8139NetworkAdapter() override; diff --git a/Kernel/PCI/Access.cpp b/Kernel/PCI/Access.cpp index 520ae696c7..d632aa4d94 100644 --- a/Kernel/PCI/Access.cpp +++ b/Kernel/PCI/Access.cpp @@ -77,6 +77,11 @@ void PCI::Access::enumerate_slot(int type, u8 bus, u8 slot, Function<void(Addres } } +PCI::ID PCI::Access::get_id(Address address) +{ + return { read16_field(address, PCI_VENDOR_ID), read16_field(address, PCI_DEVICE_ID) }; +} + void PCI::Access::enumerate_bus(int type, u8 bus, Function<void(Address, ID)>& callback) { for (u8 slot = 0; slot < 32; ++slot) @@ -105,6 +110,11 @@ void enumerate_all(Function<void(Address, ID)> callback) PCI::Access::the().enumerate_all(callback); } +ID get_id(Address address) +{ + return PCI::Access::the().get_id(address); +} + u8 get_interrupt_line(Address address) { return PCI::Access::the().get_interrupt_line(address); diff --git a/Kernel/PCI/Access.h b/Kernel/PCI/Access.h index 05cde7dd42..dad1d48b67 100644 --- a/Kernel/PCI/Access.h +++ b/Kernel/PCI/Access.h @@ -53,7 +53,7 @@ public: space_size = (~space_size) + 1; return space_size; } - + virtual ID get_id(Address address) final; virtual u8 get_revision_id(Address address) { return read8_field(address, PCI_REVISION_ID); } virtual u8 get_subclass(Address address) { return read8_field(address, PCI_SUBCLASS); } virtual u8 get_class(Address address) { return read8_field(address, PCI_CLASS); } diff --git a/Kernel/PCI/Definitions.h b/Kernel/PCI/Definitions.h index 76344d77e2..f5748a23c5 100644 --- a/Kernel/PCI/Definitions.h +++ b/Kernel/PCI/Definitions.h @@ -74,6 +74,10 @@ struct ID { { return vendor_id == other.vendor_id && device_id == other.device_id; } + bool operator!=(const ID& other) const + { + return vendor_id != other.vendor_id || device_id != other.device_id; + } }; struct Address { @@ -156,6 +160,7 @@ struct ChangeableAddress : public Address { } }; +ID get_id(PCI::Address); void enumerate_all(Function<void(Address, ID)> callback); u8 get_interrupt_line(Address); u32 get_BAR0(Address); diff --git a/Kernel/PCI/Initializer.cpp b/Kernel/PCI/Initializer.cpp index c126d15fb2..0c6c97cf63 100644 --- a/Kernel/PCI/Initializer.cpp +++ b/Kernel/PCI/Initializer.cpp @@ -27,6 +27,8 @@ #include <Kernel/ACPI/ACPIParser.h> #include <Kernel/IO.h> #include <Kernel/KParams.h> +#include <Kernel/Net/E1000NetworkAdapter.h> +#include <Kernel/Net/RTL8139NetworkAdapter.h> #include <Kernel/PCI/IOAccess.h> #include <Kernel/PCI/Initializer.h> #include <Kernel/PCI/MMIOAccess.h> @@ -43,11 +45,29 @@ PCI::Initializer& PCI::Initializer::the() void PCI::Initializer::initialize_pci_mmio_access(ACPI_RAW::MCFG& mcfg) { PCI::MMIOAccess::initialize(mcfg); + detect_devices(); } void PCI::Initializer::initialize_pci_io_access() { PCI::IOAccess::initialize(); + detect_devices(); } + +void PCI::Initializer::detect_devices() +{ + PCI::enumerate_all([&](const PCI::Address& address, PCI::ID id) { + kprintf("PCI: device @ %w:%b:%b.%d [%w:%w]\n", + address.seg(), + address.bus(), + address.slot(), + address.function(), + id.vendor_id, + id.device_id); + E1000NetworkAdapter::detect(address); + RTL8139NetworkAdapter::detect(address); + }); +} + void PCI::Initializer::test_and_initialize(bool disable_pci_mmio) { if (disable_pci_mmio) { @@ -129,4 +149,4 @@ void PCI::Initializer::dismiss() PCI::Initializer::~Initializer() { -}
\ No newline at end of file +} diff --git a/Kernel/PCI/Initializer.h b/Kernel/PCI/Initializer.h index 30aa06d411..c66701a515 100644 --- a/Kernel/PCI/Initializer.h +++ b/Kernel/PCI/Initializer.h @@ -39,10 +39,11 @@ public: static void dismiss(); private: + void detect_devices(); ~Initializer(); Initializer(); bool test_acpi(); bool test_pci_io(); bool test_pci_mmio(); void initialize_pci_mmio_access_after_test(); -};
\ No newline at end of file +}; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index a5b2348a21..426dd3b309 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -62,10 +62,8 @@ #include <Kernel/Heap/kmalloc.h> #include <Kernel/KParams.h> #include <Kernel/Multiboot.h> -#include <Kernel/Net/E1000NetworkAdapter.h> #include <Kernel/Net/LoopbackAdapter.h> #include <Kernel/Net/NetworkTask.h> -#include <Kernel/Net/RTL8139NetworkAdapter.h> #include <Kernel/PCI/Access.h> #include <Kernel/PCI/Initializer.h> #include <Kernel/Random.h> @@ -145,16 +143,6 @@ extern "C" [[noreturn]] void init() PIT::initialize(); - PCI::enumerate_all([](const PCI::Address& address, PCI::ID id) { - kprintf("PCI: device @ %w:%b:%b.%d [%w:%w]\n", - address.seg(), - address.bus(), - address.slot(), - address.function(), - id.vendor_id, - id.device_id); - }); - if (text_debug) { dbgprintf("Text mode enabled\n"); } else { @@ -170,8 +158,6 @@ extern "C" [[noreturn]] void init() } LoopbackAdapter::the(); - auto e1000 = E1000NetworkAdapter::autodetect(); - auto rtl8139 = RTL8139NetworkAdapter::autodetect(); Process::initialize(); Thread::initialize(); @@ -218,6 +204,13 @@ void init_stage2() new RandomDevice; new PTYMultiplexer; + bool dmi_unreliable = KParams::the().has("dmi_unreliable"); + if (dmi_unreliable) { + DMIDecoder::initialize_untrusted(); + } else { + DMIDecoder::initialize(); + } + bool text_debug = KParams::the().has("text_debug"); bool force_pio = KParams::the().has("force_pio"); @@ -226,13 +219,6 @@ void init_stage2() root = "/dev/hda"; } - bool dmi_unreliable = KParams::the().has("dmi_unreliable"); - if (dmi_unreliable) { - DMIDecoder::initialize_untrusted(); - } else { - DMIDecoder::initialize(); - } - if (!root.starts_with("/dev/hda")) { kprintf("init_stage2: root filesystem must be on the first IDE hard drive (/dev/hda)\n"); hang(); |