mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:57:35 +00:00
Kernel/Storage: Don't try to enumerate PCI adapters if PCI is disabled
If there's no PCI bus, then it's safe to assume that we run on a x86 machine that has an ISA IDE controller in the system. In such case, we just instantiate a ISAIDEController object that assumes fixed locations of IDE IO ports.
This commit is contained in:
parent
fafa339264
commit
30eeba1981
11 changed files with 283 additions and 142 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
|
||||
* Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -16,9 +16,9 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
UNMAP_AFTER_INIT NonnullRefPtr<IDEController> IDEController::initialize()
|
||||
{
|
||||
return adopt_ref(*new IDEController(device_identifier, force_pio));
|
||||
return adopt_ref(*new IDEController());
|
||||
}
|
||||
|
||||
bool IDEController::reset()
|
||||
|
@ -61,121 +61,14 @@ void IDEController::complete_current_request(AsyncDeviceRequest::RequestResult)
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT IDEController::IDEController(PCI::DeviceIdentifier const& device_identifier, bool force_pio)
|
||||
: ATAController()
|
||||
, PCI::Device(device_identifier.address())
|
||||
, m_prog_if(device_identifier.prog_if())
|
||||
, m_interrupt_line(device_identifier.interrupt_line())
|
||||
UNMAP_AFTER_INIT IDEController::IDEController()
|
||||
{
|
||||
PCI::enable_io_space(device_identifier.address());
|
||||
PCI::enable_memory_space(device_identifier.address());
|
||||
initialize(force_pio);
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT IDEController::~IDEController()
|
||||
{
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x05) != 0;
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled_on_primary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x1) == 0x1;
|
||||
}
|
||||
|
||||
bool IDEController::is_pci_native_mode_enabled_on_secondary_channel() const
|
||||
{
|
||||
return (m_prog_if.value() & 0x4) == 0x4;
|
||||
}
|
||||
|
||||
bool IDEController::is_bus_master_capable() const
|
||||
{
|
||||
return m_prog_if.value() & (1 << 7);
|
||||
}
|
||||
|
||||
static const char* detect_controller_type(u8 programming_value)
|
||||
{
|
||||
switch (programming_value) {
|
||||
case 0x00:
|
||||
return "ISA Compatibility mode-only controller";
|
||||
case 0x05:
|
||||
return "PCI native mode-only controller";
|
||||
case 0x0A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode";
|
||||
case 0x0F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode";
|
||||
case 0x80:
|
||||
return "ISA Compatibility mode-only controller, supports bus mastering";
|
||||
case 0x85:
|
||||
return "PCI native mode-only controller, supports bus mastering";
|
||||
case 0x8A:
|
||||
return "ISA Compatibility mode controller, supports both channels switched to PCI native mode, supports bus mastering";
|
||||
case 0x8F:
|
||||
return "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering";
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void IDEController::initialize(bool force_pio)
|
||||
{
|
||||
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 @ {}: interrupt line was set to {}", pci_address(), m_interrupt_line.value());
|
||||
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 @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11));
|
||||
|
||||
if (!is_bus_master_capable())
|
||||
force_pio = true;
|
||||
|
||||
auto bar0 = PCI::get_BAR0(pci_address());
|
||||
auto primary_base_io = (bar0 == 0x1 || bar0 == 0) ? IOAddress(0x1F0) : IOAddress(bar0 & (~1));
|
||||
auto bar1 = PCI::get_BAR1(pci_address());
|
||||
auto primary_control_io = (bar1 == 0x1 || bar1 == 0) ? IOAddress(0x3F6) : IOAddress(bar1 & (~1));
|
||||
auto bar2 = PCI::get_BAR2(pci_address());
|
||||
auto secondary_base_io = (bar2 == 0x1 || bar2 == 0) ? IOAddress(0x170) : IOAddress(bar2 & (~1));
|
||||
auto bar3 = PCI::get_BAR3(pci_address());
|
||||
auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress(bar3 & (~1));
|
||||
|
||||
auto irq_line = m_interrupt_line.value();
|
||||
if (is_pci_native_mode_enabled()) {
|
||||
VERIFY(irq_line != 0);
|
||||
}
|
||||
|
||||
if (is_pci_native_mode_enabled_on_primary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { primary_base_io, primary_control_io }, IDEChannel::ChannelType::Primary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
}
|
||||
|
||||
m_channels[0].enable_irq();
|
||||
|
||||
if (is_pci_native_mode_enabled_on_secondary_channel()) {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, irq_line, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
} else {
|
||||
if (force_pio)
|
||||
m_channels.append(IDEChannel::create(*this, { secondary_base_io, secondary_control_io }, IDEChannel::ChannelType::Secondary));
|
||||
else
|
||||
m_channels.append(BMIDEChannel::create(*this, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
}
|
||||
|
||||
m_channels[1].enable_irq();
|
||||
}
|
||||
|
||||
RefPtr<StorageDevice> IDEController::device_by_channel_and_position(u32 index) const
|
||||
{
|
||||
switch (index) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue