Skip to content

Commit

Permalink
Kernel: Simplify APIC::enable()
Browse files Browse the repository at this point in the history
We install a SpuriousInterruptHandler when calling APIC::enable(),
and we don't enable local interrupts for now.
  • Loading branch information
supercomputer7 authored and awesomekling committed Mar 6, 2020
1 parent a3fa40f commit c335c94
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 19 deletions.
37 changes: 18 additions & 19 deletions Kernel/Interrupts/APIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@
#include <AK/Types.h>
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Interrupts/APIC.h>
#include <Kernel/Interrupts/SpuriousInterruptHandler.h>
#include <Kernel/VM/MemoryManager.h>
#include <LibBareMetal/IO.h>

#define IRQ_APIC_SPURIOUS 0x1f
#define IRQ_APIC_SPURIOUS 0x7f

#define APIC_BASE_MSR 0x1b

#define APIC_REG_EOI 0xb0
#define APIC_REG_LD 0xd0
#define APIC_REG_DF 0xe0
#define APIC_REG_SIV 0xf0
#define APIC_REG_TPR 0x80
#define APIC_REG_ICR_LOW 0x300
#define APIC_REG_ICR_HIGH 0x310
#define APIC_REG_LVT_TIMER 0x320
Expand All @@ -50,13 +52,6 @@

namespace Kernel {

extern "C" void apic_spurious_interrupt_entry();

asm(
".globl apic_spurious_interrupt_entry \n"
"apic_spurious_interrupt_entry: \n"
" iret\n");

namespace APIC {

class ICRReg {
Expand Down Expand Up @@ -120,14 +115,14 @@ namespace APIC {
static void write_register(u32 offset, u32 value)
{
auto lapic_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)g_apic_base)), PAGE_SIZE, "LAPIC Write Access", Region::Access::Read | Region::Access::Write, false, true);
auto* lapic = (u32*)lapic_region->vaddr().offset(offset_in_page((u32)g_apic_base)).offset(offset).as_ptr();
auto* lapic = (volatile u32*)lapic_region->vaddr().offset(offset_in_page((u32)g_apic_base)).offset(offset).as_ptr();
*lapic = value;
}

static u32 read_register(u32 offset)
{
auto lapic_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)g_apic_base)), PAGE_SIZE, "LAPIC Read Access", Region::Access::Read, false, true);
auto* lapic = (u32*)lapic_region->vaddr().offset(offset_in_page((u32)g_apic_base)).offset(offset).as_ptr();
auto* lapic = (volatile u32*)lapic_region->vaddr().offset(offset_in_page((u32)g_apic_base)).offset(offset).as_ptr();
return *lapic;
}

Expand Down Expand Up @@ -190,23 +185,27 @@ namespace APIC {
{
klog() << "Enabling local APIC for cpu #" << cpu;

// dummy read, apparently to avoid a bug in old CPUs.
read_register(APIC_REG_SIV);
// set spurious interrupt vector
write_register(APIC_REG_SIV, read_register(APIC_REG_SIV) | 0x100);
write_register(APIC_REG_SIV, IRQ_APIC_SPURIOUS | 0x100);

// local destination mode (flat mode)
write_register(APIC_REG_DF, 0xf0000000);

// set destination id (note that this limits it to 8 cpus)
write_register(APIC_REG_LD, (1 << cpu) << 24);
write_register(APIC_REG_LD, 0);

SpuriousInterruptHandler::initialize(IRQ_APIC_SPURIOUS);

register_interrupt_handler(IRQ_APIC_SPURIOUS, apic_spurious_interrupt_entry);
write_register(APIC_REG_LVT_TIMER, APIC_LVT(0, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_THERMAL, APIC_LVT(0, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_PERFORMANCE_COUNTER, APIC_LVT(0, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_LINT0, APIC_LVT(0, 7) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_LINT1, APIC_LVT(0, 0) | APIC_LVT_TRIGGER_LEVEL);
write_register(APIC_REG_LVT_ERR, APIC_LVT(0, 0) | APIC_LVT_MASKED);

write_register(APIC_REG_LVT_TIMER, APIC_LVT(0xff, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_THERMAL, APIC_LVT(0xff, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_PERFORMANCE_COUNTER, APIC_LVT(0xff, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_LINT0, APIC_LVT(0x1f, 7) | APIC_LVT_MASKED);
write_register(APIC_REG_LVT_LINT1, APIC_LVT(0xff, 4) | APIC_LVT_TRIGGER_LEVEL); // nmi
write_register(APIC_REG_LVT_ERR, APIC_LVT(0xe3, 0) | APIC_LVT_MASKED);
write_register(APIC_REG_TPR, 0);

if (cpu != 0) {
static volatile u32 foo = 0;
Expand Down
1 change: 1 addition & 0 deletions Kernel/Interrupts/SpuriousInterruptHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <AK/OwnPtr.h>
#include <AK/Types.h>
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Interrupts/IRQController.h>
#include <Kernel/Interrupts/GenericInterruptHandler.h>

namespace Kernel {
Expand Down

0 comments on commit c335c94

Please sign in to comment.