diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 774fe41870..3ce8776cc7 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -46,6 +46,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_INTEL_COMMON_BLOCK_CPU select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT select SOC_INTEL_COMMON_BLOCK_CSE + select SOC_INTEL_COMMON_BLOCK_EBDA select SOC_INTEL_COMMON_BLOCK_FAST_SPI select SOC_INTEL_COMMON_BLOCK_GPIO select SOC_INTEL_COMMON_BLOCK_GSPI diff --git a/src/soc/intel/cannonlake/bootblock/pch.c b/src/soc/intel/cannonlake/bootblock/pch.c index 0062c0d61c..091e6f7cbc 100644 --- a/src/soc/intel/cannonlake/bootblock/pch.c +++ b/src/soc/intel/cannonlake/bootblock/pch.c @@ -196,6 +196,4 @@ void pch_early_init(void) enable_rtc_upper_bank(); heci_init(HECI1_BASE_ADDRESS); - - clear_cbmem_top(); } diff --git a/src/soc/intel/cannonlake/include/soc/bootblock.h b/src/soc/intel/cannonlake/include/soc/bootblock.h index fcef4ef358..2a6ca1fb15 100644 --- a/src/soc/intel/cannonlake/include/soc/bootblock.h +++ b/src/soc/intel/cannonlake/include/soc/bootblock.h @@ -27,6 +27,4 @@ void pch_early_init(void); void pch_early_iorange_init(void); void report_platform_info(void); -void clear_cbmem_top(void); - #endif diff --git a/src/soc/intel/cannonlake/include/soc/ebda.h b/src/soc/intel/cannonlake/include/soc/ebda.h new file mode 100644 index 0000000000..4cde5c0106 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/ebda.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_EBDA_H +#define SOC_EBDA_H + +struct ebda_config { + uint32_t signature; /* 0x00 - EBDA signature */ + uint32_t tolum_base; /* 0x04 - coreboot memory start */ +}; + +#endif diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c index e5117ad81d..c14ccd712f 100644 --- a/src/soc/intel/cannonlake/memmap.c +++ b/src/soc/intel/cannonlake/memmap.c @@ -13,6 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +#include #include #include #include @@ -20,8 +22,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -81,20 +83,6 @@ int smm_subregion(int sub, void **start, size_t *size) return 0; } -static void *top_of_ram_register(void) -{ - int num; - int offset; - num = (read32((uintptr_t *)HPET_BASE_ADDRESS) >> 8) & 0x1f; - offset = 0x100 + (0x20 * num) + 0x08; - return (void *)(uintptr_t)(HPET_BASE_ADDRESS + offset); -} - -void clear_cbmem_top(void) -{ - write32(top_of_ram_register(), 0); -} - static bool is_ptt_enable(void) { if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) == @@ -268,44 +256,62 @@ static uintptr_t calculate_dram_base(size_t *reserved_mem_size) return dram_base; } -void cbmem_top_init(void) +/* Fill up memory layout information */ +void fill_soc_memmap_ebda(struct ebda_config *cfg) { - uintptr_t top; size_t chipset_mem_size; - top = calculate_dram_base(&chipset_mem_size); - - write32(top_of_ram_register(), top); + cfg->tolum_base = calculate_dram_base(&chipset_mem_size); } +void cbmem_top_init(void) +{ + /* Fill up EBDA area */ + fill_ebda_area(); +} + +/* + * +-------------------------+ Top of RAM (aligned) + * | System Management Mode | + * | code and data | Length: CONFIG_TSEG_SIZE + * | (TSEG) | + * +-------------------------+ SMM base (aligned) + * | | + * | Chipset Reserved Memory | + * | | + * +-------------------------+ top_of_ram (aligned) + * | | + * | CBMEM Root | + * | | + * +-------------------------+ + * | | + * | FSP Reserved Memory | + * | | + * +-------------------------+ + * | | + * | Various CBMEM Entries | + * | | + * +-------------------------+ top_of_stack (8 byte aligned) + * | | + * | stack (CBMEM Entry) | + * | | + * +-------------------------+ + */ void *cbmem_top(void) { + struct ebda_config ebda_cfg; + struct ebda_config *cfg = &ebda_cfg; + /* - * +-------------------------+ Top of RAM (aligned) - * | System Management Mode | - * | code and data | Length: CONFIG_TSEG_SIZE - * | (TSEG) | - * +-------------------------+ SMM base (aligned) - * | | - * | Chipset Reserved Memory | - * | | - * +-------------------------+ top_of_ram (aligned) - * | | - * | CBMEM Root | - * | | - * +-------------------------+ - * | | - * | FSP Reserved Memory | - * | | - * +-------------------------+ - * | | - * | Various CBMEM Entries | - * | | - * +-------------------------+ top_of_stack (8 byte aligned) - * | | - * | stack (CBMEM Entry) | - * | | - * +-------------------------+ + * Check if Tseg has been initialized, we will use this as a flag + * to check if the MRC is done, and only then continue to read the + * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before + * PRMRR_MASK MSR lock bit is set. */ - return (void *)(uintptr_t)read32(top_of_ram_register()); + if (sa_get_tseg_base() == 0) + return NULL; + + retrieve_ebda_object(cfg); + + return (void *)(uintptr_t)cfg->tolum_base; }