Ver código fonte

Revert "Kernel: Replace IRQHandler with the new InterruptHandler class"

This reverts commit 6c72736b26a81a8f03d8dd47989bfffe26bb1c95.

I am unable to boot on my home machine with this change in the tree.
Andreas Kling 5 anos atrás
pai
commit
e64c335e5a

+ 4 - 4
Kernel/ACPI/ACPIDynamicParser.cpp

@@ -41,20 +41,20 @@ void ACPIDynamicParser::initialize_without_rsdp()
 }
 
 ACPIDynamicParser::ACPIDynamicParser()
-    : InterruptHandler(9)
+    : IRQHandler(9)
     , ACPIStaticParser()
 
 {
     kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n");
 }
 ACPIDynamicParser::ACPIDynamicParser(ACPI_RAW::RSDPDescriptor20& rsdp)
-    : InterruptHandler(9)
+    : IRQHandler(9)
     , ACPIStaticParser(rsdp)
 {
     kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n");
 }
 
-void ACPIDynamicParser::handle_interrupt()
+void ACPIDynamicParser::handle_irq()
 {
     // FIXME: Implement IRQ handling of ACPI signals!
     ASSERT_NOT_REACHED();
@@ -90,4 +90,4 @@ void ACPIDynamicParser::build_namespace()
 {
     // FIXME: Implement AML Interpretation to build the ACPI namespace
     ASSERT_NOT_REACHED();
-}
+}

+ 4 - 4
Kernel/ACPI/ACPIDynamicParser.h

@@ -29,12 +29,12 @@
 #include <AK/RefPtr.h>
 #include <Kernel/ACPI/ACPIStaticParser.h>
 #include <Kernel/Devices/DiskDevice.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Lock.h>
 #include <Kernel/VM/PhysicalAddress.h>
 #include <Kernel/VM/PhysicalPage.h>
 
-class ACPIDynamicParser final : public InterruptHandler
+class ACPIDynamicParser final : public IRQHandler
     , ACPIStaticParser {
 public:
     static void initialize(ACPI_RAW::RSDPDescriptor20& rsdp);
@@ -53,7 +53,7 @@ protected:
 private:
     void build_namespace();
     // ^IRQHandler
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
 
     OwnPtr<Region> m_acpi_namespace;
-};
+};

+ 8 - 16
Kernel/Arch/i386/CPU.cpp

@@ -26,12 +26,12 @@
 
 #include "APIC.h"
 #include "Assertions.h"
+#include "IRQHandler.h"
 #include "PIC.h"
 #include "Process.h"
 #include <AK/Types.h>
 #include <Kernel/Arch/i386/CPU.h>
 #include <Kernel/KSyms.h>
-#include <Kernel/SharedInterruptHandler.h>
 #include <Kernel/VM/MemoryManager.h>
 #include <LibC/mallocdefs.h>
 
@@ -48,7 +48,7 @@ static DescriptorTablePointer s_gdtr;
 static Descriptor s_idt[256];
 static Descriptor s_gdt[256];
 
-static SharedInterruptHandler* s_irq_handler[256];
+static IRQHandler* s_irq_handler[16];
 
 static Vector<u16>* s_gdt_freelist;
 
@@ -435,25 +435,18 @@ static void unimp_trap()
     hang();
 }
 
-void register_shared_interrupt_handler(u8 irq, SharedInterruptHandler& handler)
+void register_irq_handler(u8 irq, IRQHandler& handler)
 {
     ASSERT(!s_irq_handler[irq]);
     s_irq_handler[irq] = &handler;
 }
 
-void unregister_shared_interrupt_handler(u8 irq, SharedInterruptHandler& handler)
+void unregister_irq_handler(u8 irq, IRQHandler& handler)
 {
     ASSERT(s_irq_handler[irq] == &handler);
     s_irq_handler[irq] = nullptr;
 }
 
-SharedInterruptHandler& get_interrupt_handler(u8 number)
-{
-    ASSERT(number < 256);
-    ASSERT(s_irq_handler[number] != nullptr);
-    return *s_irq_handler[number];
-}
-
 void register_interrupt_handler(u8 index, void (*f)())
 {
     s_idt[index].low = 0x00080000 | LSW((f));
@@ -531,8 +524,8 @@ void idt_init()
     register_interrupt_handler(0x5e, irq_14_asm_entry);
     register_interrupt_handler(0x5f, irq_15_asm_entry);
 
-    for (u8 i = 0; i < 255; ++i) {
-        SharedInterruptHandler::initialize(i);
+    for (u8 i = 0; i < 16; ++i) {
+        s_irq_handler[i] = nullptr;
     }
 
     flush_idt();
@@ -548,9 +541,8 @@ void handle_irq(RegisterDump regs)
     clac();
     ASSERT(regs.isr_number >= 0x50 && regs.isr_number <= 0x5f);
     u8 irq = (u8)(regs.isr_number - 0x50);
-    ASSERT(s_irq_handler[irq] != nullptr);
-    s_irq_handler[irq]->handle_interrupt();
-    // FIXME: Determine if we use IRQs or MSIs (in the future) to send EOI...
+    if (s_irq_handler[irq])
+        s_irq_handler[irq]->handle_irq();
     PIC::eoi(irq);
 }
 

+ 3 - 4
Kernel/Arch/i386/CPU.h

@@ -240,7 +240,7 @@ public:
     u64 raw[4];
 };
 
-class SharedInterruptHandler;
+class IRQHandler;
 struct RegisterDump;
 
 void gdt_init();
@@ -248,9 +248,8 @@ void idt_init();
 void sse_init();
 void register_interrupt_handler(u8 number, void (*f)());
 void register_user_callable_interrupt_handler(u8 number, void (*f)());
-void register_shared_interrupt_handler(u8 number, SharedInterruptHandler&);
-SharedInterruptHandler& get_interrupt_handler(u8 number);
-void unregister_shared_interrupt_handler(u8 number, SharedInterruptHandler&);
+void register_irq_handler(u8 number, IRQHandler&);
+void unregister_irq_handler(u8 number, IRQHandler&);
 void flush_idt();
 void flush_gdt();
 void load_task_register(u16 selector);

+ 0 - 14
Kernel/Arch/i386/PIC.cpp

@@ -75,20 +75,6 @@ void enable(u8 irq)
     }
 }
 
-bool is_enabled(u8 irq)
-{
-    InterruptDisabler disabler;
-    u8 imr;
-    if (irq & 8) {
-        imr = IO::in8(PIC1_CMD);
-        imr &= (1 << (irq - 8));
-    } else {
-        imr = IO::in8(PIC0_CMD);
-        imr &= (1 << irq);
-    }
-    return (!!imr);
-}
-
 void eoi(u8 irq)
 {
     if (irq & 8)

+ 0 - 1
Kernel/Arch/i386/PIC.h

@@ -34,7 +34,6 @@ void enable(u8 number);
 void disable(u8 number);
 void eoi(u8 number);
 void initialize();
-bool is_enabled(u8 number);
 u16 get_isr();
 u16 get_irr();
 

+ 2 - 1
Kernel/Devices/BlockDevice.h

@@ -34,9 +34,10 @@ public:
 
     size_t block_size() const { return m_block_size; }
     virtual bool is_seekable() const override { return true; }
+
 protected:
     BlockDevice(unsigned major, unsigned minor, size_t block_size = PAGE_SIZE)
-        : Device(major, minor, (u8)DEVICE_TYPE::BLOCK_DEVICE)
+        : Device(major, minor)
         , m_block_size(block_size)
     {
     }

+ 1 - 1
Kernel/Devices/CharacterDevice.h

@@ -34,7 +34,7 @@ public:
 
 protected:
     CharacterDevice(unsigned major, unsigned minor)
-        : Device(major, minor, (u8)DEVICE_TYPE::CHAR_DEVICE)
+        : Device(major, minor)
     {
     }
 

+ 25 - 9
Kernel/Devices/Device.cpp

@@ -25,32 +25,48 @@
  */
 
 #include <Kernel/Devices/Device.h>
-#include <Kernel/Devices/HardwareEventsManager.h>
+#include <Kernel/FileSystem/InodeMetadata.h>
 #include <LibC/errno_numbers.h>
 
+static HashMap<u32, Device*>* s_all_devices;
+
+HashMap<u32, Device*>& Device::all_devices()
+{
+    if (s_all_devices == nullptr)
+        s_all_devices = new HashMap<u32, Device*>;
+    return *s_all_devices;
+}
+
 void Device::for_each(Function<void(Device&)> callback)
 {
-    for (auto* entry : HardwareEventsManager::the().get_devices_list()) {
-        ASSERT(entry != nullptr);
-        callback(*entry);
-    }
+    for (auto& entry : all_devices())
+        callback(*entry.value);
 }
 
 Device* Device::get_device(unsigned major, unsigned minor)
 {
-    return HardwareEventsManager::the().get_device(major, minor);
+    auto it = all_devices().find(encoded_device(major, minor));
+    if (it == all_devices().end())
+        return nullptr;
+    return it->value;
 }
 
-Device::Device(unsigned major, unsigned minor, u8 device_type)
+Device::Device(unsigned major, unsigned minor)
     : m_major(major)
     , m_minor(minor)
 {
-    HardwareEventsManager::the().register_device(*this, device_type);
+    u32 device_id = encoded_device(major, minor);
+    auto it = all_devices().find(device_id);
+    if (it != all_devices().end()) {
+        dbg() << "Already registered " << major << "," << minor << ": " << it->value->class_name();
+    }
+    ASSERT(!all_devices().contains(device_id));
+    all_devices().set(device_id, this);
 }
 
 Device::~Device()
 {
-    HardwareEventsManager::the().unregister_device(*this);
+    all_devices().remove(encoded_device(m_major, m_minor));
 }
 
 String Device::absolute_path() const

+ 3 - 9
Kernel/Devices/Device.h

@@ -39,11 +39,6 @@
 #include <Kernel/FileSystem/File.h>
 #include <Kernel/UnixTypes.h>
 
-enum class DEVICE_TYPE {
-    BLOCK_DEVICE = 1,
-    CHAR_DEVICE = 2
-};
-
 class Device : public File {
 public:
     virtual ~Device() override;
@@ -60,17 +55,16 @@ public:
     virtual bool is_device() const override { return true; }
     virtual bool is_disk_device() const { return false; }
 
-    virtual bool is_block_device() const override { return false; }
-    virtual bool is_character_device() const override { return true; }
-
     static void for_each(Function<void(Device&)>);
     static Device* get_device(unsigned major, unsigned minor);
 
 protected:
-    Device(unsigned major, unsigned minor, u8 device_type);
+    Device(unsigned major, unsigned minor);
     void set_uid(uid_t uid) { m_uid = uid; }
     void set_gid(gid_t gid) { m_gid = gid; }
 
+    static HashMap<u32, Device*>& all_devices();
+
 private:
     unsigned m_major { 0 };
     unsigned m_minor { 0 };

+ 7 - 7
Kernel/Devices/FloppyDiskDevice.cpp

@@ -109,7 +109,7 @@ const char* FloppyDiskDevice::class_name() const
 }
 
 FloppyDiskDevice::FloppyDiskDevice(FloppyDiskDevice::DriveType type)
-    : InterruptHandler(IRQ_FLOPPY_DRIVE)
+    : IRQHandler(IRQ_FLOPPY_DRIVE)
     , DiskDevice(89, (type == FloppyDiskDevice::DriveType::Master) ? 0 : 1, BYTES_PER_SECTOR)
     , m_io_base_addr((type == FloppyDiskDevice::DriveType::Master) ? 0x3F0 : 0x370)
 {
@@ -167,7 +167,7 @@ bool FloppyDiskDevice::read_sectors_with_dma(u16 lba, u16 count, u8* outbuf)
     //while(start < PIT::seconds_since_boot() + 1)
     //    ;
 
-    disable_interrupts();
+    disable_irq();
 
     IO::out8(0xA, FLOPPY_DMA_CHANNEL | 0x4); // Channel 2 SEL, MASK_ON = 1
     IO::out8(0x0B, 0x56);                    // Begin DMA, Single Transfer, Increment, Auto, FDC -> RAM, Channel 2
@@ -195,7 +195,7 @@ bool FloppyDiskDevice::read_sectors_with_dma(u16 lba, u16 count, u8* outbuf)
         send_byte(0x1b); // GPL3 value. The Datasheet doesn't really specify the values for this properly...
         send_byte(0xff);
 
-        enable_interrupts();
+        enable_irq();
 
         wait_for_irq(); // TODO: See if there was a lockup here via some "timeout counter"
         m_interrupted = false;
@@ -269,7 +269,7 @@ bool FloppyDiskDevice::write_sectors_with_dma(u16 lba, u16 count, const u8* inbu
     //while(start < PIT::seconds_since_boot() + 1)
     //    ;
 
-    disable_interrupts();
+    disable_irq();
 
     IO::out8(0xA, FLOPPY_DMA_CHANNEL | 0x4); // Channel 2 SEL, MASK_ON = 1
     IO::out8(0x0B, 0x5A);                    // Begin DMA, Single Transfer, Increment, Auto, RAM -> FDC, Channel 2
@@ -295,7 +295,7 @@ bool FloppyDiskDevice::write_sectors_with_dma(u16 lba, u16 count, const u8* inbu
         send_byte(0x1b); // GPL3 value. The Datasheet doesn't really specify the values for this properly...
         send_byte(0xff);
 
-        enable_interrupts();
+        enable_irq();
 
         wait_for_irq(); // TODO: See if there was a lockup here via some "timeout counter"
         m_interrupted = false;
@@ -358,7 +358,7 @@ bool FloppyDiskDevice::wait_for_irq()
     return true;
 }
 
-void FloppyDiskDevice::handle_interrupt()
+void FloppyDiskDevice::handle_irq()
 {
     // The only thing we need to do is acknowledge the IRQ happened
     m_interrupted = true;
@@ -512,7 +512,7 @@ void FloppyDiskDevice::initialize()
     kprintf("fdc: m_io_base = 0x%x IRQn = %d\n", m_io_base_addr, IRQ_FLOPPY_DRIVE);
 #endif
 
-    enable_interrupts();
+    enable_irq();
 
     // Get the version of the Floppy Disk Controller
     send_byte(FloppyCommand::Version);

+ 3 - 3
Kernel/Devices/FloppyDiskDevice.h

@@ -99,7 +99,7 @@
 
 #include <AK/RefPtr.h>
 #include <Kernel/Devices/DiskDevice.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Lock.h>
 #include <Kernel/VM/PhysicalAddress.h>
 #include <Kernel/VM/PhysicalPage.h>
@@ -120,7 +120,7 @@ struct FloppyControllerCommand {
 // uses the Intel 82077A controller. More about this controller can
 // be found here: http://www.buchty.net/casio/files/82077.pdf
 //
-class FloppyDiskDevice final : public InterruptHandler
+class FloppyDiskDevice final : public IRQHandler
     , public DiskDevice {
     AK_MAKE_ETERNAL
 
@@ -176,7 +176,7 @@ protected:
 
 private:
     // ^IRQHandler
-    void handle_interrupt();
+    void handle_irq();
 
     // ^DiskDevice
     virtual const char* class_name() const override;

+ 3 - 3
Kernel/Devices/KeyboardDevice.cpp

@@ -483,7 +483,7 @@ void KeyboardDevice::key_state_changed(u8 raw, bool pressed)
     m_has_e0_prefix = false;
 }
 
-void KeyboardDevice::handle_interrupt()
+void KeyboardDevice::handle_irq()
 {
     for (;;) {
         u8 status = IO::in8(I8042_STATUS);
@@ -551,7 +551,7 @@ KeyboardDevice& KeyboardDevice::the()
 }
 
 KeyboardDevice::KeyboardDevice()
-    : InterruptHandler(IRQ_KEYBOARD)
+    : IRQHandler(IRQ_KEYBOARD)
     , CharacterDevice(85, 1)
 {
     s_the = this;
@@ -563,7 +563,7 @@ KeyboardDevice::KeyboardDevice()
     while (IO::in8(I8042_STATUS) & I8042_BUFFER_FULL)
         IO::in8(I8042_BUFFER);
 
-    enable_interrupts();
+    enable_irq();
 }
 
 KeyboardDevice::~KeyboardDevice()

+ 3 - 3
Kernel/Devices/KeyboardDevice.h

@@ -26,16 +26,16 @@
 
 #pragma once
 
+#include "IRQHandler.h"
 #include "KeyCode.h"
 #include <AK/CircularQueue.h>
 #include <AK/DoublyLinkedList.h>
 #include <AK/Types.h>
 #include <Kernel/Devices/CharacterDevice.h>
-#include <Kernel/InterruptHandler.h>
 
 class KeyboardClient;
 
-class KeyboardDevice final : public InterruptHandler
+class KeyboardDevice final : public IRQHandler
     , public CharacterDevice {
     AK_MAKE_ETERNAL
 public:
@@ -57,7 +57,7 @@ public:
 
 private:
     // ^IRQHandler
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
 
     // ^CharacterDevice
     virtual const char* class_name() const override { return "KeyboardDevice"; }

+ 17 - 17
Kernel/Devices/PATAChannel.cpp

@@ -112,25 +112,18 @@ static Lock& s_lock()
     return *lock;
 };
 
-OwnPtr<PATAChannel> PATAChannel::autodetect(ChannelType type, bool force_pio)
+OwnPtr<PATAChannel> PATAChannel::create(ChannelType type, bool force_pio)
 {
-    PCI::Address found_address;
-    PCI::enumerate_all([&](const PCI::Address& address, PCI::ID id) {
-        if (PCI::get_class(address) == PCI_Mass_Storage_Class && PCI::get_subclass(address) == PCI_IDE_Controller_Subclass) {
-            found_address = address;
-            kprintf("PATAChannel: PATA Controller found! id=%w:%w\n", id.vendor_id, id.device_id);
-        }
-    });
-    return make<PATAChannel>(found_address, type, force_pio);
+    return make<PATAChannel>(type, force_pio);
 }
 
-PATAChannel::PATAChannel(PCI::Address pci_address, ChannelType type, bool force_pio)
-    : PCI::Device(pci_address, (type == ChannelType::Primary ? PATA_PRIMARY_IRQ : PATA_SECONDARY_IRQ))
+PATAChannel::PATAChannel(ChannelType type, bool force_pio)
+    : IRQHandler((type == ChannelType::Primary ? PATA_PRIMARY_IRQ : PATA_SECONDARY_IRQ))
     , m_channel_number((type == ChannelType::Primary ? 0 : 1))
     , m_io_base((type == ChannelType::Primary ? 0x1F0 : 0x170))
     , m_control_base((type == ChannelType::Primary ? 0x3f6 : 0x376))
 {
-    disable_interrupts();
+    disable_irq();
 
     m_dma_enabled.resource() = true;
     ProcFS::add_sys_bool("ide_dma", m_dma_enabled);
@@ -147,8 +140,14 @@ PATAChannel::~PATAChannel()
 
 void PATAChannel::initialize(bool force_pio)
 {
+    PCI::enumerate_all([this](const PCI::Address& address, PCI::ID id) {
+        if (PCI::get_class(address) == PCI_Mass_Storage_Class && PCI::get_subclass(address) == PCI_IDE_Controller_Subclass) {
+            m_pci_address = address;
+            kprintf("PATAChannel: PATA Controller found! id=%w:%w\n", id.vendor_id, id.device_id);
+        }
+    });
 
-    if (get_pci_address().is_null()) {
+    if (m_pci_address.is_null()) {
         kprintf("PATAChannel: PCI address was null; can not set up DMA\n");
         return;
     }
@@ -159,9 +158,9 @@ void PATAChannel::initialize(bool force_pio)
     }
 
     // Let's try to set up DMA transfers.
-    PCI::enable_bus_mastering(get_pci_address());
+    PCI::enable_bus_mastering(m_pci_address);
     prdt().end_of_table = 0x8000;
-    m_bus_master_base = PCI::get_BAR4(get_pci_address()) & 0xfffc;
+    m_bus_master_base = PCI::get_BAR4(m_pci_address) & 0xfffc;
     m_dma_buffer_page = MM.allocate_supervisor_physical_page();
     kprintf("PATAChannel: Bus master IDE: I/O @ %x\n", m_bus_master_base);
 }
@@ -182,11 +181,12 @@ static void print_ide_status(u8 status)
 void PATAChannel::wait_for_irq()
 {
     cli();
-    InterruptHandler::Enabler enabler(*this);
+    enable_irq();
     current->wait_on(m_irq_queue);
+    disable_irq();
 }
 
-void PATAChannel::handle_interrupt()
+void PATAChannel::handle_irq()
 {
     u8 status = IO::in8(m_io_base + ATA_REG_STATUS);
     if (status & ATA_SR_ERR) {

+ 6 - 6
Kernel/Devices/PATAChannel.h

@@ -38,10 +38,9 @@
 
 #include <AK/OwnPtr.h>
 #include <AK/RefPtr.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Lock.h>
 #include <Kernel/PCI/Access.h>
-#include <Kernel/PCI/Device.h>
 #include <Kernel/VM/PhysicalAddress.h>
 #include <Kernel/VM/PhysicalPage.h>
 #include <Kernel/WaitQueue.h>
@@ -53,7 +52,7 @@ struct PhysicalRegionDescriptor {
 };
 
 class PATADiskDevice;
-class PATAChannel final : public PCI::Device {
+class PATAChannel final : public IRQHandler {
     friend class PATADiskDevice;
     AK_MAKE_ETERNAL
 public:
@@ -63,8 +62,8 @@ public:
     };
 
 public:
-    static OwnPtr<PATAChannel> autodetect(ChannelType type, bool force_pio);
-    PATAChannel(PCI::Address pci_address, ChannelType type, bool force_pio);
+    static OwnPtr<PATAChannel> create(ChannelType type, bool force_pio);
+    PATAChannel(ChannelType type, bool force_pio);
     virtual ~PATAChannel() override;
 
     RefPtr<PATADiskDevice> master_device() { return m_master; };
@@ -72,7 +71,7 @@ public:
 
 private:
     //^ IRQHandler
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
 
     void initialize(bool force_pio);
     void detect_disks();
@@ -91,6 +90,7 @@ private:
 
     WaitQueue m_irq_queue;
 
+    PCI::Address m_pci_address;
     PhysicalRegionDescriptor& prdt() { return *reinterpret_cast<PhysicalRegionDescriptor*>(m_prdt_page->paddr().offset(0xc0000000).as_ptr()); }
     RefPtr<PhysicalPage> m_prdt_page;
     RefPtr<PhysicalPage> m_dma_buffer_page;

+ 1 - 1
Kernel/Devices/PATADiskDevice.h

@@ -31,7 +31,7 @@
 #pragma once
 
 #include <Kernel/Devices/DiskDevice.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Lock.h>
 
 class PATAChannel;

+ 3 - 3
Kernel/Devices/PS2MouseDevice.cpp

@@ -54,7 +54,7 @@
 static PS2MouseDevice* s_the;
 
 PS2MouseDevice::PS2MouseDevice()
-    : InterruptHandler(IRQ_MOUSE)
+    : IRQHandler(IRQ_MOUSE)
     , CharacterDevice(10, 1)
 {
     s_the = this;
@@ -70,7 +70,7 @@ PS2MouseDevice& PS2MouseDevice::the()
     return *s_the;
 }
 
-void PS2MouseDevice::handle_interrupt()
+void PS2MouseDevice::handle_irq()
 {
     for (;;) {
         u8 status = IO::in8(I8042_STATUS);
@@ -242,7 +242,7 @@ void PS2MouseDevice::initialize_device()
         kprintf("PS2MouseDevice: No mouse wheel detected!\n");
     }
 
-    enable_interrupts();
+    enable_irq();
 }
 
 void PS2MouseDevice::expect_ack()

+ 3 - 3
Kernel/Devices/PS2MouseDevice.h

@@ -28,10 +28,10 @@
 
 #include <AK/CircularQueue.h>
 #include <Kernel/Devices/CharacterDevice.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/MousePacket.h>
 
-class PS2MouseDevice final : public InterruptHandler
+class PS2MouseDevice final : public IRQHandler
     , public CharacterDevice {
 public:
     PS2MouseDevice();
@@ -47,7 +47,7 @@ public:
 
 private:
     // ^IRQHandler
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
 
     // ^CharacterDevice
     virtual const char* class_name() const override { return "PS2MouseDevice"; }

+ 5 - 4
Kernel/Devices/SB16.cpp

@@ -74,7 +74,7 @@ void SB16::set_sample_rate(uint16_t hz)
 static SB16* s_the;
 
 SB16::SB16()
-    : InterruptHandler(5)
+    : IRQHandler(5)
     , CharacterDevice(42, 42) // ### ?
 {
     s_the = this;
@@ -92,7 +92,7 @@ SB16& SB16::the()
 
 void SB16::initialize()
 {
-    disable_interrupts();
+    disable_irq();
 
     IO::out8(0x226, 1);
     IO::delay();
@@ -153,7 +153,7 @@ void SB16::dma_start(uint32_t length)
     IO::out8(0xd4, (channel % 4));
 }
 
-void SB16::handle_interrupt()
+void SB16::handle_irq()
 {
     // Stop sound output ready for the next block.
     dsp_write(0xd5);
@@ -168,8 +168,9 @@ void SB16::handle_interrupt()
 void SB16::wait_for_irq()
 {
     cli();
-    InterruptHandler::Enabler enabler(*this);
+    enable_irq();
     current->wait_on(m_irq_queue);
+    disable_irq();
 }
 
 ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length)

+ 3 - 3
Kernel/Devices/SB16.h

@@ -28,14 +28,14 @@
 
 #include <AK/CircularQueue.h>
 #include <Kernel/Devices/CharacterDevice.h>
-#include <Kernel/InterruptHandler.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/VM/PhysicalAddress.h>
 #include <Kernel/VM/PhysicalPage.h>
 #include <Kernel/WaitQueue.h>
 
 class SB16;
 
-class SB16 final : public InterruptHandler
+class SB16 final : public IRQHandler
     , public CharacterDevice {
 public:
     SB16();
@@ -51,7 +51,7 @@ public:
 
 private:
     // ^IRQHandler
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
 
     // ^CharacterDevice
     virtual const char* class_name() const override { return "SB16"; }

+ 13 - 28
Kernel/Devices/HardwareEventsManager.cpp → Kernel/IRQHandler.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -24,42 +24,27 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <Kernel/Devices/HardwareEventsManager.h>
+#include "IRQHandler.h"
+#include <Kernel/Arch/i386/CPU.h>
+#include <Kernel/Arch/i386/PIC.h>
 
-static HardwareEventsManager* s_hardware_events_manager;
-
-HardwareEventsManager& HardwareEventsManager::the()
-{
-    if (s_hardware_events_manager == nullptr) {
-        s_hardware_events_manager = new HardwareEventsManager();
-    }
-    return *s_hardware_events_manager;
-}
-
-HashTable<Device*>& HardwareEventsManager::get_devices_list()
+IRQHandler::IRQHandler(u8 irq)
+    : m_irq_number(irq)
 {
-    return m_devices;
+    register_irq_handler(m_irq_number, *this);
 }
 
-void HardwareEventsManager::unregister_device(Device& device)
+IRQHandler::~IRQHandler()
 {
-    get_devices_list().remove(&device);
+    unregister_irq_handler(m_irq_number, *this);
 }
 
-HardwareEventsManager::HardwareEventsManager()
+void IRQHandler::enable_irq()
 {
+    PIC::enable(m_irq_number);
 }
 
-Device* HardwareEventsManager::get_device(unsigned major, unsigned minor)
-{
-    for (auto* entry : HardwareEventsManager::get_devices_list()) {
-        ASSERT(entry != nullptr);
-        if (entry->major() == major && entry->minor() == minor)
-            return entry;
-    }
-    return nullptr;
-}
-void HardwareEventsManager::register_device(Device& device, u8)
+void IRQHandler::disable_irq()
 {
-    get_devices_list().set(&device);
+    PIC::disable(m_irq_number);
 }

+ 13 - 11
Kernel/Devices/HardwareEventsManager.h → Kernel/IRQHandler.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,18 +27,20 @@
 #pragma once
 
 #include <AK/Types.h>
-#include <Kernel/Devices/Device.h>
 
-class HardwareEventsManager {
+class IRQHandler {
 public:
-    static HardwareEventsManager& the();
-    void register_device(Device&, u8);
-    void unregister_device(Device&);
-    void register_device_event();
-    Device* get_device(unsigned, unsigned);
-    HashTable<Device*>& get_devices_list();
+    virtual ~IRQHandler();
+    virtual void handle_irq() = 0;
+
+    u8 irq_number() const { return m_irq_number; }
+
+    void enable_irq();
+    void disable_irq();
+
+protected:
+    explicit IRQHandler(u8 irq);
 
 private:
-    HashTable<Device*> m_devices;
-    HardwareEventsManager();
+    u8 m_irq_number { 0 };
 };

+ 1 - 4
Kernel/Makefile

@@ -15,7 +15,6 @@ OBJS = \
     Arch/i386/PIT.o \
     CMOS.o \
     Console.o \
-    Devices/HardwareEventsManager.o \
     Devices/BXVGADevice.o \
     Devices/BlockDevice.o \
     Devices/CharacterDevice.o \
@@ -55,8 +54,7 @@ OBJS = \
     FileSystem/VirtualFileSystem.o \
     Heap/SlabAllocator.o \
     Heap/kmalloc.o \
-    InterruptHandler.o \
-    SharedInterruptHandler.o \
+    IRQHandler.o \
     KBufferBuilder.o \
     KParams.o \
     KSyms.o \
@@ -76,7 +74,6 @@ OBJS = \
     PCI/IOAccess.o \
     PCI/MMIOAccess.o \
     PCI/Initializer.o \
-    PCI/Device.o \
     Process.o \
     ProcessTracer.o \
     Profiling.o \

+ 13 - 12
Kernel/Net/E1000NetworkAdapter.cpp

@@ -135,23 +135,24 @@ OwnPtr<E1000NetworkAdapter> E1000NetworkAdapter::autodetect()
     return make<E1000NetworkAdapter>(found_address, irq);
 }
 
-E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 interrupt_vector)
-    : PCI::Device(pci_address, interrupt_vector)
+E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 irq)
+    : IRQHandler(irq)
+    , m_pci_address(pci_address)
 {
     set_interface_name("e1k");
 
     kprintf("E1000: Found at PCI address @ %w:%b:%b.%b\n", pci_address.seg(), pci_address.bus(), pci_address.slot(), pci_address.function());
 
-    enable_bus_mastering(get_pci_address());
+    enable_bus_mastering(m_pci_address);
 
     size_t mmio_base_size = PCI::get_BAR_Space_Size(pci_address, 0);
-    m_mmio_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(get_pci_address()))), PAGE_ROUND_UP(mmio_base_size), "E1000 MMIO", Region::Access::Read | Region::Access::Write, false, false);
+    m_mmio_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(m_pci_address))), PAGE_ROUND_UP(mmio_base_size), "E1000 MMIO", Region::Access::Read | Region::Access::Write, false, false);
     m_mmio_base = m_mmio_region->vaddr();
     m_use_mmio = true;
-    m_io_base = PCI::get_BAR1(get_pci_address()) & ~1;
-    m_interrupt_line = PCI::get_interrupt_line(get_pci_address());
+    m_io_base = PCI::get_BAR1(m_pci_address) & ~1;
+    m_interrupt_line = PCI::get_interrupt_line(m_pci_address);
     kprintf("E1000: IO port base: %w\n", m_io_base);
-    kprintf("E1000: MMIO base: P%x\n", PCI::get_BAR0(get_pci_address()) & 0xfffffffc);
+    kprintf("E1000: MMIO base: P%x\n", PCI::get_BAR0(pci_address) & 0xfffffffc);
     kprintf("E1000: MMIO base size: %u bytes\n", mmio_base_size);
     kprintf("E1000: Interrupt line: %u\n", m_interrupt_line);
     detect_eeprom();
@@ -170,14 +171,14 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 interrupt_
     out32(REG_IMASK, 0xff & ~4);
     in32(0xc0);
 
-    enable_interrupts();
+    enable_irq();
 }
 
 E1000NetworkAdapter::~E1000NetworkAdapter()
 {
 }
 
-void E1000NetworkAdapter::handle_interrupt()
+void E1000NetworkAdapter::handle_irq()
 {
     out32(REG_IMASK, 0x1);
 
@@ -372,14 +373,14 @@ u32 E1000NetworkAdapter::in32(u16 address)
 
 void E1000NetworkAdapter::send_raw(const u8* data, int length)
 {
-    disable_interrupts();
+    disable_irq();
     u32 tx_current = in32(REG_TXDESCTAIL);
 #ifdef E1000_DEBUG
     kprintf("E1000: Sending packet (%d bytes)\n", length);
 #endif
     auto& descriptor = m_tx_descriptors[tx_current];
     ASSERT(length <= 8192);
-    auto* vptr = (void*)(descriptor.addr + 0xc0000000);
+    auto *vptr = (void*)(descriptor.addr + 0xc0000000);
     memcpy(vptr, data, length);
     descriptor.length = length;
     descriptor.status = 0;
@@ -390,7 +391,7 @@ void E1000NetworkAdapter::send_raw(const u8* data, int length)
     tx_current = (tx_current + 1) % number_of_tx_descriptors;
     out32(REG_TXDESCTAIL, tx_current);
     cli();
-    enable_interrupts();
+    enable_irq();
     for (;;) {
         if (descriptor.status) {
             sti();

+ 5 - 4
Kernel/Net/E1000NetworkAdapter.h

@@ -27,23 +27,23 @@
 #pragma once
 
 #include <AK/OwnPtr.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Net/NetworkAdapter.h>
 #include <Kernel/PCI/Access.h>
-#include <Kernel/PCI/Device.h>
 
 class E1000NetworkAdapter final : public NetworkAdapter
-    , public PCI::Device {
+    , public IRQHandler {
 public:
     static OwnPtr<E1000NetworkAdapter> autodetect();
 
-    E1000NetworkAdapter(PCI::Address, u8 interrupt_vector);
+    E1000NetworkAdapter(PCI::Address, u8 irq);
     virtual ~E1000NetworkAdapter() override;
 
     virtual void send_raw(const u8*, int) override;
     virtual bool link_up() override;
 
 private:
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
     virtual const char* class_name() const override { return "E1000NetworkAdapter"; }
 
     struct [[gnu::packed]] e1000_rx_desc
@@ -86,6 +86,7 @@ private:
 
     void receive();
 
+    PCI::Address m_pci_address;
     u16 m_io_base { 0 };
     VirtualAddress m_mmio_base;
     OwnPtr<Region> m_mmio_region;

+ 8 - 7
Kernel/Net/RTL8139NetworkAdapter.cpp

@@ -139,17 +139,18 @@ OwnPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::autodetect()
     return make<RTL8139NetworkAdapter>(found_address, irq);
 }
 
-RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 interrupt_vector)
-    : PCI::Device(pci_address, interrupt_vector)
+RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 irq)
+    : IRQHandler(irq)
+    , m_pci_address(pci_address)
 {
     set_interface_name("rtl8139");
 
     kprintf("RTL8139: Found at PCI address %b:%b:%b\n", pci_address.bus(), pci_address.slot(), pci_address.function());
 
-    enable_bus_mastering(get_pci_address());
+    enable_bus_mastering(m_pci_address);
 
-    m_io_base = PCI::get_BAR0(get_pci_address()) & ~1;
-    m_interrupt_line = PCI::get_interrupt_line(get_pci_address());
+    m_io_base = PCI::get_BAR0(m_pci_address) & ~1;
+    m_interrupt_line = PCI::get_interrupt_line(m_pci_address);
     kprintf("RTL8139: IO port base: %w\n", m_io_base);
     kprintf("RTL8139: Interrupt line: %u\n", m_interrupt_line);
 
@@ -173,14 +174,14 @@ RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 interr
     const auto& mac = mac_address();
     kprintf("RTL8139: MAC address: %s\n", mac.to_string().characters());
 
-    enable_interrupts();
+    enable_irq();
 }
 
 RTL8139NetworkAdapter::~RTL8139NetworkAdapter()
 {
 }
 
-void RTL8139NetworkAdapter::handle_interrupt()
+void RTL8139NetworkAdapter::handle_irq()
 {
     for (;;) {
         int status = in16(REG_ISR);

+ 5 - 4
Kernel/Net/RTL8139NetworkAdapter.h

@@ -27,25 +27,25 @@
 #pragma once
 
 #include <AK/OwnPtr.h>
+#include <Kernel/IRQHandler.h>
 #include <Kernel/Net/NetworkAdapter.h>
 #include <Kernel/PCI/Access.h>
-#include <Kernel/PCI/Device.h>
 
 #define RTL8139_TX_BUFFER_COUNT 4
 
 class RTL8139NetworkAdapter final : public NetworkAdapter
-    , public PCI::Device {
+    , public IRQHandler {
 public:
     static OwnPtr<RTL8139NetworkAdapter> autodetect();
 
-    RTL8139NetworkAdapter(PCI::Address, u8 interrupt_vector);
+    RTL8139NetworkAdapter(PCI::Address, u8 irq);
     virtual ~RTL8139NetworkAdapter() override;
 
     virtual void send_raw(const u8*, int) override;
     virtual bool link_up() override { return m_link_up; }
 
 private:
-    virtual void handle_interrupt() override;
+    virtual void handle_irq() override;
     virtual const char* class_name() const override { return "RTL8139NetworkAdapter"; }
 
     void reset();
@@ -60,6 +60,7 @@ private:
     u16 in16(u16 address);
     u32 in32(u16 address);
 
+    PCI::Address m_pci_address;
     u16 m_io_base { 0 };
     u8 m_interrupt_line { 0 };
     u32 m_rx_buffer_addr { 0 };

+ 7 - 7
Kernel/init.cpp

@@ -101,14 +101,8 @@ extern "C" [[noreturn]] void init()
 
     bool text_debug = KParams::the().has("text_debug");
 
-    gdt_init();
-    idt_init();
-
     setup_acpi();
 
-    // Sample test to see if the ACPI parser is working...
-    kprintf("ACPI: HPET table @ P 0x%x\n", ACPIParser::the().find_table("HPET"));
-
     new VFS;
     new DebugLogDevice;
 
@@ -120,6 +114,8 @@ extern "C" [[noreturn]] void init()
 
     RTC::initialize();
     PIC::initialize();
+    gdt_init();
+    idt_init();
 
     // call global constructors after gtd and itd init
     for (ctor_func_t* ctor = &start_ctors; ctor < &end_ctors; ctor++)
@@ -140,6 +136,9 @@ extern "C" [[noreturn]] void init()
     new VirtualConsole(1);
     VirtualConsole::switch_to(0);
 
+    // Sample test to see if the ACPI parser is working...
+    kprintf("ACPI: HPET table @ P 0x%x\n", ACPIParser::the().find_table("HPET"));
+
     PCI::Initializer::the().test_and_initialize(KParams::the().has("nopci_mmio"));
     PCI::Initializer::the().dismiss();
 
@@ -172,6 +171,7 @@ extern "C" [[noreturn]] void init()
     LoopbackAdapter::the();
     auto e1000 = E1000NetworkAdapter::autodetect();
     auto rtl8139 = RTL8139NetworkAdapter::autodetect();
+
     Process::initialize();
     Thread::initialize();
 
@@ -231,7 +231,7 @@ void init_stage2()
         hang();
     }
 
-    auto pata0 = PATAChannel::autodetect(PATAChannel::ChannelType::Primary, force_pio);
+    auto pata0 = PATAChannel::create(PATAChannel::ChannelType::Primary, force_pio);
     NonnullRefPtr<DiskDevice> root_dev = *pata0->master_device();
 
     root = root.substring(strlen("/dev/hda"), root.length() - strlen("/dev/hda"));