11
#include <drivers/common/memory.h>
15
#ifdef LAPIC_REGS_X86_H_
20
#include <kernel/panic.h>
23
#define lapic_read_icr1() lapic_read(LAPIC_ICR1)
24
#define lapic_read_icr2() lapic_read(LAPIC_ICR2)
26
#define lapic_write_icr1(val) lapic_write(LAPIC_ICR1, val)
27
#define lapic_write_icr2(val) lapic_write(LAPIC_ICR2, val)
29
#define TMR_PERIODIC 0x20000
30
#define TMR_BASEDIV (1<<20)
32
static void udelay(int delay) {
35
for (i = delay * 10; i != 0; i-- );
38
void lapic_send_init_ipi(uint32_t apic_id) {
41
val = (apic_id & 0xFF) << 24;
42
lapic_write_icr2(val);
45
val = LAPIC_ICR_DM_INIT;
46
val |= LAPIC_ICR_INT_ASSERT;
47
val |= LAPIC_ICR_DEST_FIELD;
48
val |= LAPIC_ICR_INIT_LEVELTRIG;
49
lapic_write_icr1(val);
54
while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING);
57
void lapic_send_startup_ipi(uint32_t apic_id, uint32_t trampoline) {
60
val = (apic_id & 0xFF) << 24;
61
lapic_write_icr2(val);
64
val = (trampoline >> 12) & 0xFF;
65
val |= LAPIC_ICR_DM_FIXED;
66
val |= LAPIC_ICR_DM_STARTUP;
67
val |= LAPIC_ICR_DEST_FIELD;
68
lapic_write_icr1(val);
72
val = (trampoline >> 12) & 0xFF;
73
val |= LAPIC_ICR_DM_FIXED;
74
val |= LAPIC_ICR_DM_STARTUP;
75
val |= LAPIC_ICR_DEST_FIELD;
76
lapic_write_icr1(val);
81
while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING);
84
void lapic_send_ipi(unsigned int vector, unsigned int cpu, int type) {
87
while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING) {
88
panic("Not implemented\n");
95
case LAPIC_ICR_DEST_FIELD:
96
lapic_write_icr2(icr2 | (cpu << 24));
97
lapic_write_icr1(icr1 | type | LAPIC_ICR_LOGICAL_DEST | vector);
99
case LAPIC_ICR_DEST_SELF:
101
lapic_write_icr2(icr2);
102
lapic_write_icr1(icr1 | type | vector);
104
case LAPIC_ICR_DEST_ALL:
106
lapic_write_icr2(icr2);
107
lapic_write_icr1(icr1 | type | vector);
109
case LAPIC_ICR_DEST_ALL_BUT_SELF:
111
lapic_write_icr2(icr2);
112
lapic_write_icr1(icr1 | type | vector);
115
panic("Unknown send ipi type request\n");
121
static inline void lapic_enable_in_msr(void) {
122
#ifdef LAPIC_REGS_X86_H_
123
uint32_t msr_hi, msr_lo;
125
ia32_msr_read(IA32_APIC_BASE, &msr_lo, &msr_hi);
126
msr_lo |= (1 << IA32_APIC_BASE_ENABLE_BIT);
127
ia32_msr_write(IA32_APIC_BASE, msr_lo, msr_hi);
131
int lapic_enable(void) {
134
lapic_enable_in_msr();
141
val = (0x1 << cpu_get_id()) << 24;
142
lapic_write(LAPIC_LDR, val);
144
lapic_write(LAPIC_DFR, val);
147
val = lapic_read(LAPIC_SIVR);
149
lapic_write(LAPIC_SIVR, val);
155
lapic_write(LAPIC_LVT_TR, LAPIC_DISABLE);
156
lapic_write(LAPIC_LVT_PCR, LAPIC_NMI);
157
lapic_write(LAPIC_LVT_LINT0, LAPIC_DISABLE);
158
lapic_write(LAPIC_LVT_LINT1, LAPIC_DISABLE);
159
lapic_write(LAPIC_TASKPRIOR, 0);
165
PERIPH_MEMORY_DEFINE(local_apic, LOCAL_APIC_DEF_ADDR, 0x1000);