summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig4
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/Kconfig2
-rw-r--r--arch/arm/cpu/arm926ejs/spear/spl.c47
-rw-r--r--arch/arm/cpu/arm926ejs/spear/start.S56
-rw-r--r--arch/arm/mach-imx/hab.c2
-rw-r--r--arch/arm/mach-omap2/am33xx/board.c2
-rw-r--r--arch/sandbox/dts/test.dts4
-rw-r--r--arch/sandbox/include/asm/test.h8
-rw-r--r--cmd/Kconfig17
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bcb.c340
-rw-r--r--cmd/bootm.c6
-rw-r--r--cmd/disk.c4
-rw-r--r--cmd/fdc.c4
-rw-r--r--cmd/fpga.c2
-rw-r--r--cmd/nand.c4
-rw-r--r--cmd/source.c4
-rw-r--r--cmd/ximg.c6
-rw-r--r--common/bootm.c8
-rw-r--r--common/image-fdt.c6
-rw-r--r--common/image.c10
-rw-r--r--common/spl/Kconfig2
-rw-r--r--common/spl/spl.c2
-rw-r--r--configs/bcm963158_ram_defconfig2
-rw-r--r--configs/bcm968580xref_ram_defconfig2
-rw-r--r--configs/gardena-smart-gateway-mt7688-ram_defconfig2
-rw-r--r--configs/gardena-smart-gateway-mt7688_defconfig2
-rw-r--r--configs/ids8313_defconfig2
-rw-r--r--configs/imx6dl_icore_nand_defconfig2
-rw-r--r--configs/imx6q_icore_nand_defconfig2
-rw-r--r--configs/imx6qdl_icore_mipi_defconfig2
-rw-r--r--configs/imx6qdl_icore_mmc_defconfig2
-rw-r--r--configs/imx6qdl_icore_nand_defconfig2
-rw-r--r--configs/imx6qdl_icore_rqs_defconfig2
-rw-r--r--configs/imx6ul_geam_mmc_defconfig2
-rw-r--r--configs/imx6ul_geam_nand_defconfig2
-rw-r--r--configs/imx6ul_isiot_emmc_defconfig2
-rw-r--r--configs/imx6ul_isiot_nand_defconfig2
-rw-r--r--configs/linkit-smart-7688-ram_defconfig2
-rw-r--r--configs/linkit-smart-7688_defconfig2
-rw-r--r--configs/syzygy_hub_defconfig2
-rw-r--r--configs/xilinx_versal_mini_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_defconfig2
-rw-r--r--configs/xilinx_zynqmp_mini_qspi_defconfig2
-rw-r--r--configs/zynq_cc108_defconfig2
-rw-r--r--configs/zynq_dlc20_rev1_0_defconfig2
-rw-r--r--configs/zynq_microzed_defconfig2
-rw-r--r--configs/zynq_z_turn_defconfig2
-rw-r--r--configs/zynq_zc702_defconfig2
-rw-r--r--configs/zynq_zc706_defconfig2
-rw-r--r--configs/zynq_zc770_xm010_defconfig2
-rw-r--r--configs/zynq_zc770_xm011_defconfig2
-rw-r--r--configs/zynq_zc770_xm011_x16_defconfig2
-rw-r--r--configs/zynq_zc770_xm012_defconfig2
-rw-r--r--configs/zynq_zc770_xm013_defconfig2
-rw-r--r--configs/zynq_zed_defconfig2
-rw-r--r--configs/zynq_zybo_defconfig2
-rw-r--r--configs/zynq_zybo_z7_defconfig2
-rw-r--r--doc/android/avb2.txt (renamed from doc/README.avb2)0
-rw-r--r--doc/android/bcb.txt89
-rw-r--r--doc/android/fastboot.txt (renamed from doc/README.android-fastboot)0
-rw-r--r--doc/device-tree-bindings/pci_endpoint/cdns,cdns-pcie-ep.txt18
-rw-r--r--doc/uImage.FIT/signature.txt2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/gpio/pca953x_gpio.c1
-rw-r--r--drivers/pci_endpoint/Kconfig34
-rw-r--r--drivers/pci_endpoint/Makefile8
-rw-r--r--drivers/pci_endpoint/pci_ep-uclass.c211
-rw-r--r--drivers/pci_endpoint/pcie-cadence-ep.c177
-rw-r--r--drivers/pci_endpoint/pcie-cadence.h309
-rw-r--r--drivers/pci_endpoint/sandbox-pci_ep.c182
-rw-r--r--drivers/tpm/tpm2_tis_spi.c12
-rw-r--r--include/android_bootloader_message.h126
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/image.h2
-rw-r--r--include/pci_ep.h414
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/pci_ep.c64
80 files changed, 2103 insertions, 168 deletions
diff --git a/Kconfig b/Kconfig
index df8f2946c5..d2eb744e70 100644
--- a/Kconfig
+++ b/Kconfig
@@ -344,7 +344,7 @@ config FIT_SIGNATURE
check the legacy image format is disabled by default, so that
unsigned images cannot be loaded. If a board needs the legacy image
format support in this case, enable it using
- CONFIG_IMAGE_FORMAT_LEGACY.
+ CONFIG_LEGACY_IMAGE_FORMAT.
config FIT_SIGNATURE_MAX_SIZE
hex "Max size of signed FIT structures"
@@ -473,7 +473,7 @@ endif # SPL
endif # FIT
-config IMAGE_FORMAT_LEGACY
+config LEGACY_IMAGE_FORMAT
bool "Enable support for the legacy image format"
default y if !FIT_SIGNATURE
help
diff --git a/MAINTAINERS b/MAINTAINERS
index bea3122f2b..e91684191f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -633,6 +633,12 @@ M: Simon Glass <sjg@chromium.org>
S: Maintained
F: tools/patman/
+PCI Endpoint
+M: Ramon Fried <rfried.dev@gmail.com>
+S: Maintained
+F: drivers/pci_endpoint/
+F: include/pci_ep.h
+
POWER
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained
diff --git a/arch/Kconfig b/arch/Kconfig
index 28afe39801..355d214522 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -90,6 +90,7 @@ config SANDBOX
select DM_SPI_FLASH
select HAVE_BLOCK_DEVICE
select LZO
+ select PCI_ENDPOINT
select SPI
select SUPPORT_OF_CONTROL
imply BITREVERSE
@@ -120,6 +121,7 @@ config SANDBOX
imply VIRTIO_BLK
imply VIRTIO_NET
imply DM_SOUND
+ imply PCI_SANDBOX_EP
imply PCH
config SH
diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c
index d2bddb589a..fc332fb626 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -16,6 +16,12 @@
#include <asm/arch/spr_syscntl.h>
#include <linux/mtd/st_smi.h>
+/* Reserve some space to store the BootROM's stack pointer during SPL operation.
+ * The BSS cannot be used for this purpose because it will be zeroed after
+ * having stored the pointer, so force the location to the data section.
+ */
+u32 bootrom_stash_sp __attribute__((section(".data")));
+
static void ddr_clock_init(void)
{
struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
@@ -223,8 +229,9 @@ u32 spl_boot_device(void)
{
u32 mode = 0;
- /* Currently only SNOR is supported as the only */
- if (snor_boot_selected()) {
+ if (usb_boot_selected()) {
+ mode = BOOT_DEVICE_BOOTROM;
+ } else if (snor_boot_selected()) {
/* SNOR-SMI initialization */
snor_init();
@@ -234,6 +241,18 @@ u32 spl_boot_device(void)
return mode;
}
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = spl_boot_device();
+
+ /*
+ * If the main boot device (eg. NOR) is empty, try to jump back into the
+ * BootROM for USB boot process.
+ */
+ if (USB_BOOT_SUPPORTED)
+ spl_boot_list[1] = BOOT_DEVICE_BOOTROM;
+}
+
void board_init_f(ulong dummy)
{
struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
@@ -251,6 +270,28 @@ void board_init_f(ulong dummy)
puts("Configure DDR\n");
mpmc_init();
spear_late_init();
+}
- board_init_r(NULL, 0);
+/*
+ * In a few cases (Ethernet, UART or USB boot, we might want to go back into the
+ * BootROM code right after having initialized a few components like the DRAM).
+ * The following function is called from SPL common code (board_init_r).
+ */
+void board_return_to_bootrom(void)
+{
+ /*
+ * Retrieve the BootROM's stack pointer and jump back to the start of
+ * the SPL, where we can easily branch back into the BootROM. Don't do
+ * it right here because SPL might be compiled in Thumb mode while the
+ * BootROM expects ARM mode.
+ */
+ asm volatile ("ldr r0, =bootrom_stash_sp;"
+ "ldr r0, [r0];"
+ "mov sp, r0;"
+#if defined(CONFIG_SPL_SYS_THUMB_BUILD)
+ "blx back_to_bootrom;"
+#else
+ "bl back_to_bootrom;"
+#endif
+ );
}
diff --git a/arch/arm/cpu/arm926ejs/spear/start.S b/arch/arm/cpu/arm926ejs/spear/start.S
index 1cab4ca6fb..9ac96291b7 100644
--- a/arch/arm/cpu/arm926ejs/spear/start.S
+++ b/arch/arm/cpu/arm926ejs/spear/start.S
@@ -21,51 +21,35 @@
*
* Startup Code (reset vector)
*
- * Below are the critical initializations already taken place in BootROM.
- * So, these are not taken care in Xloader
- * 1. Relocation to RAM
- * 2. Initializing stacks
+ * The BootROM already initialized its own stack in the [0-0xb00] reserved
+ * range of the SRAM. The SPL (in _main) will update the stack pointer to
+ * its own SRAM area (right before the gd section).
*
*************************************************************************
*/
.globl reset
+ .globl back_to_bootrom
reset:
-/*
- * Xloader has to return back to BootROM in a few cases.
- * eg. Ethernet boot, UART boot, USB boot
- * Saving registers for returning back
- */
- stmdb sp!, {r0-r12,r14}
- bl cpu_init_crit
-/*
- * Clearing bss area is not done in Xloader.
- * BSS area lies in the DDR location which is not yet initialized
- * bss is assumed to be uninitialized.
- */
- ldmia sp!, {r0-r12,pc}
+ /*
+ * SPL has to return back to BootROM in a few cases (eg. Ethernet boot,
+ * UART boot, USB boot): save registers in BootROM's stack and then the
+ * BootROM's stack pointer in the SPL's data section.
+ */
+ push {r0-r12,lr}
+ ldr r0, =bootrom_stash_sp
+ str sp, [r0]
-/*
- *************************************************************************
- *
- * CPU_init_critical registers
- *
- * setup important registers
- * setup memory timing
- *
- *************************************************************************
- */
-cpu_init_crit:
/*
- * flush v4 I/D caches
+ * Flush v4 I/D caches
*/
mov r0, #0
- mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
- mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+ mcr p15, 0, r0, c7, c7, 0 /* Flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* Flush v4 TLB */
/*
- * enable instruction cache
+ * Enable instruction cache
*/
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
@@ -73,7 +57,9 @@ cpu_init_crit:
/*
* Go setup Memory and board specific bits prior to relocation.
+ * This call is not supposed to return.
*/
- stmdb sp!, {lr}
- bl _main /* _main will call board_init_f */
- ldmia sp!, {pc}
+ b _main /* _main will call board_init_f */
+
+back_to_bootrom:
+ pop {r0-r12,pc}
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 24d16299e8..ce50dbe907 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -310,7 +310,7 @@ static ulong get_image_ivt_offset(ulong img_addr)
buf = map_sysmem(img_addr, 0);
switch (genimg_get_format(buf)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
return (image_get_image_size((image_header_t *)img_addr)
+ 0x1000 - 1) & ~(0x1000 - 1);
diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c
index 5507348981..03460c3eb7 100644
--- a/arch/arm/mach-omap2/am33xx/board.c
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -375,8 +375,8 @@ void update_rtc_magic(void)
*/
int board_early_init_f(void)
{
- prcm_init();
set_mux_conf_regs();
+ prcm_init();
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)
update_rtc_magic();
#endif
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index c328258901..a7a566c0d8 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -487,6 +487,10 @@
};
};
+ pci_ep: pci_ep {
+ compatible = "sandbox,pci_ep";
+ };
+
probing {
compatible = "simple-bus";
test1 {
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index e956a05262..7ec9b61008 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -177,4 +177,12 @@ int sandbox_get_beep_frequency(struct udevice *dev);
*/
int sandbox_get_pch_spi_protect(struct udevice *dev);
+/**
+ * sandbox_get_pci_ep_irq_count() - Get the PCI EP IRQ count
+ *
+ * @dev: Device to check
+ * @return irq count
+ */
+int sandbox_get_pci_ep_irq_count(struct udevice *dev);
+
#endif
diff --git a/cmd/Kconfig b/cmd/Kconfig
index cda7931fe3..3afb760a81 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -631,6 +631,23 @@ config CMD_ADC
Shows ADC device info and permit printing one-shot analog converted
data from a named Analog to Digital Converter.
+config CMD_BCB
+ bool "bcb"
+ depends on MMC
+ depends on PARTITIONS
+ help
+ Read/modify/write the fields of Bootloader Control Block, usually
+ stored on the flash "misc" partition with its structure defined in:
+ https://android.googlesource.com/platform/bootable/recovery/+/master/
+ bootloader_message/include/bootloader_message/bootloader_message.h
+
+ Some real-life use-cases include (but are not limited to):
+ - Determine the "boot reason" (and act accordingly):
+ https://source.android.com/devices/bootloader/boot-reason
+ - Get/pass a list of commands from/to recovery:
+ https://android.googlesource.com/platform/bootable/recovery
+ - Inspect/dump the contents of the BCB fields
+
config CMD_BIND
bool "bind/unbind - Bind or unbind a device to/from a driver"
depends on DM
diff --git a/cmd/Makefile b/cmd/Makefile
index f982564ab9..49e64cde1d 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_CMD_ADC) += adc.o
obj-$(CONFIG_CMD_ARMFLASH) += armflash.o
obj-y += blk_common.o
obj-$(CONFIG_CMD_SOURCE) += source.o
+obj-$(CONFIG_CMD_BCB) += bcb.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_CMD_BIND) += bind.o
diff --git a/cmd/bcb.c b/cmd/bcb.c
new file mode 100644
index 0000000000..2bd5a744de
--- /dev/null
+++ b/cmd/bcb.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Eugeniu Rosca <rosca.eugeniu@gmail.com>
+ *
+ * Command to read/modify/write Android BCB fields
+ */
+
+#include <android_bootloader_message.h>
+#include <command.h>
+#include <common.h>
+
+enum bcb_cmd {
+ BCB_CMD_LOAD,
+ BCB_CMD_FIELD_SET,
+ BCB_CMD_FIELD_CLEAR,
+ BCB_CMD_FIELD_TEST,
+ BCB_CMD_FIELD_DUMP,
+ BCB_CMD_STORE,
+};
+
+static int bcb_dev = -1;
+static int bcb_part = -1;
+static struct bootloader_message bcb = { { 0 } };
+
+static int bcb_cmd_get(char *cmd)
+{
+ if (!strncmp(cmd, "load", sizeof("load")))
+ return BCB_CMD_LOAD;
+ if (!strncmp(cmd, "set", sizeof("set")))
+ return BCB_CMD_FIELD_SET;
+ if (!strncmp(cmd, "clear", sizeof("clear")))
+ return BCB_CMD_FIELD_CLEAR;
+ if (!strncmp(cmd, "test", sizeof("test")))
+ return BCB_CMD_FIELD_TEST;
+ if (!strncmp(cmd, "store", sizeof("store")))
+ return BCB_CMD_STORE;
+ if (!strncmp(cmd, "dump", sizeof("dump")))
+ return BCB_CMD_FIELD_DUMP;
+ else
+ return -1;
+}
+
+static int bcb_is_misused(int argc, char *const argv[])
+{
+ int cmd = bcb_cmd_get(argv[0]);
+
+ switch (cmd) {
+ case BCB_CMD_LOAD:
+ if (argc != 3)
+ goto err;
+ break;
+ case BCB_CMD_FIELD_SET:
+ if (argc != 3)
+ goto err;
+ break;
+ case BCB_CMD_FIELD_TEST:
+ if (argc != 4)
+ goto err;
+ break;
+ case BCB_CMD_FIELD_CLEAR:
+ if (argc != 1 && argc != 2)
+ goto err;
+ break;
+ case BCB_CMD_STORE:
+ if (argc != 1)
+ goto err;
+ break;
+ case BCB_CMD_FIELD_DUMP:
+ if (argc != 2)
+ goto err;
+ break;
+ default:
+ printf("Error: 'bcb %s' not supported\n", argv[0]);
+ return -1;
+ }
+
+ if (cmd != BCB_CMD_LOAD && (bcb_dev < 0 || bcb_part < 0)) {
+ printf("Error: Please, load BCB first!\n");
+ return -1;
+ }
+
+ return 0;
+err:
+ printf("Error: Bad usage of 'bcb %s'\n", argv[0]);
+
+ return -1;
+}
+
+static int bcb_field_get(char *name, char **field, int *size)
+{
+ if (!strncmp(name, "command", sizeof("command"))) {
+ *field = bcb.command;
+ *size = sizeof(bcb.command);
+ } else if (!strncmp(name, "status", sizeof("status"))) {
+ *field = bcb.status;
+ *size = sizeof(bcb.status);
+ } else if (!strncmp(name, "recovery", sizeof("recovery"))) {
+ *field = bcb.recovery;
+ *size = sizeof(bcb.recovery);
+ } else if (!strncmp(name, "stage", sizeof("stage"))) {
+ *field = bcb.stage;
+ *size = sizeof(bcb.stage);
+ } else if (!strncmp(name, "reserved", sizeof("reserved"))) {
+ *field = bcb.reserved;
+ *size = sizeof(bcb.reserved);
+ } else {
+ printf("Error: Unknown bcb field '%s'\n", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+do_bcb_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct blk_desc *desc;
+ disk_partition_t info;
+ u64 cnt;
+ char *endp;
+ int part, ret;
+
+ ret = blk_get_device_by_str("mmc", argv[1], &desc);
+ if (ret < 0)
+ goto err_1;
+
+ part = simple_strtoul(argv[2], &endp, 0);
+ if (*endp == '\0') {
+ ret = part_get_info(desc, part, &info);
+ if (ret)
+ goto err_1;
+ } else {
+ part = part_get_info_by_name(desc, argv[2], &info);
+ if (part < 0) {
+ ret = part;
+ goto err_1;
+ }
+ }
+
+ cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), info.blksz);
+ if (cnt > info.size)
+ goto err_2;
+
+ if (blk_dread(desc, info.start, cnt, &bcb) != cnt) {
+ ret = -EIO;
+ goto err_1;
+ }
+
+ bcb_dev = desc->devnum;
+ bcb_part = part;
+ debug("%s: Loaded from mmc %d:%d\n", __func__, bcb_dev, bcb_part);
+
+ return CMD_RET_SUCCESS;
+err_1:
+ printf("Error: mmc %s:%s read failed (%d)\n", argv[1], argv[2], ret);
+ goto err;
+err_2:
+ printf("Error: mmc %s:%s too small!", argv[1], argv[2]);
+ goto err;
+err:
+ bcb_dev = -1;
+ bcb_part = -1;
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_bcb_set(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int size, len;
+ char *field, *str, *found;
+
+ if (bcb_field_get(argv[1], &field, &size))
+ return CMD_RET_FAILURE;
+
+ len = strlen(argv[2]);
+ if (len >= size) {
+ printf("Error: sizeof('%s') = %d >= %d = sizeof(bcb.%s)\n",
+ argv[2], len, size, argv[1]);
+ return CMD_RET_FAILURE;
+ }
+ str = argv[2];
+
+ field[0] = '\0';
+ while ((found = strsep(&str, ":"))) {
+ if (field[0] != '\0')
+ strcat(field, "\n");
+ strcat(field, found);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_bcb_clear(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int size;
+ char *field;
+
+ if (argc == 1) {
+ memset(&bcb, 0, sizeof(bcb));
+ return CMD_RET_SUCCESS;
+ }
+
+ if (bcb_field_get(argv[1], &field, &size))
+ return CMD_RET_FAILURE;
+
+ memset(field, 0, size);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_bcb_test(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int size;
+ char *field;
+ char *op = argv[2];
+
+ if (bcb_field_get(argv[1], &field, &size))
+ return CMD_RET_FAILURE;
+
+ if (*op == '=' && *(op + 1) == '\0') {
+ if (!strncmp(argv[3], field, size))
+ return CMD_RET_SUCCESS;
+ else
+ return CMD_RET_FAILURE;
+ } else if (*op == '~' && *(op + 1) == '\0') {
+ if (!strstr(field, argv[3]))
+ return CMD_RET_FAILURE;
+ else
+ return CMD_RET_SUCCESS;
+ } else {
+ printf("Error: Unknown operator '%s'\n", op);
+ }
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_bcb_dump(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int size;
+ char *field;
+
+ if (bcb_field_get(argv[1], &field, &size))
+ return CMD_RET_FAILURE;
+
+ print_buffer((ulong)field - (ulong)&bcb, (void *)field, 1, size, 16);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_bcb_store(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ struct blk_desc *desc;
+ disk_partition_t info;
+ u64 cnt;
+ int ret;
+
+ desc = blk_get_devnum_by_type(IF_TYPE_MMC, bcb_dev);
+ if (!desc) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ ret = part_get_info(desc, bcb_part, &info);
+ if (ret)
+ goto err;
+
+ cnt = DIV_ROUND_UP(sizeof(struct bootloader_message), info.blksz);
+
+ if (blk_dwrite(desc, info.start, cnt, &bcb) != cnt) {
+ ret = -EIO;
+ goto err;
+ }
+
+ return CMD_RET_SUCCESS;
+err:
+ printf("Error: mmc %d:%d write failed (%d)\n", bcb_dev, bcb_part, ret);
+
+ return CMD_RET_FAILURE;
+}
+
+static cmd_tbl_t cmd_bcb_sub[] = {
+ U_BOOT_CMD_MKENT(load, CONFIG_SYS_MAXARGS, 1, do_bcb_load, "", ""),
+ U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 1, do_bcb_set, "", ""),
+ U_BOOT_CMD_MKENT(clear, CONFIG_SYS_MAXARGS, 1, do_bcb_clear, "", ""),
+ U_BOOT_CMD_MKENT(test, CONFIG_SYS_MAXARGS, 1, do_bcb_test, "", ""),
+ U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_bcb_dump, "", ""),
+ U_BOOT_CMD_MKENT(store, CONFIG_SYS_MAXARGS, 1, do_bcb_store, "", ""),
+};
+
+static int do_bcb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ cmd_tbl_t *c;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], cmd_bcb_sub, ARRAY_SIZE(cmd_bcb_sub));
+ if (!c)
+ return CMD_RET_USAGE;
+
+ if (bcb_is_misused(argc, argv)) {
+ /* We try to improve the user experience by reporting the
+ * root-cause of misusage, so don't return CMD_RET_USAGE,
+ * since the latter prints out the full-blown help text
+ */
+ return CMD_RET_FAILURE;
+ }
+
+ return c->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+ bcb, CONFIG_SYS_MAXARGS, 1, do_bcb,
+ "Load/set/clear/test/dump/store Android BCB fields",
+ "load <dev> <part> - load BCB from mmc <dev>:<part>\n"
+ "bcb set <field> <val> - set BCB <field> to <val>\n"
+ "bcb clear [<field>] - clear BCB <field> or all fields\n"
+ "bcb test <field> <op> <val> - test BCB <field> against <val>\n"
+ "bcb dump <field> - dump BCB <field>\n"
+ "bcb store - store BCB back to mmc\n"
+ "\n"
+ "Legend:\n"
+ "<dev> - MMC device index containing the BCB partition\n"
+ "<part> - MMC partition index or name containing the BCB\n"
+ "<field> - one of {command,status,recovery,stage,reserved}\n"
+ "<op> - the binary operator used in 'bcb test':\n"
+ " '=' returns true if <val> matches the string stored in <field>\n"
+ " '~' returns true if <val> matches a subset of <field>'s string\n"
+ "<val> - string/text provided as input to bcb {set,test}\n"
+ " NOTE: any ':' character in <val> will be replaced by line feed\n"
+ " during 'bcb set' and used as separator by upper layers\n"
+);
diff --git a/cmd/bootm.c b/cmd/bootm.c
index c3a063474a..41b341e2e5 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -249,7 +249,7 @@ static int image_info(ulong addr)
printf("\n## Checking Image at %08lx ...\n", addr);
switch (genimg_get_format(hdr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
puts(" Legacy image found\n");
if (!image_check_magic(hdr)) {
@@ -337,7 +337,7 @@ static int do_imls_nor(void)
goto next_sector;
switch (genimg_get_format(hdr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
if (!image_check_hcrc(hdr))
goto next_sector;
@@ -485,7 +485,7 @@ static int do_imls_nand(void)
}
switch (genimg_get_format(buffer)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
header = (const image_header_t *)buffer;
diff --git a/cmd/disk.c b/cmd/disk.c
index dcc36a6c2c..9e635c1172 100644
--- a/cmd/disk.c
+++ b/cmd/disk.c
@@ -15,7 +15,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
ulong addr = CONFIG_SYS_LOAD_ADDR;
ulong cnt;
disk_partition_t info;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
image_header_t *hdr;
#endif
struct blk_desc *dev_desc;
@@ -62,7 +62,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
switch (genimg_get_format((void *) addr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *) addr;
diff --git a/cmd/fdc.c b/cmd/fdc.c
index 906845d404..7bfaae0e38 100644
--- a/cmd/fdc.c
+++ b/cmd/fdc.c
@@ -634,7 +634,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
FDC_COMMAND_STRUCT *pCMD = &cmd;
unsigned long addr,imsize;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
image_header_t *hdr; /* used for fdc boot */
#endif
unsigned char boot_drive;
@@ -690,7 +690,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
switch (genimg_get_format ((void *)addr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *)addr;
image_print_contents (hdr);
diff --git a/cmd/fpga.c b/cmd/fpga.c
index b1f224bc6a..bc48abdd6d 100644
--- a/cmd/fpga.c
+++ b/cmd/fpga.c
@@ -280,7 +280,7 @@ static int do_fpga_loadmk(cmd_tbl_t *cmdtp, int flag, int argc,
}
switch (genimg_get_format(fpga_data)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
{
image_header_t *hdr = (image_header_t *)fpga_data;
diff --git a/cmd/nand.c b/cmd/nand.c
index a22945d144..899d504533 100644
--- a/cmd/nand.c
+++ b/cmd/nand.c
@@ -846,7 +846,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, struct mtd_info *mtd,
int r;
char *s;
size_t cnt;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
image_header_t *hdr;
#endif
#if defined(CONFIG_FIT)
@@ -874,7 +874,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, struct mtd_info *mtd,
bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ);
switch (genimg_get_format ((void *)addr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *)addr;
diff --git a/cmd/source.c b/cmd/source.c
index 6d98a1cfd3..1a9a71aa37 100644
--- a/cmd/source.c
+++ b/cmd/source.c
@@ -44,7 +44,7 @@ int
source (ulong addr, const char *fit_uname)
{
ulong len;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
const image_header_t *hdr;
#endif
u32 *data;
@@ -61,7 +61,7 @@ source (ulong addr, const char *fit_uname)
buf = map_sysmem(addr, 0);
switch (genimg_get_format(buf)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
hdr = buf;
diff --git a/cmd/ximg.c b/cmd/ximg.c
index 32bfae8b22..9e53cc4557 100644
--- a/cmd/ximg.c
+++ b/cmd/ximg.c
@@ -35,7 +35,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
ulong data, len;
int verify;
int part = 0;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
ulong count;
image_header_t *hdr = NULL;
#endif
@@ -67,7 +67,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
}
switch (genimg_get_format((void *)addr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
printf("## Copying part %d from legacy image "
@@ -217,7 +217,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
}
break;
#endif
-#if defined(CONFIG_BZIP2) && defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_BZIP2) && defined(CONFIG_LEGACY_IMAGE_FORMAT)
case IH_COMP_BZIP2:
{
int i;
diff --git a/common/bootm.c b/common/bootm.c
index d193751647..bea516025f 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -98,7 +98,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
/* get image parameters */
switch (genimg_get_format(os_hdr)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
images.os.type = image_get_type(os_hdr);
images.os.comp = image_get_comp(os_hdr);
@@ -738,7 +738,7 @@ err:
return ret;
}
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
/**
* image_get_kernel - verify legacy format kernel image
* @img_addr: in RAM address of the legacy format image to be verified
@@ -807,7 +807,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images,
ulong *os_data, ulong *os_len)
{
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
image_header_t *hdr;
#endif
ulong img_addr;
@@ -828,7 +828,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
*os_data = *os_len = 0;
buf = map_sysmem(img_addr, 0);
switch (genimg_get_format(buf)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
printf("## Booting kernel from Legacy Image at %08lx ...\n",
img_addr);
diff --git a/common/image-fdt.c b/common/image-fdt.c
index eb552ca207..e70da3dcb3 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -33,7 +33,7 @@ static void fdt_error(const char *msg)
puts(" - must RESET the board to recover.\n");
}
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
static const image_header_t *image_get_fdt(ulong fdt_addr)
{
const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0);
@@ -263,7 +263,7 @@ error:
int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
{
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
const image_header_t *fdt_hdr;
ulong load, load_end;
ulong image_start, image_data, image_end;
@@ -344,7 +344,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
*/
buf = map_sysmem(fdt_addr, 0);
switch (genimg_get_format(buf)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
/* verify fdt_addr points to a valid image header */
printf("## Flattened Device Tree from Legacy Image at %08lx\n",
diff --git a/common/image.c b/common/image.c
index 75b84d5009..9f9538fac2 100644
--- a/common/image.c
+++ b/common/image.c
@@ -38,7 +38,7 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
DECLARE_GLOBAL_DATA_PTR;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
int verify);
#endif
@@ -377,7 +377,7 @@ void image_print_contents(const void *ptr)
#ifndef USE_HOSTCC
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
/**
* image_get_ramdisk - get and verify ramdisk image
* @rd_addr: ramdisk image start address
@@ -867,7 +867,7 @@ ulong genimg_get_kernel_addr(char * const img_addr)
*/
int genimg_get_format(const void *img_addr)
{
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
const image_header_t *hdr;
hdr = (const image_header_t *)img_addr;
@@ -933,7 +933,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
{
ulong rd_addr, rd_load;
ulong rd_data, rd_len;
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
const image_header_t *rd_hdr;
#endif
void *buf;
@@ -1025,7 +1025,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
*/
buf = map_sysmem(rd_addr, 0);
switch (genimg_get_format(buf)) {
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
case IMAGE_FORMAT_LEGACY:
printf("## Loading init Ramdisk from Legacy "
"Image at %08lx ...\n", rd_addr);
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 802166131c..a48617ddcd 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -158,7 +158,7 @@ config SPL_RAW_IMAGE_SUPPORT
config SPL_LEGACY_IMAGE_SUPPORT
bool "Support SPL loading and booting of Legacy images"
- default y if !TI_SECURE_DEVICE
+ default y if !TI_SECURE_DEVICE && !SPL_LOAD_FIT
help
SPL will support loading and booting Legacy images when this option
is y. If this is not set, SPL will move on to other available
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 4ddeff9b51..d5e3f680f4 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -535,7 +535,7 @@ static int spl_load_image(struct spl_image_info *spl_image,
}
/**
- * boot_from_devices() - Try loading an booting U-Boot from a list of devices
+ * boot_from_devices() - Try loading a booting U-Boot from a list of devices
*
* @spl_image: Place to put the image details if successful
* @spl_boot_list: List of boot devices to try
diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig
index dfd69069c7..5eafbaaa5a 100644
--- a/configs/bcm963158_ram_defconfig
+++ b/configs/bcm963158_ram_defconfig
@@ -12,7 +12,7 @@ CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/bcm968580xref_ram_defconfig b/configs/bcm968580xref_ram_defconfig
index d331e4e807..49731ee230 100644
--- a/configs/bcm968580xref_ram_defconfig
+++ b/configs/bcm968580xref_ram_defconfig
@@ -10,7 +10,7 @@ CONFIG_TPL_SYS_MALLOC_F_LEN=0x400
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_HUSH_PARSER=y
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
index 4edade457b..1a1167b2a6 100644
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -9,7 +9,7 @@ CONFIG_MIPS_BOOT_FDT=y
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index 707d270920..a456e3b575 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -12,7 +12,7 @@ CONFIG_MIPS_BOOT_FDT=y
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 154a075682..31ed63c000 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -117,7 +117,7 @@ CONFIG_LCRR_EADC_1=y
CONFIG_LCRR_CLKDIV_2=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_BOOTDELAY=1
diff --git a/configs/imx6dl_icore_nand_defconfig b/configs/imx6dl_icore_nand_defconfig
index 6801ff00eb..b86b9e8773 100644
--- a/configs/imx6dl_icore_nand_defconfig
+++ b/configs/imx6dl_icore_nand_defconfig
@@ -12,7 +12,7 @@ CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_BOUNCE_BUFFER=y
diff --git a/configs/imx6q_icore_nand_defconfig b/configs/imx6q_icore_nand_defconfig
index 1657298cf3..4ea0803ab5 100644
--- a/configs/imx6q_icore_nand_defconfig
+++ b/configs/imx6q_icore_nand_defconfig
@@ -12,7 +12,7 @@ CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6qdl_icore_mipi_defconfig b/configs/imx6qdl_icore_mipi_defconfig
index d52b18c939..268c909882 100644
--- a/configs/imx6qdl_icore_mipi_defconfig
+++ b/configs/imx6qdl_icore_mipi_defconfig
@@ -17,7 +17,7 @@ CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig
index 68e371df3a..b15c547e37 100644
--- a/configs/imx6qdl_icore_mmc_defconfig
+++ b/configs/imx6qdl_icore_mmc_defconfig
@@ -19,7 +19,7 @@ CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6qdl_icore_nand_defconfig b/configs/imx6qdl_icore_nand_defconfig
index 1657298cf3..4ea0803ab5 100644
--- a/configs/imx6qdl_icore_nand_defconfig
+++ b/configs/imx6qdl_icore_nand_defconfig
@@ -12,7 +12,7 @@ CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6qdl_icore_rqs_defconfig b/configs/imx6qdl_icore_rqs_defconfig
index 3d164c0685..712c79f54e 100644
--- a/configs/imx6qdl_icore_rqs_defconfig
+++ b/configs/imx6qdl_icore_rqs_defconfig
@@ -14,7 +14,7 @@ CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6ul_geam_mmc_defconfig b/configs/imx6ul_geam_mmc_defconfig
index 4d3bef81a3..8a7b1ad6d5 100644
--- a/configs/imx6ul_geam_mmc_defconfig
+++ b/configs/imx6ul_geam_mmc_defconfig
@@ -13,7 +13,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6ul_geam_nand_defconfig b/configs/imx6ul_geam_nand_defconfig
index 68e16bb4be..d24027cd69 100644
--- a/configs/imx6ul_geam_nand_defconfig
+++ b/configs/imx6ul_geam_nand_defconfig
@@ -12,7 +12,7 @@ CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6ul_isiot_emmc_defconfig b/configs/imx6ul_isiot_emmc_defconfig
index 92f5bd031c..584d766262 100644
--- a/configs/imx6ul_isiot_emmc_defconfig
+++ b/configs/imx6ul_isiot_emmc_defconfig
@@ -13,7 +13,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/imx6ul_isiot_nand_defconfig b/configs/imx6ul_isiot_nand_defconfig
index 8ed5ea4a83..80f7cb3e03 100644
--- a/configs/imx6ul_isiot_nand_defconfig
+++ b/configs/imx6ul_isiot_nand_defconfig
@@ -12,7 +12,7 @@ CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_SUPPORT_RAW_INITRD=y
diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig
index 7d7cdf04ea..aa76633802 100644
--- a/configs/linkit-smart-7688-ram_defconfig
+++ b/configs/linkit-smart-7688-ram_defconfig
@@ -7,7 +7,7 @@ CONFIG_BOARD_LINKIT_SMART_7688=y
CONFIG_MIPS_BOOT_FDT=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_BOARD_EARLY_INIT_F=y
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
index b3acbbc2c7..3750e59a4b 100644
--- a/configs/linkit-smart-7688_defconfig
+++ b/configs/linkit-smart-7688_defconfig
@@ -10,7 +10,7 @@ CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
CONFIG_MIPS_BOOT_FDT=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_BOARD_EARLY_INIT_F=y
diff --git a/configs/syzygy_hub_defconfig b/configs/syzygy_hub_defconfig
index 075045bdc7..ac1bac877d 100644
--- a/configs/syzygy_hub_defconfig
+++ b/configs/syzygy_hub_defconfig
@@ -15,7 +15,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 19fac90122..012ba3ebbe 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -8,7 +8,7 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_SYS_MALLOC_LEN=0x2000
CONFIG_SYS_MEM_RSVD_FOR_MMU=y
CONFIG_COUNTER_FREQUENCY=2720000
-# CONFIG_IMAGE_FORMAT_LEGACY is not set
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index aa9dd230b5..93fa7d8f6b 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -7,7 +7,7 @@ CONFIG_ENV_SIZE=0x80
CONFIG_SYS_MEM_RSVD_FOR_MMU=y
CONFIG_ZYNQMP_PSU_INIT_ENABLED=y
# CONFIG_CMD_ZYNQMP is not set
-# CONFIG_IMAGE_FORMAT_LEGACY is not set
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_BOARD_LATE_INIT is not set
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index d3cc851176..b0bc84d55e 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -11,7 +11,7 @@ CONFIG_ZYNQMP_NO_DDR=y
# CONFIG_PSCI_RESET is not set
# CONFIG_CMD_ZYNQMP is not set
# CONFIG_EXPERT is not set
-# CONFIG_IMAGE_FORMAT_LEGACY is not set
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_BOARD_LATE_INIT is not set
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_TEXT_BASE=0xfffc0000
diff --git a/configs/zynq_cc108_defconfig b/configs/zynq_cc108_defconfig
index 35ebd14485..4d914ea725 100644
--- a/configs/zynq_cc108_defconfig
+++ b/configs/zynq_cc108_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_dlc20_rev1_0_defconfig b/configs/zynq_dlc20_rev1_0_defconfig
index 944c11381b..1e15889bda 100644
--- a/configs/zynq_dlc20_rev1_0_defconfig
+++ b/configs/zynq_dlc20_rev1_0_defconfig
@@ -14,7 +14,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index a48f203c16..1fceccdc09 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -10,7 +10,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_z_turn_defconfig b/configs/zynq_z_turn_defconfig
index d105b71c28..0908fc767c 100644
--- a/configs/zynq_z_turn_defconfig
+++ b/configs/zynq_z_turn_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig
index 3c4103f1f8..2ff263034a 100644
--- a/configs/zynq_zc702_defconfig
+++ b/configs/zynq_zc702_defconfig
@@ -14,7 +14,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig
index 3124de9795..33f26a6f2a 100644
--- a/configs/zynq_zc706_defconfig
+++ b/configs/zynq_zc706_defconfig
@@ -16,7 +16,7 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_FIT_PRINT=y
CONFIG_SPL_LOAD_FIT=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_FPGA_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 3b59cf2473..55ae55edc4 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -14,7 +14,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc770_xm011_defconfig b/configs/zynq_zc770_xm011_defconfig
index 6d377e94fb..7792ba29a0 100644
--- a/configs/zynq_zc770_xm011_defconfig
+++ b/configs/zynq_zc770_xm011_defconfig
@@ -15,7 +15,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm011_x16_defconfig b/configs/zynq_zc770_xm011_x16_defconfig
index fc2d3f362c..3a3740629b 100644
--- a/configs/zynq_zc770_xm011_x16_defconfig
+++ b/configs/zynq_zc770_xm011_x16_defconfig
@@ -15,7 +15,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 0767e91b07..d777ba889e 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -12,7 +12,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 9eb67cf4ec..c5288e56e3 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -12,7 +12,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index b5dbe405e0..e47cce5e07 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 0ad92849dd..ee15d83147 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zybo_z7_defconfig b/configs/zynq_zybo_z7_defconfig
index d434982df3..43b746f56c 100644
--- a/configs/zynq_zybo_z7_defconfig
+++ b/configs/zynq_zybo_z7_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-CONFIG_IMAGE_FORMAT_LEGACY=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/doc/README.avb2 b/doc/android/avb2.txt
index a29cee1b6f..a29cee1b6f 100644
--- a/doc/README.avb2
+++ b/doc/android/avb2.txt
diff --git a/doc/android/bcb.txt b/doc/android/bcb.txt
new file mode 100644
index 0000000000..7b7177cacf
--- /dev/null
+++ b/doc/android/bcb.txt
@@ -0,0 +1,89 @@
+Android Bootloader Control Block (BCB)
+
+The purpose behind this file is to:
+ - give an overview of BCB w/o duplicating public documentation
+ - describe the main BCB use-cases which concern U-Boot
+ - reflect current support status in U-Boot
+ - mention any relevant U-Boot build-time tunables
+ - precisely exemplify one or more use-cases
+
+Additions and fixes are welcome!
+
+
+1. OVERVIEW
+---------------------------------
+Bootloader Control Block (BCB) is a well established term/acronym in
+the Android namespace which refers to a location in a dedicated raw
+(i.e. FS-unaware) flash (e.g. eMMC) partition, usually called "misc",
+which is used as media for exchanging messages between Android userspace
+(particularly recovery [1]) and an Android-capable bootloader.
+
+On higher level, BCB provides a way to implement a subset of Android
+Bootloader Requirements [2], amongst which are:
+ - Android-specific bootloader flow [3]
+ - Get the "reboot reason" (and act accordingly) [4]
+ - Get/pass a list of commands from/to recovery [1]
+ - TODO
+
+
+2. 'BCB'. SHELL COMMAND OVERVIEW
+-----------------------------------
+The 'bcb' command provides a CLI to facilitate the development of the
+requirements enumerated above. Below is the command's help message:
+
+=> bcb
+bcb - Load/set/clear/test/dump/store Android BCB fields
+
+Usage:
+bcb load <dev> <part> - load BCB from mmc <dev>:<part>
+bcb set <field> <val> - set BCB <field> to <val>
+bcb clear [<field>] - clear BCB <field> or all fields
+bcb test <field> <op> <val> - test BCB <field> against <val>
+bcb dump <field> - dump BCB <field>
+bcb store - store BCB back to mmc
+
+Legend:
+<dev> - MMC device index containing the BCB partition
+<part> - MMC partition index or name containing the BCB
+<field> - one of {command,status,recovery,stage,reserved}
+<op> - the binary operator used in 'bcb test':
+ '=' returns true if <val> matches the string stored in <field>
+ '~' returns true if <val> matches a subset of <field>'s string
+<val> - string/text provided as input to bcb {set,test}
+ NOTE: any ':' character in <val> will be replaced by line feed
+ during 'bcb set' and used as separator by upper layers
+
+
+3. 'BCB'. EXAMPLE OF GETTING REBOOT REASON
+-----------------------------------
+if bcb load 1 misc; then
+ # valid BCB found
+ if bcb test command = bootonce-bootloader; then
+ bcb clear command; bcb store;
+ # do the equivalent of AOSP ${fastbootcmd}
+ # i.e. call fastboot
+ else if bcb test command = boot-recovery; then
+ bcb clear command; bcb store;
+ # do the equivalent of AOSP ${recoverycmd}
+ # i.e. do anything required for booting into recovery
+ else
+ # boot Android OS normally
+ fi
+else
+ # corrupted/non-existent BCB
+ # report error or boot non-Android OS (platform-specific)
+fi
+
+
+4. ENABLE ON YOUR BOARD
+-----------------------------------
+The following Kconfig options must be enabled:
+CONFIG_PARTITIONS=y
+CONFIG_MMC=y
+CONFIG_BCB=y
+
+[1] https://android.googlesource.com/platform/bootable/recovery
+[2] https://source.android.com/devices/bootloader
+[3] https://patchwork.ozlabs.org/patch/746835/
+ ("[U-Boot,5/6] Initial support for the Android Bootloader flow")
+[4] https://source.android.com/devices/bootloader/boot-reason
diff --git a/doc/README.android-fastboot b/doc/android/fastboot.txt
index 431191c473..431191c473 100644
--- a/doc/README.android-fastboot
+++ b/doc/android/fastboot.txt
diff --git a/doc/device-tree-bindings/pci_endpoint/cdns,cdns-pcie-ep.txt b/doc/device-tree-bindings/pci_endpoint/cdns,cdns-pcie-ep.txt
new file mode 100644
index 0000000000..7705430559
--- /dev/null
+++ b/doc/device-tree-bindings/pci_endpoint/cdns,cdns-pcie-ep.txt
@@ -0,0 +1,18 @@
+* Cadence PCIe endpoint controller
+
+Required properties:
+- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used.
+- reg: Should contain the controller register base address.
+
+Optional properties:
+- max-functions: Maximum number of functions that can be configured (default 1).
+- cdns,max-outbound-regions: Set to maximum number of outbound regions (default 8)
+
+Example:
+
+pcie_ep@fc000000 {
+ compatible = "cdns,cdns-pcie-ep";
+ reg = <0x0 0xfc000000 0x0 0x01000000>;
+ cdns,max-outbound-regions = <16>;
+ max-functions = /bits/ 8 <8>;
+};
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
index bfff6fdc73..78b59e7203 100644
--- a/doc/uImage.FIT/signature.txt
+++ b/doc/uImage.FIT/signature.txt
@@ -335,7 +335,7 @@ CONFIG_RSA - enable RSA algorithm for signing
WARNING: When relying on signed FIT images with required signature check
the legacy image format is default disabled by not defining
-CONFIG_IMAGE_FORMAT_LEGACY
+CONFIG_LEGACY_IMAGE_FORMAT
Testing
-------
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 96ff4f566a..5a9d01b508 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -66,6 +66,8 @@ source "drivers/nvme/Kconfig"
source "drivers/pci/Kconfig"
+source "drivers/pci_endpoint/Kconfig"
+
source "drivers/pch/Kconfig"
source "drivers/pcmcia/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 6635dabd2c..603aa98590 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_FPGA) += fpga/
obj-y += misc/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_NVME) += nvme/
+obj-$(CONFIG_PCI_ENDPOINT) += pci_endpoint/
obj-y += pcmcia/
obj-y += dfu/
obj-$(CONFIG_PCH) += pch/
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index 341527acc5..07a3356b3c 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -363,6 +363,7 @@ static const struct udevice_id pca953x_ids[] = {
{ .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
{ .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
+ { .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
{ .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
diff --git a/drivers/pci_endpoint/Kconfig b/drivers/pci_endpoint/Kconfig
new file mode 100644
index 0000000000..19cfa0aafb
--- /dev/null
+++ b/drivers/pci_endpoint/Kconfig
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# PCI Endpoint Support
+#
+
+menu "PCI Endpoint"
+
+config PCI_ENDPOINT
+ bool "PCI Endpoint Support"
+ depends on DM
+ help
+ Enable this configuration option to support configurable PCI
+ endpoints. This should be enabled if the platform has a PCI
+ controllers that can operate in endpoint mode (as a device
+ connected to PCI host or bridge).
+
+config PCIE_CADENCE_EP
+ bool "Cadence PCIe endpoint controller"
+ depends on PCI_ENDPOINT
+ help
+ Say Y here if you want to support the Cadence PCIe controller in
+ endpoint mode. This PCIe controller may be embedded into many
+ different vendors SoCs.
+
+config PCI_SANDBOX_EP
+ bool "Sandbox PCIe endpoint controller"
+ depends on PCI_ENDPOINT
+ help
+ Say Y here if you want to support the Sandbox PCIe controller in
+ endpoint mode.
+ The sandbox driver act as a dummy driver which stores and
+ retrieves PCIe endpoint configuration as is.
+
+endmenu
diff --git a/drivers/pci_endpoint/Makefile b/drivers/pci_endpoint/Makefile
new file mode 100644
index 0000000000..3cd987259d
--- /dev/null
+++ b/drivers/pci_endpoint/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2019
+# Ramon Fried <ramon.fried@gmail.com>
+
+obj-y += pci_ep-uclass.o
+obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
+obj-$(CONFIG_PCI_SANDBOX_EP) += sandbox-pci_ep.o
diff --git a/drivers/pci_endpoint/pci_ep-uclass.c b/drivers/pci_endpoint/pci_ep-uclass.c
new file mode 100644
index 0000000000..2f9c70398d
--- /dev/null
+++ b/drivers/pci_endpoint/pci_ep-uclass.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PCI Endpoint uclass
+ *
+ * Based on Linux PCI-EP driver written by
+ * Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * Copyright (c) 2019
+ * Written by Ramon Fried <ramon.fried@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <linux/log2.h>
+#include <pci_ep.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int pci_ep_write_header(struct udevice *dev, uint fn, struct pci_ep_header *hdr)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->write_header)
+ return -ENOSYS;
+
+ return ops->write_header(dev, fn, hdr);
+}
+
+int pci_ep_read_header(struct udevice *dev, uint fn, struct pci_ep_header *hdr)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->read_header)
+ return -ENOSYS;
+
+ return ops->read_header(dev, fn, hdr);
+}
+
+int pci_ep_set_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+ int flags = ep_bar->flags;
+
+ /* Some basic bar validity checks */
+ if (ep_bar->barno > BAR_5 || ep_bar < BAR_0)
+ return -EINVAL;
+
+ if ((ep_bar->barno == BAR_5 &&
+ (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)) ||
+ ((flags & PCI_BASE_ADDRESS_SPACE_IO) &&
+ (flags & PCI_BASE_ADDRESS_IO_MASK)) ||
+ (upper_32_bits(ep_bar->size) &&
+ !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)))
+ return -EINVAL;
+
+ if (!ops->set_bar)
+ return -ENOSYS;
+
+ return ops->set_bar(dev, func_no, ep_bar);
+}
+
+int pci_ep_read_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar,
+ enum pci_barno barno)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ /* Some basic bar validity checks */
+ if (barno > BAR_5 || barno < BAR_0)
+ return -EINVAL;
+
+ if (!ops->read_bar)
+ return -ENOSYS;
+
+ return ops->read_bar(dev, func_no, ep_bar, barno);
+}
+
+int pci_ep_clear_bar(struct udevice *dev, uint func_num, enum pci_barno bar)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->clear_bar)
+ return -ENOSYS;
+
+ return ops->clear_bar(dev, func_num, bar);
+}
+
+int pci_ep_map_addr(struct udevice *dev, uint func_no, phys_addr_t addr,
+ u64 pci_addr, size_t size)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->map_addr)
+ return -ENOSYS;
+
+ return ops->map_addr(dev, func_no, addr, pci_addr, size);
+}
+
+int pci_ep_unmap_addr(struct udevice *dev, uint func_no, phys_addr_t addr)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->unmap_addr)
+ return -ENOSYS;
+
+ return ops->unmap_addr(dev, func_no, addr);
+}
+
+int pci_ep_set_msi(struct udevice *dev, uint func_no, uint interrupts)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+ uint encode_int;
+
+ if (interrupts > 32)
+ return -EINVAL;
+
+ if (!ops->set_msi)
+ return -ENOSYS;
+
+ /* MSI spec permits allocation of
+ * only 1, 2, 4, 8, 16, 32 interrupts
+ */
+ encode_int = order_base_2(interrupts);
+
+ return ops->set_msi(dev, func_no, encode_int);
+}
+
+int pci_ep_get_msi(struct udevice *dev, uint func_no)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+ int interrupt;
+
+ if (!ops->get_msi)
+ return -ENOSYS;
+
+ interrupt = ops->get_msi(dev, func_no);
+
+ if (interrupt < 0)
+ return 0;
+
+ /* Translate back from order base 2*/
+ interrupt = 1 << interrupt;
+
+ return interrupt;
+}
+
+int pci_ep_set_msix(struct udevice *dev, uint func_no, uint interrupts)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (interrupts < 1 || interrupts > 2048)
+ return -EINVAL;
+
+ if (!ops->set_msix)
+ return -ENOSYS;
+
+ return ops->set_msix(dev, func_no, interrupts - 1);
+}
+
+int pci_ep_get_msix(struct udevice *dev, uint func_no)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+ int interrupt;
+
+ if (!ops->get_msix)
+ return -ENOSYS;
+
+ interrupt = ops->get_msix(dev, func_no);
+
+ if (interrupt < 0)
+ return 0;
+
+ return interrupt + 1;
+}
+
+int pci_ep_raise_irq(struct udevice *dev, uint func_no,
+ enum pci_ep_irq_type type, uint interrupt_num)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->raise_irq)
+ return -ENOSYS;
+
+ return ops->raise_irq(dev, func_no, type, interrupt_num);
+}
+
+int pci_ep_start(struct udevice *dev)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->start)
+ return -ENOSYS;
+
+ return ops->start(dev);
+}
+
+int pci_ep_stop(struct udevice *dev)
+{
+ struct pci_ep_ops *ops = pci_ep_get_ops(dev);
+
+ if (!ops->stop)
+ return -ENOSYS;
+
+ return ops->stop(dev);
+}
+
+UCLASS_DRIVER(pci_ep) = {
+ .id = UCLASS_PCI_EP,
+ .name = "pci_ep",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+};
diff --git a/drivers/pci_endpoint/pcie-cadence-ep.c b/drivers/pci_endpoint/pcie-cadence-ep.c
new file mode 100644
index 0000000000..59231d340a
--- /dev/null
+++ b/drivers/pci_endpoint/pcie-cadence-ep.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019
+ * Written by Ramon Fried <ramon.fried@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <pci_ep.h>
+#include <linux/sizes.h>
+#include <linux/log2.h>
+#include "pcie-cadence.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int cdns_write_header(struct udevice *dev, uint fn,
+ struct pci_ep_header *hdr)
+{
+ struct cdns_pcie *pcie = dev_get_priv(dev);
+
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG,
+ hdr->progif_code);
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE,
+ hdr->subclass_code |
+ hdr->baseclass_code << 8);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE,
+ hdr->cache_line_size);
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID,
+ hdr->subsys_id);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN,
+ hdr->interrupt_pin);
+
+ /*
+ * Vendor ID can only be modified from function 0, all other functions
+ * use the same vendor ID as function 0.
+ */
+ if (fn == 0) {
+ /* Update the vendor IDs. */
+ u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
+ CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
+ }
+
+ return 0;
+}
+
+static int cdns_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
+{
+ struct cdns_pcie *pcie = dev_get_priv(dev);
+ dma_addr_t bar_phys = ep_bar->phys_addr;
+ enum pci_barno bar = ep_bar->barno;
+ int flags = ep_bar->flags;
+ u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+ u64 sz;
+
+ /* BAR size is 2^(aperture + 7) */
+ sz = max_t(size_t, ep_bar->size, CDNS_PCIE_EP_MIN_APERTURE);
+ /*
+ * roundup_pow_of_two() returns an unsigned long, which is not suited
+ * for 64bit values.
+ */
+ sz = 1ULL << fls64(sz - 1);
+ aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+
+ if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
+ } else {
+ bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+ bool is_64bits = (sz > SZ_2G) |
+ !!(ep_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+ if (is_64bits && (bar & 1))
+ return -EINVAL;
+
+ if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
+ ep_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+
+ if (is_64bits && is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+ else if (is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+ else if (is_64bits)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS;
+ else
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS;
+ }
+
+ addr0 = lower_32_bits(bar_phys);
+ addr1 = upper_32_bits(bar_phys);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
+ addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
+ addr1);
+
+ if (bar < BAR_4) {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+ b = bar;
+ } else {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+ b = bar - BAR_4;
+ }
+
+ cfg = cdns_pcie_readl(pcie, reg);
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+ cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+ cdns_pcie_writel(pcie, reg, cfg);
+
+ return 0;
+}
+
+static int cdns_set_msi(struct udevice *dev, uint fn, uint mmc)
+{
+ struct cdns_pcie *pcie = dev_get_priv(dev);
+ u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+
+ /*
+ * Set the Multiple Message Capable bitfield into the Message Control
+ * register.
+ */
+ u16 flags;
+
+ flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+ flags = (flags & ~PCI_MSI_FLAGS_QMASK) | (mmc << 1);
+ flags |= PCI_MSI_FLAGS_64BIT;
+ flags &= ~PCI_MSI_FLAGS_MASKBIT;
+ cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags);
+
+ return 0;
+}
+
+static struct pci_ep_ops cdns_pci_ep_ops = {
+ .write_header = cdns_write_header,
+ .set_bar = cdns_set_bar,
+ .set_msi = cdns_set_msi,
+};
+
+static int cdns_pci_ep_probe(struct udevice *dev)
+{
+ struct cdns_pcie *pdata = dev_get_priv(dev);
+
+ pdata->reg_base = (void __iomem *)devfdt_get_addr(dev);
+ if (!pdata->reg_base)
+ return -ENOMEM;
+
+ pdata->max_functions = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "max-functions", 1);
+ pdata->max_regions = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "cdns,max-outbound-regions", 8);
+
+ return 0;
+}
+
+static int cdns_pci_ep_remove(struct udevice *dev)
+{
+ return 0;
+}
+
+const struct udevice_id cadence_pci_ep_of_match[] = {
+ { .compatible = "cdns,cdns-pcie-ep" },
+ { }
+};
+
+U_BOOT_DRIVER(cdns_pcie) = {
+ .name = "cdns,pcie-ep",
+ .id = UCLASS_PCI_EP,
+ .of_match = cadence_pci_ep_of_match,
+ .ops = &cdns_pci_ep_ops,
+ .probe = cdns_pci_ep_probe,
+ .remove = cdns_pci_ep_remove,
+ .priv_auto_alloc_size = sizeof(struct cdns_pcie),
+};
diff --git a/drivers/pci_endpoint/pcie-cadence.h b/drivers/pci_endpoint/pcie-cadence.h
new file mode 100644
index 0000000000..91630d35c3
--- /dev/null
+++ b/drivers/pci_endpoint/pcie-cadence.h
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Cadence PCIe controlloer definitions
+ * Adapted from linux kernel driver.
+ * Copyright (c) 2017 Cadence
+ *
+ * Copyright (c) 2019
+ * Written by Ramon Fried <ramon.fried@gmail.com>
+ */
+
+#ifndef PCIE_CADENCE_H
+#define PCIE_CADENCE_H
+
+#include <common.h>
+#include <pci_ep.h>
+#include <asm/io.h>
+
+/*
+ * Local Management Registers
+ */
+#define CDNS_PCIE_LM_BASE 0x00100000
+
+/* Vendor ID Register */
+#define CDNS_PCIE_LM_ID (CDNS_PCIE_LM_BASE + 0x0044)
+#define CDNS_PCIE_LM_ID_VENDOR_MASK GENMASK(15, 0)
+#define CDNS_PCIE_LM_ID_VENDOR_SHIFT 0
+#define CDNS_PCIE_LM_ID_VENDOR(vid) \
+ (((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK)
+#define CDNS_PCIE_LM_ID_SUBSYS_MASK GENMASK(31, 16)
+#define CDNS_PCIE_LM_ID_SUBSYS_SHIFT 16
+#define CDNS_PCIE_LM_ID_SUBSYS(sub) \
+ (((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK)
+
+/* Root Port Requestor ID Register */
+#define CDNS_PCIE_LM_RP_RID (CDNS_PCIE_LM_BASE + 0x0228)
+#define CDNS_PCIE_LM_RP_RID_MASK GENMASK(15, 0)
+#define CDNS_PCIE_LM_RP_RID_SHIFT 0
+#define CDNS_PCIE_LM_RP_RID_(rid) \
+ (((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK)
+
+/* Endpoint Bus and Device Number Register */
+#define CDNS_PCIE_LM_EP_ID (CDNS_PCIE_LM_BASE + 0x022c)
+#define CDNS_PCIE_LM_EP_ID_DEV_MASK GENMASK(4, 0)
+#define CDNS_PCIE_LM_EP_ID_DEV_SHIFT 0
+#define CDNS_PCIE_LM_EP_ID_BUS_MASK GENMASK(15, 8)
+#define CDNS_PCIE_LM_EP_ID_BUS_SHIFT 8
+
+/* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
+ (CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
+ (CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
+ (GENMASK(4, 0) << ((b) * 8))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+ (((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
+ (GENMASK(7, 5) << ((b) * 8))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+ (((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_LM_EP_FUNC_CFG (CDNS_PCIE_LM_BASE + 0x02c0)
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_LM_RC_BAR_CFG (CDNS_PCIE_LM_BASE + 0x0300)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK GENMASK(5, 0)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+ (((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK GENMASK(8, 6)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+ (((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK GENMASK(13, 9)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+ (((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK GENMASK(16, 14)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+ (((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE BIT(17)
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS 0
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS BIT(18)
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE BIT(19)
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS 0
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS BIT(20)
+#define CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE BIT(31)
+
+/* BAR control values applicable to both Endpoint Function and Root Complex */
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED 0x0
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS 0x1
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS 0x4
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS 0x5
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS 0x6
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS 0x7
+
+/*
+ * Endpoint Function Registers (PCI configuration space for endpoint functions)
+ */
+#define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
+
+#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90
+
+/*
+ * Root Port Registers (PCI configuration space for the root port function)
+ */
+#define CDNS_PCIE_RP_BASE 0x00200000
+
+/*
+ * Address Translation Registers
+ */
+#define CDNS_PCIE_AT_BASE 0x00400000
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+ (((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+ (((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
+
+/* Region r Outbound AXI to PCIe Address Translation Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
+ (CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
+
+/* Region r Outbound PCIe Descriptor Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK GENMASK(3, 0)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM 0x2
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO 0x6
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0 0xa
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1 0xb
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG 0xc
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG 0xd
+/* Bit 23 MUST be set in RC mode. */
+#define CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
+ (((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
+
+/* Region r Outbound PCIe Descriptor Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_DESC1(r) \
+ (CDNS_PCIE_AT_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK GENMASK(7, 0)
+#define CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
+ ((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK)
+
+/* Region r AXI Region Base Address Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
+ (CDNS_PCIE_AT_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
+ (CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
+ (CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
+
+/* AXI link down register */
+#define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
+
+enum cdns_pcie_rp_bar {
+ RP_BAR0,
+ RP_BAR1,
+ RP_NO_BAR
+};
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+ (CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+ (CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
+
+/* Normal/Vendor specific message access: offset inside some outbound region */
+#define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK GENMASK(7, 5)
+#define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \
+ (((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK)
+#define CDNS_PCIE_NORMAL_MSG_CODE_MASK GENMASK(15, 8)
+#define CDNS_PCIE_NORMAL_MSG_CODE(code) \
+ (((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
+#define CDNS_PCIE_MSG_NO_DATA BIT(16)
+
+#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */
+
+enum cdns_pcie_msg_code {
+ MSG_CODE_ASSERT_INTA = 0x20,
+ MSG_CODE_ASSERT_INTB = 0x21,
+ MSG_CODE_ASSERT_INTC = 0x22,
+ MSG_CODE_ASSERT_INTD = 0x23,
+ MSG_CODE_DEASSERT_INTA = 0x24,
+ MSG_CODE_DEASSERT_INTB = 0x25,
+ MSG_CODE_DEASSERT_INTC = 0x26,
+ MSG_CODE_DEASSERT_INTD = 0x27,
+};
+
+enum cdns_pcie_msg_routing {
+ /* Route to Root Complex */
+ MSG_ROUTING_TO_RC,
+
+ /* Use Address Routing */
+ MSG_ROUTING_BY_ADDR,
+
+ /* Use ID Routing */
+ MSG_ROUTING_BY_ID,
+
+ /* Route as Broadcast Message from Root Complex */
+ MSG_ROUTING_BCAST,
+
+ /* Local message; terminate at receiver (INTx messages) */
+ MSG_ROUTING_LOCAL,
+
+ /* Gather & route to Root Complex (PME_TO_Ack message) */
+ MSG_ROUTING_GATHER,
+};
+
+struct cdns_pcie {
+ void __iomem *reg_base;
+ u32 max_functions;
+ u32 max_regions;
+};
+
+/* Register access */
+static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
+{
+ writel(value, pcie->reg_base + reg);
+}
+
+static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
+{
+ return readl(pcie->reg_base + reg);
+}
+
+/* Root Port register access */
+static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
+ u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
+ u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+static inline void cdns_pcie_rp_writel(struct cdns_pcie *pcie,
+ u32 reg, u32 value)
+{
+ writel(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+/* Endpoint Function register access */
+static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u32 value)
+{
+ writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+#endif /* end of include guard: PCIE_CADENCE_H */
diff --git a/drivers/pci_endpoint/sandbox-pci_ep.c b/drivers/pci_endpoint/sandbox-pci_ep.c
new file mode 100644
index 0000000000..0258433d8f
--- /dev/null
+++ b/drivers/pci_endpoint/sandbox-pci_ep.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 Ramon Fried <ramon.fried@gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <pci.h>
+#include <pci_ep.h>
+#include <asm/test.h>
+
+/**
+ * struct sandbox_pci_ep_priv - private data for driver
+ * @hdr: Stores the EP device header
+ * @msix: required MSIx count;
+ * @msi: required MSI count;
+ */
+struct sandbox_pci_ep_priv {
+ struct pci_ep_header hdr;
+ struct pci_bar bars[6];
+ int msix;
+ int msi;
+ int irq_count;
+};
+
+/* Method exported for testing purposes */
+int sandbox_get_pci_ep_irq_count(struct udevice *dev)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ return priv->irq_count;
+}
+
+static const struct udevice_id sandbox_pci_ep_ids[] = {
+ { .compatible = "sandbox,pci_ep" },
+ { }
+};
+
+static int sandbox_write_header(struct udevice *dev, uint fn,
+ struct pci_ep_header *hdr)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ memcpy(&priv->hdr, hdr, sizeof(*hdr));
+
+ return 0;
+}
+
+static int sandbox_read_header(struct udevice *dev, uint fn,
+ struct pci_ep_header *hdr)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ memcpy(hdr, &priv->hdr, sizeof(*hdr));
+
+ return 0;
+}
+
+static int sandbox_set_bar(struct udevice *dev, uint fn,
+ struct pci_bar *ep_bar)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+ int bar_idx;
+
+ if (fn > 0)
+ return -ENODEV;
+
+ bar_idx = ep_bar->barno;
+
+ memcpy(&priv->bars[bar_idx], ep_bar, sizeof(*ep_bar));
+
+ return 0;
+}
+
+static int sandbox_read_bar(struct udevice *dev, uint fn,
+ struct pci_bar *ep_bar, enum pci_barno barno)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+ int bar_idx;
+
+ if (fn > 0)
+ return -ENODEV;
+
+ bar_idx = ep_bar->barno;
+
+ memcpy(ep_bar, &priv->bars[bar_idx], sizeof(*ep_bar));
+
+ return 0;
+}
+
+static int sandbox_set_msi(struct udevice *dev, uint fn, uint interrupts)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ priv->msi = interrupts;
+
+ return 0;
+}
+
+static int sandbox_get_msi(struct udevice *dev, uint fn)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ return priv->msi;
+}
+
+static int sandbox_set_msix(struct udevice *dev, uint fn, uint interrupts)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ priv->msix = interrupts;
+
+ return 0;
+}
+
+static int sandbox_get_msix(struct udevice *dev, uint fn)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ return priv->msix;
+}
+
+static int sandbox_raise_irq(struct udevice *dev, uint fn,
+ enum pci_ep_irq_type type, uint interrupt_num)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ if (fn > 0)
+ return -ENODEV;
+
+ priv->irq_count++;
+
+ return 0;
+}
+
+static int sandbox_pci_ep_probe(struct udevice *dev)
+{
+ struct sandbox_pci_ep_priv *priv = dev_get_priv(dev);
+
+ memset(priv, 0, sizeof(*priv));
+ return 0;
+}
+
+static struct pci_ep_ops sandbox_pci_ep_ops = {
+ .write_header = sandbox_write_header,
+ .read_header = sandbox_read_header,
+ .set_bar = sandbox_set_bar,
+ .read_bar = sandbox_read_bar,
+ .set_msi = sandbox_set_msi,
+ .get_msi = sandbox_get_msi,
+ .set_msix = sandbox_set_msix,
+ .get_msix = sandbox_get_msix,
+ .raise_irq = sandbox_raise_irq,
+};
+
+U_BOOT_DRIVER(pci_ep_sandbox) = {
+ .name = "pci_ep_sandbox",
+ .id = UCLASS_PCI_EP,
+ .of_match = sandbox_pci_ep_ids,
+ .probe = sandbox_pci_ep_probe,
+ .ops = &sandbox_pci_ep_ops,
+ .priv_auto_alloc_size = sizeof(struct sandbox_pci_ep_priv),
+};
diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c
index 8878130bd7..7186c179d1 100644
--- a/drivers/tpm/tpm2_tis_spi.c
+++ b/drivers/tpm/tpm2_tis_spi.c
@@ -295,6 +295,14 @@ static int tpm_tis_spi_wait_for_stat(struct udevice *dev, u8 mask,
return -ETIMEDOUT;
}
+static u8 tpm_tis_spi_valid_status(struct udevice *dev, u8 *status)
+{
+ struct tpm_chip *chip = dev_get_priv(dev);
+
+ return tpm_tis_spi_wait_for_stat(dev, TPM_STS_VALID,
+ chip->timeout_c, status);
+}
+
static int tpm_tis_spi_get_burstcount(struct udevice *dev)
{
struct tpm_chip *chip = dev_get_priv(dev);
@@ -455,7 +463,7 @@ static int tpm_tis_spi_send(struct udevice *dev, const u8 *buf, size_t len)
i += size;
}
- ret = tpm_tis_spi_status(dev, &status);
+ ret = tpm_tis_spi_valid_status(dev, &status);
if (ret)
goto out_err;
@@ -469,7 +477,7 @@ static int tpm_tis_spi_send(struct udevice *dev, const u8 *buf, size_t len)
if (ret)
goto out_err;
- ret = tpm_tis_spi_status(dev, &status);
+ ret = tpm_tis_spi_valid_status(dev, &status);
if (ret)
goto out_err;
diff --git a/include/android_bootloader_message.h b/include/android_bootloader_message.h
index b84789f022..286d7ab0f3 100644
--- a/include/android_bootloader_message.h
+++ b/include/android_bootloader_message.h
@@ -2,7 +2,7 @@
* This is from the Android Project,
* Repository: https://android.googlesource.com/platform/bootable/recovery
* File: bootloader_message/include/bootloader_message/bootloader_message.h
- * Commit: c784ce50e8c10eaf70e1f97e24e8324aef45faf5
+ * Commit: See U-Boot commit description
*
* Copyright (C) 2008 The Android Open Source Project
*
@@ -12,18 +12,24 @@
#ifndef __ANDROID_BOOTLOADER_MESSAGE_H
#define __ANDROID_BOOTLOADER_MESSAGE_H
+#ifndef __UBOOT__
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#else
/* compiler.h defines the types that otherwise are included from stdint.h and
* stddef.h
*/
#include <compiler.h>
+#endif
-/* Spaces used by misc partition are as below:
- * 0 - 2K For bootloader_message
- * 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
- * as bootloader_message_ab struct)
- * 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
- * Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
- * are not configurable without changing all of them. */
+// Spaces used by misc partition are as below:
+// 0 - 2K For bootloader_message
+// 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
+// as bootloader_message_ab struct)
+// 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
+// Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
+// are not configurable without changing all of them.
static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
@@ -61,17 +67,17 @@ struct bootloader_message {
char status[32];
char recovery[768];
- /* The 'recovery' field used to be 1024 bytes. It has only ever
- * been used to store the recovery command line, so 768 bytes
- * should be plenty. We carve off the last 256 bytes to store the
- * stage string (for multistage packages) and possible future
- * expansion. */
+ // The 'recovery' field used to be 1024 bytes. It has only ever
+ // been used to store the recovery command line, so 768 bytes
+ // should be plenty. We carve off the last 256 bytes to store the
+ // stage string (for multistage packages) and possible future
+ // expansion.
char stage[32];
- /* The 'reserved' field used to be 224 bytes when it was initially
- * carved off from the 1024-byte recovery field. Bump it up to
- * 1184-byte so that the entire bootloader_message struct rounds up
- * to 2048-byte. */
+ // The 'reserved' field used to be 224 bytes when it was initially
+ // carved off from the 1024-byte recovery field. Bump it up to
+ // 1184-byte so that the entire bootloader_message struct rounds up
+ // to 2048-byte.
char reserved[1184];
};
@@ -79,10 +85,12 @@ struct bootloader_message {
* We must be cautious when changing the bootloader_message struct size,
* because A/B-specific fields may end up with different offsets.
*/
+#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message) == 2048,
"struct bootloader_message size changes, which may break A/B devices");
#endif
+#endif /* __UBOOT__ */
/**
* The A/B-specific bootloader message structure (4-KiB).
@@ -108,7 +116,7 @@ struct bootloader_message_ab {
char slot_suffix[32];
char update_channel[128];
- /* Round up the entire struct to 4096-byte. */
+ // Round up the entire struct to 4096-byte.
char reserved[1888];
};
@@ -116,26 +124,28 @@ struct bootloader_message_ab {
* Be cautious about the struct size change, in case we put anything post
* bootloader_message_ab struct (b/29159185).
*/
+#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message_ab) == 4096,
"struct bootloader_message_ab size changes");
#endif
+#endif /* __UBOOT__ */
#define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */
#define BOOT_CTRL_VERSION 1
struct slot_metadata {
- /* Slot priority with 15 meaning highest priority, 1 lowest
- * priority and 0 the slot is unbootable. */
+ // Slot priority with 15 meaning highest priority, 1 lowest
+ // priority and 0 the slot is unbootable.
uint8_t priority : 4;
- /* Number of times left attempting to boot this slot. */
+ // Number of times left attempting to boot this slot.
uint8_t tries_remaining : 3;
- /* 1 if this slot has booted successfully, 0 otherwise. */
+ // 1 if this slot has booted successfully, 0 otherwise.
uint8_t successful_boot : 1;
- /* 1 if this slot is corrupted from a dm-verity corruption, 0
- * otherwise. */
+ // 1 if this slot is corrupted from a dm-verity corruption, 0
+ // otherwise.
uint8_t verity_corrupted : 1;
- /* Reserved for further use. */
+ // Reserved for further use.
uint8_t reserved : 7;
} __attribute__((packed));
@@ -148,99 +158,99 @@ struct slot_metadata {
* mandatory.
*/
struct bootloader_control {
- /* NUL terminated active slot suffix. */
+ // NUL terminated active slot suffix.
char slot_suffix[4];
- /* Bootloader Control AB magic number (see BOOT_CTRL_MAGIC). */
+ // Bootloader Control AB magic number (see BOOT_CTRL_MAGIC).
uint32_t magic;
- /* Version of struct being used (see BOOT_CTRL_VERSION). */
+ // Version of struct being used (see BOOT_CTRL_VERSION).
uint8_t version;
- /* Number of slots being managed. */
+ // Number of slots being managed.
uint8_t nb_slot : 3;
- /* Number of times left attempting to boot recovery. */
+ // Number of times left attempting to boot recovery.
uint8_t recovery_tries_remaining : 3;
- /* Ensure 4-bytes alignment for slot_info field. */
+ // Ensure 4-bytes alignment for slot_info field.
uint8_t reserved0[2];
- /* Per-slot information. Up to 4 slots. */
+ // Per-slot information. Up to 4 slots.
struct slot_metadata slot_info[4];
- /* Reserved for further use. */
+ // Reserved for further use.
uint8_t reserved1[8];
- /* CRC32 of all 28 bytes preceding this field (little endian
- * format). */
+ // CRC32 of all 28 bytes preceding this field (little endian
+ // format).
uint32_t crc32_le;
} __attribute__((packed));
+#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_control) ==
sizeof(((struct bootloader_message_ab *)0)->slot_suffix),
"struct bootloader_control has wrong size");
#endif
+#endif /* __UBOOT__ */
#ifndef __UBOOT__
-
#ifdef __cplusplus
#include <string>
#include <vector>
-/* Return the block device name for the bootloader message partition and waits
- * for the device for up to 10 seconds. In case of error returns the empty
- * string. */
+// Return the block device name for the bootloader message partition and waits
+// for the device for up to 10 seconds. In case of error returns the empty
+// string.
std::string get_bootloader_message_blk_device(std::string* err);
-/* Read bootloader message into boot. Error message will be set in err. */
+// Read bootloader message into boot. Error message will be set in err.
bool read_bootloader_message(bootloader_message* boot, std::string* err);
-/* Read bootloader message from the specified misc device into boot. */
+// Read bootloader message from the specified misc device into boot.
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
std::string* err);
-/* Write bootloader message to BCB. */
+// Write bootloader message to BCB.
bool write_bootloader_message(const bootloader_message& boot, std::string* err);
-/* Write bootloader message to the specified BCB device. */
+// Write bootloader message to the specified BCB device.
bool write_bootloader_message_to(const bootloader_message& boot,
const std::string& misc_blk_device, std::string* err);
-/* Write bootloader message (boots into recovery with the options) to BCB. Will
- * set the command and recovery fields, and reset the rest. */
+// Write bootloader message (boots into recovery with the options) to BCB. Will
+// set the command and recovery fields, and reset the rest.
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err);
-/* Write bootloader message (boots into recovery with the options) to the specific BCB device. Will
- * set the command and recovery fields, and reset the rest. */
+// Write bootloader message (boots into recovery with the options) to the specific BCB device. Will
+// set the command and recovery fields, and reset the rest.
bool write_bootloader_message_to(const std::vector<std::string>& options,
const std::string& misc_blk_device, std::string* err);
-/* Update bootloader message (boots into recovery with the options) to BCB. Will
- * only update the command and recovery fields. */
+// Update bootloader message (boots into recovery with the options) to BCB. Will
+// only update the command and recovery fields.
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
-/* Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
- * the command and recovery fields. */
+// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
+// the command and recovery fields.
bool update_bootloader_message_in_struct(bootloader_message* boot,
const std::vector<std::string>& options);
-/* Clear BCB. */
+// Clear BCB.
bool clear_bootloader_message(std::string* err);
-/* Writes the reboot-bootloader reboot reason to the bootloader_message. */
+// Writes the reboot-bootloader reboot reason to the bootloader_message.
bool write_reboot_bootloader(std::string* err);
-/* Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC). */
+// Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool read_wipe_package(std::string* package_data, size_t size, std::string* err);
-/* Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC). */
+// Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool write_wipe_package(const std::string& package_data, std::string* err);
#else
#include <stdbool.h>
-/* C Interface. */
+// C Interface.
bool write_bootloader_message(const char* options);
bool write_reboot_bootloader(void);
-#endif /* ifdef __cplusplus */
-
+#endif // ifdef __cplusplus
#endif /* __UBOOT__ */
#endif /* __ANDROID_BOOTLOADER_MESSAGE_H */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 418392875c..5056a084d2 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -69,6 +69,7 @@ enum uclass_id {
UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
UCLASS_PCH, /* x86 platform controller hub */
UCLASS_PCI, /* PCI bus */
+ UCLASS_PCI_EP, /* PCI endpoint device */
UCLASS_PCI_GENERIC, /* Generic PCI bus device */
UCLASS_PHY, /* Physical Layer (PHY) device */
UCLASS_PINCONFIG, /* Pin configuration node device */
diff --git a/include/image.h b/include/image.h
index bb7089ef5d..5f82194951 100644
--- a/include/image.h
+++ b/include/image.h
@@ -561,7 +561,7 @@ int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start,
#ifndef USE_HOSTCC
/* Image format types, returned by _get_format() routine */
#define IMAGE_FORMAT_INVALID 0x00
-#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
#endif
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
diff --git a/include/pci_ep.h b/include/pci_ep.h
new file mode 100644
index 0000000000..00e8c6d8ab
--- /dev/null
+++ b/include/pci_ep.h
@@ -0,0 +1,414 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Adapted from Linux kernel driver
+ * Copyright (C) 2017 Texas Instruments
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * (C) Copyright 2019
+ * Ramon Fried <ramon.fried@gmail.com>
+ */
+
+#ifndef _PCI_EP_H
+#define _PCI_EP_H
+
+#include <pci.h>
+
+/**
+ * enum pci_interrupt_pin - PCI INTx interrupt values
+ * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt
+ * @PCI_INTERRUPT_INTA: PCI INTA pin
+ * @PCI_INTERRUPT_INTB: PCI INTB pin
+ * @PCI_INTERRUPT_INTC: PCI INTC pin
+ * @PCI_INTERRUPT_INTD: PCI INTD pin
+ *
+ * Corresponds to values for legacy PCI INTx interrupts, as can be found in the
+ * PCI_INTERRUPT_PIN register.
+ */
+enum pci_interrupt_pin {
+ PCI_INTERRUPT_UNKNOWN,
+ PCI_INTERRUPT_INTA,
+ PCI_INTERRUPT_INTB,
+ PCI_INTERRUPT_INTC,
+ PCI_INTERRUPT_INTD,
+};
+
+enum pci_barno {
+ BAR_0,
+ BAR_1,
+ BAR_2,
+ BAR_3,
+ BAR_4,
+ BAR_5,
+};
+
+enum pci_ep_irq_type {
+ PCI_EP_IRQ_UNKNOWN,
+ PCI_EP_IRQ_LEGACY,
+ PCI_EP_IRQ_MSI,
+ PCI_EP_IRQ_MSIX,
+};
+
+/**
+ * struct pci_bar - represents the BAR (Base Address Register) of EP device
+ * @phys_addr: physical address that should be mapped to the BAR
+ * @size: the size of the address space present in BAR
+ * pci_barno: number of pci BAR to set (0..5)
+ * @flags: BAR access flags
+ */
+struct pci_bar {
+ dma_addr_t phys_addr;
+ size_t size;
+ enum pci_barno barno;
+ int flags;
+};
+
+/**
+ * struct pci_ep_header - represents standard configuration header
+ * @vendorid: identifies device manufacturer
+ * @deviceid: identifies a particular device
+ * @revid: specifies a device-specific revision identifier
+ * @progif_code: identifies a specific register-level programming interface
+ * @subclass_code: identifies more specifically the function of the device
+ * @baseclass_code: broadly classifies the type of function the device performs
+ * @cache_line_size: specifies the system cacheline size in units of DWORDs
+ * @subsys_vendor_id: vendor of the add-in card or subsystem
+ * @subsys_id: id specific to vendor
+ * @interrupt_pin: interrupt pin the device (or device function) uses
+ */
+struct pci_ep_header {
+ u16 vendorid;
+ u16 deviceid;
+ u8 revid;
+ u8 progif_code;
+ u8 subclass_code;
+ u8 baseclass_code;
+ u8 cache_line_size;
+ u16 subsys_vendor_id;
+ u16 subsys_id;
+ enum pci_interrupt_pin interrupt_pin;
+};
+
+/* PCI endpoint operations */
+struct pci_ep_ops {
+ /**
+ * write_header() - Write a PCI configuration space header
+ *
+ * @dev: device to write to
+ * @func_num: EP function to fill
+ * @hdr: header to write
+ * @return 0 if OK, -ve on error
+ */
+ int (*write_header)(struct udevice *dev, uint func_num,
+ struct pci_ep_header *hdr);
+ /**
+ * read_header() - Read a PCI configuration space header
+ *
+ * @dev: device to write to
+ * @func_num: EP function to fill
+ * @hdr: header to read to
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_header)(struct udevice *dev, uint func_num,
+ struct pci_ep_header *hdr);
+ /**
+ * set_bar() - Set BAR (Base Address Register) properties
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @bar: bar data
+ * @return 0 if OK, -ve on error
+ */
+ int (*set_bar)(struct udevice *dev, uint func_num,
+ struct pci_bar *bar);
+ /**
+ * read_bar() - Read BAR (Base Address Register) properties
+ *
+ * @dev: device to read
+ * @func_num: EP function to read
+ * @bar: struct to copy data to
+ * @barno: bar number to read
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_bar)(struct udevice *dev, uint func_num,
+ struct pci_bar *bar, enum pci_barno barno);
+ /**
+ * clear_bar() - clear BAR (Base Address Register)
+ *
+ * @dev: device to clear
+ * @func_num: EP function to clear
+ * @bar: bar number
+ * @return 0 if OK, -ve on error
+ */
+ int (*clear_bar)(struct udevice *dev, uint func_num,
+ enum pci_barno bar);
+ /**
+ * map_addr() - map CPU address to PCI address
+ *
+ * outband region is used in order to generate PCI read/write
+ * transaction from local memory/write.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @addr: local physical address base
+ * @pci_addr: pci address to translate to
+ * @size: region size
+ * @return 0 if OK, -ve on error
+ */
+ int (*map_addr)(struct udevice *dev, uint func_num,
+ phys_addr_t addr, u64 pci_addr, size_t size);
+ /**
+ * unmap_addr() - unmap CPU address to PCI address
+ *
+ * unmap previously mapped region.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @addr: local physical address base
+ * @return 0 if OK, -ve on error
+ */
+ int (*unmap_addr)(struct udevice *dev, uint func_num,
+ phys_addr_t addr);
+ /**
+ * set_msi() - set msi capability property
+ *
+ * set the number of required MSI vectors the device
+ * needs for operation.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @interrupts: required interrupts count
+ * @return 0 if OK, -ve on error
+ */
+ int (*set_msi)(struct udevice *dev, uint func_num, uint interrupts);
+
+ /**
+ * get_msi() - get the number of MSI interrupts allocated by the host.
+ *
+ * Read the Multiple Message Enable bitfield from
+ * Message control register.
+ *
+ * @dev: device to use
+ * @func_num: EP function to use
+ * @return msi count if OK, -EINVAL if msi were not enabled at host.
+ */
+ int (*get_msi)(struct udevice *dev, uint func_num);
+
+ /**
+ * set_msix() - set msix capability property
+ *
+ * set the number of required MSIx vectors the device
+ * needs for operation.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @interrupts: required interrupts count
+ * @return 0 if OK, -ve on error
+ */
+ int (*set_msix)(struct udevice *dev, uint func_num,
+ uint interrupts);
+
+ /**
+ * get_msix() - get the number of MSIx interrupts allocated by the host.
+ *
+ * Read the Multiple Message Enable bitfield from
+ * Message control register.
+ *
+ * @dev: device to use
+ * @func_num: EP function to use
+ * @return msi count if OK, -EINVAL if msi were not enabled at host.
+ */
+ int (*get_msix)(struct udevice *dev, uint func_num);
+
+ /**
+ * raise_irq() - raise a legacy, MSI or MSI-X interrupt
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @type: type of irq to send
+ * @interrupt_num: interrupt vector to use
+ * @return 0 if OK, -ve on error
+ */
+ int (*raise_irq)(struct udevice *dev, uint func_num,
+ enum pci_ep_irq_type type, uint interrupt_num);
+ /**
+ * start() - start the PCI link
+ *
+ * @dev: device to set
+ * @return 0 if OK, -ve on error
+ */
+ int (*start)(struct udevice *dev);
+
+ /**
+ * stop() - stop the PCI link
+ *
+ * @dev: device to set
+ * @return 0 if OK, -ve on error
+ */
+ int (*stop)(struct udevice *dev);
+};
+
+#define pci_ep_get_ops(dev) ((struct pci_ep_ops *)(dev)->driver->ops)
+
+/**
+ * pci_ep_write_header() - Write a PCI configuration space header
+ *
+ * @dev: device to write to
+ * @func_num: EP function to fill
+ * @hdr: header to write
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_write_header(struct udevice *dev, uint func_num,
+ struct pci_ep_header *hdr);
+
+/**
+ * dm_pci_ep_read_header() - Read a PCI configuration space header
+ *
+ * @dev: device to write to
+ * @func_num: EP function to fill
+ * @hdr: header to read to
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_read_header(struct udevice *dev, uint func_num,
+ struct pci_ep_header *hdr);
+/**
+ * pci_ep_set_bar() - Set BAR (Base Address Register) properties
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @bar: bar data
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_set_bar(struct udevice *dev, uint func_num, struct pci_bar *bar);
+
+/**
+ * pci_ep_read_bar() - Read BAR (Base Address Register) properties
+ *
+ * @dev: device to read
+ * @func_num: EP function to read
+ * @bar: struct to copy data to
+ * @barno: bar number to read
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_read_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar,
+ enum pci_barno barno);
+
+/**
+ * pci_ep_clear_bar() - Clear BAR (Base Address Register)
+ * mark the BAR as empty so host won't map it.
+ * @dev: device to clear
+ * @func_num: EP function to clear
+ * @bar: bar number
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_clear_bar(struct udevice *dev, uint func_num, enum pci_barno bar);
+/**
+ * pci_ep_map_addr() - map CPU address to PCI address
+ *
+ * outband region is used in order to generate PCI read/write
+ * transaction from local memory/write.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @addr: local physical address base
+ * @pci_addr: pci address to translate to
+ * @size: region size
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_map_addr(struct udevice *dev, uint func_num, phys_addr_t addr,
+ u64 pci_addr, size_t size);
+/**
+ * pci_ep_unmap_addr() - unmap CPU address to PCI address
+ *
+ * unmap previously mapped region.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @addr: local physical address base
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_unmap_addr(struct udevice *dev, uint func_num, phys_addr_t addr);
+
+/**
+ * pci_ep_set_msi() - set msi capability property
+ *
+ * set the number of required MSI vectors the device
+ * needs for operation.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @interrupts: required interrupts count
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_set_msi(struct udevice *dev, uint func_num, uint interrupts);
+
+/**
+ * pci_ep_get_msi() - get the number of MSI interrupts allocated by the host.
+ *
+ * Read the Multiple Message Enable bitfield from
+ * Message control register.
+ *
+ * @dev: device to use
+ * @func_num: EP function to use
+ * @return msi count if OK, -EINVAL if msi were not enabled at host.
+ */
+int pci_ep_get_msi(struct udevice *dev, uint func_num);
+
+/**
+ * pci_ep_set_msix() - set msi capability property
+ *
+ * set the number of required MSIx vectors the device
+ * needs for operation.
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @interrupts: required interrupts count
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_set_msix(struct udevice *dev, uint func_num, uint interrupts);
+
+/**
+ * pci_ep_get_msix() - get the number of MSIx interrupts allocated by the host.
+ *
+ * Read the Multiple Message Enable bitfield from
+ * Message control register.
+ *
+ * @dev: device to use
+ * @func_num: EP function to use
+ * @return msi count if OK, -EINVAL if msi were not enabled at host.
+ */
+int pci_ep_get_msix(struct udevice *dev, uint func_num);
+
+/**
+ * pci_ep_raise_irq() - raise a legacy, MSI or MSI-X interrupt
+ *
+ * @dev: device to set
+ * @func_num: EP function to set
+ * @type: type of irq to send
+ * @interrupt_num: interrupt vector to use
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_raise_irq(struct udevice *dev, uint func_num,
+ enum pci_ep_irq_type type, uint interrupt_num);
+/**
+ * pci_ep_start() - start the PCI link
+ *
+ * Enable PCI endpoint device and start link
+ * process.
+ *
+ * @dev: device to set
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_start(struct udevice *dev);
+
+/**
+ * pci_ep_stop() - stop the PCI link
+ *
+ * Disable PCI endpoint device and stop
+ * link.
+ *
+ * @dev: device to set
+ * @return 0 if OK, -ve on error
+ */
+int pci_ep_stop(struct udevice *dev);
+
+#endif
diff --git a/test/dm/Makefile b/test/dm/Makefile
index aeb3aa0ca7..420bf81154 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -31,6 +31,7 @@ obj-y += ofnode.o
obj-$(CONFIG_OSD) += osd.o
obj-$(CONFIG_DM_VIDEO) += panel.o
obj-$(CONFIG_DM_PCI) += pci.o
+obj-$(CONFIG_PCI_ENDPOINT) += pci_ep.o
obj-$(CONFIG_PCH) += pch.o
obj-$(CONFIG_PHY) += phy.o
obj-$(CONFIG_POWER_DOMAIN) += power-domain.o
diff --git a/test/dm/pci_ep.c b/test/dm/pci_ep.c
new file mode 100644
index 0000000000..101f861751
--- /dev/null
+++ b/test/dm/pci_ep.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Ramon Fried
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+#include <hexdump.h>
+#include <pci_ep.h>
+
+/* Test that sandbox PCI EP works correctly */
+static int dm_test_pci_ep_base(struct unit_test_state *uts)
+{
+ struct udevice *bus;
+ struct pci_bar tmp_bar;
+ struct pci_ep_header tmp_header;
+ int i;
+
+ struct pci_ep_header ep_header = {
+ .vendorid = 0x1234,
+ .deviceid = 0x2020,
+ .revid = 1,
+ .interrupt_pin = PCI_INTERRUPT_INTA,
+ };
+
+ struct pci_bar bar = {
+ .phys_addr = 0x80000000,
+ .size = 0x100000,
+ .barno = BAR_0,
+ .flags = PCI_BASE_ADDRESS_MEM_TYPE_64 |
+ PCI_BASE_ADDRESS_MEM_PREFETCH,
+ };
+
+ ut_assertok(uclass_get_device(UCLASS_PCI_EP, 0, &bus));
+ ut_assertnonnull(bus);
+
+ ut_assertok(pci_ep_write_header(bus, 0, &ep_header));
+ ut_assertok(pci_ep_read_header(bus, 0, &tmp_header));
+ ut_asserteq_mem(&tmp_header, &ep_header, sizeof(ep_header));
+
+ ut_assertok(pci_ep_set_msi(bus, 0, 4));
+ ut_asserteq(pci_ep_get_msi(bus, 0), 4);
+
+ ut_assertok(pci_ep_set_msix(bus, 0, 360));
+ ut_asserteq(pci_ep_get_msix(bus, 0), 360);
+
+ ut_assertok(pci_ep_set_bar(bus, 0, &bar));
+
+ ut_assertok(pci_ep_read_bar(bus, 0, &tmp_bar, BAR_0));
+ ut_asserteq_mem(&tmp_bar, &bar, sizeof(bar));
+
+ for (i = 0; i < 10; i++)
+ ut_assertok(pci_ep_raise_irq(bus, 0, 1, PCI_EP_IRQ_LEGACY));
+
+ ut_asserteq(sandbox_get_pci_ep_irq_count(bus), 10);
+ return 0;
+}
+
+DM_TEST(dm_test_pci_ep_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+