[coreboot-gerrit] Change in coreboot[master]: soc/intel/cannonlake: Add early CPU initialization

Andrey Petrov (Code Review) gerrit at coreboot.org
Wed Jun 7 03:03:33 CEST 2017


Andrey Petrov has uploaded this change for review. ( https://review.coreboot.org/20066


Change subject: soc/intel/cannonlake: Add early CPU initialization
......................................................................

soc/intel/cannonlake: Add early CPU initialization

Add basic CPU initialization for bootblock, as well as relevant headers.

Change-Id: I318b7ea0f3aa5b5d28bf70784ccd20f2fe28cd86
Signed-off-by: Andrey Petrov <andrey.petrov at intel.com>
---
A src/soc/intel/cannonlake/bootblock/cpu.c
A src/soc/intel/cannonlake/include/soc/cpu.h
A src/soc/intel/cannonlake/include/soc/msr.h
3 files changed, 280 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/20066/1

diff --git a/src/soc/intel/cannonlake/bootblock/cpu.c b/src/soc/intel/cannonlake/bootblock/cpu.c
new file mode 100644
index 0000000..844d9a7
--- /dev/null
+++ b/src/soc/intel/cannonlake/bootblock/cpu.c
@@ -0,0 +1,156 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/intel/microcode/microcode.c>
+#include <cpu/x86/mtrr.h>
+#include <delay.h>
+#include <lib.h>
+#include <reset.h>
+#include <soc/bootblock.h>
+#include <soc/cpu.h>
+#include <soc/iomap.h>
+#include <soc/msr.h>
+#include <soc/pmc.h>
+
+/* Soft Reset Data Register Bit 12 = MAX Boot Frequency */
+#define SPI_STRAP_MAX_FREQ	(1<<12)
+/* Soft Reset Data Register Bit 6-11 = Flex Ratio */
+#define FLEX_RATIO_BIT	6
+
+static void set_pch_cpu_strap(u8 flex_ratio)
+{
+	u32 soft_reset_data;
+	uint8_t *pwrmbase = (void *)PCH_PWRM_BASE_ADDRESS;
+	u32 ssl, ssms;
+
+	/* Set Strap Lock Disable */
+	ssl = read32(pwrmbase + SSML);
+	ssl |= SSML_SSL_DS;
+	write32(pwrmbase + SSML, ssl);
+
+	/* Soft Reset Data Register Bit 12 = MAX Boot Frequency
+	 * Bit 6-11 = Flex Ratio
+	 * Soft Reset Data register located at PWRMBASE offset 0x1054[0:15].
+	 */
+	soft_reset_data = SPI_STRAP_MAX_FREQ;
+	soft_reset_data |= (flex_ratio << FLEX_RATIO_BIT);
+	write32(pwrmbase + SSMD, soft_reset_data);
+
+	/* Set Strap Mux Select  set to '1' */
+	ssms = read32(pwrmbase + SSMC);
+	ssms |= SSMC_SSMS;
+	write32(pwrmbase + SSMC, ssms);
+
+	/* Set Strap Lock Enable */
+	ssl = read32(pwrmbase + SSML);
+	ssl |= SSML_SSL_EN;
+	write32(pwrmbase + SSML, ssl);
+}
+
+static void set_flex_ratio_to_tdp_nominal(void)
+{
+	msr_t flex_ratio, msr;
+	u8 nominal_ratio;
+
+	/* Check for Flex Ratio support */
+	flex_ratio = rdmsr(MSR_FLEX_RATIO);
+	if (!(flex_ratio.lo & FLEX_RATIO_EN))
+		return;
+
+	/* Check for >0 configurable TDPs */
+	msr = rdmsr(MSR_PLATFORM_INFO);
+	if (((msr.hi >> 1) & 3) == 0)
+		return;
+
+	/* Use nominal TDP ratio for flex ratio */
+	msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+	nominal_ratio = msr.lo & 0xff;
+
+	/* See if flex ratio is already set to nominal TDP ratio */
+	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
+		return;
+
+	/* Set flex ratio to nominal TDP ratio */
+	flex_ratio.lo &= ~0xff00;
+	flex_ratio.lo |= nominal_ratio << 8;
+	flex_ratio.lo |= FLEX_RATIO_LOCK;
+	wrmsr(MSR_FLEX_RATIO, flex_ratio);
+
+	/* Set PCH Soft Reset Data Register with new Flex Ratio */
+	set_pch_cpu_strap(nominal_ratio);
+
+	/* Delay before reset to avoid potential TPM lockout */
+	mdelay(30);
+
+	/* Issue soft reset, will be "CPU only" due to soft reset data */
+	soft_reset();
+}
+
+static void cache_bios_region(void)
+{
+	int mtrr;
+	size_t rom_size;
+	uint32_t alignment;
+
+	mtrr = get_free_var_mtrr();
+
+	if (mtrr == -1)
+		return;
+
+	rom_size = CONFIG_ROM_SIZE;
+
+	if (!rom_size)
+		return;
+
+	/* Round to power of two */
+	alignment = 1 << (log2_ceil(rom_size));
+	rom_size = ALIGN_UP(rom_size, alignment);
+	set_var_mtrr(mtrr, 4ULL*GiB - rom_size, rom_size, MTRR_TYPE_WRPROT);
+}
+
+void bootblock_cpu_init(void)
+{
+	cache_bios_region();
+	/* Set flex ratio and reset if needed */
+	set_flex_ratio_to_tdp_nominal();
+	intel_update_microcode_from_cbfs();
+}
+
+void set_max_freq(void)
+{
+	msr_t msr, perf_ctl, platform_info;
+
+	/* Check for configurable TDP option */
+	platform_info = rdmsr(MSR_PLATFORM_INFO);
+
+	if ((platform_info.hi >> 1) & 3) {
+		/* Set to nominal TDP ratio */
+		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
+		perf_ctl.lo = (msr.lo & 0xff) << 8;
+	} else {
+		/* Platform Info bits 15:8 give max ratio */
+		msr = rdmsr(MSR_PLATFORM_INFO);
+		perf_ctl.lo = msr.lo & 0xff00;
+	}
+
+	perf_ctl.hi = 0;
+	wrmsr(MSR_IA32_PERF_CTL, perf_ctl);
+
+	printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n",
+		((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK);
+}
diff --git a/src/soc/intel/cannonlake/include/soc/cpu.h b/src/soc/intel/cannonlake/include/soc/cpu.h
new file mode 100644
index 0000000..d97605b
--- /dev/null
+++ b/src/soc/intel/cannonlake/include/soc/cpu.h
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_CANNONLAKE_CPU_H_
+#define _SOC_CANNONLAKE_CPU_H_
+
+#include <arch/cpu.h>
+#include <device/device.h>
+
+/* CPU types */
+#define CANNONLAKE_FAMILY_ULT	0x60660
+
+/* Supported CPUIDs */
+#define CPUID_CANNONLAKE_A0	0x60660
+#define CPUID_CANNONLAKE_B0	0x60661
+#define CPUID_CANNONLAKE_C0	0x60662
+
+/* CPU bus clock is fixed at 100MHz */
+#define CPU_BCLK		100
+
+/* Latency times in units of 1024ns. */
+#define C_STATE_LATENCY_CONTROL_0_LIMIT	0x4e
+#define C_STATE_LATENCY_CONTROL_1_LIMIT	0x76
+#define C_STATE_LATENCY_CONTROL_2_LIMIT	0x94
+#define C_STATE_LATENCY_CONTROL_3_LIMIT	0xfa
+#define C_STATE_LATENCY_CONTROL_4_LIMIT	0x14c
+#define C_STATE_LATENCY_CONTROL_5_LIMIT	0x3f2
+
+/* Power in units of mW */
+#define C1_POWER	0x3e8
+#define C3_POWER	0x1f4
+#define C6_POWER	0x15e
+#define C7_POWER	0xc8
+#define C8_POWER	0xc8
+#define C9_POWER	0xc8
+#define C10_POWER	0xc8
+
+#define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \
+	(((1 << ((base)*5)) * (limit)) / 1000)
+#define C_STATE_LATENCY_FROM_LAT_REG(reg) \
+	C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \
+				      (IRTL_1024_NS >> 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/src/soc/intel/cannonlake/include/soc/msr.h b/src/soc/intel/cannonlake/include/soc/msr.h
new file mode 100644
index 0000000..25c13e2
--- /dev/null
+++ b/src/soc/intel/cannonlake/include/soc/msr.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SOC_MSR_H_
+#define _SOC_MSR_H_
+
+#include <intelblocks/msr.h>
+
+#define MSR_EMULATE_PM_TIMER           0x121
+#define  EMULATE_PM_TMR_EN             (1 << 16)
+#define  uCODE_TMR_EMULATION_19_MHZ    0x2FBA2E26
+#define  uCODE_TMR_EMULATION_24_MHZ    0x262E8B52
+#define  EMULATE_DELAY_OFFSET_VALUE            20
+#define  EMULATE_DELAY_VALUE           0x13
+#define MSR_PIC_MSG_CONTROL		0x2e
+#define MSR_BIOS_UPGD_TRIG		0x7a
+#define MSR_FLEX_RATIO			0x194
+#define  FLEX_RATIO_LOCK		(1 << 20)
+#define  FLEX_RATIO_EN			(1 << 16)
+#define IA32_THERM_INTERRUPT		0x19b
+#define IA32_ENERGY_PERFORMANCE_BIAS	0x1b0
+#define  ENERGY_POLICY_PERFORMANCE	0
+#define  ENERGY_POLICY_NORMAL		6
+#define  ENERGY_POLICY_POWERSAVE	15
+#define IA32_PACKAGE_THERM_INTERRUPT	0x1b2
+#define PRMRR_PHYS_BASE_MSR		0x1f4
+#define PRMRR_PHYS_MASK_MSR		0x1f5
+#define  PRMRR_PHYS_MASK_LOCK		(1 << 10)
+#define  PRMRR_PHYS_MASK_VALID		(1 << 11)
+#define IA32_PLATFORM_DCA_CAP		0x1f8
+#define MSR_LT_LOCK_MEMORY		0x2e7
+#define UNCORE_PRMRR_PHYS_BASE_MSR	0x2f4
+#define UNCORE_PRMRR_PHYS_MASK_MSR	0x2f5
+#define MSR_SGX_OWNEREPOCH0		0x300
+#define MSR_SGX_OWNEREPOCH1		0x301
+#define MSR_VR_CURRENT_CONFIG		0x601
+#define MSR_VR_MISC_CONFIG		0x603
+#define MSR_VR_MISC_CONFIG2		0x636
+#define MSR_PP0_POWER_LIMIT		0x638
+#define MSR_PP1_POWER_LIMIT		0x640
+
+/* SMM save state MSRs */
+#define SMBASE_MSR			0xc20
+#define IEDBASE_MSR			0xc22
+
+/* MTRR_CAP_MSR bits */
+#define SMRR_SUPPORTED (1<<11)
+#define PRMRR_SUPPORTED (1<<12)
+
+#endif

-- 
To view, visit https://review.coreboot.org/20066
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I318b7ea0f3aa5b5d28bf70784ccd20f2fe28cd86
Gerrit-Change-Number: 20066
Gerrit-PatchSet: 1
Gerrit-Owner: Andrey Petrov <andrey.petrov at intel.com>



More information about the coreboot-gerrit mailing list