From e20bc464fbc14db65d1fb99474776147a18e7bda Mon Sep 17 00:00:00 2001 From: Kangheui Won Date: Tue, 6 Apr 2021 16:55:48 +1000 Subject: soc/amd: move psp_verstage to amd/common psp_verstage is not specific to picasso. There might be picasso-specific code but move everything into common as a first step. While developing psp_verstage for cezanne picasso-specific code will move back to picasso directory. BUG=b:182477057 BRANCH=none TEST=build psp_verstage on zork Signed-off-by: Kangheui Won Change-Id: Ifb1df0d82b972f28be2ffebd476c2553cbda9810 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52306 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/common/psp_verstage/Makefile.inc | 24 ++ src/soc/amd/common/psp_verstage/delay.c | 10 + src/soc/amd/common/psp_verstage/fch.c | 158 ++++++++++++ src/soc/amd/common/psp_verstage/include/arch/io.h | 21 ++ .../psp_verstage/include/arch/smp/spinlock.h | 15 ++ src/soc/amd/common/psp_verstage/pmutil.c | 20 ++ src/soc/amd/common/psp_verstage/post.c | 11 + src/soc/amd/common/psp_verstage/printk.c | 40 +++ src/soc/amd/common/psp_verstage/psp.c | 8 + src/soc/amd/common/psp_verstage/psp_verstage.c | 277 +++++++++++++++++++++ src/soc/amd/common/psp_verstage/psp_verstage.h | 59 +++++ src/soc/amd/common/psp_verstage/reset.c | 11 + src/soc/amd/common/psp_verstage/svc.c | 166 ++++++++++++ src/soc/amd/common/psp_verstage/svc.h | 57 +++++ src/soc/amd/common/psp_verstage/timer.c | 15 ++ src/soc/amd/common/psp_verstage/vboot_crypto.c | 153 ++++++++++++ src/soc/amd/picasso/Makefile.inc | 1 + src/soc/amd/picasso/psp_verstage/Makefile.inc | 20 -- src/soc/amd/picasso/psp_verstage/delay.c | 10 - src/soc/amd/picasso/psp_verstage/fch.c | 158 ------------ src/soc/amd/picasso/psp_verstage/include/arch/io.h | 21 -- .../psp_verstage/include/arch/smp/spinlock.h | 15 -- src/soc/amd/picasso/psp_verstage/pmutil.c | 20 -- src/soc/amd/picasso/psp_verstage/post.c | 11 - src/soc/amd/picasso/psp_verstage/printk.c | 40 --- src/soc/amd/picasso/psp_verstage/psp.c | 8 - src/soc/amd/picasso/psp_verstage/psp_verstage.c | 277 --------------------- src/soc/amd/picasso/psp_verstage/psp_verstage.h | 59 ----- src/soc/amd/picasso/psp_verstage/reset.c | 11 - src/soc/amd/picasso/psp_verstage/svc.c | 166 ------------ src/soc/amd/picasso/psp_verstage/svc.h | 57 ----- src/soc/amd/picasso/psp_verstage/timer.c | 15 -- src/soc/amd/picasso/psp_verstage/vboot_crypto.c | 153 ------------ 33 files changed, 1046 insertions(+), 1041 deletions(-) create mode 100644 src/soc/amd/common/psp_verstage/Makefile.inc create mode 100644 src/soc/amd/common/psp_verstage/delay.c create mode 100644 src/soc/amd/common/psp_verstage/fch.c create mode 100644 src/soc/amd/common/psp_verstage/include/arch/io.h create mode 100644 src/soc/amd/common/psp_verstage/include/arch/smp/spinlock.h create mode 100644 src/soc/amd/common/psp_verstage/pmutil.c create mode 100644 src/soc/amd/common/psp_verstage/post.c create mode 100644 src/soc/amd/common/psp_verstage/printk.c create mode 100644 src/soc/amd/common/psp_verstage/psp.c create mode 100644 src/soc/amd/common/psp_verstage/psp_verstage.c create mode 100644 src/soc/amd/common/psp_verstage/psp_verstage.h create mode 100644 src/soc/amd/common/psp_verstage/reset.c create mode 100644 src/soc/amd/common/psp_verstage/svc.c create mode 100644 src/soc/amd/common/psp_verstage/svc.h create mode 100644 src/soc/amd/common/psp_verstage/timer.c create mode 100644 src/soc/amd/common/psp_verstage/vboot_crypto.c delete mode 100644 src/soc/amd/picasso/psp_verstage/delay.c delete mode 100644 src/soc/amd/picasso/psp_verstage/fch.c delete mode 100644 src/soc/amd/picasso/psp_verstage/include/arch/io.h delete mode 100644 src/soc/amd/picasso/psp_verstage/include/arch/smp/spinlock.h delete mode 100644 src/soc/amd/picasso/psp_verstage/pmutil.c delete mode 100644 src/soc/amd/picasso/psp_verstage/post.c delete mode 100644 src/soc/amd/picasso/psp_verstage/printk.c delete mode 100644 src/soc/amd/picasso/psp_verstage/psp.c delete mode 100644 src/soc/amd/picasso/psp_verstage/psp_verstage.c delete mode 100644 src/soc/amd/picasso/psp_verstage/psp_verstage.h delete mode 100644 src/soc/amd/picasso/psp_verstage/reset.c delete mode 100644 src/soc/amd/picasso/psp_verstage/svc.c delete mode 100644 src/soc/amd/picasso/psp_verstage/svc.h delete mode 100644 src/soc/amd/picasso/psp_verstage/timer.c delete mode 100644 src/soc/amd/picasso/psp_verstage/vboot_crypto.c (limited to 'src/soc') diff --git a/src/soc/amd/common/psp_verstage/Makefile.inc b/src/soc/amd/common/psp_verstage/Makefile.inc new file mode 100644 index 0000000000..40d9c45763 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/Makefile.inc @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-only + +verstage-generic-ccopts += -I$(src)/soc/amd/common/psp_verstage/include +verstage-generic-ccopts += -I$(src)/vendorcode/amd/fsp/picasso/include +verstage-generic-ccopts += -D__USER_SPACE__ +CPPFLAGS_common += -I$(VBOOT_SOURCE)/firmware/2lib/include/ + +# This size should match the size in the linker script. +CFLAGS_arm += -Wstack-usage=40960 + +verstage-y += delay.c +verstage-y += fch.c +verstage-y += pmutil.c +verstage-y += post.c +verstage-y += printk.c +verstage-y += psp_verstage.c +verstage-y += psp.c +verstage-y += reset.c +verstage-y += svc.c +verstage-y += timer.c +verstage-y += vboot_crypto.c + +$(obj)/psp_verstage.bin: $(objcbfs)/verstage.elf + $(OBJCOPY_verstage) -O binary $^ $@ diff --git a/src/soc/amd/common/psp_verstage/delay.c b/src/soc/amd/common/psp_verstage/delay.c new file mode 100644 index 0000000000..ff62524503 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/delay.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void udelay(uint32_t usecs) +{ + svc_delay_in_usec(usecs); +} diff --git a/src/soc/amd/common/psp_verstage/fch.c b/src/soc/amd/common/psp_verstage/fch.c new file mode 100644 index 0000000000..a032bde9b2 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/fch.c @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "psp_verstage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void i2c3_set_bar(void *bar) +{ + i2c_set_bar(3, (uintptr_t)bar); +} + +static void i2c2_set_bar(void *bar) +{ + i2c_set_bar(2, (uintptr_t)bar); +} + +static void espi_set_bar(void *bar) +{ + espi_update_static_bar((uintptr_t)bar); +} + +static void iomux_set_bar(void *bar) +{ + acpimmio_iomux = bar; +} + +static void misc_set_bar(void *bar) +{ + acpimmio_misc = bar; +} + +static void gpio_set_bar(void *bar) +{ + acpimmio_gpio0 = bar; +} + +static uintptr_t io_bar; + +static void io_set_bar(void *bar) +{ + io_bar = (uintptr_t)bar; +} + +u8 io_read8(u16 reg) +{ + return read8((void *)(io_bar + reg)); +} + +void io_write8(u16 reg, u8 value) +{ + write8((void *)(io_bar + reg), value); +} + +static void aoac_set_bar(void *bar) +{ + acpimmio_aoac = bar; +} + +static struct { + const char *name; + struct { + enum fch_io_device device; + uint32_t arg0; + } args; + void (*set_bar)(void *bar); + void *_bar; +} bar_map[] = { + {"IOMUX", {FCH_IO_DEVICE_IOMUX}, iomux_set_bar}, + {"MISC", {FCH_IO_DEVICE_MISC}, misc_set_bar}, + {"GPIO", {FCH_IO_DEVICE_GPIO}, gpio_set_bar}, + {"IO", {FCH_IO_DEVICE_IOPORT}, io_set_bar}, + {"eSPI", {FCH_IO_DEVICE_ESPI}, espi_set_bar}, + {"I2C2", {FCH_IO_DEVICE_I2C, 2}, i2c2_set_bar}, + {"I2C3", {FCH_IO_DEVICE_I2C, 3}, i2c3_set_bar}, + {"SPI", {FCH_IO_DEVICE_SPI}, spi_set_base}, + {"AOAC", {FCH_IO_DEVICE_AOAC}, aoac_set_bar}, +}; + +uintptr_t *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; +} + +static uint32_t map_fch_devices(void) +{ + void *bar; + uint32_t err; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(bar_map); ++i) { + err = svc_map_fch_dev(bar_map[i].args.device, bar_map[i].args.arg0, 0, &bar); + if (err) { + printk(BIOS_ERR, "Failed to map %s: %u\n", bar_map[i].name, err); + return err; + } + + bar_map[i]._bar = bar; + bar_map[i].set_bar(bar); + } + + return BL_OK; +} + +uint32_t unmap_fch_devices(void) +{ + void *bar; + uint32_t err, rtn = BL_OK; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(bar_map); ++i) { + bar = bar_map[i]._bar; + if (!bar) + continue; + + err = svc_unmap_fch_dev(bar_map[i].args.device, bar); + if (err) { + printk(BIOS_ERR, "Failed to unmap %s: %u\n", bar_map[i].name, err); + rtn = err; + } else { + bar_map[i]._bar = NULL; + bar_map[i].set_bar(NULL); + } + } + + return rtn; +} + +uint32_t verstage_soc_early_init(void) +{ + return map_fch_devices(); +} + +void verstage_soc_init(void) +{ + if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI)) + espi_setup(); +} diff --git a/src/soc/amd/common/psp_verstage/include/arch/io.h b/src/soc/amd/common/psp_verstage/include/arch/io.h new file mode 100644 index 0000000000..efa128b25c --- /dev/null +++ b/src/soc/amd/common/psp_verstage/include/arch/io.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ARCH_IO_H__ +#define __ARCH_IO_H__ + +#include + +u8 io_read8(u16 reg); +void io_write8(u16 reg, u8 value); + +static inline void outb(uint8_t value, uint16_t port) +{ + io_write8(port, value); +} + +static inline uint8_t inb(uint16_t port) +{ + return io_read8(port); +} + +#endif diff --git a/src/soc/amd/common/psp_verstage/include/arch/smp/spinlock.h b/src/soc/amd/common/psp_verstage/include/arch/smp/spinlock.h new file mode 100644 index 0000000000..0a3a4d4676 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/include/arch/smp/spinlock.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_SMP_SPINLOCK_H +#define _ARCH_SMP_SPINLOCK_H + +#define DECLARE_SPIN_LOCK(x) +#define spin_is_locked(lock) 0 +#define spin_unlock_wait(lock) do {} while (0) +#define spin_lock(lock) do {} while (0) +#define spin_unlock(lock) do {} while (0) + +#include +#define boot_cpu() 1 + +#endif diff --git a/src/soc/amd/common/psp_verstage/pmutil.c b/src/soc/amd/common/psp_verstage/pmutil.c new file mode 100644 index 0000000000..ddaf54d470 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/pmutil.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +int platform_is_resuming(void) +{ + uint32_t bootmode = 0; + if (svc_get_boot_mode(&bootmode)) { + printk(BIOS_ERR, "Error getting boot mode. Assuming no resume.\n"); + return 0; + } + + if (bootmode == PSP_BOOT_MODE_S3_RESUME || bootmode == PSP_BOOT_MODE_S0i3_RESUME) + return 1; + + return 0; +} diff --git a/src/soc/amd/common/psp_verstage/post.c b/src/soc/amd/common/psp_verstage/post.c new file mode 100644 index 0000000000..5b429c912b --- /dev/null +++ b/src/soc/amd/common/psp_verstage/post.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void arch_post_code(u8 value) +{ + if (CONFIG(POST_IO) && CONFIG_POST_IO_PORT == 0x80) + svc_write_postcode(value); +} diff --git a/src/soc/amd/common/psp_verstage/printk.c b/src/soc/amd/common/psp_verstage/printk.c new file mode 100644 index 0000000000..c56f78c298 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/printk.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +void console_hw_init(void) +{ + __cbmemc_init(); +} + +int printk(int msg_level, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vprintk(msg_level, fmt, args); + va_end(args); + + return i; +} + +int vprintk(int msg_level, const char *fmt, va_list args) +{ + int i, cnt, log_this; + char buf[256]; + + log_this = console_log_level(msg_level); + if (log_this < CONSOLE_LOG_FAST) + return 0; + + cnt = vsnprintf(buf, sizeof(buf), fmt, args); + for (i = 0; i < cnt; i++) + __cbmemc_tx_byte(buf[i]); + svc_debug_print(buf); + return i; +} diff --git a/src/soc/amd/common/psp_verstage/psp.c b/src/soc/amd/common/psp_verstage/psp.c new file mode 100644 index 0000000000..7f24b20384 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/psp.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +int boot_cpu(void) +{ + return 1; +} diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c new file mode 100644 index 0000000000..d4c5d155af --- /dev/null +++ b/src/soc/amd/common/psp_verstage/psp_verstage.c @@ -0,0 +1,277 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "psp_verstage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char _bss_start, _bss_end; +static struct mem_region_device boot_dev = + MEM_REGION_DEV_RO_INIT(NULL, CONFIG_ROM_SIZE); + +void __weak verstage_mainboard_early_init(void) {} +void __weak verstage_mainboard_init(void) {} + +static void reboot_into_recovery(struct vb2_context *ctx, uint32_t subcode) +{ + subcode += PSP_VBOOT_ERROR_SUBCODE; + svc_write_postcode(subcode); + + /* + * If there's an error but the PSP_verstage is already booting to RO, + * don't reset the system. It may be that the error is fatal, but if + * the system is stuck, don't intentionally force it into a reboot loop. + */ + if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { + printk(BIOS_ERR, "Already in recovery mode. Staying in RO.\n"); + return; + } + + vb2api_fail(ctx, VB2_RECOVERY_RO_UNSPECIFIED, (int)subcode); + vboot_save_data(ctx); + + svc_debug_print("Rebooting into recovery\n"); + vboot_reboot(); +} + +static uint32_t check_cmos_recovery(void) +{ + /* Only reset if cmos is valid */ + if (vbnv_cmos_failed()) + return 0; + + /* If the byte is set, clear it, then return error to reboot */ + if (cmos_read(CMOS_RECOVERY_BYTE) == CMOS_RECOVERY_MAGIC_VAL) { + cmos_write(0x00, CMOS_RECOVERY_BYTE); + printk(BIOS_DEBUG, "Reboot into recovery requested by coreboot\n"); + return POSTCODE_CMOS_RECOVERY; + } + + return 0; +} + +/* + * Tell the PSP where to load the rest of the firmware from + */ +static uint32_t update_boot_region(struct vb2_context *ctx) +{ + struct psp_ef_table *ef_table; + uint32_t psp_dir_addr, bios_dir_addr; + uint32_t *psp_dir_in_spi, *bios_dir_in_spi; + const char *fname; + void *amdfw_location; + + /* Continue booting from RO */ + if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { + printk(BIOS_ERR, "In recovery mode. Staying in RO.\n"); + return 0; + } + + if (vboot_is_firmware_slot_a(ctx)) { + fname = "apu/amdfw_a"; + } else { + fname = "apu/amdfw_b"; + } + + amdfw_location = cbfs_map(fname, NULL); + if (!amdfw_location) { + printk(BIOS_ERR, "Error: AMD Firmware table not found.\n"); + return POSTCODE_AMD_FW_MISSING; + } + ef_table = (struct psp_ef_table *)amdfw_location; + if (ef_table->signature != EMBEDDED_FW_SIGNATURE) { + printk(BIOS_ERR, "Error: ROMSIG address is not correct.\n"); + return POSTCODE_ROMSIG_MISMATCH_ERROR; + } + + psp_dir_addr = ef_table->psp_table; + bios_dir_addr = ef_table->bios1_entry; + psp_dir_in_spi = (uint32_t *)((psp_dir_addr & SPI_ADDR_MASK) + + (uint32_t)boot_dev.base); + bios_dir_in_spi = (uint32_t *)((bios_dir_addr & SPI_ADDR_MASK) + + (uint32_t)boot_dev.base); + if (*psp_dir_in_spi != PSP_COOKIE) { + printk(BIOS_ERR, "Error: PSP Directory address is not correct.\n"); + return POSTCODE_PSP_COOKIE_MISMATCH_ERROR; + } + if (*bios_dir_in_spi != BDT1_COOKIE) { + printk(BIOS_ERR, "Error: BIOS Directory address is not correct.\n"); + return POSTCODE_BDT1_COOKIE_MISMATCH_ERROR; + } + + if (svc_update_psp_bios_dir((void *)&psp_dir_addr, + (void *)&bios_dir_addr, DIR_OFFSET_SET)) { + printk(BIOS_ERR, "Error: Updated BIOS Directory could not be set.\n"); + return POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR; + } + + return 0; +} + +/* + * Save workbuf (and soon memory console and timestamps) to the bootloader to pass + * back to coreboot. + */ +static uint32_t save_buffers(struct vb2_context **ctx) +{ + uint32_t retval; + uint32_t buffer_size = MIN_TRANSFER_BUFFER_SIZE; + uint32_t max_buffer_size; + struct transfer_info_struct buffer_info = {0}; + + /* + * This should never fail, but if it does, we should still try to + * save the buffer. If that fails, then we should go to recovery mode. + */ + if (svc_get_max_workbuf_size(&max_buffer_size)) { + post_code(POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE); + printk(BIOS_NOTICE, "Notice: using default transfer buffer size.\n"); + max_buffer_size = MIN_TRANSFER_BUFFER_SIZE; + } + printk(BIOS_DEBUG, "\nMaximum buffer size: %d bytes\n", max_buffer_size); + + /* Shrink workbuf if MP2 is in use and cannot be used to save buffer */ + if (max_buffer_size < VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE) { + retval = vb2api_relocate(_vboot2_work, _vboot2_work, MIN_WORKBUF_TRANSFER_SIZE, + ctx); + if (retval != VB2_SUCCESS) { + printk(BIOS_ERR, "Error shrinking workbuf. Error code %#x\n", retval); + buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE; + post_code(POSTCODE_WORKBUF_RESIZE_WARNING); + } + } else { + buffer_size = + (uint32_t)((uintptr_t)_etransfer_buffer - (uintptr_t)_transfer_buffer); + + buffer_info.console_offset = (uint32_t)((uintptr_t)_preram_cbmem_console - + (uintptr_t)_transfer_buffer); + buffer_info.timestamp_offset = (uint32_t)((uintptr_t)_timestamp - + (uintptr_t)_transfer_buffer); + buffer_info.fmap_offset = (uint32_t)((uintptr_t)_fmap_cache - + (uintptr_t)_transfer_buffer); + } + + if (buffer_size > max_buffer_size) { + printk(BIOS_ERR, "Error: Buffer is larger than max buffer size.\n"); + post_code(POSTCODE_WORKBUF_BUFFER_SIZE_ERROR); + return POSTCODE_WORKBUF_BUFFER_SIZE_ERROR; + } + + buffer_info.magic_val = TRANSFER_MAGIC_VAL; + buffer_info.struct_bytes = sizeof(buffer_info); + buffer_info.buffer_size = buffer_size; + buffer_info.workbuf_offset = (uint32_t)((uintptr_t)_fmap_cache - + (uintptr_t)_vboot2_work); + + memcpy(_transfer_buffer, &buffer_info, sizeof(buffer_info)); + + retval = svc_save_uapp_data(UAPP_COPYBUF_CHROME_WORKBUF, (void *)_transfer_buffer, + buffer_size); + if (retval) { + printk(BIOS_ERR, "Error: Could not save workbuf. Error code 0x%08x\n", retval); + return POSTCODE_WORKBUF_SAVE_ERROR; + } + + return 0; +} + +void Main(void) +{ + uint32_t retval; + struct vb2_context *ctx = NULL; + + /* + * Do not use printk() before console_init() + * Do not use post_code() before verstage_mainboard_init() + */ + timestamp_init(timestamp_get()); + svc_write_postcode(POSTCODE_ENTERED_PSP_VERSTAGE); + svc_debug_print("Entering verstage on PSP\n"); + memset(&_bss_start, '\0', &_bss_end - &_bss_start); + + svc_write_postcode(POSTCODE_CONSOLE_INIT); + console_init(); + + svc_write_postcode(POSTCODE_EARLY_INIT); + retval = verstage_soc_early_init(); + if (retval) { + svc_debug_print("verstage_soc_early_init failed\n"); + reboot_into_recovery(NULL, retval); + } + svc_debug_print("calling verstage_mainboard_early_init\n"); + + verstage_mainboard_early_init(); + + svc_write_postcode(POSTCODE_LATE_INIT); + fch_io_enable_legacy_io(); + verstage_soc_init(); + verstage_mainboard_init(); + + post_code(POSTCODE_VERSTAGE_MAIN); + + vboot_run_logic(); + + ctx = vboot_get_context(); + retval = check_cmos_recovery(); + if (retval) + reboot_into_recovery(ctx, retval); + + post_code(POSTCODE_UPDATE_BOOT_REGION); + retval = update_boot_region(ctx); + if (retval) + reboot_into_recovery(ctx, retval); + + post_code(POSTCODE_SAVE_BUFFERS); + retval = save_buffers(&ctx); + if (retval) + reboot_into_recovery(ctx, retval); + + + post_code(POSTCODE_UNMAP_SPI_ROM); + if (boot_dev.base) { + if (svc_unmap_spi_rom((void *)boot_dev.base)) + printk(BIOS_ERR, "Error unmapping SPI rom\n"); + } + + post_code(POSTCODE_UNMAP_FCH_DEVICES); + unmap_fch_devices(); + + post_code(POSTCODE_LEAVING_VERSTAGE); + + printk(BIOS_DEBUG, "Leaving verstage on PSP\n"); + svc_exit(retval); +} + +const struct region_device *boot_device_ro(void) +{ + uintptr_t *addr; + + addr = map_spi_rom(); + mem_region_device_ro_init(&boot_dev, (void *)addr, CONFIG_ROM_SIZE); + + return &boot_dev.rdev; +} + +/* + * The stage_entry function is not used directly, but stage_entry() is marked as an entry + * point in arm/arch/header.h, so if stage_entry() isn't present and calling Main(), all + * the verstage code gets dropped by the linker. Slightly hacky, but mostly harmless. + */ +void stage_entry(uintptr_t stage_arg) +{ + Main(); +} diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.h b/src/soc/amd/common/psp_verstage/psp_verstage.h new file mode 100644 index 0000000000..4f85d7caa1 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/psp_verstage.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef PSP_VERSTAGE_H +#define PSP_VERSTAGE_H + +#include +#include + +#define EMBEDDED_FW_SIGNATURE 0x55aa55aa +#define PSP_COOKIE 0x50535024 /* 'PSP$' */ +#define BDT1_COOKIE 0x44484224 /* 'DHB$ */ + +#define PSP_VBOOT_ERROR_SUBCODE 0x0D5D0000 + +#define POSTCODE_ENTERED_PSP_VERSTAGE 0x00 +#define POSTCODE_CONSOLE_INIT 0x01 +#define POSTCODE_EARLY_INIT 0x02 +#define POSTCODE_LATE_INIT 0x03 +#define POSTCODE_VERSTAGE_MAIN 0x04 + +#define POSTCODE_SAVE_BUFFERS 0x0E +#define POSTCODE_UPDATE_BOOT_REGION 0x0F + +#define POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE 0xC0 +#define POSTCODE_WORKBUF_RESIZE_WARNING 0xC1 +#define POSTCODE_WORKBUF_SAVE_ERROR 0xC2 +#define POSTCODE_WORKBUF_BUFFER_SIZE_ERROR 0xC3 +#define POSTCODE_ROMSIG_MISMATCH_ERROR 0xC4 +#define POSTCODE_PSP_COOKIE_MISMATCH_ERROR 0xC5 +#define POSTCODE_BDT1_COOKIE_MISMATCH_ERROR 0xC6 +#define POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR 0xC7 +#define POSTCODE_FMAP_REGION_MISSING 0xC8 +#define POSTCODE_AMD_FW_MISSING 0xC9 +#define POSTCODE_CMOS_RECOVERY 0xCA + +#define POSTCODE_UNMAP_SPI_ROM 0xF0 +#define POSTCODE_UNMAP_FCH_DEVICES 0xF1 +#define POSTCODE_LEAVING_VERSTAGE 0xF2 + +#define SPI_ADDR_MASK 0x00ffffff +#define MIN_TRANSFER_BUFFER_SIZE (8 * KiB) +#define MIN_WORKBUF_TRANSFER_SIZE (MIN_TRANSFER_BUFFER_SIZE - TRANSFER_INFO_SIZE) + +struct psp_ef_table { + uint32_t signature; /* 0x55aa55aa */ + uint32_t reserved0[4]; + uint32_t psp_table; + uint32_t bios0_entry; + uint32_t bios1_entry; + uint32_t bios2_entry; +} __attribute__((packed, aligned(16))); + +void test_svc_calls(void); +uint32_t unmap_fch_devices(void); +uint32_t verstage_soc_early_init(void); +void verstage_soc_init(void); +uintptr_t *map_spi_rom(void); + +#endif /* PSP_VERSTAGE_H */ diff --git a/src/soc/amd/common/psp_verstage/reset.c b/src/soc/amd/common/psp_verstage/reset.c new file mode 100644 index 0000000000..7cd790795e --- /dev/null +++ b/src/soc/amd/common/psp_verstage/reset.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void do_board_reset(void) +{ + printk(BIOS_ERR, "Resetting the board now.\n"); + svc_reset_system(RESET_TYPE_COLD); +} diff --git a/src/soc/amd/common/psp_verstage/svc.c b/src/soc/amd/common/psp_verstage/svc.c new file mode 100644 index 0000000000..acc9c70318 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/svc.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "svc.h" + +#include +#include +#include + +void svc_exit(uint32_t status) +{ + uint32_t unused = 0; + SVC_CALL0(SVC_EXIT, unused); +} + +uint32_t svc_map_user_stack(void *start_addr, void *end_addr, void *stack_va) +{ + uint32_t retval = 0; + SVC_CALL3(SVC_MAP_USER_STACK, (uint32_t)start_addr, + (uint32_t)end_addr, stack_va, retval); + return retval; +} + +void svc_debug_print(const char *string) +{ + uint32_t unused = 0; + SVC_CALL1(SVC_DEBUG_PRINT, (uint32_t)string, unused); +} + +void svc_debug_print_ex(uint32_t dword0, + uint32_t dword1, uint32_t dword2, uint32_t dword3) +{ + uint32_t unused = 0; + SVC_CALL4(SVC_DEBUG_PRINT_EX, dword0, dword1, dword2, dword3, unused); +} + +uint32_t svc_wait_10ns_multiple(uint32_t multiple) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_WAIT_10NS_MULTIPLE, multiple, retval); + return retval; +} + +uint32_t svc_get_boot_mode(uint32_t *boot_mode) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_GET_BOOT_MODE, boot_mode, retval); + return retval; +} + +void svc_delay_in_usec(uint32_t delay) +{ + uint32_t unused = 0; + SVC_CALL1(SVC_DELAY_IN_MICRO_SECONDS, delay, unused); +} + +uint32_t svc_get_spi_rom_info(struct spirom_info *spi_rom_info) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_GET_SPI_INFO, (uint32_t)spi_rom_info, retval); + return retval; +} + +uint32_t svc_map_fch_dev(enum fch_io_device io_device, + uint32_t arg1, uint32_t arg2, void **io_device_axi_addr) +{ + uint32_t retval = 0; + assert(io_device < FCH_IO_DEVICE_END); + SVC_CALL4(SVC_MAP_FCH_IO_DEVICE, io_device, arg1, arg2, + (uint32_t)io_device_axi_addr, retval); + return retval; +} + +uint32_t svc_unmap_fch_dev(enum fch_io_device io_device, void *io_device_axi_addr) +{ + uint32_t retval = 0; + assert(io_device < FCH_IO_DEVICE_END); + SVC_CALL2(SVC_UNMAP_FCH_IO_DEVICE, (uint32_t)io_device, + (uint32_t)io_device_axi_addr, retval); + return retval; +} + +uint32_t svc_map_spi_rom(void *spi_rom_addr, + uint32_t size, void **spi_rom_axi_addr) +{ + uint32_t retval = 0; + SVC_CALL3(SVC_MAP_SPIROM_DEVICE, spi_rom_addr, size, + (uint32_t)spi_rom_axi_addr, retval); + return retval; +} + +uint32_t svc_unmap_spi_rom(void *spi_rom_addr) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_UNMAP_SPIROM_DEVICE, (uint32_t)spi_rom_addr, retval); + return retval; +} + +uint32_t svc_update_psp_bios_dir(uint32_t *psp_dir_offset, + uint32_t *bios_dir_offset, enum dir_offset_operation operation) +{ + uint32_t retval = 0; + assert(operation < DIR_OFFSET_OPERATION_MAX); + SVC_CALL3(SVC_UPDATE_PSP_BIOS_DIR, (uint32_t)psp_dir_offset, + (uint32_t)bios_dir_offset, operation, retval); + return retval; +} + +uint32_t svc_save_uapp_data(enum uapp_copybuf type, void *address, + uint32_t size) +{ + uint32_t retval = 0; + assert(type < UAPP_COPYBUF_MAX); + SVC_CALL3(SVC_COPY_DATA_FROM_UAPP, type, (uint32_t)address, size, retval); + return retval; +} + +uint32_t svc_read_timer_val(enum psp_timer_type type, uint64_t *counter_value) +{ + unsigned int retval = 0; + assert(type < PSP_TIMER_TYPE_MAX); + SVC_CALL2(SVC_READ_TIMER_VAL, type, counter_value, retval); + return retval; +} + +uint32_t svc_reset_system(enum reset_type reset_type) +{ + unsigned int retval = 0; + assert(reset_type < RESET_TYPE_MAX); + SVC_CALL1(SVC_RESET_SYSTEM, reset_type, retval); + return retval; +} + +uint32_t svc_write_postcode(uint32_t postcode) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_WRITE_POSTCODE, postcode, retval); + return retval; +} + +uint32_t svc_get_max_workbuf_size(uint32_t *size) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_GET_MAX_WORKBUF_SIZE, size, retval); + return retval; +} + +uint32_t svc_crypto_sha(struct sha_generic_data *sha_op, enum sha_operation_mode sha_mode) +{ + uint32_t retval = 0; + SVC_CALL2(SVC_SHA, sha_op, sha_mode, retval); + return retval; +} + +uint32_t svc_rsa_pkcs_verify(const struct rsapkcs_verify_params *rsa_params) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_RSAPKCS_VERIFY, rsa_params, retval); + return retval; +} + +uint32_t svc_modexp(struct mod_exp_params *mod_exp_param) +{ + uint32_t retval = 0; + SVC_CALL1(SVC_MODEXP, mod_exp_param, retval); + return retval; +} diff --git a/src/soc/amd/common/psp_verstage/svc.h b/src/soc/amd/common/psp_verstage/svc.h new file mode 100644 index 0000000000..03bae066e0 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/svc.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef PSP_VERSTAGE_SVC_H +#define PSP_VERSTAGE_SVC_H + +#define SVC_CALL4(SVC_ID, R0, R1, R2, R3, Ret) \ + __asm__ __volatile__ ( \ + "mov r0, %[reg0]\n\t" \ + "mov r1, %[reg1]\n\t" \ + "mov r2, %[reg2]\n\t" \ + "mov r3, %[reg3]\n\t" \ + "svc %[id]\n\t" \ + "mov %[result], r0\n\t" \ + : [result] "=r" (Ret) /* output */ \ + : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1), [reg2] "r" (R2), \ + [reg3] "r" (R3) /* input(s) */ \ + : "r0", "r1", "r2", "r3", "memory", "cc" /* list of clobbered registers */); + +#define SVC_CALL3(SVC_ID, R0, R1, R2, Ret) \ + __asm__ __volatile__ ( \ + "mov r0, %[reg0]\n\t" \ + "mov r1, %[reg1]\n\t" \ + "mov r2, %[reg2]\n\t" \ + "svc %[id]\n\t" \ + "mov %[result], r0\n\t" \ + : [result] "=r" (Ret) /* output */ \ + : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1), [reg2] "r" (R2) \ + : "r0", "r1", "r2", "memory", "cc" /* list of clobbered registers */); + +#define SVC_CALL2(SVC_ID, R0, R1, Ret) \ + __asm__ __volatile__ ( \ + "mov r0, %[reg0]\n\t" \ + "mov r1, %[reg1]\n\t" \ + "svc %[id]\n\t" \ + "mov %[result], r0\n\t" \ + : [result] "=r" (Ret) /* output */ \ + : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1)/* input(s) */ \ + : "r0", "r1", "memory", "cc" /* list of clobbered registers */); + +#define SVC_CALL1(SVC_ID, R0, Ret) \ + __asm__ __volatile__ ( \ + "mov r0, %[reg0]\n\t" \ + "svc %[id]\n\t" \ + "mov %[result], r0\n\t" \ + : [result] "=r" (Ret) /* output */ \ + : [id] "i" (SVC_ID), [reg0] "r" (R0) /* input(s) */ \ + : "r0", "memory", "cc" /* list of clobbered registers */); + +#define SVC_CALL0(SVC_ID, Ret) \ + __asm__ __volatile__ ( \ + "svc %[id]\n\t" \ + "mov %[result], r0\n\t" \ + : [result] "=r" (Ret) /* output */ \ + : [id] "I" (SVC_ID) /* input(s) */ \ + : "memory", "cc" /* list of clobbered registers */); + +#endif /* PSP_VERSTAGE_SVC_H */ diff --git a/src/soc/amd/common/psp_verstage/timer.c b/src/soc/amd/common/psp_verstage/timer.c new file mode 100644 index 0000000000..04728baf0c --- /dev/null +++ b/src/soc/amd/common/psp_verstage/timer.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void timer_monotonic_get(struct mono_time *mt) +{ + /* Chrono timer is based on a 25MHz clock */ + uint64_t clk; + + svc_read_timer_val(PSP_TIMER_TYPE_CHRONO, &clk); + + mt->microseconds = clk / 25; +} diff --git a/src/soc/amd/common/psp_verstage/vboot_crypto.c b/src/soc/amd/common/psp_verstage/vboot_crypto.c new file mode 100644 index 0000000000..3f7151ac11 --- /dev/null +++ b/src/soc/amd/common/psp_verstage/vboot_crypto.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <2crypto.h> +#include <2return_codes.h> +#include +#include +#include +#include "psp_verstage.h" +#include +#include +#include +#include + +static struct sha_generic_data sha_op; +static uint32_t sha_op_size_remaining; +static uint8_t __attribute__((aligned(32))) sha_hash[64]; + +vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, uint32_t data_size) +{ + printk(BIOS_DEBUG, "Calculating hash of %d bytes\n", data_size); + + sha_op_size_remaining = data_size; + + if (hash_alg == VB2_HASH_SHA256) { + sha_op.SHAType = SHA_TYPE_256; + sha_op.DigestLen = 32; + } else if (hash_alg == VB2_HASH_SHA512) { + sha_op.SHAType = SHA_TYPE_512; + sha_op.DigestLen = 64; + } else { + printk(BIOS_INFO, "Unsupported hash_alg %d!\n", hash_alg); + return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; + } + + /* Set init flag for first operation */ + sha_op.Init = 1; + + /* Clear eom flag until last operation */ + sha_op.Eom = 0; + + /* Need documentation on this b:157610147 */ + sha_op.DataMemType = 2; + + sha_op.Digest = sha_hash; + + sha_op.IntermediateDigest = NULL; + + sha_op.IntermediateMsgLen = 0; + + return VB2_SUCCESS; +} + +vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) +{ + uint32_t retval; + sha_op.Data = (uint8_t *) buf; + + if (!sha_op_size_remaining) { + printk(BIOS_ERR, "ERROR: got more data than expected.\n"); + return VB2_ERROR_UNKNOWN; + } + + while (size) { + sha_op.DataLen = size; + + sha_op_size_remaining -= sha_op.DataLen; + + /* Set eom flag for final operation */ + if (sha_op_size_remaining == 0) + sha_op.Eom = 1; + + retval = svc_crypto_sha(&sha_op, SHA_GENERIC); + if (retval) { + printk(BIOS_ERR, "ERROR: HW crypto failed - errorcode: %#x\n", + retval); + return VB2_ERROR_UNKNOWN; + } + + /* Clear init flag after first operation */ + if (sha_op.Init == 1) + sha_op.Init = 0; + + size -= sha_op.DataLen; + } + + return VB2_SUCCESS; +} + +/* Copy the hash back to verstage */ +vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size) +{ + if (sha_op.Eom == 0) { + printk(BIOS_ERR, "ERROR: Got less data than expected.\n"); + return VB2_ERROR_UNKNOWN; + } + + if (digest_size != sha_op.DigestLen) { + printk(BIOS_ERR, "ERROR: Digest size does not match expected length.\n"); + return VB2_ERROR_UNKNOWN; + } + + memcpy(digest, sha_hash, digest_size); + + return VB2_SUCCESS; +} + +vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key, + uint8_t *inout, + uint32_t *workbuf32, int exp) +{ + /* workbuf32 is guaranteed to be a length of + * 3 * key->arrsize * sizeof(uint32_t). + * Since PSP expects everything in LE and *inout is BE array, + * we'll use workbuf for temporary buffer for endian conversion. + */ + struct mod_exp_params mod_exp_param; + unsigned int key_bytes = key->arrsize * sizeof(uint32_t); + uint32_t *sig_swapped = workbuf32; + uint32_t *output_buffer = &workbuf32[key->arrsize]; + uint32_t *inout_32 = (uint32_t *)inout; + uint32_t retval; + uint32_t i; + + /* PSP only supports 2K and 4K moduli */ + if (key->sig_alg != VB2_SIG_RSA2048 && + key->sig_alg != VB2_SIG_RSA2048_EXP3 && + key->sig_alg != VB2_SIG_RSA4096) { + return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; + } + + for (i = 0; i < key->arrsize; i++) + sig_swapped[i] = swab32(inout_32[key->arrsize - i - 1]); + + mod_exp_param.pExponent = (char *)&exp; + mod_exp_param.ExpSize = sizeof(exp); + mod_exp_param.pModulus = (char *)key->n; + mod_exp_param.ModulusSize = key_bytes; + mod_exp_param.pMessage = (char *)sig_swapped; + mod_exp_param.pOutput = (char *)output_buffer; + + retval = svc_modexp(&mod_exp_param); + if (retval) { + printk(BIOS_ERR, "ERROR: HW crypto failed - errorcode: %#x\n", + retval); + return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; + } + + /* vboot expects results in *inout with BE, so copy & convert. */ + for (i = 0; i < key->arrsize; i++) + inout_32[i] = swab32(output_buffer[key->arrsize - i - 1]); + + return VB2_SUCCESS; +} diff --git a/src/soc/amd/picasso/Makefile.inc b/src/soc/amd/picasso/Makefile.inc index b5a2934922..e8ee087b7b 100644 --- a/src/soc/amd/picasso/Makefile.inc +++ b/src/soc/amd/picasso/Makefile.inc @@ -7,6 +7,7 @@ subdirs-y += ../../../cpu/x86/cache subdirs-y += ../../../cpu/x86/mtrr subdirs-y += ../../../cpu/x86/pae subdirs-$(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK) += psp_verstage +subdirs-$(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK) += ../common/psp_verstage # Beware that all-y also adds the compilation unit to verstage on PSP all-y += config.c diff --git a/src/soc/amd/picasso/psp_verstage/Makefile.inc b/src/soc/amd/picasso/psp_verstage/Makefile.inc index 0986fd8750..e70360fa51 100644 --- a/src/soc/amd/picasso/psp_verstage/Makefile.inc +++ b/src/soc/amd/picasso/psp_verstage/Makefile.inc @@ -2,26 +2,6 @@ verstage-generic-ccopts += -I$(src)/soc/amd/picasso/psp_verstage/include verstage-generic-ccopts += -I$(src)/vendorcode/amd/fsp/picasso/include -verstage-generic-ccopts += -D__USER_SPACE__ -CPPFLAGS_common += -I$(VBOOT_SOURCE)/firmware/2lib/include/ - -# This size should match the size in the linker script. -CFLAGS_arm += -Wstack-usage=40960 - -verstage-y += delay.c -verstage-y += fch.c -verstage-y += pmutil.c -verstage-y += post.c -verstage-y += printk.c -verstage-y += psp_verstage.c -verstage-y += psp.c -verstage-y += reset.c -verstage-y += svc.c -verstage-y += timer.c -verstage-y += vboot_crypto.c verstage-y += $(top)/src/vendorcode/amd/fsp/picasso/bl_uapp/bl_uapp_startup.S verstage-y += $(top)/src/vendorcode/amd/fsp/picasso/bl_uapp/bl_uapp_end.S - -$(obj)/psp_verstage.bin: $(objcbfs)/verstage.elf - $(OBJCOPY_verstage) -O binary $^ $@ diff --git a/src/soc/amd/picasso/psp_verstage/delay.c b/src/soc/amd/picasso/psp_verstage/delay.c deleted file mode 100644 index ff62524503..0000000000 --- a/src/soc/amd/picasso/psp_verstage/delay.c +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void udelay(uint32_t usecs) -{ - svc_delay_in_usec(usecs); -} diff --git a/src/soc/amd/picasso/psp_verstage/fch.c b/src/soc/amd/picasso/psp_verstage/fch.c deleted file mode 100644 index a032bde9b2..0000000000 --- a/src/soc/amd/picasso/psp_verstage/fch.c +++ /dev/null @@ -1,158 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include "psp_verstage.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void i2c3_set_bar(void *bar) -{ - i2c_set_bar(3, (uintptr_t)bar); -} - -static void i2c2_set_bar(void *bar) -{ - i2c_set_bar(2, (uintptr_t)bar); -} - -static void espi_set_bar(void *bar) -{ - espi_update_static_bar((uintptr_t)bar); -} - -static void iomux_set_bar(void *bar) -{ - acpimmio_iomux = bar; -} - -static void misc_set_bar(void *bar) -{ - acpimmio_misc = bar; -} - -static void gpio_set_bar(void *bar) -{ - acpimmio_gpio0 = bar; -} - -static uintptr_t io_bar; - -static void io_set_bar(void *bar) -{ - io_bar = (uintptr_t)bar; -} - -u8 io_read8(u16 reg) -{ - return read8((void *)(io_bar + reg)); -} - -void io_write8(u16 reg, u8 value) -{ - write8((void *)(io_bar + reg), value); -} - -static void aoac_set_bar(void *bar) -{ - acpimmio_aoac = bar; -} - -static struct { - const char *name; - struct { - enum fch_io_device device; - uint32_t arg0; - } args; - void (*set_bar)(void *bar); - void *_bar; -} bar_map[] = { - {"IOMUX", {FCH_IO_DEVICE_IOMUX}, iomux_set_bar}, - {"MISC", {FCH_IO_DEVICE_MISC}, misc_set_bar}, - {"GPIO", {FCH_IO_DEVICE_GPIO}, gpio_set_bar}, - {"IO", {FCH_IO_DEVICE_IOPORT}, io_set_bar}, - {"eSPI", {FCH_IO_DEVICE_ESPI}, espi_set_bar}, - {"I2C2", {FCH_IO_DEVICE_I2C, 2}, i2c2_set_bar}, - {"I2C3", {FCH_IO_DEVICE_I2C, 3}, i2c3_set_bar}, - {"SPI", {FCH_IO_DEVICE_SPI}, spi_set_base}, - {"AOAC", {FCH_IO_DEVICE_AOAC}, aoac_set_bar}, -}; - -uintptr_t *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; -} - -static uint32_t map_fch_devices(void) -{ - void *bar; - uint32_t err; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(bar_map); ++i) { - err = svc_map_fch_dev(bar_map[i].args.device, bar_map[i].args.arg0, 0, &bar); - if (err) { - printk(BIOS_ERR, "Failed to map %s: %u\n", bar_map[i].name, err); - return err; - } - - bar_map[i]._bar = bar; - bar_map[i].set_bar(bar); - } - - return BL_OK; -} - -uint32_t unmap_fch_devices(void) -{ - void *bar; - uint32_t err, rtn = BL_OK; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(bar_map); ++i) { - bar = bar_map[i]._bar; - if (!bar) - continue; - - err = svc_unmap_fch_dev(bar_map[i].args.device, bar); - if (err) { - printk(BIOS_ERR, "Failed to unmap %s: %u\n", bar_map[i].name, err); - rtn = err; - } else { - bar_map[i]._bar = NULL; - bar_map[i].set_bar(NULL); - } - } - - return rtn; -} - -uint32_t verstage_soc_early_init(void) -{ - return map_fch_devices(); -} - -void verstage_soc_init(void) -{ - if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI)) - espi_setup(); -} diff --git a/src/soc/amd/picasso/psp_verstage/include/arch/io.h b/src/soc/amd/picasso/psp_verstage/include/arch/io.h deleted file mode 100644 index efa128b25c..0000000000 --- a/src/soc/amd/picasso/psp_verstage/include/arch/io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __ARCH_IO_H__ -#define __ARCH_IO_H__ - -#include - -u8 io_read8(u16 reg); -void io_write8(u16 reg, u8 value); - -static inline void outb(uint8_t value, uint16_t port) -{ - io_write8(port, value); -} - -static inline uint8_t inb(uint16_t port) -{ - return io_read8(port); -} - -#endif diff --git a/src/soc/amd/picasso/psp_verstage/include/arch/smp/spinlock.h b/src/soc/amd/picasso/psp_verstage/include/arch/smp/spinlock.h deleted file mode 100644 index 0a3a4d4676..0000000000 --- a/src/soc/amd/picasso/psp_verstage/include/arch/smp/spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _ARCH_SMP_SPINLOCK_H -#define _ARCH_SMP_SPINLOCK_H - -#define DECLARE_SPIN_LOCK(x) -#define spin_is_locked(lock) 0 -#define spin_unlock_wait(lock) do {} while (0) -#define spin_lock(lock) do {} while (0) -#define spin_unlock(lock) do {} while (0) - -#include -#define boot_cpu() 1 - -#endif diff --git a/src/soc/amd/picasso/psp_verstage/pmutil.c b/src/soc/amd/picasso/psp_verstage/pmutil.c deleted file mode 100644 index ddaf54d470..0000000000 --- a/src/soc/amd/picasso/psp_verstage/pmutil.c +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -int platform_is_resuming(void) -{ - uint32_t bootmode = 0; - if (svc_get_boot_mode(&bootmode)) { - printk(BIOS_ERR, "Error getting boot mode. Assuming no resume.\n"); - return 0; - } - - if (bootmode == PSP_BOOT_MODE_S3_RESUME || bootmode == PSP_BOOT_MODE_S0i3_RESUME) - return 1; - - return 0; -} diff --git a/src/soc/amd/picasso/psp_verstage/post.c b/src/soc/amd/picasso/psp_verstage/post.c deleted file mode 100644 index 5b429c912b..0000000000 --- a/src/soc/amd/picasso/psp_verstage/post.c +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void arch_post_code(u8 value) -{ - if (CONFIG(POST_IO) && CONFIG_POST_IO_PORT == 0x80) - svc_write_postcode(value); -} diff --git a/src/soc/amd/picasso/psp_verstage/printk.c b/src/soc/amd/picasso/psp_verstage/printk.c deleted file mode 100644 index c56f78c298..0000000000 --- a/src/soc/amd/picasso/psp_verstage/printk.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -void console_hw_init(void) -{ - __cbmemc_init(); -} - -int printk(int msg_level, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i = vprintk(msg_level, fmt, args); - va_end(args); - - return i; -} - -int vprintk(int msg_level, const char *fmt, va_list args) -{ - int i, cnt, log_this; - char buf[256]; - - log_this = console_log_level(msg_level); - if (log_this < CONSOLE_LOG_FAST) - return 0; - - cnt = vsnprintf(buf, sizeof(buf), fmt, args); - for (i = 0; i < cnt; i++) - __cbmemc_tx_byte(buf[i]); - svc_debug_print(buf); - return i; -} diff --git a/src/soc/amd/picasso/psp_verstage/psp.c b/src/soc/amd/picasso/psp_verstage/psp.c deleted file mode 100644 index 7f24b20384..0000000000 --- a/src/soc/amd/picasso/psp_verstage/psp.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include - -int boot_cpu(void) -{ - return 1; -} diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.c b/src/soc/amd/picasso/psp_verstage/psp_verstage.c deleted file mode 100644 index d4c5d155af..0000000000 --- a/src/soc/amd/picasso/psp_verstage/psp_verstage.c +++ /dev/null @@ -1,277 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include "psp_verstage.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern char _bss_start, _bss_end; -static struct mem_region_device boot_dev = - MEM_REGION_DEV_RO_INIT(NULL, CONFIG_ROM_SIZE); - -void __weak verstage_mainboard_early_init(void) {} -void __weak verstage_mainboard_init(void) {} - -static void reboot_into_recovery(struct vb2_context *ctx, uint32_t subcode) -{ - subcode += PSP_VBOOT_ERROR_SUBCODE; - svc_write_postcode(subcode); - - /* - * If there's an error but the PSP_verstage is already booting to RO, - * don't reset the system. It may be that the error is fatal, but if - * the system is stuck, don't intentionally force it into a reboot loop. - */ - if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { - printk(BIOS_ERR, "Already in recovery mode. Staying in RO.\n"); - return; - } - - vb2api_fail(ctx, VB2_RECOVERY_RO_UNSPECIFIED, (int)subcode); - vboot_save_data(ctx); - - svc_debug_print("Rebooting into recovery\n"); - vboot_reboot(); -} - -static uint32_t check_cmos_recovery(void) -{ - /* Only reset if cmos is valid */ - if (vbnv_cmos_failed()) - return 0; - - /* If the byte is set, clear it, then return error to reboot */ - if (cmos_read(CMOS_RECOVERY_BYTE) == CMOS_RECOVERY_MAGIC_VAL) { - cmos_write(0x00, CMOS_RECOVERY_BYTE); - printk(BIOS_DEBUG, "Reboot into recovery requested by coreboot\n"); - return POSTCODE_CMOS_RECOVERY; - } - - return 0; -} - -/* - * Tell the PSP where to load the rest of the firmware from - */ -static uint32_t update_boot_region(struct vb2_context *ctx) -{ - struct psp_ef_table *ef_table; - uint32_t psp_dir_addr, bios_dir_addr; - uint32_t *psp_dir_in_spi, *bios_dir_in_spi; - const char *fname; - void *amdfw_location; - - /* Continue booting from RO */ - if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { - printk(BIOS_ERR, "In recovery mode. Staying in RO.\n"); - return 0; - } - - if (vboot_is_firmware_slot_a(ctx)) { - fname = "apu/amdfw_a"; - } else { - fname = "apu/amdfw_b"; - } - - amdfw_location = cbfs_map(fname, NULL); - if (!amdfw_location) { - printk(BIOS_ERR, "Error: AMD Firmware table not found.\n"); - return POSTCODE_AMD_FW_MISSING; - } - ef_table = (struct psp_ef_table *)amdfw_location; - if (ef_table->signature != EMBEDDED_FW_SIGNATURE) { - printk(BIOS_ERR, "Error: ROMSIG address is not correct.\n"); - return POSTCODE_ROMSIG_MISMATCH_ERROR; - } - - psp_dir_addr = ef_table->psp_table; - bios_dir_addr = ef_table->bios1_entry; - psp_dir_in_spi = (uint32_t *)((psp_dir_addr & SPI_ADDR_MASK) + - (uint32_t)boot_dev.base); - bios_dir_in_spi = (uint32_t *)((bios_dir_addr & SPI_ADDR_MASK) + - (uint32_t)boot_dev.base); - if (*psp_dir_in_spi != PSP_COOKIE) { - printk(BIOS_ERR, "Error: PSP Directory address is not correct.\n"); - return POSTCODE_PSP_COOKIE_MISMATCH_ERROR; - } - if (*bios_dir_in_spi != BDT1_COOKIE) { - printk(BIOS_ERR, "Error: BIOS Directory address is not correct.\n"); - return POSTCODE_BDT1_COOKIE_MISMATCH_ERROR; - } - - if (svc_update_psp_bios_dir((void *)&psp_dir_addr, - (void *)&bios_dir_addr, DIR_OFFSET_SET)) { - printk(BIOS_ERR, "Error: Updated BIOS Directory could not be set.\n"); - return POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR; - } - - return 0; -} - -/* - * Save workbuf (and soon memory console and timestamps) to the bootloader to pass - * back to coreboot. - */ -static uint32_t save_buffers(struct vb2_context **ctx) -{ - uint32_t retval; - uint32_t buffer_size = MIN_TRANSFER_BUFFER_SIZE; - uint32_t max_buffer_size; - struct transfer_info_struct buffer_info = {0}; - - /* - * This should never fail, but if it does, we should still try to - * save the buffer. If that fails, then we should go to recovery mode. - */ - if (svc_get_max_workbuf_size(&max_buffer_size)) { - post_code(POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE); - printk(BIOS_NOTICE, "Notice: using default transfer buffer size.\n"); - max_buffer_size = MIN_TRANSFER_BUFFER_SIZE; - } - printk(BIOS_DEBUG, "\nMaximum buffer size: %d bytes\n", max_buffer_size); - - /* Shrink workbuf if MP2 is in use and cannot be used to save buffer */ - if (max_buffer_size < VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE) { - retval = vb2api_relocate(_vboot2_work, _vboot2_work, MIN_WORKBUF_TRANSFER_SIZE, - ctx); - if (retval != VB2_SUCCESS) { - printk(BIOS_ERR, "Error shrinking workbuf. Error code %#x\n", retval); - buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE; - post_code(POSTCODE_WORKBUF_RESIZE_WARNING); - } - } else { - buffer_size = - (uint32_t)((uintptr_t)_etransfer_buffer - (uintptr_t)_transfer_buffer); - - buffer_info.console_offset = (uint32_t)((uintptr_t)_preram_cbmem_console - - (uintptr_t)_transfer_buffer); - buffer_info.timestamp_offset = (uint32_t)((uintptr_t)_timestamp - - (uintptr_t)_transfer_buffer); - buffer_info.fmap_offset = (uint32_t)((uintptr_t)_fmap_cache - - (uintptr_t)_transfer_buffer); - } - - if (buffer_size > max_buffer_size) { - printk(BIOS_ERR, "Error: Buffer is larger than max buffer size.\n"); - post_code(POSTCODE_WORKBUF_BUFFER_SIZE_ERROR); - return POSTCODE_WORKBUF_BUFFER_SIZE_ERROR; - } - - buffer_info.magic_val = TRANSFER_MAGIC_VAL; - buffer_info.struct_bytes = sizeof(buffer_info); - buffer_info.buffer_size = buffer_size; - buffer_info.workbuf_offset = (uint32_t)((uintptr_t)_fmap_cache - - (uintptr_t)_vboot2_work); - - memcpy(_transfer_buffer, &buffer_info, sizeof(buffer_info)); - - retval = svc_save_uapp_data(UAPP_COPYBUF_CHROME_WORKBUF, (void *)_transfer_buffer, - buffer_size); - if (retval) { - printk(BIOS_ERR, "Error: Could not save workbuf. Error code 0x%08x\n", retval); - return POSTCODE_WORKBUF_SAVE_ERROR; - } - - return 0; -} - -void Main(void) -{ - uint32_t retval; - struct vb2_context *ctx = NULL; - - /* - * Do not use printk() before console_init() - * Do not use post_code() before verstage_mainboard_init() - */ - timestamp_init(timestamp_get()); - svc_write_postcode(POSTCODE_ENTERED_PSP_VERSTAGE); - svc_debug_print("Entering verstage on PSP\n"); - memset(&_bss_start, '\0', &_bss_end - &_bss_start); - - svc_write_postcode(POSTCODE_CONSOLE_INIT); - console_init(); - - svc_write_postcode(POSTCODE_EARLY_INIT); - retval = verstage_soc_early_init(); - if (retval) { - svc_debug_print("verstage_soc_early_init failed\n"); - reboot_into_recovery(NULL, retval); - } - svc_debug_print("calling verstage_mainboard_early_init\n"); - - verstage_mainboard_early_init(); - - svc_write_postcode(POSTCODE_LATE_INIT); - fch_io_enable_legacy_io(); - verstage_soc_init(); - verstage_mainboard_init(); - - post_code(POSTCODE_VERSTAGE_MAIN); - - vboot_run_logic(); - - ctx = vboot_get_context(); - retval = check_cmos_recovery(); - if (retval) - reboot_into_recovery(ctx, retval); - - post_code(POSTCODE_UPDATE_BOOT_REGION); - retval = update_boot_region(ctx); - if (retval) - reboot_into_recovery(ctx, retval); - - post_code(POSTCODE_SAVE_BUFFERS); - retval = save_buffers(&ctx); - if (retval) - reboot_into_recovery(ctx, retval); - - - post_code(POSTCODE_UNMAP_SPI_ROM); - if (boot_dev.base) { - if (svc_unmap_spi_rom((void *)boot_dev.base)) - printk(BIOS_ERR, "Error unmapping SPI rom\n"); - } - - post_code(POSTCODE_UNMAP_FCH_DEVICES); - unmap_fch_devices(); - - post_code(POSTCODE_LEAVING_VERSTAGE); - - printk(BIOS_DEBUG, "Leaving verstage on PSP\n"); - svc_exit(retval); -} - -const struct region_device *boot_device_ro(void) -{ - uintptr_t *addr; - - addr = map_spi_rom(); - mem_region_device_ro_init(&boot_dev, (void *)addr, CONFIG_ROM_SIZE); - - return &boot_dev.rdev; -} - -/* - * The stage_entry function is not used directly, but stage_entry() is marked as an entry - * point in arm/arch/header.h, so if stage_entry() isn't present and calling Main(), all - * the verstage code gets dropped by the linker. Slightly hacky, but mostly harmless. - */ -void stage_entry(uintptr_t stage_arg) -{ - Main(); -} diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.h b/src/soc/amd/picasso/psp_verstage/psp_verstage.h deleted file mode 100644 index 4f85d7caa1..0000000000 --- a/src/soc/amd/picasso/psp_verstage/psp_verstage.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef PSP_VERSTAGE_H -#define PSP_VERSTAGE_H - -#include -#include - -#define EMBEDDED_FW_SIGNATURE 0x55aa55aa -#define PSP_COOKIE 0x50535024 /* 'PSP$' */ -#define BDT1_COOKIE 0x44484224 /* 'DHB$ */ - -#define PSP_VBOOT_ERROR_SUBCODE 0x0D5D0000 - -#define POSTCODE_ENTERED_PSP_VERSTAGE 0x00 -#define POSTCODE_CONSOLE_INIT 0x01 -#define POSTCODE_EARLY_INIT 0x02 -#define POSTCODE_LATE_INIT 0x03 -#define POSTCODE_VERSTAGE_MAIN 0x04 - -#define POSTCODE_SAVE_BUFFERS 0x0E -#define POSTCODE_UPDATE_BOOT_REGION 0x0F - -#define POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE 0xC0 -#define POSTCODE_WORKBUF_RESIZE_WARNING 0xC1 -#define POSTCODE_WORKBUF_SAVE_ERROR 0xC2 -#define POSTCODE_WORKBUF_BUFFER_SIZE_ERROR 0xC3 -#define POSTCODE_ROMSIG_MISMATCH_ERROR 0xC4 -#define POSTCODE_PSP_COOKIE_MISMATCH_ERROR 0xC5 -#define POSTCODE_BDT1_COOKIE_MISMATCH_ERROR 0xC6 -#define POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR 0xC7 -#define POSTCODE_FMAP_REGION_MISSING 0xC8 -#define POSTCODE_AMD_FW_MISSING 0xC9 -#define POSTCODE_CMOS_RECOVERY 0xCA - -#define POSTCODE_UNMAP_SPI_ROM 0xF0 -#define POSTCODE_UNMAP_FCH_DEVICES 0xF1 -#define POSTCODE_LEAVING_VERSTAGE 0xF2 - -#define SPI_ADDR_MASK 0x00ffffff -#define MIN_TRANSFER_BUFFER_SIZE (8 * KiB) -#define MIN_WORKBUF_TRANSFER_SIZE (MIN_TRANSFER_BUFFER_SIZE - TRANSFER_INFO_SIZE) - -struct psp_ef_table { - uint32_t signature; /* 0x55aa55aa */ - uint32_t reserved0[4]; - uint32_t psp_table; - uint32_t bios0_entry; - uint32_t bios1_entry; - uint32_t bios2_entry; -} __attribute__((packed, aligned(16))); - -void test_svc_calls(void); -uint32_t unmap_fch_devices(void); -uint32_t verstage_soc_early_init(void); -void verstage_soc_init(void); -uintptr_t *map_spi_rom(void); - -#endif /* PSP_VERSTAGE_H */ diff --git a/src/soc/amd/picasso/psp_verstage/reset.c b/src/soc/amd/picasso/psp_verstage/reset.c deleted file mode 100644 index 7cd790795e..0000000000 --- a/src/soc/amd/picasso/psp_verstage/reset.c +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void do_board_reset(void) -{ - printk(BIOS_ERR, "Resetting the board now.\n"); - svc_reset_system(RESET_TYPE_COLD); -} diff --git a/src/soc/amd/picasso/psp_verstage/svc.c b/src/soc/amd/picasso/psp_verstage/svc.c deleted file mode 100644 index acc9c70318..0000000000 --- a/src/soc/amd/picasso/psp_verstage/svc.c +++ /dev/null @@ -1,166 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include "svc.h" - -#include -#include -#include - -void svc_exit(uint32_t status) -{ - uint32_t unused = 0; - SVC_CALL0(SVC_EXIT, unused); -} - -uint32_t svc_map_user_stack(void *start_addr, void *end_addr, void *stack_va) -{ - uint32_t retval = 0; - SVC_CALL3(SVC_MAP_USER_STACK, (uint32_t)start_addr, - (uint32_t)end_addr, stack_va, retval); - return retval; -} - -void svc_debug_print(const char *string) -{ - uint32_t unused = 0; - SVC_CALL1(SVC_DEBUG_PRINT, (uint32_t)string, unused); -} - -void svc_debug_print_ex(uint32_t dword0, - uint32_t dword1, uint32_t dword2, uint32_t dword3) -{ - uint32_t unused = 0; - SVC_CALL4(SVC_DEBUG_PRINT_EX, dword0, dword1, dword2, dword3, unused); -} - -uint32_t svc_wait_10ns_multiple(uint32_t multiple) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_WAIT_10NS_MULTIPLE, multiple, retval); - return retval; -} - -uint32_t svc_get_boot_mode(uint32_t *boot_mode) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_GET_BOOT_MODE, boot_mode, retval); - return retval; -} - -void svc_delay_in_usec(uint32_t delay) -{ - uint32_t unused = 0; - SVC_CALL1(SVC_DELAY_IN_MICRO_SECONDS, delay, unused); -} - -uint32_t svc_get_spi_rom_info(struct spirom_info *spi_rom_info) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_GET_SPI_INFO, (uint32_t)spi_rom_info, retval); - return retval; -} - -uint32_t svc_map_fch_dev(enum fch_io_device io_device, - uint32_t arg1, uint32_t arg2, void **io_device_axi_addr) -{ - uint32_t retval = 0; - assert(io_device < FCH_IO_DEVICE_END); - SVC_CALL4(SVC_MAP_FCH_IO_DEVICE, io_device, arg1, arg2, - (uint32_t)io_device_axi_addr, retval); - return retval; -} - -uint32_t svc_unmap_fch_dev(enum fch_io_device io_device, void *io_device_axi_addr) -{ - uint32_t retval = 0; - assert(io_device < FCH_IO_DEVICE_END); - SVC_CALL2(SVC_UNMAP_FCH_IO_DEVICE, (uint32_t)io_device, - (uint32_t)io_device_axi_addr, retval); - return retval; -} - -uint32_t svc_map_spi_rom(void *spi_rom_addr, - uint32_t size, void **spi_rom_axi_addr) -{ - uint32_t retval = 0; - SVC_CALL3(SVC_MAP_SPIROM_DEVICE, spi_rom_addr, size, - (uint32_t)spi_rom_axi_addr, retval); - return retval; -} - -uint32_t svc_unmap_spi_rom(void *spi_rom_addr) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_UNMAP_SPIROM_DEVICE, (uint32_t)spi_rom_addr, retval); - return retval; -} - -uint32_t svc_update_psp_bios_dir(uint32_t *psp_dir_offset, - uint32_t *bios_dir_offset, enum dir_offset_operation operation) -{ - uint32_t retval = 0; - assert(operation < DIR_OFFSET_OPERATION_MAX); - SVC_CALL3(SVC_UPDATE_PSP_BIOS_DIR, (uint32_t)psp_dir_offset, - (uint32_t)bios_dir_offset, operation, retval); - return retval; -} - -uint32_t svc_save_uapp_data(enum uapp_copybuf type, void *address, - uint32_t size) -{ - uint32_t retval = 0; - assert(type < UAPP_COPYBUF_MAX); - SVC_CALL3(SVC_COPY_DATA_FROM_UAPP, type, (uint32_t)address, size, retval); - return retval; -} - -uint32_t svc_read_timer_val(enum psp_timer_type type, uint64_t *counter_value) -{ - unsigned int retval = 0; - assert(type < PSP_TIMER_TYPE_MAX); - SVC_CALL2(SVC_READ_TIMER_VAL, type, counter_value, retval); - return retval; -} - -uint32_t svc_reset_system(enum reset_type reset_type) -{ - unsigned int retval = 0; - assert(reset_type < RESET_TYPE_MAX); - SVC_CALL1(SVC_RESET_SYSTEM, reset_type, retval); - return retval; -} - -uint32_t svc_write_postcode(uint32_t postcode) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_WRITE_POSTCODE, postcode, retval); - return retval; -} - -uint32_t svc_get_max_workbuf_size(uint32_t *size) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_GET_MAX_WORKBUF_SIZE, size, retval); - return retval; -} - -uint32_t svc_crypto_sha(struct sha_generic_data *sha_op, enum sha_operation_mode sha_mode) -{ - uint32_t retval = 0; - SVC_CALL2(SVC_SHA, sha_op, sha_mode, retval); - return retval; -} - -uint32_t svc_rsa_pkcs_verify(const struct rsapkcs_verify_params *rsa_params) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_RSAPKCS_VERIFY, rsa_params, retval); - return retval; -} - -uint32_t svc_modexp(struct mod_exp_params *mod_exp_param) -{ - uint32_t retval = 0; - SVC_CALL1(SVC_MODEXP, mod_exp_param, retval); - return retval; -} diff --git a/src/soc/amd/picasso/psp_verstage/svc.h b/src/soc/amd/picasso/psp_verstage/svc.h deleted file mode 100644 index 03bae066e0..0000000000 --- a/src/soc/amd/picasso/psp_verstage/svc.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef PSP_VERSTAGE_SVC_H -#define PSP_VERSTAGE_SVC_H - -#define SVC_CALL4(SVC_ID, R0, R1, R2, R3, Ret) \ - __asm__ __volatile__ ( \ - "mov r0, %[reg0]\n\t" \ - "mov r1, %[reg1]\n\t" \ - "mov r2, %[reg2]\n\t" \ - "mov r3, %[reg3]\n\t" \ - "svc %[id]\n\t" \ - "mov %[result], r0\n\t" \ - : [result] "=r" (Ret) /* output */ \ - : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1), [reg2] "r" (R2), \ - [reg3] "r" (R3) /* input(s) */ \ - : "r0", "r1", "r2", "r3", "memory", "cc" /* list of clobbered registers */); - -#define SVC_CALL3(SVC_ID, R0, R1, R2, Ret) \ - __asm__ __volatile__ ( \ - "mov r0, %[reg0]\n\t" \ - "mov r1, %[reg1]\n\t" \ - "mov r2, %[reg2]\n\t" \ - "svc %[id]\n\t" \ - "mov %[result], r0\n\t" \ - : [result] "=r" (Ret) /* output */ \ - : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1), [reg2] "r" (R2) \ - : "r0", "r1", "r2", "memory", "cc" /* list of clobbered registers */); - -#define SVC_CALL2(SVC_ID, R0, R1, Ret) \ - __asm__ __volatile__ ( \ - "mov r0, %[reg0]\n\t" \ - "mov r1, %[reg1]\n\t" \ - "svc %[id]\n\t" \ - "mov %[result], r0\n\t" \ - : [result] "=r" (Ret) /* output */ \ - : [id] "i" (SVC_ID), [reg0] "r" (R0), [reg1] "r" (R1)/* input(s) */ \ - : "r0", "r1", "memory", "cc" /* list of clobbered registers */); - -#define SVC_CALL1(SVC_ID, R0, Ret) \ - __asm__ __volatile__ ( \ - "mov r0, %[reg0]\n\t" \ - "svc %[id]\n\t" \ - "mov %[result], r0\n\t" \ - : [result] "=r" (Ret) /* output */ \ - : [id] "i" (SVC_ID), [reg0] "r" (R0) /* input(s) */ \ - : "r0", "memory", "cc" /* list of clobbered registers */); - -#define SVC_CALL0(SVC_ID, Ret) \ - __asm__ __volatile__ ( \ - "svc %[id]\n\t" \ - "mov %[result], r0\n\t" \ - : [result] "=r" (Ret) /* output */ \ - : [id] "I" (SVC_ID) /* input(s) */ \ - : "memory", "cc" /* list of clobbered registers */); - -#endif /* PSP_VERSTAGE_SVC_H */ diff --git a/src/soc/amd/picasso/psp_verstage/timer.c b/src/soc/amd/picasso/psp_verstage/timer.c deleted file mode 100644 index 04728baf0c..0000000000 --- a/src/soc/amd/picasso/psp_verstage/timer.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void timer_monotonic_get(struct mono_time *mt) -{ - /* Chrono timer is based on a 25MHz clock */ - uint64_t clk; - - svc_read_timer_val(PSP_TIMER_TYPE_CHRONO, &clk); - - mt->microseconds = clk / 25; -} diff --git a/src/soc/amd/picasso/psp_verstage/vboot_crypto.c b/src/soc/amd/picasso/psp_verstage/vboot_crypto.c deleted file mode 100644 index 3f7151ac11..0000000000 --- a/src/soc/amd/picasso/psp_verstage/vboot_crypto.c +++ /dev/null @@ -1,153 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <2crypto.h> -#include <2return_codes.h> -#include -#include -#include -#include "psp_verstage.h" -#include -#include -#include -#include - -static struct sha_generic_data sha_op; -static uint32_t sha_op_size_remaining; -static uint8_t __attribute__((aligned(32))) sha_hash[64]; - -vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, uint32_t data_size) -{ - printk(BIOS_DEBUG, "Calculating hash of %d bytes\n", data_size); - - sha_op_size_remaining = data_size; - - if (hash_alg == VB2_HASH_SHA256) { - sha_op.SHAType = SHA_TYPE_256; - sha_op.DigestLen = 32; - } else if (hash_alg == VB2_HASH_SHA512) { - sha_op.SHAType = SHA_TYPE_512; - sha_op.DigestLen = 64; - } else { - printk(BIOS_INFO, "Unsupported hash_alg %d!\n", hash_alg); - return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; - } - - /* Set init flag for first operation */ - sha_op.Init = 1; - - /* Clear eom flag until last operation */ - sha_op.Eom = 0; - - /* Need documentation on this b:157610147 */ - sha_op.DataMemType = 2; - - sha_op.Digest = sha_hash; - - sha_op.IntermediateDigest = NULL; - - sha_op.IntermediateMsgLen = 0; - - return VB2_SUCCESS; -} - -vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) -{ - uint32_t retval; - sha_op.Data = (uint8_t *) buf; - - if (!sha_op_size_remaining) { - printk(BIOS_ERR, "ERROR: got more data than expected.\n"); - return VB2_ERROR_UNKNOWN; - } - - while (size) { - sha_op.DataLen = size; - - sha_op_size_remaining -= sha_op.DataLen; - - /* Set eom flag for final operation */ - if (sha_op_size_remaining == 0) - sha_op.Eom = 1; - - retval = svc_crypto_sha(&sha_op, SHA_GENERIC); - if (retval) { - printk(BIOS_ERR, "ERROR: HW crypto failed - errorcode: %#x\n", - retval); - return VB2_ERROR_UNKNOWN; - } - - /* Clear init flag after first operation */ - if (sha_op.Init == 1) - sha_op.Init = 0; - - size -= sha_op.DataLen; - } - - return VB2_SUCCESS; -} - -/* Copy the hash back to verstage */ -vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size) -{ - if (sha_op.Eom == 0) { - printk(BIOS_ERR, "ERROR: Got less data than expected.\n"); - return VB2_ERROR_UNKNOWN; - } - - if (digest_size != sha_op.DigestLen) { - printk(BIOS_ERR, "ERROR: Digest size does not match expected length.\n"); - return VB2_ERROR_UNKNOWN; - } - - memcpy(digest, sha_hash, digest_size); - - return VB2_SUCCESS; -} - -vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key, - uint8_t *inout, - uint32_t *workbuf32, int exp) -{ - /* workbuf32 is guaranteed to be a length of - * 3 * key->arrsize * sizeof(uint32_t). - * Since PSP expects everything in LE and *inout is BE array, - * we'll use workbuf for temporary buffer for endian conversion. - */ - struct mod_exp_params mod_exp_param; - unsigned int key_bytes = key->arrsize * sizeof(uint32_t); - uint32_t *sig_swapped = workbuf32; - uint32_t *output_buffer = &workbuf32[key->arrsize]; - uint32_t *inout_32 = (uint32_t *)inout; - uint32_t retval; - uint32_t i; - - /* PSP only supports 2K and 4K moduli */ - if (key->sig_alg != VB2_SIG_RSA2048 && - key->sig_alg != VB2_SIG_RSA2048_EXP3 && - key->sig_alg != VB2_SIG_RSA4096) { - return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; - } - - for (i = 0; i < key->arrsize; i++) - sig_swapped[i] = swab32(inout_32[key->arrsize - i - 1]); - - mod_exp_param.pExponent = (char *)&exp; - mod_exp_param.ExpSize = sizeof(exp); - mod_exp_param.pModulus = (char *)key->n; - mod_exp_param.ModulusSize = key_bytes; - mod_exp_param.pMessage = (char *)sig_swapped; - mod_exp_param.pOutput = (char *)output_buffer; - - retval = svc_modexp(&mod_exp_param); - if (retval) { - printk(BIOS_ERR, "ERROR: HW crypto failed - errorcode: %#x\n", - retval); - return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; - } - - /* vboot expects results in *inout with BE, so copy & convert. */ - for (i = 0; i < key->arrsize; i++) - inout_32[i] = swab32(output_buffer[key->arrsize - i - 1]); - - return VB2_SUCCESS; -} -- cgit v1.2.3