[U-Boot] [PATCH v3 0/8] x86: Add additional system setup for ivybridge

This series adds full support for the LPC (Low Pin Count) bridge, the PCH (Platform Controller Hub), PCI devices like USB and SATA and more CPU init support (turbo mode, etc.)
With this series, chromebook_link can use SATA and USB at the command line.
Changes in v3: - Add new patch to add ivybridge directory to Makefile - Add new patch to fix SIZE_MAX compiler warning when using stdint.h - Split out CONFIG_INTEL_CORE_ARCH removal patch - Use exitsing disable_lapic() code instead of duplicating it
Changes in v2: - Remove use of __PRE_RAM__ define - Use existing lapic_setup() code instead of duplicating it
Simon Glass (8): x86: Drop old CONFIG_INTEL_CORE_ARCH code x86: Add LAPIC setup code x86: Add init for model 206AX CPU x86: Drop some msr functions that we don't support x86: ivybridge: Add northbridge init functions x86: config: Enable SPI for chromebook_link x86: Add ivybridge directory to Makefile Fix SIZE_MAX compiler warning when using stdint.h
arch/x86/cpu/Makefile | 3 + arch/x86/cpu/interrupts.c | 28 -- arch/x86/cpu/ivybridge/Makefile | 2 + arch/x86/cpu/ivybridge/bd82x6x.c | 8 + arch/x86/cpu/ivybridge/model_206ax.c | 514 ++++++++++++++++++++++ arch/x86/cpu/ivybridge/northbridge.c | 188 ++++++++ arch/x86/cpu/lapic.c | 57 +++ arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 3 + arch/x86/include/asm/arch-ivybridge/model_206ax.h | 4 + arch/x86/include/asm/arch-ivybridge/sandybridge.h | 13 +- arch/x86/include/asm/lapic.h | 124 +++++- arch/x86/include/asm/msr-index.h | 2 + arch/x86/include/asm/msr.h | 11 - arch/x86/include/asm/post.h | 1 + include/configs/chromebook_link.h | 4 - include/fdtdec.h | 1 + include/linux/kernel.h | 2 + lib/fdtdec.c | 1 + 18 files changed, 920 insertions(+), 46 deletions(-) create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c create mode 100644 arch/x86/cpu/ivybridge/northbridge.c create mode 100644 arch/x86/cpu/lapic.c

This is no-longer used, so drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Split out CONFIG_INTEL_CORE_ARCH removal patch
Changes in v2: None
arch/x86/cpu/interrupts.c | 28 ---------------------------- 1 file changed, 28 deletions(-)
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index ea03724..a21d2a6 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -617,31 +617,3 @@ asm(".globl irq_common_entry\n" \ DECLARE_INTERRUPT(253) \ DECLARE_INTERRUPT(254) \ DECLARE_INTERRUPT(255)); - -#if defined(CONFIG_INTEL_CORE_ARCH) -/* - * Get the number of CPU time counter ticks since it was read first time after - * restart. This yields a free running counter guaranteed to take almost 6 - * years to wrap around even at 100GHz clock rate. - */ -u64 get_ticks(void) -{ - u64 now_tick = rdtsc(); - - if (!gd->arch.tsc_base) - gd->arch.tsc_base = now_tick; - - return now_tick - gd->arch.tsc_base; -} - -#define PLATFORM_INFO_MSR 0xce - -unsigned long get_tbclk(void) -{ - u32 ratio; - u64 platform_info = native_read_msr(PLATFORM_INFO_MSR); - - ratio = (platform_info >> 8) & 0xff; - return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */ -} -#endif

On Tue, Nov 25, 2014 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
This is no-longer used, so drop it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Split out CONFIG_INTEL_CORE_ARCH removal patch
Changes in v2: None
arch/x86/cpu/interrupts.c | 28 ---------------------------- 1 file changed, 28 deletions(-)
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index ea03724..a21d2a6 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -617,31 +617,3 @@ asm(".globl irq_common_entry\n" \ DECLARE_INTERRUPT(253) \ DECLARE_INTERRUPT(254) \ DECLARE_INTERRUPT(255));
-#if defined(CONFIG_INTEL_CORE_ARCH) -/*
- Get the number of CPU time counter ticks since it was read first time after
- restart. This yields a free running counter guaranteed to take almost 6
- years to wrap around even at 100GHz clock rate.
- */
-u64 get_ticks(void) -{
u64 now_tick = rdtsc();
if (!gd->arch.tsc_base)
gd->arch.tsc_base = now_tick;
return now_tick - gd->arch.tsc_base;
-}
-#define PLATFORM_INFO_MSR 0xce
-unsigned long get_tbclk(void) -{
u32 ratio;
u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
ratio = (platform_info >> 8) & 0xff;
return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
-}
-#endif
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 24 November 2014 at 22:22, Bin Meng bmeng.cn@gmail.com wrote:
On Tue, Nov 25, 2014 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
This is no-longer used, so drop it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Split out CONFIG_INTEL_CORE_ARCH removal patch
Changes in v2: None
arch/x86/cpu/interrupts.c | 28 ---------------------------- 1 file changed, 28 deletions(-)
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index ea03724..a21d2a6 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -617,31 +617,3 @@ asm(".globl irq_common_entry\n" \ DECLARE_INTERRUPT(253) \ DECLARE_INTERRUPT(254) \ DECLARE_INTERRUPT(255));
-#if defined(CONFIG_INTEL_CORE_ARCH) -/*
- Get the number of CPU time counter ticks since it was read first time after
- restart. This yields a free running counter guaranteed to take almost 6
- years to wrap around even at 100GHz clock rate.
- */
-u64 get_ticks(void) -{
u64 now_tick = rdtsc();
if (!gd->arch.tsc_base)
gd->arch.tsc_base = now_tick;
return now_tick - gd->arch.tsc_base;
-}
-#define PLATFORM_INFO_MSR 0xce
-unsigned long get_tbclk(void) -{
u32 ratio;
u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
ratio = (platform_info >> 8) & 0xff;
return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
-}
-#endif
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86.

Add code to set up the Local Advanced Peripheral Interrupt Controller.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Use exitsing disable_lapic() code instead of duplicating it
Changes in v2: - Remove use of __PRE_RAM__ define - Use existing lapic_setup() code instead of duplicating it
arch/x86/cpu/Makefile | 1 + arch/x86/cpu/lapic.c | 57 ++++++++++++++++++++ arch/x86/include/asm/lapic.h | 124 ++++++++++++++++++++++++++++++++++++++++++- arch/x86/include/asm/post.h | 1 + 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 arch/x86/cpu/lapic.c
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index db2abdf..4d3c5ea 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -13,5 +13,6 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o diff --git a/arch/x86/cpu/lapic.c b/arch/x86/cpu/lapic.c new file mode 100644 index 0000000..4690603 --- /dev/null +++ b/arch/x86/cpu/lapic.c @@ -0,0 +1,57 @@ +/* + * From coreboot file of same name + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <asm/msr.h> +#include <asm/io.h> +#include <asm/lapic.h> +#include <asm/post.h> + +void lapic_setup(void) +{ +#if NEED_LAPIC == 1 + /* Only Pentium Pro and later have those MSR stuff */ + debug("Setting up local apic: "); + + /* Enable the local apic */ + enable_lapic(); + + /* + * 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)); + + debug("apic_id: 0x%02lx, ", lapicid()); +#else /* !NEED_LLAPIC */ + /* Only Pentium Pro and later have those MSR stuff */ + debug("Disabling local apic: "); + disable_lapic(); +#endif /* !NEED_LAPIC */ + debug("done.\n"); + post_code(POST_LAPIC); +} diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h index 948e643..0a7f443 100644 --- a/arch/x86/include/asm/lapic.h +++ b/arch/x86/include/asm/lapic.h @@ -14,6 +14,13 @@ #include <asm/msr.h> #include <asm/processor.h>
+/* See if I need to initialize the local apic */ +#if CONFIG_SMP || CONFIG_IOAPIC +# define NEED_LAPIC 1 +#else +# define NEED_LAPIC 0 +#endif + static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg) { @@ -37,8 +44,9 @@ static inline void enable_lapic(void)
msr = msr_read(LAPIC_BASE_MSR); msr.hi &= 0xffffff00; - msr.lo &= 0x000007ff; - msr.lo |= LAPIC_DEFAULT_BASE | (1 << 11); + msr.lo |= LAPIC_BASE_MSR_ENABLE; + msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK; + msr.lo |= LAPIC_DEFAULT_BASE; msr_write(LAPIC_BASE_MSR, msr); }
@@ -56,4 +64,116 @@ static inline __attribute__((always_inline)) unsigned long lapicid(void) return lapic_read(LAPIC_ID) >> 24; }
+#if !CONFIG_AP_IN_SIPI_WAIT +/* If we need to go back to sipi wait, we use the long non-inlined version of + * this function in lapic_cpu_init.c + */ +static inline __attribute__((always_inline)) void stop_this_cpu(void) +{ + /* Called by an AP when it is ready to halt and wait for a new task */ + for (;;) + cpu_hlt(); +} +#else +void stop_this_cpu(void); +#endif + +#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \ + sizeof(*(ptr)))) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + +/* + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway + * Note 2: xchg has side effect, so that attribute volatile is necessary, + * but generally the primitive is invalid, *ptr is output argument. --ANK + */ +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + switch (size) { + case 1: + __asm__ __volatile__("xchgb %b0,%1" + : "=q" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + case 2: + __asm__ __volatile__("xchgw %w0,%1" + : "=r" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + case 4: + __asm__ __volatile__("xchgl %0,%1" + : "=r" (x) + : "m" (*__xg(ptr)), "0" (x) + : "memory"); + break; + } + + return x; +} + +static inline void lapic_write_atomic(unsigned long reg, unsigned long v) +{ + (void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v); +} + + +#ifdef X86_GOOD_APIC +# define FORCE_READ_AROUND_WRITE 0 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write((x), (y)) +#else +# define FORCE_READ_AROUND_WRITE 1 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write_atomic((x), (y)) +#endif + +static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) +{ + int timeout; + unsigned long status; + int result; + lapic_wait_icr_idle(); + lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid)); + lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4)); + timeout = 0; + do { + status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK; + } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000); + + result = -1; + if (status == LAPIC_ICR_RR_VALID) { + *pvalue = lapic_read(LAPIC_RRR); + result = 0; + } + return result; +} + + +void lapic_setup(void); + +#if CONFIG_SMP +struct device; +int start_cpu(struct device *cpu); +#endif /* CONFIG_SMP */ + +int boot_cpu(void); + +/** + * struct x86_cpu_priv - Information about a single CPU + * + * @apic_id: Advanced Programmable Interrupt Controller Identifier, which is + * just a number representing the CPU core + * + * TODO: Move this to driver model once lifecycle is understood + */ +struct x86_cpu_priv { + int apic_id; + int start_err; +}; + #endif diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h index ce68839..6d2ae5d 100644 --- a/arch/x86/include/asm/post.h +++ b/arch/x86/include/asm/post.h @@ -30,6 +30,7 @@ #define POST_PRE_MRC 0x2e #define POST_MRC 0x2f #define POST_DRAM 0x2f +#define POST_LAPIC 0x30
#define POST_RAM_FAILURE 0xea

On Tue, Nov 25, 2014 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
Add code to set up the Local Advanced Peripheral Interrupt Controller.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Use exitsing disable_lapic() code instead of duplicating it
Changes in v2:
- Remove use of __PRE_RAM__ define
- Use existing lapic_setup() code instead of duplicating it
arch/x86/cpu/Makefile | 1 + arch/x86/cpu/lapic.c | 57 ++++++++++++++++++++ arch/x86/include/asm/lapic.h | 124 ++++++++++++++++++++++++++++++++++++++++++- arch/x86/include/asm/post.h | 1 + 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 arch/x86/cpu/lapic.c
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index db2abdf..4d3c5ea 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -13,5 +13,6 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o diff --git a/arch/x86/cpu/lapic.c b/arch/x86/cpu/lapic.c new file mode 100644 index 0000000..4690603 --- /dev/null +++ b/arch/x86/cpu/lapic.c @@ -0,0 +1,57 @@ +/*
- From coreboot file of same name
- Copyright (C) 2008-2009 coresystems GmbH
- Copyright (C) 2014 Google, Inc
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <asm/msr.h> +#include <asm/io.h> +#include <asm/lapic.h> +#include <asm/post.h>
+void lapic_setup(void) +{ +#if NEED_LAPIC == 1
/* Only Pentium Pro and later have those MSR stuff */
debug("Setting up local apic: ");
/* Enable the local apic */
enable_lapic();
/*
* 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));
debug("apic_id: 0x%02lx, ", lapicid());
+#else /* !NEED_LLAPIC */
/* Only Pentium Pro and later have those MSR stuff */
debug("Disabling local apic: ");
disable_lapic();
+#endif /* !NEED_LAPIC */
debug("done.\n");
post_code(POST_LAPIC);
+} diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h index 948e643..0a7f443 100644 --- a/arch/x86/include/asm/lapic.h +++ b/arch/x86/include/asm/lapic.h @@ -14,6 +14,13 @@ #include <asm/msr.h> #include <asm/processor.h>
+/* See if I need to initialize the local apic */ +#if CONFIG_SMP || CONFIG_IOAPIC +# define NEED_LAPIC 1 +#else +# define NEED_LAPIC 0 +#endif
static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg) { @@ -37,8 +44,9 @@ static inline void enable_lapic(void)
msr = msr_read(LAPIC_BASE_MSR); msr.hi &= 0xffffff00;
msr.lo &= 0x000007ff;
msr.lo |= LAPIC_DEFAULT_BASE | (1 << 11);
msr.lo |= LAPIC_BASE_MSR_ENABLE;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE; msr_write(LAPIC_BASE_MSR, msr);
}
@@ -56,4 +64,116 @@ static inline __attribute__((always_inline)) unsigned long lapicid(void) return lapic_read(LAPIC_ID) >> 24; }
+#if !CONFIG_AP_IN_SIPI_WAIT +/* If we need to go back to sipi wait, we use the long non-inlined version of
- this function in lapic_cpu_init.c
- */
+static inline __attribute__((always_inline)) void stop_this_cpu(void) +{
/* Called by an AP when it is ready to halt and wait for a new task */
for (;;)
cpu_hlt();
+} +#else +void stop_this_cpu(void); +#endif
+#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \
sizeof(*(ptr))))
+struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x))
+/*
- Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- Note 2: xchg has side effect, so that attribute volatile is necessary,
but generally the primitive is invalid, *ptr is output argument. --ANK
- */
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
int size)
+{
switch (size) {
case 1:
__asm__ __volatile__("xchgb %b0,%1"
: "=q" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 2:
__asm__ __volatile__("xchgw %w0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 4:
__asm__ __volatile__("xchgl %0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
}
return x;
+}
+static inline void lapic_write_atomic(unsigned long reg, unsigned long v) +{
(void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v);
+}
+#ifdef X86_GOOD_APIC +# define FORCE_READ_AROUND_WRITE 0 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write((x), (y)) +#else +# define FORCE_READ_AROUND_WRITE 1 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write_atomic((x), (y)) +#endif
+static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) +{
int timeout;
unsigned long status;
int result;
lapic_wait_icr_idle();
lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4));
timeout = 0;
do {
status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK;
} while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000);
result = -1;
if (status == LAPIC_ICR_RR_VALID) {
*pvalue = lapic_read(LAPIC_RRR);
result = 0;
}
return result;
+}
+void lapic_setup(void);
+#if CONFIG_SMP +struct device; +int start_cpu(struct device *cpu); +#endif /* CONFIG_SMP */
+int boot_cpu(void);
+/**
- struct x86_cpu_priv - Information about a single CPU
- @apic_id: Advanced Programmable Interrupt Controller Identifier, which is
- just a number representing the CPU core
- TODO: Move this to driver model once lifecycle is understood
- */
+struct x86_cpu_priv {
int apic_id;
int start_err;
+};
#endif diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h index ce68839..6d2ae5d 100644 --- a/arch/x86/include/asm/post.h +++ b/arch/x86/include/asm/post.h @@ -30,6 +30,7 @@ #define POST_PRE_MRC 0x2e #define POST_MRC 0x2f #define POST_DRAM 0x2f +#define POST_LAPIC 0x30
#define POST_RAM_FAILURE 0xea
--
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 24 November 2014 at 22:24, Bin Meng bmeng.cn@gmail.com wrote:
On Tue, Nov 25, 2014 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
Add code to set up the Local Advanced Peripheral Interrupt Controller.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Use exitsing disable_lapic() code instead of duplicating it
Changes in v2:
- Remove use of __PRE_RAM__ define
- Use existing lapic_setup() code instead of duplicating it
arch/x86/cpu/Makefile | 1 + arch/x86/cpu/lapic.c | 57 ++++++++++++++++++++ arch/x86/include/asm/lapic.h | 124 ++++++++++++++++++++++++++++++++++++++++++- arch/x86/include/asm/post.h | 1 + 4 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 arch/x86/cpu/lapic.c
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index db2abdf..4d3c5ea 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -13,5 +13,6 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o diff --git a/arch/x86/cpu/lapic.c b/arch/x86/cpu/lapic.c new file mode 100644 index 0000000..4690603 --- /dev/null +++ b/arch/x86/cpu/lapic.c @@ -0,0 +1,57 @@ +/*
- From coreboot file of same name
- Copyright (C) 2008-2009 coresystems GmbH
- Copyright (C) 2014 Google, Inc
- SPDX-License-Identifier: GPL-2.0
- */
+#include <common.h> +#include <asm/msr.h> +#include <asm/io.h> +#include <asm/lapic.h> +#include <asm/post.h>
+void lapic_setup(void) +{ +#if NEED_LAPIC == 1
/* Only Pentium Pro and later have those MSR stuff */
debug("Setting up local apic: ");
/* Enable the local apic */
enable_lapic();
/*
* 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));
debug("apic_id: 0x%02lx, ", lapicid());
+#else /* !NEED_LLAPIC */
/* Only Pentium Pro and later have those MSR stuff */
debug("Disabling local apic: ");
disable_lapic();
+#endif /* !NEED_LAPIC */
debug("done.\n");
post_code(POST_LAPIC);
+} diff --git a/arch/x86/include/asm/lapic.h b/arch/x86/include/asm/lapic.h index 948e643..0a7f443 100644 --- a/arch/x86/include/asm/lapic.h +++ b/arch/x86/include/asm/lapic.h @@ -14,6 +14,13 @@ #include <asm/msr.h> #include <asm/processor.h>
+/* See if I need to initialize the local apic */ +#if CONFIG_SMP || CONFIG_IOAPIC +# define NEED_LAPIC 1 +#else +# define NEED_LAPIC 0 +#endif
static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg) { @@ -37,8 +44,9 @@ static inline void enable_lapic(void)
msr = msr_read(LAPIC_BASE_MSR); msr.hi &= 0xffffff00;
msr.lo &= 0x000007ff;
msr.lo |= LAPIC_DEFAULT_BASE | (1 << 11);
msr.lo |= LAPIC_BASE_MSR_ENABLE;
msr.lo &= ~LAPIC_BASE_MSR_ADDR_MASK;
msr.lo |= LAPIC_DEFAULT_BASE; msr_write(LAPIC_BASE_MSR, msr);
}
@@ -56,4 +64,116 @@ static inline __attribute__((always_inline)) unsigned long lapicid(void) return lapic_read(LAPIC_ID) >> 24; }
+#if !CONFIG_AP_IN_SIPI_WAIT +/* If we need to go back to sipi wait, we use the long non-inlined version of
- this function in lapic_cpu_init.c
- */
+static inline __attribute__((always_inline)) void stop_this_cpu(void) +{
/* Called by an AP when it is ready to halt and wait for a new task */
for (;;)
cpu_hlt();
+} +#else +void stop_this_cpu(void); +#endif
+#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \
sizeof(*(ptr))))
+struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x))
+/*
- Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- Note 2: xchg has side effect, so that attribute volatile is necessary,
but generally the primitive is invalid, *ptr is output argument. --ANK
- */
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
int size)
+{
switch (size) {
case 1:
__asm__ __volatile__("xchgb %b0,%1"
: "=q" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 2:
__asm__ __volatile__("xchgw %w0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
case 4:
__asm__ __volatile__("xchgl %0,%1"
: "=r" (x)
: "m" (*__xg(ptr)), "0" (x)
: "memory");
break;
}
return x;
+}
+static inline void lapic_write_atomic(unsigned long reg, unsigned long v) +{
(void)xchg((volatile unsigned long *)(LAPIC_DEFAULT_BASE + reg), v);
+}
+#ifdef X86_GOOD_APIC +# define FORCE_READ_AROUND_WRITE 0 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write((x), (y)) +#else +# define FORCE_READ_AROUND_WRITE 1 +# define lapic_read_around(x) lapic_read(x) +# define lapic_write_around(x, y) lapic_write_atomic((x), (y)) +#endif
+static inline int lapic_remote_read(int apicid, int reg, unsigned long *pvalue) +{
int timeout;
unsigned long status;
int result;
lapic_wait_icr_idle();
lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
lapic_write_around(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4));
timeout = 0;
do {
status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK;
} while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000);
result = -1;
if (status == LAPIC_ICR_RR_VALID) {
*pvalue = lapic_read(LAPIC_RRR);
result = 0;
}
return result;
+}
+void lapic_setup(void);
+#if CONFIG_SMP +struct device; +int start_cpu(struct device *cpu); +#endif /* CONFIG_SMP */
+int boot_cpu(void);
+/**
- struct x86_cpu_priv - Information about a single CPU
- @apic_id: Advanced Programmable Interrupt Controller Identifier, which is
- just a number representing the CPU core
- TODO: Move this to driver model once lifecycle is understood
- */
+struct x86_cpu_priv {
int apic_id;
int start_err;
+};
#endif diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h index ce68839..6d2ae5d 100644 --- a/arch/x86/include/asm/post.h +++ b/arch/x86/include/asm/post.h @@ -30,6 +30,7 @@ #define POST_PRE_MRC 0x2e #define POST_MRC 0x2f #define POST_DRAM 0x2f +#define POST_LAPIC 0x30
#define POST_RAM_FAILURE 0xea
--
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86.

Add the setup code for the CPU so that it can be used at full speed.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/bd82x6x.c | 6 + arch/x86/cpu/ivybridge/model_206ax.c | 514 ++++++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 3 + arch/x86/include/asm/msr-index.h | 2 + include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 528 insertions(+) create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index aedc395..95491b5 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -11,6 +11,7 @@ obj-y += early_init.o obj-y += early_me.o obj-y += lpc.o obj-y += me_status.o +obj-y += model_206ax.o obj-y += microcode_intel.o obj-y += pch.o obj-y += pci.o diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 1fcbc28..1a3c036 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -90,6 +90,7 @@ int bd82x6x_init_pci_devices(void) { const void *blob = gd->fdt_blob; struct pci_controller *hose; + struct x86_cpu_priv *cpu; int sata_node;
hose = pci_bus_to_hose(0); @@ -105,6 +106,11 @@ int bd82x6x_init_pci_devices(void) bd82x6x_usb_ehci_init(PCH_EHCI1_DEV); bd82x6x_usb_ehci_init(PCH_EHCI2_DEV);
+ cpu = calloc(1, sizeof(*cpu)); + if (!cpu) + return -ENOMEM; + model_206ax_init(cpu); + return 0; }
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c new file mode 100644 index 0000000..11dc625 --- /dev/null +++ b/arch/x86/cpu/ivybridge/model_206ax.c @@ -0,0 +1,514 @@ +/* + * From Coreboot file of same name + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium Authors + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <fdtdec.h> +#include <malloc.h> +#include <asm/acpi.h> +#include <asm/cpu.h> +#include <asm/lapic.h> +#include <asm/lapic_def.h> +#include <asm/msr.h> +#include <asm/mtrr.h> +#include <asm/processor.h> +#include <asm/speedstep.h> +#include <asm/turbo.h> +#include <asm/arch/model_206ax.h> + +static void enable_vmx(void) +{ + struct cpuid_result regs; +#ifdef CONFIG_ENABLE_VMX + int enable = true; +#else + int enable = false; +#endif + msr_t msr; + + regs = cpuid(1); + /* Check that the VMX is supported before reading or writing the MSR. */ + if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) + return; + + msr = msr_read(MSR_IA32_FEATURE_CONTROL); + + if (msr.lo & (1 << 0)) { + debug("VMX is locked, so %s will do nothing\n", __func__); + /* VMX locked. If we set it again we get an illegal + * instruction + */ + return; + } + + /* The IA32_FEATURE_CONTROL MSR may initialize with random values. + * It must be cleared regardless of VMX config setting. + */ + msr.hi = 0; + msr.lo = 0; + + debug("%s VMX\n", enable ? "Enabling" : "Disabling"); + + /* + * Even though the Intel manual says you must set the lock bit in + * addition to the VMX bit in order for VMX to work, it is incorrect. + * Thus we leave it unlocked for the OS to manage things itself. + * This is good for a few reasons: + * - No need to reflash the bios just to toggle the lock bit. + * - The VMX bits really really should match each other across cores, + * so hard locking it on one while another has the opposite setting + * can easily lead to crashes as code using VMX migrates between + * them. + * - Vendors that want to "upsell" from a bios that disables+locks to + * one that doesn't is sleazy. + * By leaving this to the OS (e.g. Linux), people can do exactly what + * they want on the fly, and do it correctly (e.g. across multiple + * cores). + */ + if (enable) { + msr.lo |= (1 << 2); + if (regs.ecx & CPUID_SMX) + msr.lo |= (1 << 1); + } + + msr_write(MSR_IA32_FEATURE_CONTROL, msr); +} + +/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ +static const u8 power_limit_time_sec_to_msr[] = { + [0] = 0x00, + [1] = 0x0a, + [2] = 0x0b, + [3] = 0x4b, + [4] = 0x0c, + [5] = 0x2c, + [6] = 0x4c, + [7] = 0x6c, + [8] = 0x0d, + [10] = 0x2d, + [12] = 0x4d, + [14] = 0x6d, + [16] = 0x0e, + [20] = 0x2e, + [24] = 0x4e, + [28] = 0x6e, + [32] = 0x0f, + [40] = 0x2f, + [48] = 0x4f, + [56] = 0x6f, + [64] = 0x10, + [80] = 0x30, + [96] = 0x50, + [112] = 0x70, + [128] = 0x11, +}; + +/* Convert POWER_LIMIT_1_TIME MSR value to seconds */ +static const u8 power_limit_time_msr_to_sec[] = { + [0x00] = 0, + [0x0a] = 1, + [0x0b] = 2, + [0x4b] = 3, + [0x0c] = 4, + [0x2c] = 5, + [0x4c] = 6, + [0x6c] = 7, + [0x0d] = 8, + [0x2d] = 10, + [0x4d] = 12, + [0x6d] = 14, + [0x0e] = 16, + [0x2e] = 20, + [0x4e] = 24, + [0x6e] = 28, + [0x0f] = 32, + [0x2f] = 40, + [0x4f] = 48, + [0x6f] = 56, + [0x10] = 64, + [0x30] = 80, + [0x50] = 96, + [0x70] = 112, + [0x11] = 128, +}; + +int cpu_config_tdp_levels(void) +{ + struct cpuid_result result; + msr_t platform_info; + + /* Minimum CPU revision */ + result = cpuid(1); + if (result.eax < IVB_CONFIG_TDP_MIN_CPUID) + return 0; + + /* Bits 34:33 indicate how many levels supported */ + platform_info = msr_read(MSR_PLATFORM_INFO); + return (platform_info.hi >> 1) & 3; +} + +/* + * Configure processor power limits if possible + * This must be done AFTER set of BIOS_RESET_CPL + */ +void set_power_limits(u8 power_limit_1_time) +{ + msr_t msr = msr_read(MSR_PLATFORM_INFO); + msr_t limit; + unsigned power_unit; + unsigned tdp, min_power, max_power, max_time; + u8 power_limit_1_val; + + if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr)) + return; + + if (!(msr.lo & PLATFORM_INFO_SET_TDP)) + return; + + /* Get units */ + msr = msr_read(MSR_PKG_POWER_SKU_UNIT); + power_unit = 2 << ((msr.lo & 0xf) - 1); + + /* Get power defaults for this SKU */ + msr = msr_read(MSR_PKG_POWER_SKU); + tdp = msr.lo & 0x7fff; + min_power = (msr.lo >> 16) & 0x7fff; + max_power = msr.hi & 0x7fff; + max_time = (msr.hi >> 16) & 0x7f; + + debug("CPU TDP: %u Watts\n", tdp / power_unit); + + if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time) + power_limit_1_time = power_limit_time_msr_to_sec[max_time]; + + if (min_power > 0 && tdp < min_power) + tdp = min_power; + + if (max_power > 0 && tdp > max_power) + tdp = max_power; + + power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time]; + + /* Set long term power limit to TDP */ + limit.lo = 0; + limit.lo |= tdp & PKG_POWER_LIMIT_MASK; + limit.lo |= PKG_POWER_LIMIT_EN; + limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) << + PKG_POWER_LIMIT_TIME_SHIFT; + + /* Set short term power limit to 1.25 * TDP */ + limit.hi = 0; + limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK; + limit.hi |= PKG_POWER_LIMIT_EN; + /* Power limit 2 time is only programmable on SNB EP/EX */ + + msr_write(MSR_PKG_POWER_LIMIT, limit); + + /* Use nominal TDP values for CPUs with configurable TDP */ + if (cpu_config_tdp_levels()) { + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + limit.hi = 0; + limit.lo = msr.lo & 0xff; + msr_write(MSR_TURBO_ACTIVATION_RATIO, limit); + } +} + +static void configure_c_states(void) +{ + struct cpuid_result result; + msr_t msr; + + msr = msr_read(MSR_PMG_CST_CONFIG_CTL); + msr.lo |= (1 << 28); /* C1 Auto Undemotion Enable */ + msr.lo |= (1 << 27); /* C3 Auto Undemotion Enable */ + msr.lo |= (1 << 26); /* C1 Auto Demotion Enable */ + msr.lo |= (1 << 25); /* C3 Auto Demotion Enable */ + msr.lo &= ~(1 << 10); /* Disable IO MWAIT redirection */ + msr.lo |= 7; /* No package C-state limit */ + msr_write(MSR_PMG_CST_CONFIG_CTL, msr); + + msr = msr_read(MSR_PMG_IO_CAPTURE_ADR); + msr.lo &= ~0x7ffff; + msr.lo |= (PMB0_BASE + 4); /* LVL_2 base address */ + msr.lo |= (2 << 16); /* CST Range: C7 is max C-state */ + msr_write(MSR_PMG_IO_CAPTURE_ADR, msr); + + msr = msr_read(MSR_MISC_PWR_MGMT); + msr.lo &= ~(1 << 0); /* Enable P-state HW_ALL coordination */ + msr_write(MSR_MISC_PWR_MGMT, msr); + + msr = msr_read(MSR_POWER_CTL); + msr.lo |= (1 << 18); /* Enable Energy Perf Bias MSR 0x1b0 */ + msr.lo |= (1 << 1); /* C1E Enable */ + msr.lo |= (1 << 0); /* Bi-directional PROCHOT# */ + msr_write(MSR_POWER_CTL, msr); + + /* C3 Interrupt Response Time Limit */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | 0x50; + msr_write(MSR_PKGC3_IRTL, msr); + + /* C6 Interrupt Response Time Limit */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | 0x68; + msr_write(MSR_PKGC6_IRTL, msr); + + /* C7 Interrupt Response Time Limit */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | 0x6D; + msr_write(MSR_PKGC7_IRTL, msr); + + /* Primary Plane Current Limit */ + msr = msr_read(MSR_PP0_CURRENT_CONFIG); + msr.lo &= ~0x1fff; + msr.lo |= PP0_CURRENT_LIMIT; + msr_write(MSR_PP0_CURRENT_CONFIG, msr); + + /* Secondary Plane Current Limit */ + msr = msr_read(MSR_PP1_CURRENT_CONFIG); + msr.lo &= ~0x1fff; + result = cpuid(1); + if (result.eax >= 0x30600) + msr.lo |= PP1_CURRENT_LIMIT_IVB; + else + msr.lo |= PP1_CURRENT_LIMIT_SNB; + msr_write(MSR_PP1_CURRENT_CONFIG, msr); +} + +static int configure_thermal_target(void) +{ + int tcc_offset; + msr_t msr; + int node; + + /* Find pointer to CPU configuration */ + node = fdtdec_next_compatible(gd->fdt_blob, 0, + COMPAT_INTEL_MODEL_206AX); + if (node < 0) + return -ENOENT; + tcc_offset = fdtdec_get_int(gd->fdt_blob, node, "tcc-offset", 0); + + /* Set TCC activaiton offset if supported */ + msr = msr_read(MSR_PLATFORM_INFO); + if ((msr.lo & (1 << 30)) && tcc_offset) { + msr = msr_read(MSR_TEMPERATURE_TARGET); + msr.lo &= ~(0xf << 24); /* Bits 27:24 */ + msr.lo |= (tcc_offset & 0xf) << 24; + msr_write(MSR_TEMPERATURE_TARGET, msr); + } + + return 0; +} + +static void configure_misc(void) +{ + msr_t msr; + + msr = msr_read(IA32_MISC_ENABLE); + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */ + msr_write(IA32_MISC_ENABLE, msr); + + /* Disable Thermal interrupts */ + msr.lo = 0; + msr.hi = 0; + msr_write(IA32_THERM_INTERRUPT, msr); + + /* Enable package critical interrupt only */ + msr.lo = 1 << 4; + msr.hi = 0; + msr_write(IA32_PACKAGE_THERM_INTERRUPT, msr); +} + +static void enable_lapic_tpr(void) +{ + msr_t msr; + + msr = msr_read(MSR_PIC_MSG_CONTROL); + msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */ + msr_write(MSR_PIC_MSG_CONTROL, msr); +} + +static void configure_dca_cap(void) +{ + struct cpuid_result cpuid_regs; + msr_t msr; + + /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ + cpuid_regs = cpuid(1); + if (cpuid_regs.ecx & (1 << 18)) { + msr = msr_read(IA32_PLATFORM_DCA_CAP); + msr.lo |= 1; + msr_write(IA32_PLATFORM_DCA_CAP, msr); + } +} + +static void set_max_ratio(void) +{ + msr_t msr, perf_ctl; + + perf_ctl.hi = 0; + + /* Check for configurable TDP option */ + if (cpu_config_tdp_levels()) { + /* Set to nominal TDP ratio */ + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = msr_read(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + msr_write(IA32_PERF_CTL, perf_ctl); + + debug("model_x06ax: frequency set to %d\n", + ((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK); +} + +static void set_energy_perf_bias(u8 policy) +{ + msr_t msr; + + /* Energy Policy is bits 3:0 */ + msr = msr_read(IA32_ENERGY_PERFORMANCE_BIAS); + msr.lo &= ~0xf; + msr.lo |= policy & 0xf; + msr_write(IA32_ENERGY_PERFORMANCE_BIAS, msr); + + debug("model_x06ax: energy policy set to %u\n", policy); +} + +static void configure_mca(void) +{ + msr_t msr; + int i; + + msr.lo = 0; + msr.hi = 0; + /* This should only be done on a cold boot */ + for (i = 0; i < 7; i++) + msr_write(IA32_MC0_STATUS + (i * 4), msr); +} + +#if CONFIG_USBDEBUG +static unsigned ehci_debug_addr; +#endif + +/* + * Initialize any extra cores/threads in this package. + */ +static int intel_cores_init(struct x86_cpu_priv *cpu) +{ + struct cpuid_result result; + unsigned threads_per_package, threads_per_core, i; + + /* Logical processors (threads) per core */ + result = cpuid_ext(0xb, 0); + threads_per_core = result.ebx & 0xffff; + + /* Logical processors (threads) per package */ + result = cpuid_ext(0xb, 1); + threads_per_package = result.ebx & 0xffff; + + debug("CPU: %u has %u cores, %u threads per core\n", + cpu->apic_id, threads_per_package / threads_per_core, + threads_per_core); + + for (i = 1; i < threads_per_package; ++i) { + struct x86_cpu_priv *new_cpu; + + new_cpu = calloc(1, sizeof(*new_cpu)); + if (!new_cpu) + return -ENOMEM; + + new_cpu->apic_id = cpu->apic_id + i; + + /* Update APIC ID if no hyperthreading */ + if (threads_per_core == 1) + new_cpu->apic_id <<= 1; + + debug("CPU: %u has core %u\n", cpu->apic_id, new_cpu->apic_id); + +#if CONFIG_SMP && CONFIG_MAX_CPUS > 1 + /* Start the new cpu */ + if (!start_cpu(new_cpu)) { + /* Record the error in cpu? */ + printk(BIOS_ERR, "CPU %u would not start!\n", + new_cpu->apic_id); + new_cpu->start_err = 1; + } +#endif + } + + return 0; +} + +int model_206ax_init(struct x86_cpu_priv *cpu) +{ + int ret; + + /* Clear out pending MCEs */ + configure_mca(); + +#if CONFIG_USBDEBUG + /* Is this caution really needed? */ + if (!ehci_debug_addr) + ehci_debug_addr = get_ehci_debug(); + set_ehci_debug(0); +#endif + + /* Setup MTRRs based on physical address size */ +#if 0 /* TODO: Implement this */ + struct cpuid_result cpuid_regs; + + cpuid_regs = cpuid(0x80000008); + x86_setup_fixed_mtrrs(); + x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2); + x86_mtrr_check(); +#endif + +#if CONFIG_USBDEBUG + set_ehci_debug(ehci_debug_addr); +#endif + + /* Enable the local cpu apics */ + enable_lapic_tpr(); + lapic_setup(); + + /* Enable virtualization if enabled in CMOS */ + enable_vmx(); + + /* Configure C States */ + configure_c_states(); + + /* Configure Enhanced SpeedStep and Thermal Sensors */ + configure_misc(); + + /* Thermal throttle activation offset */ + ret = configure_thermal_target(); + if (ret) + return ret; + + /* Enable Direct Cache Access */ + configure_dca_cap(); + + /* Set energy policy */ + set_energy_perf_bias(ENERGY_POLICY_NORMAL); + + /* Set Max Ratio */ + set_max_ratio(); + + /* Enable Turbo */ + turbo_enable(); + + /* Start up extra cores */ + intel_cores_init(cpu); + + return 0; +} diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h index 6454dd9..96d51c2 100644 --- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h +++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h @@ -15,4 +15,7 @@ void bd82x6x_usb_xhci_init(pci_dev_t dev); int bd82x6x_init_pci_devices(void); int bd82x6x_init(void);
+struct x86_cpu_priv; +int model_206ax_init(struct x86_cpu_priv *cpu); + #endif diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 6027d59..2cbb270 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -326,6 +326,8 @@ #define MSR_AMD_PERF_STATUS 0xc0010063 #define MSR_AMD_PERF_CTL 0xc0010062
+#define MSR_PMG_CST_CONFIG_CTL 0x000000e2 +#define MSR_PMG_IO_CAPTURE_ADR 0x000000e4 #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8
diff --git a/include/fdtdec.h b/include/fdtdec.h index 0a0afce..b6e1d40 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -121,6 +121,7 @@ enum fdt_compat_id { COMPAT_INTEL_MICROCODE, /* Intel microcode update */ COMPAT_MEMORY_SPD, /* Memory SPD information */ COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */ + COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */
COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 480442f..723a957 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -76,6 +76,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(MEMORY_SPD, "memory-spd"), COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"), + COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"), };
const char *fdtdec_get_compatible(enum fdt_compat_id id)

On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
Add the setup code for the CPU so that it can be used at full speed.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/bd82x6x.c | 6 + arch/x86/cpu/ivybridge/model_206ax.c | 514 ++++++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 3 + arch/x86/include/asm/msr-index.h | 2 + include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 528 insertions(+) create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c
Applied to u-boot-x86.

These are not available in U-Boot as yet, so drop them.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/include/asm/msr.h | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index df43983..1955a75 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -229,17 +229,6 @@ do { \ struct msr *msrs_alloc(void); void msrs_free(struct msr *msrs);
-#ifdef CONFIG_SMP -int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); -int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); -void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); -void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); -int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); -int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); -int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); -int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); - -#endif /* CONFIG_SMP */ #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_MSR_H */

On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
These are not available in U-Boot as yet, so drop them.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/include/asm/msr.h | 11 ----------- 1 file changed, 11 deletions(-)
Applied to u-boot-x86.

Add init for the northbridge, another part of the platform controller hub.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/bd82x6x.c | 2 + arch/x86/cpu/ivybridge/northbridge.c | 188 ++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/model_206ax.h | 4 + arch/x86/include/asm/arch-ivybridge/sandybridge.h | 13 +- 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/ivybridge/northbridge.c
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 95491b5..1296a78 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -13,6 +13,7 @@ obj-y += lpc.o obj-y += me_status.o obj-y += model_206ax.o obj-y += microcode_intel.o +obj-y += northbridge.o obj-y += pch.o obj-y += pci.o obj-y += report_platform.o diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 1a3c036..739f979 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -128,6 +128,8 @@ int bd82x6x_init(void)
bd82x6x_pci_init(PCH_DEV); bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node); + northbridge_enable(PCH_DEV); + northbridge_init(PCH_DEV);
return 0; } diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c new file mode 100644 index 0000000..c50b5de --- /dev/null +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -0,0 +1,188 @@ +/* + * From Coreboot northbridge/intel/sandybridge/northbridge.c + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium Authors + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <asm/msr.h> +#include <asm/acpi.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/arch/pch.h> +#include <asm/arch/model_206ax.h> +#include <asm/arch/sandybridge.h> + +static int bridge_revision_id = -1; + +int bridge_silicon_revision(void) +{ + if (bridge_revision_id < 0) { + struct cpuid_result result; + uint8_t stepping, bridge_id; + pci_dev_t dev; + + result = cpuid(1); + stepping = result.eax & 0xf; + dev = PCI_BDF(0, 0, 0); + bridge_id = pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0; + bridge_revision_id = bridge_id | stepping; + } + + return bridge_revision_id; +} + +/* + * Reserve everything between A segment and 1MB: + * + * 0xa0000 - 0xbffff: legacy VGA + * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel) + * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI + */ +static const int legacy_hole_base_k = 0xa0000 / 1024; +static const int legacy_hole_size_k = 384; + +static int get_pcie_bar(u32 *base, u32 *len) +{ + pci_dev_t dev = PCI_BDF(0, 0, 0); + u32 pciexbar_reg; + + *base = 0; + *len = 0; + + pciexbar_reg = pci_read_config32(dev, PCIEXBAR); + + if (!(pciexbar_reg & (1 << 0))) + return 0; + + switch ((pciexbar_reg >> 1) & 3) { + case 0: /* 256MB */ + *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) | + (1 << 28)); + *len = 256 * 1024 * 1024; + return 1; + case 1: /* 128M */ + *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) | + (1 << 28) | (1 << 27)); + *len = 128 * 1024 * 1024; + return 1; + case 2: /* 64M */ + *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) | + (1 << 28) | (1 << 27) | (1 << 26)); + *len = 64 * 1024 * 1024; + return 1; + } + + return 0; +} + +static void add_fixed_resources(pci_dev_t dev, int index) +{ + u32 pcie_config_base, pcie_config_size; + + if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) { + debug("Adding PCIe config bar base=0x%08x size=0x%x\n", + pcie_config_base, pcie_config_size); + } +} + +static void northbridge_dmi_init(pci_dev_t dev) +{ + /* Clear error status bits */ + writel(0xffffffff, DMIBAR_REG(0x1c4)); + writel(0xffffffff, DMIBAR_REG(0x1d0)); + + /* Steps prior to DMI ASPM */ + if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { + clrsetbits_le32(DMIBAR_REG(0x250), (1 << 22) | (1 << 20), + 1 << 21); + } + + setbits_le32(DMIBAR_REG(0x238), 1 << 29); + + if (bridge_silicon_revision() >= SNB_STEP_D0) { + setbits_le32(DMIBAR_REG(0x1f8), 1 << 16); + } else if (bridge_silicon_revision() >= SNB_STEP_D1) { + clrsetbits_le32(DMIBAR_REG(0x1f8), 1 << 26, 1 << 16); + setbits_le32(DMIBAR_REG(0x1fc), (1 << 12) | (1 << 23)); + } + + /* Enable ASPM on SNB link, should happen before PCH link */ + if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) + setbits_le32(DMIBAR_REG(0xd04), 1 << 4); + + setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0)); +} + +void northbridge_init(pci_dev_t dev) +{ + u32 bridge_type; + + add_fixed_resources(dev, 6); + northbridge_dmi_init(dev); + + bridge_type = readl(MCHBAR_REG(0x5f10)); + bridge_type &= ~0xff; + + if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { + /* Enable Power Aware Interrupt Routing - fixed priority */ + clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4); + + /* 30h for IvyBridge */ + bridge_type |= 0x30; + } else { + /* 20h for Sandybridge */ + bridge_type |= 0x20; + } + writel(bridge_type, MCHBAR_REG(0x5f10)); + + /* + * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU + * that BIOS has initialized memory and power management + */ + setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 1); + debug("Set BIOS_RESET_CPL\n"); + + /* Configure turbo power limits 1ms after reset complete bit */ + mdelay(1); + set_power_limits(28); + + /* + * CPUs with configurable TDP also need power limits set + * in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT. + */ + if (cpu_config_tdp_levels()) { + msr_t msr = msr_read(MSR_PKG_POWER_LIMIT); + + writel(msr.lo, MCHBAR_REG(0x59A0)); + writel(msr.hi, MCHBAR_REG(0x59A4)); + } + + /* Set here before graphics PM init */ + writel(0x00100001, MCHBAR_REG(0x5500)); +} + +void northbridge_enable(pci_dev_t dev) +{ +#if CONFIG_HAVE_ACPI_RESUME + switch (pci_read_config32(dev, SKPAD)) { + case 0xcafebabe: + debug("Normal boot.\n"); + apci_set_slp_type(0); + break; + case 0xcafed00d: + debug("S3 Resume.\n"); + apci_set_slp_type(3); + break; + default: + debug("Unknown boot method, assuming normal.\n"); + apci_set_slp_type(0); + break; + } +#endif +} diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h index 8281d7a..7b4f2e7 100644 --- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h +++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h @@ -79,4 +79,8 @@ #define PSS_LATENCY_TRANSITION 10 #define PSS_LATENCY_BUSMASTER 10
+/* Configure power limits for turbo mode */ +void set_power_limits(u8 power_limit_1_time); +int cpu_config_tdp_levels(void); + #endif diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h index 114ee19..cf7457f 100644 --- a/arch/x86/include/asm/arch-ivybridge/sandybridge.h +++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h @@ -97,11 +97,22 @@ /* * MCHBAR */ -#define MCHBAR_REG(reg) (DEFAULT_RCBA + (reg)) +#define MCHBAR_REG(reg) (DEFAULT_MCHBAR + (reg))
#define SSKPD 0x5d14 /* 16bit (scratchpad) */ #define BIOS_RESET_CPL 0x5da8 /* 8bit */
+/* + * DMIBAR + */ + +#define DMIBAR_REG(x) (DEFAULT_DMIBAR + x) + +int bridge_silicon_revision(void); + +void northbridge_enable(pci_dev_t dev); +void northbridge_init(pci_dev_t dev); + void report_platform_info(void);
void sandybridge_early_init(int chipset_type);

On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
Add init for the northbridge, another part of the platform controller hub.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/bd82x6x.c | 2 + arch/x86/cpu/ivybridge/northbridge.c | 188 ++++++++++++++++++++++ arch/x86/include/asm/arch-ivybridge/model_206ax.h | 4 + arch/x86/include/asm/arch-ivybridge/sandybridge.h | 13 +- 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/ivybridge/northbridge.c
Applied to u-boot-x86.

Enable SPI so that the SPI flash can be used.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
include/configs/chromebook_link.h | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 86429cf..6b57b28 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -46,10 +46,6 @@ */ #undef CONFIG_VIDEO #undef CONFIG_CFB_CONSOLE -#undef CONFIG_ICH_SPI -#undef CONFIG_SPI -#undef CONFIG_CMD_SPI -#undef CONFIG_CMD_SF
#define CONFIG_PCI_MEM_BUS 0xe0000000 #define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS

On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
Enable SPI so that the SPI flash can be used.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
include/configs/chromebook_link.h | 4 ---- 1 file changed, 4 deletions(-)
Applied to u-boot-x86.

It is now required to add subdirectories in the x86 cpu Makefile. Add this to fix a build breakage for chromebook_link.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch to add ivybridge directory to Makefile
Changes in v2: None
arch/x86/cpu/Makefile | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 4d3c5ea..7f09db5 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -13,6 +13,8 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ +obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o

Hi Simon,
Can you apply this as a single patch ASAP to fix the build error, please?
Masahiro
On Mon, 24 Nov 2014 21:18:20 -0700 Simon Glass sjg@chromium.org wrote:
It is now required to add subdirectories in the x86 cpu Makefile. Add this to fix a build breakage for chromebook_link.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to add ivybridge directory to Makefile
Changes in v2: None
arch/x86/cpu/Makefile | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 4d3c5ea..7f09db5 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -13,6 +13,8 @@ obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o
obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ +obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ obj-y += lapic.o obj-$(CONFIG_PCI) += pci.o obj-y += turbo.o -- 2.1.0.rc2.206.gedb03e5
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

+Tom
On 25 November 2014 at 00:04, Masahiro Yamada yamada.m@jp.panasonic.com wrote:
Hi Simon,
Can you apply this as a single patch ASAP to fix the build error, please?
Masahiro
It's a new board and the support is so far incomplete anyway, so it's not unexpected that some pull requests might collide.
Since I'm bringing in the remaining patches to finish off this port (display, keyboard, USB, SATA, EC all work!), I will just include this patch there. It's a lot of patches so Tom please feel free to pick just this one if you like.
I'll send an x86 pull request as soon as I've completed final testing (the last one for this release).
Applied to u-boot-x86.

This new symbol may be defined by the compiler. If it is, avoid a compiler warning when USE_STDINT is defined.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch to fix SIZE_MAX compiler warning when using stdint.h
Changes in v2: None
include/linux/kernel.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 89fcae0..0b61671 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -16,7 +16,9 @@ #define LLONG_MAX ((long long)(~0ULL>>1)) #define LLONG_MIN (-LLONG_MAX - 1) #define ULLONG_MAX (~0ULL) +#ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) +#endif
#define U8_MAX ((u8)~0U) #define S8_MAX ((s8)(U8_MAX>>1))

+Masahiro
On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
This new symbol may be defined by the compiler. If it is, avoid a compiler warning when USE_STDINT is defined.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to fix SIZE_MAX compiler warning when using stdint.h
Changes in v2: None
include/linux/kernel.h | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-x86.

Simon,
I am not happy about this because my intention was to sync <linux/kernel.h> with that of Linux as much as possible.
I have posted a new thread for open discussion because I doubt if USE_STDINT is a good idea.
On Tue, 25 Nov 2014 14:47:22 -0700 Simon Glass sjg@chromium.org wrote:
+Masahiro
On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
This new symbol may be defined by the compiler. If it is, avoid a compiler warning when USE_STDINT is defined.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to fix SIZE_MAX compiler warning when using stdint.h
Changes in v2: None
include/linux/kernel.h | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-x86.
Best Regards Masahiro Yamada

Hi Masahiro,
On 26 November 2014 at 00:49, Masahiro Yamada yamada.m@jp.panasonic.com wrote:
Simon,
I am not happy about this because my intention was to sync <linux/kernel.h> with that of Linux as much as possible.
I have posted a new thread for open discussion because I doubt if USE_STDINT is a good idea.
OK, let's discuss on the other thread.
- Simon
On Tue, 25 Nov 2014 14:47:22 -0700 Simon Glass sjg@chromium.org wrote:
+Masahiro
On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
This new symbol may be defined by the compiler. If it is, avoid a compiler warning when USE_STDINT is defined.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to fix SIZE_MAX compiler warning when using stdint.h
Changes in v2: None
include/linux/kernel.h | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-x86.
Best Regards Masahiro Yamada

Hi,
On 24 November 2014 at 21:18, Simon Glass sjg@chromium.org wrote:
This series adds full support for the LPC (Low Pin Count) bridge, the PCH (Platform Controller Hub), PCI devices like USB and SATA and more CPU init support (turbo mode, etc.)
With this series, chromebook_link can use SATA and USB at the command line.
Changes in v3:
- Add new patch to add ivybridge directory to Makefile
- Add new patch to fix SIZE_MAX compiler warning when using stdint.h
- Split out CONFIG_INTEL_CORE_ARCH removal patch
- Use exitsing disable_lapic() code instead of duplicating it
I forgot to mention that this series is rebased on u-boot-x86/master so I have dropped the already-applied patches.
Changes in v2:
- Remove use of __PRE_RAM__ define
- Use existing lapic_setup() code instead of duplicating it
Simon Glass (8): x86: Drop old CONFIG_INTEL_CORE_ARCH code x86: Add LAPIC setup code x86: Add init for model 206AX CPU x86: Drop some msr functions that we don't support x86: ivybridge: Add northbridge init functions x86: config: Enable SPI for chromebook_link x86: Add ivybridge directory to Makefile Fix SIZE_MAX compiler warning when using stdint.h
arch/x86/cpu/Makefile | 3 + arch/x86/cpu/interrupts.c | 28 -- arch/x86/cpu/ivybridge/Makefile | 2 + arch/x86/cpu/ivybridge/bd82x6x.c | 8 + arch/x86/cpu/ivybridge/model_206ax.c | 514 ++++++++++++++++++++++ arch/x86/cpu/ivybridge/northbridge.c | 188 ++++++++ arch/x86/cpu/lapic.c | 57 +++ arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 3 + arch/x86/include/asm/arch-ivybridge/model_206ax.h | 4 + arch/x86/include/asm/arch-ivybridge/sandybridge.h | 13 +- arch/x86/include/asm/lapic.h | 124 +++++- arch/x86/include/asm/msr-index.h | 2 + arch/x86/include/asm/msr.h | 11 - arch/x86/include/asm/post.h | 1 + include/configs/chromebook_link.h | 4 - include/fdtdec.h | 1 + include/linux/kernel.h | 2 + lib/fdtdec.c | 1 + 18 files changed, 920 insertions(+), 46 deletions(-) create mode 100644 arch/x86/cpu/ivybridge/model_206ax.c create mode 100644 arch/x86/cpu/ivybridge/northbridge.c create mode 100644 arch/x86/cpu/lapic.c
-- 2.1.0.rc2.206.gedb03e5
Regards, Simon
participants (3)
-
Bin Meng
-
Masahiro Yamada
-
Simon Glass