diff options
Diffstat (limited to 'src/soc/amd/phoenix/psp_verstage')
-rw-r--r-- | src/soc/amd/phoenix/psp_verstage/Makefile.inc | 19 | ||||
-rw-r--r-- | src/soc/amd/phoenix/psp_verstage/chipset.c | 115 | ||||
-rw-r--r-- | src/soc/amd/phoenix/psp_verstage/svc.c | 219 | ||||
-rw-r--r-- | src/soc/amd/phoenix/psp_verstage/svc.h | 98 | ||||
-rw-r--r-- | src/soc/amd/phoenix/psp_verstage/uart.c | 13 |
5 files changed, 464 insertions, 0 deletions
diff --git a/src/soc/amd/phoenix/psp_verstage/Makefile.inc b/src/soc/amd/phoenix/psp_verstage/Makefile.inc new file mode 100644 index 000000000000..6ff447c3a3f2 --- /dev/null +++ b/src/soc/amd/phoenix/psp_verstage/Makefile.inc @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ifeq $($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y) + +subdirs-y += ../../common/psp_verstage + +verstage-generic-ccopts += -I$(src)/soc/amd/phoenix/psp_verstage/include +verstage-generic-ccopts += -I$(src)/soc/amd/common/psp_verstage/include +verstage-generic-ccopts += -Isrc/vendorcode/amd/fsp/phoenix/include +verstage-generic-ccopts += -Isrc/vendorcode/amd/fsp/common/include + +verstage-y += svc.c +verstage-y += chipset.c +verstage-y += uart.c + +verstage-y +=$(top)/src/vendorcode/amd/fsp/common/bl_uapp/bl_uapp_startup.S +verstage-y += $(top)/src/vendorcode/amd/fsp/common/bl_uapp/bl_uapp_end.S + +endif diff --git a/src/soc/amd/phoenix/psp_verstage/chipset.c b/src/soc/amd/phoenix/psp_verstage/chipset.c new file mode 100644 index 000000000000..3f3a7cfcba93 --- /dev/null +++ b/src/soc/amd/phoenix/psp_verstage/chipset.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* TODO: Update for Phoenix */ + +#include <bl_uapp/bl_syscall_public.h> +#include <cbfs.h> +#include <console/console.h> +#include <psp_verstage.h> + +/* + * We can't pass pointer to hash table in the SPI. + * The AMD PSP team specifically required that whole hash table + * should be copied into memory before passing them to the PSP + * to reduce window of TOCTOU. + */ +#define MAX_NUM_HASH_ENTRIES 128 +static struct psp_fw_hash_table hash_table; +static struct psp_fw_entry_hash_256 hash_256[MAX_NUM_HASH_ENTRIES]; +static struct psp_fw_entry_hash_384 hash_384[MAX_NUM_HASH_ENTRIES]; + +void update_psp_fw_hash_table(const char *fname) +{ + uint8_t *spi_ptr = (uint8_t *)cbfs_map(fname, NULL); + uint32_t len; + + if (!spi_ptr) { + printk(BIOS_ERR, "AMD Firmware hash table %s not found\n", fname); + /* + * If we don't supply hash table, the PSP will refuse to boot. + * So returning here is safe to do. + */ + return; + } + + memcpy(&hash_table, spi_ptr, offsetof(struct psp_fw_hash_table, fw_hash_256)); + + if (hash_table.no_of_entries_256 > MAX_NUM_HASH_ENTRIES || + hash_table.no_of_entries_384 > MAX_NUM_HASH_ENTRIES) { + printk(BIOS_ERR, "Too many entries in AMD Firmware hash table" + " (SHA256:%d, SHA384:%d)\n", + hash_table.no_of_entries_256, hash_table.no_of_entries_384); + return; + } + + if (hash_table.no_of_entries_256 == 0 && + hash_table.no_of_entries_384 == 0) { + printk(BIOS_ERR, "No entries in AMD Firmware hash table" + " (SHA256:%d, SHA384:%d)\n", + hash_table.no_of_entries_256, hash_table.no_of_entries_384); + return; + } + + spi_ptr += offsetof(struct psp_fw_hash_table, fw_hash_256); + + hash_table.fw_hash_256 = hash_256; + hash_table.fw_hash_384 = hash_384; + len = sizeof(struct psp_fw_entry_hash_256) * hash_table.no_of_entries_256; + memcpy(hash_256, spi_ptr, len); + + spi_ptr += len; + len = sizeof(struct psp_fw_entry_hash_384) * hash_table.no_of_entries_384; + memcpy(hash_384, spi_ptr, len); + + svc_set_fw_hash_table(&hash_table); +} + +uint32_t update_psp_bios_dir(uint32_t *psp_dir_offset, uint32_t *bios_dir_offset) +{ + return svc_update_psp_bios_dir(psp_dir_offset, bios_dir_offset); +} + +uint32_t save_uapp_data(void *address, uint32_t size) +{ + return svc_save_uapp_data(address, size); +} + +uint32_t get_bios_dir_addr(struct embedded_firmware *ef_table) +{ + return 0; +} + +int platform_set_sha_op(enum vb2_hash_algorithm hash_alg, + struct sha_generic_data *sha_op) +{ + if (hash_alg == VB2_HASH_SHA256) { + sha_op->SHAType = SHA_TYPE_256; + sha_op->DigestLen = 32; + } else if (hash_alg == VB2_HASH_SHA384) { + sha_op->SHAType = SHA_TYPE_384; + sha_op->DigestLen = 48; + } else { + return -1; + } + return 0; +} + + +/* Functions below are stub functions for not-yet-implemented PSP features. + * These functions should be replaced with proper implementations later. + */ + +uint32_t svc_write_postcode(uint32_t postcode) +{ + return 0; +} + +void platform_report_mode(int developer_mode_enabled) +{ + printk(BIOS_INFO, "Reporting %s mode\n", + developer_mode_enabled ? "Developer" : "Normal"); + if (developer_mode_enabled) + svc_set_platform_boot_mode(CHROME_BOOK_BOOT_MODE_DEVELOPER); + else + svc_set_platform_boot_mode(CHROME_BOOK_BOOT_MODE_NORMAL); +} diff --git a/src/soc/amd/phoenix/psp_verstage/svc.c b/src/soc/amd/phoenix/psp_verstage/svc.c new file mode 100644 index 000000000000..becfcb09ca6b --- /dev/null +++ b/src/soc/amd/phoenix/psp_verstage/svc.c @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* TODO: Update for Phoenix */ + +#include "svc.h" + +#include <assert.h> +#include <bl_uapp/bl_syscall_public.h> +#include <psp_verstage.h> +#include <stddef.h> +#include <string.h> +#include <svc_call.h> + +void svc_exit(uint32_t status) +{ + uint32_t unused = 0; + SVC_CALL0(SVC_EXIT, unused); +} + +void svc_debug_print(const char *string) +{ + uint32_t unused = 0; + struct cmd_param_debug param = { + .debug_buffer = (char *)string, + .debug_buffer_len = strlen(string), + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_DEBUG_PRINT, (void *)¶m, unused); +} + +void svc_debug_print_ex(uint32_t dword0, + uint32_t dword1, uint32_t dword2, uint32_t dword3) +{ + uint32_t unused = 0; + struct cmd_param_debug_ex param = { + .word0 = dword0, + .word1 = dword1, + .word2 = dword2, + .word3 = dword3, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_DEBUG_PRINT_EX, (void *)¶m, unused); +} + +uint32_t svc_get_boot_mode(uint32_t *boot_mode) +{ + uint32_t retval = 0; + struct cmd_param_get_boot_mode param = { + .ptr_boot_mode = boot_mode, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_GET_BOOT_MODE, (void *)¶m, retval); + return retval; +} + +void svc_delay_in_usec(uint32_t delay) +{ + uint32_t unused = 0; + struct cmd_param_delay_in_micro_second param = { + .delay = delay, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_DELAY_IN_MICRO_SECONDS, (void *)¶m, unused); +} + +uint32_t svc_get_spi_rom_info(struct spirom_info *spi_rom_info) +{ + uint32_t retval = 0; + struct cmd_param_spirom_info param = { + .ptr_spirom_info = spi_rom_info, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_GET_SPI_INFO, (void *)¶m, 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; + struct cmd_param_map_fch_io_device param = { + .io_device = io_device, + .arg1 = arg1, + .arg2 = arg2, + .pptr_io_device_addr_axi = io_device_axi_addr, + }; + assert(io_device < FCH_IO_DEVICE_END); + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_MAP_FCH_IO_DEVICE, (void *)¶m, retval); + return retval; +} + +uint32_t svc_unmap_fch_dev(enum fch_io_device io_device, void *io_device_axi_addr) +{ + uint32_t retval = 0; + struct cmd_param_unmap_fch_io_device param = { + .io_device = io_device, + .ptr_io_device_addr_axi = io_device_axi_addr, + }; + assert(io_device < FCH_IO_DEVICE_END); + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_UNMAP_FCH_IO_DEVICE, (void *)¶m, 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; + struct cmd_param_map_spirom param = { + .spirom_addr = (uintptr_t)spi_rom_addr, + .size = size, + .ppspirom_addr_axi = spi_rom_axi_addr, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_MAP_SPIROM_DEVICE, (void *)¶m, retval); + return retval; +} + +uint32_t svc_unmap_spi_rom(void *spi_rom_addr) +{ + uint32_t retval = 0; + struct cmd_param_unmap_spirom param = { + .ptr_spirom_addr_axi = spi_rom_addr, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_UNMAP_SPIROM_DEVICE, (void *)¶m, retval); + return retval; +} + +uint32_t svc_update_psp_bios_dir(uint32_t *psp_dir_offset, + uint32_t *bios_dir_offset) +{ + uint32_t retval = 0; + struct cmd_param_psp_update param = { + .ptr_psp_dir_addr = psp_dir_offset, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_UPDATE_PSP_BIOS_DIR, (void *)¶m, retval); + return retval; +} + +uint32_t svc_save_uapp_data(void *address, uint32_t size) +{ + uint32_t retval = 0; + struct cmd_param_copy_data_from_uapp param = { + .address = (uintptr_t)address, + .size = size, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_COPY_DATA_FROM_UAPP, (void *)¶m, retval); + return retval; +} + +uint32_t svc_read_timer_val(enum psp_timer_type type, uint64_t *counter_value) +{ + unsigned int retval = 0; + struct cmd_param_read_timer_val param = { + .timer_type = type, + .ptr_counter_value = counter_value, + }; + assert(type < PSP_TIMER_TYPE_MAX); + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_READ_TIMER_VAL, (void *)¶m, retval); + return retval; +} + +uint32_t svc_reset_system(enum reset_type reset_type) +{ + unsigned int retval = 0; + struct cmd_param_reset_system param = { + .reset_type = reset_type, + }; + assert(reset_type < RESET_TYPE_MAX); + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_RESET_SYSTEM, (void *)¶m, retval); + return retval; +} + +uint32_t svc_crypto_sha(struct sha_generic_data *sha_op, enum sha_operation_mode sha_mode) +{ + uint32_t retval = 0; + struct cmd_param_sha param = { + .ptr_sha_op = sha_op, + }; + assert(sha_mode == SHA_GENERIC); + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_SHA, (void *)¶m, retval); + return retval; +} + +uint32_t svc_modexp(struct mod_exp_params *mod_exp_param) +{ + uint32_t retval = 0; + struct cmd_param_modexp param = { + .ptr_modexp = mod_exp_param, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_MODEXP, (void *)¶m, retval); + return retval; + +} + +uint32_t svc_ccp_dma(uint32_t spi_rom_offset, void *dest, uint32_t size) +{ + uint32_t retval = 0; + struct cmd_param_ccp_dma param = { + .spi_offset = spi_rom_offset, + .dst_addr = (uintptr_t)dest, + .size = size, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_CCP_DMA, (void *)¶m, retval); + return retval; +} + +uint32_t svc_set_platform_boot_mode(enum chrome_platform_boot_mode boot_mode) +{ + uint32_t retval = 0; + struct cmd_param_set_platform_boot_mode param = { + .boot_mode = boot_mode, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_SET_PLATFORM_BOOT_MODE, (void *)¶m, retval); + return retval; +} + +uint32_t svc_set_fw_hash_table(struct psp_fw_hash_table *hash_table) +{ + uint32_t retval = 0; + struct cmd_param_set_fw_hash_table param = { + .ptr_psp_fw_hash_table = hash_table, + }; + SVC_CALL2(SVC_VERSTAGE_CMD, CMD_SET_FW_HASH_TABLE, (void *)¶m, retval); + return retval; +} diff --git a/src/soc/amd/phoenix/psp_verstage/svc.h b/src/soc/amd/phoenix/psp_verstage/svc.h new file mode 100644 index 000000000000..3c59a1c28163 --- /dev/null +++ b/src/soc/amd/phoenix/psp_verstage/svc.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* TODO: Update for Phoenix */ +/* TODO: See what can be made common */ + +#ifndef PSP_VERSTAGE_SVC_H +#define PSP_VERSTAGE_SVC_H + +#include <bl_uapp/bl_syscall_public.h> +#include <types.h> + +struct cmd_param_sha { + struct sha_generic_data *ptr_sha_op; +}; + +struct cmd_param_debug { + char *debug_buffer; + uint32_t debug_buffer_len; +}; + +struct cmd_param_debug_ex { + uint32_t word0; + uint32_t word1; + uint32_t word2; + uint32_t word3; +}; + +struct cmd_param_modexp { + struct mod_exp_params *ptr_modexp; +}; + +struct cmd_param_psp_update { + unsigned int *ptr_psp_dir_addr; +}; + +struct cmd_param_spirom_info { + struct spirom_info *ptr_spirom_info; +}; + +struct cmd_param_map_spirom { + unsigned int spirom_addr; + unsigned int size; + void **ppspirom_addr_axi; +}; + +struct cmd_param_unmap_spirom { + void *ptr_spirom_addr_axi; +}; + +struct cmd_param_read_timer_val { + enum psp_timer_type timer_type; + uint64_t *ptr_counter_value; +}; + +struct cmd_param_delay_in_micro_second { + uint32_t delay; +}; + +struct cmd_param_reset_system { + uint32_t reset_type; +}; + +struct cmd_param_get_boot_mode { + unsigned int *ptr_boot_mode; +}; + +struct cmd_param_copy_data_from_uapp { + unsigned int address; + unsigned int size; +}; + +struct cmd_param_map_fch_io_device { + enum fch_io_device io_device; + unsigned int arg1; + unsigned int arg2; + void **pptr_io_device_addr_axi; +}; + +struct cmd_param_unmap_fch_io_device { + enum fch_io_device io_device; + void *ptr_io_device_addr_axi; +}; + +struct cmd_param_ccp_dma { + uint32_t spi_offset; + uint32_t dst_addr; + uint32_t size; +}; + +struct cmd_param_set_platform_boot_mode { + uint32_t boot_mode; +}; + +struct cmd_param_set_fw_hash_table { + struct psp_fw_hash_table *ptr_psp_fw_hash_table; +}; + +#endif /* PSP_VERSTAGE_SVC_H */ diff --git a/src/soc/amd/phoenix/psp_verstage/uart.c b/src/soc/amd/phoenix/psp_verstage/uart.c new file mode 100644 index 000000000000..d2cba278919f --- /dev/null +++ b/src/soc/amd/phoenix/psp_verstage/uart.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* TODO: Can this be made common? Kconfig option? */ + +#include <bl_uapp/bl_syscall_public.h> +#include <amdblocks/uart.h> +#include <types.h> + +uintptr_t get_uart_base(unsigned int idx) +{ + /* Mapping the UART is not supported. */ + return 0; +} |