blob: 5ed8a5f9cbd49bea23e24b59f970c22e13870823 [file] [log] [blame]
Lee Leahy89c61b52016-02-07 14:55:05 -08001/*
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
25static 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
44static struct {
45 u8 revision_id;
46 const char *stepping;
47} stepping_table[] = {
48 { 0, "A0" },
49};
50
51static 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
60static 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
68static 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 Leahy50a8c8c2016-04-12 13:37:02 -070089 d_variant = 0;
Lee Leahy89c61b52016-02-07 14:55:05 -080090 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
125void report_platform_info(void)
126{
127 report_cpu_info();
128}