Lee Leahy | 89c61b5 | 2016-02-07 14:55:05 -0800 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2014 Google Inc. |
| 5 | * Copyright (C) 2015-2016 Intel Corporation. |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; version 2 of the License. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | */ |
| 16 | |
| 17 | #include <arch/cpu.h> |
| 18 | #include <console/console.h> |
| 19 | #include <device/pci.h> |
| 20 | #include <device/pci_def.h> |
| 21 | #include <soc/cpu.h> |
| 22 | #include <soc/pci_devs.h> |
| 23 | #include <soc/romstage.h> |
| 24 | |
| 25 | static const struct { |
| 26 | u32 cpuid; |
| 27 | u32 extended_temp; |
| 28 | u32 ecc; |
| 29 | u32 secure_boot; |
| 30 | u32 d_variant; |
| 31 | u32 mm_number; |
| 32 | const char *name; |
| 33 | } cpu_table[] = { |
| 34 | { CPUID_QUARK_X1000, 0, 0, 0, 0, 930237, "Quark X1000" }, |
| 35 | { CPUID_QUARK_X1000, 0, 1, 0, 0, 930239, "Quark X1010" }, |
| 36 | { CPUID_QUARK_X1000, 0, 1, 1, 0, 934775, "Quark X1020" }, |
| 37 | { CPUID_QUARK_X1000, 0, 1, 1, 1, 930236, "Quark X1020D" }, |
| 38 | { CPUID_QUARK_X1000, 1, 0, 0, 0, 934413, "Quark X1001" }, |
| 39 | { CPUID_QUARK_X1000, 1, 1, 0, 0, 934415, "Quark X1011" }, |
| 40 | { CPUID_QUARK_X1000, 1, 1, 1, 0, 934943, "Quark X1021" }, |
| 41 | { CPUID_QUARK_X1000, 1, 1, 1, 1, 934411, "Quark X1021D" }, |
| 42 | }; |
| 43 | |
| 44 | static struct { |
| 45 | u8 revision_id; |
| 46 | const char *stepping; |
| 47 | } stepping_table[] = { |
| 48 | { 0, "A0" }, |
| 49 | }; |
| 50 | |
| 51 | static uint32_t memory_cntrl_read(uint32_t offset) |
| 52 | { |
| 53 | /* Read the memory controller register */ |
| 54 | mea_write(offset); |
| 55 | mcr_write(QUARK_OPCODE_READ, QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID, |
| 56 | offset); |
| 57 | return mdr_read(); |
| 58 | } |
| 59 | |
| 60 | static uint32_t fuse_port_read(uint32_t offset) |
| 61 | { |
| 62 | /* Read the SoC unit register */ |
| 63 | mea_write(offset); |
| 64 | mcr_write(QUARK_ALT_OPCODE_READ, QUARK_SCSS_FUSE_SB_PORT_ID, offset); |
| 65 | return mdr_read(); |
| 66 | } |
| 67 | |
| 68 | static void report_cpu_info(void) |
| 69 | { |
| 70 | struct cpuid_result cpuidr; |
| 71 | const char *cpu_type = "Unknown"; |
| 72 | u32 d_variant; |
| 73 | u32 ecc_enabled; |
| 74 | u32 extended_temp; |
| 75 | u32 i; |
| 76 | u8 revision; |
| 77 | u32 secure_boot; |
| 78 | const char *stepping = "Unknown"; |
| 79 | |
| 80 | /* Determine if ECC is enabled */ |
| 81 | ecc_enabled = (0 == (B_DFUSESTAT_ECC_DIS |
| 82 | & memory_cntrl_read(QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT))); |
| 83 | |
| 84 | /* Determine if secure boot is enabled */ |
| 85 | secure_boot = (0 != (fuse_port_read(QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE) |
| 86 | & B_ROM_FUSE_IN_SECURE_SKU)); |
| 87 | |
| 88 | /* TODO: Determine if this is a D variant */ |
Lee Leahy | 50a8c8c | 2016-04-12 13:37:02 -0700 | [diff] [blame] | 89 | d_variant = 0; |
Lee Leahy | 89c61b5 | 2016-02-07 14:55:05 -0800 | [diff] [blame] | 90 | if (ecc_enabled && secure_boot) |
| 91 | d_variant = 0; /* or 1 */ |
| 92 | |
| 93 | /* TODO: Determine the temperature variant */ |
| 94 | extended_temp = 0; |
| 95 | |
| 96 | /* Look for string to match the CPU ID value */ |
| 97 | cpuidr = cpuid(1); |
| 98 | for (i = 0; i < ARRAY_SIZE(cpu_table); i++) { |
| 99 | if ((cpu_table[i].cpuid == cpuidr.eax) |
| 100 | && (cpu_table[i].extended_temp == extended_temp) |
| 101 | && (cpu_table[i].ecc == ecc_enabled) |
| 102 | && (cpu_table[i].secure_boot == secure_boot) |
| 103 | && (cpu_table[i].d_variant == d_variant)) { |
| 104 | cpu_type = cpu_table[i].name; |
| 105 | break; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | /* |
| 110 | * Translate the host bridge revision ID into the stepping |
| 111 | * Developer's Manual Section C.2 |
| 112 | */ |
| 113 | revision = pci_read_config8(MC_BDF, PCI_REVISION_ID); |
| 114 | for (i = 0; i < ARRAY_SIZE(stepping_table); i++) { |
| 115 | if (stepping_table[i].revision_id == revision) { |
| 116 | stepping = stepping_table[i].stepping; |
| 117 | break; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | printk(BIOS_DEBUG, "CPU: ID %x:%x, %s %s Stepping\n", cpuidr.eax, |
| 122 | revision, cpu_type, stepping); |
| 123 | } |
| 124 | |
| 125 | void report_platform_info(void) |
| 126 | { |
| 127 | report_cpu_info(); |
| 128 | } |