1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <console/usb.h>
8 #include <device/device.h>
9 #include <device/dram/ddr3.h>
10 #include <device/pci_ops.h>
14 #include <commonlib/bsd/ipchksum.h>
15 #include <cpu/intel/model_206ax/model_206ax.h>
16 #include <pc80/mc146818rtc.h>
17 #include <device/pci_def.h>
19 #include <mrc_cache.h>
24 #include <timestamp.h>
27 #include "sandybridge.h"
29 #include <security/vboot/vboot_common.h>
30 #include <southbridge/intel/bd82x6x/pch.h>
31 #include <memory_info.h>
32 #include <mode_switch.h>
34 /* Management Engine is in the southbridge */
35 #include <southbridge/intel/bd82x6x/me.h>
38 * MRC scrambler seed offsets should be reserved in
39 * mainboard cmos.layout and not covered by checksum.
41 #if CONFIG(USE_OPTION_TABLE)
42 #include "option_table.h"
43 #define CMOS_OFFSET_MRC_SEED (CMOS_VSTART_mrc_scrambler_seed >> 3)
44 #define CMOS_OFFSET_MRC_SEED_S3 (CMOS_VSTART_mrc_scrambler_seed_s3 >> 3)
45 #define CMOS_OFFSET_MRC_SEED_CHK (CMOS_VSTART_mrc_scrambler_seed_chk >> 3)
47 #define CMOS_OFFSET_MRC_SEED 152
48 #define CMOS_OFFSET_MRC_SEED_S3 156
49 #define CMOS_OFFSET_MRC_SEED_CHK 160
52 #define MRC_CACHE_VERSION 0
54 /* Assembly functions: */
55 void mrc_wrapper(void *func_ptr
, uint32_t arg1
);
56 void __prot2lm_do_putchar(uint8_t byte
);
58 static void save_mrc_data(struct pei_data
*pei_data
)
62 /* Save the MRC S3 restore data to cbmem */
63 mrc_cache_stash_data(MRC_TRAINING_DATA
, MRC_CACHE_VERSION
,
64 (void *)(uintptr_t)pei_data
->mrc_output_ptr
,
65 pei_data
->mrc_output_len
);
67 /* Save the MRC seed values to CMOS */
68 cmos_write32(pei_data
->scrambler_seed
, CMOS_OFFSET_MRC_SEED
);
69 printk(BIOS_DEBUG
, "Save scrambler seed 0x%08x to CMOS 0x%02x\n",
70 pei_data
->scrambler_seed
, CMOS_OFFSET_MRC_SEED
);
72 cmos_write32(pei_data
->scrambler_seed_s3
, CMOS_OFFSET_MRC_SEED_S3
);
73 printk(BIOS_DEBUG
, "Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
74 pei_data
->scrambler_seed_s3
, CMOS_OFFSET_MRC_SEED_S3
);
76 /* Save a simple checksum of the seed values */
77 c1
= ipchksum((u8
*)&pei_data
->scrambler_seed
, sizeof(u32
));
78 c2
= ipchksum((u8
*)&pei_data
->scrambler_seed_s3
, sizeof(u32
));
79 checksum
= ipchksum_add(sizeof(u32
), c1
, c2
);
81 cmos_write((checksum
>> 0) & 0xff, CMOS_OFFSET_MRC_SEED_CHK
);
82 cmos_write((checksum
>> 8) & 0xff, CMOS_OFFSET_MRC_SEED_CHK
+ 1);
85 static void prepare_mrc_cache(struct pei_data
*pei_data
)
87 u16 c1
, c2
, checksum
, seed_checksum
;
90 /* Preset just in case there is an error */
91 pei_data
->mrc_input_ptr
= 0;
92 pei_data
->mrc_input_len
= 0;
94 /* Read scrambler seeds from CMOS */
95 pei_data
->scrambler_seed
= cmos_read32(CMOS_OFFSET_MRC_SEED
);
96 printk(BIOS_DEBUG
, "Read scrambler seed 0x%08x from CMOS 0x%02x\n",
97 pei_data
->scrambler_seed
, CMOS_OFFSET_MRC_SEED
);
99 pei_data
->scrambler_seed_s3
= cmos_read32(CMOS_OFFSET_MRC_SEED_S3
);
100 printk(BIOS_DEBUG
, "Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
101 pei_data
->scrambler_seed_s3
, CMOS_OFFSET_MRC_SEED_S3
);
103 /* Compute seed checksum and compare */
104 c1
= ipchksum((u8
*)&pei_data
->scrambler_seed
, sizeof(u32
));
105 c2
= ipchksum((u8
*)&pei_data
->scrambler_seed_s3
, sizeof(u32
));
106 checksum
= ipchksum_add(sizeof(u32
), c1
, c2
);
108 seed_checksum
= cmos_read(CMOS_OFFSET_MRC_SEED_CHK
);
109 seed_checksum
|= cmos_read(CMOS_OFFSET_MRC_SEED_CHK
+ 1) << 8;
111 if (checksum
!= seed_checksum
) {
112 printk(BIOS_ERR
, "%s: invalid seed checksum\n", __func__
);
113 pei_data
->scrambler_seed
= 0;
114 pei_data
->scrambler_seed_s3
= 0;
118 pei_data
->mrc_input_ptr
= (uintptr_t)mrc_cache_current_mmap_leak(MRC_TRAINING_DATA
,
121 if (!pei_data
->mrc_input_ptr
) {
122 /* Error message printed in find_current_mrc_cache */
126 pei_data
->mrc_input_len
= mrc_size
;
128 printk(BIOS_DEBUG
, "%s: at 0x%x, size %zx\n", __func__
,
129 pei_data
->mrc_input_ptr
, mrc_size
);
133 * Find PEI executable in coreboot filesystem and execute it.
135 * @param pei_data: configuration data for UEFI PEI reference code
137 static void sdram_initialize(struct pei_data
*pei_data
)
139 int (*entry
)(struct pei_data
*pei_data
);
141 /* Wait for ME to be ready */
142 intel_early_me_init();
143 intel_early_me_uma_size();
145 printk(BIOS_DEBUG
, "Starting UEFI PEI System Agent\n");
148 * Always pass in mrc_cache data. The driver will determine
149 * whether to use the data or not.
151 prepare_mrc_cache(pei_data
);
153 /* If MRC data is not found we cannot continue S3 resume. */
154 if (pei_data
->boot_mode
== 2 && !pei_data
->mrc_input_ptr
) {
155 printk(BIOS_DEBUG
, "Giving up in %s: No MRC data\n", __func__
);
160 * Pass console handler in pei_data. On x86_64 provide a wrapper around
161 * do_putchar that switches to long mode before calling do_putchar.
164 pei_data
->tx_byte_ptr
= (uintptr_t)__prot2lm_do_putchar
;
166 pei_data
->tx_byte_ptr
= (uintptr_t)do_putchar
;
168 /* Locate and call UEFI System Agent binary. */
169 entry
= cbfs_map("mrc.bin", NULL
);
172 rv
= protected_mode_call_2arg(mrc_wrapper
, (uintptr_t)entry
, (uintptr_t)pei_data
);
176 printk(BIOS_ERR
, "PEI version mismatch.\n");
179 printk(BIOS_ERR
, "Invalid memory frequency.\n");
182 printk(BIOS_ERR
, "MRC returned %x.\n", rv
);
184 die_with_post_code(POSTCODE_INVALID_VENDOR_BINARY
,
185 "Nonzero MRC return value.\n");
188 die("UEFI PEI System Agent not found.\n");
191 /* mrc.bin reconfigures USB, so reinit it to have debug */
192 if (CONFIG(USBDEBUG_IN_PRE_RAM
))
193 usbdebug_hw_init(true);
195 /* Print the MRC version after executing the UEFI PEI stage */
196 u32 version
= mchbar_read32(MRC_REVISION
);
197 printk(BIOS_DEBUG
, "MRC Version %u.%u.%u Build %u\n",
198 (version
>> 24) & 0xff, (version
>> 16) & 0xff,
199 (version
>> 8) & 0xff, (version
>> 0) & 0xff);
202 * Send ME init done for SandyBridge here.
203 * This is done inside the SystemAgent binary on IvyBridge.
205 if (BASE_REV_SNB
== (pci_read_config16(PCI_CPU_DEVICE
, PCI_DEVICE_ID
) & BASE_REV_MASK
))
206 intel_early_me_init_done(ME_INIT_STATUS_SUCCESS
);
208 intel_early_me_status();
210 report_memory_config();
214 * These are the location and structure of MRC_VAR data in CAR.
215 * The CAR region looks like this:
216 * +------------------+ -> DCACHE_RAM_BASE
222 * +------------------+ -> DCACHE_RAM_BASE + DCACHE_RAM_SIZE
227 * +------------------+
232 * +------------------+ -> DACHE_RAM_BASE + DACHE_RAM_SIZE
233 * + DCACHE_RAM_MRC_VAR_SIZE
235 #define DCACHE_RAM_MRC_VAR_BASE (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE \
236 + CONFIG_DCACHE_RAM_MRC_VAR_SIZE - 0x4000)
238 struct mrc_var_data
{
246 static bool do_pcie_init(void)
248 if (IS_IVY_CPU(cpu_get_cpuid())) {
249 return is_devfn_enabled(PCI_DEVFN(1, 0));
255 static void devicetree_fill_pei_data(struct pei_data
*pei_data
)
257 const struct northbridge_intel_sandybridge_config
*cfg
= config_of_soc();
259 switch (cfg
->max_mem_clock_mhz
) {
260 /* MRC only supports fixed numbers of frequencies */
262 printk(BIOS_WARNING
, "RAMINIT: Limiting DDR3 clock to 800 Mhz\n");
265 pei_data
->max_ddr3_freq
= 800;
268 pei_data
->max_ddr3_freq
= 1066;
271 pei_data
->max_ddr3_freq
= 1333;
274 pei_data
->max_ddr3_freq
= 1600;
279 * SPD addresses are listed in devicetree as actual addresses,
280 * and for MRC need to be shifted left so bit 0 is always zero.
282 if (!CONFIG(HAVE_SPD_IN_CBFS
)) {
283 for (unsigned int i
= 0; i
< ARRAY_SIZE(cfg
->spd_addresses
); i
++) {
284 pei_data
->spd_addresses
[i
] = cfg
->spd_addresses
[i
] << 1;
287 memcpy(pei_data
->ts_addresses
, cfg
->ts_addresses
, sizeof(pei_data
->ts_addresses
));
290 static void spd_fill_pei_data(struct pei_data
*pei_data
)
292 struct spd_info spdi
= {0};
293 unsigned int i
, have_memory_down
= 0;
295 mb_get_spd_map(&spdi
);
297 for (i
= 0; i
< ARRAY_SIZE(spdi
.addresses
); i
++) {
298 if (spdi
.addresses
[i
] == SPD_MEMORY_DOWN
) {
299 pei_data
->spd_addresses
[i
] = 0;
300 have_memory_down
= 1;
302 /* MRC expects left-aligned SMBus addresses. */
303 pei_data
->spd_addresses
[i
] = spdi
.addresses
[i
] << 1;
306 /* Copy SPD data from CBFS for on-board memory */
307 if (have_memory_down
) {
308 printk(BIOS_DEBUG
, "SPD index %d\n", spdi
.spd_index
);
311 uint8_t *spd_file
= cbfs_map("spd.bin", &spd_file_len
);
314 die("SPD data %s!", "not found");
316 if (spd_file_len
< ((spdi
.spd_index
+ 1) * SPD_SIZE_MAX_DDR3
))
317 die("SPD data %s!", "incomplete");
319 /* MRC only uses index 0... */
320 memcpy(pei_data
->spd_data
[0], spd_file
+ (spdi
.spd_index
* SPD_SIZE_MAX_DDR3
), SPD_SIZE_MAX_DDR3
);
322 /* but coreboot uses the other indices */
323 for (i
= 1; i
< ARRAY_SIZE(spdi
.addresses
); i
++) {
324 if (spdi
.addresses
[i
] == SPD_MEMORY_DOWN
)
325 memcpy(pei_data
->spd_data
[i
], pei_data
->spd_data
[0], SPD_SIZE_MAX_DDR3
);
330 static void disable_p2p(void)
332 /* Disable PCI-to-PCI bridge early to prevent probing by MRC */
333 const struct device
*const p2p
= pcidev_on_root(0x1e, 0);
334 if (p2p
&& p2p
->enabled
)
337 RCBA32(FD
) |= PCH_DISABLE_P2P
;
340 static void setup_sdram_meminfo(struct pei_data
*pei_data
);
342 void perform_raminit(int s3resume
)
344 const struct northbridge_intel_sandybridge_config
*cfg
= config_of_soc();
345 struct pei_data pei_data
= {
346 .pei_version
= PEI_VERSION
,
347 .mchbar
= CONFIG_FIXED_MCHBAR_MMIO_BASE
,
348 .dmibar
= CONFIG_FIXED_DMIBAR_MMIO_BASE
,
349 .epbar
= CONFIG_FIXED_EPBAR_MMIO_BASE
,
350 .pciexbar
= CONFIG_ECAM_MMCONF_BASE_ADDRESS
,
351 .smbusbar
= CONFIG_FIXED_SMBUS_IO_BASE
,
354 .hpet_address
= HPET_BASE_ADDRESS
,
355 .rcba
= (uintptr_t)DEFAULT_RCBA
,
356 .pmbase
= DEFAULT_PMBASE
,
357 .gpiobase
= DEFAULT_GPIOBASE
,
358 .thermalbase
= 0xfed08000,
359 .tseg_size
= CONFIG_SMM_TSEG_SIZE
,
360 .system_type
= !(get_platform_type() == PLATFORM_MOBILE
),
361 .pcie_init
= do_pcie_init(),
362 .gbe_enable
= is_devfn_enabled(PCI_DEVFN(0x19, 0)),
363 .boot_mode
= s3resume
? BOOT_PATH_RESUME
: BOOT_PATH_NORMAL
,
364 .ec_present
= cfg
->ec_present
,
365 .ddr3lv_support
= cfg
->ddr3lv_support
,
367 .ddr_refresh_rate_config
= cfg
->ddr_refresh_rate_config
,
368 .usb3
.mode
= cfg
->usb3
.mode
,
369 /* .usb3.hs_port_switch_mask = native config->xhci_switchable_ports */
370 .usb3
.preboot_support
= cfg
->usb3
.preboot_support
,
371 .usb3
.xhci_streams
= cfg
->usb3
.xhci_streams
,
374 struct mrc_var_data
*mrc_var
;
376 /* Prepare USB controller early in S3 resume */
380 southbridge_fill_pei_data(&pei_data
);
381 devicetree_fill_pei_data(&pei_data
);
382 if (CONFIG(HAVE_SPD_IN_CBFS
))
383 spd_fill_pei_data(&pei_data
);
384 mainboard_fill_pei_data(&pei_data
);
388 /* Fill after mainboard_fill_pei_data as it might provide spd_data */
389 pei_data
.dimm_channel0_disabled
=
390 (!pei_data
.spd_addresses
[0] && !pei_data
.spd_data
[0][0]) +
391 (!pei_data
.spd_addresses
[1] && !pei_data
.spd_data
[1][0]) * 2;
393 pei_data
.dimm_channel1_disabled
=
394 (!pei_data
.spd_addresses
[2] && !pei_data
.spd_data
[2][0]) +
395 (!pei_data
.spd_addresses
[3] && !pei_data
.spd_data
[3][0]) * 2;
399 timestamp_add_now(TS_INITRAM_START
);
400 sdram_initialize(&pei_data
);
401 timestamp_add_now(TS_INITRAM_END
);
403 /* Sanity check mrc_var location by verifying a known field */
404 mrc_var
= (void *)DCACHE_RAM_MRC_VAR_BASE
;
405 if (mrc_var
->tx_byte
== pei_data
.tx_byte_ptr
) {
406 printk(BIOS_DEBUG
, "MRC_VAR pool occupied [%08x,%08x]\n",
407 mrc_var
->pool_base
, mrc_var
->pool_base
+ mrc_var
->pool_used
);
410 printk(BIOS_ERR
, "Could not parse MRC_VAR data\n");
411 hexdump(mrc_var
, sizeof(*mrc_var
));
414 const int cbmem_was_initted
= !cbmem_recovery(s3resume
);
416 save_mrc_data(&pei_data
);
418 if (s3resume
&& !cbmem_was_initted
) {
419 /* Failed S3 resume, reset to come up cleanly */
422 setup_sdram_meminfo(&pei_data
);
425 static void setup_sdram_meminfo(struct pei_data
*pei_data
)
427 u32 addr_decode_ch
[2];
428 struct memory_info
*mem_info
;
429 struct dimm_info
*dimm
;
434 mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(struct memory_info
));
435 memset(mem_info
, 0, sizeof(struct memory_info
));
437 addr_decode_ch
[0] = mchbar_read32(MAD_DIMM_CH0
);
438 addr_decode_ch
[1] = mchbar_read32(MAD_DIMM_CH1
);
440 const int refclk
= mchbar_read32(MC_BIOS_REQ
) & 0x100 ? 100 : 133;
441 const int ddr_frequency
= (mchbar_read32(MC_BIOS_DATA
) * refclk
* 100 * 2 + 50) / 100;
443 for (i
= 0; i
< ARRAY_SIZE(addr_decode_ch
); i
++) {
444 u32 ch_conf
= addr_decode_ch
[i
];
447 dimm_size
= ((ch_conf
>> 0) & 0xff) * 256;
449 dimm
= &mem_info
->dimm
[dimm_cnt
];
450 dimm
->dimm_size
= dimm_size
;
451 dimm
->ddr_type
= MEMORY_TYPE_DDR3
;
452 dimm
->ddr_frequency
= ddr_frequency
;
453 dimm
->rank_per_dimm
= 1 + ((ch_conf
>> 17) & 1);
454 dimm
->channel_num
= i
;
456 dimm
->bank_locator
= i
* 2;
457 memcpy(dimm
->serial
, /* bytes 122-125 */
458 &pei_data
->spd_data
[0][SPD_DDR3_SERIAL_NUM
],
459 sizeof(uint8_t) * SPD_DDR3_SERIAL_LEN
);
460 memcpy(dimm
->module_part_number
, /* bytes 128-145 */
461 &pei_data
->spd_data
[0][SPD_DDR3_PART_NUM
],
462 sizeof(uint8_t) * SPD_DDR3_PART_LEN
);
463 dimm
->mod_id
= /* bytes 117/118 */
464 (pei_data
->spd_data
[0][SPD_DDR3_MOD_ID2
] << 8) |
465 (pei_data
->spd_data
[0][SPD_DDR3_MOD_ID1
] & 0xFF);
466 dimm
->mod_type
= SPD_DDR3_DIMM_TYPE_SO_DIMM
;
467 dimm
->bus_width
= MEMORY_BUS_WIDTH_64
;
471 dimm_size
= ((ch_conf
>> 8) & 0xff) * 256;
473 dimm
= &mem_info
->dimm
[dimm_cnt
];
474 dimm
->dimm_size
= dimm_size
;
475 dimm
->ddr_type
= MEMORY_TYPE_DDR3
;
476 dimm
->ddr_frequency
= ddr_frequency
;
477 dimm
->rank_per_dimm
= 1 + ((ch_conf
>> 18) & 1);
478 dimm
->channel_num
= i
;
480 dimm
->bank_locator
= i
* 2;
481 memcpy(dimm
->serial
, /* bytes 122-125 */
482 &pei_data
->spd_data
[0][SPD_DDR3_SERIAL_NUM
],
483 sizeof(uint8_t) * SPD_DDR3_SERIAL_LEN
);
484 memcpy(dimm
->module_part_number
, /* bytes 128-145 */
485 &pei_data
->spd_data
[0][SPD_DDR3_PART_NUM
],
486 sizeof(uint8_t) * SPD_DDR3_PART_LEN
);
487 dimm
->mod_id
= /* bytes 117/118 */
488 (pei_data
->spd_data
[0][SPD_DDR3_MOD_ID2
] << 8) |
489 (pei_data
->spd_data
[0][SPD_DDR3_MOD_ID1
] & 0xFF);
490 dimm
->mod_type
= SPD_DDR3_DIMM_TYPE_SO_DIMM
;
491 dimm
->bus_width
= MEMORY_BUS_WIDTH_64
;
495 mem_info
->dimm_cnt
= dimm_cnt
;