blob: c1a0b97cb2adb265544b2cee3c9dcc7bc450addb [file] [log] [blame]
Rizwan Qureshi1222a732016-08-23 14:31:23 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2016 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
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053016#include <arch/cpu.h>
17#include <arch/early_variables.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053018#include <arch/symbols.h>
19#include <assert.h>
20#include <cpu/x86/mtrr.h>
Naresh G Solanki79239b72016-11-16 21:34:41 +053021#include <cpu/x86/msr.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053022#include <cbmem.h>
23#include <chip.h>
Rizwan Qureshi1222a732016-08-23 14:31:23 +053024#include <console/console.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053025#include <device/pci_def.h>
Rizwan Qureshi1222a732016-08-23 14:31:23 +053026#include <fsp/util.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053027#include <fsp/memmap.h>
Shaunak Sahad3476802017-07-08 01:08:40 -070028#include <intelblocks/pmclib.h>
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053029#include <memory_info.h>
Barnali Sarkarf7f01f72018-01-11 16:40:54 +053030#include <smbios.h>
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053031#include <soc/intel/common/smbios.h>
Naresh G Solanki79239b72016-11-16 21:34:41 +053032#include <soc/msr.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053033#include <soc/pci_devs.h>
34#include <soc/pm.h>
Rizwan Qureshi1222a732016-08-23 14:31:23 +053035#include <soc/romstage.h>
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053036#include <string.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053037#include <timestamp.h>
Philipp Deppenwiesefea24292017-10-17 17:02:29 +020038#include <security/vboot/vboot_common.h>
Barnali Sarkar5bf42c62016-08-24 20:48:46 +053039
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053040#define FSP_SMBIOS_MEMORY_INFO_GUID \
41{ \
42 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \
43 0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \
44}
45
Subrata Banik54fa28e2018-02-07 14:59:34 +053046/* Memory Channel Present Status */
47enum {
48 CHANNEL_NOT_PRESENT,
49 CHANNEL_DISABLED,
50 CHANNEL_PRESENT
51};
52
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053053/* Save the DIMM information for SMBIOS table 17 */
54static void save_dimm_info(void)
55{
56 int channel, dimm, dimm_max, index;
57 size_t hob_size;
Barnali Sarkarf7f01f72018-01-11 16:40:54 +053058 uint8_t ddr_type;
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053059 const CONTROLLER_INFO *ctrlr_info;
60 const CHANNEL_INFO *channel_info;
61 const DIMM_INFO *src_dimm;
62 struct dimm_info *dest_dimm;
63 struct memory_info *mem_info;
64 const MEMORY_INFO_DATA_HOB *memory_info_hob;
Subrata Banik54fa28e2018-02-07 14:59:34 +053065 const uint8_t smbios_memory_info_guid[16] =
66 FSP_SMBIOS_MEMORY_INFO_GUID;
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053067
68 /* Locate the memory info HOB, presence validated by raminit */
69 memory_info_hob =
70 fsp_find_extension_hob_by_guid(smbios_memory_info_guid,
71 &hob_size);
Subrata Banik54fa28e2018-02-07 14:59:34 +053072 if (memory_info_hob == NULL || hob_size == 0) {
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053073 printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n");
74 return;
75 }
76
77 /*
78 * Allocate CBMEM area for DIMM information used to populate SMBIOS
79 * table 17
80 */
81 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
82 if (mem_info == NULL) {
83 printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
84 return;
85 }
86 memset(mem_info, 0, sizeof(*mem_info));
87
88 /* Describe the first N DIMMs in the system */
89 index = 0;
90 dimm_max = ARRAY_SIZE(mem_info->dimm);
91 ctrlr_info = &memory_info_hob->Controller[0];
Nico Huber9dc62ea2017-07-19 15:45:14 +020092 for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) {
Balaji Manigandan Bbd55c022017-09-22 14:27:56 +053093 channel_info = &ctrlr_info->ChannelInfo[channel];
Subrata Banik54fa28e2018-02-07 14:59:34 +053094 if (channel_info->Status != CHANNEL_PRESENT)
Nico Huber9dc62ea2017-07-19 15:45:14 +020095 continue;
96 for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) {
Balaji Manigandan Bbd55c022017-09-22 14:27:56 +053097 src_dimm = &channel_info->DimmInfo[dimm];
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +053098 dest_dimm = &mem_info->dimm[index];
99
Nico Huber9dc62ea2017-07-19 15:45:14 +0200100 if (src_dimm->Status != DIMM_PRESENT)
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +0530101 continue;
102
Elyes HAOUAS0ce41f12018-11-13 10:03:31 +0100103 switch (memory_info_hob->MemoryType) {
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530104 case MRC_DDR_TYPE_DDR4:
Elyes HAOUAS28114ae2018-11-14 17:51:00 +0100105 ddr_type = MEMORY_TYPE_DDR4;
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530106 break;
107 case MRC_DDR_TYPE_DDR3:
Elyes HAOUAS28114ae2018-11-14 17:51:00 +0100108 ddr_type = MEMORY_TYPE_DDR3;
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530109 break;
110 case MRC_DDR_TYPE_LPDDR3:
Elyes HAOUAS28114ae2018-11-14 17:51:00 +0100111 ddr_type = MEMORY_TYPE_LPDDR3;
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530112 break;
113 default:
Elyes HAOUAS28114ae2018-11-14 17:51:00 +0100114 ddr_type = MEMORY_TYPE_UNKNOWN;
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530115 break;
116 }
117
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +0530118 /* Populate the DIMM information */
119 dimm_info_fill(dest_dimm,
120 src_dimm->DimmCapacity,
Barnali Sarkarf7f01f72018-01-11 16:40:54 +0530121 ddr_type,
Balaji Manigandan Bbd55c022017-09-22 14:27:56 +0530122 memory_info_hob->ConfiguredMemoryClockSpeed,
Francois Toguo993f68a2019-02-04 17:05:51 -0800123 src_dimm->RankInDimm,
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +0530124 channel_info->ChannelId,
125 src_dimm->DimmId,
126 (const char *)src_dimm->ModulePartNum,
127 sizeof(src_dimm->ModulePartNum),
128 memory_info_hob->DataWidth);
129 index++;
130 }
131 }
132 mem_info->dimm_cnt = index;
133 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
134}
135
Aaron Durbin79f07412017-04-16 21:49:29 -0500136asmlinkage void car_stage_entry(void)
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530137{
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530138 bool s3wake;
139 struct postcar_frame pcf;
140 uintptr_t top_of_ram;
141 struct chipset_power_state *ps;
142
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530143 console_init();
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530144
145 /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
146 systemagent_early_init();
147
Shaunak Sahad3476802017-07-08 01:08:40 -0700148 ps = pmc_get_power_state();
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530149 timestamp_add_now(TS_START_ROMSTAGE);
Shaunak Sahad3476802017-07-08 01:08:40 -0700150 s3wake = pmc_fill_power_state(ps) == ACPI_S3;
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530151 fsp_memory_init(s3wake);
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530152 pmc_set_disb();
Barnali Sarkarb7fa7fb2017-02-10 21:36:58 +0530153 if (!s3wake)
154 save_dimm_info();
Aaron Durbin4dc9fb02017-07-11 17:29:02 -0600155 if (postcar_frame_init(&pcf, 1*KiB))
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530156 die("Unable to initialize postcar frame.\n");
157
158 /*
159 * We need to make sure ramstage will be run cached. At this
160 * point exact location of ramstage in cbmem is not known.
161 * Instruct postcar to cache 16 megs under cbmem top which is
162 * a safe bet to cover ramstage.
163 */
164 top_of_ram = (uintptr_t) cbmem_top();
165 printk(BIOS_DEBUG, "top_of_ram = 0x%lx\n", top_of_ram);
166 top_of_ram -= 16*MiB;
167 postcar_frame_add_mtrr(&pcf, top_of_ram, 16*MiB, MTRR_TYPE_WRBACK);
168
169 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
170 void *smm_base;
171 size_t smm_size;
172 uintptr_t tseg_base;
173
174 /*
175 * Cache the TSEG region at the top of ram. This region is
176 * not restricted to SMM mode until SMM has been relocated.
177 * By setting the region to cacheable it provides faster access
178 * when relocating the SMM handler as well as using the TSEG
179 * region for other purposes.
180 */
181 smm_region(&smm_base, &smm_size);
182 tseg_base = (uintptr_t)smm_base;
183 postcar_frame_add_mtrr(&pcf, tseg_base, smm_size,
184 MTRR_TYPE_WRBACK);
185 }
186
187 /* Cache the ROM as WP just below 4GiB. */
Nico Huber6ea67752018-05-27 14:37:52 +0200188 postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530189
Aaron Durbin79f07412017-04-16 21:49:29 -0500190 run_postcar_phase(&pcf);
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530191}
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530192
Naresh G Solanki79239b72016-11-16 21:34:41 +0530193static void cpu_flex_override(FSP_M_CONFIG *m_cfg)
194{
195 msr_t flex_ratio;
196 m_cfg->CpuRatioOverride = 1;
197 /*
198 * Set cpuratio to that value set in bootblock, This will ensure FSPM
199 * knows the intended flex ratio.
200 */
201 flex_ratio = rdmsr(MSR_FLEX_RATIO);
202 m_cfg->CpuRatio = (flex_ratio.lo >> 8) & 0xff;
203}
204
Aamir Bohra63755122017-02-06 21:48:48 +0530205static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
206 const struct soc_intel_skylake_config *config)
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530207{
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530208 int i;
209 uint32_t mask = 0;
210
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530211 /*
212 * Set IGD stolen size to 64MB. The FBC hardware for skylake does not
213 * have access to the bios_reserved range so it always assumes 8MB is
214 * used and so the kernel will avoid the last 8MB of the stolen window.
215 * With the default stolen size of 32MB(-8MB) there is not enough space
216 * for FBC to work with a high resolution panel.
217 */
218 m_cfg->IgdDvmt50PreAlloc = 2;
219 m_cfg->MmioSize = 0x800; /* 2GB in MB */
220 m_cfg->TsegSize = CONFIG_SMM_TSEG_SIZE;
221 m_cfg->IedSize = CONFIG_IED_REGION_SIZE;
222 m_cfg->ProbelessTrace = config->ProbelessTrace;
Subrata Banik3214bc42017-07-10 13:17:09 +0530223 m_cfg->SaGv = config->SaGv;
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530224 m_cfg->UserBd = BOARD_TYPE_ULT_ULX;
225 m_cfg->RMT = config->Rmt;
Shaunak Sahaef250c42018-08-31 12:49:08 -0700226 m_cfg->CmdTriStateDis = config->CmdTriStateDis;
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530227 m_cfg->DdrFreqLimit = config->DdrFreqLimit;
Nico Huber6275e342018-11-21 00:11:35 +0100228 m_cfg->VmxEnable = IS_ENABLED(CONFIG_ENABLE_VMX);
Robbie Zhange65affa2017-02-13 12:07:53 -0800229 m_cfg->PrmrrSize = config->PrmrrSize;
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530230 for (i = 0; i < ARRAY_SIZE(config->PcieRpEnable); i++) {
231 if (config->PcieRpEnable[i])
232 mask |= (1<<i);
233 }
234 m_cfg->PcieRpEnableMask = mask;
Naresh G Solanki79239b72016-11-16 21:34:41 +0530235
236 cpu_flex_override(m_cfg);
Nico Huber2afe4dc2017-09-19 09:36:03 +0200237
238 if (!config->ignore_vtd) {
239 m_cfg->PchHpetBdfValid = 1;
240 m_cfg->PchHpetBusNumber = 250;
241 m_cfg->PchHpetDeviceNumber = 15;
242 m_cfg->PchHpetFunctionNumber = 0;
243 }
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530244}
245
Andrey Petrovf796c6e2016-11-18 14:57:51 -0800246void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530247{
Aamir Bohra63755122017-02-06 21:48:48 +0530248 const struct device *dev;
249 const struct soc_intel_skylake_config *config;
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530250 FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
251 FSP_M_TEST_CONFIG *m_t_cfg = &mupd->FspmTestConfig;
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530252
Aamir Bohra63755122017-02-06 21:48:48 +0530253 dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
254 config = dev->chip_info;
255
256 soc_memory_init_params(m_cfg, config);
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530257
Duncan Lauriee0b57952017-08-10 16:27:48 -0700258 /* Skip creating Management Engine MBP HOB */
259 m_t_cfg->SkipMbpHob = 0x01;
260
Barnali Sarkar5bf42c62016-08-24 20:48:46 +0530261 /* Enable DMI Virtual Channel for ME */
262 m_t_cfg->DmiVcm = 0x01;
263
264 /* Enable Sending DID to ME */
265 m_t_cfg->SendDidMsg = 0x01;
266 m_t_cfg->DidInitStat = 0x01;
267
Aamir Bohra63755122017-02-06 21:48:48 +0530268 /* DCI and TraceHub configs */
269 m_t_cfg->PchDciEn = config->PchDciEn;
270 m_cfg->EnableTraceHub = config->EnableTraceHub;
271 m_cfg->TraceHubMemReg0Size = config->TraceHubMemReg0Size;
272 m_cfg->TraceHubMemReg1Size = config->TraceHubMemReg1Size;
273
Naresh G Solankiff48b3b2017-07-12 23:01:26 +0530274 /* Enable SMBus controller based on config */
275 m_cfg->SmbusEnable = config->SmbusEnable;
276
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530277 mainboard_memory_init_params(mupd);
278}
279
Pratik Prajapatiffc934d2016-11-18 14:36:34 -0800280void soc_update_memory_params_for_mma(FSP_M_CONFIG *memory_cfg,
281 struct mma_config_param *mma_cfg)
282{
283 /* Boot media is memory mapped for Skylake and Kabylake (SPI). */
284 assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED));
285
286 memory_cfg->MmaTestContentPtr =
287 (uintptr_t) rdev_mmap_full(&mma_cfg->test_content);
288 memory_cfg->MmaTestContentSize =
289 region_device_sz(&mma_cfg->test_content);
290 memory_cfg->MmaTestConfigPtr =
291 (uintptr_t) rdev_mmap_full(&mma_cfg->test_param);
292 memory_cfg->MmaTestConfigSize =
293 region_device_sz(&mma_cfg->test_param);
294 memory_cfg->MrcFastBoot = 0x00;
295 memory_cfg->SaGv = 0x02;
296}
297
Aaron Durbin64031672018-04-21 14:45:32 -0600298__weak void mainboard_memory_init_params(FSPM_UPD *mupd)
Rizwan Qureshi1222a732016-08-23 14:31:23 +0530299{
300 /* Do nothing */
301}