diff mbox series

[02/32] x86: apl: Add core init for the SoC

Message ID 20200928042611.1696178-2-sjg@chromium.org
State New
Delegated to: Bin Meng
Headers show
Series x86: Allow Coral to boot into Chrome OS | expand

Commit Message

Simon Glass Sept. 28, 2020, 4:25 a.m. UTC
Set up MSRs required for Apollo Lake. This enables Linux to use the
timers correctly. Also write the fixed MSRs for this platform.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/apollolake/cpu.c              | 84 ++++++++++++++++++++++
 arch/x86/cpu/apollolake/cpu_common.c       | 25 +++++++
 arch/x86/cpu/apollolake/cpu_spl.c          | 20 ------
 arch/x86/cpu/intel_common/cpu.c            | 19 +++++
 arch/x86/include/asm/arch-apollolake/cpu.h |  7 ++
 arch/x86/include/asm/cpu_common.h          |  2 +
 arch/x86/include/asm/msr-index.h           | 20 +++++-
 7 files changed, 156 insertions(+), 21 deletions(-)

Comments

Bin Meng Oct. 16, 2020, 9:55 a.m. UTC | #1
Hi Simon,

On Mon, Sep 28, 2020 at 12:26 PM Simon Glass <sjg@chromium.org> wrote:
>
> Set up MSRs required for Apollo Lake. This enables Linux to use the
> timers correctly. Also write the fixed MSRs for this platform.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/cpu/apollolake/cpu.c              | 84 ++++++++++++++++++++++
>  arch/x86/cpu/apollolake/cpu_common.c       | 25 +++++++
>  arch/x86/cpu/apollolake/cpu_spl.c          | 20 ------
>  arch/x86/cpu/intel_common/cpu.c            | 19 +++++
>  arch/x86/include/asm/arch-apollolake/cpu.h |  7 ++
>  arch/x86/include/asm/cpu_common.h          |  2 +
>  arch/x86/include/asm/msr-index.h           | 20 +++++-
>  7 files changed, 156 insertions(+), 21 deletions(-)
>
> diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
> index 8da2e64e226..e39b4cfba3c 100644
> --- a/arch/x86/cpu/apollolake/cpu.c
> +++ b/arch/x86/cpu/apollolake/cpu.c
> @@ -13,6 +13,9 @@
>  #include <asm/cpu_x86.h>
>  #include <asm/intel_acpi.h>
>  #include <asm/msr.h>
> +#include <asm/mtrr.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/iomap.h>
>  #include <dm/acpi.h>
>
>  #define CSTATE_RES(address_space, width, offset, address)              \
> @@ -86,6 +89,86 @@ static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
>         return 0;
>  }
>
> +static void update_fixed_mtrss(void)

I think the name should be _mtrrs, not mtrss

> +{
> +       native_write_msr(MTRR_FIX_64K_00000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +       native_write_msr(MTRR_FIX_16K_80000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +       native_write_msr(MTRR_FIX_4K_E0000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +       native_write_msr(MTRR_FIX_4K_E8000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +       native_write_msr(MTRR_FIX_4K_F0000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +       native_write_msr(MTRR_FIX_4K_F8000_MSR,
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
> +                        MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
> +}
> +
> +static void setup_core_msrs(void)
> +{
> +       wrmsrl(MSR_PMG_CST_CONFIG_CONTROL,
> +              PKG_C_STATE_LIMIT_C2_MASK | CORE_C_STATE_LIMIT_C10_MASK |
> +              IO_MWAIT_REDIRECT_MASK | CST_CFG_LOCK_MASK);
> +       /* Power Management I/O base address for I/O trapping to C-states */
> +       wrmsrl(MSR_PMG_IO_CAPTURE_ADR, ACPI_PMIO_CST_REG |
> +              (PMG_IO_BASE_CST_RNG_BLK_SIZE << 16));
> +       /* Disable C1E */
> +       msr_clrsetbits_64(MSR_POWER_CTL, 0x2, 0);
> +       /* Disable support for MONITOR and MWAIT instructions */
> +       msr_clrsetbits_64(MSR_IA32_MISC_ENABLE, MISC_ENABLE_MWAIT, 0);
> +       /*
> +        * Enable and Lock the Advanced Encryption Standard (AES-NI)
> +        * feature register
> +        */
> +       msr_clrsetbits_64(MSR_FEATURE_CONFIG, FEATURE_CONFIG_RESERVED_MASK,
> +                         FEATURE_CONFIG_LOCK);
> +
> +       update_fixed_mtrss();
> +}
> +
> +static int soc_core_init(void)
> +{
> +       struct udevice *pmc;
> +       int ret;
> +
> +       /* Clear out pending MCEs */
> +       cpu_mca_configure();
> +
> +       /* Set core MSRs */
> +       setup_core_msrs();
> +       /*
> +        * Enable ACPI PM timer emulation, which also lets microcode know
> +        * location of ACPI_BASE_ADDRESS. This also enables other features
> +        * implemented in microcode.
> +        */
> +       ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc);
> +       if (ret)
> +               return log_msg_ret("PMC", ret);
> +       enable_pm_timer_emulation(pmc);
> +
> +       return 0;
> +}
> +
> +static int cpu_apl_probe(struct udevice *dev)
> +{
> +       if (gd->flags & GD_FLG_RELOC) {
> +               int ret;
> +
> +               ret = soc_core_init();
> +               if (ret)
> +                       return log_ret(ret);
> +       }
> +
> +       return 0;
> +}
> +
>  struct acpi_ops apl_cpu_acpi_ops = {
>         .fill_ssdt      = acpi_cpu_fill_ssdt,
>  };
> @@ -107,6 +190,7 @@ U_BOOT_DRIVER(cpu_x86_apl_drv) = {
>         .id             = UCLASS_CPU,
>         .of_match       = cpu_x86_apl_ids,
>         .bind           = cpu_x86_bind,
> +       .probe          = cpu_apl_probe,
>         .ops            = &cpu_x86_apl_ops,
>         ACPI_OPS_PTR(&apl_cpu_acpi_ops)
>         .flags          = DM_FLAG_PRE_RELOC,
> diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c
> index ba6bda37bc5..63f6999b024 100644
> --- a/arch/x86/cpu/apollolake/cpu_common.c
> +++ b/arch/x86/cpu/apollolake/cpu_common.c
> @@ -4,8 +4,13 @@
>   */
>
>  #include <common.h>
> +#include <dm.h>
> +#include <log.h>
>  #include <asm/cpu_common.h>
>  #include <asm/msr.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/iomap.h>
> +#include <power/acpi_pmc.h>
>
>  void cpu_flush_l1d_to_l2(void)
>  {
> @@ -15,3 +20,23 @@ void cpu_flush_l1d_to_l2(void)
>         msr.lo |= FLUSH_DL1_L2;
>         msr_write(MSR_POWER_MISC, msr);
>  }
> +
> +void enable_pm_timer_emulation(const struct udevice *pmc)
> +{
> +       struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
> +       msr_t msr;
> +
> +       /*
> +        * The derived frequency is calculated as follows:
> +        *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
> +        *
> +        * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
> +        * used.
> +        */
> +       msr.hi = (3579545ULL << 32) / CTC_FREQ;
> +
> +       /* Set PM1 timer IO port and enable */
> +       msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
> +       debug("PM timer %x %x\n", msr.hi, msr.lo);
> +       msr_write(MSR_EMULATE_PM_TIMER, msr);
> +}
> diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
> index 9f32f2e27e1..fafe4dbc0a0 100644
> --- a/arch/x86/cpu/apollolake/cpu_spl.c
> +++ b/arch/x86/cpu/apollolake/cpu_spl.c
> @@ -114,26 +114,6 @@ static int fast_spi_cache_bios_region(void)
>         return 0;
>  }
>
> -static void enable_pm_timer_emulation(struct udevice *pmc)
> -{
> -       struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
> -       msr_t msr;
> -
> -       /*
> -        * The derived frequency is calculated as follows:
> -        *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
> -        *
> -        * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
> -        * used.
> -        */
> -       msr.hi = (3579545ULL << 32) / CTC_FREQ;
> -
> -       /* Set PM1 timer IO port and enable */
> -       msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
> -       debug("PM timer %x %x\n", msr.hi, msr.lo);
> -       msr_write(MSR_EMULATE_PM_TIMER, msr);
> -}
> -
>  static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep)
>  {
>         uint base;
> diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
> index 39aa0f63c65..c756fe08906 100644
> --- a/arch/x86/cpu/intel_common/cpu.c
> +++ b/arch/x86/cpu/intel_common/cpu.c
> @@ -306,3 +306,22 @@ int cpu_get_cores_per_package(void)
>
>         return cores;
>  }
> +
> +void cpu_mca_configure(void)
> +{
> +       msr_t msr;
> +       int i;
> +       int num_banks;
> +
> +       msr = msr_read(MSR_IA32_MCG_CAP);
> +       num_banks = msr.lo & 0xff;
> +       msr.lo = 0;
> +       msr.hi = 0;
> +       for (i = 0; i < num_banks; i++) {
> +               /* Clear the machine check status */
> +               msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr);
> +               /* Initialize machine checks */
> +               msr_write(MSR_IA32_MC0_CTL + i * 4,
> +                         (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
> +       }
> +}
> diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h
> index 5e906c5e7d7..a692104cd1f 100644
> --- a/arch/x86/include/asm/arch-apollolake/cpu.h
> +++ b/arch/x86/include/asm/arch-apollolake/cpu.h
> @@ -15,6 +15,13 @@
>  #ifndef __ASSEMBLY__
>  /* Flush L1D to L2 */
>  void cpu_flush_l1d_to_l2(void);
> +
> +/**
> + * Enable emulation of the PM timer

Could we put more details on what this function does?

> + *
> + * @pmc: PMC device
> + */
> +void enable_pm_timer_emulation(const struct udevice *pmc);
>  #endif
>
>  #endif /* _ASM_ARCH_CPU_H */
> diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
> index 48f56c2aad9..66311de7fdc 100644
> --- a/arch/x86/include/asm/cpu_common.h
> +++ b/arch/x86/include/asm/cpu_common.h
> @@ -184,4 +184,6 @@ int cpu_get_max_turbo_ratio(void);
>   */
>  int cpu_get_cores_per_package(void);
>
> +void cpu_mca_configure(void);

Please add some comments on what this function does

> +
>  #endif
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 94e6b18e21c..c49b4225ac2 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -68,7 +68,18 @@
>  #define MSR_BSEL_CR_OVERCLOCK_CONTROL  0x000000cd
>  #define MSR_PLATFORM_INFO              0x000000ce
>  #define MSR_PMG_CST_CONFIG_CONTROL     0x000000e2
> -#define SINGLE_PCTL                    (1 << 11)
> +/* Set MSR_PMG_CST_CONFIG_CONTROL[3:0] for Package C-State limit */
> +#define   PKG_C_STATE_LIMIT_C2_MASK    BIT(1)
> +/* Set MSR_PMG_CST_CONFIG_CONTROL[7:4] for Core C-State limit*/
> +#define   CORE_C_STATE_LIMIT_C10_MASK  0x70
> +/* Set MSR_PMG_CST_CONFIG_CONTROL[10] to IO redirect to MWAIT */
> +#define   IO_MWAIT_REDIRECT_MASK       BIT(10)
> +/* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */
> +#define   CST_CFG_LOCK_MASK            BIT(15)
> +#define   SINGLE_PCTL                  BIT(11)
> +
> +/* ACPI PMIO Offset to C-state register */
> +#define ACPI_PMIO_CST_REG      (ACPI_BASE_ADDRESS + 0x14)
>
>  #define MSR_MTRRcap                    0x000000fe
>  #define MSR_IA32_BBL_CR_CTL            0x00000119
> @@ -83,6 +94,10 @@
>  #define  EMULATE_PM_TMR_EN             (1 << 16)
>  #define  EMULATE_DELAY_VALUE           0x13
>
> +#define MSR_FEATURE_CONFIG     0x13c
> +#define   FEATURE_CONFIG_RESERVED_MASK 0x3ULL
> +#define   FEATURE_CONFIG_LOCK  (1 << 0)
> +
>  #define MSR_IA32_SYSENTER_CS           0x00000174
>  #define MSR_IA32_SYSENTER_ESP          0x00000175
>  #define MSR_IA32_SYSENTER_EIP          0x00000176
> @@ -453,6 +468,9 @@
>  #define MSR_AMD_PERF_CTL               0xc0010062
>
>  #define MSR_PMG_CST_CONFIG_CTL         0x000000e2
> +/* CST Range (R/W) IO port block size */
> +#define PMG_IO_BASE_CST_RNG_BLK_SIZE   0x5
> +
>  #define MSR_PMG_IO_CAPTURE_ADR         0x000000e4
>  #define MSR_IA32_MPERF                 0x000000e7
>  #define MSR_IA32_APERF                 0x000000e8
> --

Regards,
Bin
diff mbox series

Patch

diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
index 8da2e64e226..e39b4cfba3c 100644
--- a/arch/x86/cpu/apollolake/cpu.c
+++ b/arch/x86/cpu/apollolake/cpu.c
@@ -13,6 +13,9 @@ 
 #include <asm/cpu_x86.h>
 #include <asm/intel_acpi.h>
 #include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/iomap.h>
 #include <dm/acpi.h>
 
 #define CSTATE_RES(address_space, width, offset, address)		\
@@ -86,6 +89,86 @@  static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
 	return 0;
 }
 
+static void update_fixed_mtrss(void)
+{
+	native_write_msr(MTRR_FIX_64K_00000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	native_write_msr(MTRR_FIX_16K_80000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	native_write_msr(MTRR_FIX_4K_E0000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	native_write_msr(MTRR_FIX_4K_E8000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	native_write_msr(MTRR_FIX_4K_F0000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	native_write_msr(MTRR_FIX_4K_F8000_MSR,
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+			 MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+}
+
+static void setup_core_msrs(void)
+{
+	wrmsrl(MSR_PMG_CST_CONFIG_CONTROL,
+	       PKG_C_STATE_LIMIT_C2_MASK | CORE_C_STATE_LIMIT_C10_MASK |
+	       IO_MWAIT_REDIRECT_MASK | CST_CFG_LOCK_MASK);
+	/* Power Management I/O base address for I/O trapping to C-states */
+	wrmsrl(MSR_PMG_IO_CAPTURE_ADR, ACPI_PMIO_CST_REG |
+	       (PMG_IO_BASE_CST_RNG_BLK_SIZE << 16));
+	/* Disable C1E */
+	msr_clrsetbits_64(MSR_POWER_CTL, 0x2, 0);
+	/* Disable support for MONITOR and MWAIT instructions */
+	msr_clrsetbits_64(MSR_IA32_MISC_ENABLE, MISC_ENABLE_MWAIT, 0);
+	/*
+	 * Enable and Lock the Advanced Encryption Standard (AES-NI)
+	 * feature register
+	 */
+	msr_clrsetbits_64(MSR_FEATURE_CONFIG, FEATURE_CONFIG_RESERVED_MASK,
+			  FEATURE_CONFIG_LOCK);
+
+	update_fixed_mtrss();
+}
+
+static int soc_core_init(void)
+{
+	struct udevice *pmc;
+	int ret;
+
+	/* Clear out pending MCEs */
+	cpu_mca_configure();
+
+	/* Set core MSRs */
+	setup_core_msrs();
+	/*
+	 * Enable ACPI PM timer emulation, which also lets microcode know
+	 * location of ACPI_BASE_ADDRESS. This also enables other features
+	 * implemented in microcode.
+	 */
+	ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc);
+	if (ret)
+		return log_msg_ret("PMC", ret);
+	enable_pm_timer_emulation(pmc);
+
+	return 0;
+}
+
+static int cpu_apl_probe(struct udevice *dev)
+{
+	if (gd->flags & GD_FLG_RELOC) {
+		int ret;
+
+		ret = soc_core_init();
+		if (ret)
+			return log_ret(ret);
+	}
+
+	return 0;
+}
+
 struct acpi_ops apl_cpu_acpi_ops = {
 	.fill_ssdt	= acpi_cpu_fill_ssdt,
 };
@@ -107,6 +190,7 @@  U_BOOT_DRIVER(cpu_x86_apl_drv) = {
 	.id		= UCLASS_CPU,
 	.of_match	= cpu_x86_apl_ids,
 	.bind		= cpu_x86_bind,
+	.probe		= cpu_apl_probe,
 	.ops		= &cpu_x86_apl_ops,
 	ACPI_OPS_PTR(&apl_cpu_acpi_ops)
 	.flags		= DM_FLAG_PRE_RELOC,
diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c
index ba6bda37bc5..63f6999b024 100644
--- a/arch/x86/cpu/apollolake/cpu_common.c
+++ b/arch/x86/cpu/apollolake/cpu_common.c
@@ -4,8 +4,13 @@ 
  */
 
 #include <common.h>
+#include <dm.h>
+#include <log.h>
 #include <asm/cpu_common.h>
 #include <asm/msr.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/iomap.h>
+#include <power/acpi_pmc.h>
 
 void cpu_flush_l1d_to_l2(void)
 {
@@ -15,3 +20,23 @@  void cpu_flush_l1d_to_l2(void)
 	msr.lo |= FLUSH_DL1_L2;
 	msr_write(MSR_POWER_MISC, msr);
 }
+
+void enable_pm_timer_emulation(const struct udevice *pmc)
+{
+	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
+	msr_t msr;
+
+	/*
+	 * The derived frequency is calculated as follows:
+	 *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
+	 *
+	 * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
+	 * used.
+	 */
+	msr.hi = (3579545ULL << 32) / CTC_FREQ;
+
+	/* Set PM1 timer IO port and enable */
+	msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
+	debug("PM timer %x %x\n", msr.hi, msr.lo);
+	msr_write(MSR_EMULATE_PM_TIMER, msr);
+}
diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c
index 9f32f2e27e1..fafe4dbc0a0 100644
--- a/arch/x86/cpu/apollolake/cpu_spl.c
+++ b/arch/x86/cpu/apollolake/cpu_spl.c
@@ -114,26 +114,6 @@  static int fast_spi_cache_bios_region(void)
 	return 0;
 }
 
-static void enable_pm_timer_emulation(struct udevice *pmc)
-{
-	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
-	msr_t msr;
-
-	/*
-	 * The derived frequency is calculated as follows:
-	 *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
-	 *
-	 * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
-	 * used.
-	 */
-	msr.hi = (3579545ULL << 32) / CTC_FREQ;
-
-	/* Set PM1 timer IO port and enable */
-	msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
-	debug("PM timer %x %x\n", msr.hi, msr.lo);
-	msr_write(MSR_EMULATE_PM_TIMER, msr);
-}
-
 static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep)
 {
 	uint base;
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 39aa0f63c65..c756fe08906 100644
--- a/arch/x86/cpu/intel_common/cpu.c
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -306,3 +306,22 @@  int cpu_get_cores_per_package(void)
 
 	return cores;
 }
+
+void cpu_mca_configure(void)
+{
+	msr_t msr;
+	int i;
+	int num_banks;
+
+	msr = msr_read(MSR_IA32_MCG_CAP);
+	num_banks = msr.lo & 0xff;
+	msr.lo = 0;
+	msr.hi = 0;
+	for (i = 0; i < num_banks; i++) {
+		/* Clear the machine check status */
+		msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr);
+		/* Initialize machine checks */
+		msr_write(MSR_IA32_MC0_CTL + i * 4,
+			  (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
+	}
+}
diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h
index 5e906c5e7d7..a692104cd1f 100644
--- a/arch/x86/include/asm/arch-apollolake/cpu.h
+++ b/arch/x86/include/asm/arch-apollolake/cpu.h
@@ -15,6 +15,13 @@ 
 #ifndef __ASSEMBLY__
 /* Flush L1D to L2 */
 void cpu_flush_l1d_to_l2(void);
+
+/**
+ * Enable emulation of the PM timer
+ *
+ * @pmc: PMC device
+ */
+void enable_pm_timer_emulation(const struct udevice *pmc);
 #endif
 
 #endif /* _ASM_ARCH_CPU_H */
diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
index 48f56c2aad9..66311de7fdc 100644
--- a/arch/x86/include/asm/cpu_common.h
+++ b/arch/x86/include/asm/cpu_common.h
@@ -184,4 +184,6 @@  int cpu_get_max_turbo_ratio(void);
  */
 int cpu_get_cores_per_package(void);
 
+void cpu_mca_configure(void);
+
 #endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 94e6b18e21c..c49b4225ac2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -68,7 +68,18 @@ 
 #define MSR_BSEL_CR_OVERCLOCK_CONTROL	0x000000cd
 #define MSR_PLATFORM_INFO		0x000000ce
 #define MSR_PMG_CST_CONFIG_CONTROL	0x000000e2
-#define SINGLE_PCTL			(1 << 11)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[3:0] for Package C-State limit */
+#define   PKG_C_STATE_LIMIT_C2_MASK	BIT(1)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[7:4] for Core C-State limit*/
+#define   CORE_C_STATE_LIMIT_C10_MASK	0x70
+/* Set MSR_PMG_CST_CONFIG_CONTROL[10] to IO redirect to MWAIT */
+#define   IO_MWAIT_REDIRECT_MASK	BIT(10)
+/* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */
+#define   CST_CFG_LOCK_MASK		BIT(15)
+#define   SINGLE_PCTL			BIT(11)
+
+/* ACPI PMIO Offset to C-state register */
+#define ACPI_PMIO_CST_REG	(ACPI_BASE_ADDRESS + 0x14)
 
 #define MSR_MTRRcap			0x000000fe
 #define MSR_IA32_BBL_CR_CTL		0x00000119
@@ -83,6 +94,10 @@ 
 #define  EMULATE_PM_TMR_EN		(1 << 16)
 #define  EMULATE_DELAY_VALUE		0x13
 
+#define MSR_FEATURE_CONFIG	0x13c
+#define   FEATURE_CONFIG_RESERVED_MASK	0x3ULL
+#define   FEATURE_CONFIG_LOCK	(1 << 0)
+
 #define MSR_IA32_SYSENTER_CS		0x00000174
 #define MSR_IA32_SYSENTER_ESP		0x00000175
 #define MSR_IA32_SYSENTER_EIP		0x00000176
@@ -453,6 +468,9 @@ 
 #define MSR_AMD_PERF_CTL		0xc0010062
 
 #define MSR_PMG_CST_CONFIG_CTL		0x000000e2
+/* CST Range (R/W) IO port block size */
+#define PMG_IO_BASE_CST_RNG_BLK_SIZE	0x5
+
 #define MSR_PMG_IO_CAPTURE_ADR		0x000000e4
 #define MSR_IA32_MPERF			0x000000e7
 #define MSR_IA32_APERF			0x000000e8