soc/intel/skylake: Use CPU MP Init Common code
[coreboot.git] / src / soc / intel / skylake / bootblock / report_platform.c
blobe7fbb8a08faa72b0550430e7a563fe0d99483666
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Google Inc.
5 * Copyright (C) 2015 Intel Corporation.
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.
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.
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>
23 #include <intelblocks/mp_init.h>
24 #include <soc/bootblock.h>
25 #include <soc/cpu.h>
26 #include <soc/pch.h>
27 #include <soc/pci_devs.h>
28 #include <soc/systemagent.h>
29 #include <string.h>
31 static struct {
32 u32 cpuid;
33 const char *name;
34 } cpu_table[] = {
35 { CPUID_SKYLAKE_C0, "Skylake C0" },
36 { CPUID_SKYLAKE_D0, "Skylake D0" },
37 { CPUID_SKYLAKE_HQ0, "Skylake H Q0" },
38 { CPUID_SKYLAKE_HR0, "Skylake H R0" },
39 { CPUID_KABYLAKE_G0, "Kabylake G0" },
40 { CPUID_KABYLAKE_H0, "Kabylake H0" },
41 { CPUID_KABYLAKE_Y0, "Kabylake Y0" },
42 { CPUID_KABYLAKE_HA0, "Kabylake H A0" },
43 { CPUID_KABYLAKE_HB0, "Kabylake H B0" },
46 static struct {
47 u16 mchid;
48 const char *name;
49 } mch_table[] = {
50 { PCI_DEVICE_ID_INTEL_SKL_ID_U, "Skylake-U" },
51 { PCI_DEVICE_ID_INTEL_SKL_ID_Y, "Skylake-Y" },
52 { PCI_DEVICE_ID_INTEL_SKL_ID_ULX, "Skylake-ULX" },
53 { PCI_DEVICE_ID_INTEL_SKL_ID_H, "Skylake-H" },
54 { PCI_DEVICE_ID_INTEL_SKL_ID_H_EM, "Skylake-H Embedded" },
55 { PCI_DEVICE_ID_INTEL_KBL_ID_U, "Kabylake-U" },
56 { PCI_DEVICE_ID_INTEL_KBL_U_R, "Kabylake-R ULT"},
57 { PCI_DEVICE_ID_INTEL_KBL_ID_Y, "Kabylake-Y" },
58 { PCI_DEVICE_ID_INTEL_KBL_ID_H, "Kabylake-H" },
61 static struct {
62 u16 lpcid;
63 const char *name;
64 } pch_table[] = {
65 { PCI_DEVICE_ID_INTEL_SPT_LP_SAMPLE, "Skylake LP Sample" },
66 { PCI_DEVICE_ID_INTEL_SPT_LP_U_BASE, "Skylake-U Base" },
67 { PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM, "Skylake-U Premium" },
68 { PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM, "Skylake-Y Premium" },
69 { PCI_DEVICE_ID_INTEL_KBP_H_PREMIUM, "Kabylake-H Premium" },
70 { PCI_DEVICE_ID_INTEL_KBP_H_C236, "Kabylake-H C236" },
71 { PCI_DEVICE_ID_INTEL_KBP_H_QM170, "Kabylake-H QM170" },
72 { PCI_DEVICE_ID_INTEL_KBP_LP_U_PREMIUM, "Kabylake-U Premium" },
73 { PCI_DEVICE_ID_INTEL_KBP_LP_Y_PREMIUM, "Kabylake-Y Premium" },
74 { PCI_DEVICE_ID_INTEL_KBP_LP_SUPER_SKU, "Kabylake Super Sku" },
75 { PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM_HDCP22,
76 "Kabylake-Y iHDCP 2.2 Premium" },
77 { PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM_HDCP22,
78 "Kabylake-U iHDCP 2.2 Premium" },
81 static struct {
82 u16 igdid;
83 const char *name;
84 } igd_table[] = {
85 { PCI_DEVICE_ID_INTEL_SKL_GT1_SULTM, "Skylake ULT GT1"},
86 { PCI_DEVICE_ID_INTEL_SKL_GT2_SULXM, "Skylake ULX GT2" },
87 { PCI_DEVICE_ID_INTEL_SKL_GT2_SULTM, "Skylake ULT GT2" },
88 { PCI_DEVICE_ID_INTEL_SKL_GT2_SHALM, "Skylake HALO GT2" },
89 { PCI_DEVICE_ID_INTEL_SKL_GT4_SHALM, "Skylake HALO GT4" },
90 { PCI_DEVICE_ID_INTEL_KBL_GT1_SULTM, "Kabylake ULT GT1"},
91 { PCI_DEVICE_ID_INTEL_KBL_GT2_SULXM, "Kabylake ULX GT2" },
92 { PCI_DEVICE_ID_INTEL_KBL_GT2_SULTM, "Kabylake ULT GT2" },
93 { PCI_DEVICE_ID_INTEL_KBL_GT2_SULTMR, "Kabylake-R ULT GT2"},
94 { PCI_DEVICE_ID_INTEL_KBL_GT2_SHALM, "Kabylake HALO GT2" },
97 static void report_cpu_info(void)
99 struct cpuid_result cpuidr;
100 u32 i, index;
101 char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */
102 int vt, txt, aes;
103 msr_t microcode_ver;
104 static const char * const mode[] = {"NOT ", ""};
105 const char *cpu_type = "Unknown";
107 index = 0x80000000;
108 cpuidr = cpuid(index);
109 if (cpuidr.eax < 0x80000004) {
110 strcpy(cpu_string, "Platform info not available");
111 } else {
112 u32 *p = (u32 *) cpu_string;
113 for (i = 2; i <= 4; i++) {
114 cpuidr = cpuid(index + i);
115 *p++ = cpuidr.eax;
116 *p++ = cpuidr.ebx;
117 *p++ = cpuidr.ecx;
118 *p++ = cpuidr.edx;
121 /* Skip leading spaces in CPU name string */
122 while (cpu_name[0] == ' ')
123 cpu_name++;
125 microcode_ver.lo = 0;
126 microcode_ver.hi = 0;
127 wrmsr(0x8B, microcode_ver);
128 cpuidr = cpuid(1);
129 microcode_ver = rdmsr(0x8b);
131 /* Look for string to match the name */
132 for (i = 0; i < ARRAY_SIZE(cpu_table); i++) {
133 if (cpu_table[i].cpuid == cpuidr.eax) {
134 cpu_type = cpu_table[i].name;
135 break;
139 printk(BIOS_DEBUG, "CPU: %s\n", cpu_name);
140 printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n",
141 cpuidr.eax, cpu_type, microcode_ver.hi);
143 aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
144 txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
145 vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
146 printk(BIOS_DEBUG,
147 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
148 mode[aes], mode[txt], mode[vt]);
151 static void report_mch_info(void)
153 int i;
154 u16 mchid = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID);
155 u8 mch_revision = pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID);
156 const char *mch_type = "Unknown";
158 for (i = 0; i < ARRAY_SIZE(mch_table); i++) {
159 if (mch_table[i].mchid == mchid) {
160 mch_type = mch_table[i].name;
161 break;
165 printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n",
166 mchid, mch_revision, mch_type);
169 static void report_pch_info(void)
171 int i;
172 u16 lpcid = pch_type();
173 const char *pch_type = "Unknown";
175 for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
176 if (pch_table[i].lpcid == lpcid) {
177 pch_type = pch_table[i].name;
178 break;
181 printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n",
182 lpcid, pch_revision(), pch_type);
185 static void report_igd_info(void)
187 int i;
188 u16 igdid = pci_read_config16(SA_DEV_IGD, PCI_DEVICE_ID);
189 const char *igd_type = "Unknown";
191 for (i = 0; i < ARRAY_SIZE(igd_table); i++) {
192 if (igd_table[i].igdid == igdid) {
193 igd_type = igd_table[i].name;
194 break;
197 printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n",
198 igdid, pci_read_config8(SA_DEV_IGD, PCI_REVISION_ID), igd_type);
201 void report_platform_info(void)
203 report_cpu_info();
204 report_mch_info();
205 report_pch_info();
206 report_igd_info();
210 * Dump in the log memory controller configuration as read from the memory
211 * controller registers.
213 void report_memory_config(void)
215 u32 addr_decoder_common, addr_decode_ch[2];
216 int i;
218 addr_decoder_common = MCHBAR32(0x5000);
219 addr_decode_ch[0] = MCHBAR32(0x5004);
220 addr_decode_ch[1] = MCHBAR32(0x5008);
222 printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
223 (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
224 printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
225 addr_decoder_common & 3,
226 (addr_decoder_common >> 2) & 3,
227 (addr_decoder_common >> 4) & 3);
229 for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
230 u32 ch_conf = addr_decode_ch[i];
231 printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
232 i, ch_conf);
233 printk(BIOS_DEBUG, " enhanced interleave mode %s\n",
234 ((ch_conf >> 22) & 1) ? "on" : "off");
235 printk(BIOS_DEBUG, " rank interleave %s\n",
236 ((ch_conf >> 21) & 1) ? "on" : "off");
237 printk(BIOS_DEBUG, " DIMMA %d MB width %s %s rank%s\n",
238 ((ch_conf >> 0) & 0xff) * 256,
239 ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
240 ((ch_conf >> 17) & 1) ? "dual" : "single",
241 ((ch_conf >> 16) & 1) ? "" : ", selected");
242 printk(BIOS_DEBUG, " DIMMB %d MB width %s %s rank%s\n",
243 ((ch_conf >> 8) & 0xff) * 256,
244 ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
245 ((ch_conf >> 18) & 1) ? "dual" : "single",
246 ((ch_conf >> 16) & 1) ? ", selected" : "");