summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2020-02-02 01:52:51 +0200
committerAndreas Kling <kling@serenityos.org>2020-02-02 00:57:13 +0100
commit583e9ad372388a88a82474dff0fcb1f30a153d21 (patch)
tree2a322e26330d4ec37029560d3cf88ca732047a9b /Kernel
parent60715695b285f8d74711e925300d22346ca838d2 (diff)
downloadserenity-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.cpp20
-rw-r--r--Kernel/Net/E1000NetworkAdapter.h2
-rw-r--r--Kernel/Net/RTL8139NetworkAdapter.cpp20
-rw-r--r--Kernel/Net/RTL8139NetworkAdapter.h2
-rw-r--r--Kernel/PCI/Access.cpp10
-rw-r--r--Kernel/PCI/Access.h2
-rw-r--r--Kernel/PCI/Definitions.h5
-rw-r--r--Kernel/PCI/Initializer.cpp22
-rw-r--r--Kernel/PCI/Initializer.h3
-rw-r--r--Kernel/init.cpp28
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();