Skip to content

Commit

Permalink
Kernel: Replace IRQHandler with the new InterruptHandler class
Browse files Browse the repository at this point in the history
System components that need an IRQ handling are now inheriting the
InterruptHandler class.

In addition to that, the initialization process of PATAChannel was
changed to fit the changes.
PATAChannel, E1000NetworkAdapter and RTL8139NetworkAdapter are now
inheriting from PCI::Device instead of InterruptHandler directly.
  • Loading branch information
supercomputer7 authored and awesomekling committed Jan 22, 2020
1 parent 1ee3724 commit 6c72736
Show file tree
Hide file tree
Showing 29 changed files with 193 additions and 169 deletions.
8 changes: 4 additions & 4 deletions Kernel/ACPI/ACPIDynamicParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -90,4 +90,4 @@ void ACPIDynamicParser::build_namespace()
{
// FIXME: Implement AML Interpretation to build the ACPI namespace
ASSERT_NOT_REACHED();
}
}
8 changes: 4 additions & 4 deletions Kernel/ACPI/ACPIDynamicParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -53,7 +53,7 @@ class ACPIDynamicParser final : public IRQHandler
private:
void build_namespace();
// ^IRQHandler
virtual void handle_irq() override;
virtual void handle_interrupt() override;

OwnPtr<Region> m_acpi_namespace;
};
};
24 changes: 16 additions & 8 deletions Kernel/Arch/i386/CPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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;

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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();
Expand All @@ -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);
}

Expand Down
7 changes: 4 additions & 3 deletions Kernel/Arch/i386/CPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,17 @@ class PageDirectoryPointerTable {
u64 raw[4];
};

class IRQHandler;
class SharedInterruptHandler;
struct RegisterDump;

void gdt_init();
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);
Expand Down
14 changes: 14 additions & 0 deletions Kernel/Arch/i386/PIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Kernel/Arch/i386/PIC.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
3 changes: 1 addition & 2 deletions Kernel/Devices/BlockDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ class BlockDevice : public Device {

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)
{
}
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Devices/CharacterDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CharacterDevice : public Device {

protected:
CharacterDevice(unsigned major, unsigned minor)
: Device(major, minor)
: Device(major, minor, (u8)DEVICE_TYPE::CHAR_DEVICE)
{
}

Expand Down
34 changes: 9 additions & 25 deletions Kernel/Devices/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions Kernel/Devices/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -55,16 +60,17 @@ class Device : public File {
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 };
Expand Down
14 changes: 7 additions & 7 deletions Kernel/Devices/FloppyDiskDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions Kernel/Devices/FloppyDiskDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -122,7 +122,7 @@ struct FloppyControllerCommand {
// uses the Intel 82077A controller. More about this controller can
// be found here: http:https://www.buchty.net/casio/files/82077.pdf
//
class FloppyDiskDevice final : public IRQHandler
class FloppyDiskDevice final : public InterruptHandler
, public DiskDevice {
AK_MAKE_ETERNAL

Expand Down Expand Up @@ -178,7 +178,7 @@ class FloppyDiskDevice final : public IRQHandler

private:
// ^IRQHandler
void handle_irq();
void handle_interrupt();

// ^DiskDevice
virtual const char* class_name() const override;
Expand Down
Loading

0 comments on commit 6c72736

Please sign in to comment.