blob: a9eef40756da2fba8622153c1929000fbd861c3d [file] [log] [blame]
Aamir Bohra3ee54bb2018-10-17 11:55:01 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2018 Intel Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <arch/cpu.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020017#include <device/pci_ops.h>
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053018#include <console/console.h>
19#include <cpu/x86/msr.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
22#include <intelblocks/mp_init.h>
23#include <soc/bootblock.h>
24#include <soc/pch.h>
25#include <soc/pci_devs.h>
26#include <string.h>
27
28#define BIOS_SIGN_ID 0x8B
29
30static struct {
31 u32 cpuid;
32 const char *name;
33} cpu_table[] = {
Aamir Bohra9eac0392018-06-30 12:07:04 +053034 { CPUID_ICELAKE_A0, "Icelake A0" },
35 { CPUID_ICELAKE_B0, "Icelake B0" },
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053036};
37
38static struct {
39 u16 mchid;
40 const char *name;
41} mch_table[] = {
Aamir Bohra9eac0392018-06-30 12:07:04 +053042 { PCI_DEVICE_ID_INTEL_ICL_ID_U, "Icelake-U" },
43 { PCI_DEVICE_ID_INTEL_ICL_ID_U_2_2, "Icelake-U-2-2" },
44 { PCI_DEVICE_ID_INTEL_ICL_ID_Y, "Icelake-Y" },
45 { PCI_DEVICE_ID_INTEL_ICL_ID_Y_2, "Icelake-Y-2" },
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053046};
47
48static struct {
Subrata Banik3d152ac2018-10-31 23:08:14 +053049 u16 espiid;
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053050 const char *name;
51} pch_table[] = {
Subrata Banik3d152ac2018-10-31 23:08:14 +053052 { PCI_DEVICE_ID_INTEL_ICL_BASE_U_ESPI, "Icelake-U Base" },
53 { PCI_DEVICE_ID_INTEL_ICL_BASE_Y_ESPI, "Icelake-Y Base" },
54 { PCI_DEVICE_ID_INTEL_ICL_U_PREMIUM_ESPI, "Icelake-U Premium" },
55 { PCI_DEVICE_ID_INTEL_ICL_U_SUPER_U_ESPI, "Icelake-U Super" },
56 { PCI_DEVICE_ID_INTEL_ICL_U_SUPER_U_ESPI_REV0, "Icelake-U Super REV0" },
57 { PCI_DEVICE_ID_INTEL_ICL_SUPER_Y_ESPI, "Icelake-Y Super" },
58 { PCI_DEVICE_ID_INTEL_ICL_Y_PREMIUM_ESPI, "Icelake-Y Premium" },
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053059};
60
61static struct {
62 u16 igdid;
63 const char *name;
64} igd_table[] = {
Aamir Bohra9eac0392018-06-30 12:07:04 +053065 { PCI_DEVICE_ID_INTEL_ICL_GT0_ULT, "Icelake ULT GT0" },
66 { PCI_DEVICE_ID_INTEL_ICL_GT0_5_ULT, "Icelake ULT GT0.5" },
67 { PCI_DEVICE_ID_INTEL_ICL_GT1_ULT, "Icelake U GT1" },
68 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_0, "Icelake Y GT2" },
69 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_1, "Icelake Y GT2_1" },
70 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULT_1, "Icelake U GT2_1" },
71 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_2, "Icelake Y GT2_2" },
72 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULT_2, "Icelake U GT2_2" },
73 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_3, "Icelake Y GT2_3" },
74 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULT_3, "Icelake U GT2_3" },
75 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_4, "Icelake Y GT2_4" },
76 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULT_4, "Icelake U GT2_4" },
77 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULX_5, "Icelake Y GT2_5" },
78 { PCI_DEVICE_ID_INTEL_ICL_GT2_ULT_5, "Icelake U GT2_5" },
79 { PCI_DEVICE_ID_INTEL_ICL_GT3_ULT, "Icelake U GT3" },
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053080};
81
82static uint8_t get_dev_revision(pci_devfn_t dev)
83{
84 return pci_read_config8(dev, PCI_REVISION_ID);
85}
86
87static uint16_t get_dev_id(pci_devfn_t dev)
88{
89 return pci_read_config16(dev, PCI_DEVICE_ID);
90}
91
92static void report_cpu_info(void)
93{
94 struct cpuid_result cpuidr;
Subrata Banik53b08c32018-12-10 14:11:35 +053095 u32 i, index, cpu_id, cpu_feature_flag;
Aamir Bohra3ee54bb2018-10-17 11:55:01 +053096 char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
97 int vt, txt, aes;
98 msr_t microcode_ver;
99 static const char *const mode[] = {"NOT ", ""};
100 const char *cpu_type = "Unknown";
101 u32 p[13];
102
103 index = 0x80000000;
104 cpuidr = cpuid(index);
105 if (cpuidr.eax < 0x80000004) {
106 strcpy(cpu_string, "Platform info not available");
107 } else {
108 int j = 0;
109
110 for (i = 2; i <= 4; i++) {
111 cpuidr = cpuid(index + i);
112 p[j++] = cpuidr.eax;
113 p[j++] = cpuidr.ebx;
114 p[j++] = cpuidr.ecx;
115 p[j++] = cpuidr.edx;
116 }
117 p[12] = 0;
118 cpu_name = (char *)p;
119 }
120 /* Skip leading spaces in CPU name string */
121 while (cpu_name[0] == ' ')
122 cpu_name++;
123
124 microcode_ver.lo = 0;
125 microcode_ver.hi = 0;
126 wrmsr(BIOS_SIGN_ID, microcode_ver);
Subrata Banik53b08c32018-12-10 14:11:35 +0530127 cpu_id = cpu_get_cpuid();
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530128 microcode_ver = rdmsr(BIOS_SIGN_ID);
129
130 /* Look for string to match the name */
131 for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
Subrata Banik53b08c32018-12-10 14:11:35 +0530132 if (cpu_table[i].cpuid == cpu_id) {
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530133 cpu_type = cpu_table[i].name;
134 break;
135 }
136 }
137
138 printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
139 printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
Subrata Banik53b08c32018-12-10 14:11:35 +0530140 cpu_id, cpu_type, microcode_ver.hi);
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530141
Subrata Banik53b08c32018-12-10 14:11:35 +0530142 cpu_feature_flag = cpu_get_feature_flags_ecx();
143 aes = (cpu_feature_flag & CPUID_AES) ? 1 : 0;
144 txt = (cpu_feature_flag & CPUID_SMX) ? 1 : 0;
145 vt = (cpu_feature_flag & CPUID_VMX) ? 1 : 0;
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530146 printk(BIOS_DEBUG,
147 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
148 mode[aes], mode[txt], mode[vt]);
149}
150
151static void report_mch_info(void)
152{
153 int i;
154 pci_devfn_t dev = SA_DEV_ROOT;
155 uint16_t mchid = get_dev_id(dev);
156 uint8_t mch_revision = get_dev_revision(dev);
157 const char *mch_type = "Unknown";
158
159 for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
160 if (mch_table[i].mchid == mchid) {
161 mch_type = mch_table[i].name;
162 break;
163 }
164 }
165
166 printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
167 mchid, mch_revision, mch_type);
168}
169
170static void report_pch_info(void)
171{
172 int i;
Subrata Banik3d152ac2018-10-31 23:08:14 +0530173 pci_devfn_t dev = PCH_DEV_ESPI;
174 uint16_t espiid = get_dev_id(dev);
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530175 const char *pch_type = "Unknown";
176
177 for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
Subrata Banik3d152ac2018-10-31 23:08:14 +0530178 if (pch_table[i].espiid == espiid) {
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530179 pch_type = pch_table[i].name;
180 break;
181 }
182 }
183 printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
Subrata Banik3d152ac2018-10-31 23:08:14 +0530184 espiid, get_dev_revision(dev), pch_type);
Aamir Bohra3ee54bb2018-10-17 11:55:01 +0530185}
186
187static void report_igd_info(void)
188{
189 int i;
190 pci_devfn_t dev = SA_DEV_IGD;
191 uint16_t igdid = get_dev_id(dev);
192 const char *igd_type = "Unknown";
193
194 for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
195 if (igd_table[i].igdid == igdid) {
196 igd_type = igd_table[i].name;
197 break;
198 }
199 }
200 printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
201 igdid, get_dev_revision(dev), igd_type);
202}
203
204void report_platform_info(void)
205{
206 report_cpu_info();
207 report_mch_info();
208 report_pch_info();
209 report_igd_info();
210}