]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
x86: ivybridge: Add LAPIC support
authorSimon Glass <sjg@chromium.org>
Thu, 13 Nov 2014 05:42:27 +0000 (22:42 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 21 Nov 2014 06:34:15 +0000 (07:34 +0100)
The local advanced programmable interrupt controller is not used much in
U-Boot but we do need to set it up. Add basic support for this, which will
be extended as needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/ivybridge/cpu.c
arch/x86/include/asm/lapic.h [new file with mode: 0644]
arch/x86/include/asm/lapic_def.h [new file with mode: 0644]

index d5be2f587fb942eedcc65e6e8e2b2330af2f710f..60976db44d884b2a855c30a67418297125aa8232 100644 (file)
@@ -16,6 +16,7 @@
 #include <fdtdec.h>
 #include <asm/cpu.h>
 #include <asm/io.h>
+#include <asm/lapic.h>
 #include <asm/msr.h>
 #include <asm/mtrr.h>
 #include <asm/pci.h>
@@ -283,6 +284,8 @@ int print_cpuinfo(void)
        if (ret)
                return ret;
 
+       enable_lapic();
+
        ret = microcode_update_intel();
        if (ret && ret != -ENOENT && ret != -EEXIST)
                return ret;
diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h
new file mode 100644 (file)
index 0000000..948e643
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * From Coreboot file of same name
+ *
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef _ARCH_ASM_LAPIC_H
+#define _ARCH_ASM_LAPIC_H
+
+#include <asm/io.h>
+#include <asm/lapic_def.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+static inline __attribute__((always_inline))
+               unsigned long lapic_read(unsigned long reg)
+{
+       return readl(LAPIC_DEFAULT_BASE + reg);
+}
+
+static inline __attribute__((always_inline))
+               void lapic_write(unsigned long reg, unsigned long val)
+{
+       writel(val, LAPIC_DEFAULT_BASE + reg);
+}
+
+static inline __attribute__((always_inline)) void lapic_wait_icr_idle(void)
+{
+       do { } while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY);
+}
+
+static inline void enable_lapic(void)
+{
+       msr_t msr;
+
+       msr = msr_read(LAPIC_BASE_MSR);
+       msr.hi &= 0xffffff00;
+       msr.lo &= 0x000007ff;
+       msr.lo |= LAPIC_DEFAULT_BASE | (1 << 11);
+       msr_write(LAPIC_BASE_MSR, msr);
+}
+
+static inline void disable_lapic(void)
+{
+       msr_t msr;
+
+       msr = msr_read(LAPIC_BASE_MSR);
+       msr.lo &= ~(1 << 11);
+       msr_write(LAPIC_BASE_MSR, msr);
+}
+
+static inline __attribute__((always_inline)) unsigned long lapicid(void)
+{
+       return lapic_read(LAPIC_ID) >> 24;
+}
+
+#endif
diff --git a/arch/x86/include/asm/lapic_def.h b/arch/x86/include/asm/lapic_def.h
new file mode 100644 (file)
index 0000000..722cead
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Taken from the Coreboot file of the same name
+ *
+ * (C) Copyright 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef _ASM_LAPIC_DEF_H
+#define _ASM_LAPIC_DEF_H
+
+#define LAPIC_BASE_MSR                 0x1B
+#define LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR     (1 << 8)
+#define LAPIC_BASE_MSR_ENABLE          (1 << 11)
+#define LAPIC_BASE_MSR_ADDR_MASK       0xFFFFF000
+
+#define LOCAL_APIC_ADDR                        0xfee00000
+#define LAPIC_DEFAULT_BASE             LOCAL_APIC_ADDR
+
+#define LAPIC_ID                       0x020
+#define LAPIC_LVR                      0x030
+#define LAPIC_TASKPRI                  0x80
+#define LAPIC_TPRI_MASK                        0xFF
+#define LAPIC_ARBID                    0x090
+#define LAPIC_RRR                      0x0C0
+#define LAPIC_SVR                      0x0f0
+#define LAPIC_SPIV                     0x0f0
+#define LAPIC_SPIV_ENABLE              0x100
+#define LAPIC_ESR                      0x280
+#define LAPIC_ESR_SEND_CS              0x00001
+#define LAPIC_ESR_RECV_CS              0x00002
+#define LAPIC_ESR_SEND_ACC             0x00004
+#define LAPIC_ESR_RECV_ACC             0x00008
+#define LAPIC_ESR_SENDILL              0x00020
+#define LAPIC_ESR_RECVILL              0x00040
+#define LAPIC_ESR_ILLREGA              0x00080
+#define LAPIC_ICR                      0x300
+#define LAPIC_DEST_SELF                        0x40000
+#define LAPIC_DEST_ALLINC              0x80000
+#define LAPIC_DEST_ALLBUT              0xC0000
+#define LAPIC_ICR_RR_MASK              0x30000
+#define LAPIC_ICR_RR_INVALID           0x00000
+#define LAPIC_ICR_RR_INPROG            0x10000
+#define LAPIC_ICR_RR_VALID             0x20000
+#define LAPIC_INT_LEVELTRIG            0x08000
+#define LAPIC_INT_ASSERT               0x04000
+#define LAPIC_ICR_BUSY                 0x01000
+#define LAPIC_DEST_LOGICAL             0x00800
+#define LAPIC_DM_FIXED                 0x00000
+#define LAPIC_DM_LOWEST                        0x00100
+#define LAPIC_DM_SMI                   0x00200
+#define LAPIC_DM_REMRD                 0x00300
+#define LAPIC_DM_NMI                   0x00400
+#define LAPIC_DM_INIT                  0x00500
+#define LAPIC_DM_STARTUP               0x00600
+#define LAPIC_DM_EXTINT                        0x00700
+#define LAPIC_VECTOR_MASK              0x000FF
+#define LAPIC_ICR2                     0x310
+#define GET_LAPIC_DEST_FIELD(x)                (((x) >> 24) & 0xFF)
+#define SET_LAPIC_DEST_FIELD(x)                ((x) << 24)
+#define LAPIC_LVTT                     0x320
+#define LAPIC_LVTPC                    0x340
+#define LAPIC_LVT0                     0x350
+#define LAPIC_LVT_TIMER_BASE_MASK      (0x3 << 18)
+#define GET_LAPIC_TIMER_BASE(x)                (((x) >> 18) & 0x3)
+#define SET_LAPIC_TIMER_BASE(x)                (((x) << 18))
+#define LAPIC_TIMER_BASE_CLKIN         0x0
+#define LAPIC_TIMER_BASE_TMBASE                0x1
+#define LAPIC_TIMER_BASE_DIV           0x2
+#define LAPIC_LVT_TIMER_PERIODIC       (1 << 17)
+#define LAPIC_LVT_MASKED               (1 << 16)
+#define LAPIC_LVT_LEVEL_TRIGGER                (1 << 15)
+#define LAPIC_LVT_REMOTE_IRR           (1 << 14)
+#define LAPIC_INPUT_POLARITY           (1 << 13)
+#define LAPIC_SEND_PENDING             (1 << 12)
+#define LAPIC_LVT_RESERVED_1           (1 << 11)
+#define LAPIC_DELIVERY_MODE_MASK       (7 << 8)
+#define LAPIC_DELIVERY_MODE_FIXED      (0 << 8)
+#define LAPIC_DELIVERY_MODE_NMI                (4 << 8)
+#define LAPIC_DELIVERY_MODE_EXTINT     (7 << 8)
+#define GET_LAPIC_DELIVERY_MODE(x)     (((x) >> 8) & 0x7)
+#define SET_LAPIC_DELIVERY_MODE(x, y)  (((x) & ~0x700)|((y) << 8))
+#define LAPIC_MODE_FIXED               0x0
+#define LAPIC_MODE_NMI                 0x4
+#define LAPIC_MODE_EXINT               0x7
+#define LAPIC_LVT1                     0x360
+#define LAPIC_LVTERR                   0x370
+#define LAPIC_TMICT                    0x380
+#define LAPIC_TMCCT                    0x390
+#define LAPIC_TDCR                     0x3E0
+#define LAPIC_TDR_DIV_TMBASE           (1 << 2)
+#define LAPIC_TDR_DIV_1                        0xB
+#define LAPIC_TDR_DIV_2                        0x0
+#define LAPIC_TDR_DIV_4                        0x1
+#define LAPIC_TDR_DIV_8                        0x2
+#define LAPIC_TDR_DIV_16               0x3
+#define LAPIC_TDR_DIV_32               0x8
+#define LAPIC_TDR_DIV_64               0x9
+#define LAPIC_TDR_DIV_128              0xA
+
+#endif