soc/amd/common: Convert to C_ENVIRONMENT_BOOTBLOCK

Add dedicated CAR setup and teardown functions and Kconfig
options to force their inclusion into the build.  The .S files
are mostly duplicated code from the old cache_as_ram.inc file.

The .S files use global proc names in anticipation for use with
the Kconfig symbols C_ENVIRONMENT_BOOTBLOCK and POSTCAR_STAGE.

Move the mainboard romstage functionality into the soc directory
and change the function name to be compatible with the call
from assembly_entry.S.  Drop the BIST check like other devices.

Move InitReset and InitEarly to bootblock.  These AGESA entry
points set some default settings, and release/recapture the
AP cores.  There are currently some early dependencies on
InitReset.  Future work should include:
 * Pull the necessary functionality from InitReset into bootblock
 * Move InitReset and InitEarly to car_stage_entry() and out of
   bootblock
   - Add a mechanism for the BSP to give the APs an address
     to call and skip most of bootblock and verstage (when
     available) (1)
   - Reunify BiosCallOuts.c and OemCustomize.c

(1) During the InitReset call, the BSP enables the APs by setting
    core enable bits in F18F0x1DC and APs begin fetching/executing
    from the reset vector.  The BSP waits for all APs to also
    reach InitReset, where they enter an endless loop.  The BSP
    sends a command to them to execute a HLT instruction and the
    BSP eventually returns from InitReset.  The goal would be to
    preserve this process but prevent APs from rerunning early
    code.

Change-Id: I811c7ef875b980874f3c4b1f234f969ae5618c44
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/19755
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Marshall Dawson
2017-07-25 18:46:46 -06:00
committed by Martin Roth
parent c95d6ffa7c
commit 9df969aebf
20 changed files with 521 additions and 490 deletions

View File

@@ -1,6 +1,8 @@
ifeq ($(CONFIG_SOC_AMD_COMMON),y)
cpu_incs-y += $(src)/soc/amd/common/cache_as_ram.inc
bootblock-y += agesawrapper.c
bootblock-y += def_callouts.c
bootblock-y += heapmanager.c
romstage-y += agesawrapper.c
romstage-y += def_callouts.c

View File

@@ -0,0 +1,8 @@
config SOC_AMD_COMMON_BLOCK_CAR
bool
default n
help
This option allows the SOC to use a standard AMD cache-as-ram (CAR)
implementation. CAR setup is built into bootblock and teardown in
romstage. If it is not used the system must implement these functions
separately.

View File

@@ -0,0 +1,2 @@
bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/cache_as_ram.S
romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CAR) += car/exit_car.S

View File

@@ -0,0 +1,59 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Advanced Micro Devices, Inc.
*
* 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.
*/
/******************************************************************************
* $Workfile:: cache_as_ram.S
*
* Description: CAR setup called from bootblock_crt0.S.
*
******************************************************************************
*/
#include "gcccar.inc"
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
/*
* on entry:
* mm0: BIST (ignored)
* mm2_mm1: timestamp at bootblock_protected_mode_entry
*/
.global bootblock_pre_c_entry
bootblock_pre_c_entry:
post_code(0xa0)
AMD_ENABLE_STACK
/* Align the stack and keep aligned for call to bootblock_c_entry() */
and $0xfffffff0, %esp
sub $8, %esp
movd %mm2, %eax
pushl %eax /* tsc[63:32] */
movd %mm1, %eax
pushl %eax /* tsc[31:0] */
before_carstage:
post_code(0xa2)
call bootblock_c_entry
/* Never reached */
.halt_forever:
post_code(POST_DEAD_CODE)
hlt
jmp .halt_forever

View File

@@ -0,0 +1,36 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Advanced Micro Devices, Inc.
*
* 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 <gcccar.inc>
#include <cpu/x86/cache.h>
.code32
.globl chipset_teardown_car
chipset_teardown_car:
/* Disable cache */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
AMD_DISABLE_STACK
/* enable cache */
movl %cr0, %eax
andl $(~(CR0_CD | CR0_NW)), %eax
movl %eax, %cr0
ret

View File

@@ -1,170 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Advanced Micro Devices, Inc.
*
* 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.
*/
/******************************************************************************
* AMD Generic Encapsulated Software Architecture
*
* $Workfile:: cache_as_ram.inc
*
* Description: cache_as_ram.inc - AGESA Module Entry Point for GCC complier
*
******************************************************************************
*/
#include "gcccar.inc"
#include <cpu/x86/cache.h>
/*
* XMM map:
* xmm0: BIST
* xmm1: backup ebx -- cpu_init_detected
*/
.code32
.globl cache_as_ram_setup, disable_cache_as_ram, cache_as_ram_setup_out
cache_as_ram_setup:
post_code(0xa0)
/* enable SSE2 128bit instructions */
/* Turn on OSFXSR [BIT9] and OSXMMEXCPT [BIT10] onto CR4 register */
movl %cr4, %eax
orl $(3<<9), %eax
movl %eax, %cr4
/* Get the cpu_init_detected */
mov $1, %eax
cpuid
shr $24, %ebx
/* Save the BIST result */
cvtsi2sd %ebp, %xmm0
/* for normal part %ebx already contain cpu_init_detected from fallback call */
/* Save the cpu_init_detected */
cvtsi2sd %ebx, %xmm1
post_code(0xa1)
AMD_ENABLE_STACK
/* Align the stack. */
and $0xfffffff0, %esp
#ifdef __x86_64__
/* switch to 64 bit long mode */
mov %esi, %ecx
add $0, %ecx # core number
xor %eax, %eax
lea (0x1000+0x23)(%ecx), %edi
mov %edi, (%ecx)
mov %eax, 4(%ecx)
lea 0x1000(%ecx), %edi
movl $0x000000e3, 0x00(%edi)
movl %eax, 0x04(%edi)
movl $0x400000e3, 0x08(%edi)
movl %eax, 0x0c(%edi)
movl $0x800000e3, 0x10(%edi)
movl %eax, 0x14(%edi)
movl $0xc00000e3, 0x18(%edi)
movl %eax, 0x1c(%edi)
# load ROM based identity mapped page tables
mov %ecx, %eax
mov %eax, %cr3
# enable PAE
mov %cr4, %eax
bts $5, %eax
mov %eax, %cr4
# enable long mode
mov $0xC0000080, %ecx
rdmsr
bts $8, %eax
wrmsr
# enable paging
mov %cr0, %eax
bts $31, %eax
mov %eax, %cr0
# use call far to switch to 64-bit code segment
ljmp $0x18, $1f
1:
/* Pass the cpu_init_detected */
cvtsd2si %xmm1, %esi
/* Pass the BIST result */
cvtsd2si %xmm0, %edi
.code64
call cache_as_ram_main
.code32
#else
/* Restore the BIST result */
cvtsd2si %xmm0, %edx
/* Restore the cpu_init_detected */
cvtsd2si %xmm1, %ebx
/* Must maintain 16-byte stack alignment here. */
pushl $0x0
pushl $0x0
pushl %ebx /* init detected */
pushl %edx /* bist */
call cache_as_ram_main
#endif
/* Should never see this postcode */
post_code(0xaf)
stop:
jmp stop
disable_cache_as_ram:
/* Save return stack */
movd 0(%esp), %xmm1
movd %esp, %xmm0
/* Disable cache */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
AMD_DISABLE_STACK
/* enable cache */
movl %cr0, %eax
andl $0x9fffffff, %eax
movl %eax, %cr0
xorl %eax, %eax
/* Restore the return stack */
wbinvd
movd %xmm0, %esp
movd %xmm1, (%esp)
ret
cache_as_ram_setup_out:
#ifdef __x86_64__
.code64
#endif

View File

@@ -40,10 +40,14 @@ config CPU_SPECIFIC_OPTIONS
select TSC_CONSTANT_RATE
select SPI_FLASH if HAVE_ACPI_RESUME
select TSC_SYNC_LFENCE
select COLLECT_TIMESTAMPS
select SOC_AMD_PI
select SOC_AMD_COMMON
select SOC_AMD_COMMON_BLOCK
select SOC_AMD_COMMON_BLOCK_PSP
select SOC_AMD_COMMON_BLOCK_CAR
select C_ENVIRONMENT_BOOTBLOCK
select BOOTBLOCK_CONSOLE
config UDELAY_LAPIC_FIXED_FSB
int
@@ -61,6 +65,14 @@ config DCACHE_RAM_SIZE
hex
default 0x10000
config DCACHE_BSP_STACK_SIZE
depends on C_ENVIRONMENT_BOOTBLOCK
hex
default 0x4000
help
The amount of anticipated stack usage in CAR by bootblock and
other stages.
config CPU_ADDR_BITS
int
default 48
@@ -124,10 +136,6 @@ config RAMBASE
hex
default 0x200000
config BOOTBLOCK_SOUTHBRIDGE_INIT
string
default "soc/amd/stoneyridge/bootblock/bootblock.c"
config SOUTHBRIDGE_AMD_STONEYRIDGE_SKIP_ISA_DMA_INIT
bool
default n

View File

@@ -37,6 +37,13 @@ subdirs-y += ../../../cpu/x86/mtrr
subdirs-y += ../../../cpu/x86/pae
subdirs-y += ../../../cpu/x86/smm
bootblock-$(CONFIG_STONEYRIDGE_UART) += uart.c
bootblock-y += fixme.c
bootblock-y += bootblock/bootblock.c
bootblock-y += early_setup.c
bootblock-y += tsc_freq.c
romstage-y += romstage.c
romstage-y += early_setup.c
romstage-y += dimmSpd.c
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c

View File

@@ -1,7 +1,8 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2010 Advanced Micro Devices, Inc.
* Copyright (C) 2016 Intel Corporation..
* Copyright (C) 2017 Advanced Micro Devices
*
* 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
@@ -14,52 +15,49 @@
*/
#include <stdint.h>
#include <arch/io.h>
#include <device/pci_ids.h>
#include <soc/pci_devs.h>
#include <console/console.h>
#include <smp/node.h>
#include <bootblock_common.h>
#include <agesawrapper.h>
#include <agesawrapper_call.h>
#include <soc/hudson.h>
/*
* Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
*
* Hardware should enable LPC ROM by pin straps. This function does not
* handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
*
* The HUDSON power-on default is to map 512K ROM space.
*
*/
static void hudson_enable_rom(void)
asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
{
u8 reg8;
pci_devfn_t dev;
dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
/* Decode variable LPC ROM address ranges 1 and 2. */
reg8 = pci_io_read_config8(dev, 0x48);
reg8 |= (1 << 3) | (1 << 4);
pci_io_write_config8(dev, 0x48, reg8);
/* LPC ROM address range 1: */
/* Enable LPC ROM range mirroring start at 0x000e(0000). */
pci_io_write_config16(dev, 0x68, 0x000e);
/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
pci_io_write_config16(dev, 0x6a, 0x000f);
/* LPC ROM address range 2: */
/*
* Enable LPC ROM range start at:
* 0xfff8(0000): 512KB
* 0xfff0(0000): 1MB
* 0xffe0(0000): 2MB
* 0xffc0(0000): 4MB
* Call lib/bootblock.c main with BSP, shortcut for APs
* todo: rearchitect AGESA entry points to remove need
* to run amdinitreset, amdinitearly from bootblock.
* Remove AP shortcut.
*/
pci_io_write_config16(dev, 0x6c, 0x10000
- (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
/* Enable LPC ROM range end at 0xffff(ffff). */
pci_io_write_config16(dev, 0x6e, 0xffff);
if (!boot_cpu())
bootblock_soc_early_init(); /* APs will not return */
bootblock_main_with_timestamp(base_timestamp);
}
static void bootblock_southbridge_init(void)
void bootblock_soc_early_init(void)
{
hudson_enable_rom();
amd_initmmio();
if (!boot_cpu())
bootblock_soc_init(); /* APs will not return */
bootblock_fch_early_init();
post_code(0x90);
if (CONFIG_STONEYRIDGE_UART)
configure_hudson_uart();
}
void bootblock_soc_init(void)
{
u32 val = cpuid_eax(1);
printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
post_code(0x37);
AGESAWRAPPER(amdinitreset);
post_code(0x38);
AGESAWRAPPER(amdinitearly); /* APs will not exit amdinitearly */
}

View File

@@ -301,3 +301,51 @@ void hudson_tpm_decode_spi(void)
pci_write_config32(dev, SPIROM_BASE_ADDRESS_REGISTER, spibase
| ROUTE_TPM_2_SPI);
}
/*
* Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
*
* Hardware should enable LPC ROM by pin straps. This function does not
* handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
*
* The HUDSON power-on default is to map 512K ROM space.
*
*/
void hudson_enable_rom(void)
{
u8 reg8;
pci_devfn_t dev;
dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
/* Decode variable LPC ROM address ranges 1 and 2. */
reg8 = pci_io_read_config8(dev, 0x48);
reg8 |= (1 << 3) | (1 << 4);
pci_io_write_config8(dev, 0x48, reg8);
/* LPC ROM address range 1: */
/* Enable LPC ROM range mirroring start at 0x000e(0000). */
pci_io_write_config16(dev, 0x68, 0x000e);
/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
pci_io_write_config16(dev, 0x6a, 0x000f);
/* LPC ROM address range 2: */
/*
* Enable LPC ROM range start at:
* 0xfff8(0000): 512KB
* 0xfff0(0000): 1MB
* 0xffe0(0000): 2MB
* 0xffc0(0000): 4MB
*/
pci_io_write_config16(dev, 0x6c, 0x10000
- (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
/* Enable LPC ROM range end at 0xffff(ffff). */
pci_io_write_config16(dev, 0x6e, 0xffff);
}
void bootblock_fch_early_init(void)
{
hudson_enable_rom();
hudson_lpc_port80();
hudson_lpc_decode();
}

View File

@@ -179,6 +179,7 @@ static inline int hudson_ide_enable(void)
(CONFIG_STONEYRIDGE_SATA_MODE == 3);
}
void hudson_enable_rom(void);
void configure_hudson_uart(void);
void hudson_clk_output_48Mhz(void);
void hudson_disable_4dw_burst(void);
@@ -201,5 +202,6 @@ void pm_write16(u8 reg, u16 value);
int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);
void s3_resume_init_data(void *FchParams);
int s3_save_nvram_early(u32 dword, int size, int nvram_pos);
void bootblock_fch_early_init(void);
#endif /* STONEYRIDGE_H */

View File

@@ -16,6 +16,7 @@
#ifndef PI_STONEYRIDGE_NORTHBRIDGE_H
#define PI_STONEYRIDGE_NORTHBRIDGE_H
#include <arch/cpu.h>
#include <arch/io.h>
#include <device/device.h>
@@ -26,4 +27,7 @@ void domain_set_resources(device_t dev);
void fam15_finalize(void *chip_info);
void setup_uma_memory(void);
/* todo: remove this when postcar stage is in place */
asmlinkage void chipset_teardown_car(void);
#endif /* PI_STONEYRIDGE_NORTHBRIDGE_H */

View File

@@ -0,0 +1,52 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
*
* 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 <cbmem.h>
#include <console/console.h>
#include <program_loading.h>
#include <agesawrapper.h>
#include <agesawrapper_call.h>
#include <soc/northbridge.h>
#include <soc/hudson.h>
#include <amdblocks/psp.h>
asmlinkage void car_stage_entry(void)
{
console_init();
post_code(0x40);
AGESAWRAPPER(amdinitpost);
post_code(0x41);
psp_notify_dram();
post_code(0x42);
cbmem_initialize_empty();
/*
* This writes contents to DRAM backing before teardown.
* todo: move CAR teardown to postcar implementation and
* relocate amdinitenv to ramstage.
*/
chipset_teardown_car();
post_code(0x43);
AGESAWRAPPER(amdinitenv);
post_code(0x50);
run_ramstage();
post_code(0x54); /* Should never see this post code. */
}