blob: b8b467f866712c18033f02c276b0736d5db07da4 [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" },
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)" },
Andrey Petrova00e1042017-06-05 13:22:59 -070043};
44
45static struct {
46 u16 mchid;
47 const char *name;
48} mch_table[] = {
49 { PCI_DEVICE_ID_INTEL_CNL_ID_U, "Cannonlake-U" },
50 { PCI_DEVICE_ID_INTEL_CNL_ID_Y, "Cannonlake-Y" },
Maulikfc19ab52018-01-05 22:40:35 +053051 { PCI_DEVICE_ID_INTEL_CFL_ID_U, "Coffeelake U (4+3e)"},
Subrata Banikd1dfba42019-02-21 17:01:21 +053052 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx4, "Whiskeylake W (4+2)" },
53 { PCI_DEVICE_ID_INTEL_WHL_ID_Wx2, "Whiskeylake W (2+2)" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080054 { PCI_DEVICE_ID_INTEL_CFL_ID_H, "Coffeelake-H" },
55 { PCI_DEVICE_ID_INTEL_CFL_ID_S, "Coffeelake-S" },
Andrey Petrova00e1042017-06-05 13:22:59 -070056};
57
58static struct {
Subrata Banikec10fbb2017-12-07 11:48:48 +053059 u16 lpcid;
60 const char *name;
61} pch_table[] = {
62 { PCI_DEVICE_ID_INTEL_CNL_BASE_U_LPC, "Cannonlake-U Base" },
63 { PCI_DEVICE_ID_INTEL_CNL_U_PREMIUM_LPC, "Cannonlake-U Premium" },
64 { PCI_DEVICE_ID_INTEL_CNL_Y_PREMIUM_LPC, "Cannonlake-Y Premium" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080065 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_Q370, "Cannonlake-H Q370" },
66 { PCI_DEVICE_ID_INTEL_CNP_H_LPC_QM370, "Cannonlake-H QM370" },
Subrata Banikec10fbb2017-12-07 11:48:48 +053067};
68
69static struct {
Andrey Petrova00e1042017-06-05 13:22:59 -070070 u16 igdid;
71 const char *name;
72} igd_table[] = {
73 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_1, "Cannonlake ULX GT2" },
74 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_2, "Cannonlake ULX GT1.5" },
75 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_3, "Cannonlake ULX GT1" },
76 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_4, "Cannonlake ULX GT0.5" },
77 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_1, "Cannonlake ULT GT2" },
78 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_2, "Cannonlake ULT GT1.5" },
79 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_3, "Cannonlake ULT GT1" },
80 { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_4, "Cannonlake ULT GT0.5" },
Subrata Banikd1dfba42019-02-21 17:01:21 +053081 { PCI_DEVICE_ID_INTEL_CFL_GT2_ULT, "Coffeelake ULT GT2" },
82 { PCI_DEVICE_ID_INTEL_WHL_GT2_ULT_1, "Whiskeylake ULT GT1" },
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +080083 { PCI_DEVICE_ID_INTEL_CFL_H_GT2, "Coffeelake-H GT2" },
84 { PCI_DEVICE_ID_INTEL_CFL_S_GT2, "Coffeelake-S GT2" },
Andrey Petrova00e1042017-06-05 13:22:59 -070085};
86
Elyes HAOUASc8a649c2018-06-10 23:36:44 +020087static uint8_t get_dev_revision(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +053088{
89 return pci_read_config8(dev, PCI_REVISION_ID);
90}
91
Elyes HAOUASc8a649c2018-06-10 23:36:44 +020092static uint16_t get_dev_id(pci_devfn_t dev)
Subrata Banikec10fbb2017-12-07 11:48:48 +053093{
94 return pci_read_config16(dev, PCI_DEVICE_ID);
95}
96
Andrey Petrova00e1042017-06-05 13:22:59 -070097static void report_cpu_info(void)
98{
99 struct cpuid_result cpuidr;
Subrata Banik53b08c32018-12-10 14:11:35 +0530100 u32 i, index, cpu_id, cpu_feature_flag;
Andrey Petrova00e1042017-06-05 13:22:59 -0700101 char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
102 int vt, txt, aes;
103 msr_t microcode_ver;
Elyes HAOUAS39303d52018-07-08 12:40:45 +0200104 static const char *const mode[] = {"NOT ", ""};
Andrey Petrova00e1042017-06-05 13:22:59 -0700105 const char *cpu_type = "Unknown";
Martin Roth3f6421e2017-07-21 09:17:58 -0600106 u32 p[13];
Andrey Petrova00e1042017-06-05 13:22:59 -0700107
108 index = 0x80000000;
109 cpuidr = cpuid(index);
110 if (cpuidr.eax < 0x80000004) {
111 strcpy(cpu_string, "Platform info not available");
112 } else {
Andrey Petrova00e1042017-06-05 13:22:59 -0700113 int j=0;
114
115 for (i = 2; i <= 4; i++) {
116 cpuidr = cpuid(index + i);
117 p[j++] = cpuidr.eax;
118 p[j++] = cpuidr.ebx;
119 p[j++] = cpuidr.ecx;
120 p[j++] = cpuidr.edx;
121 }
122 p[12]=0;
123 cpu_name = (char *)p;
124 }
125 /* Skip leading spaces in CPU name string */
126 while (cpu_name[0] == ' ')
127 cpu_name++;
128
129 microcode_ver.lo = 0;
130 microcode_ver.hi = 0;
131 wrmsr(BIOS_SIGN_ID, microcode_ver);
Subrata Banik53b08c32018-12-10 14:11:35 +0530132 cpu_id = cpu_get_cpuid();
Andrey Petrova00e1042017-06-05 13:22:59 -0700133 microcode_ver = rdmsr(BIOS_SIGN_ID);
134
135 /* Look for string to match the name */
136 for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
Subrata Banik53b08c32018-12-10 14:11:35 +0530137 if (cpu_table[i].cpuid == cpu_id) {
Andrey Petrova00e1042017-06-05 13:22:59 -0700138 cpu_type = cpu_table[i].name;
139 break;
140 }
141 }
142
143 printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
144 printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
Subrata Banik53b08c32018-12-10 14:11:35 +0530145 cpu_id, cpu_type, microcode_ver.hi);
Andrey Petrova00e1042017-06-05 13:22:59 -0700146
Subrata Banik53b08c32018-12-10 14:11:35 +0530147 cpu_feature_flag = cpu_get_feature_flags_ecx();
148 aes = (cpu_feature_flag & CPUID_AES) ? 1 : 0;
149 txt = (cpu_feature_flag & CPUID_SMX) ? 1 : 0;
150 vt = (cpu_feature_flag & CPUID_VMX) ? 1 : 0;
Andrey Petrova00e1042017-06-05 13:22:59 -0700151 printk(BIOS_DEBUG,
152 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
153 mode[aes], mode[txt], mode[vt]);
154}
155
156static void report_mch_info(void)
157{
158 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200159 pci_devfn_t dev = SA_DEV_ROOT;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530160 uint16_t mchid = get_dev_id(dev);
161 uint8_t mch_revision = get_dev_revision(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700162 const char *mch_type = "Unknown";
163
164 for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
165 if (mch_table[i].mchid == mchid) {
166 mch_type = mch_table[i].name;
167 break;
168 }
169 }
170
171 printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530172 mchid, mch_revision, mch_type);
173}
174
175static void report_pch_info(void)
176{
177 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200178 pci_devfn_t dev = PCH_DEV_LPC;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530179 uint16_t lpcid = get_dev_id(dev);
180 const char *pch_type = "Unknown";
181
182 for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
183 if (pch_table[i].lpcid == lpcid) {
184 pch_type = pch_table[i].name;
185 break;
186 }
187 }
188 printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
189 lpcid, get_dev_revision(dev), pch_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700190}
191
192static void report_igd_info(void)
193{
194 int i;
Elyes HAOUASc8a649c2018-06-10 23:36:44 +0200195 pci_devfn_t dev = SA_DEV_IGD;
Subrata Banikec10fbb2017-12-07 11:48:48 +0530196 uint16_t igdid = get_dev_id(dev);
Andrey Petrova00e1042017-06-05 13:22:59 -0700197 const char *igd_type = "Unknown";
198
199 for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
200 if (igd_table[i].igdid == igdid) {
201 igd_type = igd_table[i].name;
202 break;
203 }
204 }
205 printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
Subrata Banikec10fbb2017-12-07 11:48:48 +0530206 igdid, get_dev_revision(dev), igd_type);
Andrey Petrova00e1042017-06-05 13:22:59 -0700207}
208
209void report_platform_info(void)
210{
211 report_cpu_info();
212 report_mch_info();
Subrata Banikec10fbb2017-12-07 11:48:48 +0530213 report_pch_info();
Andrey Petrova00e1042017-06-05 13:22:59 -0700214 report_igd_info();
215}