soc/intel/quark: Add C bootblock

Add a bootblock which builds with C_ENVIRONMENT_BOOTBLOCK selected.
This is the first piece in supporting FSP 2.0.  Move esraminit from
romstage into the bootblock.  Replace cache_as_ram with
car_stage_entry.S and code in romstage.c

TEST=Build and run on Galileo Gen2

Change-Id: I14d2af2adb6e75d4bff1ebfb863196df04d07daf
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: https://review.coreboot.org/15132
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Lee Leahy 2016-06-05 18:48:31 -07:00 committed by Leroy P Leahy
parent 6c3c31e49d
commit ce9e21a0ea
10 changed files with 283 additions and 284 deletions

View File

@ -26,6 +26,8 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_RAMSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_VERSTAGE_X86_32
select BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP
select C_ENVIRONMENT_BOOTBLOCK
select REG_SCRIPT
select SOC_INTEL_COMMON
select SOC_SETS_MTRRS
@ -261,4 +263,17 @@ config RMU_LOC
The location in CBFS that the RMU is located. It must match the
strap-determined base address.
#####
# Bootblock
# The following options support the C_ENVIRONMENT_BOOTBLOCK.
#####
config DCACHE_BSP_STACK_SIZE
hex
default 0x4000
config C_ENV_BOOTBLOCK_SIZE
hex
default 0x8000
endif # SOC_INTEL_QUARK

View File

@ -18,6 +18,13 @@ ifeq ($(CONFIG_SOC_INTEL_QUARK),y)
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/tsc
bootblock-y += bootblock/esram_init.S
bootblock-y += bootblock/bootblock.c
bootblock-y += i2c.c
bootblock-y += reg_access.c
bootblock-y += tsc_freq.c
bootblock-y += uart_common.c
romstage-y += i2c.c
romstage-y += memmap.c
romstage-y += reg_access.c

View File

@ -0,0 +1,77 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 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; 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.
*/
#include <bootblock_common.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <program_loading.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/reg_access.h>
static const struct reg_script clear_smi_and_wake_events[] = {
/* Clear any SMI or wake events */
REG_GPE0_READ(R_QNC_GPE0BLK_GPE0S),
REG_GPE0_READ(R_QNC_GPE0BLK_SMIS),
REG_GPE0_OR(R_QNC_GPE0BLK_GPE0S, B_QNC_GPE0BLK_GPE0S_ALL),
REG_GPE0_OR(R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_ALL),
REG_SCRIPT_END
};
static const struct reg_script legacy_gpio_init[] = {
/* Temporarily enable the legacy GPIO controller */
REG_PCI_WRITE32(R_QNC_LPC_GBA_BASE, IO_ADDRESS_VALID
| LEGACY_GPIO_BASE_ADDRESS),
/* Temporarily enable the GPE controller */
REG_PCI_WRITE32(R_QNC_LPC_GPE0BLK, IO_ADDRESS_VALID
| GPE0_BASE_ADDRESS),
REG_PCI_OR8(PCI_COMMAND, PCI_COMMAND_IO),
REG_SCRIPT_END
};
static const struct reg_script i2c_gpio_controller_init[] = {
/* Temporarily enable the GPIO controller */
REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, I2C_BASE_ADDRESS),
REG_PCI_WRITE32(PCI_BASE_ADDRESS_1, GPIO_BASE_ADDRESS),
REG_PCI_OR8(PCI_COMMAND, PCI_COMMAND_MEMORY),
REG_SCRIPT_END
};
static const struct reg_script hsuart_init[] = {
/* Enable the HSUART */
REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, UART_BASE_ADDRESS),
REG_PCI_OR8(PCI_COMMAND, PCI_COMMAND_MEMORY),
REG_SCRIPT_END
};
void bootblock_soc_early_init(void)
{
/* Initialize the controllers */
reg_script_run_on_dev(I2CGPIO_BDF, i2c_gpio_controller_init);
reg_script_run_on_dev(LPC_BDF, legacy_gpio_init);
/* Enable the HSUART */
if (IS_ENABLED(CONFIG_ENABLE_BUILTIN_HSUART0))
reg_script_run_on_dev(HSUART0_BDF, hsuart_init);
if (IS_ENABLED(CONFIG_ENABLE_BUILTIN_HSUART1))
reg_script_run_on_dev(HSUART1_BDF, hsuart_init);
}
void platform_prog_run(struct prog *prog)
{
/* Display the program entry point */
printk(BIOS_SPEW, "Calling %s, 0x%p(0x%p)\n", prog->name,
prog->entry, prog->arg);
}

View File

@ -29,7 +29,9 @@
**/
#include <cpu/x86/cr.h>
#include <cpu/x86/post_code.h>
#include <soc/QuarkNcSocId.h>
#include <soc/sd.h>
.macro RET32
jmp *%esp
@ -97,16 +99,36 @@
.equ CFGNONSTICKY_W1_OFFSET, (0x52)
.equ FORCE_WARM_RESET, (0x00000001)
verify_bist:
cmp $0, %eax
je setup_esram
mov $POST_DEAD_CODE, %eax
#if IS_ENABLED(CONFIG_POST_IO)
outb %al, $CONFIG_POST_IO_PORT
#else
post_code(POST_DEAD_CODE)
#endif
jmp .
.global bootblock_save_bist_and_timestamp
bootblock_save_bist_and_timestamp:
/* eax: Low 32-bits of timestamp
* ebx: BIST result
* ebp: return address
* edx: High 32-bits of timestamp
*/
/* No values to save since Quark does not generate a BIST value
* and the timestamp is not saved since future expansion in
* bootblock_crt0.S could use ebp and edi. This code prevents
* the use of the MMx registers by the default implementation.
*/
jmp *%ebp
.global bootblock_pre_c_entry
bootblock_pre_c_entry:
/* Get the timestamp since value from bootblock_crt0.S was discarded */
rdtsc
movl %eax, %ebp
movl %edx, %edi
/* Registers:
* ebp: Low 32-bits of timestamp
* edi: High 32-bits of timestamp
*/
setup_esram:
/* Ensure cache is disabled. */
@ -452,28 +474,9 @@ stackless_PCIConfig_Read:
esram_init_done:
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)
/* Copy FSP image to eSRAM and call it. */
/* TODO: FSP location/size could be got in a routine. */
cld
movl $(0x00040000), %ecx /* 256K DWORDs = 64K */
shrl $2, %ecx
movl $CONFIG_FSP_LOC, %esi /* The source address. */
movl $CONFIG_FSP_ESRAM_LOC, %edi /* FSP destination in ESRAM */
rep movsl
#endif /* CONFIG_PLATFORM_USES_FSP1_1 */
#if IS_ENABLED(CONFIG_ENABLE_DEBUG_LED)
sd_led:
.equ SD_PFA, (0x14 << 11) /* B0:D20:F0 - SDIO controller */
.equ SD_CFG_BASE, (PCI_CFG | SD_PFA) /* SD cntrl base in PCI config space */
.equ SD_CFG_CMD, (SD_CFG_BASE+0x04) /* Command reg in PCI config space */
.equ SD_CFG_ADDR, (SD_CFG_BASE+0x10) /* Base address in PCI config space */
.equ SD_BASE_ADDR, (0xA0018000) /* SD controller's base address */
.equ SD_HOST_CTRL, (SD_BASE_ADDR+0x28) /* HOST_CTRL register */
/* Set the SDIO controller's base address */
movl $(SD_BASE_ADDR), %eax
movl $(SD_CFG_ADDR), %ebx
@ -514,3 +517,23 @@ L44:
jmp .
#endif /* CONFIG_ENABLE_DEBUG_LED_ESRAM */
#endif /* CONFIG_ENABLE_DEBUG_LED */
/* Registers:
* ebp: Low 32-bits of timestamp
* edi: High 32-bits of timestamp
*/
/* Setup bootblock stack */
movl $_car_stack_end, %esp
before_carstage:
post_code(0x2b)
/* Get the timestamp passed in bootblock_crt0.S */
push %edi
push %ebp
/* We can call into C functions now */
call bootblock_main_with_timestamp
/* Never reached */

View File

@ -25,6 +25,7 @@
#include <fsp/romstage.h>
#include <soc/reg_access.h>
asmlinkage void *car_state_c_entry(void);
uint32_t port_reg_read(uint8_t port, uint32_t offset);
void port_reg_write(uint8_t port, uint32_t offset, uint32_t value);
void report_platform_info(void);

View File

@ -0,0 +1,26 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 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 _QUARK_SD_H_
#define _QUARK_SD_H_
#define SD_PFA (0x14 << 11) /* B0:D20:F0 - SDIO controller */
#define SD_CFG_BASE (PCI_CFG | SD_PFA) /* SD cntrl base in PCI config space */
#define SD_CFG_CMD (SD_CFG_BASE+0x04) /* Command reg in PCI config space */
#define SD_CFG_ADDR (SD_CFG_BASE+0x10) /* Base address in PCI config space */
#define SD_BASE_ADDR (0xA0018000) /* SD controller's base address */
#define SD_HOST_CTRL (SD_BASE_ADDR+0x28) /* HOST_CTRL register */
#endif /* _QUARK_SD_H_ */

View File

@ -13,9 +13,7 @@
# GNU General Public License for more details.
#
cpu_incs-y += $(src)/soc/intel/quark/romstage/esram_init.inc
cpu_incs-y += $(src)/soc/intel/quark/romstage/cache_as_ram.inc
romstage-y += car_stage_entry.S
romstage-y += mtrr.c
romstage-y += pcie.c
romstage-y += report_platform.c

View File

@ -1,252 +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-2014 Sage Electronic Engineering, LLC.
* Copyright (C) 2015-2016 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.
*/
/*
* Replacement for cache_as_ram.inc when using the FSP binary. This code
* locates the FSP binary, initializes the cache as RAM and performs the
* first stage of initialization. Next this code switches the stack from
* the cache to RAM and then disables the cache as RAM. Finally this code
* performs the final stage of initialization.
*/
#include <rules.h>
/*
* eax: BIST value
*/
movl %eax, %edi
cache_as_ram:
post_code(0x20)
/*
* edi: BIST value
*/
/*
* 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
/*
* Only when a valid FSP binary is found at CONFIG_FSP_LOC is
* the returned FSP_INFO_HEADER structure address above the base
* address of FSP binary specified by the CONFIG_FSP_LOC value.
* All of the error values are in the 0x8xxxxxxx range which are
* below the CONFIG_FSP_LOC value.
*/
cmp $CONFIG_FSP_ESRAM_LOC, %eax
jbe halt1
post_code(POST_FSP_TEMP_RAM_INIT)
#if IS_ENABLED(CONFIG_ENABLE_DEBUG_LED_FINDFSP)
movl $SD_HOST_CTRL, %ebx
movb 0(%ebx), %al
orb $1, %al
movb %al, 0(%ebx)
jmp .
#endif /* CONFIG_ENABLE_DEBUG_LED_FINDFSP */
/* Calculate entry into FSP */
mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
add 0x1c(%ebp), %eax /* add in the offset for FSP */
/*
* Pass early init variables on a fake stack (no memory yet)
* as well as the return location
*/
lea CAR_init_stack, %esp
/*
* BIST value is zero
* eax: TempRamInitApi address
* ebp: FSP_INFO_HEADER address
* edi: BIST value
* esi: Not used
*/
/* call FSP binary to setup temporary stack */
jmp *%eax
CAR_init_done:
addl $4, %esp
/*
* ebp: FSP_INFO_HEADER address
* ecx: Temp RAM base
* edx: Temp RAM top
* edi: BIST value
*/
cmp $0, %eax
jne halt2
#if IS_ENABLED(CONFIG_ENABLE_DEBUG_LED_TEMPRAMINIT)
movl %edx, %esi
movl $SD_HOST_CTRL, %ebx
movb 0(%ebx), %al
orb $1, %al
movb %al, 0(%ebx)
movl %esi, %edx
jmp .
#endif /* CONFIG_ENABLE_DEBUG_LED_TEMPRAMINIT */
/* Set up bootloader stack */
movl %edx, %esp
/*
* eax: 0
* ebp: FSP_INFO_HEADER address
* ecx: Temp RAM base
* edx: Temp RAM top
* edi: BIST value
* esp: Top of stack in temp RAM
*/
/* Create cache_as_ram_params on stack */
pushl %edx /* bootloader CAR end */
pushl %ecx /* bootloader CAR begin */
pushl %ebp /* FSP_INFO_HEADER */
pushl $0 /* BIST - esram_init.inc catches non-zero BIST values */
/* TODO: Locate 64-bits of storage for initial TSC value */
pushl $0 /* tsc[63:32] */
pushl $0 /* tsc[31:0] */
pushl %esp /* pointer to cache_as_ram_params */
/* Save FSP_INFO_HEADER location in ebx */
mov %ebp, %ebx
/* Coreboot assumes stack/heap region will be zero */
cld
movl %ecx, %edi
neg %ecx
/* Only clear up to current stack value. */
add %esp, %ecx
shrl $2, %ecx
xorl %eax, %eax
rep stosl
before_romstage:
post_code(0x2A)
/* Call cache_as_ram_main(struct cache_as_ram_params *) */
call cache_as_ram_main
/* One will never return from cache_as_ram_main() in verstage so there's
* no such thing as after ram init. */
#if !ENV_VERSTAGE
#include "src/drivers/intel/fsp1_1/after_raminit.S"
#endif
movb $0x69, %ah
jmp .Lhlt
halt1:
/*
* Failures for postcode 0xBA - failed in fsp_fih_early_find()
*
* 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.
*/
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.
* 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
* 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
* 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
* 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
*/
movb $0xBB, %ah
jmp .Lhlt
#----------------------------------------------------------------------------
#
# Procedure: .Lhlt
#
# Input: ah - Upper 8-bits of POST code
# al - Lower 8-bits of POST code
#
# Description:
# Infinite loop displaying alternating POST code values
#
#----------------------------------------------------------------------------
#define FLASH_DELAY 0x1000 /* I/O delay between post codes on failure */
#define POST_DELAY 0x50
.Lhlt:
xchg %al, %ah
mov $POST_DELAY, %dh
#if IS_ENABLED(CONFIG_POST_IO)
outb %al, $CONFIG_POST_IO_PORT
#else
post_code(POST_DEAD_CODE)
#endif
.flash_setup:
movl $FLASH_DELAY, %ecx
.flash_delay:
outb %al, $0xED
loop .flash_delay
#if IS_ENABLED(CONFIG_ENABLE_DEBUG_LED_FINDFSP)
movl $SD_HOST_CTRL, %ebx
movb 0(%ebx), %dl
xorb $1, %dl
movb %dl, 0(%ebx)
#endif /* CONFIG_ENABLE_DEBUG_LED_FINDFSP */
decb %dh
jnz .flash_setup
jmp .Lhlt
/*
* esp is set to this location so that the call into and return from the FSP
* in find_fsp will work.
*/
.align 4
fake_fsp_stack:
.long find_fsp_ret
.long CONFIG_FSP_ESRAM_LOC /* FSP base address */
CAR_init_params:
.long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */
.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

View File

@ -0,0 +1,76 @@
/*
* 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-2014 Sage Electronic Engineering, LLC.
* Copyright (C) 2015-2016 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.
*
* Replacement for cache_as_ram.inc when using the C environment boot block.
*/
#include <rules.h>
#include <soc/sd.h>
.section ".text"
.global car_stage_entry
car_stage_entry:
/* Enter the C code */
call car_state_c_entry
#if !ENV_VERSTAGE
#include "src/drivers/intel/fsp1_1/after_raminit.S"
#endif
/* The code should never reach this point */
movb $0x69, %ah
jmp .Lhlt
#----------------------------------------------------------------------------
#
# Procedure: .Lhlt
#
# Input: ah - Upper 8-bits of POST code
# al - Lower 8-bits of POST code
#
# Description:
# Infinite loop displaying alternating POST code values
#
#----------------------------------------------------------------------------
#define FLASH_DELAY 0x1000 /* I/O delay between post codes on failure */
#define POST_DELAY 0x50
.Lhlt:
xchg %al, %ah
mov $POST_DELAY, %dh
#if IS_ENABLED(CONFIG_POST_IO)
outb %al, $CONFIG_POST_IO_PORT
#else
post_code(POST_DEAD_CODE)
#endif
.flash_setup:
movl $FLASH_DELAY, %ecx
.flash_delay:
outb %al, $0xED
loop .flash_delay
#if IS_ENABLED(CONFIG_ENABLE_DEBUG_LED)
movl $SD_HOST_CTRL, %ebx
movb 0(%ebx), %dl
xorb $1, %dl
movb %dl, 0(%ebx)
#endif /* CONFIG_ENABLE_DEBUG_LED */
decb %dh
jnz .flash_setup
jmp .Lhlt

View File

@ -29,6 +29,7 @@
#include <soc/pm.h>
#include <soc/romstage.h>
#include <soc/reg_access.h>
#include <string.h>
static const struct reg_script clear_smi_and_wake_events[] = {
/* Clear any SMI or wake events */
@ -65,6 +66,33 @@ static const struct reg_script hsuart_init[] = {
REG_SCRIPT_END
};
asmlinkage void *car_state_c_entry(void)
{
post_code(0x20);
if (IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)) {
FSP_INFO_HEADER *fih;
struct cache_as_ram_params car_params = {0};
void *top_of_stack;
/* Copy the FSP binary into ESRAM */
memcpy((void *)CONFIG_FSP_ESRAM_LOC, (void *)CONFIG_FSP_LOC,
0x00040000);
/* Locate the FSP header in ESRAM */
fih = find_fsp(CONFIG_FSP_ESRAM_LOC);
/* Start the early verstage/romstage code */
post_code(0x2A);
car_params.fih = fih;
top_of_stack = cache_as_ram_main(&car_params);
/* Initialize MTRRs and switch stacks after RAM initialized */
return top_of_stack;
}
return NULL;
}
void car_soc_pre_console_init(void)
{
/* Initialize the controllers */