diff options
Diffstat (limited to 'src/soc/intel/quark/romstage/report_platform.c')
-rw-r--r-- | src/soc/intel/quark/romstage/report_platform.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/soc/intel/quark/romstage/report_platform.c b/src/soc/intel/quark/romstage/report_platform.c new file mode 100644 index 0000000000..7ede746e1b --- /dev/null +++ b/src/soc/intel/quark/romstage/report_platform.c @@ -0,0 +1,127 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015-2016 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/cpu.h> +#include <console/console.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <soc/cpu.h> +#include <soc/pci_devs.h> +#include <soc/romstage.h> + +static const struct { + u32 cpuid; + u32 extended_temp; + u32 ecc; + u32 secure_boot; + u32 d_variant; + u32 mm_number; + const char *name; +} cpu_table[] = { + { CPUID_QUARK_X1000, 0, 0, 0, 0, 930237, "Quark X1000" }, + { CPUID_QUARK_X1000, 0, 1, 0, 0, 930239, "Quark X1010" }, + { CPUID_QUARK_X1000, 0, 1, 1, 0, 934775, "Quark X1020" }, + { CPUID_QUARK_X1000, 0, 1, 1, 1, 930236, "Quark X1020D" }, + { CPUID_QUARK_X1000, 1, 0, 0, 0, 934413, "Quark X1001" }, + { CPUID_QUARK_X1000, 1, 1, 0, 0, 934415, "Quark X1011" }, + { CPUID_QUARK_X1000, 1, 1, 1, 0, 934943, "Quark X1021" }, + { CPUID_QUARK_X1000, 1, 1, 1, 1, 934411, "Quark X1021D" }, +}; + +static struct { + u8 revision_id; + const char *stepping; +} stepping_table[] = { + { 0, "A0" }, +}; + +static uint32_t memory_cntrl_read(uint32_t offset) +{ + /* Read the memory controller register */ + mea_write(offset); + mcr_write(QUARK_OPCODE_READ, QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID, + offset); + return mdr_read(); +} + +static uint32_t fuse_port_read(uint32_t offset) +{ + /* Read the SoC unit register */ + mea_write(offset); + mcr_write(QUARK_ALT_OPCODE_READ, QUARK_SCSS_FUSE_SB_PORT_ID, offset); + return mdr_read(); +} + +static void report_cpu_info(void) +{ + struct cpuid_result cpuidr; + const char *cpu_type = "Unknown"; + u32 d_variant; + u32 ecc_enabled; + u32 extended_temp; + u32 i; + u8 revision; + u32 secure_boot; + const char *stepping = "Unknown"; + + /* Determine if ECC is enabled */ + ecc_enabled = (0 == (B_DFUSESTAT_ECC_DIS + & memory_cntrl_read(QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT))); + + /* Determine if secure boot is enabled */ + secure_boot = (0 != (fuse_port_read(QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE) + & B_ROM_FUSE_IN_SECURE_SKU)); + + /* TODO: Determine if this is a D variant */ + if (ecc_enabled && secure_boot) + d_variant = 0; /* or 1 */ + + /* TODO: Determine the temperature variant */ + extended_temp = 0; + + /* Look for string to match the CPU ID value */ + cpuidr = cpuid(1); + for (i = 0; i < ARRAY_SIZE(cpu_table); i++) { + if ((cpu_table[i].cpuid == cpuidr.eax) + && (cpu_table[i].extended_temp == extended_temp) + && (cpu_table[i].ecc == ecc_enabled) + && (cpu_table[i].secure_boot == secure_boot) + && (cpu_table[i].d_variant == d_variant)) { + cpu_type = cpu_table[i].name; + break; + } + } + + /* + * Translate the host bridge revision ID into the stepping + * Developer's Manual Section C.2 + */ + revision = pci_read_config8(MC_BDF, PCI_REVISION_ID); + for (i = 0; i < ARRAY_SIZE(stepping_table); i++) { + if (stepping_table[i].revision_id == revision) { + stepping = stepping_table[i].stepping; + break; + } + } + + printk(BIOS_DEBUG, "CPU: ID %x:%x, %s %s Stepping\n", cpuidr.eax, + revision, cpu_type, stepping); +} + +void report_platform_info(void) +{ + report_cpu_info(); +} |