aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/icelake/bootblock
diff options
context:
space:
mode:
authorAamir Bohra <aamir.bohra@intel.com>2018-10-17 11:55:01 +0530
committerPatrick Georgi <pgeorgi@google.com>2018-10-26 11:20:54 +0000
commit3ee54bbf9413b5e174e65eff14769bdd2f5a3203 (patch)
tree1c27e4e0434d3e22e4fb9bb38ba59aa623070f80 /src/soc/intel/icelake/bootblock
parentbb7f4c7a4f3a076ba3e52fea9228e4a064316128 (diff)
soc/intel/icelake: Do initial SoC commit
Clone entirely from Cannonlake commit id: 3487095304dbbbf66de86f8bce0e40b7acb3ea27 List of changes on top off initial cannonlake clone 1. Replace "Cannonlake" with "Icelake" 2. Replace "cnl" with "icl" 3. Replace "cnp" with "icp" 4. Rename structrue based on Cannonlake with Icelake 5. Remove and clean below files 5.a. All NHLT blobs and related files. 5.b. remove cnl_memcfg_init.c file, will be added later. 5.c. Remove vr_config.c, this is WIP. 5.d. Clean up upd override in fsp_params.c, will be added once FSP available. 5.e Remove CNL-H based GPIO configuartion. Ice Lake specific changes will follow in subsequent patches. Change-Id: I756fa7275c4190aebc0695f14484498aaf5662a5 Signed-off-by: Subrata Banik <subrata.banik@intel.com> Signed-off-by: Aamir Bohra <aamir.bohra@intel.com> Reviewed-on: https://review.coreboot.org/29162 Reviewed-by: Shelley Chen <shchen@google.com> Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Reviewed-by: Naresh Solanki <naresh.solanki@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/intel/icelake/bootblock')
-rw-r--r--src/soc/intel/icelake/bootblock/bootblock.c43
-rw-r--r--src/soc/intel/icelake/bootblock/cpu.c26
-rw-r--r--src/soc/intel/icelake/bootblock/pch.c210
-rw-r--r--src/soc/intel/icelake/bootblock/report_platform.c212
4 files changed, 491 insertions, 0 deletions
diff --git a/src/soc/intel/icelake/bootblock/bootblock.c b/src/soc/intel/icelake/bootblock/bootblock.c
new file mode 100644
index 0000000000..40c2d41b7a
--- /dev/null
+++ b/src/soc/intel/icelake/bootblock/bootblock.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Intel Corp.
+ *
+ * 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 <bootblock_common.h>
+#include <intelblocks/gspi.h>
+#include <intelblocks/uart.h>
+#include <soc/bootblock.h>
+#include <soc/iomap.h>
+#include <soc/pch.h>
+
+asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
+{
+ /* Call lib/bootblock.c main */
+ bootblock_main_with_timestamp(base_timestamp, NULL, 0);
+}
+
+void bootblock_soc_early_init(void)
+{
+ bootblock_systemagent_early_init();
+ bootblock_pch_early_init();
+ bootblock_cpu_init();
+ pch_early_iorange_init();
+ if (IS_ENABLED(CONFIG_UART_DEBUG))
+ uart_bootblock_init();
+}
+
+void bootblock_soc_init(void)
+{
+ report_platform_info();
+ pch_early_init();
+}
diff --git a/src/soc/intel/icelake/bootblock/cpu.c b/src/soc/intel/icelake/bootblock/cpu.c
new file mode 100644
index 0000000000..f02b09027a
--- /dev/null
+++ b/src/soc/intel/icelake/bootblock/cpu.c
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Intel Corp.
+ *
+ * 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 <intelblocks/cpulib.h>
+#include <intelblocks/fast_spi.h>
+#include <soc/bootblock.h>
+
+void bootblock_cpu_init(void)
+{
+ /* Temporarily cache the memory-mapped boot media. */
+ if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED) &&
+ IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
+ fast_spi_cache_bios_region();
+}
diff --git a/src/soc/intel/icelake/bootblock/pch.c b/src/soc/intel/icelake/bootblock/pch.c
new file mode 100644
index 0000000000..269e2a3c2b
--- /dev/null
+++ b/src/soc/intel/icelake/bootblock/pch.c
@@ -0,0 +1,210 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Intel Corp.
+ *
+ * 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci_ids.h>
+#include <intelblocks/fast_spi.h>
+#include <intelblocks/gspi.h>
+#include <intelblocks/lpc_lib.h>
+#include <intelblocks/p2sb.h>
+#include <intelblocks/pcr.h>
+#include <intelblocks/pmclib.h>
+#include <intelblocks/rtc.h>
+#include <intelblocks/smbus.h>
+#include <soc/bootblock.h>
+#include <soc/iomap.h>
+#include <soc/lpc.h>
+#include <soc/p2sb.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <soc/pcr_ids.h>
+#include <soc/pm.h>
+#include <soc/smbus.h>
+
+#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP 0x1400
+#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H 0x0980
+
+#define PCR_PSFX_TO_SHDW_BAR0 0
+#define PCR_PSFX_TO_SHDW_BAR1 0x4
+#define PCR_PSFX_TO_SHDW_BAR2 0x8
+#define PCR_PSFX_TO_SHDW_BAR3 0xC
+#define PCR_PSFX_TO_SHDW_BAR4 0x10
+#define PCR_PSFX_TO_SHDW_PCIEN_IOEN 0x01
+#define PCR_PSFX_T0_SHDW_PCIEN 0x1C
+
+#define PCR_DMI_ACPIBA 0x27B4
+#define PCR_DMI_ACPIBDID 0x27B8
+#define PCR_DMI_PMBASEA 0x27AC
+#define PCR_DMI_PMBASEC 0x27B0
+#define PCR_DMI_TCOBASE 0x2778
+/* Enable TCO I/O range decode. */
+#define TCOEN (1 << 1)
+
+#define PCR_DMI_LPCIOD 0x2770
+#define PCR_DMI_LPCIOE 0x2774
+
+static uint32_t get_pmc_reg_base(void)
+{
+ uint8_t pch_series;
+
+ pch_series = get_pch_series();
+
+ if (pch_series == PCH_H)
+ return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H;
+ else if (pch_series == PCH_LP)
+ return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP;
+ else
+ return 0;
+}
+
+static void soc_config_pwrmbase(void)
+{
+ uint32_t reg32;
+
+ /*
+ * Assign Resources to PWRMBASE
+ * Clear BIT 1-2 Command Register
+ */
+ reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND);
+ reg32 &= ~(PCI_COMMAND_MEMORY);
+ pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32);
+
+ /* Program PWRM Base */
+ pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS);
+
+ /* Enable Bus Master and MMIO Space */
+ reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MEMORY;
+ pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32);
+
+ /* Enable PWRM in PMC */
+ reg32 = read32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL));
+ write32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL), reg32 | PWRM_EN);
+}
+
+void bootblock_pch_early_init(void)
+{
+ fast_spi_early_init(SPI_BASE_ADDRESS);
+ gspi_early_bar_init();
+ p2sb_enable_bar();
+ p2sb_configure_hpet();
+
+ /*
+ * Enabling PWRM Base for accessing
+ * Global Reset Cause Register.
+ */
+ soc_config_pwrmbase();
+}
+
+
+static void soc_config_acpibase(void)
+{
+ uint32_t pmc_reg_value;
+ uint32_t pmc_base_reg;
+
+ pmc_base_reg = get_pmc_reg_base();
+ if (!pmc_base_reg)
+ die("Invalid PMC base address\n");
+
+ pmc_reg_value = pcr_read32(PID_PSF3, pmc_base_reg +
+ PCR_PSFX_TO_SHDW_BAR4);
+
+ if (pmc_reg_value != 0xFFFFFFFF) {
+ /* Disable Io Space before changing the address */
+ pcr_rmw32(PID_PSF3, pmc_base_reg +
+ PCR_PSFX_T0_SHDW_PCIEN,
+ ~PCR_PSFX_TO_SHDW_PCIEN_IOEN, 0);
+ /* Program ABASE in PSF3 PMC space BAR4*/
+ pcr_write32(PID_PSF3, pmc_base_reg +
+ PCR_PSFX_TO_SHDW_BAR4,
+ ACPI_BASE_ADDRESS);
+ /* Enable IO Space */
+ pcr_rmw32(PID_PSF3, pmc_base_reg +
+ PCR_PSFX_T0_SHDW_PCIEN,
+ ~0, PCR_PSFX_TO_SHDW_PCIEN_IOEN);
+ }
+}
+
+static void soc_config_tco(void)
+{
+ uint32_t reg32;
+ uint16_t tcobase;
+ uint16_t tcocnt;
+
+ /* Disable TCO in SMBUS Device first before changing Base Address */
+ reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL);
+ reg32 &= ~TCO_BASE_EN;
+ pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32);
+
+ /* Program TCO Base */
+ tcobase = TCO_BASE_ADDRESS;
+ pci_write_config32(PCH_DEV_SMBUS, TCOBASE, tcobase);
+
+ /* Enable TCO in SMBUS */
+ pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | TCO_BASE_EN);
+
+ /*
+ * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1]
+ */
+ pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN);
+
+ /* Program TCO timer halt */
+ tcocnt = inw(tcobase + TCO1_CNT);
+ tcocnt |= TCO_TMR_HLT;
+ outw(tcocnt, tcobase + TCO1_CNT);
+}
+
+void pch_early_iorange_init(void)
+{
+ uint16_t dec_rng, dec_en = 0;
+
+ /* IO Decode Range */
+ if (IS_ENABLED(CONFIG_DRIVERS_UART_8250IO) &&
+ IS_ENABLED(CONFIG_UART_DEBUG)) {
+ dec_rng = COMA_RANGE | (COMB_RANGE << 4);
+ dec_en = COMA_LPC_EN | COMB_LPC_EN;
+ pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, dec_rng);
+ pcr_write16(PID_DMI, PCR_DMI_LPCIOD, dec_rng);
+ }
+
+ /* IO Decode Enable */
+ dec_en |= SE_LPC_EN | KBC_LPC_EN | MC1_LPC_EN | GAMEL_LPC_EN;
+ pci_write_config16(PCH_DEV_LPC, LPC_EN, dec_en);
+ pcr_write16(PID_DMI, PCR_DMI_LPCIOE, dec_en);
+
+ /* Program generic IO Decode Range */
+ pch_enable_lpc();
+}
+
+void pch_early_init(void)
+{
+ /*
+ * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT,
+ * GPE0_STS, GPE0_EN registers.
+ */
+ soc_config_acpibase();
+
+ /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */
+ soc_config_tco();
+
+ /* Program SMBUS_BASE_ADDRESS and Enable it */
+ smbus_common_init();
+
+ /* Set up GPE configuration */
+ pmc_gpe_init();
+
+ enable_rtc_upper_bank();
+}
diff --git a/src/soc/intel/icelake/bootblock/report_platform.c b/src/soc/intel/icelake/bootblock/report_platform.c
new file mode 100644
index 0000000000..9df6a1ef84
--- /dev/null
+++ b/src/soc/intel/icelake/bootblock/report_platform.c
@@ -0,0 +1,212 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2018 Intel Corp.
+ *
+ * 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/cpu.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <intelblocks/mp_init.h>
+#include <soc/bootblock.h>
+#include <soc/pch.h>
+#include <soc/pci_devs.h>
+#include <string.h>
+
+#define BIOS_SIGN_ID 0x8B
+
+static struct {
+ u32 cpuid;
+ const char *name;
+} cpu_table[] = {
+ { CPUID_CANNONLAKE_A0, "Cannonlake A0" },
+ { CPUID_CANNONLAKE_B0, "Cannonlake B0" },
+ { CPUID_CANNONLAKE_C0, "Cannonlake C0" },
+ { CPUID_CANNONLAKE_D0, "Cannonlake D0" },
+ { CPUID_COFFEELAKE_D0, "Coffeelake D0" },
+ { CPUID_WHISKEYLAKE_W0, "Whiskeylake W0"},
+ { CPUID_COFFEELAKE_U0, "Coffeelake U0 (6+2)" },
+};
+
+static struct {
+ u16 mchid;
+ const char *name;
+} mch_table[] = {
+ { PCI_DEVICE_ID_INTEL_CNL_ID_U, "Cannonlake-U" },
+ { PCI_DEVICE_ID_INTEL_CNL_ID_Y, "Cannonlake-Y" },
+ { PCI_DEVICE_ID_INTEL_CFL_ID_U, "Coffeelake U (4+3e)"},
+ { PCI_DEVICE_ID_INTEL_WHL_ID_Wx4, "Whiskeylake W (4+2)"},
+ { PCI_DEVICE_ID_INTEL_WHL_ID_Wx2, "Whiskeylake W (2+2)"},
+ { PCI_DEVICE_ID_INTEL_CFL_ID_H, "Coffeelake-H" },
+ { PCI_DEVICE_ID_INTEL_CFL_ID_S, "Coffeelake-S" },
+};
+
+static struct {
+ u16 lpcid;
+ const char *name;
+} pch_table[] = {
+ { PCI_DEVICE_ID_INTEL_CNL_BASE_U_LPC, "Cannonlake-U Base" },
+ { PCI_DEVICE_ID_INTEL_CNL_U_PREMIUM_LPC, "Cannonlake-U Premium" },
+ { PCI_DEVICE_ID_INTEL_CNL_Y_PREMIUM_LPC, "Cannonlake-Y Premium" },
+ { PCI_DEVICE_ID_INTEL_CNP_H_LPC_Q370, "Cannonlake-H Q370" },
+ { PCI_DEVICE_ID_INTEL_CNP_H_LPC_QM370, "Cannonlake-H QM370" },
+};
+
+static struct {
+ u16 igdid;
+ const char *name;
+} igd_table[] = {
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_1, "Cannonlake ULX GT2" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_2, "Cannonlake ULX GT1.5" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_3, "Cannonlake ULX GT1" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_4, "Cannonlake ULX GT0.5" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_1, "Cannonlake ULT GT2" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_2, "Cannonlake ULT GT1.5" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_3, "Cannonlake ULT GT1" },
+ { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_4, "Cannonlake ULT GT0.5" },
+ { PCI_DEVICE_ID_INTEL_CFL_GT2_ULT, "Coffeelake ULT GT2"},
+ { PCI_DEVICE_ID_INTEL_WHL_GT2_ULT_1, "Whiskeylake ULT GT1"},
+ { PCI_DEVICE_ID_INTEL_CFL_H_GT2, "Coffeelake-H GT2" },
+ { PCI_DEVICE_ID_INTEL_CFL_S_GT2, "Coffeelake-S GT2" },
+};
+
+static uint8_t get_dev_revision(pci_devfn_t dev)
+{
+ return pci_read_config8(dev, PCI_REVISION_ID);
+}
+
+static uint16_t get_dev_id(pci_devfn_t dev)
+{
+ return pci_read_config16(dev, PCI_DEVICE_ID);
+}
+
+static void report_cpu_info(void)
+{
+ struct cpuid_result cpuidr;
+ u32 i, index;
+ char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
+ int vt, txt, aes;
+ msr_t microcode_ver;
+ static const char *const mode[] = {"NOT ", ""};
+ const char *cpu_type = "Unknown";
+ u32 p[13];
+
+ index = 0x80000000;
+ cpuidr = cpuid(index);
+ if (cpuidr.eax < 0x80000004) {
+ strcpy(cpu_string, "Platform info not available");
+ } else {
+ int j = 0;
+
+ for (i = 2; i <= 4; i++) {
+ cpuidr = cpuid(index + i);
+ p[j++] = cpuidr.eax;
+ p[j++] = cpuidr.ebx;
+ p[j++] = cpuidr.ecx;
+ p[j++] = cpuidr.edx;
+ }
+ p[12] = 0;
+ cpu_name = (char *)p;
+ }
+ /* Skip leading spaces in CPU name string */
+ while (cpu_name[0] == ' ')
+ cpu_name++;
+
+ microcode_ver.lo = 0;
+ microcode_ver.hi = 0;
+ wrmsr(BIOS_SIGN_ID, microcode_ver);
+ cpuidr = cpuid(1);
+ microcode_ver = rdmsr(BIOS_SIGN_ID);
+
+ /* Look for string to match the name */
+ for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
+ if (cpu_table[i].cpuid == cpuidr.eax) {
+ cpu_type = cpu_table[i].name;
+ break;
+ }
+ }
+
+ printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
+ printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
+ cpuidr.eax, cpu_type, microcode_ver.hi);
+
+ aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
+ txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
+ vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
+ printk(BIOS_DEBUG,
+ "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
+ mode[aes], mode[txt], mode[vt]);
+}
+
+static void report_mch_info(void)
+{
+ int i;
+ pci_devfn_t dev = SA_DEV_ROOT;
+ uint16_t mchid = get_dev_id(dev);
+ uint8_t mch_revision = get_dev_revision(dev);
+ const char *mch_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
+ if (mch_table[i].mchid == mchid) {
+ mch_type = mch_table[i].name;
+ break;
+ }
+ }
+
+ printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
+ mchid, mch_revision, mch_type);
+}
+
+static void report_pch_info(void)
+{
+ int i;
+ pci_devfn_t dev = PCH_DEV_LPC;
+ uint16_t lpcid = get_dev_id(dev);
+ const char *pch_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
+ if (pch_table[i].lpcid == lpcid) {
+ pch_type = pch_table[i].name;
+ break;
+ }
+ }
+ printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
+ lpcid, get_dev_revision(dev), pch_type);
+}
+
+static void report_igd_info(void)
+{
+ int i;
+ pci_devfn_t dev = SA_DEV_IGD;
+ uint16_t igdid = get_dev_id(dev);
+ const char *igd_type = "Unknown";
+
+ for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
+ if (igd_table[i].igdid == igdid) {
+ igd_type = igd_table[i].name;
+ break;
+ }
+ }
+ printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
+ igdid, get_dev_revision(dev), igd_type);
+}
+
+void report_platform_info(void)
+{
+ report_cpu_info();
+ report_mch_info();
+ report_pch_info();
+ report_igd_info();
+}