X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/37fb1e9cee287c9ae8c065ff517c508eb5f9d7dd..05b7549a0f980efa33265a091a5174a78851ce05:/lunaix-os/includes/hal/apic.h?ds=sidebyside diff --git a/lunaix-os/includes/hal/apic.h b/lunaix-os/includes/hal/apic.h new file mode 100644 index 0000000..851e75e --- /dev/null +++ b/lunaix-os/includes/hal/apic.h @@ -0,0 +1,82 @@ +#ifndef __LUNAIX_APIC_H +#define __LUNAIX_APIC_H + +#include + +#define APIC_BASE_VADDR 0x1000 +#define __APIC_BASE_PADDR 0xFEE00000 + +#define IA32_APIC_BASE_MSR 0x1B +#define IA32_APIC_ENABLE 0x800 + +/* + * Common APIC memory-mapped registers + * Ref: Intel Manual, Vol. 3A, Table 10-1 + */ + +#define APIC_IDR 0x20 // ID Reg +#define APIC_VER 0x30 // Version Reg +#define APIC_TPR 0x80 // Task Priority +#define APIC_APR 0x90 // Arbitration Priority +#define APIC_PPR 0xA0 // Processor Priority +#define APIC_EOI 0xB0 // End-Of-Interrupt +#define APIC_RRD 0xC0 // Remote Read +#define APIC_LDR 0xD0 // Local Destination Reg +#define APIC_DFR 0xE0 // Destination Format Reg +#define APIC_SPIVR 0xF0 // Spurious Interrupt Vector Reg +#define APIC_ISR_BASE 0x100 // Base address for In-Service-Interrupt bitmap register (256bits) +#define APIC_TMR_BASE 0x180 // Base address for Trigger-Mode bitmap register (256bits) +#define APIC_IRR_BASE 0x200 // Base address for Interrupt-Request bitmap register (256bits) +#define APIC_ESR 0x280 // Error Status Reg +#define APIC_ICR_BASE 0x300 // Interrupt Command +#define APIC_LVT_LINT0 0x350 +#define APIC_LVT_LINT1 0x360 +#define APIC_LVT_ERROR 0x370 + +// APIC Timer specific +#define APIC_TIMER_LVT 0x320 +#define APIC_TIMER_ICR 0x380 // Initial Count +#define APIC_TIMER_CCR 0x390 // Current Count +#define APIC_TIMER_DCR 0x3E0 // Divide Configuration + +#define APIC_SPIV_FOCUS_DISABLE 0x200 +#define APIC_SPIV_APIC_ENABLE 0x100 +#define APIC_SPIV_EOI_BROADCAST 0x1000 + +#define LVT_DELIVERY_FIXED 0 +#define LVT_DELIVERY_NMI (0x4 << 8) +#define LVT_TRIGGER_EDGE (0 << 15) +#define LVT_TRIGGER_LEVEL (1 << 15) +#define LVT_MASKED (1 << 16) +#define LVT_TIMER_ONESHOT (0 << 17) +#define LVT_TIMER_PERIODIC (1 << 17) + +// Dividers for timer. See Intel Manual Vol3A. 10-17 (pp. 3207), Figure 10-10 +#define APIC_TIMER_DIV1 0b1011 +#define APIC_TIMER_DIV2 0b0000 +#define APIC_TIMER_DIV4 0b0001 +#define APIC_TIMER_DIV8 0b0010 +#define APIC_TIMER_DIV16 0b0011 +#define APIC_TIMER_DIV32 0b1000 +#define APIC_TIMER_DIV64 0b1001 +#define APIC_TIMER_DIV128 0b1010 + +#define APIC_PRIORITY(cls, subcls) (((cls) << 4) | (subcls)) + +#define apic_read_reg(reg) (*(uint32_t*)(APIC_BASE_VADDR + (reg))) +#define apic_write_reg(reg, val) (*(uint32_t*)(APIC_BASE_VADDR + (reg)) = (val)) + +void +init_apic(); + +/** + * @brief Tell the APIC that the handler for current interrupt is finished. + * This will issue a write action to EOI register. + * + */ +inline static void +apic_done_servicing() { + apic_write_reg(APIC_EOI, 0); +} + +#endif /* __LUNAIX_APIC_H */