Andrey Petrov (andrey.petrov@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13798
-gerrit
commit c804131044ec8084309ee4610c5265d304fbd00e Author: Andrey Petrov andrey.petrov@intel.com Date: Thu Feb 25 14:16:33 2016 -0800
drivers/intel/fsp2_0: Add MemoryInit API
This adds implementation of fsp_memory_init() that is used to train memory.
Change-Id: I72268aaa91eea7e4d4f072d70a47871d74c2b979 Signed-off-by: Andrey Petrov andrey.petrov@intel.com --- src/drivers/intel/fsp2_0/memory_init.c | 125 +++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+)
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c new file mode 100644 index 0000000..06d0b03 --- /dev/null +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -0,0 +1,125 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * (Written by Andrey Petrov andrey.petrov@intel.com for Intel Corp.) + * (Written by Alexandru Gagniuc alexandrux.gagniuc@intel.com for Intel Corp.) + * + * 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; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <arch/io.h> +#include <arch/cpu.h> +#include <console/console.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <memrange.h> +#include <string.h> +#include <timestamp.h> + +/* offsets for fields in ARCH UPD from the beginning of FSP-M config region */ +#define FSPM_UPD_OFFSET_REVISION 0x20 +#define FSPM_UPD_OFFSET_NVSBUFFER 0x24 +#define FSPM_UPD_OFFSET_STACKBASE 0x28 +#define FSPM_UPD_OFFSET_STACKSIZE 0x2c +#define FSPM_UPD_OFFSET_BLSZ 0x30 +#define FSPM_UPD_OFFSET_BOOTMODE 0x34 +/* + * FSP_M_CONFIG structure start. + * FSP_M_CONFIG contains all SoC-specific parameters. + */ +#define FSPM_UPD_OFFSET_MCONFIG 0x40 + +struct fsp_memory_init_params { + void *nvs_buffer; + void *raminit_upd; + void **hob_list; +} __attribute__ ((__packed__)); + +typedef asmlinkage enum fsp_status (*fsp_memory_init_fn) + (struct fsp_memory_init_params *); + +static struct FSP_M_CONFIG *fspm_parse_upd(void *cfg_region, + struct fsp_m_arch_upd *arch_upd) +{ + uint8_t *raw_hdr = (uint8_t*) cfg_region; + + arch_upd->revision = read8(raw_hdr + FSPM_UPD_OFFSET_REVISION); + arch_upd->nvs_buffer = read32(raw_hdr + FSPM_UPD_OFFSET_NVSBUFFER); + arch_upd->stack_base = read32(raw_hdr + FSPM_UPD_OFFSET_STACKBASE); + arch_upd->stack_size = read32(raw_hdr + FSPM_UPD_OFFSET_STACKSIZE); + arch_upd->bootloader_tolumsz = read32(raw_hdr + FSPM_UPD_OFFSET_BLSZ); + arch_upd->boot_mode = read32(raw_hdr + FSPM_UPD_OFFSET_BOOTMODE); + + return (struct FSP_M_CONFIG *) (raw_hdr + FSPM_UPD_OFFSET_MCONFIG); +} + +static void fspm_update_cfg(void *cfg_region, struct fsp_m_arch_upd *arch_upd) +{ + uint8_t *raw_hdr = (uint8_t*) cfg_region; + + write8(raw_hdr + FSPM_UPD_OFFSET_REVISION, arch_upd->revision); + write32(raw_hdr + FSPM_UPD_OFFSET_NVSBUFFER, arch_upd->nvs_buffer); + write32(raw_hdr + FSPM_UPD_OFFSET_STACKBASE, arch_upd->stack_base); + write32(raw_hdr + FSPM_UPD_OFFSET_STACKSIZE, arch_upd->stack_size); + write32(raw_hdr + FSPM_UPD_OFFSET_BLSZ, arch_upd->bootloader_tolumsz); + write32(raw_hdr + FSPM_UPD_OFFSET_BOOTMODE, arch_upd->boot_mode); +} + +static enum fsp_status do_fsp_memory_init(void **hob_list_ptr, + struct fsp_header *hdr) +{ + enum fsp_status status; + fsp_memory_init_fn fsp_raminit; + struct fsp_memory_init_params raminit_params; + struct fsp_m_arch_upd arch_upd; + struct FSP_M_CONFIG *fsp_m_config; + void *mem_upd; + + post_code(0x34); + /* UPD region resides in CAR. Thus, it can be directly modified. */ + mem_upd = (void *)(hdr->cfg_region_offset + hdr->image_base); + + /* Read default values from arch_upd, perhaps they can be useful. */ + fsp_m_config = fspm_parse_upd(mem_upd, &arch_upd); + + /* Get any board specific changes */ + raminit_params.nvs_buffer = NULL; + raminit_params.raminit_upd = mem_upd; + raminit_params.hob_list = hob_list_ptr; + + /* Give SoC and mainboard a chance to update the UPD */ + platform_fsp_memory_init_params_cb(&arch_upd, fsp_m_config); + + /* Update the actual upd region */ + fspm_update_cfg(mem_upd, &arch_upd); + + /* Call FspMemoryInit */ + fsp_raminit = (void *)(hdr->image_base + hdr->memory_init_entry_offset); + printk(BIOS_DEBUG, "Calling FspMemoryInit: 0x%p\n", fsp_raminit); + printk(BIOS_SPEW, "\t%p: nvs_buffer\n", raminit_params.nvs_buffer); + printk(BIOS_SPEW, "\t%p: raminit_upd\n", raminit_params.raminit_upd); + printk(BIOS_SPEW, "\t%p: hob_list\n", raminit_params.hob_list); + + timestamp_add_now(TS_FSP_MEMORY_INIT_START); + status = fsp_raminit(&raminit_params); + post_code(0x37); + timestamp_add_now(TS_FSP_MEMORY_INIT_END); + + printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status); + + return status; +} + +enum fsp_status fsp_memory_init(void **hob_list, struct range_entry *range) +{ + struct fsp_header hdr; + + if (fsp_load_binary(&hdr, "blobs/fspm.bin", range) != CB_SUCCESS) + return FSP_NOT_FOUND; + + return do_fsp_memory_init(hob_list, &hdr); +}