2 * This file is part of the coreboot project.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <cpu/x86/lapic.h>
15 #include <console/console.h>
16 #include <cpu/x86/msr.h>
17 #include <cpu/x86/mtrr.h>
19 void setup_lapic(void)
21 /* this is so interrupts work. This is very limited scope --
22 * linux will do better later, we hope ...
24 /* this is the first way we learned to do it. It fails on real SMP
25 * stuff. So we have to do things differently ...
26 * see the Intel mp1.4 spec, page A-3
30 /* Only Pentium Pro and later have those MSR stuff */
33 printk(BIOS_INFO
, "Setting up local APIC...");
35 /* Enable the local APIC */
36 msr
= rdmsr(LAPIC_BASE_MSR
);
37 msr
.lo
|= LAPIC_BASE_MSR_ENABLE
;
38 msr
.lo
&= ~LAPIC_BASE_MSR_ADDR_MASK
;
39 msr
.lo
|= LAPIC_DEFAULT_BASE
;
40 wrmsr(LAPIC_BASE_MSR
, msr
);
43 * Set Task Priority to 'accept all'.
45 lapic_write_around(LAPIC_TASKPRI
,
46 lapic_read_around(LAPIC_TASKPRI
) & ~LAPIC_TPRI_MASK
);
48 /* Put the local APIC in virtual wire mode */
49 lapic_write_around(LAPIC_SPIV
,
50 (lapic_read_around(LAPIC_SPIV
) & ~(LAPIC_VECTOR_MASK
))
52 lapic_write_around(LAPIC_LVT0
,
53 (lapic_read_around(LAPIC_LVT0
) &
54 ~(LAPIC_LVT_MASKED
| LAPIC_LVT_LEVEL_TRIGGER
|
55 LAPIC_LVT_REMOTE_IRR
| LAPIC_INPUT_POLARITY
|
56 LAPIC_SEND_PENDING
|LAPIC_LVT_RESERVED_1
|
57 LAPIC_DELIVERY_MODE_MASK
))
58 | (LAPIC_LVT_REMOTE_IRR
|LAPIC_SEND_PENDING
|
59 LAPIC_DELIVERY_MODE_EXTINT
)
61 lapic_write_around(LAPIC_LVT1
,
62 (lapic_read_around(LAPIC_LVT1
) &
63 ~(LAPIC_LVT_MASKED
| LAPIC_LVT_LEVEL_TRIGGER
|
64 LAPIC_LVT_REMOTE_IRR
| LAPIC_INPUT_POLARITY
|
65 LAPIC_SEND_PENDING
|LAPIC_LVT_RESERVED_1
|
66 LAPIC_DELIVERY_MODE_MASK
))
67 | (LAPIC_LVT_REMOTE_IRR
|LAPIC_SEND_PENDING
|
68 LAPIC_DELIVERY_MODE_NMI
)
71 printk(BIOS_DEBUG
, " apic_id: 0x%02lx ", lapicid());
73 #else /* !NEED_LAPIC */
74 /* Only Pentium Pro and later have those MSR stuff */
77 printk(BIOS_INFO
, "Disabling local APIC...");
79 msr
= rdmsr(LAPIC_BASE_MSR
);
80 msr
.lo
&= ~LAPIC_BASE_MSR_ENABLE
;
81 wrmsr(LAPIC_BASE_MSR
, msr
);
82 #endif /* !NEED_LAPIC */
83 printk(BIOS_INFO
, "done.\n");