blob: 0ac87aa2d3e678f6d0b7d441500250a7697d77f9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#ifndef ARCH_SMP_LAPIC_H
#define ARCH_SMP_LAPIC_H
#include <cpu/p6/msr.h>
#include <cpu/p6/apic.h>
#include <arch/hlt.h>
static void enable_lapic(void)
{
msr_t msr;
msr = rdmsr(0x1b);
msr.hi &= 0xffffff00;
msr.lo &= 0x000007ff;
msr.lo |= APIC_DEFAULT_BASE | (1 << 11);
wrmsr(0x1b, msr);
}
static void disable_lapic(void)
{
msr_t msr;
msr = rdmsr(0x1b);
msr.lo &= ~ (1 << 11);
wrmsr(0x1b, msr);
}
static inline unsigned long lapicid(void)
{
return apic_read(APIC_ID) >> 24;
}
static void stop_this_cpu(void)
{
unsigned apicid;
apicid = lapicid();
/* Send an APIC INIT to myself */
apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT);
/* Wait for the ipi send to finish */
apic_wait_icr_idle();
/* Deassert the APIC INIT */
apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
/* Wait for the ipi send to finish */
apic_wait_icr_idle();
/* If I haven't halted spin forever */
for(;;) {
hlt();
}
}
#endif /* ARCH_SMP_LAPIC_H */
|