summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/ACPI/ACPIDynamicParser.cpp8
-rw-r--r--Kernel/ACPI/ACPIDynamicParser.h8
-rw-r--r--Kernel/Arch/i386/CPU.cpp24
-rw-r--r--Kernel/Arch/i386/CPU.h7
-rw-r--r--Kernel/Arch/i386/PIC.cpp14
-rw-r--r--Kernel/Arch/i386/PIC.h1
-rw-r--r--Kernel/Devices/BlockDevice.h3
-rw-r--r--Kernel/Devices/CharacterDevice.h2
-rw-r--r--Kernel/Devices/Device.cpp34
-rw-r--r--Kernel/Devices/Device.h12
-rw-r--r--Kernel/Devices/FloppyDiskDevice.cpp14
-rw-r--r--Kernel/Devices/FloppyDiskDevice.h6
-rw-r--r--Kernel/Devices/HardwareEventsManager.cpp (renamed from Kernel/IRQHandler.cpp)41
-rw-r--r--Kernel/Devices/HardwareEventsManager.h (renamed from Kernel/IRQHandler.h)24
-rw-r--r--Kernel/Devices/KeyboardDevice.cpp6
-rw-r--r--Kernel/Devices/KeyboardDevice.h6
-rw-r--r--Kernel/Devices/PATAChannel.cpp34
-rw-r--r--Kernel/Devices/PATAChannel.h12
-rw-r--r--Kernel/Devices/PATADiskDevice.h2
-rw-r--r--Kernel/Devices/PS2MouseDevice.cpp6
-rw-r--r--Kernel/Devices/PS2MouseDevice.h6
-rw-r--r--Kernel/Devices/SB16.cpp9
-rw-r--r--Kernel/Devices/SB16.h6
-rw-r--r--Kernel/Makefile5
-rw-r--r--Kernel/Net/E1000NetworkAdapter.cpp25
-rw-r--r--Kernel/Net/E1000NetworkAdapter.h9
-rw-r--r--Kernel/Net/RTL8139NetworkAdapter.cpp15
-rw-r--r--Kernel/Net/RTL8139NetworkAdapter.h9
-rw-r--r--Kernel/init.cpp14
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"));