[PATCH 02/32] x86: apl: Add core init for the SoC
Bin Meng
bmeng.cn at gmail.com
Fri Oct 16 11:55:24 CEST 2020
Hi Simon,
On Mon, Sep 28, 2020 at 12:26 PM Simon Glass <sjg at 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 at 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
More information about the U-Boot
mailing list