cougar_canyon2: Switch CPU/NB/SB to the shared FSP code

CPU - fsp_model_206ax:
- Remove Kconfig options and mark this as using the FSP.
- Use shared FSP cache_as_ram.inc file
Mainboard - intel/cougar_canyon2:
- Update to use the shared FSP header file.
- Modify to call copy_and_run() directly instead of returning to
cache_as_ram.inc.
Northbridge - fsp_sandybridge:
- remove mrccache, fsp_util.[ch]
- add fsp/chipset_fsp_util.[ch] with chipset specific FSP bits.
- Update to use the shared FSP header file.

These changes were validated with FSP:
CHIEFRIVER_FSP_GOLD_001_09-OCTOBER-2013.fd
SHA256: e1bbd614058675636ee45f8dc1a6dbf0e818bcdb32318b7f8d8b6ac0ce730801
MD5: 24965382fbb832f7b184d3f24157abda

Change-Id: Ibc52a78312c2fcbd1e632bc2484e4379a4f057d4
Signed-off-by: Martin Roth <gaumless@gmail.com>
Signed-off-by: Martin Roth <martin.roth@se-eng.com>
Reviewed-on: http://review.coreboot.org/5636
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
This commit is contained in:
Martin Roth 2014-04-25 15:09:27 -06:00 committed by Martin Roth
parent a6427161c2
commit 2dd3f877cc
18 changed files with 439 additions and 1186 deletions

View File

@ -28,6 +28,7 @@ if CPU_INTEL_FSP_MODEL_206AX || CPU_INTEL_FSP_MODEL_306AX
config CPU_SPECIFIC_OPTIONS
def_bool y
select PLATFORM_USES_FSP
select ARCH_BOOTBLOCK_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
@ -70,26 +71,4 @@ config MICROCODE_INCLUDE_PATH
default "../intel/cpu/ivybridge/microcode" if CPU_INTEL_FSP_MODEL_306AX
default "../intel/cpu/sandybridge/microcode" if CPU_INTEL_FSP_MODEL_206AX
config FSP_IMAGE_ID_DWORD0
hex
default 0x2D325453 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
default 0x2D324343 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
help
The FSP Image ID is different for each platform's FSP and can be used to
verify that the right FSP binary is loaded.
For the ivybridge/89xx FSP, the Image Id will be "ST2-FSP\0",
for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
This dword holds the first 4 bytes of the string, as
a hex value.
config FSP_IMAGE_ID_DWORD1
hex
default 0x00505346
help
For the ivybridge/I89xx FSP, the Image Id will be "ST2-FSP\0",
for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
This dword holds the second 4 bytes of the string, as
a hex value. Since the strings use the same second dword,
no additional logic is needed.
endif

View File

@ -7,9 +7,8 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
cpu_incs += $(src)/cpu/intel/fsp_model_206ax/cache_as_ram.inc
CC_bootblock := $(CC_bootblock) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
CC_romstage := $(CC_romstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
CC_ramstage := $(CC_ramstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
CC_x86_32 := $(CC_x86_32) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
ifneq ($(wildcard $(shell realpath -L "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
INCLUDES += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
endif
endif

View File

@ -1,292 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2007-2008 coresystems GmbH
* Copyright (C) 2013 Sage Electronic Engineering, LLC.
*
* 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
*/
#include <cpu/x86/stack.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
#include <cbmem.h>
#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
#define LHLT_DELAY 0x50000 /* delay between post codes on FSP failure */
#define NoEvictMod_MSR 0x2e0
cache_as_ram:
post_code(0x20)
/* Send INIT IPI to all excluding ourself. */
movl $0x000C4500, %eax
movl $0xFEE00300, %esi
movl %eax, (%esi)
/* All CPUs need to be in Wait for SIPI state */
wait_for_sipi:
movl (%esi), %eax
bt $12, %eax
jc wait_for_sipi
post_code(0x21)
/* Zero out all fixed range and variable range MTRRs. */
movl $mtrr_table, %esi
movl $((mtrr_table_end - mtrr_table) / 2), %edi
xorl %eax, %eax
xorl %edx, %edx
clear_mtrrs:
movw (%esi), %bx
movzx %bx, %ecx
wrmsr
add $2, %esi
dec %edi
jnz clear_mtrrs
/* Init floating point */
emms
fninit
/*
* Find the FSP binary in cbfs.
* Make a fake stack that has the return value back to this code.
*/
lea fake_fsp_stack, %esp
jmp find_fsp
find_fsp_ret:
/* Save the FSP location */
mov %eax, %ebp
cmp $CONFIG_FSP_LOC, %eax
jb halt1
post_code(0x22)
/* Calculate entry into FSP */
mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
/*
* Pass early init variables on a fake stack (no memory yet)
* as well as the return location
*/
lea CAR_init_stack, %esp
/* call FSP binary to setup temporary stack */
jmp *%eax
CAR_init_done:
addl $4, %esp
cmp $0, %eax
jne halt2
/* Save FSP_INFO_HEADER location in ebx */
mov %ebp, %ebx
/*
* setup bootloader stack
* ecx: stack base
* edx: stack top
*/
lea -4(%edx), %esp
movl %esp, %ebp
before_romstage:
post_code(0x23)
/* Call romstage.c main function. */
pushl %ebx
call main
romstage_main_return:
post_code(0x2f)
/* Disable cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
post_code(0x31)
/* Disable MTRR. */
movl $MTRRdefType_MSR, %ecx
rdmsr
andl $(~MTRRdefTypeEn), %eax
wrmsr
post_code(0x32)
/* Zero out all fixed range and variable range MTRRs. */
movl $mtrr_table, %esi
movl $((mtrr_table_end - mtrr_table) / 2), %edi
xorl %eax, %eax
xorl %edx, %edx
_clear_mtrrs_:
movw (%esi), %bx
movzx %bx, %ecx
wrmsr
add $2, %esi
dec %edi
jnz _clear_mtrrs_
post_code(0x33)
/* Enable cache. */
movl %cr0, %eax
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
movl %eax, %cr0
post_code(0x36)
/* Disable cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
post_code(0x38)
/* Enable Write Back and Speculative Reads for the first MB
* and ramstage.
*/
movl $MTRRphysBase_MSR(0), %ecx
movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
xorl %edx, %edx
wrmsr
movl $MTRRphysMask_MSR(0), %ecx
movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
movl $CPU_PHYSMASK_HI, %edx // 36bit address space
wrmsr
#if CACHE_ROM_SIZE
/* Enable Caching and speculative Reads for the
* complete ROM now that we actually have RAM.
*/
movl $MTRRphysBase_MSR(1), %ecx
movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
xorl %edx, %edx
wrmsr
movl $MTRRphysMask_MSR(1), %ecx
movl $(~(CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
movl $CPU_PHYSMASK_HI, %edx
wrmsr
#endif
post_code(0x39)
/* And enable cache again after setting MTRRs. */
movl %cr0, %eax
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
movl %eax, %cr0
post_code(0x3a)
/* Enable MTRR. */
movl $MTRRdefType_MSR, %ecx
rdmsr
orl $MTRRdefTypeEn, %eax
wrmsr
post_code(0x3d)
/* Clear boot_complete flag. */
xorl %ebp, %ebp
__main:
post_code(POST_PREPARE_RAMSTAGE)
cld /* Clear direction flag. */
movl %ebp, %esi
movl $ROMSTAGE_STACK, %esp
movl %esp, %ebp
pushl %esi
call copy_and_run
halt1:
/*
* Failures for postcode 0xBA - failed in find_fsp()
*
* Values are:
* 0x01 - FV signature, "_FVH" not present
* 0x02 - FFS GUID not present
* 0x03 - FSP INFO Header not found
* 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
* a different location, or does it need to be?
* 0x05 - FSP INFO Header signature "FSPH" not found
* 0x06 - FSP Image ID is not the expected ID.
* For ivybridge_bd82x6x, the ID is expected to be 'CC2-FSP\0'
* For ivybridge_i89xx, the ID is expected to be 'ST2-FSP\0'
*
*/
movb $0xBA, %ah
jmp .Lhlt
halt2:
/*
* Failures for postcode 0xBB - failed in the FSP:
*
* 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
* 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
* 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
* 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
* 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
* 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
*/
movb $0xBB, %ah
.Lhlt:
xchg %al, %ah
#if CONFIG_POST_IO
outb %al, $CONFIG_POST_IO_PORT
#else
post_code(POST_DEAD_CODE)
#endif
movl $LHLT_DELAY, %ecx
.Lhlt_Delay:
outb %al, $0xED
loop .Lhlt_Delay
jmp .Lhlt
.align 4
fake_fsp_stack:
.long find_fsp_ret
CAR_init_params:
.long CONFIG_CPU_MICROCODE_CBFS_LOC
.long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
.long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */
.long CONFIG_ROM_SIZE /* Total Firmware Length */
CAR_init_stack:
.long CAR_init_done
.long CAR_init_params
mtrr_table:
/* Fixed MTRRs */
.word 0x250, 0x258, 0x259
.word 0x268, 0x269, 0x26A
.word 0x26B, 0x26C, 0x26D
.word 0x26E, 0x26F
/* Variable MTRRs */
.word 0x200, 0x201, 0x202, 0x203
.word 0x204, 0x205, 0x206, 0x207
.word 0x208, 0x209, 0x20A, 0x20B
.word 0x20C, 0x20D, 0x20E, 0x20F
/* .word 0x210, 0x211, 0x212, 0x213 */
mtrr_table_end:

View File

@ -33,7 +33,7 @@
#include <console/console.h>
#include <reset.h>
#include "superio/smsc/sio1007/chip.h"
#include "northbridge/intel/fsp_sandybridge/fsp_util.h"
#include <fsp_util.h>
#include "northbridge/intel/fsp_sandybridge/northbridge.h"
#include "northbridge/intel/fsp_sandybridge/raminit.h"
#include "southbridge/intel/fsp_bd82x6x/pch.h"
@ -42,6 +42,7 @@
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "gpio.h"
#include <arch/stages.h>
static inline void reset_system(void)
{
@ -345,13 +346,9 @@ void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr) {
cbmemc_reinit();
#endif
/*
* FSP returns to this function instead of main, so we can't return back
* to the cache_as_ram.inc. Just jump there to finish the ramstage loading.
*/
asm volatile (
"jmp romstage_main_return\n"
);
/* Load the ramstage. */
copy_and_run();
while (1);
}
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)

View File

@ -28,15 +28,6 @@ config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE
if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
config HAVE_FSP_BIN
bool "Use Intel Firmware Support Package"
help
Select this option to add an Intel FSP binary to
the resulting coreboot image.
Note: Without this binary, coreboot builds relying on the FSP
will not boot
config VGA_BIOS_ID
string
default "8086,0106"
@ -47,32 +38,6 @@ config VGA_BIOS_ID
0x80860102, 0x8086010a, 0x80860112, 0x80860116
0x80860122, 0x80860126, 0x80860166
config DCACHE_RAM_BASE
hex
default 0xff7f0000
config DCACHE_RAM_SIZE
hex
default 0x10000
if HAVE_FSP_BIN
config FSP_FILE
string "Intel FSP binary path and filename"
default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
help
The path and filename of the Intel FSP binary for this platform.
config FSP_LOC
hex "Intel FSP Binary location in cbfs"
default 0xfff80000
help
The location in cbfs that the FSP is located. This must match the
value that is set in the FSP binary. If the FSP needs to be moved,
rebase the FSP with the Intel's BCT (tool).
config CBFS_SIZE
hex "Size of CBFS filesystem in ROM"
default 0x100000
@ -84,35 +49,7 @@ config CBFS_SIZE
This option specifies the maximum size of the CBFS portion in the
firmware image.
config ENABLE_FAST_BOOT
bool "Enable Fast Boot"
default y if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
help
Enabling this feature will cause MRC data to be cached in NV storage
which will speed up boot time on future reboots and/or power cycles.
config MRC_CACHE_SIZE
hex "MRC Data Cache Size"
default 0x10000
depends on ENABLE_FAST_BOOT
help
This is the amount of space in NV storage that is reserved for MRC data
cache storage when using fast boot.
config VIRTUAL_ROM_SIZE
hex "Virtual ROM Size"
default ROM_SIZE
depends on ENABLE_FAST_BOOT
help
This is used to calculate the offset of the MRC data cache in NV
Storage for "Fast Boot". If in doubt, leave this set to the default
which sets the virtual size equal to the ROM size.
Example: Cougar Canyon 2 has 2 8 MB SPI ROMs. When the SPI ROMs are
loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
size is 16 MB.
endif # HAVE_FSP_BIN
# Ivybridge Specific FSP Kconfig
source src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
endif # NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE

View File

@ -2,7 +2,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2010 Google Inc.
# Copyright (C) 2013 Sage Electronic Engineering, LLC.
# Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
#
# 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
@ -18,41 +18,20 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
subdirs-y += fsp
ramstage-y += northbridge.c
ramstage-y += gma.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
ramstage-y += fsp_util.c
ramstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
romstage-y += raminit.c
romstage-y += fsp_util.c
romstage-y += early_init.c
romstage-y += report_platform.c
romstage-y += ../../../arch/x86/lib/walkcbfs.S
romstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
ifeq ($(CONFIG_HAVE_FSP_BIN),y)
# We don't ship an FSP, but booting without it is bound to fail
cbfs-files-y += fsp.bin
fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
fsp.bin-position := $(CONFIG_FSP_LOC)
fsp.bin-type := 0xab
endif
ifeq ($(CONFIG_ENABLE_FAST_BOOT),y)
$(obj)/mrc.cache:
dd if=/dev/zero count=1 \
bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
tr '\000' '\377' > $@
cbfs-files-y += mrc.cache
mrc.cache-file := $(obj)/mrc.cache
mrc.cache-position := 0xfff50000
mrc.cache-type := 0xac
endif
INCLUDES += -I$(src)/northbridge/intel/fsp_sandybridge/fsp
$(obj)/northbridge/intel/fsp_sandybridge/acpi.ramstage.o : $(obj)/build.h

View File

@ -0,0 +1,42 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2014 Sage Electronic Engineering, LLC.
##
## 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
##
config SANDYBRIDGE_FSP_SPECIFIC_OPTIONS
def_bool y
select PLATFORM_USES_FSP
select USE_GENERIC_FSP_CAR_INC
select FSP_USES_UPD if SOUTHBRIDGE_INTEL_FSP_I89XX
config FSP_FILE
string
default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_BD82X6X
default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_I89XX
help
The path and filename of the Intel FSP binary for this platform.
config FSP_LOC
hex "Intel FSP Binary location in CBFS"
default 0xfff80000
help
The location in CBFS that the FSP is located. This must match the
value that is set in the FSP binary. If the FSP needs to be moved,
rebase the FSP with the Intel's BCT (tool).
The Ivy Bridge Processor/Panther Point FSP is built with a preferred
base address of 0xFFF80000

View File

@ -0,0 +1,22 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2014 Sage Electronic Engineering, LLC.
#
# 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
#
ramstage-y += chipset_fsp_util.c
romstage-y += chipset_fsp_util.c

View File

@ -0,0 +1,117 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
*
* 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
*/
#include <types.h>
#include <string.h>
#include <cpu/x86/stack.h>
#include <console/console.h>
#include <bootstate.h>
#include <cbmem.h>
#include <device/device.h>
#include <southbridge_pci_devs.h>
#include <fsp_util.h>
#include "../chip.h"
#include <reset.h>
#ifndef CONFIG_ENABLE_FSP_FAST_BOOT
# error "CONFIG_ENABLE_FSP_FAST_BOOT must be set."
#endif
#ifdef __PRE_RAM__
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData)
{
VPD_DATA_REGION *VpdDataRgnPtr;
UPD_DATA_REGION *UpdDataRgnPtr;
VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset + FspInfo->ImageBase);
UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32)(VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase);
memcpy((void*)UpdData, (void*)UpdDataRgnPtr, sizeof(UPD_DATA_REGION));
}
static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
{
UpdData->HTEnable = TRUE;
UpdData->TurboEnable = FALSE;
UpdData->MemoryDownEnable = FALSE;
UpdData->FastBootEnable = CONFIG_ENABLE_FSP_FAST_BOOT;
}
#else /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
const PLATFORM_CONFIG DefaultPlatformConfig = {
#if IS_ENABLED(CONFIG_DISABLE_SANDYBRIDGE_HYPERTHREADING)
FALSE, /* Hyperthreading */
#else
TRUE, /* Hyperthreading */
#endif
FALSE, /* Turbo Mode */
FALSE, /* Memory Down */
#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
TRUE, /* Fast Boot */
#else
FALSE, /* Fast Boot */
#endif /* CONFIG_ENABLE_FSP_FAST_BOOT */
};
#endif /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
/*
*
* Call the FSP to do memory init. The FSP doesn't return to this function.
* The FSP returns to the romstage_main_continue().
*
*/
void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
FSP_INFO_HEADER *fsp_ptr)
{
FSP_INIT_RT_BUFFER *pFspRtBuffer = FspInitParams->RtBufferPtr;
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
UPD_DATA_REGION *fsp_upd_data = pFspRtBuffer->Common.UpdDataRgnPtr;
#else
MEM_CONFIG MemoryConfig;
memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
#endif
FspInitParams->NvsBufferPtr = NULL;
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
/* Initialize the UPD Data */
GetUpdDefaultFromFsp (fsp_ptr, fsp_upd_data);/home/martin/extra/git/coreboot
ConfigureDefaultUpdData(fsp_upd_data);
#else
pFspRtBuffer->Platform.MemoryConfig = &MemoryConfig;
pFspRtBuffer->PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
#endif
#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
/* Find the fastboot cache that was saved in the ROM */
FspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
#endif
pFspRtBuffer->Common.BootMode = 0;
}
/* The FSP returns here after the fsp_early_init call */
void ChipsetFspReturnPoint(EFI_STATUS Status,
VOID *HobListPtr)
{
if (Status == 0xFFFFFFFF) {
hard_reset();
}
romstage_main_continue(Status, HobListPtr);
}
#endif /* __PRE_RAM__ */

View File

@ -0,0 +1,65 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
*
* 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
*/
#ifndef CHIPSET_FSP_UTIL_H
#define CHIPSET_FSP_UTIL_H
#include <fsptypes.h>
#include <fspfv.h>
#include <fspffs.h>
#include <fspapi.h>
#include <fspplatform.h>
#include <fspinfoheader.h>
#include <fsphob.h>
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
#include <peifsp.h>
#include <fsp_vpd.h>
#endif
#define FSP_RESERVE_MEMORY_SIZE 0x200000
#define FSP_INFO_HEADER_GUID \
{ \
0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
}
#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
{ \
0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
}
/*
*The FSP Image ID is different for each platform's FSP and
* can be used to verify that the right FSP binary is loaded.
*/
#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
/* ST2-FSP0 */
#define FSP_IMAGE_ID_DWORD0 0x2D325453
#define FSP_IMAGE_ID_DWORD1 0x30505346
#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X)
/* CC2-FSP\0 */
#define FSP_IMAGE_ID_DWORD0 0x2D324343
#define FSP_IMAGE_ID_DWORD1 0x00505346
#endif
void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr);
#endif /* CHIPSET_FSP_UTIL_H */

View File

@ -1,414 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Sage Electronic Engineering, LLC.
*
* 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
*/
#include <types.h>
#include <string.h>
#include <cpu/x86/stack.h>
#include <console/console.h>
#include <lib.h>
#include "fsp_util.h"
#if CONFIG_ENABLE_FAST_BOOT
#include <device/device.h>
#include "northbridge.h"
#include <cbmem.h>
#include <ip_checksum.h>
#endif
void find_fsp (void);
#ifndef __PRE_RAM__
/* Globals pointers for FSP structures */
void *FspHobListPtr;
FSP_INFO_HEADER *fsp_header_ptr;
void FspNotify (u32 Phase)
{
FSP_NOTFY_PHASE NotifyPhaseProc;
NOTIFY_PHASE_PARAMS NotifyPhaseParams;
EFI_STATUS Status;
if (fsp_header_ptr == NULL) {
find_fsp();
if (fsp_header_ptr == NULL) {
post_code(0x4F); /* output something in case there is no serial */
die("Can't find the FSP!\n");
}
}
/* call FSP PEI to Notify PostPciEnumeration */
NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase + fsp_header_ptr->NotifyPhaseEntry);
NotifyPhaseParams.Phase = Phase;
Status = NotifyPhaseProc (&NotifyPhaseParams);
if (Status != 0)
printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
}
#endif
#ifdef __PRE_RAM__
/*
*
* Call the FSP to do memory init. The FSP doesn't return to this function.
* The FSP returns to the romstage_main_continue().
*
*/
const PLATFORM_CONFIG DefaultPlatformConfig = {
TRUE, // Hyperthreading
FALSE, // Turbo Mode
FALSE, // Memory Down
#if CONFIG_ENABLE_FAST_BOOT
TRUE, // Fast Boot
#else
FALSE, // Fast Boot
#endif
};
void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
{
FSP_FSP_INIT FspInitApi;
FSP_INIT_PARAMS FspInitParams;
FSP_INIT_RT_BUFFER FspRtBuffer;
MEM_CONFIG MemoryConfig;
memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
FspRtBuffer.Platform.MemoryConfig = &MemoryConfig;
FspRtBuffer.PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
FspInitParams.NvsBufferPtr = NULL;
#if CONFIG_ENABLE_FAST_BOOT
/* find_current_mrc_cache */
struct mrc_data_container *mrc_cache = NULL;
if (((mrc_cache = find_current_mrc_cache()) == NULL) || (mrc_cache->mrc_data_size == -1UL)) {
printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
FspInitParams.NvsBufferPtr = (void *) NULL;
} else {
printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
printk(BIOS_SPEW, "Saved MRC data:\n");
hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, (mrc_cache->mrc_data_size / 4));
FspInitParams.NvsBufferPtr = (void *) (EFI_HOB_GUID_TYPE *) mrc_cache->mrc_data;
}
#endif
/* Not sure why passing BootMode is required - the only valid value is 0 */
FspRtBuffer.Common.BootMode = 0;
FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
FspInitParams.ContinuationFunc = (CONTINUATION_PROC)romstage_main_continue;
FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
/* call back to romstage.c here to allow structures to be changed */
romstage_fsp_rt_buffer_callback(&FspRtBuffer);
FspInitApi(&FspInitParams);
/* Should never return. Control will continue from ContinuationFunc */
die("Uh Oh! FspInitApi returned");
}
#endif
void __attribute__((optimize("O0"))) find_fsp ()
{
#ifdef __PRE_RAM__
volatile register u8 *fsp_ptr asm ("eax");
/* Entry point for CAR assembly routine */
__asm__ __volatile__ (
".global find_fsp\n\t"
"find_fsp:\n\t"
);
#else
u8 *fsp_ptr;
#endif
/* The FSP is stored in CBFS */
fsp_ptr = (u8 *) CONFIG_FSP_LOC;
/* Check the FV signature, _FVH */
if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
/* Go to the end of the FV header and align the address. */
fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
} else {
fsp_ptr = (u8*)ERROR_NO_FV_SIG;
}
/* Check the FFS GUID */
if (((u32)fsp_ptr > 0xff) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
/* Add the FFS Header size to the base to find the Raw section Header */
fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
} else {
fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
}
if (((u32)fsp_ptr > 0xff) &&
((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
/* Add the Raw Header size to the base to find the FSP INFO Header */
fsp_ptr += sizeof(EFI_RAW_SECTION);
} else {
fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
}
#if 0 /* removed for debugging */
/* Verify that the FSP is set to the base address we're expecting.*/
if (((u32)fsp_ptr > 0xff) &&
(*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
}
/* Verify the FSP Signature */
if (((u32)fsp_ptr > 0xff) &&
(*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
}
/* Verify the FSP ID */
if (((u32)fsp_ptr > 0xff) &&
(*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != CONFIG_FSP_IMAGE_ID_DWORD0)){
fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
}
if (((u32)fsp_ptr > 0xff) &&
(*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC + 4) != CONFIG_FSP_IMAGE_ID_DWORD1)) {
fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
}
#endif /* removed for debugging */
#ifdef __PRE_RAM__
__asm__ __volatile__ ("ret");
#else
fsp_header_ptr = (FSP_INFO_HEADER *) fsp_ptr;
printk(BIOS_SPEW,"fsp_header_ptr: 0x%x\n", (u32)fsp_header_ptr);
return;
#endif
}
void print_fsp_info(void) {
#ifndef __PRE_RAM__
if (fsp_header_ptr == NULL)
find_fsp();
printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
printk(BIOS_INFO,"FSP Revision: %d.%d\n",
(u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
(u8)(fsp_header_ptr->ImageRevision & 0xff));
#endif
}
#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
static void print_hob_mem_attributes(void *Hobptr) {
EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
const char * Hobmemtypenames[15];
Hobmemtypenames[0] = "EfiReservedMemoryType";
Hobmemtypenames[1] = "EfiLoaderCode";
Hobmemtypenames[2] = "EfiLoaderData";
Hobmemtypenames[3] = "EfiBootServicesCode";
Hobmemtypenames[4] = "EfiBootServicesData";
Hobmemtypenames[5] = "EfiRuntimeServicesCode";
Hobmemtypenames[6] = "EfiRuntimeServicesData";
Hobmemtypenames[7] = "EfiConventionalMemory";
Hobmemtypenames[8] = "EfiUnusableMemory";
Hobmemtypenames[9] = "EfiACPIReclaimMemory";
Hobmemtypenames[10] = "EfiACPIMemoryNVS";
Hobmemtypenames[11] = "EfiMemoryMappedIO";
Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
Hobmemtypenames[13] = "EfiPalCode";
Hobmemtypenames[14] = "EfiMaxMemoryType";
printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(long unsigned int)Hobmemaddr, (long unsigned int)Hobmemlength);
}
static void print_hob_resource_attributes(void *Hobptr) {
EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
u32 Hobrestype = HobResourcePtr->ResourceType;
u32 Hobresattr = HobResourcePtr->ResourceAttribute;
u64 Hobresaddr = HobResourcePtr->PhysicalStart;
u64 Hobreslength = HobResourcePtr->ResourceLength;
const char *Hobrestypestr = NULL;
// HOB Resource Types
switch (Hobrestype) {
case EFI_RESOURCE_SYSTEM_MEMORY:
Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
case EFI_RESOURCE_MEMORY_MAPPED_IO:
Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
case EFI_RESOURCE_IO:
Hobrestypestr = "EFI_RESOURCE_IO"; break;
case EFI_RESOURCE_FIRMWARE_DEVICE:
Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
case EFI_RESOURCE_MEMORY_RESERVED:
Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
case EFI_RESOURCE_IO_RESERVED:
Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
case EFI_RESOURCE_MAX_MEMORY_TYPE:
Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
default:
Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
}
printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
Hobrestypestr, Hobrestype, Hobresattr);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(long unsigned int)Hobresaddr, (long unsigned int)Hobreslength);
}
static const char * get_hob_type_string(void *Hobptr) {
EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
u16 Hobtype = HobHeaderPtr->HobType;
const char *Hobtypestring = NULL;
switch (Hobtype) {
case EFI_HOB_TYPE_HANDOFF:
Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
case EFI_HOB_TYPE_GUID_EXTENSION:
Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
case EFI_HOB_TYPE_MEMORY_POOL:
Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
case EFI_HOB_TYPE_UNUSED:
Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
case EFI_HOB_TYPE_END_OF_HOB_LIST:
Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
default:
Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
}
return Hobtypestring;
}
/* Print out a structure of all the HOBs
* that match a certain type:
* Print all types (0x0000)
* EFI_HOB_TYPE_HANDOFF (0x0001)
* EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
* EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
* EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
* EFI_HOB_TYPE_MEMORY_POOL (0x0007)
* EFI_HOB_TYPE_UNUSED (0xFFFE)
* EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
*/
void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
u32 *Currenthob;
u32 *Nexthob = 0;
u8 Lasthob = 0;
u32 Currenttype;
const char *Currenttypestr;
Currenthob = Hoblistptr;
/* Print out HOBs of our desired type until
* the end of the HOB list
*/
printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
(u32) Hoblistptr);
do {
EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Currenthob;
Currenttype = CurrentHeaderPtr->HobType; // Get the type of this HOB
Currenttypestr = get_hob_type_string(Currenthob);
if (Currenttype == Hobtype || Hobtype == 0x0000) {
printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
(u32) Currenthob, Currenttypestr, Currenttype);
switch (Currenttype) {
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
print_hob_mem_attributes(Currenthob); break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
print_hob_resource_attributes(Currenthob); break;
}
}
Lasthob = END_OF_HOB_LIST(Currenthob); // Check for end of HOB list
if (!Lasthob) {
Nexthob = GET_NEXT_HOB(Currenthob); // Get next HOB pointer
Currenthob = Nexthob; // Start on next HOB
}
} while (!Lasthob);
printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
}
#if CONFIG_ENABLE_FAST_BOOT
/**
* Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
*/
void save_mrc_data(void *hob_start)
{
u32 *mrc_hob;
u32 *mrc_hob_data;
u32 mrc_hob_size;
struct mrc_data_container *mrc_data;
int output_len;
const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
if (mrc_hob == NULL) die ("mrc_hob is NULL");
mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
(void *)mrc_hob_data, mrc_hob_size);
output_len = ALIGN(mrc_hob_size, 16);
/* Save the MRC S3/Fastboot/ADR restore data to cbmem */
mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
output_len + sizeof(struct mrc_data_container));
/* Just return if there was a problem with getting CBMEM */
if (mrc_data == NULL) return;
printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
(void *)mrc_hob_data, mrc_data, output_len);
mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
mrc_data->mrc_data_size = output_len;
mrc_data->reserved = 0;
memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
/* Zero the unused space in aligned buffer. */
if (output_len > mrc_hob_size)
memset((mrc_data->mrc_data + mrc_hob_size), 0,
output_len - mrc_hob_size);
mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
mrc_data->mrc_data_size);
printk(BIOS_SPEW, "MRC data in CBMEM(includes align and checksum):\n");
hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, (output_len / 4));
}
#endif
#endif /*__PRE_RAM__*/

View File

@ -1,88 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Sage Electronic Engineering, LLC.
*
* 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
*/
#ifndef FSP_UTIL_H
#define FSP_UTIL_H
#include <fsptypes.h>
#include <fspfv.h>
#include <fspffs.h>
#include <fspapi.h>
#include <fspplatform.h>
#include <fspinfoheader.h>
#include <fsphob.h>
void fsp_early_init(FSP_INFO_HEADER *fsp_info);
void FspNotify(u32 Phase);
void romstage_main_continue(EFI_STATUS Status, VOID *HobListPtr);
void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
void print_fsp_info(void);
#if CONFIG_ENABLE_FAST_BOOT
void save_mrc_data(void *hob_start);
#endif
/* Additional HOB types not included in the FSP:
* #define EFI_HOB_TYPE_HANDOFF 0x0001
* #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
* #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
* #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
* #define EFI_HOB_TYPE_FV 0x0005
* #define EFI_HOB_TYPE_CPU 0x0006
* #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
* #define EFI_HOB_TYPE_CV 0x0008
* #define EFI_HOB_TYPE_UNUSED 0xFFFE
* #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff
*/
#define EFI_HOB_TYPE_HANDOFF 0x0001
#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
#if CONFIG_ENABLE_FAST_BOOT
#define FSP_INFO_HEADER_GUID \
{ \
0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
}
#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
{ \
0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
}
#endif
/* The offset in bytes from the start of the info structure */
#define FSP_IMAGE_SIG_LOC 0
#define FSP_IMAGE_ID_LOC 16
#define FSP_IMAGE_BASE_LOC 28
#define FSP_SIG 0x48505346 /* 'FSPH' */
#define ERROR_NO_FV_SIG 1
#define ERROR_NO_FFS_GUID 2
#define ERROR_NO_INFO_HEADER 3
#define ERROR_IMAGEBASE_MISMATCH 4
#define ERROR_INFO_HEAD_SIG_MISMATCH 5
#define ERROR_FSP_SIG_MISMATCH 6
#ifndef __PRE_RAM__
extern void *FspHobListPtr;
#endif
#endif /* FSP_UTIL_H */

View File

@ -1,257 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2012 Google Inc.
* Copyright (C) 2013 Sage Electronic Engineering, LLC.
*
* 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
*/
#include <stdint.h>
#include <string.h>
#include <bootstate.h>
#include <console/console.h>
#include <cbfs.h>
#include <ip_checksum.h>
#include <device/device.h>
#include <cbmem.h>
#include "northbridge.h"
#include <spi-generic.h>
#include <spi_flash.h>
#include "fsp_util.h"
/* convert a pointer to flash area into the offset inside the flash */
static inline u32 to_flash_offset(void *p) {
return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
}
static struct mrc_data_container *next_mrc_block(
struct mrc_data_container *mrc_cache)
{
/* MRC data blocks are aligned within the region */
u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
mrc_size += MRC_DATA_ALIGN;
}
u8 *region_ptr = (u8*)mrc_cache;
region_ptr += mrc_size;
return (struct mrc_data_container *)region_ptr;
}
static int is_mrc_cache(struct mrc_data_container *mrc_cache)
{
return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
}
static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
{
size_t region_size;
*mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
"mrc.cache", 0xac,
&region_size);
return region_size;
}
/*
* Find the largest index block in the MRC cache. Return NULL if none is
* found.
*/
static struct mrc_data_container *find_current_mrc_cache_local
(struct mrc_data_container *mrc_cache, u32 region_size)
{
u32 region_end;
u32 entry_id = 0;
struct mrc_data_container *mrc_next = mrc_cache;
region_end = (u32) mrc_cache + region_size;
/* Search for the last filled entry in the region */
while (is_mrc_cache(mrc_next)) {
entry_id++;
mrc_cache = mrc_next;
mrc_next = next_mrc_block(mrc_next);
if ((u32)mrc_next >= region_end) {
/* Stay in the MRC data region */
break;
}
}
if (entry_id == 0) {
printk(BIOS_ERR, "%s: No valid MRC cache found.\n", __func__);
return NULL;
}
/* Verify checksum */
if (mrc_cache->mrc_checksum !=
compute_ip_checksum(mrc_cache->mrc_data,
mrc_cache->mrc_data_size)) {
printk(BIOS_ERR, "%s: MRC cache checksum mismatch\n", __func__);
return NULL;
}
printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
entry_id - 1);
return mrc_cache;
}
/* SPI code needs malloc/free.
* Also unknown if writing flash from XIP-flash code is a good idea
*/
#if !defined(__PRE_RAM__)
/* find the first empty block in the MRC cache area.
* If there's none, return NULL.
*
* @mrc_cache_base - base address of the MRC cache area
* @mrc_cache - current entry (for which we need to find next)
* @region_size - total size of the MRC cache area
*/
static struct mrc_data_container *find_next_mrc_cache
(struct mrc_data_container *mrc_cache_base,
struct mrc_data_container *mrc_cache,
u32 region_size)
{
u32 region_end = (u32) mrc_cache_base + region_size;
u32 mrc_data_size = mrc_cache->mrc_data_size;
mrc_cache = next_mrc_block(mrc_cache);
if (((u32)mrc_cache + mrc_data_size) >= region_end) {
/* Crossed the boundary */
mrc_cache = NULL;
printk(BIOS_DEBUG, "%s: no available entries found\n",
__func__);
} else {
printk(BIOS_DEBUG,
"%s: picked next entry from cache block at %p\n",
__func__, mrc_cache);
}
return mrc_cache;
}
static void update_mrc_cache(void *unused)
{
printk(BIOS_DEBUG, "Updating MRC cache data.\n");
struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
struct mrc_data_container *cache, *cache_base;
u32 cache_size;
if (!current) {
printk(BIOS_ERR, "No MRC cache in cbmem. Can't update flash.\n");
return;
}
if (current->mrc_data_size == -1) {
printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
return;
}
cache_size = get_mrc_cache_region(&cache_base);
if (cache_base == NULL) {
printk(BIOS_ERR, "%s: could not find MRC cache area\n",
__func__);
return;
}
/*
* we need to:
*/
// 0. compare MRC data to last mrc-cache block (exit if same)
cache = find_current_mrc_cache_local(cache_base, cache_size);
if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
(memcmp(cache, current, cache->mrc_data_size) == 0)) {
printk(BIOS_DEBUG,
"MRC data in flash is up to date. No update.\n");
return;
}
// 1. use spi_flash_probe() to find the flash, then
spi_init();
struct spi_flash *flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
if (!flash) {
printk(BIOS_DEBUG, "Could not find SPI device\n");
return;
}
// 2. look up the first unused block
if (cache)
cache = find_next_mrc_cache(cache_base, cache, cache_size);
/*
* 3. if no such place exists, erase entire mrc-cache range & use
* block 0. First time around the erase is not needed, but this is a
* small overhead for simpler code.
*/
if (!cache) {
printk(BIOS_DEBUG,
"Need to erase the MRC cache region of %d bytes at %p\n",
cache_size, cache_base);
flash->erase(flash, to_flash_offset(cache_base), cache_size);
/* we will start at the beginning again */
cache = cache_base;
}
// 4. write mrc data with flash->write()
printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
cache);
flash->write(flash, to_flash_offset(cache),
current->mrc_data_size + sizeof(*current), current);
}
static void find_fsp_hob(void *unused)
{
/* Set the global HOB list pointer */
FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
if (!FspHobListPtr){
printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
} else {
/* 0x0000: Print all types */
print_hob_type_structure(0x000, FspHobListPtr);
#if CONFIG_ENABLE_FAST_BOOT
save_mrc_data(FspHobListPtr);
update_mrc_cache(NULL);
#endif
}
}
BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
find_fsp_hob, NULL),
};
#endif /* !defined(__PRE_RAM__) */
struct mrc_data_container *find_current_mrc_cache(void)
{
struct mrc_data_container *cache_base;
u32 cache_size;
cache_size = get_mrc_cache_region(&cache_base);
if (cache_base == NULL) {
printk(BIOS_ERR, "%s: could not find MRC cache area\n",
__func__);
return NULL;
}
/*
* we need to:
*/
// 0. compare MRC data to last mrc-cache block (exit if same)
return find_current_mrc_cache_local(cache_base, cache_size);
}

View File

@ -36,7 +36,7 @@
#include <cbmem.h>
#include "chip.h"
#include "northbridge.h"
#include "fsp_util.h"
#include <fsp_util.h>
static int bridge_revision_id = -1;
static u8 finished_FSP_after_pci = 0;

View File

@ -226,15 +226,6 @@ void report_platform_info(void);
#define MRC_DATA_ALIGN 0x1000
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
struct mrc_data_container {
u32 mrc_signature; // "MRCD"
u32 mrc_data_size; // Actual total size of this structure
u32 mrc_checksum; // IP style checksum
u32 reserved; // For header alignment
u8 mrc_data[0]; // Variable size, platform/run time dependent.
} __attribute__ ((packed));
struct mrc_data_container *find_current_mrc_cache(void);
#if !defined(__PRE_RAM__)
#include "gma.h"
int init_igd_opregion(igd_opregion_t *igd_opregion);

View File

@ -0,0 +1,47 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2014 Sage Electronic Engineering, LLC.
*
* 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
*/
#ifndef _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
#define _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
#include <device/pci_def.h>
#define BUS0 0
/* NB PCIe PEG slot */
#define NB_PEG_DEV 0x01
#define NB_PEG_FUNC 0
# define NB_PEG_DEVFN PCI_DEVFN(NB_PEG_DEV, NB_PEG_FUNC)
#define PCIE_CTRL1_FUNC 1
# define PCIE_CTRL1_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL1_FUNC)
#define PCIE_CTRL2_FUNC 2
# define PCIE_CTRL2_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL2_FUNC)
/* Onboard Graphics */
#define GFX_DEV 0x02
#define GFX_FUNC 0
# define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC)
/* NB PCIe slot */
#define NB_PCIE_DEV 0x06
#define NB_PCIE_FUNC 0
# define NB_PCIE_DEVFN PCI_DEVFN(NB_PCIE_DEV, NB_PCIE_FUNC)
#endif /* _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ */

View File

@ -69,3 +69,5 @@ else
endif
PHONY += bd82x6x_add_me
INCLUDES += -I$(src)/southbridge/intel/fsp_bd82x6x

View File

@ -0,0 +1,127 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2014 Sage Electronic Engineering, LLC.
*
* 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
*/
#ifndef _INTEL_FSP_BD82X6X_PCI_DEVS_H_
#define _INTEL_FSP_BD82X6X_PCI_DEVS_H_
#include <device/pci_def.h>
#define BUS0 0
/* XHCI */
#define XHCI_DEV 0x14
#define XHCI_FUNC 0
# define XHCI_DEVFN PCI_DEVFN(XHCI_DEV, XHCI_FUNC)
/* Management Engine Interface */
#define MEI_DEV 0x16
#define MEI1_FUNC 0x0
# define MEI1_DEVFN PCI_DEVFN(MEI_DEV, MEI1_FUNC)
#define MEI2_FUNC 0x1
# define MEI2_DEVFN PCI_DEVFN(MEI_DEV, MEI2_FUNC)
/* MEI - IDE Redirection */
#define IDE_DEV 0x16
#define IDE_FUNC 2
# define IDE_DEVFN PCI_DEVFN(IDE_DEV, IDE_FUNC)
/* MEI - Keyboard / Text Redirection */
#define KT_DEV 0x16
#define KT_FUNC 0x3
#define KT_DEVFN PCI_DEVFN(KT_DEV, KT_FUNC)
/* Gigabit Ethernet */
#define GBE_DEV 0x19
#define GBE_FUNC 0x0
#define GBE_DEVFN PCI_DEVFN(GBE_DEV, GBE_FUNC)
/* EHCI */
#define EHCI1_DEV 0x1D
#define EHCI1_FUNC 0
# define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV, EHCI1_FUNC)
#define EHCI2_DEV 0x1A
#define EHCI2_FUNC 0
# define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV, EHCI2_FUNC)
/* HD Audio */
#define HDA_DEV 0x1B
#define HDA_FUNC 0
# define HDA_DEVFN PCI_DEVFN(HDA_DEV, HDA_FUNC)
/* PCIe Ports */
#define SB_PCIE_DEV 0x1C
#define SB_PCIE_PORT1_FUNC 0
# define SB_PCIE_PORT1_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT1_FUNC)
#define SB_PCIE_PORT2_FUNC 1
# define SB_PCIE_PORT2_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT2_FUNC)
#define SB_PCIE_PORT3_FUNC 2
# define SB_PCIE_PORT3_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT3_FUNC)
#define SB_PCIE_PORT4_FUNC 3
# define SB_PCIE_PORT4_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT4_FUNC)
#define SB_PCIE_PORT5_FUNC 4
# define SB_PCIE_PORT5_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT5_FUNC)
#define SB_PCIE_PORT6_FUNC 5
# define SB_PCIE_PORT6_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT6_FUNC)
#define SB_PCIE_PORT7_FUNC 6
# define SB_PCIE_PORT7_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT7_FUNC)
#define SB_PCIE_PORT8_FUNC 7
# define SB_PCIE_PORT8_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT8_FUNC)
/* PCI Bridge */
#define SB_PCI_DEV 0x1E
#define SB_PCI_PORT_FUNC 0
# define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV, SB_PCI_PORT_FUNC)
/* Platform Controller Hub */
#define PCH_DEV 0x1F
/* LPC */
#define LPC_DEV PCH_DEV
#define LPC_FUNC 0
# define LPC_DEVFN PCI_DEVFN(LPC_DEV, LPC_FUNC)
/* SMBUS */
#define SMBUS_DEV PCH_DEV
#define SMBUS_FUNC 3
# define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)
/* SATA */
#define SATA_DEV PCH_DEV
#define SATA1_FUNC 2
# define SATA1_DEVFN PCI_DEVFN(SATA_DEV, SATA1_FUNC)
#define SATA2_FUNC 5
# define SATA2_DEVFN PCI_DEVFN(SATA_DEV, SATA2_FUNC)
/* Thermal Sensor */
#define TS_DEV PCH_DEV
#define TS_FUNC 6
# define TS_DEVFN PCI_DEVFN(TS_DEV, TS_FUNC)
#endif /* _INTEL_FSP_BD82X6X_PCI_DEVS_H_ */