Xilinx Zynq fixes and cleanups. Updated Xilinx SDK instructions for EL-1 / Hypervisor support. Updated the `zynq.ld` script to use 0x4000000 and only DDR0 region. Updated the example BIF files to use EL-1. Fix for cast warnings to `ext_flash_*` API's.

pull/39/head
David Garske 2020-03-30 07:52:07 -07:00
parent 1d2a3abd9a
commit 85b7c4d52f
10 changed files with 51 additions and 46 deletions

View File

@ -4,6 +4,17 @@ To use this example project:
1. Copy `.cproject` and `.project` into the wolfBoot root. 1. Copy `.cproject` and `.project` into the wolfBoot root.
2. From the Xilinx SDK Import wolfBoot using "Import" -> "Existing Projects into Workspace". 2. From the Xilinx SDK Import wolfBoot using "Import" -> "Existing Projects into Workspace".
## Xilinx SDK BSP
This project uses a BSP named `standalone_bsp_0`, which must be configured to use "hypervisor guest" in the BSP configuration settings. This will enable the EL-1 support required with Bl31 (ARM Trusted Firmware). The BSP generates a include/bspconfig.h, which should have these defines set:
```
#define EL1_NONSECURE 1
#define HYP_GUEST 1
```
Note: This is a generated file from the BSP configurator tool, which is edited by opening the `system.mss` file.
## wolfBoot Configuration ## wolfBoot Configuration
A build settings template for Zynq UltraScale+ can be found here `./config/examples/zynqmp.config`. This file can be copied to wolfBoot root as `.config` for building from the command line. These template settings are also in this `.cproject` as preprocessor macros. These settings are loaded into the `target.h.in` template by the wolfBoot `make`. If not using the built-in make then the following defines will need to be manually created in `target.h`: A build settings template for Zynq UltraScale+ can be found here `./config/examples/zynqmp.config`. This file can be copied to wolfBoot root as `.config` for building from the command line. These template settings are also in this `.cproject` as preprocessor macros. These settings are loaded into the `target.h.in` template by the wolfBoot `make`. If not using the built-in make then the following defines will need to be manually created in `target.h`:

View File

@ -6,6 +6,6 @@ the_ROM_image:
[destination_cpu=pmu] pmufw.elf [destination_cpu=pmu] pmufw.elf
[destination_device=pl] system.bit [destination_device=pl] system.bit
[destination_cpu=a53-0, exception_level=el-3, trustzone] bl31.elf [destination_cpu=a53-0, exception_level=el-3, trustzone] bl31.elf
[destination_cpu=a53-0, exception_level=el-2] wolfboot.elf [destination_cpu=a53-0, exception_level=el-1] wolfboot.elf
[destination_cpu=a53-0, offset=0x800000, partition_owner=uboot] helloworld_v1_signed.bin [destination_cpu=a53-0, partition_owner=uboot, offset=0x800000] helloworld_v1_signed.bin
} }

View File

@ -1,4 +1,5 @@
// Boot BIF example with Xilinx Secure Boot authentication and wolfBoot // Boot BIF example with Xilinx Secure Boot authentication and wolfBoot
// Note: Using partition_owner=uboot prevents FSBL from loading to RAM
the_ROM_image: the_ROM_image:
{ {
// Boot Header Authentication Enable // Boot Header Authentication Enable
@ -11,19 +12,17 @@ the_ROM_image:
[pskfile] pskf.pem [pskfile] pskf.pem
[sskfile] sskf.pem [sskfile] sskf.pem
[bootloader, destination_cpu=a53-0, authentication=rsa] zynqmp_fsbl.elf [destination_cpu=a53-0, authentication=rsa, bootloader] zynqmp_fsbl.elf
[destination_cpu=pmu, authentication=rsa] pmufw.elf [destination_cpu=pmu, authentication=rsa] pmufw.elf
[destination_device=pl, authentication=rsa] system.bit [destination_device=pl, authentication=rsa] system.bit
[destination_cpu=a53-0, exception_level=el-3, trustzone, authentication=rsa] bl31.elf [destination_cpu=a53-0, authentication=rsa, exception_level=el-3, trustzone] bl31.elf
[destination_cpu=a53-0, authentication=rsa, load=0x11800000] system.dtb
// Second Stage wolfBoot Bootloader
[destination_cpu=a53-0, authentication=rsa, exception_level=el-1] wolfboot.elf
// ARM Device Tree (loaded to RAM at 0x11800000 by wolfBoot) // ARM Device Tree (loaded to RAM at 0x11800000 by wolfBoot)
[ destination_cpu=a53-0, authentication=rsa, offset=0x007E0000, partition_owner=uboot] system.dtb [destination_cpu=a53-0, authentication=rsa, partition_owner=uboot, offset=0x7B0000] system.dtb
// Second Stage wolfBoot Bootloader (in RAM at 0x0)
[destination_cpu=a53-0, exception_level=el-2, authentication=rsa] wolfboot.elf
// Kernel / Application (load to RAM at 0x10000000 by wolfBoot) // Kernel / Application (load to RAM at 0x10000000 by wolfBoot)
// Using partition_owner=uboot prevents FSBL from loading to RAM [destination_cpu=a53-0, partition_owner=uboot, offset=0x800000] kernel_v1_signed.bin
[destination_cpu=a53-0, offset=0x800000, partition_owner=uboot] kernel.ui
} }

View File

@ -83,7 +83,7 @@ To associate the update or the swap partition to an external memory, define `PAR
The following functions are used to access the external memory, and must be defined when `EXT\_FLASH` The following functions are used to access the external memory, and must be defined when `EXT\_FLASH`
is on: is on:
`int ext_flash_write(uint32_t address, const uint8_t *data, int len)` `int ext_flash_write(uintptr_t address, const uint8_t *data, int len)`
This function provides an implementation of the flash write function, using the This function provides an implementation of the flash write function, using the
external memory's specific interface. `address` is the offset from the beginning of the external memory's specific interface. `address` is the offset from the beginning of the
@ -91,7 +91,7 @@ addressable space in the device, `data` is the payload to be stored,
and `len` is the size of the payload. `ext_flash_write` should return 0 upon success, and `len` is the size of the payload. `ext_flash_write` should return 0 upon success,
or a negative value in case of failure. or a negative value in case of failure.
`int ext_flash_read(uint32_t address, uint8_t *data, int len)` `int ext_flash_read(uintptr_t address, uint8_t *data, int len)`
This function provides an indirect read of the external memory, using the This function provides an indirect read of the external memory, using the
driver's specific interface. `address` is the offset from the beginning of the driver's specific interface. `address` is the offset from the beginning of the
@ -99,7 +99,7 @@ addressable space in the device, `data` is a pointer where payload is stored upo
call, and `len` is the maximum size allowed for the payload. `ext_flash_read` should return 0 call, and `len` is the maximum size allowed for the payload. `ext_flash_read` should return 0
upon success, or a negative value in case of failure. upon success, or a negative value in case of failure.
`int ext_flash_erase(uint32_t address, int len)` `int ext_flash_erase(uintptr_t address, int len)`
Called by the bootloader to erase part of the external memory. Called by the bootloader to erase part of the external memory.
Erase operations must be performed via the specific interface of the target driver (e.g. SPI flash). Erase operations must be performed via the specific interface of the target driver (e.g. SPI flash).

View File

@ -44,7 +44,7 @@
#include "xzynq_gqspi.h" #include "xzynq_gqspi.h"
#endif #endif
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014 #define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999 #define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999
/* Generic Quad-SPI */ /* Generic Quad-SPI */
@ -149,7 +149,7 @@
#define QSPIDMA_DST_CTRL2_DEF 0x081BFFF8UL #define QSPIDMA_DST_CTRL2_DEF 0x081BFFF8UL
/* QSPIDMA_DST_STS */ /* QSPIDMA_DST_STS */
#define QSPIDMA_DST_STS_WTC 0xE000U #define QSPIDMA_DST_STS_WTC 0xE000U
/* QSPIDMA_DST_I_STS */ /* QSPIDMA_DST_I_STS */
#define QSPIDMA_DST_I_STS_ALL_MASK 0xFEU #define QSPIDMA_DST_I_STS_ALL_MASK 0xFEU
@ -185,8 +185,8 @@
/* Flash Commands */ /* Flash Commands */
#define WRITE_ENABLE_CMD 0x06U #define WRITE_ENABLE_CMD 0x06U
#define WRITE_DISABLE_CMD 0x04U #define WRITE_DISABLE_CMD 0x04U
#define READ_ID_CMD 0x9FU #define READ_ID_CMD 0x9FU
#define MULTI_IO_READ_ID_CMD 0xAFU #define MULTI_IO_READ_ID_CMD 0xAFU
#define READ_FSR_CMD 0x70U #define READ_FSR_CMD 0x70U
@ -194,16 +194,12 @@
#define EXIT_QSPI_MODE_CMD 0xF5U #define EXIT_QSPI_MODE_CMD 0xF5U
#define ENTER_4B_ADDR_MODE_CMD 0xB7U #define ENTER_4B_ADDR_MODE_CMD 0xB7U
#define EXIT_4B_ADDR_MODE_CMD 0xE9U #define EXIT_4B_ADDR_MODE_CMD 0xE9U
#define FAST_READ_CMD 0x0BU #define FAST_READ_CMD 0x0BU
#define QUAD_READ_4B_CMD 0x6CU #define QUAD_READ_4B_CMD 0x6CU
#define PAGE_PROG_CMD 0x02U #define PAGE_PROG_CMD 0x02U
#define QUAD_PAGE_PROG_4B_CMD 0x34U #define QUAD_PAGE_PROG_4B_CMD 0x34U
#define SEC_ERASE_CMD 0xD8U #define SEC_ERASE_CMD 0xD8U
#define SEC_4K_ERASE_CMD 0x20U #define SEC_4K_ERASE_CMD 0x20U
#define RESET_ENABLE_CMD 0x66U #define RESET_ENABLE_CMD 0x66U
#define RESET_MEMORY_CMD 0x99U #define RESET_MEMORY_CMD 0x99U
@ -282,6 +278,7 @@ static int qspi_transfer(QspiDev_t* pDev,
return GQSPI_CODE_SUCCESS; return GQSPI_CODE_SUCCESS;
} }
#else #else
static inline int qspi_isr_wait(uint32_t wait_mask, uint32_t wait_val) static inline int qspi_isr_wait(uint32_t wait_mask, uint32_t wait_val)
{ {
uint32_t timeout = 0; uint32_t timeout = 0;

View File

@ -11,11 +11,8 @@ _EL2_STACK_SIZE = DEFINED(_EL2_STACK_SIZE) ? _EL2_STACK_SIZE : 1024;
/* Define Memories in the system */ /* Define Memories in the system */
MEMORY MEMORY
{ {
ddr4_ctrl_C0_DDR4_ADDRESS_BLOCK : ORIGIN = 0x500000000, LENGTH = 0x20000000 psu_ddr_0_MEM_0 : ORIGIN = 0x40000000, LENGTH = 0x100000
psu_ddr_0_MEM_0 : ORIGIN = 0x0, LENGTH = 0x7FF00000
psu_ddr_1_MEM_0 : ORIGIN = 0x800000000, LENGTH = 0x80000000
psu_ocm_ram_0_MEM_0 : ORIGIN = 0xFFFC0000, LENGTH = 0x40000
psu_qspi_linear_0_MEM_0 : ORIGIN = 0xC0000000, LENGTH = 0x20000000
} }
/* Specify the default entry point to the program */ /* Specify the default entry point to the program */
@ -230,16 +227,6 @@ SECTIONS
__sdata_end = .; __sdata_end = .;
} > psu_ddr_0_MEM_0 } > psu_ddr_0_MEM_0
.sbss (NOLOAD) : {
. = ALIGN(64);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
. = ALIGN(64);
__sbss_end = .;
} > psu_ddr_0_MEM_0
.tdata : { .tdata : {
. = ALIGN(64); . = ALIGN(64);
__tdata_start = .; __tdata_start = .;
@ -258,6 +245,17 @@ SECTIONS
__tbss_end = .; __tbss_end = .;
} > psu_ddr_0_MEM_0 } > psu_ddr_0_MEM_0
.sbss (NOLOAD) : {
. = ALIGN(64);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
. = ALIGN(64);
__sbss_end = .;
} > psu_ddr_0_MEM_0
.bss (NOLOAD) : { .bss (NOLOAD) : {
. = ALIGN(64); . = ALIGN(64);
__bss_start__ = .; __bss_start__ = .;

View File

@ -154,7 +154,7 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset)
if (offset > img->fw_size) if (offset > img->fw_size)
return NULL; return NULL;
if (PART_IS_EXT(img)) { if (PART_IS_EXT(img)) {
ext_flash_read((unsigned long)(img->fw_base) + offset, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE); ext_flash_read((uintptr_t)(img->fw_base) + offset, ext_hash_block, WOLFBOOT_SHA_BLOCK_SIZE);
return ext_hash_block; return ext_hash_block;
} else } else
return (uint8_t *)(img->fw_base + offset); return (uint8_t *)(img->fw_base + offset);

View File

@ -345,7 +345,7 @@ uint32_t wolfBoot_get_image_version(uint8_t part)
if (PARTN_IS_EXT(PART_UPDATE)) if (PARTN_IS_EXT(PART_UPDATE))
{ {
#ifdef EXT_FLASH #ifdef EXT_FLASH
ext_flash_read((uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE); ext_flash_read((uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE);
hdr_cpy_done = 1; hdr_cpy_done = 1;
image = hdr_cpy; image = hdr_cpy;
#endif #endif
@ -355,7 +355,7 @@ uint32_t wolfBoot_get_image_version(uint8_t part)
} else if (part == PART_BOOT) { } else if (part == PART_BOOT) {
if (PARTN_IS_EXT(PART_BOOT)) { if (PARTN_IS_EXT(PART_BOOT)) {
#ifdef EXT_FLASH #ifdef EXT_FLASH
ext_flash_read((uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE); ext_flash_read((uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE);
hdr_cpy_done = 1; hdr_cpy_done = 1;
image = hdr_cpy; image = hdr_cpy;
#endif #endif
@ -376,7 +376,7 @@ uint16_t wolfBoot_get_image_type(uint8_t part)
if (PARTN_IS_EXT(PART_UPDATE)) if (PARTN_IS_EXT(PART_UPDATE))
{ {
#ifdef EXT_FLASH #ifdef EXT_FLASH
ext_flash_read((uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE); ext_flash_read((uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE);
hdr_cpy_done = 1; hdr_cpy_done = 1;
image = hdr_cpy; image = hdr_cpy;
#endif #endif
@ -386,7 +386,7 @@ uint16_t wolfBoot_get_image_type(uint8_t part)
} else if (part == PART_BOOT) { } else if (part == PART_BOOT) {
if (PARTN_IS_EXT(PART_BOOT)) { if (PARTN_IS_EXT(PART_BOOT)) {
#ifdef EXT_FLASH #ifdef EXT_FLASH
ext_flash_read((uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE); ext_flash_read((uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS, hdr_cpy, IMAGE_HEADER_SIZE);
hdr_cpy_done = 1; hdr_cpy_done = 1;
image = hdr_cpy; image = hdr_cpy;
#endif #endif

View File

@ -52,7 +52,7 @@ static int wolfBoot_copy_sector(struct wolfBoot_image *src, struct wolfBoot_imag
wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE); wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE);
while (pos < WOLFBOOT_SECTOR_SIZE) { while (pos < WOLFBOOT_SECTOR_SIZE) {
if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) { if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) {
ext_flash_read((uint32_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE); ext_flash_read((uintptr_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE);
wb_flash_write(dst, dst_sector_offset + pos, buffer, FLASHBUFFER_SIZE); wb_flash_write(dst, dst_sector_offset + pos, buffer, FLASHBUFFER_SIZE);
} }
pos += FLASHBUFFER_SIZE; pos += FLASHBUFFER_SIZE;

View File

@ -56,7 +56,7 @@ static void RAMFUNCTION wolfBoot_self_update(struct wolfBoot_image *src)
if (PART_IS_EXT(src)) { if (PART_IS_EXT(src)) {
uint8_t buffer[FLASHBUFFER_SIZE]; uint8_t buffer[FLASHBUFFER_SIZE];
if (src_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) { if (src_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) {
ext_flash_read((uint32_t)(src->hdr) + src_offset + pos, (void *)buffer, FLASHBUFFER_SIZE); ext_flash_read((uintptr_t)(src->hdr) + src_offset + pos, (void *)buffer, FLASHBUFFER_SIZE);
hal_flash_write(pos + (uint32_t)&_start_text, buffer, FLASHBUFFER_SIZE); hal_flash_write(pos + (uint32_t)&_start_text, buffer, FLASHBUFFER_SIZE);
} }
pos += FLASHBUFFER_SIZE; pos += FLASHBUFFER_SIZE;
@ -122,7 +122,7 @@ static int wolfBoot_copy_sector(struct wolfBoot_image *src, struct wolfBoot_imag
wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE); wb_flash_erase(dst, dst_sector_offset, WOLFBOOT_SECTOR_SIZE);
while (pos < WOLFBOOT_SECTOR_SIZE) { while (pos < WOLFBOOT_SECTOR_SIZE) {
if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) { if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) {
ext_flash_read((uint32_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE); ext_flash_read((uintptr_t)(src->hdr) + src_sector_offset + pos, (void *)buffer, FLASHBUFFER_SIZE);
wb_flash_write(dst, dst_sector_offset + pos, buffer, FLASHBUFFER_SIZE); wb_flash_write(dst, dst_sector_offset + pos, buffer, FLASHBUFFER_SIZE);
} }
pos += FLASHBUFFER_SIZE; pos += FLASHBUFFER_SIZE;