1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:17:42 +00:00

Kernel/PCI: Propagate usage of DeviceIdentifier everywhere

This allows us to remove a bunch of PCI API functions, and instead to
leverage the cached data from DeviceIdentifier object in many places.
This commit is contained in:
Liav A 2021-09-23 10:20:54 +03:00 committed by Andreas Kling
parent da327746a2
commit 057f5a12c2
40 changed files with 150 additions and 186 deletions

View file

@ -120,36 +120,6 @@ u32 get_BAR(Address address, u8 bar)
} }
} }
u8 get_revision_id(Address address)
{
return read8(address, PCI_REVISION_ID);
}
u8 get_subclass(Address address)
{
return read8(address, PCI_SUBCLASS);
}
u8 get_class(Address address)
{
return read8(address, PCI_CLASS);
}
u8 get_programming_interface(Address address)
{
return read8(address, PCI_PROG_IF);
}
u16 get_subsystem_id(Address address)
{
return read16(address, PCI_SUBSYSTEM_ID);
}
u16 get_subsystem_vendor_id(Address address)
{
return read16(address, PCI_SUBSYSTEM_VENDOR_ID);
}
void enable_bus_mastering(Address address) void enable_bus_mastering(Address address)
{ {
auto value = read16(address, PCI_COMMAND); auto value = read16(address, PCI_COMMAND);

View file

@ -31,12 +31,6 @@ u32 get_BAR3(Address);
u32 get_BAR4(Address); u32 get_BAR4(Address);
u32 get_BAR5(Address); u32 get_BAR5(Address);
u32 get_BAR(Address address, u8 bar); u32 get_BAR(Address address, u8 bar);
u8 get_revision_id(Address);
u8 get_programming_interface(Address);
u8 get_subclass(Address);
u8 get_class(Address);
u16 get_subsystem_id(Address);
u16 get_subsystem_vendor_id(Address);
size_t get_BAR_space_size(Address, u8); size_t get_BAR_space_size(Address, u8);
void enable_bus_mastering(Address); void enable_bus_mastering(Address);
void disable_bus_mastering(Address); void disable_bus_mastering(Address);

View file

@ -62,10 +62,10 @@ static constexpr u16 UCHI_PORTSC_NON_WRITE_CLEAR_BIT_MASK = 0x1FF5; // This is u
static constexpr u8 UHCI_NUMBER_OF_ISOCHRONOUS_TDS = 128; static constexpr u8 UHCI_NUMBER_OF_ISOCHRONOUS_TDS = 128;
static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024; static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024;
KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::Address address) KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
// NOTE: This assumes that address is pointing to a valid UHCI controller. // NOTE: This assumes that address is pointing to a valid UHCI controller.
auto controller = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UHCIController(address))); auto controller = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UHCIController(pci_device_identifier.address())));
TRY(controller->initialize()); TRY(controller->initialize());
return controller; return controller;
} }

View file

@ -33,7 +33,7 @@ class UHCIController final
public: public:
static constexpr u8 NUMBER_OF_ROOT_PORTS = 2; static constexpr u8 NUMBER_OF_ROOT_PORTS = 2;
static KResultOr<NonnullRefPtr<UHCIController>> try_to_initialize(PCI::Address address); static KResultOr<NonnullRefPtr<UHCIController>> try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier);
virtual ~UHCIController() override; virtual ~UHCIController() override;
virtual StringView purpose() const override { return "UHCI"; } virtual StringView purpose() const override { return "UHCI"; }

View file

@ -34,7 +34,7 @@ UNMAP_AFTER_INIT void USBManagement::enumerate_controllers()
if (kernel_command_line().disable_uhci_controller()) if (kernel_command_line().disable_uhci_controller())
return; return;
if (auto uhci_controller_or_error = UHCIController::try_to_initialize(address); !uhci_controller_or_error.is_error()) if (auto uhci_controller_or_error = UHCIController::try_to_initialize(device_identifier); !uhci_controller_or_error.is_error())
m_controllers.append(uhci_controller_or_error.release_value()); m_controllers.append(uhci_controller_or_error.release_value());
return; return;

View file

@ -13,9 +13,9 @@ namespace Kernel::VirtIO {
unsigned Console::next_device_id = 0; unsigned Console::next_device_id = 0;
UNMAP_AFTER_INIT NonnullRefPtr<Console> Console::must_create(PCI::Address address) UNMAP_AFTER_INIT NonnullRefPtr<Console> Console::must_create(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
return adopt_ref_if_nonnull(new Console(address)).release_nonnull(); return adopt_ref_if_nonnull(new Console(pci_device_identifier)).release_nonnull();
} }
UNMAP_AFTER_INIT void Console::initialize() UNMAP_AFTER_INIT void Console::initialize()
@ -61,8 +61,8 @@ UNMAP_AFTER_INIT void Console::initialize()
} }
} }
UNMAP_AFTER_INIT Console::Console(PCI::Address address) UNMAP_AFTER_INIT Console::Console(PCI::DeviceIdentifier const& pci_device_identifier)
: VirtIO::Device(address) : VirtIO::Device(pci_device_identifier)
, m_device_id(next_device_id++) , m_device_id(next_device_id++)
{ {
} }

View file

@ -18,7 +18,7 @@ class Console
friend VirtIO::ConsolePort; friend VirtIO::ConsolePort;
public: public:
static NonnullRefPtr<Console> must_create(PCI::Address address); static NonnullRefPtr<Console> must_create(PCI::DeviceIdentifier const&);
virtual ~Console() override = default; virtual ~Console() override = default;
virtual StringView purpose() const override { return class_name(); } virtual StringView purpose() const override { return class_name(); }
@ -32,7 +32,7 @@ public:
private: private:
virtual StringView class_name() const override { return "VirtIOConsole"; } virtual StringView class_name() const override { return "VirtIOConsole"; }
explicit Console(PCI::Address); explicit Console(PCI::DeviceIdentifier const&);
enum class ControlEvent : u16 { enum class ControlEvent : u16 {
DeviceReady = 0, DeviceReady = 0,
DeviceAdd = 1, DeviceAdd = 1,

View file

@ -18,20 +18,20 @@ UNMAP_AFTER_INIT void detect()
{ {
if (kernel_command_line().disable_virtio()) if (kernel_command_line().disable_virtio())
return; return;
PCI::enumerate([&](const PCI::Address& address, PCI::DeviceIdentifier const& device_identifier) { PCI::enumerate([&](const PCI::Address&, PCI::DeviceIdentifier const& device_identifier) {
if (address.is_null() || device_identifier.hardware_id().is_null()) if (device_identifier.hardware_id().is_null())
return; return;
// TODO: We should also be checking that the device_id is in between 0x1000 - 0x107F inclusive // TODO: We should also be checking that the device_id is in between 0x1000 - 0x107F inclusive
if (device_identifier.hardware_id().vendor_id != PCI::VendorID::VirtIO) if (device_identifier.hardware_id().vendor_id != PCI::VendorID::VirtIO)
return; return;
switch (device_identifier.hardware_id().device_id) { switch (device_identifier.hardware_id().device_id) {
case PCI::DeviceID::VirtIOConsole: { case PCI::DeviceID::VirtIOConsole: {
auto& console = Console::must_create(address).leak_ref(); auto& console = Console::must_create(device_identifier).leak_ref();
console.initialize(); console.initialize();
break; break;
} }
case PCI::DeviceID::VirtIOEntropy: { case PCI::DeviceID::VirtIOEntropy: {
auto& rng = RNG::must_create(address).leak_ref(); auto& rng = RNG::must_create(device_identifier).leak_ref();
rng.initialize(); rng.initialize();
break; break;
} }
@ -46,12 +46,12 @@ UNMAP_AFTER_INIT void detect()
}); });
} }
static StringView const determine_device_class(const PCI::Address& address) static StringView const determine_device_class(PCI::DeviceIdentifier const& device_identifier)
{ {
if (PCI::get_revision_id(address) == 0) { if (device_identifier.revision_id().value() == 0) {
// Note: If the device is a legacy (or transitional) device, therefore, // Note: If the device is a legacy (or transitional) device, therefore,
// probe the subsystem ID in the PCI header and figure out the // probe the subsystem ID in the PCI header and figure out the
auto subsystem_device_id = PCI::get_subsystem_id(address); auto subsystem_device_id = device_identifier.subsystem_id().value();
switch (subsystem_device_id) { switch (subsystem_device_id) {
case 1: case 1:
return "VirtIONetAdapter"sv; return "VirtIONetAdapter"sv;
@ -67,7 +67,7 @@ static StringView const determine_device_class(const PCI::Address& address)
} }
} }
auto id = PCI::get_hardware_id(address); auto id = device_identifier.hardware_id();
VERIFY(id.vendor_id == PCI::VendorID::VirtIO); VERIFY(id.vendor_id == PCI::VendorID::VirtIO);
switch (id.device_id) { switch (id.device_id) {
case PCI::DeviceID::VirtIONetAdapter: case PCI::DeviceID::VirtIONetAdapter:
@ -150,11 +150,11 @@ UNMAP_AFTER_INIT void Device::initialize()
set_status_bit(DEVICE_STATUS_DRIVER); set_status_bit(DEVICE_STATUS_DRIVER);
} }
UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::Address address) UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::DeviceIdentifier const& device_identifier)
: PCI::Device(address) : PCI::Device(device_identifier.address())
, IRQHandler(PCI::get_interrupt_line(address)) , IRQHandler(PCI::get_interrupt_line(device_identifier.address()))
, m_io_base(IOAddress(PCI::get_BAR0(pci_address()) & ~1)) , m_io_base(IOAddress(PCI::get_BAR0(pci_address()) & ~1))
, m_class_name(VirtIO::determine_device_class(address)) , m_class_name(VirtIO::determine_device_class(device_identifier))
{ {
dbgln("{}: Found @ {}", m_class_name, pci_address()); dbgln("{}: Found @ {}", m_class_name, pci_address());
} }

View file

@ -93,7 +93,7 @@ public:
protected: protected:
virtual StringView class_name() const { return "VirtIO::Device"; } virtual StringView class_name() const { return "VirtIO::Device"; }
explicit Device(PCI::Address); explicit Device(PCI::DeviceIdentifier const&);
struct MappedMMIO { struct MappedMMIO {
OwnPtr<Memory::Region> base; OwnPtr<Memory::Region> base;
size_t size { 0 }; size_t size { 0 };

View file

@ -9,9 +9,9 @@
namespace Kernel::VirtIO { namespace Kernel::VirtIO {
UNMAP_AFTER_INIT NonnullRefPtr<RNG> RNG::must_create(PCI::Address address) UNMAP_AFTER_INIT NonnullRefPtr<RNG> RNG::must_create(PCI::DeviceIdentifier const& device_identifier)
{ {
return adopt_ref_if_nonnull(new RNG(address)).release_nonnull(); return adopt_ref_if_nonnull(new RNG(device_identifier)).release_nonnull();
} }
UNMAP_AFTER_INIT void RNG::initialize() UNMAP_AFTER_INIT void RNG::initialize()
@ -33,8 +33,8 @@ UNMAP_AFTER_INIT void RNG::initialize()
} }
} }
UNMAP_AFTER_INIT RNG::RNG(PCI::Address address) UNMAP_AFTER_INIT RNG::RNG(PCI::DeviceIdentifier const& device_identifier)
: VirtIO::Device(address) : VirtIO::Device(device_identifier)
{ {
} }

View file

@ -19,7 +19,7 @@ class RNG final
: public RefCounted<RNG> : public RefCounted<RNG>
, public VirtIO::Device { , public VirtIO::Device {
public: public:
static NonnullRefPtr<RNG> must_create(PCI::Address address); static NonnullRefPtr<RNG> must_create(PCI::DeviceIdentifier const&);
virtual StringView purpose() const override { return class_name(); } virtual StringView purpose() const override { return class_name(); }
virtual ~RNG() override = default; virtual ~RNG() override = default;
@ -27,7 +27,7 @@ public:
private: private:
virtual StringView class_name() const override { return "VirtIOConsole"; } virtual StringView class_name() const override { return "VirtIOConsole"; }
explicit RNG(PCI::Address); explicit RNG(PCI::DeviceIdentifier const&);
virtual bool handle_device_config_change() override; virtual bool handle_device_config_change() override;
virtual void handle_queue_update(u16 queue_index) override; virtual void handle_queue_update(u16 queue_index) override;
void request_entropy_from_host(); void request_entropy_from_host();

View file

@ -71,11 +71,11 @@ struct [[gnu::packed]] BochsDisplayMMIORegisters {
ExtensionRegisters extension_regs; ExtensionRegisters extension_regs;
}; };
UNMAP_AFTER_INIT NonnullRefPtr<BochsGraphicsAdapter> BochsGraphicsAdapter::initialize(PCI::Address address) UNMAP_AFTER_INIT NonnullRefPtr<BochsGraphicsAdapter> BochsGraphicsAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
PCI::HardwareID id = PCI::get_hardware_id(address); PCI::HardwareID id = pci_device_identifier.hardware_id();
VERIFY((id.vendor_id == PCI::VendorID::QEMUOld && id.device_id == 0x1111) || (id.vendor_id == PCI::VendorID::VirtualBox && id.device_id == 0xbeef)); VERIFY((id.vendor_id == PCI::VendorID::QEMUOld && id.device_id == 0x1111) || (id.vendor_id == PCI::VendorID::VirtualBox && id.device_id == 0xbeef));
return adopt_ref(*new BochsGraphicsAdapter(address)); return adopt_ref(*new BochsGraphicsAdapter(pci_device_identifier));
} }
void BochsGraphicsAdapter::set_framebuffer_to_big_endian_format() void BochsGraphicsAdapter::set_framebuffer_to_big_endian_format()
@ -100,21 +100,23 @@ void BochsGraphicsAdapter::set_framebuffer_to_little_endian_format()
full_memory_barrier(); full_memory_barrier();
} }
UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::Address pci_address) UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::DeviceIdentifier const& pci_device_identifier)
: PCI::Device(pci_address) : PCI::Device(pci_device_identifier.address())
, m_mmio_registers(PCI::get_BAR2(pci_address) & 0xfffffff0) , m_mmio_registers(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0)
, m_registers(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(m_mmio_registers)) , m_registers(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(m_mmio_registers))
{ {
// We assume safe resolutio is 1024x768x32 // We assume safe resolutio is 1024x768x32
m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(PhysicalAddress(PCI::get_BAR0(pci_address) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32)); m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32));
// FIXME: This is a very wrong way to do this... // FIXME: This is a very wrong way to do this...
GraphicsManagement::the().m_console = m_framebuffer_console; GraphicsManagement::the().m_console = m_framebuffer_console;
// Note: If we use VirtualBox graphics adapter (which is based on Bochs one), we need to use IO ports // Note: If we use VirtualBox graphics adapter (which is based on Bochs one), we need to use IO ports
auto id = PCI::get_hardware_id(pci_address); if (pci_device_identifier.hardware_id().vendor_id == 0x80ee && pci_device_identifier.hardware_id().device_id == 0xbeef)
if (id.vendor_id == 0x80ee && id.device_id == 0xbeef)
m_io_required = true; m_io_required = true;
if (pci_device_identifier.class_code().value() == 0x3 && pci_device_identifier.subclass_code().value() == 0x0)
m_is_vga_capable = true;
// Note: According to Gerd Hoffmann - "The linux driver simply does // Note: According to Gerd Hoffmann - "The linux driver simply does
// the unblank unconditionally. With bochs-display this is not needed but // the unblank unconditionally. With bochs-display this is not needed but
// it also has no bad side effect". // it also has no bad side effect".
@ -132,7 +134,7 @@ UNMAP_AFTER_INIT void BochsGraphicsAdapter::initialize_framebuffer_devices()
GraphicsDevice::Type BochsGraphicsAdapter::type() const GraphicsDevice::Type BochsGraphicsAdapter::type() const
{ {
if (PCI::get_class(pci_address()) == 0x3 && PCI::get_subclass(pci_address()) == 0x0) if (m_is_vga_capable)
return Type::VGACompatible; return Type::VGACompatible;
return Type::Bochs; return Type::Bochs;
} }

View file

@ -29,7 +29,7 @@ private:
TYPEDEF_DISTINCT_ORDERED_ID(u16, IndexID); TYPEDEF_DISTINCT_ORDERED_ID(u16, IndexID);
public: public:
static NonnullRefPtr<BochsGraphicsAdapter> initialize(PCI::Address); static NonnullRefPtr<BochsGraphicsAdapter> initialize(PCI::DeviceIdentifier const&);
virtual ~BochsGraphicsAdapter() = default; virtual ~BochsGraphicsAdapter() = default;
virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); } virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); }
@ -47,7 +47,7 @@ private:
virtual void enable_consoles() override; virtual void enable_consoles() override;
virtual void disable_consoles() override; virtual void disable_consoles() override;
explicit BochsGraphicsAdapter(PCI::Address); explicit BochsGraphicsAdapter(PCI::DeviceIdentifier const&);
IndexID index_id() const; IndexID index_id() const;
@ -71,5 +71,6 @@ private:
Spinlock m_console_mode_switch_lock; Spinlock m_console_mode_switch_lock;
bool m_console_enabled { false }; bool m_console_enabled { false };
bool m_io_required { false }; bool m_io_required { false };
bool m_is_vga_capable { false };
}; };
} }

View file

@ -50,23 +50,23 @@ void GraphicsManagement::activate_graphical_mode()
} }
} }
static inline bool is_vga_compatible_pci_device(PCI::Address address) static inline bool is_vga_compatible_pci_device(PCI::DeviceIdentifier const& device_identifier)
{ {
// Note: Check for Display Controller, VGA Compatible Controller or // Note: Check for Display Controller, VGA Compatible Controller or
// Unclassified, VGA-Compatible Unclassified Device // Unclassified, VGA-Compatible Unclassified Device
auto is_display_controller_vga_compatible = PCI::get_class(address) == 0x3 && PCI::get_subclass(address) == 0x0; auto is_display_controller_vga_compatible = device_identifier.class_code().value() == 0x3 && device_identifier.subclass_code().value() == 0x0;
auto is_general_pci_vga_compatible = PCI::get_class(address) == 0x0 && PCI::get_subclass(address) == 0x1; auto is_general_pci_vga_compatible = device_identifier.class_code().value() == 0x0 && device_identifier.subclass_code().value() == 0x1;
return is_display_controller_vga_compatible || is_general_pci_vga_compatible; return is_display_controller_vga_compatible || is_general_pci_vga_compatible;
} }
static inline bool is_display_controller_pci_device(PCI::Address address) static inline bool is_display_controller_pci_device(PCI::DeviceIdentifier const& device_identifier)
{ {
return PCI::get_class(address) == 0x3; return device_identifier.class_code().value() == 0x3;
} }
UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_device(const PCI::Address& address, PCI::HardwareID id) UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_device(PCI::DeviceIdentifier const& device_identifier)
{ {
VERIFY(is_vga_compatible_pci_device(address) || is_display_controller_pci_device(address)); VERIFY(is_vga_compatible_pci_device(device_identifier) || is_display_controller_pci_device(device_identifier));
auto add_and_configure_adapter = [&](GraphicsDevice& graphics_device) { auto add_and_configure_adapter = [&](GraphicsDevice& graphics_device) {
m_graphics_devices.append(graphics_device); m_graphics_devices.append(graphics_device);
if (!m_framebuffer_devices_allowed) { if (!m_framebuffer_devices_allowed) {
@ -77,24 +77,24 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
}; };
RefPtr<GraphicsDevice> adapter; RefPtr<GraphicsDevice> adapter;
switch (id.vendor_id) { switch (device_identifier.hardware_id().vendor_id) {
case PCI::VendorID::QEMUOld: case PCI::VendorID::QEMUOld:
if (id.device_id == 0x1111) if (device_identifier.hardware_id().device_id == 0x1111)
adapter = BochsGraphicsAdapter::initialize(address); adapter = BochsGraphicsAdapter::initialize(device_identifier);
break; break;
case PCI::VendorID::VirtualBox: case PCI::VendorID::VirtualBox:
if (id.device_id == 0xbeef) if (device_identifier.hardware_id().device_id == 0xbeef)
adapter = BochsGraphicsAdapter::initialize(address); adapter = BochsGraphicsAdapter::initialize(device_identifier);
break; break;
case PCI::VendorID::Intel: case PCI::VendorID::Intel:
adapter = IntelNativeGraphicsAdapter::initialize(address); adapter = IntelNativeGraphicsAdapter::initialize(device_identifier);
break; break;
case PCI::VendorID::VirtIO: case PCI::VendorID::VirtIO:
dmesgln("Graphics: Using VirtIO console"); dmesgln("Graphics: Using VirtIO console");
adapter = Graphics::VirtIOGPU::GraphicsAdapter::initialize(address); adapter = Graphics::VirtIOGPU::GraphicsAdapter::initialize(device_identifier);
break; break;
default: default:
if (!is_vga_compatible_pci_device(address)) if (!is_vga_compatible_pci_device(device_identifier))
break; break;
// Note: Although technically possible that a system has a // Note: Although technically possible that a system has a
// non-compatible VGA graphics device that was initialized by the // non-compatible VGA graphics device that was initialized by the
@ -108,10 +108,10 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
// utilize VESA BIOS extensions (that we don't currently) of these cards // utilize VESA BIOS extensions (that we don't currently) of these cards
// support, so we want to utilize the provided framebuffer of these // support, so we want to utilize the provided framebuffer of these
// devices, if possible. // devices, if possible.
if (!m_vga_adapter && PCI::is_io_space_enabled(address)) { if (!m_vga_adapter && PCI::is_io_space_enabled(device_identifier.address())) {
if (multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) { if (multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
dmesgln("Graphics: Using a preset resolution from the bootloader"); dmesgln("Graphics: Using a preset resolution from the bootloader");
adapter = VGACompatibleAdapter::initialize_with_preset_resolution(address, adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
multiboot_framebuffer_addr, multiboot_framebuffer_addr,
multiboot_framebuffer_width, multiboot_framebuffer_width,
multiboot_framebuffer_height, multiboot_framebuffer_height,
@ -119,7 +119,7 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
} }
} else { } else {
dmesgln("Graphics: Using a VGA compatible generic adapter"); dmesgln("Graphics: Using a VGA compatible generic adapter");
adapter = VGACompatibleAdapter::initialize(address); adapter = VGACompatibleAdapter::initialize(device_identifier);
} }
break; break;
} }
@ -129,8 +129,8 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
// Note: If IO space is enabled, this VGA adapter is operating in VGA mode. // Note: If IO space is enabled, this VGA adapter is operating in VGA mode.
// Note: If no other VGA adapter is attached as m_vga_adapter, we should attach it then. // Note: If no other VGA adapter is attached as m_vga_adapter, we should attach it then.
if (!m_vga_adapter && PCI::is_io_space_enabled(address) && adapter->type() == GraphicsDevice::Type::VGACompatible) { if (!m_vga_adapter && PCI::is_io_space_enabled(device_identifier.address()) && adapter->type() == GraphicsDevice::Type::VGACompatible) {
dbgln("Graphics adapter @ {} is operating in VGA mode", address); dbgln("Graphics adapter @ {} is operating in VGA mode", device_identifier.address());
m_vga_adapter = static_ptr_cast<VGACompatibleAdapter>(adapter); m_vga_adapter = static_ptr_cast<VGACompatibleAdapter>(adapter);
} }
return true; return true;
@ -179,13 +179,13 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
dbgln("Forcing no initialization of framebuffer devices"); dbgln("Forcing no initialization of framebuffer devices");
} }
PCI::enumerate([&](const PCI::Address& address, PCI::DeviceIdentifier const& device_identifier) { PCI::enumerate([&](const PCI::Address&, PCI::DeviceIdentifier const& device_identifier) {
// Note: Each graphics controller will try to set its native screen resolution // Note: Each graphics controller will try to set its native screen resolution
// upon creation. Later on, if we don't want to have framebuffer devices, a // upon creation. Later on, if we don't want to have framebuffer devices, a
// framebuffer console will take the control instead. // framebuffer console will take the control instead.
if (!is_vga_compatible_pci_device(address) && !is_display_controller_pci_device(address)) if (!is_vga_compatible_pci_device(device_identifier) && !is_display_controller_pci_device(device_identifier))
return; return;
determine_and_initialize_graphics_device(address, device_identifier.hardware_id()); determine_and_initialize_graphics_device(device_identifier);
}); });
if (m_graphics_devices.is_empty()) { if (m_graphics_devices.is_empty()) {

View file

@ -47,7 +47,7 @@ public:
void activate_graphical_mode(); void activate_graphical_mode();
private: private:
bool determine_and_initialize_graphics_device(const PCI::Address& address, PCI::HardwareID id); bool determine_and_initialize_graphics_device(PCI::DeviceIdentifier const&);
NonnullRefPtrVector<GraphicsDevice> m_graphics_devices; NonnullRefPtrVector<GraphicsDevice> m_graphics_devices;
RefPtr<Graphics::Console> m_console; RefPtr<Graphics::Console> m_console;

View file

@ -41,13 +41,12 @@ static bool is_supported_model(u16 device_id)
#define DDC2_I2C_ADDRESS 0x50 #define DDC2_I2C_ADDRESS 0x50
RefPtr<IntelNativeGraphicsAdapter> IntelNativeGraphicsAdapter::initialize(PCI::Address address) RefPtr<IntelNativeGraphicsAdapter> IntelNativeGraphicsAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
auto id = PCI::get_hardware_id(address); VERIFY(pci_device_identifier.hardware_id().vendor_id == 0x8086);
VERIFY(id.vendor_id == 0x8086); if (!is_supported_model(pci_device_identifier.hardware_id().device_id))
if (!is_supported_model(id.device_id))
return {}; return {};
return adopt_ref(*new IntelNativeGraphicsAdapter(address)); return adopt_ref(*new IntelNativeGraphicsAdapter(pci_device_identifier.address()));
} }
static size_t compute_dac_multiplier(size_t pixel_clock_in_khz) static size_t compute_dac_multiplier(size_t pixel_clock_in_khz)

View file

@ -105,7 +105,7 @@ private:
}; };
public: public:
static RefPtr<IntelNativeGraphicsAdapter> initialize(PCI::Address); static RefPtr<IntelNativeGraphicsAdapter> initialize(PCI::DeviceIdentifier const&);
private: private:
explicit IntelNativeGraphicsAdapter(PCI::Address); explicit IntelNativeGraphicsAdapter(PCI::Address);

View file

@ -13,14 +13,14 @@
namespace Kernel { namespace Kernel {
UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize_with_preset_resolution(PCI::Address address, PhysicalAddress m_framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch) UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize_with_preset_resolution(PCI::DeviceIdentifier const& pci_device_identifier, PhysicalAddress m_framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch)
{ {
return adopt_ref(*new VGACompatibleAdapter(address, m_framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch)); return adopt_ref(*new VGACompatibleAdapter(pci_device_identifier.address(), m_framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch));
} }
UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize(PCI::Address address) UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
return adopt_ref(*new VGACompatibleAdapter(address)); return adopt_ref(*new VGACompatibleAdapter(pci_device_identifier.address()));
} }
UNMAP_AFTER_INIT void VGACompatibleAdapter::initialize_framebuffer_devices() UNMAP_AFTER_INIT void VGACompatibleAdapter::initialize_framebuffer_devices()

View file

@ -20,8 +20,8 @@ class VGACompatibleAdapter : public GraphicsDevice
, public PCI::Device { , public PCI::Device {
AK_MAKE_ETERNAL AK_MAKE_ETERNAL
public: public:
static NonnullRefPtr<VGACompatibleAdapter> initialize_with_preset_resolution(PCI::Address, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch); static NonnullRefPtr<VGACompatibleAdapter> initialize_with_preset_resolution(PCI::DeviceIdentifier const&, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
static NonnullRefPtr<VGACompatibleAdapter> initialize(PCI::Address); static NonnullRefPtr<VGACompatibleAdapter> initialize(PCI::DeviceIdentifier const&);
virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); } virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); }

View file

@ -46,8 +46,8 @@ void GPU::initialize()
} }
} }
GPU::GPU(PCI::Address address) GPU::GPU(PCI::DeviceIdentifier const& device_identifier)
: VirtIO::Device(address) : VirtIO::Device(device_identifier)
{ {
auto region_or_error = MM.allocate_contiguous_kernel_region(32 * PAGE_SIZE, "VirtGPU Scratch Space", Memory::Region::Access::ReadWrite); auto region_or_error = MM.allocate_contiguous_kernel_region(32 * PAGE_SIZE, "VirtGPU Scratch Space", Memory::Region::Access::ReadWrite);
if (region_or_error.is_error()) if (region_or_error.is_error())

View file

@ -40,7 +40,7 @@ class GPU final
friend class FrameBufferDevice; friend class FrameBufferDevice;
public: public:
GPU(PCI::Address); GPU(PCI::DeviceIdentifier const&);
virtual ~GPU() override; virtual ~GPU() override;
void create_framebuffer_devices(); void create_framebuffer_devices();

View file

@ -13,16 +13,16 @@
namespace Kernel::Graphics::VirtIOGPU { namespace Kernel::Graphics::VirtIOGPU {
NonnullRefPtr<GraphicsAdapter> GraphicsAdapter::initialize(PCI::Address base_address) NonnullRefPtr<GraphicsAdapter> GraphicsAdapter::initialize(PCI::DeviceIdentifier const& device_identifier)
{ {
VERIFY(PCI::get_hardware_id(base_address).vendor_id == PCI::VendorID::VirtIO); VERIFY(device_identifier.hardware_id().vendor_id == PCI::VendorID::VirtIO);
return adopt_ref(*new GraphicsAdapter(base_address)); return adopt_ref(*new GraphicsAdapter(device_identifier));
} }
GraphicsAdapter::GraphicsAdapter(PCI::Address base_address) GraphicsAdapter::GraphicsAdapter(PCI::DeviceIdentifier const& device_identifier)
: PCI::Device(base_address) : PCI::Device(device_identifier.address())
{ {
m_gpu_device = adopt_ref(*new GPU(base_address)).leak_ref(); m_gpu_device = adopt_ref(*new GPU(device_identifier)).leak_ref();
m_gpu_device->initialize(); m_gpu_device->initialize();
} }

View file

@ -18,12 +18,12 @@ class GraphicsAdapter final
AK_MAKE_ETERNAL AK_MAKE_ETERNAL
public: public:
static NonnullRefPtr<GraphicsAdapter> initialize(PCI::Address); static NonnullRefPtr<GraphicsAdapter> initialize(PCI::DeviceIdentifier const&);
virtual bool framebuffer_devices_initialized() const override { return m_created_framebuffer_devices; } virtual bool framebuffer_devices_initialized() const override { return m_created_framebuffer_devices; }
private: private:
explicit GraphicsAdapter(PCI::Address base_address); explicit GraphicsAdapter(PCI::DeviceIdentifier const&);
virtual void initialize_framebuffer_devices() override; virtual void initialize_framebuffer_devices() override;
virtual Type type() const override { return Type::Raw; } virtual Type type() const override { return Type::Raw; }

View file

@ -180,15 +180,14 @@ static bool is_valid_device_id(u16 device_id)
} }
} }
UNMAP_AFTER_INIT RefPtr<E1000ENetworkAdapter> E1000ENetworkAdapter::try_to_initialize(PCI::Address address) UNMAP_AFTER_INIT RefPtr<E1000ENetworkAdapter> E1000ENetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
auto id = PCI::get_hardware_id(address); if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Intel)
if (id.vendor_id != PCI::VendorID::Intel)
return {}; return {};
if (!is_valid_device_id(id.device_id)) if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id))
return {}; return {};
u8 irq = PCI::get_interrupt_line(address); u8 irq = PCI::get_interrupt_line(pci_device_identifier.address());
auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000ENetworkAdapter(address, irq)); auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), irq));
if (!adapter) if (!adapter)
return {}; return {};
if (adapter->initialize()) if (adapter->initialize())

View file

@ -21,7 +21,7 @@ namespace Kernel {
class E1000ENetworkAdapter final class E1000ENetworkAdapter final
: public E1000NetworkAdapter { : public E1000NetworkAdapter {
public: public:
static RefPtr<E1000ENetworkAdapter> try_to_initialize(PCI::Address); static RefPtr<E1000ENetworkAdapter> try_to_initialize(PCI::DeviceIdentifier const&);
virtual bool initialize() override; virtual bool initialize() override;

View file

@ -158,15 +158,14 @@ UNMAP_AFTER_INIT static bool is_valid_device_id(u16 device_id)
} }
} }
UNMAP_AFTER_INIT RefPtr<E1000NetworkAdapter> E1000NetworkAdapter::try_to_initialize(PCI::Address address) UNMAP_AFTER_INIT RefPtr<E1000NetworkAdapter> E1000NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
auto id = PCI::get_hardware_id(address); if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Intel)
if (id.vendor_id != PCI::VendorID::Intel)
return {}; return {};
if (!is_valid_device_id(id.device_id)) if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id))
return {}; return {};
u8 irq = PCI::get_interrupt_line(address); u8 irq = PCI::get_interrupt_line(pci_device_identifier.address());
auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000NetworkAdapter(address, irq)); auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), irq));
if (!adapter) if (!adapter)
return {}; return {};
if (adapter->initialize()) if (adapter->initialize())

View file

@ -20,7 +20,7 @@ class E1000NetworkAdapter : public NetworkAdapter
, public PCI::Device , public PCI::Device
, public IRQHandler { , public IRQHandler {
public: public:
static RefPtr<E1000NetworkAdapter> try_to_initialize(PCI::Address); static RefPtr<E1000NetworkAdapter> try_to_initialize(PCI::DeviceIdentifier const&);
virtual bool initialize(); virtual bool initialize();

View file

@ -137,7 +137,7 @@ struct [[gnu::packed]] received_packet_header {
u16 length; u16 length;
}; };
UNMAP_AFTER_INIT RefPtr<NE2000NetworkAdapter> NE2000NetworkAdapter::try_to_initialize(PCI::Address address) UNMAP_AFTER_INIT RefPtr<NE2000NetworkAdapter> NE2000NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
constexpr auto ne2k_ids = Array { constexpr auto ne2k_ids = Array {
PCI::HardwareID { 0x10EC, 0x8029 }, // RealTek RTL-8029(AS) PCI::HardwareID { 0x10EC, 0x8029 }, // RealTek RTL-8029(AS)
@ -154,11 +154,10 @@ UNMAP_AFTER_INIT RefPtr<NE2000NetworkAdapter> NE2000NetworkAdapter::try_to_initi
PCI::HardwareID { 0x12c3, 0x5598 }, // Holtek HT80229 PCI::HardwareID { 0x12c3, 0x5598 }, // Holtek HT80229
PCI::HardwareID { 0x8c4a, 0x1980 }, // Winbond W89C940 (misprogrammed) PCI::HardwareID { 0x8c4a, 0x1980 }, // Winbond W89C940 (misprogrammed)
}; };
auto id = PCI::get_hardware_id(address); if (!ne2k_ids.span().contains_slow(pci_device_identifier.hardware_id()))
if (!ne2k_ids.span().contains_slow(id))
return {}; return {};
u8 irq = PCI::get_interrupt_line(address); u8 irq = PCI::get_interrupt_line(pci_device_identifier.address());
return adopt_ref_if_nonnull(new (nothrow) NE2000NetworkAdapter(address, irq)); return adopt_ref_if_nonnull(new (nothrow) NE2000NetworkAdapter(pci_device_identifier.address(), irq));
} }
UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq) UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address, u8 irq)

View file

@ -20,7 +20,7 @@ class NE2000NetworkAdapter final : public NetworkAdapter
, public PCI::Device , public PCI::Device
, public IRQHandler { , public IRQHandler {
public: public:
static RefPtr<NE2000NetworkAdapter> try_to_initialize(PCI::Address); static RefPtr<NE2000NetworkAdapter> try_to_initialize(PCI::DeviceIdentifier const&);
virtual ~NE2000NetworkAdapter() override; virtual ~NE2000NetworkAdapter() override;

View file

@ -73,17 +73,17 @@ RefPtr<NetworkAdapter> NetworkingManagement::lookup_by_name(const StringView& na
return found_adapter; return found_adapter;
} }
UNMAP_AFTER_INIT RefPtr<NetworkAdapter> NetworkingManagement::determine_network_device(PCI::Address address) const UNMAP_AFTER_INIT RefPtr<NetworkAdapter> NetworkingManagement::determine_network_device(PCI::DeviceIdentifier const& device_identifier) const
{ {
if (auto candidate = E1000NetworkAdapter::try_to_initialize(address); !candidate.is_null()) if (auto candidate = E1000NetworkAdapter::try_to_initialize(device_identifier); !candidate.is_null())
return candidate; return candidate;
if (auto candidate = E1000ENetworkAdapter::try_to_initialize(address); !candidate.is_null()) if (auto candidate = E1000ENetworkAdapter::try_to_initialize(device_identifier); !candidate.is_null())
return candidate; return candidate;
if (auto candidate = RTL8139NetworkAdapter::try_to_initialize(address); !candidate.is_null()) if (auto candidate = RTL8139NetworkAdapter::try_to_initialize(device_identifier); !candidate.is_null())
return candidate; return candidate;
if (auto candidate = RTL8168NetworkAdapter::try_to_initialize(address); !candidate.is_null()) if (auto candidate = RTL8168NetworkAdapter::try_to_initialize(device_identifier); !candidate.is_null())
return candidate; return candidate;
if (auto candidate = NE2000NetworkAdapter::try_to_initialize(address); !candidate.is_null()) if (auto candidate = NE2000NetworkAdapter::try_to_initialize(device_identifier); !candidate.is_null())
return candidate; return candidate;
return {}; return {};
} }
@ -91,11 +91,11 @@ UNMAP_AFTER_INIT RefPtr<NetworkAdapter> NetworkingManagement::determine_network_
bool NetworkingManagement::initialize() bool NetworkingManagement::initialize()
{ {
if (!kernel_command_line().is_physical_networking_disabled()) { if (!kernel_command_line().is_physical_networking_disabled()) {
PCI::enumerate([&](const PCI::Address& address, PCI::DeviceIdentifier const& device_identifier) { PCI::enumerate([&](const PCI::Address&, PCI::DeviceIdentifier const& device_identifier) {
// Note: PCI class 2 is the class of Network devices // Note: PCI class 2 is the class of Network devices
if (device_identifier.class_code().value() != 0x02) if (device_identifier.class_code().value() != 0x02)
return; return;
if (auto adapter = determine_network_device(address); !adapter.is_null()) if (auto adapter = determine_network_device(device_identifier); !adapter.is_null())
m_adapters.append(adapter.release_nonnull()); m_adapters.append(adapter.release_nonnull());
}); });
} }

View file

@ -36,7 +36,7 @@ public:
NonnullRefPtr<NetworkAdapter> loopback_adapter() const; NonnullRefPtr<NetworkAdapter> loopback_adapter() const;
private: private:
RefPtr<NetworkAdapter> determine_network_device(PCI::Address address) const; RefPtr<NetworkAdapter> determine_network_device(PCI::DeviceIdentifier const&) const;
NonnullRefPtrVector<NetworkAdapter> m_adapters; NonnullRefPtrVector<NetworkAdapter> m_adapters;
RefPtr<NetworkAdapter> m_loopback_adapter; RefPtr<NetworkAdapter> m_loopback_adapter;

View file

@ -112,14 +112,13 @@ namespace Kernel {
#define RX_BUFFER_SIZE 32768 #define RX_BUFFER_SIZE 32768
#define TX_BUFFER_SIZE PACKET_SIZE_MAX #define TX_BUFFER_SIZE PACKET_SIZE_MAX
UNMAP_AFTER_INIT RefPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::try_to_initialize(PCI::Address address) UNMAP_AFTER_INIT RefPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 }; constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 };
auto id = PCI::get_hardware_id(address); if (pci_device_identifier.hardware_id() != rtl8139_id)
if (id != rtl8139_id)
return {}; return {};
u8 irq = PCI::get_interrupt_line(address); u8 irq = PCI::get_interrupt_line(pci_device_identifier.address());
return adopt_ref_if_nonnull(new (nothrow) RTL8139NetworkAdapter(address, irq)); return adopt_ref_if_nonnull(new (nothrow) RTL8139NetworkAdapter(pci_device_identifier.address(), irq));
} }
UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq) UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq)

View file

@ -22,7 +22,7 @@ class RTL8139NetworkAdapter final : public NetworkAdapter
, public PCI::Device , public PCI::Device
, public IRQHandler { , public IRQHandler {
public: public:
static RefPtr<RTL8139NetworkAdapter> try_to_initialize(PCI::Address); static RefPtr<RTL8139NetworkAdapter> try_to_initialize(PCI::DeviceIdentifier const&);
virtual ~RTL8139NetworkAdapter() override; virtual ~RTL8139NetworkAdapter() override;

View file

@ -181,15 +181,14 @@ namespace Kernel {
#define TX_BUFFER_SIZE 0x1FF8 #define TX_BUFFER_SIZE 0x1FF8
#define RX_BUFFER_SIZE 0x1FF8 // FIXME: this should be increased (0x3FFF) #define RX_BUFFER_SIZE 0x1FF8 // FIXME: this should be increased (0x3FFF)
UNMAP_AFTER_INIT RefPtr<RTL8168NetworkAdapter> RTL8168NetworkAdapter::try_to_initialize(PCI::Address address) UNMAP_AFTER_INIT RefPtr<RTL8168NetworkAdapter> RTL8168NetworkAdapter::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
auto id = PCI::get_hardware_id(address); if (pci_device_identifier.hardware_id().vendor_id != PCI::VendorID::Realtek)
if (id.vendor_id != PCI::VendorID::Realtek)
return {}; return {};
if (id.device_id != 0x8168) if (pci_device_identifier.hardware_id().device_id != 0x8168)
return {}; return {};
u8 irq = PCI::get_interrupt_line(address); u8 irq = PCI::get_interrupt_line(pci_device_identifier.address());
return adopt_ref_if_nonnull(new (nothrow) RTL8168NetworkAdapter(address, irq)); return adopt_ref_if_nonnull(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier.address(), irq));
} }
bool RTL8168NetworkAdapter::determine_supported_version() const bool RTL8168NetworkAdapter::determine_supported_version() const

View file

@ -22,7 +22,7 @@ class RTL8168NetworkAdapter final : public NetworkAdapter
, public PCI::Device , public PCI::Device
, public IRQHandler { , public IRQHandler {
public: public:
static RefPtr<RTL8168NetworkAdapter> try_to_initialize(PCI::Address); static RefPtr<RTL8168NetworkAdapter> try_to_initialize(PCI::DeviceIdentifier const&);
virtual ~RTL8168NetworkAdapter() override; virtual ~RTL8168NetworkAdapter() override;

View file

@ -15,9 +15,9 @@
namespace Kernel { namespace Kernel {
NonnullRefPtr<AHCIController> AHCIController::initialize(PCI::Address address) NonnullRefPtr<AHCIController> AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{ {
return adopt_ref(*new AHCIController(address)); return adopt_ref(*new AHCIController(pci_device_identifier.address()));
} }
bool AHCIController::reset() bool AHCIController::reset()

View file

@ -25,7 +25,7 @@ class AHCIController final : public StorageController
friend class AHCIPort; friend class AHCIPort;
AK_MAKE_ETERNAL AK_MAKE_ETERNAL
public: public:
UNMAP_AFTER_INIT static NonnullRefPtr<AHCIController> initialize(PCI::Address address); UNMAP_AFTER_INIT static NonnullRefPtr<AHCIController> initialize(PCI::DeviceIdentifier const& pci_device_identifier);
virtual ~AHCIController() override; virtual ~AHCIController() override;
virtual RefPtr<StorageDevice> device(u32 index) const override; virtual RefPtr<StorageDevice> device(u32 index) const override;

View file

@ -16,9 +16,9 @@
namespace Kernel { namespace Kernel {
UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize(PCI::Address address, bool force_pio) UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
{ {
return adopt_ref(*new IDEController(address, force_pio)); return adopt_ref(*new IDEController(device_identifier, force_pio));
} }
bool IDEController::reset() bool IDEController::reset()
@ -51,12 +51,13 @@ void IDEController::complete_current_request(AsyncDeviceRequest::RequestResult)
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
UNMAP_AFTER_INIT IDEController::IDEController(PCI::Address address, bool force_pio) UNMAP_AFTER_INIT IDEController::IDEController(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
: StorageController() : StorageController()
, PCI::Device(address) , PCI::Device(device_identifier.address())
, m_prog_if(device_identifier.prog_if())
{ {
PCI::enable_io_space(address); PCI::enable_io_space(device_identifier.address());
PCI::enable_memory_space(address); PCI::enable_memory_space(device_identifier.address());
initialize(force_pio); initialize(force_pio);
} }
@ -66,22 +67,22 @@ UNMAP_AFTER_INIT IDEController::~IDEController()
bool IDEController::is_pci_native_mode_enabled() const bool IDEController::is_pci_native_mode_enabled() const
{ {
return (PCI::get_programming_interface(pci_address()) & 0x05) != 0; return (m_prog_if.value() & 0x05) != 0;
} }
bool IDEController::is_pci_native_mode_enabled_on_primary_channel() const bool IDEController::is_pci_native_mode_enabled_on_primary_channel() const
{ {
return (PCI::get_programming_interface(pci_address()) & 0x1) == 0x1; return (m_prog_if.value() & 0x1) == 0x1;
} }
bool IDEController::is_pci_native_mode_enabled_on_secondary_channel() const bool IDEController::is_pci_native_mode_enabled_on_secondary_channel() const
{ {
return (PCI::get_programming_interface(pci_address()) & 0x4) == 0x4; return (m_prog_if.value() & 0x4) == 0x4;
} }
bool IDEController::is_bus_master_capable() const bool IDEController::is_bus_master_capable() const
{ {
return PCI::get_programming_interface(pci_address()) & (1 << 7); return m_prog_if.value() & (1 << 7);
} }
static const char* detect_controller_type(u8 programming_value) static const char* detect_controller_type(u8 programming_value)
@ -114,7 +115,7 @@ UNMAP_AFTER_INIT void IDEController::initialize(bool force_pio)
auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1)); auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1));
dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base);
dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), PCI::get_interrupt_line(pci_address())); dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), PCI::get_interrupt_line(pci_address()));
dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(PCI::get_programming_interface(pci_address()))); dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.value()));
dbgln("IDE controller @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11)); dbgln("IDE controller @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11));
dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11)); dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11));

View file

@ -21,7 +21,7 @@ class IDEController final : public StorageController
, public PCI::Device { , public PCI::Device {
AK_MAKE_ETERNAL AK_MAKE_ETERNAL
public: public:
static NonnullRefPtr<IDEController> initialize(PCI::Address address, bool force_pio); static NonnullRefPtr<IDEController> initialize(PCI::DeviceIdentifier const&, bool force_pio);
virtual ~IDEController() override; virtual ~IDEController() override;
virtual RefPtr<StorageDevice> device(u32 index) const override; virtual RefPtr<StorageDevice> device(u32 index) const override;
@ -37,12 +37,14 @@ public:
private: private:
bool is_pci_native_mode_enabled_on_primary_channel() const; bool is_pci_native_mode_enabled_on_primary_channel() const;
bool is_pci_native_mode_enabled_on_secondary_channel() const; bool is_pci_native_mode_enabled_on_secondary_channel() const;
IDEController(PCI::Address address, bool force_pio); IDEController(PCI::DeviceIdentifier const&, bool force_pio);
RefPtr<StorageDevice> device_by_channel_and_position(u32 index) const; RefPtr<StorageDevice> device_by_channel_and_position(u32 index) const;
void initialize(bool force_pio); void initialize(bool force_pio);
void detect_disks(); void detect_disks();
NonnullRefPtrVector<IDEChannel> m_channels; NonnullRefPtrVector<IDEChannel> m_channels;
// FIXME: Find a better way to get the ProgrammingInterface
PCI::ProgrammingInterface m_prog_if;
}; };
} }

View file

@ -44,15 +44,15 @@ UNMAP_AFTER_INIT void StorageManagement::enumerate_controllers(bool force_pio)
VERIFY(m_controllers.is_empty()); VERIFY(m_controllers.is_empty());
if (!kernel_command_line().disable_physical_storage()) { if (!kernel_command_line().disable_physical_storage()) {
if (kernel_command_line().is_ide_enabled()) { if (kernel_command_line().is_ide_enabled()) {
PCI::enumerate([&](const PCI::Address& address, PCI::DeviceIdentifier const& device_identifier) { PCI::enumerate([&](const PCI::Address&, PCI::DeviceIdentifier const& device_identifier) {
if (device_identifier.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && device_identifier.subclass_code().value() == PCI_IDE_CTRL_SUBCLASS_ID) { if (device_identifier.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && device_identifier.subclass_code().value() == PCI_IDE_CTRL_SUBCLASS_ID) {
m_controllers.append(IDEController::initialize(address, force_pio)); m_controllers.append(IDEController::initialize(device_identifier, force_pio));
} }
}); });
} }
PCI::enumerate([&](const PCI::Address& address, PCI::DeviceIdentifier const& device_identifier) { PCI::enumerate([&](const PCI::Address&, PCI::DeviceIdentifier const& device_identifier) {
if (device_identifier.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && device_identifier.subclass_code().value() == PCI_SATA_CTRL_SUBCLASS_ID && device_identifier.prog_if().value() == PCI_AHCI_IF_PROGIF) { if (device_identifier.class_code().value() == PCI_MASS_STORAGE_CLASS_ID && device_identifier.subclass_code().value() == PCI_SATA_CTRL_SUBCLASS_ID && device_identifier.prog_if().value() == PCI_AHCI_IF_PROGIF) {
m_controllers.append(AHCIController::initialize(address)); m_controllers.append(AHCIController::initialize(device_identifier));
} }
}); });
} }