mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:38:10 +00:00
Kernel/Storage: Introduce basic abstraction layer for ATA components
This abstraction layer is mainly for ATA ports (AHCI ports, IDE ports). The goal is to create a convenient and flexible framework so it's possible to expand to support other types of controller (e.g. Intel PIIX and ICH IDE controllers) and to abstract operations that are possible on each component. Currently only the ATA IDE code is affected by this, making it much cleaner and readable - the ATA bus mastering code is moved to the ATAPort code so more implementations in the near future can take advantage of such functionality easily. In addition to that, the hierarchy of the ATA IDE code resembles more of the SATA AHCI code now, which means the IDEChannel class is solely responsible for getting interrupts, passing them for further processing in the ATAPort code to take care of the rest of the handling logic.
This commit is contained in:
parent
7719ef3a61
commit
0810c1b972
12 changed files with 1003 additions and 746 deletions
|
@ -87,19 +87,41 @@ UNMAP_AFTER_INIT void PCIIDEController::initialize(bool force_pio)
|
|||
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));
|
||||
|
||||
auto initialize_and_enumerate = [&force_pio](IDEChannel& channel) -> void {
|
||||
{
|
||||
auto result = channel.allocate_resources_for_pci_ide_controller({}, force_pio);
|
||||
// FIXME: Propagate errors properly
|
||||
VERIFY(!result.is_error());
|
||||
}
|
||||
{
|
||||
auto result = channel.detect_connected_devices();
|
||||
// FIXME: Propagate errors properly
|
||||
VERIFY(!result.is_error());
|
||||
}
|
||||
};
|
||||
|
||||
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 primary_base_io = (bar0 == 0x1 || bar0 == 0) ? IOAddress(0x1F0) : IOAddress(bar0 & (~1));
|
||||
// Note: the PCI IDE specification says we should access the IO address with an offset of 2
|
||||
// on native PCI IDE controllers.
|
||||
auto primary_control_io = (bar1 == 0x1 || bar1 == 0) ? IOAddress(0x3F6) : IOAddress((bar1 & (~1)) | 2);
|
||||
|
||||
auto secondary_base_io = (bar2 == 0x1 || bar2 == 0) ? IOAddress(0x170) : IOAddress(bar2 & (~1));
|
||||
// Note: the PCI IDE specification says we should access the IO address with an offset of 2
|
||||
// on native PCI IDE controllers.
|
||||
auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress((bar3 & (~1)) | 2);
|
||||
|
||||
// FIXME: On IOAPIC based system, this value might be completely wrong
|
||||
// On QEMU for example, it should be "u8 irq_line = 22;" to actually work.
|
||||
auto irq_line = m_interrupt_line.value();
|
||||
|
||||
if (is_pci_native_mode_enabled()) {
|
||||
VERIFY(irq_line != 0);
|
||||
}
|
||||
|
@ -109,7 +131,7 @@ UNMAP_AFTER_INIT void PCIIDEController::initialize(bool force_pio)
|
|||
} else {
|
||||
m_channels.append(IDEChannel::create(*this, { primary_base_io, primary_control_io, bus_master_base }, IDEChannel::ChannelType::Primary));
|
||||
}
|
||||
m_channels[0].initialize_with_pci_controller({}, force_pio);
|
||||
initialize_and_enumerate(m_channels[0]);
|
||||
m_channels[0].enable_irq();
|
||||
|
||||
if (is_pci_native_mode_enabled_on_secondary_channel()) {
|
||||
|
@ -117,7 +139,7 @@ UNMAP_AFTER_INIT void PCIIDEController::initialize(bool force_pio)
|
|||
} else {
|
||||
m_channels.append(IDEChannel::create(*this, { secondary_base_io, secondary_control_io, bus_master_base.offset(8) }, IDEChannel::ChannelType::Secondary));
|
||||
}
|
||||
m_channels[1].initialize_with_pci_controller({}, force_pio);
|
||||
initialize_and_enumerate(m_channels[1]);
|
||||
m_channels[1].enable_irq();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue