From 4e6881f0ba917054405535ac922b9020a0eee4cd Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Fri, 4 Apr 2014 14:07:54 -0600 Subject: Add the Rangeley FSP include & srx directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are the .h and .c files from Intel that support interaction with the FSP. These have been modified from the FSP distribution only to strip trailing whitespace. Intel® Firmware Support Package for Intel® Atom™ Processor C2000 Product Family (Formerly Rangeley) "Intel® Firmware Support Package (Intel® FSP) provides key programming information for initializing Intel® silicon and can be easily integrated into a boot loader of the developer’s choice. It is easy to adopt, scalable to design, reduces time-to-market, and is economical to build." http://www.intel.com/fsp Change-Id: I9ed94cb92909c3681cc88bf10b85a9ba25e8fc55 Signed-off-by: Martin Roth Signed-off-by: Martin Roth Reviewed-on: http://review.coreboot.org/5457 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones --- src/vendorcode/intel/fsp/rangeley/srx/fspapi.c | 521 +++++++++++++++++++++++++ 1 file changed, 521 insertions(+) create mode 100644 src/vendorcode/intel/fsp/rangeley/srx/fspapi.c (limited to 'src/vendorcode/intel/fsp/rangeley/srx/fspapi.c') diff --git a/src/vendorcode/intel/fsp/rangeley/srx/fspapi.c b/src/vendorcode/intel/fsp/rangeley/srx/fspapi.c new file mode 100644 index 0000000000..78978f576e --- /dev/null +++ b/src/vendorcode/intel/fsp/rangeley/srx/fspapi.c @@ -0,0 +1,521 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 coresystems GmbH + * Copyright (C) 2013, 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// __PRE_RAM__ means: use "unsigned" for device, not a struct. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsptypes.h" +#include "fspfv.h" +#include "fspffs.h" +#include "fsphob.h" +#include "fspvpd.h" +#include "fspapi.h" +#include "fspplatform.h" +#include "fspinfoheader.h" +#include "fspbootmode.h" +#include "northbridge/intel/rangeley/northbridge.h" + +void find_fsp_header(void); +void early_init(FSP_INFO_HEADER *fsp_info); +void FspNotifyPhase(uint32_t Phase); +void UpdateFspUpdConfigs ( + UPD_DATA_REGION *FspUpdRgn +); + +// +// Spd Data table for Memory Down +// +#ifdef __PRE_RAM__ +#if CONFIG_MEMORY_DOWN_ENABLE +/* + * MEM_DOWN_DIMM_CONFIG + * MemoryDownDimmPopulation - 0: Empty 1: Populated. + * MemoryDownDimmSpdData - structure MEM_DOWN_DIMM_SPD_DATA for spd data. + */ + /* Apacer 2GB PC3-12800 DDR3-1600MHz ECC Unbuffered CL11 240-Pin DIMM Single Rank Memory Module Mfr P/N 78.A1GG3.AF20C */ +static const MEM_DOWN_DIMM_CONFIG OemMemoryDownDimmConfig = { +0x01, // MemoryDownDimmPopulation +{ // MemoryDownDimmSpdData + 0xB, //Byte 2 Dram Device Type + 0x2, //Byte 3 Module type (3:0) + 0x3, //Byte 4 Density and Banks + 0x19, //Byte 5 Addressing + 0x2, //Byte 6 Nominal Voltage, VDD + 0x1, //Byte 7 Module Organization + 0xB, //Byte 8 Memory Bus Width + 0x1, //Byte 10 Medium Timebase (MTB) Dividend + 0x8, //Byte 11 Medium Timebase (MTB) Divisor + 0xA, //Byte 12 Minimum cycle time (tCKmin) + 0xFC, //Byte 14 CAS latency supported, low byte + 0, //Byte 15 CAS latency supported, high byte + 0x69, //Byte 16 Minimum CAS latency time (tAA) + 0x78, //Byte 17 Minimum write recovery time (tWR) + 0x69, //Byte 18 Minimum RAS to CAS time (tRCD) + 0x30, //Byte 19 Minimum RA to RA time (tRRD) + 0x69, //Byte 20 Minimum precharge time (tRP) + 0x11, //Byte 21 Upper nibbles for tRAS (7:4), tRC (3:0) + 0x18, //Byte 22 Minimum active to precharge (tRAS) + 0x81, //Byte 23 Minimum active to active/refresh (tRC) + 0, //Byte 24 Minimum refresh recovery (tRFC), low byte + 0x5, //Byte 25 Minimum refresh recovery (tRFC), high byte + 0x3C, //Byte 26 Minimum internal wr to rd cmd (tWTR) + 0x3C, //Byte 27 Minimum internal rd to pc cmd (tRTP) + 0, //Byte 28 Upper Nibble for tFAW + 0xF0, //Byte 29 Minimum Four Activate Window Delay Time (tFAWmin), Least Significant Byte + 0x80, //Byte 32 + 0, //Byte 33 + 0, //Byte 34 + 0, //Byte 35 + 0, //Byte 41 + 0x3, //Byte 62 + 0, //Byte 63 + 0x1, //Byte 117 + 0x7A, //Byte 118 + 0, //Byte 119 + 0x13, //Byte 120 + 0x15, //Byte 121 + 0x2, //Byte 122 + 0x1, //Byte 123 + 0x31, //Byte 124 + 0x52, //Byte 125 + 0, //Byte 148 + 0, //Byte 149 +} +}; + + /* Dummy structure */ +static const MEM_DOWN_DIMM_CONFIG DummyMemoryDownDimmConfig = { +0x00, // MemoryDownDimmPopulation +{ // MemoryDownDimmSpdData + 0, //Byte 2 Dram Device Type + 0, //Byte 3 Module type (3:0) + 0, //Byte 4 Density and Banks + 0, //Byte 5 Addressing + 0, //Byte 6 Nominal Voltage, VDD + 0, //Byte 7 Module Organization + 0, //Byte 8 Memory Bus Width + 0, //Byte 10 Medium Timebase (MTB) Dividend + 0, //Byte 11 Medium Timebase (MTB) Divisor + 0, //Byte 12 Minimum cycle time (tCKmin) + 0, //Byte 14 CAS latency supported, low byte + 0, //Byte 15 CAS latency supported, high byte + 0, //Byte 16 Minimum CAS latency time (tAA) + 0, //Byte 17 Minimum write recovery time (tWR) + 0, //Byte 18 Minimum RAS to CAS time (tRCD) + 0, //Byte 19 Minimum RA to RA time (tRRD) + 0, //Byte 20 Minimum precharge time (tRP) + 0, //Byte 21 Upper nibbles for tRAS (7:4), tRC (3:0) + 0, //Byte 22 Minimum active to precharge (tRAS) + 0, //Byte 23 Minimum active to active/refresh (tRC) + 0, //Byte 24 Minimum refresh recovery (tRFC), low byte + 0, //Byte 25 Minimum refresh recovery (tRFC), high byte + 0, //Byte 26 Minimum internal wr to rd cmd (tWTR) + 0, //Byte 27 Minimum internal rd to pc cmd (tRTP) + 0, //Byte 28 Upper Nibble for tFAW + 0, //Byte 29 Minimum Four Activate Window Delay Time (tFAWmin), Least Significant Byte + 0, //Byte 32 + 0, //Byte 33 + 0, //Byte 34 + 0, //Byte 35 + 0, //Byte 41 + 0, //Byte 62 + 0, //Byte 63 + 0, //Byte 117 + 0, //Byte 118 + 0, //Byte 119 + 0, //Byte 120 + 0, //Byte 121 + 0, //Byte 122 + 0, //Byte 123 + 0, //Byte 124 + 0, //Byte 125 + 0, //Byte 148 + 0, //Byte 149 +} +}; +#endif +#endif + +// +// FSP_INFO_HEADER GUID +// +#define FSP_INFO_HEADER_GUID \ + { \ + 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \ + } + +// +// FSP_NON_VOLATILE_STORAGE_HOB_GUID +// +#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ + { \ + 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0} \ + } + +static EFI_GUID gFspInfoHeaderGuid = FSP_INFO_HEADER_GUID; +#ifdef __PRE_RAM__ +static EFI_GUID gEfiMemoryConfigDataGuid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; +#endif + +/* + * Compares two GUIDs. + * Input: + * Guid1 a 128 bit GUID. + * Guid2 a 128 bit GUID. + * Return: + * TRUE Guid1 and Guid2 are identical. + * FALSE Guid1 and Guid2 are not identical. + */ +#define CompareGuid(Guid1, Guid2) ( \ + (Guid1.Data1 == Guid2.Data1) && \ + (Guid1.Data2 == Guid2.Data2) && \ + (Guid1.Data3 == Guid2.Data3) && \ + (Guid1.Data4[0] == Guid2.Data4[0]) && \ + (Guid1.Data4[1] == Guid2.Data4[1]) && \ + (Guid1.Data4[2] == Guid2.Data4[2]) && \ + (Guid1.Data4[3] == Guid2.Data4[3]) && \ + (Guid1.Data4[4] == Guid2.Data4[4]) && \ + (Guid1.Data4[5] == Guid2.Data4[5]) && \ + (Guid1.Data4[6] == Guid2.Data4[6]) && \ + (Guid1.Data4[7] == Guid2.Data4[7]) \ + ) + +/* + * Compares two GUIDs. + * Input: + * Guid1 A pointer to a 128 bit GUID. + * Guid2 A pointer to a 128 bit GUID. + * Return: + * TRUE Guid1 and Guid2 are identical. + * FALSE Guid1 and Guid2 are not identical. + */ +#define CompareGuidPtr(Guid1, Guid2) ( \ + (((UINT32 *) Guid1)[0] == ((UINT32 *) Guid2)[0]) && \ + (((UINT32 *) Guid1)[1] == ((UINT32 *) Guid2)[1]) && \ + (((UINT32 *) Guid1)[2] == ((UINT32 *) Guid2)[2]) && \ + (((UINT32 *) Guid1)[3] == ((UINT32 *) Guid2)[3]) \ + ) + +/* + * Platform configuration pointer/structure here. + */ + +#ifdef __PRE_RAM__ +static void ContinuationFunc (EFI_STATUS Status, void *HobListPtr) +{ + /* Should add the necessary code here! */ + + EFI_HOB_GUID_TYPE *GuidHob; + + /* + * DO NOT know why the following code always fail to build. + * + * GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobListPtr); + * + * The error message as below, + * + * .data is non-zero size in romstage which is not allowed -- global variable? + * + * OR, + * + * .bss is non-zero size in romstage which is not allowed -- global variable? + * + * It's replaced with the following code. + */ + + /* Get the Memory Configure Data HOB */ + EFI_PEI_HOB_POINTERS mGuidHob; + + mGuidHob.Raw = (UINT8 *) HobListPtr; + while ((mGuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, mGuidHob.Raw)) != NULL) { + if (CompareGuid(gEfiMemoryConfigDataGuid, mGuidHob.Guid->Name)) { + break; + } + mGuidHob.Raw = GET_NEXT_HOB (mGuidHob); + } + GuidHob = (EFI_HOB_GUID_TYPE *) mGuidHob.Raw; + + if (GuidHob == NULL) { + + /* Avoid store Hob to CBMEM if NVRAM Hob not exist */ + printk(BIOS_DEBUG, "FSP NVRAM Hob NOT found.\n"); + + } else { + + /* Get Guid Hob size and Guid Hob Data pointer */ + void *GuidHobData; + uint32_t GuidHobSize; + GuidHobData = (VOID *)(*(UINT8 **)&(mGuidHob.Raw) + sizeof (EFI_HOB_GUID_TYPE)); + GuidHobSize = (uint32_t) ((((EFI_HOB_GUID_TYPE *)(mGuidHob.Raw))->Header.HobLength) - sizeof(EFI_HOB_GUID_TYPE)); + + /* DEBUG INFO */ + printk(BIOS_DEBUG, "FSP NVRAM Hob at 0x%x (size = 0x%x).\n", (uint32_t)GuidHobData, (uint32_t)GuidHobSize); + +#if CONFIG_EARLY_CBMEM_INIT + struct mrc_data_container *mrcdata; + int output_len = ALIGN(GuidHobSize, 16); + + /* Save the MRC S3/Fastboot/ADR restore data to cbmem */ + cbmem_initialize(); + mrcdata = cbmem_add + (CBMEM_ID_MRCDATA, + output_len + sizeof(struct mrc_data_container)); + + printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n", + (void *)GuidHobData, mrcdata, output_len); + + mrcdata->mrc_signature = MRC_DATA_SIGNATURE; + mrcdata->mrc_data_size = output_len; + mrcdata->reserved = 0; + memcpy(mrcdata->mrc_data, (void *)GuidHobData, + GuidHobSize); + + /* Zero the unused space in aligned buffer. */ + if (output_len > GuidHobSize) + memset(mrcdata->mrc_data + GuidHobSize, 0, + output_len - GuidHobSize); + + mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data, + mrcdata->mrc_data_size); +#endif + } + + /* Rangeley early init */ + rangeley_early_initialization(); + + /* Notify FSP for PostPciEnumeration */ + FspNotifyPhase (EnumInitPhaseAfterPciEnumeration); + + /* Return to coreboot boot process. */ + __asm__ __volatile__ ( + "jmp fsp_init_done\n\t" + ); +} + +/** C Based Basic Initialization + * + * Platform configuration with Temp Stack starts here. + * + */ +void early_init (FSP_INFO_HEADER *fsp_info) +{ + FSP_FSP_INIT FspInitApi; + FSP_INIT_PARAMS FspInitParams; + FSP_INIT_RT_BUFFER FspRtBuffer; + VPD_DATA_REGION *FspVpdRgn; + UPD_DATA_REGION FspUpdRgn; + struct mrc_data_container *mrc_cache; + + memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER)); + FspRtBuffer.Common.StackTop = (uint32_t *) ROMSTAGE_STACK; + FspRtBuffer.Common.UpdDataRgnPtr = (UPD_DATA_REGION *)&FspUpdRgn; + + /* find_current_mrc_cache */ + if (((mrc_cache = find_current_mrc_cache()) == NULL) || (mrc_cache->mrc_data_size == -1UL)) { + printk(BIOS_DEBUG, "MRC cache not present.\n"); + FspInitParams.NvsBufferPtr = (void *) NULL; + FspRtBuffer.Common.BootMode = BOOT_WITH_FULL_CONFIGURATION; + } else { + printk(BIOS_DEBUG, "MRC cache present at %x.\n", (uint32_t)mrc_cache); + FspInitParams.NvsBufferPtr = (void *) (EFI_HOB_GUID_TYPE *) mrc_cache->mrc_data; + FspRtBuffer.Common.BootMode = BOOT_WITH_FULL_CONFIGURATION; + } + + /* Get VPD region start */ + FspVpdRgn = (VPD_DATA_REGION *)(fsp_info->ImageBase + fsp_info->CfgRegionOffset); + + /* Verifify the VPD data region is valid */ + ASSERT((FspVpdRgn->PcdImageRevision == VPD_IMAGE_REV) && (FspVpdRgn->PcdVpdRegionSign == VPD_IMAGE_ID)); + + /* Copy default data from Flash */ + memcpy ((void*)&FspUpdRgn, (void *)(fsp_info->ImageBase + FspVpdRgn->PcdUpdRegionOffset), sizeof(UPD_DATA_REGION)); + + /* Verifify the UPD data region is valid */ + ASSERT(FspUpdRgn.PcdRegionTerminator == 0x55AA); + + /* Override any UPD setting if required */ + UpdateFspUpdConfigs (&FspUpdRgn); + +#if CONFIG_MEMORY_DOWN_ENABLE + /* + * Setup platform specific structure + */ + + /* Channel0/Dimm0, DIMM populated */ + FspRtBuffer.Platform.MemDownDimmConfig[0][0] = (MEM_DOWN_DIMM_CONFIG *)&OemMemoryDownDimmConfig; + /* Channel0/Dimm1, not populated */ + FspRtBuffer.Platform.MemDownDimmConfig[0][1] = (MEM_DOWN_DIMM_CONFIG *)&DummyMemoryDownDimmConfig; + /* Channel1/Dimm0, DIMM populated */ + FspRtBuffer.Platform.MemDownDimmConfig[1][0] = (MEM_DOWN_DIMM_CONFIG *)&OemMemoryDownDimmConfig; + /* Channel1/Dimm1, not populated */ + FspRtBuffer.Platform.MemDownDimmConfig[1][1] = (MEM_DOWN_DIMM_CONFIG *)&DummyMemoryDownDimmConfig; +#endif + + FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer; + FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc; + FspInitApi = (FSP_FSP_INIT)(fsp_info->ImageBase + fsp_info->FspInitEntry); + FspInitApi(&FspInitParams); + + /* Should never return. Control will continue from ContinuationFunc */ + while (1); +} +#endif + +/** C Based Basic Initialization + * + * Find FSP header + * + */ +void __attribute__((optimize("O0"))) find_fsp_header () +{ + volatile register UINT8 *ptr asm ("eax"); + +#ifdef __PRE_RAM__ + __asm__ __volatile__ ( + ".global find_fsp_entry\n\t" + "find_fsp_entry:\n\t" + ); +#endif + + // + // Start at the FSP / FV Header base + // + ptr = (UINT8 *)CONFIG_FSP_BIN_BASE; + + // + // Validate FV signature _FVH + // + if (((EFI_FIRMWARE_VOLUME_HEADER *)ptr)-> Signature != EFI_FVH_SIGNATURE) { + ptr = 0; + goto NotFound; + } + + // + // Add the Ext Header size to the Ext Header base to go to the end of FV + // header + // + ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)ptr)->ExtHeaderOffset; + ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)ptr)->ExtHeaderSize; + + // + // Align the end of FV header address to 8 bytes + // + ptr = (UINT8 *)(((uint32_t)ptr + 7) & 0xFFFFFFF8); + + // + // Now ptr is pointing to thr FFS Header. Verify if the GUID + // matches the FSP_INFO_HEADER GUID + // + if (!CompareGuid(((EFI_GUID) (((EFI_FFS_FILE_HEADER *)ptr)->Name)), ((EFI_GUID) gFspInfoHeaderGuid))) { + ptr = 0; + goto NotFound; + } + + // + // Add the FFS Header size to the base to find the Raw section Header + // + ptr += sizeof(EFI_FFS_FILE_HEADER); + if (((EFI_RAW_SECTION *)ptr)->Type != EFI_SECTION_RAW) { + ptr = 0; + goto NotFound; + } + + // + // Add the Raw Header size to the base to find the FSP INFO Header + // + ptr += sizeof(EFI_RAW_SECTION); + +NotFound: + __asm__ __volatile__ ("ret"); +} + +/** C Based Basic Initialization + * + * Notify Phase for different stage. + * + */ +void FspNotifyPhase (uint32_t Phase) +{ + FSP_NOTFY_PHASE NotifyPhaseProc; + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + FSP_INFO_HEADER *fsp_info_header; + EFI_STATUS Status; + + __asm__ __volatile__ ( + "call find_fsp_header \n\t" /* Call FSP Notify API */ + "movl %%eax, %0\n\t" + : "=m"(fsp_info_header) :: + ); + + /* call FSP PEI to Notify PostPciEnumeration */ + NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_info_header->ImageBase + fsp_info_header->NotifyPhaseEntry); + NotifyPhaseParams.Phase = Phase; + Status = NotifyPhaseProc (&NotifyPhaseParams); + if (Status != 0) { + printk(BIOS_DEBUG, "FSP API NotifyPhase failed for phase %d!\n", Phase); + } +} + +/* + * Board Specific routine before handling over to boot loader. + */ +#if !defined(__PRE_RAM__) +void mainboard_cbmem_post_handling(void) +{ + + /* Notify FSP for ReadyToBoot */ + FspNotifyPhase (EnumInitPhaseReadyToBoot); +} +#endif + +/** + This function overrides the default configurations in the UPD data region. + + @param UpdDataRgn A pointer to the UPD_DATA_REGION data strcture. + + @return None +**/ +VOID +UpdateFspUpdConfigs ( + UPD_DATA_REGION *FspUpdRgn +) +{ + /* Override any UPD setting if required */ + + // + // Uncomment the line below to disable LAN device + // + //FspUpdRgn->PcdEnableLan = 0; + +} -- cgit v1.2.3