blob: 8839816591dbab56211fdf687b5d184725554dba [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>
18#include <arch/io.h>
19#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" },
40 { CPUID_WHISKEYLAKE_W0, "Whiskeylake W0"},
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080041 { CPUID_COFFEELAKE_U0, "Coffeelake U0 (6+2)" },
Andrey Petrova00e1042017-06-05 13:22:59 -070042};
43
44static struct {
45 u16 mchid;
46 const char *name;
47} mch_table[] = {
48 { PCI_DEVICE_ID_INTEL_CNL_ID_U, "Cannonlake-U" },
49 { PCI_DEVICE_ID_INTEL_CNL_ID_Y, "Cannonlake-Y" },
Maulikfc19ab52018-01-05 22:40:35 +053050 { PCI_DEVICE_ID_INTEL_CFL_ID_U, "Coffeelake U (4+3e)"},
Krzysztof Sywulabb0cf012018-08-15 09:26:35 -070051 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx4, "Whiskeylake W (4+2)"},
52 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx2, "Whiskeylake W (2+2)"},
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080053 { PCI_DEVICE_ID_INTEL_CFL_ID_H, "Coffeelake-H" },
54 { PCI_DEVICE_ID_INTEL_CFL_ID_S, "Coffeelake-S" },
Andrey Petrova00e1042017-06-05 13:22:59 -070055};
56
57static struct {
Subrata Banikec10fbb2017-12-07 11:48:48 +053058 u16 lpcid;
59 const char *name;
60} pch_table[] = {
61 { PCI_DEVICE_ID_INTEL_CNL_BASE_U_LPC, "Cannonlake-U Base" },
62 { PCI_DEVICE_ID_INTEL_CNL_U_PREMIUM_LPC, "Cannonlake-U Premium" },
63 { PCI_DEVICE_ID_INTEL_CNL_Y_PREMIUM_LPC, "Cannonlake-Y Premium" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080064 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_Q370, "Cannonlake-H Q370" },
65 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_QM370, "Cannonlake-H QM370" },
Subrata Banikec10fbb2017-12-07 11:48:48 +053066};
67
68static struct {
Andrey Petrova00e1042017-06-05 13:22:59 -070069 u16 igdid;
70 const char *name;
71} igd_table[] = {
72 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_1, "Cannonlake ULX GT2" },
73 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_2, "Cannonlake ULX GT1.5" },
74 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_3, "Cannonlake ULX GT1" },
75 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_4, "Cannonlake ULX GT0.5" },
76 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_1, "Cannonlake ULT GT2" },
77 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_2, "Cannonlake ULT GT1.5" },
78 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_3, "Cannonlake ULT GT1" },
79 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_4, "Cannonlake ULT GT0.5" },
Maulikfc19ab52018-01-05 22:40:35 +053080 { PCI_DEVICE_ID_INTEL_CFL_GT2_ULT, "Coffeelake ULT GT2"},
81 { PCI_DEVICE_ID_INTEL_WHL_GT2_ULT_1, "Whiskeylake ULT GT1"},
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080082 { PCI_DEVICE_ID_INTEL_CFL_H_GT2, "Coffeelake-H GT2" },
83 { PCI_DEVICE_ID_INTEL_CFL_S_GT2, "Coffeelake-S GT2" },
Andrey Petrova00e1042017-06-05 13:22:59 -070084};
85
Elyes HAOUASc8a649c2018-06-10 23:36:44 +020086static uint8_t get_dev_revision(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +053087{
88 return pci_read_config8(dev, PCI_REVISION_ID);
89}
90
Elyes HAOUASc8a649c2018-06-10 23:36:44 +020091static uint16_t get_dev_id(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +053092{
93 return pci_read_config16(dev, PCI_DEVICE_ID);
94}
95
Andrey Petrova00e1042017-06-05 13:22:59 -070096static void report_cpu_info(void)
97{
98 struct cpuid_result cpuidr;
Subrata Banik53b08c32018-12-10 14:11:35 +053099 u32 i, index, cpu_id, cpu_feature_flag;
Andrey Petrova00e1042017-06-05 13:22:59 -0700100 char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
101 int vt, txt, aes;
102 msr_t microcode_ver;
Elyes HAOUAS39303d52018-07-08 12:40:45 +0200103 static const char *const mode[] = {"NOT ", ""};
Andrey Petrova00e1042017-06-05 13:22:59 -0700104 const char *cpu_type = "Unknown";
Martin Roth3f6421e2017-07-21 09:17:58 -0600105 u32 p[13];
Andrey Petrova00e1042017-06-05 13:22:59 -0700106
107 index = 0x80000000;
108 cpuidr = cpuid(index);
109 if (cpuidr.eax < 0x80000004) {
110 strcpy(cpu_string, "Platform info not available");
111 } else {
Andrey Petrova00e1042017-06-05 13:22:59 -0700112 int j=0;
113
114 for (i = 2; i <= 4; i++) {
115 cpuidr = cpuid(index + i);
116 p[j++] = cpuidr.eax;
117 p[j++] = cpuidr.ebx;
118 p[j++] = cpuidr.ecx;
119 p[j++] = cpuidr.edx;
120 }
121 p[12]=0;
122 cpu_name = (char *)p;
123 }
124 /* Skip leading spaces in CPU name string */
125 while (cpu_name[0] == ' ')
126 cpu_name++;
127
128 microcode_ver.lo = 0;
129 microcode_ver.hi = 0;
130 wrmsr(BIOS_SIGN_ID, microcode_ver);
Subrata Banik53b08c32018-12-10 14:11:35 +0530131 cpu_id = cpu_get_cpuid();
Andrey Petrova00e1042017-06-05 13:22:59 -0700132 microcode_ver = rdmsr(BIOS_SIGN_ID);
133
134 /* Look for string to match the name */
135 for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
Subrata Banik53b08c32018-12-10 14:11:35 +0530136 if (cpu_table[i].cpuid == cpu_id) {
Andrey Petrova00e1042017-06-05 13:22:59 -0700137 cpu_type = cpu_table[i].name;
138 break;
139 }
140 }
141
142 printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
143 printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
Subrata Banik53b08c32018-12-10 14:11:35 +0530144 cpu_id, cpu_type, microcode_ver.hi);
Andrey Petrova00e1042017-06-05 13:22:59 -0700145
Subrata Banik53b08c32018-12-10 14:11:35 +0530146 cpu_feature_flag = cpu_get_feature_flags_ecx();
147 aes = (cpu_feature_flag & CPUID_AES) ? 1 : 0;
148 txt = (cpu_feature_flag & CPUID_SMX) ? 1 : 0;
149 vt = (cpu_feature_flag & CPUID_VMX) ? 1 : 0;
Andrey Petrova00e1042017-06-05 13:22:59 -0700150 printk(BIOS_DEBUG,
151 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
152 mode[aes], mode[txt], mode[vt]);
153}
154
155static void report_mch_info(void)
156{
157 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200158 pci_devfn_t dev = SA_DEV_ROOT;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530159 uint16_t mchid = get_dev_id(dev);
160 uint8_t mch_revision = get_dev_revision(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700161 const char *mch_type = "Unknown";
162
163 for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
164 if (mch_table[i].mchid == mchid) {
165 mch_type = mch_table[i].name;
166 break;
167 }
168 }
169
170 printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530171 mchid, mch_revision, mch_type);
172}
173
174static void report_pch_info(void)
175{
176 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200177 pci_devfn_t dev = PCH_DEV_LPC;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530178 uint16_t lpcid = get_dev_id(dev);
179 const char *pch_type = "Unknown";
180
181 for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
182 if (pch_table[i].lpcid == lpcid) {
183 pch_type = pch_table[i].name;
184 break;
185 }
186 }
187 printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
188 lpcid, get_dev_revision(dev), pch_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700189}
190
191static void report_igd_info(void)
192{
193 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200194 pci_devfn_t dev = SA_DEV_IGD;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530195 uint16_t igdid = get_dev_id(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700196 const char *igd_type = "Unknown";
197
198 for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
199 if (igd_table[i].igdid == igdid) {
200 igd_type = igd_table[i].name;
201 break;
202 }
203 }
204 printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530205 igdid, get_dev_revision(dev), igd_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700206}
207
208void report_platform_info(void)
209{
210 report_cpu_info();
211 report_mch_info();
Subrata Banikec10fbb2017-12-07 11:48:48 +0530212 report_pch_info();
Andrey Petrova00e1042017-06-05 13:22:59 -0700213 report_igd_info();
214}