提交 3e99c183 编写于 作者: T Tom Rini

Merge branch '2020-01-07-master-imports'

- DT overlay support in FIT images in SPL
- remoteproc update
- Assorted SATA fixes
- Other assorted fixes
......@@ -444,6 +444,24 @@ config SPL_LOAD_FIT
particular it can handle selecting from multiple device tree
and passing the correct one to U-Boot.
config SPL_LOAD_FIT_APPLY_OVERLAY
bool "Enable SPL applying DT overlays from FIT"
depends on SPL_LOAD_FIT
select OF_LIBFDT_OVERLAY
help
The device tree is loaded from the FIT image. Allow the SPL is to
also load device-tree overlays from the FIT image an apply them
over the device tree.
config SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
depends on SPL_LOAD_FIT_APPLY_OVERLAY
default 0x10000
hex "size of temporary buffer used to load the overlays"
help
The size of the area where the overlays will be loaded and
uncompress. Must be at least as large as biggest overlay
(uncompressed)
config SPL_LOAD_FIT_FULL
bool "Enable SPL loading U-Boot as a FIT (full fitImage features)"
select SPL_FIT
......
......@@ -1265,7 +1265,7 @@ u-boot.ldr.hex u-boot.ldr.srec: u-boot.ldr FORCE
# from the SPL U-Boot version.
#
ifndef CONFIG_SYS_UBOOT_START
CONFIG_SYS_UBOOT_START := 0
CONFIG_SYS_UBOOT_START := $(CONFIG_SYS_TEXT_BASE)
endif
# Boards with more complex image requirements can provide an .its source file
......@@ -1292,7 +1292,8 @@ MKIMAGEFLAGS_u-boot.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
-p $(CONFIG_FIT_EXTERNAL_OFFSET) \
-n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) \
$(patsubst %,-b arch/$(ARCH)/dts/%.dtbo,$(subst ",,$(CONFIG_OF_OVERLAY_LIST)))
else
MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
......
......@@ -35,7 +35,9 @@
#define TAMP_CR1 (STM32_TAMP_BASE + 0x00)
#define PWR_CR1 (STM32_PWR_BASE + 0x00)
#define PWR_MCUCR (STM32_PWR_BASE + 0x14)
#define PWR_CR1_DBP BIT(8)
#define PWR_MCUCR_SBF BIT(6)
/* DBGMCU register */
#define DBGMCU_IDC (STM32_DBGMCU_BASE + 0x00)
......@@ -206,6 +208,11 @@ int arch_cpu_init(void)
security_init();
update_bootmode();
#endif
/* Reset Coprocessor state unless it wakes up from Standby power mode */
if (!(readl(PWR_MCUCR) & PWR_MCUCR_SBF)) {
writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE);
writel(0, TAMP_COPRO_RSC_TBL_ADDRESS);
}
#endif
boot_mode = get_bootmode();
......
......@@ -86,9 +86,18 @@ enum boot_device {
#define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x)
#define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4)
#define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5)
#define TAMP_COPRO_RSC_TBL_ADDRESS TAMP_BACKUP_REGISTER(17)
#define TAMP_COPRO_STATE TAMP_BACKUP_REGISTER(18)
#define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20)
#define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21)
#define TAMP_COPRO_STATE_OFF 0
#define TAMP_COPRO_STATE_INIT 1
#define TAMP_COPRO_STATE_CRUN 2
#define TAMP_COPRO_STATE_CSTOP 3
#define TAMP_COPRO_STATE_STANDBY 4
#define TAMP_COPRO_STATE_CRASH 5
#define TAMP_BOOT_MODE_MASK GENMASK(15, 8)
#define TAMP_BOOT_MODE_SHIFT 8
#define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4)
......
......@@ -1096,10 +1096,8 @@ static void board_copro_image_process(ulong fw_image, size_t fw_size)
printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
id, fw_image, fw_size, ret ? " Failed!" : " Success!");
if (!ret) {
if (!ret)
rproc_start(id);
env_set("copro_state", "booted");
}
}
U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
......@@ -294,6 +294,7 @@ config BOOTM_OPENRTOS
config BOOTM_OSE
bool "Support booting Enea OSE images"
depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
depends on CMD_BOOTM
help
Support booting Enea OSE images via the bootm command.
......
......@@ -348,6 +348,9 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
printf("Early malloc usage: %lx / %x\n", gd->malloc_ptr,
CONFIG_VAL(SYS_MALLOC_F_LEN));
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
print_num("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
#endif
if (gd->fdt_blob)
print_num("fdt_blob", (ulong)gd->fdt_blob);
......
......@@ -6,14 +6,20 @@
#include <common.h>
#include <errno.h>
#include <board.h>
#include <fpga.h>
#include <gzip.h>
#include <image.h>
#include <linux/libfdt.h>
#include <malloc.h>
#include <spl.h>
#include <linux/libfdt.h>
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ
#define CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ (64 * 1024)
#endif
#ifndef CONFIG_SYS_BOOTM_LEN
#define CONFIG_SYS_BOOTM_LEN (64 << 20)
#endif
......@@ -27,6 +33,29 @@ __weak ulong board_spl_fit_size_align(ulong size)
return size;
}
static int find_node_from_desc(const void *fit, int node, const char *str)
{
int child;
if (node < 0)
return -EINVAL;
/* iterate the FIT nodes and find a matching description */
for (child = fdt_first_subnode(fit, node); child >= 0;
child = fdt_next_subnode(fit, child)) {
int len;
const char *desc = fdt_getprop(fit, child, "description", &len);
if (!desc)
continue;
if (!strcmp(desc, str))
return child;
}
return -ENOENT;
}
/**
* spl_fit_get_image_name(): By using the matching configuration subnode,
* retrieve the name of an image, specified by a property name and an index
......@@ -41,12 +70,14 @@ __weak ulong board_spl_fit_size_align(ulong size)
*/
static int spl_fit_get_image_name(const void *fit, int images,
const char *type, int index,
char **outname)
const char **outname)
{
struct udevice *board;
const char *name, *str;
__maybe_unused int node;
int conf_node;
int len, i;
bool found = true;
conf_node = fit_find_config_node(fit);
if (conf_node < 0) {
......@@ -72,12 +103,45 @@ static int spl_fit_get_image_name(const void *fit, int images,
for (i = 0; i < index; i++) {
str = strchr(str, '\0') + 1;
if (!str || (str - name >= len)) {
debug("no string for index %d\n", index);
return -E2BIG;
found = false;
break;
}
}
*outname = (char *)str;
if (!found && !board_get(&board)) {
int rc;
/*
* no string in the property for this index. Check if the board
* level code can supply one.
*/
rc = board_get_fit_loadable(board, index - i - 1, type, &str);
if (rc && rc != -ENOENT)
return rc;
if (!rc) {
/*
* The board provided a name for a loadable.
* Try to match it against the description properties
* first. If no matching node is found, use it as a
* node name.
*/
int node;
int images = fdt_path_offset(fit, FIT_IMAGES_PATH);
node = find_node_from_desc(fit, images, str);
if (node > 0)
str = fdt_get_name(fit, node, NULL);
found = true;
}
}
if (!found) {
debug("no string for index %d\n", index);
return -E2BIG;
}
*outname = str;
return 0;
}
......@@ -96,7 +160,7 @@ static int spl_fit_get_image_name(const void *fit, int images,
static int spl_fit_get_image_node(const void *fit, int images,
const char *type, int index)
{
char *str;
const char *str;
int err;
int node;
......@@ -108,7 +172,7 @@ static int spl_fit_get_image_node(const void *fit, int images,
node = fdt_subnode_offset(fit, images, str);
if (node < 0) {
debug("cannot find image node '%s': %d\n", str, node);
pr_err("cannot find image node '%s': %d\n", str, node);
return -EINVAL;
}
......@@ -281,7 +345,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
void *fit, int images, ulong base_offset)
{
struct spl_image_info image_info;
int node, ret = 0;
int node, ret = 0, index = 0;
/*
* Use the address following the image as target address for the
......@@ -290,7 +354,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
image_info.load_addr = spl_image->load_addr + spl_image->size;
/* Figure out which device tree the board wants to use */
node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, index++);
if (node < 0) {
debug("%s: cannot find FDT node\n", __func__);
......@@ -313,8 +377,65 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
/* Make the load-address of the FDT available for the SPL framework */
spl_image->fdt_addr = (void *)image_info.load_addr;
#if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
if (CONFIG_IS_ENABLED(LOAD_FIT_APPLY_OVERLAY)) {
void *tmpbuffer = NULL;
for (; ; index++) {
node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP,
index);
if (node == -E2BIG) {
debug("%s: No additional FDT node\n", __func__);
break;
} else if (node < 0) {
debug("%s: unable to find FDT node %d\n",
__func__, index);
continue;
}
if (!tmpbuffer) {
/*
* allocate memory to store the DT overlay
* before it is applied. It may not be used
* depending on how the overlay is stored, so
* don't fail yet if the allocation failed.
*/
tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ);
if (!tmpbuffer)
debug("%s: unable to allocate space for overlays\n",
__func__);
}
image_info.load_addr = (ulong)tmpbuffer;
ret = spl_load_fit_image(info, sector, fit, base_offset,
node, &image_info);
if (ret < 0)
break;
/* Make room in FDT for changes from the overlay */
ret = fdt_increase_size(spl_image->fdt_addr,
image_info.size);
if (ret < 0)
break;
ret = fdt_overlay_apply_verbose(spl_image->fdt_addr,
(void *)image_info.load_addr);
if (ret) {
pr_err("failed to apply DT overlay %s\n",
fit_get_name(fit, node, NULL));
break;
}
debug("%s: DT overlay %s applied\n", __func__,
fit_get_name(fit, node, NULL));
}
if (tmpbuffer)
free(tmpbuffer);
if (ret)
return ret;
}
/* Try to make space, so we can inject details on the loadables */
ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
if (ret < 0)
return ret;
#endif
return ret;
......@@ -325,7 +446,7 @@ static int spl_fit_record_loadable(const void *fit, int images, int index,
{
int ret = 0;
#if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
char *name;
const char *name;
int node;
ret = spl_fit_get_image_name(fit, images, "loadables",
......@@ -373,6 +494,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
int images, ret;
int base_offset, hsize, align_len = ARCH_DMA_MINALIGN - 1;
int index = 0;
int firmware_node;
/*
* For FIT with external data, figure out where the external images
......@@ -502,6 +624,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
spl_fit_append_fdt(spl_image, info, sector, fit,
images, base_offset);
firmware_node = node;
/* Now check if there are more images for us to load */
for (; ; index++) {
uint8_t os_type = IH_OS_INVALID;
......@@ -510,6 +633,14 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
if (node < 0)
break;
/*
* if the firmware is also a loadable, skip it because
* it already has been loaded. This is typically the case with
* u-boot.img generated by mkimage.
*/
if (firmware_node == node)
continue;
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
&image_info);
if (ret < 0)
......
......@@ -26,6 +26,7 @@ obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/
obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/
obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/
obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += power/acpi_pmc/
obj-$(CONFIG_$(SPL_)BOARD) += board/
ifndef CONFIG_TPL_BUILD
ifdef CONFIG_SPL_BUILD
......@@ -75,7 +76,6 @@ obj-y += ata/
obj-$(CONFIG_DM_DEMO) += demo/
obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += block/
obj-y += board/
obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
obj-y += cache/
obj-$(CONFIG_CPU) += cpu/
......
......@@ -22,6 +22,7 @@
#include <dm.h>
#include <ahci.h>
#include <blk.h>
#include <dm/device-internal.h>
#else
#ifndef CONFIG_SYS_SATA1_FLAGS
#define CONFIG_SYS_SATA1_FLAGS FLAGS_DMA
......@@ -122,7 +123,7 @@ static int init_sata(struct fsl_ata_priv *priv, int dev)
/* Zero all of the device driver struct */
memset((void *)sata, 0, sizeof(fsl_sata_t));
snprintf(sata->name, 12, "SATA%d:\n", dev);
snprintf(sata->name, 12, "SATA%d:", dev);
/* Set the controller register base address to device struct */
#if !CONFIG_IS_ENABLED(BLK)
......@@ -233,10 +234,7 @@ static int init_sata(struct fsl_ata_priv *priv, int dev)
mdelay(100);
/* print sata device name */
if (!dev)
printf("%s ", sata->name);
else
printf(" %s ", sata->name);
printf("%s ", sata->name);
/* Wait PHY RDY signal changed for 500ms */
ata_wait_register(&reg->hstatus, HSTATUS_PHY_RDY,
......@@ -917,15 +915,32 @@ static int fsl_ata_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static int fsl_unbind_device(struct udevice *dev)
{
int ret;
ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
ret = device_unbind(dev);
if (ret)
return ret;
return 0;
}
static int fsl_ata_probe(struct udevice *dev)
{
struct fsl_ata_priv *blk_priv, *priv;
struct udevice *blk;
int failed_number;
char sata_name[10];
int nr_ports;
int ret;
int i;
failed_number = 0;
priv = dev_get_priv(dev);
nr_ports = priv->number;
nr_ports = min(nr_ports, CONFIG_SYS_SATA_MAX_DEVICE);
......@@ -943,7 +958,12 @@ static int fsl_ata_probe(struct udevice *dev)
ret = init_sata(priv, i);
if (ret) {
debug("%s: Failed to init sata\n", __func__);
return ret;
ret = fsl_unbind_device(blk);
if (ret)
return ret;
failed_number++;
continue;
}
blk_priv = dev_get_platdata(blk);
......@@ -952,10 +972,33 @@ static int fsl_ata_probe(struct udevice *dev)
ret = scan_sata(blk);
if (ret) {
debug("%s: Failed to scan bus\n", __func__);
return ret;
ret = fsl_unbind_device(blk);
if (ret)
return ret;
failed_number++;
continue;
}
}
if (failed_number == nr_ports)
return -ENODEV;
else
return 0;
}
static int fsl_ata_remove(struct udevice *dev)
{
fsl_sata_t *sata;
struct fsl_ata_priv *priv;
priv = dev_get_priv(dev);
sata = priv->fsl_sata;
free(sata->cmd_hdr_tbl_offset);
free(sata->cmd_desc_offset);
free(sata);
return 0;
}
......@@ -982,6 +1025,7 @@ U_BOOT_DRIVER(fsl_ahci) = {
.ops = &sata_fsl_ahci_ops,
.ofdata_to_platdata = fsl_ata_ofdata_to_platdata,
.probe = fsl_ata_probe,
.remove = fsl_ata_remove,
.priv_auto_alloc_size = sizeof(struct fsl_ata_priv),
};
#endif
......@@ -20,6 +20,7 @@
#if CONFIG_IS_ENABLED(BLK)
#include <dm.h>
#include <blk.h>
#include <dm/device-internal.h>
#endif
#include "sata_sil.h"
......@@ -763,15 +764,33 @@ U_BOOT_DRIVER(sata_sil_driver) = {
.platdata_auto_alloc_size = sizeof(struct sil_sata_priv),
};
static int sil_unbind_device(struct udevice *dev)
{
int ret;
ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;
ret = device_unbind(dev);
if (ret)
return ret;
return 0;
}
static int sil_pci_probe(struct udevice *dev)
{
struct udevice *blk;
int failed_number;
char sata_name[10];
pci_dev_t devno;
u16 word;
int ret;
int i;
failed_number = 0;
/* Get PCI device number */
devno = dm_pci_get_bdf(dev);
if (devno == -1)
......@@ -824,12 +843,44 @@ static int sil_pci_probe(struct udevice *dev)
}
ret = sil_init_sata(blk, i);
if (ret)
return -ENODEV;
if (ret) {
ret = sil_unbind_device(blk);
if (ret)
return ret;
failed_number++;
continue;
}
ret = scan_sata(blk, i);
if (ret)
return -ENODEV;
if (ret) {
ret = sil_unbind_device(blk);
if (ret)
return ret;
failed_number++;
continue;
}
}
if (failed_number == sata_info.maxport)
return -ENODEV;
else
return 0;
}
static int sil_pci_remove(struct udevice *dev)
{
int i;
struct sil_sata *sata;
struct sil_sata_priv *priv;
priv = dev_get_priv(dev);
for (i = sata_info.portbase; i < sata_info.maxport; i++) {
sata = priv->sil_sata_desc[i];
if (sata)
free(sata);
}
return 0;
......@@ -857,6 +908,7 @@ U_BOOT_DRIVER(sil_ahci_pci) = {
.of_match = sil_pci_ids,
.ops = &sata_sil_ops,
.probe = sil_pci_probe,
.remove = sil_pci_remove,
.priv_auto_alloc_size = sizeof(struct sil_sata_priv),
};
......
......@@ -8,6 +8,9 @@ menuconfig BOARD
if BOARD
config SPL_BOARD
depends on SPL_DM
bool "Enable board driver support in SPL"
config BOARD_GAZERBEAM
bool "Enable board driver for the Gazerbeam board"
......
......@@ -2,6 +2,6 @@
#
# (C) Copyright 2017
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
obj-$(CONFIG_BOARD) += board-uclass.o
obj-y += board-uclass.o
obj-$(CONFIG_BOARD_GAZERBEAM) += gazerbeam.o
obj-$(CONFIG_BOARD_SANDBOX) += sandbox.o
......@@ -23,6 +23,17 @@ int board_detect(struct udevice *dev)
return ops->detect(dev);
}
int board_get_fit_loadable(struct udevice *dev, int index,
const char *type, const char **strp)
{
struct board_ops *ops = board_get_ops(dev);
if (!ops->get_fit_loadable)
return -ENOSYS;
return ops->get_fit_loadable(dev, index, type, strp);
}
int board_get_bool(struct udevice *dev, int id, bool *val)
{
struct board_ops *ops = board_get_ops(dev);
......
......@@ -37,7 +37,11 @@ int regulator_common_ofdata_to_platdata(struct udevice *dev,
dev_pdata->startup_delay_us = dev_read_u32_default(dev,
"startup-delay-us", 0);
dev_pdata->off_on_delay_us =
dev_read_u32_default(dev, "off-on-delay-us", 0);
if (!dev_pdata->off_on_delay_us) {
dev_pdata->off_on_delay_us =
dev_read_u32_default(dev, "u-boot,off-on-delay-us", 0);
}
return 0;
}
......
......@@ -8,6 +8,39 @@
#include <elf.h>
#include <remoteproc.h>
/**
* struct resource_table - firmware resource table header
* @ver: version number
* @num: number of resource entries
* @reserved: reserved (must be zero)
* @offset: array of offsets pointing at the various resource entries
*
* A resource table is essentially a list of system resources required
* by the remote processor. It may also include configuration entries.
* If needed, the remote processor firmware should contain this table
* as a dedicated ".resource_table" ELF section.
*
* Some resources entries are mere announcements, where the host is informed
* of specific remoteproc configuration. Other entries require the host to
* do something (e.g. allocate a system resource). Sometimes a negotiation
* is expected, where the firmware requests a resource, and once allocated,
* the host should provide back its details (e.g. address of an allocated
* memory region).
*
* The header of the resource table, as expressed by this structure,
* contains a version number (should we need to change this format in the
* future), the number of available resource entries, and their offsets
* in the table.
*
* Immediately following this header are the resource entries themselves.
*/
struct resource_table {
u32 ver;
u32 num;
u32 reserved[2];
u32 offset[0];
} __packed;
/* Basic function to verify ELF32 image format */
int rproc_elf32_sanity_check(ulong addr, ulong size)
{
......@@ -276,3 +309,239 @@ ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
else
return rproc_elf32_get_boot_addr(addr);
}
/*
* Search for the resource table in an ELF32 image.
* Returns the address of the resource table section if found, NULL if there is
* no resource table section, or error pointer.
*/
static Elf32_Shdr *rproc_elf32_find_rsc_table(struct udevice *dev,
ulong fw_addr, ulong fw_size)
{
int ret;
unsigned int i;
const char *name_table;
struct resource_table *table;
const u8 *elf_data = (void *)fw_addr;
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
Elf32_Shdr *shdr;
ret = rproc_elf32_sanity_check(fw_addr, fw_size);
if (ret) {
pr_debug("Invalid ELF32 Image %d\n", ret);
return ERR_PTR(ret);
}
/* look for the resource table and handle it */
shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff);
name_table = (const char *)(elf_data +
shdr[ehdr->e_shstrndx].sh_offset);
for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
u32 size = shdr->sh_size;
u32 offset = shdr->sh_offset;
if (strcmp(name_table + shdr->sh_name, ".resource_table"))
continue;
table = (struct resource_table *)(elf_data + offset);
/* make sure we have the entire table */
if (offset + size > fw_size) {
pr_debug("resource table truncated\n");
return ERR_PTR(-ENOSPC);
}
/* make sure table has at least the header */
if (sizeof(*table) > size) {
pr_debug("header-less resource table\n");
return ERR_PTR(-ENOSPC);
}
/* we don't support any version beyond the first */
if (table->ver != 1) {
pr_debug("unsupported fw ver: %d\n", table->ver);
return ERR_PTR(-EPROTONOSUPPORT);
}
/* make sure reserved bytes are zeroes */
if (table->reserved[0] || table->reserved[1]) {
pr_debug("non zero reserved bytes\n");
return ERR_PTR(-EBADF);
}
/* make sure the offsets array isn't truncated */
if (table->num * sizeof(table->offset[0]) +
sizeof(*table) > size) {
pr_debug("resource table incomplete\n");
return ERR_PTR(-ENOSPC);
}
return shdr;
}
return NULL;
}
/* Load the resource table from an ELF32 image */
int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
{
const struct dm_rproc_ops *ops;
Elf32_Shdr *shdr;
void *src, *dst;
shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
if (!shdr)
return -ENODATA;
if (IS_ERR(shdr))
return PTR_ERR(shdr);
ops = rproc_get_ops(dev);
*rsc_addr = (ulong)shdr->sh_addr;
*rsc_size = (ulong)shdr->sh_size;
src = (void *)fw_addr + shdr->sh_offset;
if (ops->device_to_virt)
dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
else
dst = (void *)rsc_addr;
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
(ulong)dst, *rsc_size);
memcpy(dst, src, *rsc_size);
flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
roundup((unsigned long)dst + *rsc_size,
ARCH_DMA_MINALIGN) -
rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
return 0;
}
/*
* Search for the resource table in an ELF64 image.
* Returns the address of the resource table section if found, NULL if there is
* no resource table section, or error pointer.
*/
static Elf64_Shdr *rproc_elf64_find_rsc_table(struct udevice *dev,
ulong fw_addr, ulong fw_size)
{
int ret;
unsigned int i;
const char *name_table;
struct resource_table *table;
const u8 *elf_data = (void *)fw_addr;
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)fw_addr;
Elf64_Shdr *shdr;
ret = rproc_elf64_sanity_check(fw_addr, fw_size);
if (ret) {
pr_debug("Invalid ELF64 Image %d\n", ret);
return ERR_PTR(ret);
}
/* look for the resource table and handle it */
shdr = (Elf64_Shdr *)(elf_data + ehdr->e_shoff);
name_table = (const char *)(elf_data +
shdr[ehdr->e_shstrndx].sh_offset);
for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
u64 size = shdr->sh_size;
u64 offset = shdr->sh_offset;
if (strcmp(name_table + shdr->sh_name, ".resource_table"))
continue;
table = (struct resource_table *)(elf_data + offset);
/* make sure we have the entire table */
if (offset + size > fw_size) {
pr_debug("resource table truncated\n");
return ERR_PTR(-ENOSPC);
}
/* make sure table has at least the header */
if (sizeof(*table) > size) {
pr_debug("header-less resource table\n");
return ERR_PTR(-ENOSPC);
}
/* we don't support any version beyond the first */
if (table->ver != 1) {
pr_debug("unsupported fw ver: %d\n", table->ver);
return ERR_PTR(-EPROTONOSUPPORT);
}
/* make sure reserved bytes are zeroes */
if (table->reserved[0] || table->reserved[1]) {
pr_debug("non zero reserved bytes\n");
return ERR_PTR(-EBADF);
}
/* make sure the offsets array isn't truncated */
if (table->num * sizeof(table->offset[0]) +
sizeof(*table) > size) {
pr_debug("resource table incomplete\n");
return ERR_PTR(-ENOSPC);
}
return shdr;
}
return NULL;
}
/* Load the resource table from an ELF64 image */
int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
{
const struct dm_rproc_ops *ops;
Elf64_Shdr *shdr;
void *src, *dst;
shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
if (!shdr)
return -ENODATA;
if (IS_ERR(shdr))
return PTR_ERR(shdr);
ops = rproc_get_ops(dev);
*rsc_addr = (ulong)shdr->sh_addr;
*rsc_size = (ulong)shdr->sh_size;
src = (void *)fw_addr + shdr->sh_offset;
if (ops->device_to_virt)
dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
else
dst = (void *)rsc_addr;
dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
(ulong)dst, *rsc_size);
memcpy(dst, src, *rsc_size);
flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
roundup((unsigned long)dst + *rsc_size,
ARCH_DMA_MINALIGN) -
rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
return 0;
}
/* Load the resource table from an ELF32 or ELF64 image */
int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
if (!fw_addr)
return -EFAULT;
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
return rproc_elf64_load_rsc_table(dev, fw_addr, fw_size,
rsc_addr, rsc_size);
else
return rproc_elf32_load_rsc_table(dev, fw_addr, fw_size,
rsc_addr, rsc_size);
}
......@@ -22,14 +22,14 @@
* @hold_boot_regmap: regmap for remote processor reset hold boot
* @hold_boot_offset: offset of the register controlling the hold boot setting
* @hold_boot_mask: bitmask of the register for the hold boot field
* @is_running: is the remote processor running
* @rsc_table_addr: resource table address
*/
struct stm32_copro_privdata {
struct reset_ctl reset_ctl;
struct regmap *hold_boot_regmap;
uint hold_boot_offset;
uint hold_boot_mask;
bool is_running;
ulong rsc_table_addr;
};
/**
......@@ -141,6 +141,7 @@ static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da,
static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size)
{
struct stm32_copro_privdata *priv;
ulong rsc_table_size;
int ret;
priv = dev_get_priv(dev);
......@@ -155,6 +156,12 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size)
return ret;
}
if (rproc_elf32_load_rsc_table(dev, addr, size, &priv->rsc_table_addr,
&rsc_table_size)) {
priv->rsc_table_addr = 0;
dev_warn(dev, "No valid resource table for this firmware\n");
}
return rproc_elf32_load_image(dev, addr, size);
}
......@@ -180,7 +187,12 @@ static int stm32_copro_start(struct udevice *dev)
* rebooting autonomously
*/
ret = stm32_copro_set_hold_boot(dev, true);
priv->is_running = !ret;
writel(ret ? TAMP_COPRO_STATE_OFF : TAMP_COPRO_STATE_CRUN,
TAMP_COPRO_STATE);
if (!ret)
/* Store rsc_address in bkp register */
writel(priv->rsc_table_addr, TAMP_COPRO_RSC_TBL_ADDRESS);
return ret;
}
......@@ -206,7 +218,7 @@ static int stm32_copro_reset(struct udevice *dev)
return ret;
}
priv->is_running = false;
writel(TAMP_COPRO_STATE_OFF, TAMP_COPRO_STATE);
return 0;
}
......@@ -224,14 +236,11 @@ static int stm32_copro_stop(struct udevice *dev)
/**
* stm32_copro_is_running() - Is the STM32 remote processor running
* @dev: corresponding STM32 remote processor device
* @return 1 if the remote processor is running, 0 otherwise
* @return 0 if the remote processor is running, 1 otherwise
*/
static int stm32_copro_is_running(struct udevice *dev)
{
struct stm32_copro_privdata *priv;
priv = dev_get_priv(dev);
return priv->is_running;
return (readl(TAMP_COPRO_STATE) == TAMP_COPRO_STATE_OFF);
}
static const struct dm_rproc_ops stm32_copro_ops = {
......
......@@ -130,6 +130,14 @@ config OF_LIST
device tree files (without the directory or .dtb suffix)
separated by <space>.
config OF_OVERLAY_LIST
string "List of device tree overlays to include for DT control"
depends on SPL_LOAD_FIT_APPLY_OVERLAY
help
This option specifies a list of device tree overlays to use for DT
control. This option can then be used by a FIT generator to include
the overlays in the FIT image.
choice
prompt "OF LIST compression"
depends on MULTI_DTB_FIT
......
......@@ -31,6 +31,7 @@
* to read the serial number.
*/
#if CONFIG_IS_ENABLED(BOARD)
struct board_ops {
/**
* detect() - Run the hardware info detection procedure for this
......@@ -79,6 +80,24 @@ struct board_ops {
* Return: 0 if OK, -ve on error.
*/
int (*get_str)(struct udevice *dev, int id, size_t size, char *val);
/**
* get_fit_loadable - Get the name of an image to load from FIT
* This function can be used to provide the image names based on runtime
* detection. A classic use-case would when DTBOs are used to describe
* additionnal daughter cards.
*
* @dev: The board instance to gather the data.
* @index: Index of the image. Starts at 0 and gets incremented
* after each call to this function.
* @type: The type of image. For example, "fdt" for DTBs
* @strp: A pointer to string. Untouched if the function fails
*
* Return: 0 if OK, -ENOENT if no loadable is available else -ve on
* error.
*/
int (*get_fit_loadable)(struct udevice *dev, int index,
const char *type, const char **strp);
};
#define board_get_ops(dev) ((struct board_ops *)(dev)->driver->ops)
......@@ -137,3 +156,58 @@ int board_get_str(struct udevice *dev, int id, size_t size, char *val);
* Return: 0 if OK, -ve on error.
*/
int board_get(struct udevice **devp);
/**
* board_get_fit_loadable - Get the name of an image to load from FIT
* This function can be used to provide the image names based on runtime
* detection. A classic use-case would when DTBOs are used to describe
* additionnal daughter cards.
*
* @dev: The board instance to gather the data.
* @index: Index of the image. Starts at 0 and gets incremented
* after each call to this function.
* @type: The type of image. For example, "fdt" for DTBs
* @strp: A pointer to string. Untouched if the function fails
*
*
* Return: 0 if OK, -ENOENT if no loadable is available else -ve on
* error.
*/
int board_get_fit_loadable(struct udevice *dev, int index,
const char *type, const char **strp);
#else
static inline int board_detect(struct udevice *dev)
{
return -ENOSYS;
}
static inline int board_get_bool(struct udevice *dev, int id, bool *val)
{
return -ENOSYS;
}
static inline int board_get_int(struct udevice *dev, int id, int *val)
{
return -ENOSYS;
}
static inline int board_get_str(struct udevice *dev, int id, size_t size,
char *val)
{
return -ENOSYS;
}
static inline int board_get(struct udevice **devp)
{
return -ENOSYS;
}
static inline int board_get_fit_loadable(struct udevice *dev, int index,
const char *type, const char **strp)
{
return -ENOSYS;
}
#endif
......@@ -64,7 +64,6 @@
#define CONFIG_SPL_NAND_RAW_ONLY
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000
#define CONFIG_SYS_NAND_U_BOOT_SIZE 0xa0000
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_DST CONFIG_SYS_TEXT_BASE
......
......@@ -98,7 +98,6 @@
CONFIG_SPL_BSS_MAX_SIZE)
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000
#define CONFIG_SYS_MONITOR_LEN 0x100000
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#endif
/* NAND SPL */
......
......@@ -12,7 +12,6 @@
#define CONFIG_SPL_LIBCOMMON_SUPPORT
#include "imx6_spl.h"
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + 0x80000)
#define CONFIG_SYS_SPL_ARGS_ADDR 0x18000000
......
......@@ -173,8 +173,6 @@
/* Just for sure that there is a space for stack */
#define CONFIG_SPL_STACK_SIZE 0x100
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SPL_MAX_FOOTPRINT (CONFIG_SYS_INIT_RAM_SIZE - \
CONFIG_SYS_INIT_RAM_ADDR - \
CONFIG_SYS_MALLOC_F_LEN - \
......
......@@ -31,7 +31,6 @@
#define CONFIG_ENV_OVERWRITE
/* Preloader -> Uboot */
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
GENERATED_GBL_DATA_SIZE)
......
......@@ -40,7 +40,6 @@
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
/* SPL -> Uboot */
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
GENERATED_GBL_DATA_SIZE)
......
......@@ -29,7 +29,6 @@
#define CONFIG_SYS_BOOTM_LEN SZ_64M
/* Uboot definition */
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + \
SZ_2M - \
GENERATED_GBL_DATA_SIZE)
......
......@@ -26,7 +26,6 @@
* other needs. We use this rather than the inherited defines from
* ti_armv7_common.h for backwards compatibility.
*/
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SPL_BSS_START_ADDR 0x80000000
#define CONFIG_SPL_BSS_MAX_SIZE (512 << 10) /* 512 KB */
#define CONFIG_SYS_SPL_MALLOC_START 0x80208000
......
......@@ -23,7 +23,6 @@
#define CONFIG_SYS_NS16550_COM1 0x11005000
#define CONFIG_SYS_NS16550_CLK 26000000
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
GENERATED_GBL_DATA_SIZE)
......
......@@ -61,7 +61,6 @@
#define PHYS_SDRAM_1 NV_PA_SDRC_CS0
#define PHYS_SDRAM_1_SIZE 0x20000000 /* 512M */
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
#define CONFIG_SYS_BOOTMAPSZ (256 << 20) /* 256M */
......
......@@ -27,7 +27,6 @@
#define CONFIG_SYS_SPL_LEN CONFIG_SPL_PAD_TO
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + \
CONFIG_SYS_SPL_LEN)
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
#define CONFIG_SYS_MONITOR_LEN 0x60000
......
......@@ -35,8 +35,6 @@
/* Extend size of kernel image for uncompression */
#define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024)
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SKIP_LOWLEVEL_INIT
/* 0x0 - 0x40 is used for placing exception vectors */
......
......@@ -274,6 +274,4 @@
#define CONFIG_SPL_LOAD_FIT_ADDRESS 0x10000000
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
#endif /* __CONFIG_ZYNQ_COMMON_H */
......@@ -277,6 +277,64 @@ int rproc_elf_load_image(struct udevice *dev, unsigned long addr, ulong size);
* image.
*/
ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr);
/**
* rproc_elf32_load_rsc_table() - load the resource table from an ELF32 image
*
* Search for the resource table in an ELF32 image, and if found, copy it to
* device memory.
*
* @dev: device loading the resource table
* @fw_addr: ELF image address
* @fw_size: size of the ELF image
* @rsc_addr: pointer to the found resource table address. Updated on
* operation success
* @rsc_size: pointer to the found resource table size. Updated on operation
* success
*
* @return 0 if a valid resource table is successfully loaded, -ENODATA if there
* is no resource table (which is optional), or another appropriate error value.
*/
int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
/**
* rproc_elf64_load_rsc_table() - load the resource table from an ELF64 image
*
* Search for the resource table in an ELF64 image, and if found, copy it to
* device memory.
*
* @dev: device loading the resource table
* @fw_addr: ELF image address
* @fw_size: size of the ELF image
* @rsc_addr: pointer to the found resource table address. Updated on
* operation success
* @rsc_size: pointer to the found resource table size. Updated on operation
* success
*
* @return 0 if a valid resource table is successfully loaded, -ENODATA if there
* is no resource table (which is optional), or another appropriate error value.
*/
int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
/**
* rproc_elf_load_rsc_table() - load the resource table from an ELF image
*
* Auto detects if the image is ELF32 or ELF64 image and search accordingly for
* the resource table, and if found, copy it to device memory.
*
* @dev: device loading the resource table
* @fw_addr: ELF image address
* @fw_size: size of the ELF image
* @rsc_addr: pointer to the found resource table address. Updated on
* operation success
* @rsc_size: pointer to the found resource table size. Updated on operation
* success
*
* @return 0 if a valid resource table is successfully loaded, -ENODATA if there
* is no resource table (which is optional), or another appropriate error value.
*/
int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr, ulong *rsc_size);
#else
static inline int rproc_init(void) { return -ENOSYS; }
static inline int rproc_dev_init(int id) { return -ENOSYS; }
......@@ -304,6 +362,18 @@ static inline int rproc_elf_load_image(struct udevice *dev, ulong addr,
{ return -ENOSYS; }
static inline ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
{ return 0; }
static inline int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr,
ulong *rsc_size)
{ return -ENOSYS; }
static inline int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr,
ulong *rsc_size)
{ return -ENOSYS; }
static inline int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
ulong fw_size, ulong *rsc_addr,
ulong *rsc_size)
{ return -ENOSYS; }
#endif
#endif /* _RPROC_H_ */
......@@ -13,6 +13,7 @@ struct unit_test;
* cmd_ut_category() - Run a category of unit tests
*
* @name: Category name
* @prefix: Prefix of test name
* @tests: List of tests to run
* @n_ents: Number of tests in @tests
* @argc: Argument count provided. Must be >= 1. If this is 1 then all
......@@ -20,7 +21,8 @@ struct unit_test;
* @argv: Arguments: argv[1] is the test to run (if @argc >= 2)
* @return 0 if OK, CMD_RET_FAILURE on failure
*/
int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
int cmd_ut_category(const char *name, const char *prefix,
struct unit_test *tests, int n_ents,
int argc, char * const argv[]);
int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
......
......@@ -292,6 +292,10 @@ cmd_dt_S_dtb= \
$(obj)/%.dtb.S: $(obj)/%.dtb
$(call cmd,dt_S_dtb)
ifeq ($(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY),y)
DTC_FLAGS += -@
endif
quiet_cmd_dtc = DTC $@
# Modified for U-Boot
# Bring in any U-Boot-specific include at the end of the file
......
......@@ -183,5 +183,6 @@ int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
bloblist_test);
const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
return cmd_ut_category("bloblist", tests, n_ents, argc, argv);
return cmd_ut_category("bloblist", "bloblist_test_",
tests, n_ents, argc, argv);
}
......@@ -11,17 +11,25 @@
static int do_ut_all(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
int cmd_ut_category(const char *name, const char *prefix,
struct unit_test *tests, int n_ents,
int argc, char * const argv[])
{
struct unit_test_state uts = { .fail_count = 0 };
struct unit_test *test;
int prefix_len = prefix ? strlen(prefix) : 0;
if (argc == 1)
printf("Running %d %s tests\n", n_ents, name);
for (test = tests; test < tests + n_ents; test++) {
if (argc > 1 && strcmp(argv[1], test->name))
const char *test_name = test->name;
/* Remove the prefix */
if (!strncmp(test_name, prefix, prefix_len))
test_name += prefix_len;
if (argc > 1 && strcmp(argv[1], test_name))
continue;
printf("Test: %s\n", test->name);
......
......@@ -540,5 +540,6 @@ int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
compression_test);
const int n_ents = ll_entry_count(struct unit_test, compression_test);
return cmd_ut_category("compression", tests, n_ents, argc, argv);
return cmd_ut_category("compression", "compression_test_",
tests, n_ents, argc, argv);
}
......@@ -103,8 +103,8 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
0x00, 0x00, 0x00, 0x08,
/* phoff (program header offset @ 0x40)*/
0x40, 0x00, 0x00, 0x00,
/* shoff (section header offset : none) */
0x00, 0x00, 0x00, 0x00,
/* shoff (section header offset @ 0x90) */
0x90, 0x00, 0x00, 0x00,
/* flags */
0x00, 0x00, 0x00, 0x00,
/* ehsize (elf header size = 0x34) */
......@@ -113,16 +113,17 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
0x20, 0x00,
/* phnum (program header number : 1) */
0x01, 0x00,
/* shentsize (section heade size : none) */
0x00, 0x00,
/* shnum (section header number: none) */
0x00, 0x00,
/* shstrndx (section header name section index: none) */
0x00, 0x00,
/* shentsize (section header size : 40 bytes) */
0x28, 0x00,
/* shnum (section header number: 3) */
0x02, 0x00,
/* shstrndx (section header name section index: 1) */
0x01, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
/* @0x40 - PROGRAM HEADER TABLE - */
/* type : PT_LOAD */
0x01, 0x00, 0x00, 0x00,
......@@ -140,14 +141,63 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
0x05, 0x00, 0x00, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00,
/* @0x60 - RESOURCE TABLE SECTION - */
/* version */
0x01, 0x00, 0x00, 0x00,
/* num (0, no entries) */
0x00, 0x00, 0x00, 0x00,
/* Reserved */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* @0x70 - SECTION'S NAMES SECTION - */
/* section 0 name (".shrtrtab") */
0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00,
/* section 1 name (".resource_table") */
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x00,
/* padding */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* @0x90 - SECTION HEADER TABLE - */
/* Section 0 : resource table header */
/* sh_name - index into section header string table section */
0x0a, 0x00, 0x00, 0x00,
/* sh_type and sh_flags */
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
/* sh_addr = where the resource table has to be copied to */
0x00, 0x00, 0x00, 0x00,
/* sh_offset = 0x60 */
0x60, 0x00, 0x00, 0x00,
/* sh_size = 16 bytes */
0x10, 0x00, 0x00, 0x00,
/* sh_link, sh_info, sh_addralign, sh_entsize */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* Section 1 : section's names section header */
/* sh_name - index into section header string table section */
0x00, 0x00, 0x00, 0x00,
/* sh_type and sh_flags */
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* sh_addr */
0x00, 0x00, 0x00, 0x00,
/* sh_offset = 0x70 */
0x70, 0x00, 0x00, 0x00,
/* sh_size = 27 bytes */
0x1b, 0x00, 0x00, 0x00,
/* sh_link, sh_info, sh_addralign, sh_entsize */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
unsigned int size = ARRAY_SIZE(valid_elf32);
struct udevice *dev;
phys_addr_t loaded_firmware_paddr;
void *loaded_firmware;
u32 loaded_firmware_size;
phys_addr_t loaded_firmware_paddr, loaded_rsc_table_paddr;
void *loaded_firmware, *loaded_rsc_table;
u32 loaded_firmware_size, rsc_table_size;
ulong rsc_addr, rsc_size;
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)valid_elf32;
Elf32_Phdr *phdr = (Elf32_Phdr *)(valid_elf32 + ehdr->e_phoff);
Elf32_Shdr *shdr = (Elf32_Shdr *)(valid_elf32 + ehdr->e_shoff);
ut_assertok(uclass_get_device(UCLASS_REMOTEPROC, 0, &dev));
......@@ -178,6 +228,25 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
0x08000000);
unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Resource table */
shdr->sh_addr = CONFIG_SYS_SDRAM_BASE;
rsc_table_size = shdr->sh_size;
loaded_rsc_table_paddr = shdr->sh_addr + DEVICE_TO_PHYSICAL_OFFSET;
loaded_rsc_table = map_physmem(loaded_rsc_table_paddr,
rsc_table_size, MAP_NOCACHE);
ut_assertnonnull(loaded_rsc_table);
memset(loaded_rsc_table, 0, rsc_table_size);
/* Load and verify */
ut_assertok(rproc_elf32_load_rsc_table(dev, (ulong)valid_elf32, size,
&rsc_addr, &rsc_size));
ut_asserteq(rsc_addr, CONFIG_SYS_SDRAM_BASE);
ut_asserteq(rsc_size, rsc_table_size);
ut_assertok(memcmp(loaded_firmware, valid_elf32 + shdr->sh_offset,
shdr->sh_size));
unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Invalid ELF Magic */
valid_elf32[0] = 0;
ut_asserteq(-EPROTONOSUPPORT,
......
......@@ -15,5 +15,6 @@ int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
struct unit_test *tests = ll_entry_start(struct unit_test, env_test);
const int n_ents = ll_entry_count(struct unit_test, env_test);
return cmd_ut_category("environment", tests, n_ents, argc, argv);
return cmd_ut_category("environment", "env_test_",
tests, n_ents, argc, argv);
}
......@@ -16,5 +16,5 @@ int do_ut_lib(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
struct unit_test *tests = ll_entry_start(struct unit_test, lib_test);
const int n_ents = ll_entry_count(struct unit_test, lib_test);
return cmd_ut_category("lib", tests, n_ents, argc, argv);
return cmd_ut_category("lib", "lib_test_", tests, n_ents, argc, argv);
}
......@@ -129,20 +129,20 @@ int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
expect_success = false;
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
/* (2) Try to copy optee nodes from prefilled dt */
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
expect_success = true;
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
/* (3) Try to copy OP-TEE nodes into a already filled DT */
ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
expect_success = true;
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
free(fdt);
return ret;
......
......@@ -272,7 +272,7 @@ int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* Apply the stacked overlay */
ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy));
ret = cmd_ut_category("overlay", tests, n_ents, argc, argv);
ret = cmd_ut_category("overlay", "", tests, n_ents, argc, argv);
free(fdt_overlay_stacked_copy);
err3:
......
......@@ -585,5 +585,6 @@ int do_ut_unicode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
struct unit_test *tests = ll_entry_start(struct unit_test, unicode_test);
const int n_ents = ll_entry_count(struct unit_test, unicode_test);
return cmd_ut_category("Unicode", tests, n_ents, argc, argv);
return cmd_ut_category("Unicode", "unicode_test_",
tests, n_ents, argc, argv);
}
......@@ -35,14 +35,23 @@ static int dumpimage_extract_subimage(struct image_type_params *tparams,
if (tparams->verify_header) {
retval = tparams->verify_header((unsigned char *)ptr,
sbuf->st_size, &params);
if (retval != 0)
if (retval != 0) {
fprintf(stderr, "%s: failed to verify header of %s\n",
params.cmdname, tparams->name);
return -1;
}
/*
* Extract the file from the image
* if verify is successful
*/
if (tparams->extract_subimage) {
retval = tparams->extract_subimage(ptr, &params);
if (retval != 0) {
fprintf(stderr, "%s: extract_subimage failed for %s\n",
params.cmdname, tparams->name);
return -3;
}
} else {
fprintf(stderr,
"%s: extract_subimage undefined for %s\n",
......@@ -95,7 +104,6 @@ int main(int argc, char **argv)
printf("dumpimage version %s\n", PLAIN_VERSION);
exit(EXIT_SUCCESS);
case 'h':
usage();
default:
usage();
break;
......@@ -175,6 +183,9 @@ int main(int argc, char **argv)
* image type. Returns the error code if not matched
*/
retval = dumpimage_extract_subimage(tparams, ptr, &sbuf);
if (retval)
fprintf(stderr, "%s: Can't extract subimage from %s\n",
params.cmdname, params.imagefile);
} else {
/*
* Print the image information for matched image type
......
......@@ -741,9 +741,14 @@ static int fit_image_extract(
{
const void *file_data;
size_t file_size = 0;
int ret;
/* get the "data" property of component at offset "image_noffset" */
fit_image_get_data(fit, image_noffset, &file_data, &file_size);
/* get the data address and size of component at offset "image_noffset" */
ret = fit_image_get_data_and_size(fit, image_noffset, &file_data, &file_size);
if (ret) {
fprintf(stderr, "Could not get component information\n");
return ret;
}
/* save the "file_data" into the file specified by "file_name" */
return imagetool_save_subimage(file_name, (ulong) file_data, file_size);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册