This is an old revision of the document!
Overview
Quick run-through of the supporting content and files for a specific board; in this case, the hypothetical ZynqMP-based “Coyote” board from Acme Corp, with emphasis on Kbuild structure and not header files.
Based on:
CONFIG_SYS_ARCH="arm" CONFIG_SYS_CPU="armv8" CONFIG_SYS_SOC="zynqmp" CONFIG_SYS_VENDOR="xilinx" CONFIG_SYS_BOARD="zynqmp" CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp"
Writeup here.
Files/directories
Some of the following will already exist for generic ZynqMP content; use existing files as the starting point for Coyote-related content:
configs/acme_zynqmp_coyote_rev1_0_defconfig
include/configs/xilinx_zynqmp.h
arch/arm/KconfigMakefilemach-zynqmp/
- board/
- xilinx/
- zynq/
- Kconfig
- Makefile
- board.c
- cmds.c
- zynq-zed/
- common/
- board.c
configs/zynq_zed_defconfig
Board-specific config settings.
include/configs/
zynq-common.h
* Common configuration options for all Zynq boards. */ #ifndef __CONFIG_ZYNQ_COMMON_H #define __CONFIG_ZYNQ_COMMON_H /* CPU clock */ #ifndef CONFIG_CPU_FREQ_HZ # define CONFIG_CPU_FREQ_HZ 800000000 #endif #define CONFIG_REMAKE_ELF /* Cache options */ #define CONFIG_SYS_L2CACHE_OFF #ifndef CONFIG_SYS_L2CACHE_OFF # define CONFIG_SYS_L2_PL310 # define CONFIG_SYS_PL310_BASE 0xf8f02000 #endif #define ZYNQ_SCUTIMER_BASEADDR 0xF8F00600 #define CONFIG_SYS_TIMERBASE ZYNQ_SCUTIMER_BASEADDR #define CONFIG_SYS_TIMER_COUNTS_DOWN #define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMERBASE + 0x4) ... etc etc ...
arch/arm/
Things you should find under here:
- DTS config
- CPU initialization
- pinmux controller
- DRAM
- clocks
Kconfig
config ARCH_ZYNQ
bool "Xilinx Zynq based platform"
select BOARD_EARLY_INIT_F if WDT
select CLK
select CLK_ZYNQ
select CPU_V7A
select DM
select DM_ETH if NET
select DM_MMC if MMC
select DM_SERIAL
select DM_SPI
select DM_SPI_FLASH
select DM_USB if USB
select OF_CONTROL
select SPI
select SPL_BOARD_INIT if SPL
select SPL_CLK if SPL
select SPL_DM if SPL
select SPL_OF_CONTROL if SPL
select SPL_SEPARATE_BSS if SPL
select SUPPORT_SPL
imply ARCH_EARLY_INIT_R
imply BOARD_LATE_INIT
imply CMD_CLK
imply CMD_DM
imply CMD_SPL
imply FAT_WRITE
Makefile
machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp
mach-zynq/
clk.c cpu.c ddrc.c include Kconfig lowlevel_init.S Makefile ps7_spl_init.c slcr.c spl.c timer.c u-boot.lds u-boot-spl.lds
board/xilinx/zynq/
Kconfig
if ARCH_ZYNQ
config CMD_ZYNQ
bool "Enable Zynq specific commands"
default y
help
Enables Zynq specific commands.
config CMD_ZYNQ_AES
bool "Enable zynq aes command for decryption of encrypted images"
depends on CMD_ZYNQ
depends on FPGA_ZYNQPL
help
Decrypts the encrypted image present in source address
and places the decrypted image at destination address.
config CMD_ZYNQ_RSA
bool "Enable zynq rsa command for loading secure images"
default y
depends on CMD_ZYNQ
depends on CMD_ZYNQ_AES
help
Enabling this will support zynq 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
Makefile
obj-y := board.o
obj-y += ../common/board.o
ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"")
PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE))
init-objs := ps_init_gpl.o
spl/board/xilinx/zynq/ps_init_gpl.o board/xilinx/zynq/ps_init_gpl.o: $(PS_INIT_FILE)
$(CC) $(c_flags) -I $(srctree)/$(src) -c -o $@ $^
endif
ifeq ($(init-objs),)
hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE))
init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/ps7_init_gpl.c),\
$(hw-platform-y)/ps7_init_gpl.o)
endif
ifeq ($(init-objs),)
ifneq ($(wildcard $(srctree)/$(src)/ps7_init_gpl.c),)
init-objs := ps7_init_gpl.o
$(if $(CONFIG_SPL_BUILD),\
$(warning Put custom ps7_init_gpl.c/h to board/xilinx/zynq/custom_hw_platform/))
endif
endif
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_ZYNQ) += cmds.o
obj-$(CONFIG_CMD_ZYNQ_RSA) += bootimg.o
endif
obj-$(CONFIG_SPL_BUILD) += $(init-objs)
# Suppress "warning: function declaration isn't a prototype"
CFLAGS_REMOVE_ps7_init_gpl.o := -Wstrict-prototypes
# To include xil_io.h
CFLAGS_ps7_init_gpl.o := -I$(srctree)/$(src)
board.c
Probably need access to global data gd:
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) {
debug("Watchdog: Not found by seq!\n");
if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
puts("Watchdog: Not found!\n");
return 0;
}
}
wdt_start(watchdog_dev, 0, 0);
puts("Watchdog: Started\n");
# endif
return 0;
}
int board_late_init(void)
{
...
}
#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
int dram_init_banksize(void)
{
return fdtdec_setup_memory_banksize();
}
int dram_init(void)
{
if (fdtdec_setup_mem_size_base() != 0)
return -EINVAL;
zynq_ddrc_init();
return 0;
}
#else
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
CONFIG_SYS_SDRAM_SIZE);
zynq_ddrc_init();
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
}
cmds.c
static cmd_tbl_t zynq_commands[] = {
#ifdef CONFIG_CMD_ZYNQ_RSA
U_BOOT_CMD_MKENT(rsa, 3, 1, do_zynq_rsa, "", ""),
#endif
#ifdef CONFIG_CMD_ZYNQ_AES
U_BOOT_CMD_MKENT(aes, 6, 1, zynq_decrypt_image, "", ""),
#endif
};
static int do_zynq(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
cmd_tbl_t *zynq_cmd;
int ret;
if (!ARRAY_SIZE(zynq_commands)) {
puts("No zynq specific command enabled\n");
return CMD_RET_USAGE;
}
if (argc < 2)
return CMD_RET_USAGE;
zynq_cmd = find_cmd_tbl(argv[1], zynq_commands,
ARRAY_SIZE(zynq_commands));
if (!zynq_cmd || argc != zynq_cmd->maxargs)
return CMD_RET_USAGE;
ret = zynq_cmd->cmd(zynq_cmd, flag, argc, argv);
return cmd_process_error(zynq_cmd, ret);
}
#ifdef CONFIG_SYS_LONGHELP
static char zynq_help_text[] =
""
#ifdef CONFIG_CMD_ZYNQ_RSA
"rsa <baseaddr> - Verifies the authenticated and encrypted\n"
" zynq images and loads them back to load\n"
" addresses as specified in BOOT image(BOOT.BIN)\n"
#endif
#ifdef CONFIG_CMD_ZYNQ_AES
"aes <srcaddr> <srclen> <dstaddr> <dstlen>\n"
" - Decrypts the encrypted image present in source\n"
" address and places the decrypted image at\n"
" destination address\n"
#endif
;
#endif
U_BOOT_CMD(zynq, 6, 0, do_zynq,
"Zynq specific commands", zynq_help_text
);