summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/amd/common/psp_verstage/boot_dev.c51
-rw-r--r--src/soc/amd/common/psp_verstage/fch.c9
-rw-r--r--src/soc/amd/common/psp_verstage/include/psp_verstage.h6
-rw-r--r--src/soc/amd/common/psp_verstage/psp_verstage.c39
4 files changed, 75 insertions, 30 deletions
diff --git a/src/soc/amd/common/psp_verstage/boot_dev.c b/src/soc/amd/common/psp_verstage/boot_dev.c
index 4ee78b8349..c129479059 100644
--- a/src/soc/amd/common/psp_verstage/boot_dev.c
+++ b/src/soc/amd/common/psp_verstage/boot_dev.c
@@ -11,22 +11,51 @@
#define DEST_BUF_ALIGNMENT 16
-static void *boot_dev_mmap(const struct region_device *rd, size_t offset,
- size_t size __always_unused)
+static uint32_t active_map_count;
+
+static void *boot_dev_mmap(const struct region_device *rd, size_t offset, size_t size)
{
const struct mem_region_device *mdev;
+ void *mapping = NULL;
+ uint32_t ret;
mdev = container_of(rd, __typeof__(*mdev), rdev);
- return &(mdev->base[offset]);
+ if (mdev->base) {
+ if ((ret = svc_map_spi_rom(&mdev->base[offset], size, (void **)&mapping))
+ != BL_OK)
+ printk(BIOS_ERR, "Failed(%d) to map SPI ROM offset: %zu, size: %zu\n",
+ ret, offset, size);
+ else
+ active_map_count++;
+ }
+
+ return mapping;
}
-static int boot_dev_munmap(const struct region_device *rd __always_unused,
- void *mapping __always_unused)
+static int boot_dev_munmap(const struct region_device *rd, void *mapping)
{
+ uint32_t ret;
+
+ active_map_count--;
+ if ((ret = svc_unmap_spi_rom(mapping)) != BL_OK)
+ printk(BIOS_ERR, "Failed(%d) to unmap SPI ROM mapping %p\n", ret, mapping);
return 0;
}
+static ssize_t boot_dev_mmap_readat(const struct region_device *rd, void *dest,
+ size_t offset, size_t size)
+{
+ void *mapping = boot_dev_mmap(rd, offset, size);
+
+ if (!mapping)
+ return -1;
+
+ memcpy(dest, mapping, size);
+ boot_dev_munmap(rd, mapping);
+ return size;
+}
+
static ssize_t boot_dev_dma_readat(const struct region_device *rd, void *dest,
size_t offset, size_t size)
{
@@ -38,8 +67,8 @@ static ssize_t boot_dev_dma_readat(const struct region_device *rd, void *dest,
memcpy_size = size;
/* Alignment requirement is only on dest buffer for CCP DMA. So do a memcpy
until the destination buffer alignment requirement is met. */
- if (memcpy_size)
- memcpy(dest, &(mdev->base[offset]), memcpy_size);
+ if (memcpy_size && boot_dev_mmap_readat(rd, dest, offset, memcpy_size) != memcpy_size)
+ return -1;
dest = ((char *)dest + memcpy_size);
offset += memcpy_size;
@@ -65,8 +94,7 @@ static ssize_t boot_dev_readat(const struct region_device *rd, void *dest,
if (CONFIG(PSP_VERSTAGE_CCP_DMA))
return boot_dev_dma_readat(rd, dest, offset, size);
- memcpy(dest, &(mdev->base[offset]), size);
- return size;
+ return boot_dev_mmap_readat(rd, dest, offset, size);
}
const struct region_device_ops boot_dev_rdev_ro_ops = {
@@ -85,3 +113,8 @@ const struct region_device *boot_device_ro(void)
boot_dev.base = (void *)map_spi_rom();
return &boot_dev.rdev;
}
+
+uint32_t boot_dev_get_active_map_count(void)
+{
+ return active_map_count;
+}
diff --git a/src/soc/amd/common/psp_verstage/fch.c b/src/soc/amd/common/psp_verstage/fch.c
index 7f850fd149..0517545f16 100644
--- a/src/soc/amd/common/psp_verstage/fch.c
+++ b/src/soc/amd/common/psp_verstage/fch.c
@@ -90,19 +90,14 @@ static struct {
{"AOAC", {FCH_IO_DEVICE_AOAC}, aoac_set_bar},
};
-uintptr_t *map_spi_rom(void)
+void *map_spi_rom(void)
{
- uintptr_t *addr = NULL;
struct spirom_info spi = {0};
if (svc_get_spi_rom_info(&spi))
printk(BIOS_DEBUG, "Error getting SPI ROM info.\n");
- if (spi.SpiBiosSmnBase != 0)
- if (svc_map_spi_rom(spi.SpiBiosSmnBase, CONFIG_ROM_SIZE, (void **)&addr))
- printk(BIOS_DEBUG, "Error mapping SPI ROM to address.\n");
-
- return addr;
+ return spi.SpiBiosSmnBase;
}
static uint32_t map_fch_devices(void)
diff --git a/src/soc/amd/common/psp_verstage/include/psp_verstage.h b/src/soc/amd/common/psp_verstage/include/psp_verstage.h
index c3240fab56..6c5d4c0acf 100644
--- a/src/soc/amd/common/psp_verstage/include/psp_verstage.h
+++ b/src/soc/amd/common/psp_verstage/include/psp_verstage.h
@@ -38,7 +38,7 @@
#define POSTCODE_CMOS_RECOVERY 0xCA
#define POSTCODE_EARLY_INIT_ERROR 0xCB
#define POSTCODE_INIT_TPM_FAILED 0xCC
-
+#define POSTCODE_MAP_SPI_ROM_FAILED 0xCD
#define POSTCODE_UNMAP_SPI_ROM 0xF0
#define POSTCODE_UNMAP_FCH_DEVICES 0xF1
@@ -57,7 +57,7 @@ void verstage_soc_aoac_init(void);
void verstage_soc_espi_init(void);
void verstage_soc_i2c_init(void);
void verstage_soc_spi_init(void);
-uintptr_t *map_spi_rom(void);
+void *map_spi_rom(void);
uint32_t update_psp_bios_dir(uint32_t *psp_dir_offset, uint32_t *bios_dir_offset);
uint32_t save_uapp_data(void *address, uint32_t size);
@@ -72,4 +72,6 @@ void report_prev_boot_status_to_vboot(void);
void report_hsp_secure_state(void);
+uint32_t boot_dev_get_active_map_count(void);
+
#endif /* PSP_VERSTAGE_H */
diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c
index e5b0277ba9..dfea43d6c9 100644
--- a/src/soc/amd/common/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/common/psp_verstage/psp_verstage.c
@@ -10,6 +10,7 @@
#include <commonlib/region.h>
#include <console/console.h>
#include <fmap.h>
+#include <fmap_config.h>
#include <pc80/mc146818rtc.h>
#include <soc/iomap.h>
#include <soc/psp_transfer.h>
@@ -74,7 +75,8 @@ static uint32_t update_boot_region(struct vb2_context *ctx)
const char *fname;
const char *hash_fname;
void *amdfw_location;
- void *boot_dev_base = rdev_mmap_full(boot_device_ro());
+ void *map_base = NULL;
+ size_t map_offset;
/* Continue booting from RO */
if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
@@ -85,36 +87,53 @@ static uint32_t update_boot_region(struct vb2_context *ctx)
if (vboot_is_firmware_slot_a(ctx)) {
fname = "apu/amdfw_a";
hash_fname = "apu/amdfw_a_hash";
+ map_offset = FMAP_SECTION_FW_MAIN_A_START - FMAP_SECTION_FLASH_START;
+ map_base = rdev_mmap(boot_device_ro(), map_offset, FMAP_SECTION_FW_MAIN_A_SIZE);
} else {
fname = "apu/amdfw_b";
hash_fname = "apu/amdfw_b_hash";
+ map_offset = FMAP_SECTION_FW_MAIN_B_START - FMAP_SECTION_FLASH_START;
+ map_base = rdev_mmap(boot_device_ro(), map_offset, FMAP_SECTION_FW_MAIN_B_SIZE);
+ }
+
+ if (!map_base) {
+ printk(BIOS_ERR, "Failed to map RW FW_MAIN section.\n");
+ return POSTCODE_MAP_SPI_ROM_FAILED;
}
amdfw_location = cbfs_map(fname, NULL);
if (!amdfw_location) {
printk(BIOS_ERR, "AMD Firmware table not found.\n");
+ rdev_munmap(boot_device_ro(), map_base);
return POSTCODE_AMD_FW_MISSING;
}
+
ef_table = (struct embedded_firmware *)amdfw_location;
if (ef_table->signature != EMBEDDED_FW_SIGNATURE) {
printk(BIOS_ERR, "ROMSIG address is not correct.\n");
+ cbfs_unmap(amdfw_location);
+ rdev_munmap(boot_device_ro(), map_base);
return POSTCODE_ROMSIG_MISMATCH_ERROR;
}
psp_dir_addr = ef_table->new_psp_directory;
bios_dir_addr = get_bios_dir_addr(ef_table);
psp_dir_in_spi = (uint32_t *)((psp_dir_addr & SPI_ADDR_MASK) +
- (uint32_t)boot_dev_base);
+ (uint32_t)map_base - map_offset);
if (*psp_dir_in_spi != PSP_COOKIE) {
printk(BIOS_ERR, "PSP Directory address is not correct.\n");
+ cbfs_unmap(amdfw_location);
+ rdev_munmap(boot_device_ro(), map_base);
return POSTCODE_PSP_COOKIE_MISMATCH_ERROR;
}
if (bios_dir_addr) {
bios_dir_in_spi = (uint32_t *)((bios_dir_addr & SPI_ADDR_MASK) +
- (uint32_t)boot_dev_base);
+ (uint32_t)map_base - map_offset);
if (*bios_dir_in_spi != BHD_COOKIE) {
printk(BIOS_ERR, "BIOS Directory address is not correct.\n");
+ cbfs_unmap(amdfw_location);
+ rdev_munmap(boot_device_ro(), map_base);
return POSTCODE_BHD_COOKIE_MISMATCH_ERROR;
}
}
@@ -128,12 +147,16 @@ static uint32_t update_boot_region(struct vb2_context *ctx)
if (update_psp_bios_dir(&psp_dir_addr, &bios_dir_addr)) {
printk(BIOS_ERR, "Updated BIOS Directory could not be set.\n");
+ cbfs_unmap(amdfw_location);
+ rdev_munmap(boot_device_ro(), map_base);
return POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR;
}
if (CONFIG(SEPARATE_SIGNED_PSPFW))
update_psp_fw_hash_table(hash_fname);
+ cbfs_unmap(amdfw_location);
+ rdev_munmap(boot_device_ro(), map_base);
return 0;
}
@@ -208,7 +231,6 @@ void Main(void)
{
uint32_t retval;
struct vb2_context *ctx = NULL;
- void *boot_dev_base;
uint32_t bootmode;
/*
@@ -324,14 +346,7 @@ void Main(void)
if (retval)
reboot_into_recovery(ctx, retval);
-
- post_code(POSTCODE_UNMAP_SPI_ROM);
- boot_dev_base = rdev_mmap_full(boot_device_ro());
- if (boot_dev_base) {
- if (svc_unmap_spi_rom((void *)boot_dev_base))
- printk(BIOS_ERR, "Error unmapping SPI rom\n");
- }
-
+ assert(!boot_dev_get_active_map_count());
post_code(POSTCODE_UNMAP_FCH_DEVICES);
unmap_fch_devices();