diff options
29 files changed, 193 insertions, 169 deletions
diff --git a/Kernel/ACPI/ACPIDynamicParser.cpp b/Kernel/ACPI/ACPIDynamicParser.cpp index 52084e7e94..2a2a75744a 100644 --- a/Kernel/ACPI/ACPIDynamicParser.cpp +++ b/Kernel/ACPI/ACPIDynamicParser.cpp @@ -41,20 +41,20 @@ void ACPIDynamicParser::initialize_without_rsdp() } ACPIDynamicParser::ACPIDynamicParser() - : IRQHandler(9) + : InterruptHandler(9) , ACPIStaticParser() { kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n"); } ACPIDynamicParser::ACPIDynamicParser(ACPI_RAW::RSDPDescriptor20& rsdp) - : IRQHandler(9) + : InterruptHandler(9) , ACPIStaticParser(rsdp) { kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n"); } -void ACPIDynamicParser::handle_irq() +void ACPIDynamicParser::handle_interrupt() { // 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(); -}
\ No newline at end of file +} diff --git a/Kernel/ACPI/ACPIDynamicParser.h b/Kernel/ACPI/ACPIDynamicParser.h index eb87f18fc8..a4dee415fc 100644 --- a/Kernel/ACPI/ACPIDynamicParser.h +++ b/Kernel/ACPI/ACPIDynamicParser.h @@ -29,12 +29,12 @@ #include <AK/RefPtr.h> #include <Kernel/ACPI/ACPIStaticParser.h> #include <Kernel/Devices/DiskDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.h> #include <Kernel/Lock.h> #include <Kernel/VM/PhysicalAddress.h> #include <Kernel/VM/PhysicalPage.h> -class ACPIDynamicParser final : public IRQHandler +class ACPIDynamicParser final : public InterruptHandler , ACPIStaticParser { public: static void initialize(ACPI_RAW::RSDPDescriptor20& rsdp); @@ -53,7 +53,7 @@ protected: private: void build_namespace(); // ^IRQHandler - virtual void handle_irq() override; + virtual void handle_interrupt() override; OwnPtr<Region> m_acpi_namespace; -};
\ No newline at end of file +}; diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index d1ef90e6a4..56d9aaf8d8 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/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 IRQHandler* s_irq_handler[16]; +static SharedInterruptHandler* s_irq_handler[256]; static Vector<u16>* s_gdt_freelist; @@ -435,18 +435,25 @@ static void unimp_trap() hang(); } -void register_irq_handler(u8 irq, IRQHandler& handler) +void register_shared_interrupt_handler(u8 irq, SharedInterruptHandler& handler) { ASSERT(!s_irq_handler[irq]); s_irq_handler[irq] = &handler; } -void unregister_irq_handler(u8 irq, IRQHandler& handler) +void unregister_shared_interrupt_handler(u8 irq, SharedInterruptHandler& 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)); @@ -524,8 +531,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 < 16; ++i) { - s_irq_handler[i] = nullptr; + for (u8 i = 0; i < 255; ++i) { + SharedInterruptHandler::initialize(i); } flush_idt(); @@ -541,8 +548,9 @@ void handle_irq(RegisterDump regs) clac(); ASSERT(regs.isr_number >= 0x50 && regs.isr_number <= 0x5f); u8 irq = (u8)(regs.isr_number - 0x50); - if (s_irq_handler[irq]) - s_irq_handler[irq]->handle_irq(); + 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... PIC::eoi(irq); } diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index 11fb73881c..3eebbc3156 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -240,7 +240,7 @@ public: u64 raw[4]; }; -class IRQHandler; +class SharedInterruptHandler; struct RegisterDump; void gdt_init(); @@ -248,8 +248,9 @@ 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_irq_handler(u8 number, IRQHandler&); -void unregister_irq_handler(u8 number, IRQHandler&); +void register_shared_interrupt_handler(u8 number, SharedInterruptHandler&); +SharedInterruptHandler& get_interrupt_handler(u8 number); +void unregister_shared_interrupt_handler(u8 number, SharedInterruptHandler&); void flush_idt(); void flush_gdt(); void load_task_register(u16 selector); diff --git a/Kernel/Arch/i386/PIC.cpp b/Kernel/Arch/i386/PIC.cpp index 2b62494b5a..c500ef8c95 100644 --- a/Kernel/Arch/i386/PIC.cpp +++ b/Kernel/Arch/i386/PIC.cpp @@ -75,6 +75,20 @@ 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) diff --git a/Kernel/Arch/i386/PIC.h b/Kernel/Arch/i386/PIC.h index ecac1c3101..4746fb4a4b 100644 --- a/Kernel/Arch/i386/PIC.h +++ b/Kernel/Arch/i386/PIC.h @@ -34,6 +34,7 @@ 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(); diff --git a/Kernel/Devices/BlockDevice.h b/Kernel/Devices/BlockDevice.h index fd8c2fb495..483ca90fd9 100644 --- a/Kernel/Devices/BlockDevice.h +++ b/Kernel/Devices/BlockDevice.h @@ -34,10 +34,9 @@ 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) + : Device(major, minor, (u8)DEVICE_TYPE::BLOCK_DEVICE) , m_block_size(block_size) { } diff --git a/Kernel/Devices/CharacterDevice.h b/Kernel/Devices/CharacterDevice.h index 6d52eed55e..09fd7f92e8 100644 --- a/Kernel/Devices/CharacterDevice.h +++ b/Kernel/Devices/CharacterDevice.h @@ -34,7 +34,7 @@ public: protected: CharacterDevice(unsigned major, unsigned minor) - : Device(major, minor) + : Device(major, minor, (u8)DEVICE_TYPE::CHAR_DEVICE) { } diff --git a/Kernel/Devices/Device.cpp b/Kernel/Devices/Device.cpp index 833e9da0f3..09b1419d1c 100644 --- a/Kernel/Devices/Device.cpp +++ b/Kernel/Devices/Device.cpp @@ -25,48 +25,32 @@ */ #include <Kernel/Devices/Device.h> -#include <Kernel/FileSystem/InodeMetadata.h> +#include <Kernel/Devices/HardwareEventsManager.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 : all_devices()) - callback(*entry.value); + for (auto* entry : HardwareEventsManager::the().get_devices_list()) { + ASSERT(entry != nullptr); + callback(*entry); + } } Device* Device::get_device(unsigned major, unsigned minor) { - auto it = all_devices().find(encoded_device(major, minor)); - if (it == all_devices().end()) - return nullptr; - return it->value; + return HardwareEventsManager::the().get_device(major, minor); } -Device::Device(unsigned major, unsigned minor) +Device::Device(unsigned major, unsigned minor, u8 device_type) : m_major(major) , m_minor(minor) { - 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); + HardwareEventsManager::the().register_device(*this, device_type); } Device::~Device() { - all_devices().remove(encoded_device(m_major, m_minor)); + HardwareEventsManager::the().unregister_device(*this); } String Device::absolute_path() const diff --git a/Kernel/Devices/Device.h b/Kernel/Devices/Device.h index 2ddd7720c8..4aadf49a9a 100644 --- a/Kernel/Devices/Device.h +++ b/Kernel/Devices/Device.h @@ -39,6 +39,11 @@ #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; @@ -55,16 +60,17 @@ 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); + Device(unsigned major, unsigned minor, u8 device_type); 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 }; diff --git a/Kernel/Devices/FloppyDiskDevice.cpp b/Kernel/Devices/FloppyDiskDevice.cpp index 9cd38c31ab..adee42eaa7 100644 --- a/Kernel/Devices/FloppyDiskDevice.cpp +++ b/Kernel/Devices/FloppyDiskDevice.cpp @@ -109,7 +109,7 @@ const char* FloppyDiskDevice::class_name() const } FloppyDiskDevice::FloppyDiskDevice(FloppyDiskDevice::DriveType type) - : IRQHandler(IRQ_FLOPPY_DRIVE) + : InterruptHandler(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_irq(); + disable_interrupts(); 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_irq(); + enable_interrupts(); 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_irq(); + disable_interrupts(); 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_irq(); + enable_interrupts(); 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_irq() +void FloppyDiskDevice::handle_interrupt() { // 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_irq(); + enable_interrupts(); // Get the version of the Floppy Disk Controller send_byte(FloppyCommand::Version); diff --git a/Kernel/Devices/FloppyDiskDevice.h b/Kernel/Devices/FloppyDiskDevice.h index a505bc027c..b2349387bb 100644 --- a/Kernel/Devices/FloppyDiskDevice.h +++ b/Kernel/Devices/FloppyDiskDevice.h @@ -101,7 +101,7 @@ #include <AK/RefPtr.h> #include <Kernel/Devices/DiskDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.h> #include <Kernel/Lock.h> #include <Kernel/VM/PhysicalAddress.h> #include <Kernel/VM/PhysicalPage.h> @@ -122,7 +122,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 IRQHandler +class FloppyDiskDevice final : public InterruptHandler , public DiskDevice { AK_MAKE_ETERNAL @@ -178,7 +178,7 @@ protected: private: // ^IRQHandler - void handle_irq(); + void handle_interrupt(); // ^DiskDevice virtual const char* class_name() const override; diff --git a/Kernel/IRQHandler.cpp b/Kernel/Devices/HardwareEventsManager.cpp index 0a2ff3aeb5..f586ee0322 100644 --- a/Kernel/IRQHandler.cpp +++ b/Kernel/Devices/HardwareEventsManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,27 +24,42 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "IRQHandler.h" -#include <Kernel/Arch/i386/CPU.h> -#include <Kernel/Arch/i386/PIC.h> +#include <Kernel/Devices/HardwareEventsManager.h> -IRQHandler::IRQHandler(u8 irq) - : m_irq_number(irq) +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() { - register_irq_handler(m_irq_number, *this); + return m_devices; } -IRQHandler::~IRQHandler() +void HardwareEventsManager::unregister_device(Device& device) { - unregister_irq_handler(m_irq_number, *this); + get_devices_list().remove(&device); } -void IRQHandler::enable_irq() +HardwareEventsManager::HardwareEventsManager() { - PIC::enable(m_irq_number); } -void IRQHandler::disable_irq() +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) { - PIC::disable(m_irq_number); + get_devices_list().set(&device); } diff --git a/Kernel/IRQHandler.h b/Kernel/Devices/HardwareEventsManager.h index dbf0821704..b8b6c1f112 100644 --- a/Kernel/IRQHandler.h +++ b/Kernel/Devices/HardwareEventsManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,20 +27,18 @@ #pragma once #include <AK/Types.h> +#include <Kernel/Devices/Device.h> -class IRQHandler { +class HardwareEventsManager { public: - 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); + 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(); private: - u8 m_irq_number { 0 }; + HashTable<Device*> m_devices; + HardwareEventsManager(); }; diff --git a/Kernel/Devices/KeyboardDevice.cpp b/Kernel/Devices/KeyboardDevice.cpp index 86c862057e..5996e87566 100644 --- a/Kernel/Devices/KeyboardDevice.cpp +++ b/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_irq() +void KeyboardDevice::handle_interrupt() { for (;;) { u8 status = IO::in8(I8042_STATUS); @@ -551,7 +551,7 @@ KeyboardDevice& KeyboardDevice::the() } KeyboardDevice::KeyboardDevice() - : IRQHandler(IRQ_KEYBOARD) + : InterruptHandler(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_irq(); + enable_interrupts(); } KeyboardDevice::~KeyboardDevice() diff --git a/Kernel/Devices/KeyboardDevice.h b/Kernel/Devices/KeyboardDevice.h index a2c9b4e3a3..a5b24b7b2d 100644 --- a/Kernel/Devices/KeyboardDevice.h +++ b/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 IRQHandler +class KeyboardDevice final : public InterruptHandler , public CharacterDevice { AK_MAKE_ETERNAL public: @@ -57,7 +57,7 @@ public: private: // ^IRQHandler - virtual void handle_irq() override; + virtual void handle_interrupt() override; // ^CharacterDevice virtual const char* class_name() const override { return "KeyboardDevice"; } diff --git a/Kernel/Devices/PATAChannel.cpp b/Kernel/Devices/PATAChannel.cpp index b57fe42c1c..ee67eb7ff7 100644 --- a/Kernel/Devices/PATAChannel.cpp +++ b/Kernel/Devices/PATAChannel.cpp @@ -112,18 +112,25 @@ static Lock& s_lock() return *lock; }; -OwnPtr<PATAChannel> PATAChannel::create(ChannelType type, bool force_pio) +OwnPtr<PATAChannel> PATAChannel::autodetect(ChannelType type, bool force_pio) { - return make<PATAChannel>(type, 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); } -PATAChannel::PATAChannel(ChannelType type, bool force_pio) - : IRQHandler((type == ChannelType::Primary ? PATA_PRIMARY_IRQ : PATA_SECONDARY_IRQ)) +PATAChannel::PATAChannel(PCI::Address pci_address, ChannelType type, bool force_pio) + : PCI::Device(pci_address, (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_irq(); + disable_interrupts(); m_dma_enabled.resource() = true; ProcFS::add_sys_bool("ide_dma", m_dma_enabled); @@ -140,14 +147,8 @@ 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 (m_pci_address.is_null()) { + if (get_pci_address().is_null()) { kprintf("PATAChannel: PCI address was null; can not set up DMA\n"); return; } @@ -158,9 +159,9 @@ void PATAChannel::initialize(bool force_pio) } // Let's try to set up DMA transfers. - PCI::enable_bus_mastering(m_pci_address); + PCI::enable_bus_mastering(get_pci_address()); prdt().end_of_table = 0x8000; - m_bus_master_base = PCI::get_BAR4(m_pci_address) & 0xfffc; + m_bus_master_base = PCI::get_BAR4(get_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); } @@ -181,12 +182,11 @@ static void print_ide_status(u8 status) void PATAChannel::wait_for_irq() { cli(); - enable_irq(); + InterruptHandler::Enabler enabler(*this); current->wait_on(m_irq_queue); - disable_irq(); } -void PATAChannel::handle_irq() +void PATAChannel::handle_interrupt() { u8 status = IO::in8(m_io_base + ATA_REG_STATUS); if (status & ATA_SR_ERR) { diff --git a/Kernel/Devices/PATAChannel.h b/Kernel/Devices/PATAChannel.h index 829def7558..cee50d3928 100644 --- a/Kernel/Devices/PATAChannel.h +++ b/Kernel/Devices/PATAChannel.h @@ -38,9 +38,10 @@ #include <AK/OwnPtr.h> #include <AK/RefPtr.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.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> @@ -52,7 +53,7 @@ struct PhysicalRegionDescriptor { }; class PATADiskDevice; -class PATAChannel final : public IRQHandler { +class PATAChannel final : public PCI::Device { friend class PATADiskDevice; AK_MAKE_ETERNAL public: @@ -62,8 +63,8 @@ public: }; public: - static OwnPtr<PATAChannel> create(ChannelType type, bool force_pio); - PATAChannel(ChannelType type, bool force_pio); + static OwnPtr<PATAChannel> autodetect(ChannelType type, bool force_pio); + PATAChannel(PCI::Address pci_address, ChannelType type, bool force_pio); virtual ~PATAChannel() override; RefPtr<PATADiskDevice> master_device() { return m_master; }; @@ -71,7 +72,7 @@ public: private: //^ IRQHandler - virtual void handle_irq() override; + virtual void handle_interrupt() override; void initialize(bool force_pio); void detect_disks(); @@ -90,7 +91,6 @@ 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; diff --git a/Kernel/Devices/PATADiskDevice.h b/Kernel/Devices/PATADiskDevice.h index 086c6d8467..d99de6518f 100644 --- a/Kernel/Devices/PATADiskDevice.h +++ b/Kernel/Devices/PATADiskDevice.h @@ -31,7 +31,7 @@ #pragma once #include <Kernel/Devices/DiskDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.h> #include <Kernel/Lock.h> class PATAChannel; diff --git a/Kernel/Devices/PS2MouseDevice.cpp b/Kernel/Devices/PS2MouseDevice.cpp index 6a1e178560..fca9320412 100644 --- a/Kernel/Devices/PS2MouseDevice.cpp +++ b/Kernel/Devices/PS2MouseDevice.cpp @@ -54,7 +54,7 @@ static PS2MouseDevice* s_the; PS2MouseDevice::PS2MouseDevice() - : IRQHandler(IRQ_MOUSE) + : InterruptHandler(IRQ_MOUSE) , CharacterDevice(10, 1) { s_the = this; @@ -70,7 +70,7 @@ PS2MouseDevice& PS2MouseDevice::the() return *s_the; } -void PS2MouseDevice::handle_irq() +void PS2MouseDevice::handle_interrupt() { for (;;) { u8 status = IO::in8(I8042_STATUS); @@ -242,7 +242,7 @@ void PS2MouseDevice::initialize_device() kprintf("PS2MouseDevice: No mouse wheel detected!\n"); } - enable_irq(); + enable_interrupts(); } void PS2MouseDevice::expect_ack() diff --git a/Kernel/Devices/PS2MouseDevice.h b/Kernel/Devices/PS2MouseDevice.h index 6010bb6cef..e806b7fa83 100644 --- a/Kernel/Devices/PS2MouseDevice.h +++ b/Kernel/Devices/PS2MouseDevice.h @@ -28,10 +28,10 @@ #include <AK/CircularQueue.h> #include <Kernel/Devices/CharacterDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.h> #include <Kernel/MousePacket.h> -class PS2MouseDevice final : public IRQHandler +class PS2MouseDevice final : public InterruptHandler , public CharacterDevice { public: PS2MouseDevice(); @@ -47,7 +47,7 @@ public: private: // ^IRQHandler - virtual void handle_irq() override; + virtual void handle_interrupt() override; // ^CharacterDevice virtual const char* class_name() const override { return "PS2MouseDevice"; } diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index f015adcc10..8150aaacda 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -74,7 +74,7 @@ void SB16::set_sample_rate(uint16_t hz) static SB16* s_the; SB16::SB16() - : IRQHandler(5) + : InterruptHandler(5) , CharacterDevice(42, 42) // ### ? { s_the = this; @@ -92,7 +92,7 @@ SB16& SB16::the() void SB16::initialize() { - disable_irq(); + disable_interrupts(); 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_irq() +void SB16::handle_interrupt() { // Stop sound output ready for the next block. dsp_write(0xd5); @@ -168,9 +168,8 @@ void SB16::handle_irq() void SB16::wait_for_irq() { cli(); - enable_irq(); + InterruptHandler::Enabler enabler(*this); current->wait_on(m_irq_queue); - disable_irq(); } ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length) diff --git a/Kernel/Devices/SB16.h b/Kernel/Devices/SB16.h index 21df353222..25c91cf59f 100644 --- a/Kernel/Devices/SB16.h +++ b/Kernel/Devices/SB16.h @@ -28,14 +28,14 @@ #include <AK/CircularQueue.h> #include <Kernel/Devices/CharacterDevice.h> -#include <Kernel/IRQHandler.h> +#include <Kernel/InterruptHandler.h> #include <Kernel/VM/PhysicalAddress.h> #include <Kernel/VM/PhysicalPage.h> #include <Kernel/WaitQueue.h> class SB16; -class SB16 final : public IRQHandler +class SB16 final : public InterruptHandler , public CharacterDevice { public: SB16(); @@ -51,7 +51,7 @@ public: private: // ^IRQHandler - virtual void handle_irq() override; + virtual void handle_interrupt() override; // ^CharacterDevice virtual const char* class_name() const override { return "SB16"; } diff --git a/Kernel/Makefile b/Kernel/Makefile index 7cf989c555..0838721682 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -15,6 +15,7 @@ OBJS = \ Arch/i386/PIT.o \ CMOS.o \ Console.o \ + Devices/HardwareEventsManager.o \ Devices/BXVGADevice.o \ Devices/BlockDevice.o \ Devices/CharacterDevice.o \ @@ -54,7 +55,8 @@ OBJS = \ FileSystem/VirtualFileSystem.o \ Heap/SlabAllocator.o \ Heap/kmalloc.o \ - IRQHandler.o \ + InterruptHandler.o \ + SharedInterruptHandler.o \ KBufferBuilder.o \ KParams.o \ KSyms.o \ @@ -74,6 +76,7 @@ OBJS = \ PCI/IOAccess.o \ PCI/MMIOAccess.o \ PCI/Initializer.o \ + PCI/Device.o \ Process.o \ ProcessTracer.o \ Profiling.o \ diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index 8ab2937fb9..9f58334498 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -135,24 +135,23 @@ OwnPtr<E1000NetworkAdapter> E1000NetworkAdapter::autodetect() return make<E1000NetworkAdapter>(found_address, irq); } -E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 irq) - : IRQHandler(irq) - , m_pci_address(pci_address) +E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 interrupt_vector) + : PCI::Device(pci_address, interrupt_vector) { 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(m_pci_address); + enable_bus_mastering(get_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(m_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(get_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(m_pci_address) & ~1; - m_interrupt_line = PCI::get_interrupt_line(m_pci_address); + m_io_base = PCI::get_BAR1(get_pci_address()) & ~1; + m_interrupt_line = PCI::get_interrupt_line(get_pci_address()); kprintf("E1000: IO port base: %w\n", m_io_base); - kprintf("E1000: MMIO base: P%x\n", PCI::get_BAR0(pci_address) & 0xfffffffc); + kprintf("E1000: MMIO base: P%x\n", PCI::get_BAR0(get_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(); @@ -171,14 +170,14 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 irq) out32(REG_IMASK, 0xff & ~4); in32(0xc0); - enable_irq(); + enable_interrupts(); } E1000NetworkAdapter::~E1000NetworkAdapter() { } -void E1000NetworkAdapter::handle_irq() +void E1000NetworkAdapter::handle_interrupt() { out32(REG_IMASK, 0x1); @@ -373,14 +372,14 @@ u32 E1000NetworkAdapter::in32(u16 address) void E1000NetworkAdapter::send_raw(const u8* data, int length) { - disable_irq(); + disable_interrupts(); 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; @@ -391,7 +390,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_irq(); + enable_interrupts(); for (;;) { if (descriptor.status) { sti(); diff --git a/Kernel/Net/E1000NetworkAdapter.h b/Kernel/Net/E1000NetworkAdapter.h index 93efc84faf..fb1fbb58b9 100644 --- a/Kernel/Net/E1000NetworkAdapter.h +++ b/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 IRQHandler { + , public PCI::Device { public: static OwnPtr<E1000NetworkAdapter> autodetect(); - E1000NetworkAdapter(PCI::Address, u8 irq); + E1000NetworkAdapter(PCI::Address, u8 interrupt_vector); virtual ~E1000NetworkAdapter() override; virtual void send_raw(const u8*, int) override; virtual bool link_up() override; private: - virtual void handle_irq() override; + virtual void handle_interrupt() override; virtual const char* class_name() const override { return "E1000NetworkAdapter"; } struct [[gnu::packed]] e1000_rx_desc @@ -86,7 +86,6 @@ private: void receive(); - PCI::Address m_pci_address; u16 m_io_base { 0 }; VirtualAddress m_mmio_base; OwnPtr<Region> m_mmio_region; diff --git a/Kernel/Net/RTL8139NetworkAdapter.cpp b/Kernel/Net/RTL8139NetworkAdapter.cpp index c24704f3d9..6604f5bed2 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.cpp +++ b/Kernel/Net/RTL8139NetworkAdapter.cpp @@ -139,18 +139,17 @@ OwnPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::autodetect() return make<RTL8139NetworkAdapter>(found_address, irq); } -RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 irq) - : IRQHandler(irq) - , m_pci_address(pci_address) +RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 interrupt_vector) + : PCI::Device(pci_address, interrupt_vector) { 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(m_pci_address); + enable_bus_mastering(get_pci_address()); - m_io_base = PCI::get_BAR0(m_pci_address) & ~1; - m_interrupt_line = PCI::get_interrupt_line(m_pci_address); + m_io_base = PCI::get_BAR0(get_pci_address()) & ~1; + m_interrupt_line = PCI::get_interrupt_line(get_pci_address()); kprintf("RTL8139: IO port base: %w\n", m_io_base); kprintf("RTL8139: Interrupt line: %u\n", m_interrupt_line); @@ -174,14 +173,14 @@ RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address pci_address, u8 irq) const auto& mac = mac_address(); kprintf("RTL8139: MAC address: %s\n", mac.to_string().characters()); - enable_irq(); + enable_interrupts(); } RTL8139NetworkAdapter::~RTL8139NetworkAdapter() { } -void RTL8139NetworkAdapter::handle_irq() +void RTL8139NetworkAdapter::handle_interrupt() { for (;;) { int status = in16(REG_ISR); diff --git a/Kernel/Net/RTL8139NetworkAdapter.h b/Kernel/Net/RTL8139NetworkAdapter.h index a9d941a0fe..c998db0fb2 100644 --- a/Kernel/Net/RTL8139NetworkAdapter.h +++ b/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 IRQHandler { + , public PCI::Device { public: static OwnPtr<RTL8139NetworkAdapter> autodetect(); - RTL8139NetworkAdapter(PCI::Address, u8 irq); + RTL8139NetworkAdapter(PCI::Address, u8 interrupt_vector); virtual ~RTL8139NetworkAdapter() override; virtual void send_raw(const u8*, int) override; virtual bool link_up() override { return m_link_up; } private: - virtual void handle_irq() override; + virtual void handle_interrupt() override; virtual const char* class_name() const override { return "RTL8139NetworkAdapter"; } void reset(); @@ -60,7 +60,6 @@ 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 }; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 2f69a6e576..66ea5150dc 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -101,8 +101,14 @@ 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; @@ -114,8 +120,6 @@ 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++) @@ -136,9 +140,6 @@ 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(); @@ -171,7 +172,6 @@ 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::create(PATAChannel::ChannelType::Primary, force_pio); + auto pata0 = PATAChannel::autodetect(PATAChannel::ChannelType::Primary, force_pio); NonnullRefPtr<DiskDevice> root_dev = *pata0->master_device(); root = root.substring(strlen("/dev/hda"), root.length() - strlen("/dev/hda")); |