[Zion] Add a keyboard interrupt handler and a driver manager.

This commit is contained in:
Drew Galbraith 2023-11-25 11:13:25 -08:00
parent d9a936db09
commit 838ef01a2a
12 changed files with 106 additions and 23 deletions

View file

@ -136,6 +136,9 @@ Apic::Apic(const ApicConfiguration& config)
// FIXME: Get this offset from ACPI.
SetIoDoubleReg(0x14, 0x20 | APIC_MASK);
// Map Keyboard
SetIoDoubleReg(0x12, 0x22);
// For now set these based on the presets in the following spec.
// http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf
// FIXME: However in the future we should likely use the MADT for legacy

View file

@ -0,0 +1,26 @@
#include "interrupt/driver_manager.h"
#include "debug/debug.h"
DriverManager* gDriverManager = nullptr;
DriverManager& DriverManager::Get() { return *gDriverManager; }
DriverManager::DriverManager() { gDriverManager = this; }
void DriverManager::WriteMessage(uint64_t irq_num, IpcMessage&& message) {
if (!driver_map_.Contains(irq_num)) {
dbgln("WARN IRQ for {x} with no registered driver", irq_num);
return;
}
driver_map_.at(irq_num)->Send(glcr::Move(message));
}
glcr::ErrorCode DriverManager::RegisterListener(uint64_t irq_num,
glcr::RefPtr<Port> port) {
if (driver_map_.Contains(irq_num)) {
return glcr::ALREADY_EXISTS;
}
return driver_map_.Insert(irq_num, port);
}

View file

@ -0,0 +1,22 @@
#pragma once
#include <glacier/container/hash_map.h>
#include <glacier/memory/ref_ptr.h>
#include "object/port.h"
class DriverManager {
public:
static DriverManager& Get();
DriverManager();
DriverManager(const DriverManager&) = delete;
DriverManager(DriverManager&&) = delete;
void WriteMessage(uint64_t irq_num, IpcMessage&& message);
glcr::ErrorCode RegisterListener(uint64_t irq_num, glcr::RefPtr<Port> port);
private:
glcr::HashMap<uint64_t, glcr::RefPtr<Port>> driver_map_;
};

View file

@ -7,6 +7,7 @@
#include "debug/debug.h"
#include "interrupt/apic.h"
#include "interrupt/apic_timer.h"
#include "interrupt/driver_manager.h"
#include "memory/kernel_heap.h"
#include "memory/physical_memory.h"
#include "scheduler/scheduler.h"
@ -196,27 +197,39 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) {
gScheduler->Preempt();
}
glcr::RefPtr<Port> pci1_port;
extern "C" void isr_keyboard();
extern "C" void interrupt_keyboard(InterruptFrame*) {
glcr::Array<uint8_t> data(1);
data[0] = inb(0x60);
IpcMessage msg{.data = glcr::Move(data)};
DriverManager::Get().WriteMessage(kZIrqKbd, glcr::Move(msg));
gApic->SignalEOI();
}
extern "C" void isr_pci1();
extern "C" void interrupt_pci1(InterruptFrame*) {
pci1_port->Send({});
DriverManager::Get().WriteMessage(kZIrqPci1, {});
gApic->SignalEOI();
}
extern "C" void isr_pci2();
extern "C" void interrupt_pci2(InterruptFrame*) {
DriverManager::Get().WriteMessage(kZIrqPci2, {});
dbgln("Interrupt PCI line 2");
gApic->SignalEOI();
}
extern "C" void isr_pci3();
extern "C" void interrupt_pci3(InterruptFrame*) {
DriverManager::Get().WriteMessage(kZIrqPci3, {});
dbgln("Interrupt PCI line 3");
gApic->SignalEOI();
}
extern "C" void isr_pci4();
extern "C" void interrupt_pci4(InterruptFrame*) {
DriverManager::Get().WriteMessage(kZIrqPci4, {});
dbgln("Interrupt PCI line 4");
gApic->SignalEOI();
}
@ -230,6 +243,7 @@ void InitIdt() {
gIdt[0x20] = CreateDescriptor(isr_timer);
gIdt[0x21] = CreateDescriptor(isr_apic_timer);
gIdt[0x22] = CreateDescriptor(isr_keyboard);
gIdt[0x30] = CreateDescriptor(isr_pci1);
gIdt[0x31] = CreateDescriptor(isr_pci2);
@ -253,5 +267,3 @@ void UpdateFaultHandlersToIst1() {
};
asm volatile("lidt %0" ::"m"(idtp));
}
void RegisterPciPort(const glcr::RefPtr<Port>& port) { pci1_port = port; }

View file

@ -7,5 +7,3 @@
void InitIdt();
void UpdateFaultHandlersToIst1();
void RegisterPciPort(const glcr::RefPtr<Port>& port);

View file

@ -63,6 +63,7 @@ isr_handler fpe_fault
isr_handler timer
isr_handler apic_timer
isr_handler keyboard
isr_handler pci1
isr_handler pci2