summaryrefslogtreecommitdiffstats
path: root/src/soc/amd/phoenix/psp_verstage
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/phoenix/psp_verstage')
-rw-r--r--src/soc/amd/phoenix/psp_verstage/Makefile.inc19
-rw-r--r--src/soc/amd/phoenix/psp_verstage/chipset.c115
-rw-r--r--src/soc/amd/phoenix/psp_verstage/svc.c219
-rw-r--r--src/soc/amd/phoenix/psp_verstage/svc.h98
-rw-r--r--src/soc/amd/phoenix/psp_verstage/uart.c13
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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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 *)&param, 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;
+}