summaryrefslogtreecommitdiff
path: root/src/cpu/amd/agesa
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2014-06-19 16:51:54 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-07-03 09:46:15 +0200
commitadf3d6ff52eb674267eacbf37f811c7144e857b3 (patch)
tree72dea3e6d005e8f438951e431659dc96e7e03a93 /src/cpu/amd/agesa
parent23b4f0c7344c199d5adb0aece8d3ca9a624f4a34 (diff)
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>
Diffstat (limited to 'src/cpu/amd/agesa')
-rw-r--r--src/cpu/amd/agesa/Makefile.inc2
-rw-r--r--src/cpu/amd/agesa/s3_resume.c110
-rw-r--r--src/cpu/amd/agesa/s3_resume.h2
-rw-r--r--src/cpu/amd/agesa/spi.c54
4 files changed, 88 insertions, 80 deletions
diff --git a/src/cpu/amd/agesa/Makefile.inc b/src/cpu/amd/agesa/Makefile.inc
index f403d307a5..d6d2f247d6 100644
--- a/src/cpu/amd/agesa/Makefile.inc
+++ b/src/cpu/amd/agesa/Makefile.inc
@@ -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
diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c
index 42447862eb..18994084c5 100644
--- a/src/cpu/amd/agesa/s3_resume.c
+++ b/src/cpu/amd/agesa/s3_resume.c
@@ -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,20 +212,32 @@ 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);
+ write_mtrr(&nvram_pos, 0xC001001D);
- flash->spi->rw = SPI_WRITE_FLAG;
- spi_release_bus(flash->spi);
+#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)
{
@@ -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)
{
diff --git a/src/cpu/amd/agesa/s3_resume.h b/src/cpu/amd/agesa/s3_resume.h
index b72e8a2600..14984dfc9c 100644
--- a/src/cpu/amd/agesa/s3_resume.h
+++ b/src/cpu/amd/agesa/s3_resume.h
@@ -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
diff --git a/src/cpu/amd/agesa/spi.c b/src/cpu/amd/agesa/spi.c
new file mode 100644
index 0000000000..f4ffa6262f
--- /dev/null
+++ b/src/cpu/amd/agesa/spi.c
@@ -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;
+}