AGESA: Clean separation of SPI flash

To be precise, wakeup from S3 does not involve SPI writing, while
preparing for it on cold power-ons currently does.

For S3DataTypeMtrr storage is changed such that the first 4 bytes
is the length of data stored like with the other two S3DataType.

Change-Id: Id920650474530d4191075da4ef70daa66c904c5b
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/6085
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
Reviewed-by: Dave Frodin <dave.frodin@se-eng.com>
This commit is contained in:
Kyösti Mälkki 2014-06-19 16:51:54 +03:00
parent 23b4f0c734
commit adf3d6ff52
6 changed files with 91 additions and 83 deletions

View File

@ -25,6 +25,8 @@ subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY16_KB) += family16kb
romstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c
ramstage-$(CONFIG_SPI_FLASH) += spi.c
cpu_incs += $(src)/cpu/amd/agesa/cache_as_ram.inc
romstage-y += heapmanager.c

View File

@ -35,11 +35,6 @@
#include "s3_resume.h"
#include "agesawrapper.h"
#ifndef __PRE_RAM__
#include <spi-generic.h>
#include <spi_flash.h>
#endif
/* The size needs to be 4k aligned, which is the sector size of most flashes. */
#define S3_DATA_VOLATILE_SIZE 0x6000
#define S3_DATA_MTRR_SIZE 0x1000
@ -85,7 +80,7 @@ void restore_mtrr(void)
u32 pos, size;
get_s3nv_data(S3DataTypeMTRR, &pos, &size);
msrPtr = (UINT32 *)pos;
msrPtr = (UINT32 *)(pos + sizeof(UINT32));
disable_cache();
@ -178,46 +173,24 @@ static void move_stack_high_mem(void)
#endif
#ifndef __PRE_RAM__
static void write_mtrr(struct spi_flash *flash, u32 *p_nvram_pos, unsigned idx)
/* FIXME: Why store MTRR in SPI, just use CBMEM ? */
static u8 mtrr_store[S3_DATA_MTRR_SIZE];
static void write_mtrr(u8 **p_nvram_pos, unsigned idx)
{
msr_t msr_data;
msr_data = rdmsr(idx);
#if CONFIG_AMD_SB_SPI_TX_LEN >= 8
flash->write(flash, *p_nvram_pos, 8, &msr_data);
*p_nvram_pos += 8;
#else
flash->write(flash, *p_nvram_pos, 4, &msr_data.lo);
*p_nvram_pos += 4;
flash->write(flash, *p_nvram_pos, 4, &msr_data.hi);
*p_nvram_pos += 4;
#endif
memcpy(*p_nvram_pos, &msr_data, sizeof(msr_data));
*p_nvram_pos += sizeof(msr_data);
}
#endif
void OemAgesaSaveMtrr(void)
{
#ifndef __PRE_RAM__
msr_t msr_data;
u32 i;
struct spi_flash *flash;
u32 pos, size;
get_s3nv_data(S3DataTypeMTRR, &pos, &size);
spi_init();
flash = spi_flash_probe(0, 0, 0, 0);
if (!flash) {
printk(BIOS_DEBUG, "Could not find SPI device\n");
return;
}
flash->spi->rw = SPI_WRITE_FLAG;
spi_claim_bus(flash->spi);
flash->erase(flash, pos, size);
u32 nvram_pos = pos;
u8 *nvram_pos = (u8 *) mtrr_store;
/* Enable access to AMD RdDram and WrDram extension bits */
msr_data = rdmsr(SYS_CFG);
@ -225,12 +198,12 @@ void OemAgesaSaveMtrr(void)
wrmsr(SYS_CFG, msr_data);
/* Fixed MTRRs */
write_mtrr(flash, &nvram_pos, 0x250);
write_mtrr(flash, &nvram_pos, 0x258);
write_mtrr(flash, &nvram_pos, 0x259);
write_mtrr(&nvram_pos, 0x250);
write_mtrr(&nvram_pos, 0x258);
write_mtrr(&nvram_pos, 0x259);
for (i = 0x268; i < 0x270; i++)
write_mtrr(flash, &nvram_pos, i);
write_mtrr(&nvram_pos, i);
/* Disable access to AMD RdDram and WrDram extension bits */
msr_data = rdmsr(SYS_CFG);
@ -239,21 +212,33 @@ void OemAgesaSaveMtrr(void)
/* Variable MTRRs */
for (i = 0x200; i < 0x210; i++)
write_mtrr(flash, &nvram_pos, i);
write_mtrr(&nvram_pos, i);
/* SYS_CFG */
write_mtrr(flash, &nvram_pos, 0xC0010010);
write_mtrr(&nvram_pos, 0xC0010010);
/* TOM */
write_mtrr(flash, &nvram_pos, 0xC001001A);
write_mtrr(&nvram_pos, 0xC001001A);
/* TOM2 */
write_mtrr(flash, &nvram_pos, 0xC001001D);
flash->spi->rw = SPI_WRITE_FLAG;
spi_release_bus(flash->spi);
write_mtrr(&nvram_pos, 0xC001001D);
#if IS_ENABLED(CONFIG_SPI_FLASH)
u32 pos, size;
get_s3nv_data(S3DataTypeMTRR, &pos, &size);
spi_SaveS3info(pos, size, mtrr_store, nvram_pos - (u8 *) mtrr_store);
#endif
}
u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data)
{
#if IS_ENABLED(CONFIG_SPI_FLASH)
u32 pos, size;
get_s3nv_data(S3DataType, &pos, &size);
spi_SaveS3info(pos, size, Data, DataSize);
#endif
return AGESA_SUCCESS;
}
#endif
void OemAgesaGetS3Info(S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data)
{
AMD_CONFIG_PARAMS StdHeader;
@ -274,41 +259,6 @@ void OemAgesaGetS3Info(S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data)
}
}
#ifndef __PRE_RAM__
u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data)
{
struct spi_flash *flash;
u32 pos, size;
get_s3nv_data(S3DataType, &pos, &size);
spi_init();
flash = spi_flash_probe(0, 0, 0, 0);
if (!flash) {
printk(BIOS_DEBUG, "Could not find SPI device\n");
/* Dont make flow stop. */
return AGESA_SUCCESS;
}
flash->spi->rw = SPI_WRITE_FLAG;
spi_claim_bus(flash->spi);
flash->erase(flash, pos, size);
flash->write(flash, pos, sizeof(DataSize), &DataSize);
u32 nvram_pos;
for (nvram_pos = 0; nvram_pos < DataSize - CONFIG_AMD_SB_SPI_TX_LEN; nvram_pos += CONFIG_AMD_SB_SPI_TX_LEN) {
flash->write(flash, nvram_pos + pos + 4, CONFIG_AMD_SB_SPI_TX_LEN, (u8 *)(Data + nvram_pos));
}
flash->write(flash, nvram_pos + pos + 4, DataSize % CONFIG_AMD_SB_SPI_TX_LEN, (u8 *)(Data + nvram_pos));
flash->spi->rw = SPI_WRITE_FLAG;
spi_release_bus(flash->spi);
return AGESA_SUCCESS;
}
#endif
#ifdef __PRE_RAM__
static void set_resume_cache(void)
{

View File

@ -33,4 +33,6 @@ u32 OemAgesaSaveS3Info (S3_DATA_TYPE S3DataType, u32 DataSize, void *Data);
void OemAgesaGetS3Info (S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data);
void OemAgesaSaveMtrr (void);
void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len);
#endif

54
src/cpu/amd/agesa/spi.c Normal file
View File

@ -0,0 +1,54 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2012 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.
*
* 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 <console/console.h>
#include <spi-generic.h>
#include <spi_flash.h>
#include "s3_resume.h"
void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len)
{
struct spi_flash *flash;
spi_init();
flash = spi_flash_probe(0, 0, 0, 0);
if (!flash) {
printk(BIOS_DEBUG, "Could not find SPI device\n");
/* Dont make flow stop. */
return;
}
flash->spi->rw = SPI_WRITE_FLAG;
spi_claim_bus(flash->spi);
flash->erase(flash, pos, size);
flash->write(flash, pos, sizeof(len), &len);
u32 nvram_pos;
for (nvram_pos = 0; nvram_pos < len - CONFIG_AMD_SB_SPI_TX_LEN; nvram_pos += CONFIG_AMD_SB_SPI_TX_LEN) {
flash->write(flash, nvram_pos + pos + 4, CONFIG_AMD_SB_SPI_TX_LEN, (u8 *)(buf + nvram_pos));
}
flash->write(flash, nvram_pos + pos + 4, len % CONFIG_AMD_SB_SPI_TX_LEN, (u8 *)(buf + nvram_pos));
flash->spi->rw = SPI_WRITE_FLAG;
spi_release_bus(flash->spi);
return;
}

View File

@ -16,7 +16,7 @@ romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += enable_usbdebug.c
ramstage-$(CONFIG_USBDEBUG) += enable_usbdebug.c
romstage-y += early_setup.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += spi.c
ramstage-$(CONFIG_SPI_FLASH) += spi.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += resume.c
romstage-y += imc.c

View File

@ -31,7 +31,7 @@ ramstage-y += reset.c
ramstage-$(CONFIG_SB800_MANUAL_FAN_CONTROL) += fan.c
ramstage-$(CONFIG_SB800_IMC_FAN_CONTROL) += fan.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += spi.c
ramstage-$(CONFIG_SPI_FLASH) += spi.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += ../../sb800/enable_usbdebug.c