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.
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>
27 #include <soc/pci_devs.h>
28 #include <soc/systemagent.h>
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" },
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" },
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" },
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
;
101 char cpu_string
[50], *cpu_name
= cpu_string
; /* 48 bytes are reported */
104 static const char * const mode
[] = {"NOT ", ""};
105 const char *cpu_type
= "Unknown";
108 cpuidr
= cpuid(index
);
109 if (cpuidr
.eax
< 0x80000004) {
110 strcpy(cpu_string
, "Platform info not available");
112 u32
*p
= (u32
*) cpu_string
;
113 for (i
= 2; i
<= 4; i
++) {
114 cpuidr
= cpuid(index
+ i
);
121 /* Skip leading spaces in CPU name string */
122 while (cpu_name
[0] == ' ')
125 microcode_ver
.lo
= 0;
126 microcode_ver
.hi
= 0;
127 wrmsr(0x8B, microcode_ver
);
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
;
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;
147 "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n",
148 mode
[aes
], mode
[txt
], mode
[vt
]);
151 static void report_mch_info(void)
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
;
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)
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
;
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)
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
;
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)
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];
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",
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" : "");