blob: 37e22ac73da3c6317055484148ca6d30ae420309 [file] [log] [blame]
Marc Jones24484842017-05-04 21:17:45 -06001/*
2 * This file is part of the coreboot project.
3 *
Marshall Dawson9df969a2017-07-25 18:46:46 -06004 * Copyright (C) 2016 Intel Corporation..
5 * Copyright (C) 2017 Advanced Micro Devices
Marc Jones24484842017-05-04 21:17:45 -06006 *
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.
10 *
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.
15 */
16
17#include <stdint.h>
Marshall Dawsona5f225f2017-08-18 10:07:07 -060018#include <assert.h>
Marshall Dawson9df969a2017-07-25 18:46:46 -060019#include <console/console.h>
Marshall Dawson154239a2017-11-02 09:49:30 -060020#include <cpu/x86/msr.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +020021#include <cpu/amd/msr.h>
Marshall Dawson154239a2017-11-02 09:49:30 -060022#include <cpu/x86/mtrr.h>
Marshall Dawson9df969a2017-07-25 18:46:46 -060023#include <smp/node.h>
24#include <bootblock_common.h>
Richard Spiegel0ad74ac2017-12-08 16:53:29 -070025#include <amdblocks/agesawrapper.h>
26#include <amdblocks/agesawrapper_call.h>
Marshall Dawsonf5e057c2017-10-12 16:10:14 -060027#include <soc/pci_devs.h>
Marshall Dawsond85c4af2018-03-28 19:48:42 -060028#include <soc/cpu.h>
Marshall Dawsonf5e057c2017-10-12 16:10:14 -060029#include <soc/northbridge.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060030#include <soc/southbridge.h>
Marshall Dawsonf5e057c2017-10-12 16:10:14 -060031#include <amdblocks/psp.h>
Aaron Durbin51e4c1a2018-01-24 17:42:51 -070032#include <timestamp.h>
Richard Spiegel6d61db02018-04-04 10:35:21 -070033#include <halt.h>
Marc Jones24484842017-05-04 21:17:45 -060034
Marshall Dawsonc4be1752018-05-07 09:59:10 -060035#if CONFIG_PI_AGESA_TEMP_RAM_BASE < 0x100000
36#error "Error: CONFIG_PI_AGESA_TEMP_RAM_BASE must be >= 1MB"
37#endif
38#if CONFIG_PI_AGESA_CAR_HEAP_BASE < 0x100000
39#error "Error: CONFIG_PI_AGESA_CAR_HEAP_BASE must be >= 1MB"
40#endif
41
42/* Set the MMIO Configuration Base Address, Bus Range, and misc MTRRs. */
Marshall Dawson154239a2017-11-02 09:49:30 -060043static void amd_initmmio(void)
44{
45 msr_t mmconf;
46 msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
47 int mtrr;
48
49 mmconf.hi = 0;
50 mmconf.lo = CONFIG_MMCONF_BASE_ADDRESS | MMIO_RANGE_EN
51 | fms(CONFIG_MMCONF_BUS_NUMBER) << MMIO_BUS_RANGE_SHIFT;
52 wrmsr(MMIO_CONF_BASE, mmconf);
53
54 /*
55 * todo: AGESA currently writes variable MTRRs. Once that is
56 * corrected, un-hardcode this MTRR.
Marshall Dawsonc4be1752018-05-07 09:59:10 -060057 *
58 * Be careful not to use get_free_var_mtrr/set_var_mtrr pairs
59 * where all cores execute the path. Both cores within a compute
60 * unit share MTRRs. Programming core0 has the appearance of
61 * modifying core1 too. Using the pair again will create
62 * duplicate copies.
Marshall Dawson154239a2017-11-02 09:49:30 -060063 */
Marshall Dawsond85c4af2018-03-28 19:48:42 -060064 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_FLASH;
Marshall Dawson154239a2017-11-02 09:49:30 -060065 set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
Marshall Dawsonc4be1752018-05-07 09:59:10 -060066
67 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_CAR_HEAP;
68 set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,
69 CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_WRBACK);
70
71 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_TEMPRAM;
72 set_var_mtrr(mtrr, CONFIG_PI_AGESA_TEMP_RAM_BASE,
73 CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_UNCACHEABLE);
Marshall Dawson154239a2017-11-02 09:49:30 -060074}
75
Richard Spiegel6d61db02018-04-04 10:35:21 -070076asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
Marc Jones24484842017-05-04 21:17:45 -060077{
Marshall Dawson9df969a2017-07-25 18:46:46 -060078 amd_initmmio();
Richard Spiegel6d61db02018-04-04 10:35:21 -070079 /*
80 * Call lib/bootblock.c main with BSP, shortcut for APs
81 */
82 if (!boot_cpu()) {
83 void (*ap_romstage_entry)(void) =
84 (void (*)(void))get_ap_entry_ptr();
Marshall Dawson9df969a2017-07-25 18:46:46 -060085
Richard Spiegel6d61db02018-04-04 10:35:21 -070086 ap_romstage_entry(); /* execution does not return */
87 halt();
88 }
Marshall Dawson9df969a2017-07-25 18:46:46 -060089
Richard Spiegel6d61db02018-04-04 10:35:21 -070090 /* TSC cannot be relied upon. Override the TSC value passed in. */
Julius Werner12574dd2018-05-15 17:48:30 -070091 bootblock_main_with_timestamp(timestamp_get(), NULL, 0);
Richard Spiegel6d61db02018-04-04 10:35:21 -070092}
93
94void bootblock_soc_early_init(void)
95{
Richard Spiegel5401aa22018-09-11 11:36:38 -070096 /*
97 * This call (sb_reset_i2c_slaves) was originally early at
98 * bootblock_c_entry, but had to be moved here. There was an
99 * unexplained delay in the middle of the i2c transaction when
100 * we had it in bootblock_c_entry. Moving it to this point
101 * (or adding delays) fixes the issue. It seems like the processor
102 * just pauses but we don't know why.
103 */
104 sb_reset_i2c_slaves();
Marshall Dawson9df969a2017-07-25 18:46:46 -0600105 bootblock_fch_early_init();
Marshall Dawson9df969a2017-07-25 18:46:46 -0600106 post_code(0x90);
Marshall Dawson9df969a2017-07-25 18:46:46 -0600107}
108
109void bootblock_soc_init(void)
110{
Marshall Dawsona5f225f2017-08-18 10:07:07 -0600111 if (IS_ENABLED(CONFIG_STONEYRIDGE_UART))
112 assert(CONFIG_UART_FOR_CONSOLE >= 0
113 && CONFIG_UART_FOR_CONSOLE <= 1);
114
Marshall Dawson9df969a2017-07-25 18:46:46 -0600115 u32 val = cpuid_eax(1);
116 printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
117
Raul E Rangeld820f4b82018-08-13 10:39:03 -0600118 bootblock_fch_init();
119
Aaron Durbinde3e84c2018-01-29 17:44:58 -0700120 /* Initialize any early i2c buses. */
121 i2c_soc_early_init();
Marc Jones24484842017-05-04 21:17:45 -0600122}