summaryrefslogtreecommitdiff
path: root/src/cpu/x86/lapic/lapic.c
diff options
context:
space:
mode:
authorEric Biederman <ebiederm@xmission.com>2004-10-14 19:29:29 +0000
committerEric Biederman <ebiederm@xmission.com>2004-10-14 19:29:29 +0000
commitfcd5ace00b333ce31b11b02a2243dfbf39307f10 (patch)
treed686d752ccea9b185b0008c70d8523749b26e2dd /src/cpu/x86/lapic/lapic.c
parent98e619b1cefcb9871185f4cc3db85fa430dcdbce (diff)
- Add new cvs code to cvs
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1657 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/cpu/x86/lapic/lapic.c')
-rw-r--r--src/cpu/x86/lapic/lapic.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/cpu/x86/lapic/lapic.c b/src/cpu/x86/lapic/lapic.c
new file mode 100644
index 0000000000..8282890bf7
--- /dev/null
+++ b/src/cpu/x86/lapic/lapic.c
@@ -0,0 +1,72 @@
+#include <cpu/x86/lapic.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+
+void setup_lapic(void)
+{
+ /* this is so interrupts work. This is very limited scope --
+ * linux will do better later, we hope ...
+ */
+ /* this is the first way we learned to do it. It fails on real SMP
+ * stuff. So we have to do things differently ...
+ * see the Intel mp1.4 spec, page A-3
+ */
+
+#if NEED_LAPIC == 1
+ /* Only Pentium Pro and later have those MSR stuff */
+ msr_t msr;
+
+ printk_info("Setting up local apic...");
+
+ /* Enable the local apic */
+ msr = rdmsr(LAPIC_BASE_MSR);
+ msr.lo |= LAPIC_BASE_MSR_ENABLE;
+ msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
+ msr.lo |= LAPIC_DEFAULT_BASE;
+ wrmsr(LAPIC_BASE_MSR, msr);
+
+ /*
+ * Set Task Priority to 'accept all'.
+ */
+ lapic_write_around(LAPIC_TASKPRI,
+ lapic_read_around(LAPIC_TASKPRI) & ~LAPIC_TPRI_MASK);
+
+ /* Put the local apic in virtual wire mode */
+ lapic_write_around(LAPIC_SPIV,
+ (lapic_read_around(LAPIC_SPIV) & ~(LAPIC_VECTOR_MASK))
+ | LAPIC_SPIV_ENABLE);
+ lapic_write_around(LAPIC_LVT0,
+ (lapic_read_around(LAPIC_LVT0) &
+ ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
+ LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
+ LAPIC_SEND_PENDING |LAPIC_LVT_RESERVED_1 |
+ LAPIC_DELIVERY_MODE_MASK))
+ | (LAPIC_LVT_REMOTE_IRR |LAPIC_SEND_PENDING |
+ LAPIC_DELIVERY_MODE_EXTINT)
+ );
+ lapic_write_around(LAPIC_LVT1,
+ (lapic_read_around(LAPIC_LVT1) &
+ ~(LAPIC_LVT_MASKED | LAPIC_LVT_LEVEL_TRIGGER |
+ LAPIC_LVT_REMOTE_IRR | LAPIC_INPUT_POLARITY |
+ LAPIC_SEND_PENDING |LAPIC_LVT_RESERVED_1 |
+ LAPIC_DELIVERY_MODE_MASK))
+ | (LAPIC_LVT_REMOTE_IRR |LAPIC_SEND_PENDING |
+ LAPIC_DELIVERY_MODE_NMI)
+ );
+
+ printk_debug(" apic_id: %d ", lapicid());
+
+#else /* !NEED_LLAPIC */
+ /* Only Pentium Pro and later have those MSR stuff */
+ msr_t msr;
+
+ printk_info("Disabling local apic...");
+
+ msr = rdmsr(LAPIC_BASE_MSR);
+ msr.lo &= ~LAPIC_BASE_MSR_ENABLE;
+ wrmsr(LAPIC_BASE_MSR, msr);
+#endif /* !NEED_LAPIC */
+ printk_info("done.\n");
+ post_code(0x9b);
+}