blob: 1cbbd6384d5291e991281c6d51629f40683af075 [file] [log] [blame]
Andrey Petrova00e1042017-06-05 13:22:59 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
Subrata Banikb3585b92018-01-08 13:57:43 +05305 * Copyright (C) 2015-2018 Intel Corporation.
Andrey Petrova00e1042017-06-05 13:22:59 -07006 *
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>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020018#include <device/pci_ops.h>
Andrey Petrova00e1042017-06-05 13:22:59 -070019#include <console/console.h>
20#include <cpu/x86/msr.h>
21#include <device/pci.h>
22#include <device/pci_ids.h>
Subrata Banikb3585b92018-01-08 13:57:43 +053023#include <intelblocks/mp_init.h>
Andrey Petrova00e1042017-06-05 13:22:59 -070024#include <soc/bootblock.h>
Andrey Petrova00e1042017-06-05 13:22:59 -070025#include <soc/pch.h>
26#include <soc/pci_devs.h>
27#include <string.h>
28
29#define BIOS_SIGN_ID 0x8B
30
31static struct {
32 u32 cpuid;
33 const char *name;
34} cpu_table[] = {
35 { CPUID_CANNONLAKE_A0, "Cannonlake A0" },
36 { CPUID_CANNONLAKE_B0, "Cannonlake B0" },
37 { CPUID_CANNONLAKE_C0, "Cannonlake C0" },
Lijian Zhaoe9872282018-01-21 21:05:54 -080038 { CPUID_CANNONLAKE_D0, "Cannonlake D0" },
Maulikfc19ab52018-01-05 22:40:35 +053039 { CPUID_COFFEELAKE_D0, "Coffeelake D0" },
Subrata Banikd1dfba42019-02-21 17:01:21 +053040 { CPUID_WHISKEYLAKE_V0, "Whiskeylake V0" },
41 { CPUID_WHISKEYLAKE_W0, "Whiskeylake W0" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080042 { CPUID_COFFEELAKE_U0, "Coffeelake U0 (6+2)" },
Ronak Kanabar128bb2a2019-01-29 19:52:53 +053043 { CPUID_COMETLAKE_U_A0, "Cometlake-U A0 (6+2)" },
44 { CPUID_COMETLAKE_U_K0_S0, "Cometlake-U K0/S0 (6+2)/(4+2)" },
45 { CPUID_COMETLAKE_H_S_6_2_P0, "Cometlake-H/S P0 (6+2)" },
46 { CPUID_COMETLAKE_H_S_10_2_P0, "Cometlake-H/S P0 (10+2)" },
Andrey Petrova00e1042017-06-05 13:22:59 -070047};
48
49static struct {
50 u16 mchid;
51 const char *name;
52} mch_table[] = {
53 { PCI_DEVICE_ID_INTEL_CNL_ID_U, "Cannonlake-U" },
54 { PCI_DEVICE_ID_INTEL_CNL_ID_Y, "Cannonlake-Y" },
Subrata Banikab9f64d2019-02-22 13:25:04 +053055 { PCI_DEVICE_ID_INTEL_CFL_ID_U, "Coffeelake U (4+3e)" },
Subrata Banikd1dfba42019-02-21 17:01:21 +053056 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx4, "Whiskeylake W (4+2)" },
57 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx2, "Whiskeylake W (2+2)" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080058 { PCI_DEVICE_ID_INTEL_CFL_ID_H, "Coffeelake-H" },
59 { PCI_DEVICE_ID_INTEL_CFL_ID_S, "Coffeelake-S" },
Ronak Kanabarf606a2f2019-02-04 16:06:50 +053060 { PCI_DEVICE_ID_INTEL_CML_ULT, "CometLake-U (4+2)" },
Subrata Banikba8af582019-02-27 15:00:55 +053061 { PCI_DEVICE_ID_INTEL_CML_ULT_2_2, "CometLake-U (2+2)" },
Ronak Kanabarf606a2f2019-02-04 16:06:50 +053062 { PCI_DEVICE_ID_INTEL_CML_ULT_6_2, "CometLake-U (6+2)" },
63 { PCI_DEVICE_ID_INTEL_CML_ULX, "CometLake-ULX (4+2)" },
64 { PCI_DEVICE_ID_INTEL_CML_S, "CometLake-S (6+2)" },
65 { PCI_DEVICE_ID_INTEL_CML_S_10_2, "CometLake-S (10+2)" },
66 { PCI_DEVICE_ID_INTEL_CML_H, "CometLake-H (6+2)" },
67 { PCI_DEVICE_ID_INTEL_CML_H_8_2, "CometLake-H (8+2)" },
Andrey Petrova00e1042017-06-05 13:22:59 -070068};
69
70static struct {
Subrata Banikec10fbb2017-12-07 11:48:48 +053071 u16 lpcid;
72 const char *name;
73} pch_table[] = {
74 { PCI_DEVICE_ID_INTEL_CNL_BASE_U_LPC, "Cannonlake-U Base" },
75 { PCI_DEVICE_ID_INTEL_CNL_U_PREMIUM_LPC, "Cannonlake-U Premium" },
76 { PCI_DEVICE_ID_INTEL_CNL_Y_PREMIUM_LPC, "Cannonlake-Y Premium" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080077 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_Q370, "Cannonlake-H Q370" },
78 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_QM370, "Cannonlake-H QM370" },
Nico Huber129bc4c2019-05-14 13:17:28 +020079 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_CM246, "Cannonlake-H CM246" },
Ronak Kanabarda7ffb482019-02-05 01:51:13 +053080 { PCI_DEVICE_ID_INTEL_CMP_SUPER_U_LPC, "Cometlake-U Super" },
81 { PCI_DEVICE_ID_INTEL_CMP_PREMIUM_Y_LPC, "Cometlake-Y Premium" },
82 { PCI_DEVICE_ID_INTEL_CMP_PREMIUM_U_LPC, "Cometlake-U Premium" },
83 { PCI_DEVICE_ID_INTEL_CMP_BASE_U_LPC, "Cometlake-U Base" },
84 { PCI_DEVICE_ID_INTEL_CMP_SUPER_Y_LPC, "Cometlake-Y Super" },
Subrata Banikec10fbb2017-12-07 11:48:48 +053085};
86
87static struct {
Andrey Petrova00e1042017-06-05 13:22:59 -070088 u16 igdid;
89 const char *name;
90} igd_table[] = {
91 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_1, "Cannonlake ULX GT2" },
92 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_2, "Cannonlake ULX GT1.5" },
93 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_3, "Cannonlake ULX GT1" },
94 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_4, "Cannonlake ULX GT0.5" },
95 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_1, "Cannonlake ULT GT2" },
96 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_2, "Cannonlake ULT GT1.5" },
97 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_3, "Cannonlake ULT GT1" },
98 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_4, "Cannonlake ULT GT0.5" },
Subrata Banikd1dfba42019-02-21 17:01:21 +053099 { PCI_DEVICE_ID_INTEL_CFL_GT2_ULT, "Coffeelake ULT GT2" },
Lijian Zhao395f1e32019-04-14 12:27:02 -0700100 { PCI_DEVICE_ID_INTEL_WHL_GT1_ULT_1, "Whiskeylake ULT GT1" },
101 { PCI_DEVICE_ID_INTEL_WHL_GT2_ULT_1, "Whiskeylake ULT GT2" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +0800102 { PCI_DEVICE_ID_INTEL_CFL_H_GT2, "Coffeelake-H GT2" },
Nico Huberff3c9642019-05-14 13:18:05 +0200103 { PCI_DEVICE_ID_INTEL_CFL_H_XEON_GT2, "Coffeelake-H Xeon GT2" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +0800104 { PCI_DEVICE_ID_INTEL_CFL_S_GT2, "Coffeelake-S GT2" },
Ronak Kanabarf606a2f2019-02-04 16:06:50 +0530105 { PCI_DEVICE_ID_INTEL_CML_GT1_ULT_1, "CometLake ULT GT1" },
106 { PCI_DEVICE_ID_INTEL_CML_GT1_ULT_2, "CometLake ULT GT1" },
107 { PCI_DEVICE_ID_INTEL_CML_GT2_ULT_1, "CometLake ULT GT2" },
108 { PCI_DEVICE_ID_INTEL_CML_GT2_ULT_2, "CometLake ULT GT2" },
109 { PCI_DEVICE_ID_INTEL_CML_GT1_ULT_3, "CometLake ULT GT1" },
110 { PCI_DEVICE_ID_INTEL_CML_GT1_ULT_4, "CometLake ULT GT1" },
111 { PCI_DEVICE_ID_INTEL_CML_GT2_ULT_3, "CometLake ULT GT2" },
112 { PCI_DEVICE_ID_INTEL_CML_GT2_ULT_4, "CometLake ULT GT2" },
113 { PCI_DEVICE_ID_INTEL_CML_GT1_ULX_1, "CometLake ULX GT1" },
114 { PCI_DEVICE_ID_INTEL_CML_GT2_ULX_1, "CometLake ULX GT2" },
115 { PCI_DEVICE_ID_INTEL_CML_GT1_S_1, "CometLake S GT1" },
116 { PCI_DEVICE_ID_INTEL_CML_GT1_S_2, "CometLake S GT1" },
117 { PCI_DEVICE_ID_INTEL_CML_GT2_S_1, "CometLake S GT2" },
118 { PCI_DEVICE_ID_INTEL_CML_GT2_S_2, "CometLake S GT2" },
119 { PCI_DEVICE_ID_INTEL_CML_GT1_H_1, "CometLake H GT1" },
120 { PCI_DEVICE_ID_INTEL_CML_GT1_H_2, "CometLake H GT1" },
121 { PCI_DEVICE_ID_INTEL_CML_GT2_H_1, "CometLake H GT2" },
122 { PCI_DEVICE_ID_INTEL_CML_GT2_H_2, "CometLake H GT2" },
Andrey Petrova00e1042017-06-05 13:22:59 -0700123};
124
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200125static uint8_t get_dev_revision(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +0530126{
127 return pci_read_config8(dev, PCI_REVISION_ID);
128}
129
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200130static uint16_t get_dev_id(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +0530131{
132 return pci_read_config16(dev, PCI_DEVICE_ID);
133}
134
Andrey Petrova00e1042017-06-05 13:22:59 -0700135static void report_cpu_info(void)
136{
137 struct cpuid_result cpuidr;
Subrata Banik53b08c32018-12-10 14:11:35 +0530138 u32 i, index, cpu_id, cpu_feature_flag;
Andrey Petrova00e1042017-06-05 13:22:59 -0700139 char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
140 int vt, txt, aes;
141 msr_t microcode_ver;
Elyes HAOUAS39303d52018-07-08 12:40:45 +0200142 static const char *const mode[] = {"NOT ", ""};
Andrey Petrova00e1042017-06-05 13:22:59 -0700143 const char *cpu_type = "Unknown";
Martin Roth3f6421e2017-07-21 09:17:58 -0600144 u32 p[13];
Andrey Petrova00e1042017-06-05 13:22:59 -0700145
146 index = 0x80000000;
147 cpuidr = cpuid(index);
148 if (cpuidr.eax < 0x80000004) {
149 strcpy(cpu_string, "Platform info not available");
150 } else {
Andrey Petrova00e1042017-06-05 13:22:59 -0700151 int j=0;
152
153 for (i = 2; i <= 4; i++) {
154 cpuidr = cpuid(index + i);
155 p[j++] = cpuidr.eax;
156 p[j++] = cpuidr.ebx;
157 p[j++] = cpuidr.ecx;
158 p[j++] = cpuidr.edx;
159 }
160 p[12]=0;
161 cpu_name = (char *)p;
162 }
163 /* Skip leading spaces in CPU name string */
164 while (cpu_name[0] == ' ')
165 cpu_name++;
166
167 microcode_ver.lo = 0;
168 microcode_ver.hi = 0;
169 wrmsr(BIOS_SIGN_ID, microcode_ver);
Subrata Banik53b08c32018-12-10 14:11:35 +0530170 cpu_id = cpu_get_cpuid();
Andrey Petrova00e1042017-06-05 13:22:59 -0700171 microcode_ver = rdmsr(BIOS_SIGN_ID);
172
173 /* Look for string to match the name */
174 for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
Subrata Banik53b08c32018-12-10 14:11:35 +0530175 if (cpu_table[i].cpuid == cpu_id) {
Andrey Petrova00e1042017-06-05 13:22:59 -0700176 cpu_type = cpu_table[i].name;
177 break;
178 }
179 }
180
181 printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
182 printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
Subrata Banik53b08c32018-12-10 14:11:35 +0530183 cpu_id, cpu_type, microcode_ver.hi);
Andrey Petrova00e1042017-06-05 13:22:59 -0700184
Subrata Banik53b08c32018-12-10 14:11:35 +0530185 cpu_feature_flag = cpu_get_feature_flags_ecx();
186 aes = (cpu_feature_flag & CPUID_AES) ? 1 : 0;
187 txt = (cpu_feature_flag & CPUID_SMX) ? 1 : 0;
188 vt = (cpu_feature_flag & CPUID_VMX) ? 1 : 0;
Andrey Petrova00e1042017-06-05 13:22:59 -0700189 printk(BIOS_DEBUG,
190 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
191 mode[aes], mode[txt], mode[vt]);
192}
193
194static void report_mch_info(void)
195{
196 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200197 pci_devfn_t dev = SA_DEV_ROOT;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530198 uint16_t mchid = get_dev_id(dev);
199 uint8_t mch_revision = get_dev_revision(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700200 const char *mch_type = "Unknown";
201
202 for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
203 if (mch_table[i].mchid == mchid) {
204 mch_type = mch_table[i].name;
205 break;
206 }
207 }
208
209 printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530210 mchid, mch_revision, mch_type);
211}
212
213static void report_pch_info(void)
214{
215 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200216 pci_devfn_t dev = PCH_DEV_LPC;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530217 uint16_t lpcid = get_dev_id(dev);
218 const char *pch_type = "Unknown";
219
220 for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
221 if (pch_table[i].lpcid == lpcid) {
222 pch_type = pch_table[i].name;
223 break;
224 }
225 }
226 printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
227 lpcid, get_dev_revision(dev), pch_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700228}
229
230static void report_igd_info(void)
231{
232 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200233 pci_devfn_t dev = SA_DEV_IGD;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530234 uint16_t igdid = get_dev_id(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700235 const char *igd_type = "Unknown";
236
237 for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
238 if (igd_table[i].igdid == igdid) {
239 igd_type = igd_table[i].name;
240 break;
241 }
242 }
243 printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530244 igdid, get_dev_revision(dev), igd_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700245}
246
247void report_platform_info(void)
248{
249 report_cpu_info();
250 report_mch_info();
Subrata Banikec10fbb2017-12-07 11:48:48 +0530251 report_pch_info();
Andrey Petrova00e1042017-06-05 13:22:59 -0700252 report_igd_info();
253}