From d4955f0ade18cafde4a3ea20885eb9fbdc5b4514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Fri, 8 Sep 2017 07:14:17 +0300 Subject: AGESA: Move API interface under drivers/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New AGESA support files will be used for binaryPI platforms as well. Furthermore, some of those should move from split nb/ sb/ directories to soc/, so move support files for the API under drivers/. Change-Id: I549788091de91f61de8b9adc223d52ffb5732235 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/21455 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/drivers/amd/agesa/oem_s3.c | 165 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/drivers/amd/agesa/oem_s3.c (limited to 'src/drivers/amd/agesa/oem_s3.c') diff --git a/src/drivers/amd/agesa/oem_s3.c b/src/drivers/amd/agesa/oem_s3.c new file mode 100644 index 0000000000..1ca6e5b2f6 --- /dev/null +++ b/src/drivers/amd/agesa/oem_s3.c @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + S3DataTypeNonVolatile = 0, ///< NonVolatile Data Type + S3DataTypeMTRR ///< MTRR storage +} S3_DATA_TYPE; + +/* The size needs to be 4k aligned, which is the sector size of most flashes. */ +#define S3_DATA_MTRR_SIZE 0x1000 +#define S3_DATA_NONVOLATILE_SIZE 0x1000 + +#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && \ + (S3_DATA_MTRR_SIZE + S3_DATA_NONVOLATILE_SIZE) > CONFIG_S3_DATA_SIZE +#error "Please increase the value of S3_DATA_SIZE" +#endif + +static void get_s3nv_data(S3_DATA_TYPE S3DataType, uintptr_t *pos, uintptr_t *len) +{ + /* FIXME: Find file from CBFS. */ + u32 s3_data = CONFIG_S3_DATA_POS; + + switch (S3DataType) { + case S3DataTypeMTRR: + *pos = s3_data; + *len = S3_DATA_MTRR_SIZE; + break; + case S3DataTypeNonVolatile: + *pos = s3_data + S3_DATA_MTRR_SIZE; + *len = S3_DATA_NONVOLATILE_SIZE; + break; + default: + *pos = 0; + *len = 0; + break; + } +} + +AGESA_STATUS OemInitResume(AMD_S3_PARAMS *dataBlock) +{ + uintptr_t pos, size; + get_s3nv_data(S3DataTypeNonVolatile, &pos, &size); + + u32 len = *(u32*)pos; + + /* Test for uninitialized s3nv data in SPI. */ + if (len == 0 || len == (u32)-1ULL) + return AGESA_FATAL; + + dataBlock->NvStorageSize = len; + dataBlock->NvStorage = (void *) (pos + sizeof(u32)); + return AGESA_SUCCESS; +} + +AGESA_STATUS OemS3LateRestore(AMD_S3_PARAMS *dataBlock) +{ + char *heap = cbmem_find(CBMEM_ID_RESUME_SCRATCH); + if (heap == NULL) + return AGESA_FATAL; + + printk(BIOS_DEBUG, "Using resume HEAP at %08x\n", + (unsigned int)(uintptr_t) heap); + + /* Return allocated CBMEM size, we do not keep track of + * how much was actually used. + */ + dataBlock->VolatileStorageSize = HIGH_MEMORY_SCRATCH; + dataBlock->VolatileStorage = heap; + return AGESA_SUCCESS; +} + +#if ENV_RAMSTAGE + +static int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) +{ +#if IS_ENABLED(CONFIG_SPI_FLASH) + struct spi_flash flash; + + spi_init(); + if (spi_flash_probe(0, 0, &flash)) + return -1; + + spi_flash_volatile_group_begin(&flash); + + spi_flash_erase(&flash, pos, size); + spi_flash_write(&flash, pos, sizeof(len), &len); + spi_flash_write(&flash, pos + sizeof(len), len, buf); + + spi_flash_volatile_group_end(&flash); + return 0; +#else + return -1; +#endif +} + +static u8 MTRRStorage[S3_DATA_MTRR_SIZE]; + +AGESA_STATUS OemS3Save(AMD_S3_PARAMS *dataBlock) +{ + u32 MTRRStorageSize = 0; + uintptr_t pos, size; + + romstage_ram_stack_base(HIGH_ROMSTAGE_STACK_SIZE, ROMSTAGE_STACK_CBMEM); + + /* To be consumed in AmdInitResume. */ + get_s3nv_data(S3DataTypeNonVolatile, &pos, &size); + if (size && dataBlock->NvStorageSize) + spi_SaveS3info(pos, size, dataBlock->NvStorage, + dataBlock->NvStorageSize); + else + printk(BIOS_EMERG, + "Error: Cannot store memory training results in SPI.\n" + "Error: S3 resume will not be possible.\n" + ); + + /* To be consumed in AmdS3LateRestore. */ + char *heap = cbmem_add(CBMEM_ID_RESUME_SCRATCH, HIGH_MEMORY_SCRATCH); + if (heap) { + memset(heap, 0, HIGH_MEMORY_SCRATCH); + memcpy(heap, dataBlock->VolatileStorage, dataBlock->VolatileStorageSize); + } + + /* Collect MTRR setup. */ + backup_mtrr(MTRRStorage, &MTRRStorageSize); + + /* To be consumed in restore_mtrr, CPU enumeration in ramstage. */ + get_s3nv_data(S3DataTypeMTRR, &pos, &size); + if (size && MTRRStorageSize) + spi_SaveS3info(pos, size, MTRRStorage, MTRRStorageSize); + + return AGESA_SUCCESS; +} + +#endif /* ENV_RAMSTAGE */ + +const void *OemS3Saved_MTRR_Storage(void) +{ + uintptr_t pos, size; + get_s3nv_data(S3DataTypeMTRR, &pos, &size); + if (!size) + return NULL; + + return (void*)(pos + sizeof(UINT32)); +} -- cgit v1.2.3