Merge tag 'xilinx-for-v2018.05' of git://git.denx.de/u-boot-microblaze
Xilinx changes for v2018.05 - Fix mkimage recognition - Update all my fragments ZynqMP: - Use clk driver - Support loading elfs in el1 - Various DTS and defconfig changes - Enable newer pmufw versions - Support more clocks - Remove ep108 - Secure image support - Fix memtest setup Zynq: - Enabling watchdog driver - Support more clocks - defconfig changes fpga: - Simplify error path net: - GMII case update
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
ZYNQ BOARD
|
||||
M: Michal Simek <monstr@monstr.eu>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/zynq-*
|
||||
F: board/xilinx/zynq/
|
||||
F: include/configs/zynq*.h
|
||||
F: configs/zynq_*_defconfig
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <fdtdec.h>
|
||||
#include <fpga.h>
|
||||
#include <mmc.h>
|
||||
#include <wdt.h>
|
||||
#include <zynqpl.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
@@ -33,6 +35,22 @@ static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
|
||||
static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
|
||||
static struct udevice *watchdog_dev;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F)
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
# if defined(CONFIG_WDT)
|
||||
/* bss is not cleared at time when watchdog_reset() is called */
|
||||
watchdog_dev = NULL;
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
|
||||
@@ -75,6 +93,15 @@ int board_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
|
||||
if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
|
||||
puts("Watchdog: Not found!\n");
|
||||
} else {
|
||||
wdt_start(watchdog_dev, 0, 0);
|
||||
puts("Watchdog: Started\n");
|
||||
}
|
||||
# endif
|
||||
|
||||
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
|
||||
(defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
|
||||
fpga_init();
|
||||
@@ -164,3 +191,25 @@ int dram_init(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
/* Called by macro WATCHDOG_RESET */
|
||||
void watchdog_reset(void)
|
||||
{
|
||||
# if !defined(CONFIG_SPL_BUILD)
|
||||
static ulong next_reset;
|
||||
ulong now;
|
||||
|
||||
if (!watchdog_dev)
|
||||
return;
|
||||
|
||||
now = timer_get_us();
|
||||
|
||||
/* Do not reset the watchdog too often */
|
||||
if (now > next_reset) {
|
||||
wdt_reset(watchdog_dev);
|
||||
next_reset = now + 1000;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
18
board/xilinx/zynqmp/Kconfig
Normal file
18
board/xilinx/zynqmp/Kconfig
Normal file
@@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2018, Xilinx, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
if ARCH_ZYNQMP
|
||||
|
||||
config CMD_ZYNQMP
|
||||
bool "Enable ZynqMP specific commands"
|
||||
default y
|
||||
help
|
||||
Enable ZynqMP specific commands like "zynqmp secure"
|
||||
which is used for zynqmp secure image verification.
|
||||
The secure image is a xilinx specific BOOT.BIN with
|
||||
either authentication or encryption or both encryption
|
||||
and authentication feature enabled while generating
|
||||
BOOT.BIN using Xilinx bootgen tool.
|
||||
|
||||
endif
|
||||
@@ -1,6 +1,7 @@
|
||||
XILINX_ZYNQMP BOARDS
|
||||
M: Michal Simek <michal.simek@xilinx.com>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/zynqmp-*
|
||||
F: board/xilinx/zynqmp/
|
||||
F: include/configs/xilinx_zynqmp*
|
||||
F: configs/xilinx_zynqmp*
|
||||
|
||||
@@ -26,6 +26,10 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),)
|
||||
obj-y += $(init-objs)
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
|
||||
endif
|
||||
|
||||
# Suppress "warning: function declaration isn't a prototype"
|
||||
CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes
|
||||
|
||||
|
||||
105
board/xilinx/zynqmp/cmds.c
Normal file
105
board/xilinx/zynqmp/cmds.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* (C) Copyright 2018 Xilinx, Inc.
|
||||
* Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len)
|
||||
{
|
||||
int ret;
|
||||
u32 src_lo, src_hi;
|
||||
u32 key_lo = 0;
|
||||
u32 key_hi = 0;
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
u64 addr;
|
||||
|
||||
if ((ulong)src_ptr != ALIGN((ulong)src_ptr,
|
||||
CONFIG_SYS_CACHELINE_SIZE)) {
|
||||
printf("Failed: source address not aligned:%p\n", src_ptr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
src_lo = lower_32_bits((ulong)src_ptr);
|
||||
src_hi = upper_32_bits((ulong)src_ptr);
|
||||
flush_dcache_range((ulong)src_ptr, (ulong)(src_ptr + len));
|
||||
|
||||
if (key_ptr) {
|
||||
key_lo = lower_32_bits((ulong)key_ptr);
|
||||
key_hi = upper_32_bits((ulong)key_ptr);
|
||||
flush_dcache_range((ulong)key_ptr,
|
||||
(ulong)(key_ptr + KEY_PTR_LEN));
|
||||
}
|
||||
|
||||
ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi,
|
||||
key_lo, key_hi, ret_payload);
|
||||
if (ret) {
|
||||
printf("Failed: secure op status:0x%x\n", ret);
|
||||
} else {
|
||||
addr = (u64)ret_payload[1] << 32 | ret_payload[2];
|
||||
printf("Verified image at 0x%llx\n", addr);
|
||||
env_set_hex("zynqmp_verified_img_addr", addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_zynqmp - Handle the "zynqmp" command-line command
|
||||
* @cmdtp: Command data struct pointer
|
||||
* @flag: Command flag
|
||||
* @argc: Command-line argument count
|
||||
* @argv: Array of command-line arguments
|
||||
*
|
||||
* Processes the zynqmp specific commands
|
||||
*
|
||||
* Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
|
||||
*/
|
||||
static int do_zynqmp(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
u64 src_addr;
|
||||
u32 len;
|
||||
u8 *key_ptr = NULL;
|
||||
u8 *src_ptr;
|
||||
int ret;
|
||||
|
||||
if (argc > 5 || argc < 4 || strncmp(argv[1], "secure", 6))
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
src_addr = simple_strtoull(argv[2], NULL, 16);
|
||||
|
||||
len = simple_strtoul(argv[3], NULL, 16);
|
||||
|
||||
if (argc > 4)
|
||||
key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4],
|
||||
NULL, 16);
|
||||
|
||||
src_ptr = (uint8_t *)(uintptr_t)src_addr;
|
||||
|
||||
ret = zynqmp_verify_secure(key_ptr, src_ptr, len);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
#ifdef CONFIG_SYS_LONGHELP
|
||||
static char zynqmp_help_text[] =
|
||||
"secure src len [key_addr] - verifies secure images of $len bytes\n"
|
||||
" long at address $src. Optional key_addr\n"
|
||||
" can be specified if user key needs to\n"
|
||||
" be used for decryption\n";
|
||||
#endif
|
||||
|
||||
U_BOOT_CMD(
|
||||
zynqmp, 5, 1, do_zynqmp,
|
||||
"Verify and load secure images",
|
||||
zynqmp_help_text
|
||||
)
|
||||
@@ -31,6 +31,7 @@ static const struct {
|
||||
u32 id;
|
||||
u32 ver;
|
||||
char *name;
|
||||
bool evexists;
|
||||
} zynqmp_devices[] = {
|
||||
{
|
||||
.id = 0x10,
|
||||
@@ -53,11 +54,13 @@ static const struct {
|
||||
{
|
||||
.id = 0x20,
|
||||
.name = "5ev",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x20,
|
||||
.ver = 0x100,
|
||||
.name = "5eg",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x20,
|
||||
@@ -67,11 +70,13 @@ static const struct {
|
||||
{
|
||||
.id = 0x21,
|
||||
.name = "4ev",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x21,
|
||||
.ver = 0x100,
|
||||
.name = "4eg",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x21,
|
||||
@@ -81,11 +86,13 @@ static const struct {
|
||||
{
|
||||
.id = 0x30,
|
||||
.name = "7ev",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x30,
|
||||
.ver = 0x100,
|
||||
.name = "7eg",
|
||||
.evexists = 1,
|
||||
},
|
||||
{
|
||||
.id = 0x30,
|
||||
@@ -219,20 +226,48 @@ int chip_id(unsigned char id)
|
||||
return val;
|
||||
}
|
||||
|
||||
#define ZYNQMP_VERSION_SIZE 9
|
||||
#define ZYNQMP_PL_STATUS_BIT 9
|
||||
#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
|
||||
#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
|
||||
|
||||
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
|
||||
!defined(CONFIG_SPL_BUILD)
|
||||
static char *zynqmp_get_silicon_idcode_name(void)
|
||||
{
|
||||
u32 i, id, ver;
|
||||
char *buf;
|
||||
static char name[ZYNQMP_VERSION_SIZE];
|
||||
|
||||
id = chip_id(IDCODE);
|
||||
ver = chip_id(IDCODE2);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
|
||||
if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver)
|
||||
return zynqmp_devices[i].name;
|
||||
if ((zynqmp_devices[i].id == id) &&
|
||||
(zynqmp_devices[i].ver == (ver &
|
||||
ZYNQMP_CSU_VERSION_MASK))) {
|
||||
strncat(name, "zu", 2);
|
||||
strncat(name, zynqmp_devices[i].name,
|
||||
ZYNQMP_VERSION_SIZE - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
|
||||
if (i >= ARRAY_SIZE(zynqmp_devices))
|
||||
return "unknown";
|
||||
|
||||
if (!zynqmp_devices[i].evexists)
|
||||
return name;
|
||||
|
||||
if (ver & ZYNQMP_PL_STATUS_MASK)
|
||||
return name;
|
||||
|
||||
if (strstr(name, "eg") || strstr(name, "ev")) {
|
||||
buf = strstr(name, "e");
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -250,8 +285,6 @@ int board_early_init_f(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ZYNQMP_VERSION_SIZE 9
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
printf("EL Level:\tEL%d\n", current_el());
|
||||
@@ -260,12 +293,7 @@ int board_init(void)
|
||||
!defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
|
||||
defined(CONFIG_SPL_BUILD))
|
||||
if (current_el() != 3) {
|
||||
static char version[ZYNQMP_VERSION_SIZE];
|
||||
|
||||
strncat(version, "zu", 2);
|
||||
zynqmppl.name = strncat(version,
|
||||
zynqmp_get_silicon_idcode_name(),
|
||||
ZYNQMP_VERSION_SIZE - 3);
|
||||
zynqmppl.name = zynqmp_get_silicon_idcode_name();
|
||||
printf("Chip ID:\t%s\n", zynqmppl.name);
|
||||
fpga_init();
|
||||
fpga_add(fpga_xilinx, &zynqmppl);
|
||||
@@ -316,6 +344,23 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (current_el() > 1) {
|
||||
smp_kick_all_cpus();
|
||||
dcache_disable();
|
||||
armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
|
||||
ES_TO_AARCH64);
|
||||
} else {
|
||||
printf("FAIL: current EL is not above EL1\n");
|
||||
ret = EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user