aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r--arch/x86/cpu/apollolake/acpi.c25
-rw-r--r--arch/x86/cpu/apollolake/cpu.c88
-rw-r--r--arch/x86/cpu/apollolake/cpu_common.c25
-rw-r--r--arch/x86/cpu/apollolake/cpu_spl.c20
-rw-r--r--arch/x86/cpu/apollolake/fsp_s.c8
-rw-r--r--arch/x86/cpu/apollolake/hostbridge.c2
-rw-r--r--arch/x86/cpu/apollolake/lpc.c2
-rw-r--r--arch/x86/cpu/apollolake/pch.c4
-rw-r--r--arch/x86/cpu/apollolake/pmc.c2
-rw-r--r--arch/x86/cpu/apollolake/punit.c4
-rw-r--r--arch/x86/cpu/apollolake/uart.c2
-rw-r--r--arch/x86/cpu/cpu.c9
-rw-r--r--arch/x86/cpu/i386/interrupt.c14
-rw-r--r--arch/x86/cpu/intel_common/acpi.c1
-rw-r--r--arch/x86/cpu/intel_common/cpu.c19
-rw-r--r--arch/x86/cpu/intel_common/intel_opregion.c2
-rw-r--r--arch/x86/cpu/intel_common/itss.c10
-rw-r--r--arch/x86/cpu/intel_common/p2sb.c2
18 files changed, 184 insertions, 55 deletions
diff --git a/arch/x86/cpu/apollolake/acpi.c b/arch/x86/cpu/apollolake/acpi.c
index 69b544f0d9..fd21c0b496 100644
--- a/arch/x86/cpu/apollolake/acpi.c
+++ b/arch/x86/cpu/apollolake/acpi.c
@@ -65,6 +65,21 @@ int arch_write_sci_irq_select(uint scis)
return 0;
}
+/**
+ * chromeos_init_acpi() - Initialise basic data to boot Chrome OS
+ *
+ * This tells Chrome OS to boot in developer mode
+ *
+ * @cros: Structure to initialise
+ */
+static void chromeos_init_acpi(struct chromeos_acpi_gnvs *cros)
+{
+ cros->active_main_fw = 1;
+ cros->active_main_fw = 1; /* A */
+ cros->switches = CHSW_DEVELOPER_SWITCH;
+ cros->main_fw_type = 2; /* Developer */
+}
+
int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
{
struct udevice *cpu;
@@ -75,11 +90,9 @@ int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
/* TODO(sjg@chromium.org): Add the console log to gnvs->cbmc */
-#ifdef CONFIG_CHROMEOS
- /* Initialise Verified Boot data */
- chromeos_init_acpi(&gnvs->chromeos);
- gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO;
-#endif
+ if (IS_ENABLED(CONFIG_CHROMEOS))
+ chromeos_init_acpi(&gnvs->chromeos);
+
/* Set unknown wake source */
gnvs->pm1i = ~0ULL;
@@ -92,6 +105,8 @@ int acpi_create_gnvs(struct acpi_global_nvs *gnvs)
gnvs->pcnt = ret;
}
+ gnvs->dpte = 1;
+
return 0;
}
diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c
index 8da2e64e22..d37f91d1ce 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_mtrrs(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_mtrrs();
+}
+
+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,
};
@@ -102,11 +185,12 @@ static const struct udevice_id cpu_x86_apl_ids[] = {
{ }
};
-U_BOOT_DRIVER(cpu_x86_apl_drv) = {
- .name = "cpu_x86_apl",
+U_BOOT_DRIVER(intel_apl_cpu) = {
+ .name = "intel_apl_cpu",
.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 ba6bda37bc..63f6999b02 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 9f32f2e27e..fafe4dbc0a 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/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c
index 715ceab6ac..288188027a 100644
--- a/arch/x86/cpu/apollolake/fsp_s.c
+++ b/arch/x86/cpu/apollolake/fsp_s.c
@@ -116,10 +116,10 @@ static int set_power_limits(struct udevice *dev)
/* Program package power limits in RAPL MSR */
msr_write(MSR_PKG_POWER_LIMIT, limit);
- log_info("RAPL PL1 %d.%dW\n", tdp / power_unit,
- 100 * (tdp % power_unit) / power_unit);
- log_info("RAPL PL2 %d.%dW\n", pl2_val / power_unit,
- 100 * (pl2_val % power_unit) / power_unit);
+ log_debug("RAPL PL1 %d.%dW\n", tdp / power_unit,
+ 100 * (tdp % power_unit) / power_unit);
+ log_debug("RAPL PL2 %d.%dW\n", pl2_val / power_unit,
+ 100 * (pl2_val % power_unit) / power_unit);
/*
* Sett RAPL MMIO register for Power limits. RAPL driver is using MSR
diff --git a/arch/x86/cpu/apollolake/hostbridge.c b/arch/x86/cpu/apollolake/hostbridge.c
index 7fd67dcfb6..cafd9d65b2 100644
--- a/arch/x86/cpu/apollolake/hostbridge.c
+++ b/arch/x86/cpu/apollolake/hostbridge.c
@@ -396,7 +396,7 @@ static const struct udevice_id apl_hostbridge_ids[] = {
{ }
};
-U_BOOT_DRIVER(apl_hostbridge_drv) = {
+U_BOOT_DRIVER(intel_apl_hostbridge) = {
.name = "intel_apl_hostbridge",
.id = UCLASS_NORTHBRIDGE,
.of_match = apl_hostbridge_ids,
diff --git a/arch/x86/cpu/apollolake/lpc.c b/arch/x86/cpu/apollolake/lpc.c
index a29832c879..d8e05f6a8f 100644
--- a/arch/x86/cpu/apollolake/lpc.c
+++ b/arch/x86/cpu/apollolake/lpc.c
@@ -133,7 +133,7 @@ static const struct udevice_id apl_lpc_ids[] = {
};
/* All pads are LPC already configured by the hostbridge, so no probing here */
-U_BOOT_DRIVER(apl_lpc_drv) = {
+U_BOOT_DRIVER(intel_apl_lpc) = {
.name = "intel_apl_lpc",
.id = UCLASS_LPC,
.of_match = apl_lpc_ids,
diff --git a/arch/x86/cpu/apollolake/pch.c b/arch/x86/cpu/apollolake/pch.c
index 1a5a985221..d9832ff249 100644
--- a/arch/x86/cpu/apollolake/pch.c
+++ b/arch/x86/cpu/apollolake/pch.c
@@ -28,8 +28,8 @@ static const struct udevice_id apl_pch_ids[] = {
{ }
};
-U_BOOT_DRIVER(apl_pch) = {
- .name = "apl_pch",
+U_BOOT_DRIVER(intel_apl_pch) = {
+ .name = "intel_apl_pch",
.id = UCLASS_PCH,
.of_match = apl_pch_ids,
.ops = &apl_pch_ops,
diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c
index 576d018757..cacaa007e0 100644
--- a/arch/x86/cpu/apollolake/pmc.c
+++ b/arch/x86/cpu/apollolake/pmc.c
@@ -217,7 +217,7 @@ static const struct udevice_id apl_pmc_ids[] = {
{ }
};
-U_BOOT_DRIVER(apl_pmc) = {
+U_BOOT_DRIVER(intel_apl_pmc) = {
.name = "intel_apl_pmc",
.id = UCLASS_ACPI_PMC,
.of_match = apl_pmc_ids,
diff --git a/arch/x86/cpu/apollolake/punit.c b/arch/x86/cpu/apollolake/punit.c
index e76f2805d7..e67c011e22 100644
--- a/arch/x86/cpu/apollolake/punit.c
+++ b/arch/x86/cpu/apollolake/punit.c
@@ -88,8 +88,8 @@ static const struct udevice_id apl_syscon_ids[] = {
{ }
};
-U_BOOT_DRIVER(syscon_intel_punit) = {
- .name = "intel_punit_syscon",
+U_BOOT_DRIVER(intel_apl_punit) = {
+ .name = "intel_apl_punit",
.id = UCLASS_SYSCON,
.of_match = apl_syscon_ids,
.probe = apl_punit_probe,
diff --git a/arch/x86/cpu/apollolake/uart.c b/arch/x86/cpu/apollolake/uart.c
index f368f7d2db..c522aa9780 100644
--- a/arch/x86/cpu/apollolake/uart.c
+++ b/arch/x86/cpu/apollolake/uart.c
@@ -122,7 +122,7 @@ static const struct udevice_id apl_ns16550_serial_ids[] = {
{ },
};
-U_BOOT_DRIVER(apl_ns16550) = {
+U_BOOT_DRIVER(intel_apl_ns16550) = {
.name = "intel_apl_ns16550",
.id = UCLASS_SERIAL,
.of_match = apl_ns16550_serial_ids,
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index f869275396..71351262f6 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -18,6 +18,8 @@
* src/arch/x86/lib/cpu.c
*/
+#define LOG_CATEGORY UCLASS_CPU
+
#include <common.h>
#include <bootstage.h>
#include <command.h>
@@ -200,6 +202,7 @@ __weak void board_final_cleanup(void)
int last_stage_init(void)
{
struct acpi_fadt __maybe_unused *fadt;
+ int ret;
board_final_init();
@@ -210,7 +213,11 @@ int last_stage_init(void)
acpi_resume(fadt);
}
- write_tables();
+ ret = write_tables();
+ if (ret) {
+ log_err("Failed to write tables\n");
+ return log_msg_ret("table", ret);
+ }
if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
fadt = acpi_find_fadt();
diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c
index c0c4bc95fd..d85f84b29a 100644
--- a/arch/x86/cpu/i386/interrupt.c
+++ b/arch/x86/cpu/i386/interrupt.c
@@ -180,16 +180,11 @@ struct idt_entry {
u16 base_high;
} __packed;
-struct desc_ptr {
- unsigned short size;
- unsigned long address;
-} __packed;
-
struct idt_entry idt[256] __aligned(16);
-struct desc_ptr idt_ptr;
+struct idt_ptr idt_ptr;
-static inline void load_idt(const struct desc_ptr *dtr)
+static inline void load_idt(const struct idt_ptr *dtr)
{
asm volatile("cs lidt %0" : : "m" (*dtr));
}
@@ -232,6 +227,11 @@ int cpu_init_interrupts(void)
return 0;
}
+void interrupt_read_idt(struct idt_ptr *ptr)
+{
+ asm volatile("sidt %0" : : "m" (*ptr));
+}
+
void *x86_get_idt(void)
{
return &idt_ptr;
diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c
index 4496bbfd99..6a3456f476 100644
--- a/arch/x86/cpu/intel_common/acpi.c
+++ b/arch/x86/cpu/intel_common/acpi.c
@@ -202,7 +202,6 @@ int southbridge_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx)
(void **)&gnvs);
if (ret)
return log_msg_ret("bloblist", ret);
- memset(gnvs, '\0', sizeof(*gnvs));
ret = acpi_create_gnvs(gnvs);
if (ret)
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 39aa0f63c6..a51bf86f7a 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);
+ /* Initialise machine checks */
+ msr_write(MSR_IA32_MC0_CTL + i * 4,
+ (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff});
+ }
+}
diff --git a/arch/x86/cpu/intel_common/intel_opregion.c b/arch/x86/cpu/intel_common/intel_opregion.c
index c95ae04992..1eed21d8cd 100644
--- a/arch/x86/cpu/intel_common/intel_opregion.c
+++ b/arch/x86/cpu/intel_common/intel_opregion.c
@@ -42,7 +42,7 @@ static int locate_vbt(char **vbtp, int *sizep)
return -EINVAL;
}
- log_info("Found a VBT of %u bytes\n", size);
+ log_debug("Found a VBT of %u bytes\n", size);
*sizep = size;
*vbtp = vbt_data;
diff --git a/arch/x86/cpu/intel_common/itss.c b/arch/x86/cpu/intel_common/itss.c
index fe84ebe29f..de17b93ed4 100644
--- a/arch/x86/cpu/intel_common/itss.c
+++ b/arch/x86/cpu/intel_common/itss.c
@@ -67,7 +67,7 @@ static int snapshot_polarities(struct udevice *dev)
reg_start = start / IRQS_PER_IPC;
reg_end = DIV_ROUND_UP(end, IRQS_PER_IPC);
- log_info("ITSS IRQ Polarities snapshot %p\n", priv->irq_snapshot);
+ log_debug("ITSS IRQ Polarities snapshot %p\n", priv->irq_snapshot);
for (i = reg_start; i < reg_end; i++) {
uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
@@ -89,11 +89,11 @@ static void show_polarities(struct udevice *dev, const char *msg)
{
int i;
- log_info("ITSS IRQ Polarities %s:\n", msg);
+ log_debug("ITSS IRQ Polarities %s:\n", msg);
for (i = 0; i < NUM_IPC_REGS; i++) {
uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
- log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
+ log_debug("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
}
}
@@ -115,7 +115,7 @@ static int restore_polarities(struct udevice *dev)
sizeof(priv->irq_snapshot));
show_polarities(dev, "Before");
- log_info("priv->irq_snapshot %p\n", priv->irq_snapshot);
+ log_debug("priv->irq_snapshot %p\n", priv->irq_snapshot);
reg_start = start / IRQS_PER_IPC;
reg_end = DIV_ROUND_UP(end, IRQS_PER_IPC);
@@ -235,7 +235,7 @@ static const struct udevice_id itss_ids[] = {
{ }
};
-U_BOOT_DRIVER(itss_drv) = {
+U_BOOT_DRIVER(intel_itss) = {
.name = "intel_itss",
.id = UCLASS_IRQ,
.of_match = itss_ids,
diff --git a/arch/x86/cpu/intel_common/p2sb.c b/arch/x86/cpu/intel_common/p2sb.c
index 361d4c90cb..a0a4001e03 100644
--- a/arch/x86/cpu/intel_common/p2sb.c
+++ b/arch/x86/cpu/intel_common/p2sb.c
@@ -189,7 +189,7 @@ static const struct udevice_id p2sb_ids[] = {
{ }
};
-U_BOOT_DRIVER(p2sb_drv) = {
+U_BOOT_DRIVER(intel_p2sb) = {
.name = "intel_p2sb",
.id = UCLASS_P2SB,
.of_match = p2sb_ids,