Merge tag 'v2021.04-rc4' into next
Prepare v2021.04-rc4
diff --git a/Makefile b/Makefile
index 3ebb38b..36b867a 100644
--- a/Makefile
+++ b/Makefile
@@ -1326,6 +1326,7 @@
# binman
# ---------------------------------------------------------------------------
# Use 'make BINMAN_DEBUG=1' to enable debugging
+# Use 'make BINMAN_VERBOSE=3' to set vebosity level
default_dt := $(if $(DEVICE_TREE),$(DEVICE_TREE),$(CONFIG_DEFAULT_DEVICE_TREE))
quiet_cmd_binman = BINMAN $@
cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
diff --git a/arch/Kconfig b/arch/Kconfig
index 27843cd..7023223 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -142,6 +142,8 @@
imply AVB_VERIFY
imply LIBAVB
imply CMD_AVB
+ imply SCP03
+ imply CMD_SCP03
imply UDP_FUNCTION_FASTBOOT
imply VIRTIO_MMIO
imply VIRTIO_PCI
diff --git a/arch/arc/lib/reset.c b/arch/arc/lib/reset.c
index fbb56ec..b8589d0 100644
--- a/arch/arc/lib/reset.c
+++ b/arch/arc/lib/reset.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <cpu_func.h>
-__weak void reset_cpu(ulong addr)
+__weak void reset_cpu(void)
{
/* Stop debug session here */
__builtin_arc_brk();
@@ -17,7 +17,7 @@
{
printf("Resetting the board...\n");
- reset_cpu(0);
+ reset_cpu();
return 0;
}
diff --git a/arch/arm/cpu/arm920t/ep93xx/cpu.c b/arch/arm/cpu/arm920t/ep93xx/cpu.c
index c9ea4e4..3435bdc 100644
--- a/arch/arm/cpu/arm920t/ep93xx/cpu.c
+++ b/arch/arm/cpu/arm920t/ep93xx/cpu.c
@@ -14,7 +14,7 @@
#include <asm/io.h>
/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */
-extern void reset_cpu(ulong addr)
+extern void reset_cpu(void)
{
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
uint32_t value;
diff --git a/arch/arm/cpu/arm920t/imx/timer.c b/arch/arm/cpu/arm920t/imx/timer.c
index e9d5577..0cd3a03 100644
--- a/arch/arm/cpu/arm920t/imx/timer.c
+++ b/arch/arm/cpu/arm920t/imx/timer.c
@@ -81,7 +81,7 @@
/*
* Reset the cpu by setting up the watchdog timer and let him time out
*/
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
/* Disable watchdog and set Time-Out field to 0 */
WCR = 0x00000000;
diff --git a/arch/arm/cpu/arm926ejs/armada100/timer.c b/arch/arm/cpu/arm926ejs/armada100/timer.c
index ec73393..6d77ad3 100644
--- a/arch/arm/cpu/arm926ejs/armada100/timer.c
+++ b/arch/arm/cpu/arm926ejs/armada100/timer.c
@@ -142,7 +142,7 @@
* 2. Write key value to TMP_WSAR reg.
* 3. Perform write operation.
*/
-void reset_cpu(unsigned long ignored)
+void reset_cpu(void)
{
struct armd1mpmu_registers *mpmu =
(struct armd1mpmu_registers *) ARMD1_MPMU_BASE;
diff --git a/arch/arm/cpu/arm926ejs/mx25/reset.c b/arch/arm/cpu/arm926ejs/mx25/reset.c
index 38df1c9..7844a99 100644
--- a/arch/arm/cpu/arm926ejs/mx25/reset.c
+++ b/arch/arm/cpu/arm926ejs/mx25/reset.c
@@ -23,7 +23,7 @@
/*
* Reset the cpu by setting up the watchdog timer and let it time out
*/
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE;
/* Disable watchdog and set Time-Out field to 0 */
diff --git a/arch/arm/cpu/arm926ejs/mx27/reset.c b/arch/arm/cpu/arm926ejs/mx27/reset.c
index 320b0a6..496fb30 100644
--- a/arch/arm/cpu/arm926ejs/mx27/reset.c
+++ b/arch/arm/cpu/arm926ejs/mx27/reset.c
@@ -23,7 +23,7 @@
/*
* Reset the cpu by setting up the watchdog timer and let it time out
*/
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE;
/* Disable watchdog and set Time-Out field to 0 */
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c
index c936213..344b9b4 100644
--- a/arch/arm/cpu/arm926ejs/mxs/mxs.c
+++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c
@@ -32,9 +32,9 @@
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */
__weak void lowlevel_init(void) {}
-void reset_cpu(ulong ignored) __attribute__((noreturn));
+void reset_cpu(void) __attribute__((noreturn));
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
struct mxs_rtc_regs *rtc_regs =
(struct mxs_rtc_regs *)MXS_RTC_BASE;
diff --git a/arch/arm/cpu/arm926ejs/spear/reset.c b/arch/arm/cpu/arm926ejs/spear/reset.c
index a316540..97a624e 100644
--- a/arch/arm/cpu/arm926ejs/spear/reset.c
+++ b/arch/arm/cpu/arm926ejs/spear/reset.c
@@ -11,7 +11,7 @@
#include <asm/arch/spr_syscntl.h>
#include <linux/delay.h>
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
struct syscntl_regs *syscntl_regs_p =
(struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE;
diff --git a/arch/arm/cpu/arm946es/cpu.c b/arch/arm/cpu/arm946es/cpu.c
index fb0ea5e..334bb54 100644
--- a/arch/arm/cpu/arm946es/cpu.c
+++ b/arch/arm/cpu/arm946es/cpu.c
@@ -56,7 +56,7 @@
#ifndef CONFIG_ARCH_INTEGRATOR
-__attribute__((noreturn)) void reset_cpu(ulong addr __attribute__((unused)))
+__attribute__((noreturn)) void reset_cpu(void)
{
writew(0x0, 0xfffece10);
writew(0x8, 0xfffece10);
diff --git a/arch/arm/cpu/armv7/bcm281xx/reset.c b/arch/arm/cpu/armv7/bcm281xx/reset.c
index fda5a95..1491e5c 100644
--- a/arch/arm/cpu/armv7/bcm281xx/reset.c
+++ b/arch/arm/cpu/armv7/bcm281xx/reset.c
@@ -13,7 +13,7 @@
#define CLKS_SHIFT 20 /* Clock period shift */
#define LD_SHIFT 0 /* Reload value shift */
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
/*
* Set WD enable, RST enable,
diff --git a/arch/arm/cpu/armv7/bcmcygnus/reset.c b/arch/arm/cpu/armv7/bcmcygnus/reset.c
index 3bfed34..63992fd 100644
--- a/arch/arm/cpu/armv7/bcmcygnus/reset.c
+++ b/arch/arm/cpu/armv7/bcmcygnus/reset.c
@@ -10,7 +10,7 @@
#define CRMU_MAIL_BOX1 0x03024028
#define CRMU_SOFT_RESET_CMD 0xFFFFFFFF
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
/* Send soft reset command via Mailbox. */
writel(CRMU_SOFT_RESET_CMD, CRMU_MAIL_BOX1);
diff --git a/arch/arm/cpu/armv7/bcmnsp/reset.c b/arch/arm/cpu/armv7/bcmnsp/reset.c
index 675f99f..a313775 100644
--- a/arch/arm/cpu/armv7/bcmnsp/reset.c
+++ b/arch/arm/cpu/armv7/bcmnsp/reset.c
@@ -9,7 +9,7 @@
#define CRU_RESET_OFFSET 0x1803F184
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
/* Reset the cpu by setting software reset request bit */
writel(0x1, CRU_RESET_OFFSET);
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 146cf52..19ff432 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -176,9 +176,6 @@
{
}
-void arm_init_domains(void)
-{
-}
#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c
index f26a5b2..d863c96 100644
--- a/arch/arm/cpu/armv7/ls102xa/cpu.c
+++ b/arch/arm/cpu/armv7/ls102xa/cpu.c
@@ -375,7 +375,7 @@
}
#endif
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
diff --git a/arch/arm/cpu/armv7/s5p4418/cpu.c b/arch/arm/cpu/armv7/s5p4418/cpu.c
index 3c71a37..3baa761 100644
--- a/arch/arm/cpu/armv7/s5p4418/cpu.c
+++ b/arch/arm/cpu/armv7/s5p4418/cpu.c
@@ -88,7 +88,7 @@
}
#endif
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
void *clkpwr_reg = (void *)PHY_BASEADDR_CLKPWR;
const u32 sw_rst_enb_bitpos = 3;
diff --git a/arch/arm/cpu/armv7/stv0991/reset.c b/arch/arm/cpu/armv7/stv0991/reset.c
index fb67de1..77d4477 100644
--- a/arch/arm/cpu/armv7/stv0991/reset.c
+++ b/arch/arm/cpu/armv7/stv0991/reset.c
@@ -9,7 +9,7 @@
#include <asm/io.h>
#include <asm/arch/stv0991_wdru.h>
#include <linux/delay.h>
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
puts("System is going to reboot ...\n");
/*
diff --git a/arch/arm/cpu/armv7m/cpu.c b/arch/arm/cpu/armv7m/cpu.c
index 7f827da..6372101 100644
--- a/arch/arm/cpu/armv7m/cpu.c
+++ b/arch/arm/cpu/armv7m/cpu.c
@@ -47,7 +47,7 @@
/*
* Perform the low-level reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/*
* Perform reset but keep priority group unchanged.
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 3a5bf77..270a72e 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -1231,7 +1231,7 @@
__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
-void __efi_runtime reset_cpu(ulong addr)
+void __efi_runtime reset_cpu(void)
{
#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
/* clear the RST_REQ_MSK and SW_RST_REQ */
@@ -1260,7 +1260,7 @@
case EFI_RESET_COLD:
case EFI_RESET_WARM:
case EFI_RESET_PLATFORM_SPECIFIC:
- reset_cpu(0);
+ reset_cpu();
break;
case EFI_RESET_SHUTDOWN:
/* Nothing we can do */
diff --git a/arch/arm/cpu/armv8/s32v234/generic.c b/arch/arm/cpu/armv8/s32v234/generic.c
index 0fc9885..d1ae10b 100644
--- a/arch/arm/cpu/armv8/s32v234/generic.c
+++ b/arch/arm/cpu/armv8/s32v234/generic.c
@@ -319,7 +319,7 @@
#define SRC_SCR_SW_RST (1<<12)
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
printf("Feature not supported.\n");
};
diff --git a/arch/arm/cpu/pxa/pxa2xx.c b/arch/arm/cpu/pxa/pxa2xx.c
index ea91d8a..c7efb67 100644
--- a/arch/arm/cpu/pxa/pxa2xx.c
+++ b/arch/arm/cpu/pxa/pxa2xx.c
@@ -267,9 +267,9 @@
writel(readl(CKEN) | CKEN14_I2C, CKEN);
}
-void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn));
+void __attribute__((weak)) reset_cpu(void) __attribute__((noreturn));
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
uint32_t tmp;
diff --git a/arch/arm/cpu/sa1100/cpu.c b/arch/arm/cpu/sa1100/cpu.c
index 91e100a..6f67f7f 100644
--- a/arch/arm/cpu/sa1100/cpu.c
+++ b/arch/arm/cpu/sa1100/cpu.c
@@ -55,7 +55,7 @@
#define RSRR 0x00
#define RCSR 0x04
-__attribute__((noreturn)) void reset_cpu(ulong addr __attribute__((unused)))
+__attribute__((noreturn)) void reset_cpu(void)
{
/* repeat endlessly */
while (1) {
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index c20e05e..b10edf8 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -35,7 +35,6 @@
void set_section_dcache(int section, enum dcache_option option);
void arm_init_before_mmu(void);
-void arm_init_domains(void);
void cpu_cache_initialization(void);
void dram_bank_mmu_setup(int bank);
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 5fe8369..11fceec 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -397,20 +397,6 @@
isb();
}
-static inline unsigned int get_dacr(void)
-{
- unsigned int val;
- asm("mrc p15, 0, %0, c3, c0, 0 @ get DACR" : "=r" (val) : : "cc");
- return val;
-}
-
-static inline void set_dacr(unsigned int val)
-{
- asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
- : : "r" (val) : "cc");
- isb();
-}
-
#ifdef CONFIG_ARMV7_LPAE
/* Long-Descriptor Translation Table Level 1/2 Bits */
#define TTB_SECT_XN_MASK (1ULL << 54)
@@ -475,7 +461,7 @@
#define TTB_SECT_XN_MASK (1 << 4)
#define TTB_SECT_C_MASK (1 << 3)
#define TTB_SECT_B_MASK (1 << 2)
-#define TTB_SECT (2 << 0)
+#define TTB_SECT (2 << 0)
/*
* Short-descriptor format memory region attributes, without TEX remap
@@ -489,7 +475,7 @@
*/
enum dcache_option {
DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT,
- DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
+ DCACHE_WRITETHROUGH = TTB_SECT_DOMAIN(0) | TTB_SECT | TTB_SECT_C_MASK,
DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
};
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 24050e5..aab1bf4 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -22,10 +22,6 @@
{
}
-__weak void arm_init_domains(void)
-{
-}
-
static void set_section_phys(int section, phys_addr_t phys,
enum dcache_option option)
{
@@ -203,11 +199,12 @@
asm volatile("mcr p15, 0, %0, c2, c0, 0"
: : "r" (gd->arch.tlb_addr) : "memory");
#endif
- /* Set the access control to all-supervisor */
+ /*
+ * initial value of Domain Access Control Register (DACR)
+ * Set the access control to client (1U) for each of the 16 domains
+ */
asm volatile("mcr p15, 0, %0, c3, c0, 0"
- : : "r" (~0));
-
- arm_init_domains();
+ : : "r" (0x55555555));
/* and enable the mmu */
reg = get_cr(); /* get control reg. */
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 05bb1a3..6dc27d1 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -53,7 +53,7 @@
void bad_mode (void)
{
panic ("Resetting CPU ...\n");
- reset_cpu(0);
+ reset_cpu();
}
static void show_efi_loaded_images(struct pt_regs *regs)
diff --git a/arch/arm/lib/interrupts_m.c b/arch/arm/lib/interrupts_m.c
index 2ae1c5b..277854a 100644
--- a/arch/arm/lib/interrupts_m.c
+++ b/arch/arm/lib/interrupts_m.c
@@ -59,7 +59,7 @@
void bad_mode(void)
{
panic("Resetting CPU ...\n");
- reset_cpu(0);
+ reset_cpu();
}
void do_hard_fault(struct autosave_regs *autosave_regs)
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c
index 4f1a768..95169ba 100644
--- a/arch/arm/lib/reset.c
+++ b/arch/arm/lib/reset.c
@@ -39,7 +39,7 @@
disable_interrupts();
reset_misc();
- reset_cpu(0);
+ reset_cpu();
/*NOTREACHED*/
return 0;
diff --git a/arch/arm/mach-at91/arm920t/reset.c b/arch/arm/mach-at91/arm920t/reset.c
index d92bc57..91e3751 100644
--- a/arch/arm/mach-at91/arm920t/reset.c
+++ b/arch/arm/mach-at91/arm920t/reset.c
@@ -24,7 +24,7 @@
/* true empty function for defining weak symbol */
}
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
at91_st_t *st = (at91_st_t *) ATMEL_BASE_ST;
diff --git a/arch/arm/mach-at91/arm926ejs/reset.c b/arch/arm/mach-at91/arm926ejs/reset.c
index 56fbbd9..6acbfa3 100644
--- a/arch/arm/mach-at91/arm926ejs/reset.c
+++ b/arch/arm/mach-at91/arm926ejs/reset.c
@@ -12,7 +12,7 @@
#include <asm/arch/at91_rstc.h>
/* Reset the cpu by telling the reset controller to do so */
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
at91_rstc_t *rstc = (at91_rstc_t *) ATMEL_BASE_RSTC;
diff --git a/arch/arm/mach-at91/armv7/reset.c b/arch/arm/mach-at91/armv7/reset.c
index 8f4c81d..1ea415e 100644
--- a/arch/arm/mach-at91/armv7/reset.c
+++ b/arch/arm/mach-at91/armv7/reset.c
@@ -15,7 +15,7 @@
#include <asm/arch/at91_rstc.h>
/* Reset the cpu by telling the reset controller to do so */
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC;
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c
index 2b4ccd4..f13ac0c 100644
--- a/arch/arm/mach-bcm283x/reset.c
+++ b/arch/arm/mach-bcm283x/reset.c
@@ -48,7 +48,7 @@
writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc);
}
-void reset_cpu(ulong ticks)
+void reset_cpu(void)
{
struct bcm2835_wdog_regs *regs =
(struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
diff --git a/arch/arm/mach-davinci/reset.c b/arch/arm/mach-davinci/reset.c
index 4e6031a..0d59eb6 100644
--- a/arch/arm/mach-davinci/reset.c
+++ b/arch/arm/mach-davinci/reset.c
@@ -12,7 +12,7 @@
#include <asm/arch/timer_defs.h>
#include <asm/arch/hardware.h>
-void reset_cpu(unsigned long a)
+void reset_cpu(void)
{
struct davinci_timer *const wdttimer =
(struct davinci_timer *)DAVINCI_WDOG_BASE;
diff --git a/arch/arm/mach-exynos/soc.c b/arch/arm/mach-exynos/soc.c
index 810fa34..a07c87a 100644
--- a/arch/arm/mach-exynos/soc.c
+++ b/arch/arm/mach-exynos/soc.c
@@ -20,7 +20,7 @@
void *secondary_boot_addr = (void *)_main;
#endif /* CONFIG_TARGET_ESPRESSO7420 */
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
#ifdef CONFIG_CPU_V7A
writel(0x1, samsung_get_base_swreset());
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 5f37282..e6bc977 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -923,7 +923,7 @@
#endif
#if !CONFIG_IS_ENABLED(SYSRESET)
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
diff --git a/arch/arm/mach-imx/mx7ulp/soc.c b/arch/arm/mach-imx/mx7ulp/soc.c
index 8dd6b4d..320f24d 100644
--- a/arch/arm/mach-imx/mx7ulp/soc.c
+++ b/arch/arm/mach-imx/mx7ulp/soc.c
@@ -197,7 +197,7 @@
#endif
#ifndef CONFIG_ULP_WATCHDOG
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
setbits_le32(SIM0_RBASE, SIM_SOPT1_A7_SW_RESET);
while (1)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 4fbf148..9191f68 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -320,7 +320,7 @@
#endif
#ifndef CONFIG_SYSRESET
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
}
#endif
diff --git a/arch/arm/mach-keystone/ddr3.c b/arch/arm/mach-keystone/ddr3.c
index 7dea600..9ee3284 100644
--- a/arch/arm/mach-keystone/ddr3.c
+++ b/arch/arm/mach-keystone/ddr3.c
@@ -345,7 +345,7 @@
if (!ecc_test) {
puts("Reseting the device ...\n");
- reset_cpu(0);
+ reset_cpu();
}
}
@@ -445,7 +445,7 @@
tmp &= ~KS2_RSTYPE_PLL_SOFT;
__raw_writel(tmp, KS2_RSTCTRL_RSCFG);
- reset_cpu(0);
+ reset_cpu();
}
}
#endif
diff --git a/arch/arm/mach-keystone/init.c b/arch/arm/mach-keystone/init.c
index 4950f14..5b95f60 100644
--- a/arch/arm/mach-keystone/init.c
+++ b/arch/arm/mach-keystone/init.c
@@ -192,7 +192,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
volatile u32 *rstctrl = (volatile u32 *)(KS2_RSTCTRL);
u32 tmp;
diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c
index 551c22a..9c818fa 100644
--- a/arch/arm/mach-kirkwood/cpu.c
+++ b/arch/arm/mach-kirkwood/cpu.c
@@ -19,7 +19,7 @@
#include <asm/arch/soc.h>
#include <mvebu_mmc.h>
-void reset_cpu(unsigned long ignored)
+void reset_cpu(void)
{
struct kwcpu_registers *cpureg =
(struct kwcpu_registers *)KW_CPU_REG_BASE;
diff --git a/arch/arm/mach-lpc32xx/cpu.c b/arch/arm/mach-lpc32xx/cpu.c
index 32af620..c2586d0 100644
--- a/arch/arm/mach-lpc32xx/cpu.c
+++ b/arch/arm/mach-lpc32xx/cpu.c
@@ -17,28 +17,17 @@
static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE;
static struct wdt_regs *wdt = (struct wdt_regs *)WDT_BASE;
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* Enable watchdog clock */
setbits_le32(&clk->timclk_ctrl, CLK_TIMCLK_WATCHDOG);
- /* To be compatible with the original U-Boot code:
- * addr: - 0: perform hard reset.
- * - !=0: perform a soft reset; i.e. "RESOUT_N" not asserted). */
- if (addr == 0) {
- /* Reset pulse length is 13005 peripheral clock frames */
- writel(13000, &wdt->pulse);
+ /* Reset pulse length is 13005 peripheral clock frames */
+ writel(13000, &wdt->pulse);
- /* Force WDOG_RESET2 and RESOUT_N signal active */
- writel(WDTIM_MCTRL_RESFRC2 | WDTIM_MCTRL_RESFRC1
- | WDTIM_MCTRL_M_RES2, &wdt->mctrl);
- } else {
- /* Force match output active */
- writel(0x01, &wdt->emr);
-
- /* Internal reset on match output (no pulse on "RESOUT_N") */
- writel(WDTIM_MCTRL_M_RES1, &wdt->mctrl);
- }
+ /* Force WDOG_RESET2 and RESOUT_N signal active */
+ writel(WDTIM_MCTRL_RESFRC2 | WDTIM_MCTRL_RESFRC1 | WDTIM_MCTRL_M_RES2,
+ &wdt->mctrl);
while (1)
/* NOP */;
diff --git a/arch/arm/mach-mediatek/mt7622/init.c b/arch/arm/mach-mediatek/mt7622/init.c
index 7f6ce80..e501907 100644
--- a/arch/arm/mach-mediatek/mt7622/init.c
+++ b/arch/arm/mach-mediatek/mt7622/init.c
@@ -27,7 +27,7 @@
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-mediatek/mt8512/init.c b/arch/arm/mach-mediatek/mt8512/init.c
index c14e7d2..b7050df 100644
--- a/arch/arm/mach-mediatek/mt8512/init.c
+++ b/arch/arm/mach-mediatek/mt8512/init.c
@@ -43,7 +43,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *watchdog_dev = NULL;
diff --git a/arch/arm/mach-mediatek/mt8516/init.c b/arch/arm/mach-mediatek/mt8516/init.c
index 3771152..3460dcc 100644
--- a/arch/arm/mach-mediatek/mt8516/init.c
+++ b/arch/arm/mach-mediatek/mt8516/init.c
@@ -85,7 +85,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-mediatek/mt8518/init.c b/arch/arm/mach-mediatek/mt8518/init.c
index 28b00c3..f7e03de 100644
--- a/arch/arm/mach-mediatek/mt8518/init.c
+++ b/arch/arm/mach-mediatek/mt8518/init.c
@@ -42,7 +42,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-meson/board-common.c b/arch/arm/mach-meson/board-common.c
index 34b3c8f..1690b6b 100644
--- a/arch/arm/mach-meson/board-common.c
+++ b/arch/arm/mach-meson/board-common.c
@@ -167,7 +167,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct pt_regs regs;
@@ -182,7 +182,7 @@
;
}
#else
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c
index 70f76c7..0cf60d7 100644
--- a/arch/arm/mach-mvebu/armada3700/cpu.c
+++ b/arch/arm/mach-mvebu/armada3700/cpu.c
@@ -314,7 +314,7 @@
return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len);
}
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
/*
* Write magic number of 0x1d1e to North Bridge Warm Reset register
diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c
index 529dac9..474327a 100644
--- a/arch/arm/mach-mvebu/armada8k/cpu.c
+++ b/arch/arm/mach-mvebu/armada8k/cpu.c
@@ -104,7 +104,7 @@
dcache_enable();
}
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
u32 reg;
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 7dce11e..0b935c4 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -42,7 +42,7 @@
*/
}
-void reset_cpu(unsigned long ignored)
+void reset_cpu(void)
{
struct mvebu_system_registers *reg =
(struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE;
diff --git a/arch/arm/mach-nexell/Makefile b/arch/arm/mach-nexell/Makefile
index 10b3963..dda16db 100644
--- a/arch/arm/mach-nexell/Makefile
+++ b/arch/arm/mach-nexell/Makefile
@@ -10,4 +10,3 @@
obj-y += tieoff.o
obj-$(CONFIG_ARCH_S5P4418) += reg-call.o
obj-$(CONFIG_ARCH_S5P4418) += nx_sec_reg.o
-obj-$(CONFIG_CMD_BOOTL) += cmd_boot_linux.o
diff --git a/arch/arm/mach-nexell/cmd_boot_linux.c b/arch/arm/mach-nexell/cmd_boot_linux.c
deleted file mode 100644
index 9b38d38..0000000
--- a/arch/arm/mach-nexell/cmd_boot_linux.c
+++ /dev/null
@@ -1,145 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2016 nexell
- * jhkim <jhkim@nexell.co.kr>
- */
-
-#include <common.h>
-#include <bootm.h>
-#include <command.h>
-#include <environment.h>
-#include <errno.h>
-#include <image.h>
-#include <fdt_support.h>
-#include <asm/global_data.h>
-
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_CLI_FRAMEWORK)
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static bootm_headers_t linux_images;
-
-static void boot_go_set_os(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[],
- bootm_headers_t *images)
-{
- char * const img_addr = argv[0];
-
- images->os.type = IH_TYPE_KERNEL;
- images->os.comp = IH_COMP_NONE;
- images->os.os = IH_OS_LINUX;
- images->os.load = simple_strtoul(img_addr, NULL, 16);
- images->ep = images->os.load;
-#if defined(CONFIG_ARM)
- images->os.arch = IH_ARCH_ARM;
-#elif defined(CONFIG_ARM64)
- images->os.arch = IH_ARCH_ARM64;
-#else
- #error "Not support architecture ..."
-#endif
- if (!IS_ENABLED(CONFIG_OF_LIBFDT) && !IS_ENABLED(CONFIG_SPL_BUILD)) {
- /* set DTB address for linux kernel */
- if (argc > 2) {
- unsigned long ft_addr;
-
- ft_addr = simple_strtol(argv[2], NULL, 16);
- images->ft_addr = (char *)ft_addr;
-
- /*
- * if not defined IMAGE_ENABLE_OF_LIBFDT,
- * must be set to fdt address
- */
- if (!IMAGE_ENABLE_OF_LIBFDT)
- gd->bd->bi_boot_params = ft_addr;
-
- debug("## set ft:%08lx and boot params:%08lx [control of:%s]"
- "...\n", ft_addr, gd->bd->bi_boot_params,
- IMAGE_ENABLE_OF_LIBFDT ? "on" : "off");
- }
- }
-}
-
-#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
-static void boot_start_lmb(bootm_headers_t *images)
-{
- ulong mem_start;
- phys_size_t mem_size;
-
- lmb_init(&images->lmb);
-
- mem_start = getenv_bootm_low();
- mem_size = getenv_bootm_size();
-
- lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
-
- arch_lmb_reserve(&images->lmb);
- board_lmb_reserve(&images->lmb);
-}
-#else
-#define lmb_reserve(lmb, base, size)
-static inline void boot_start_lmb(bootm_headers_t *images) { }
-#endif
-
-int do_boot_linux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- boot_os_fn *boot_fn;
- bootm_headers_t *images = &linux_images;
- int flags;
- int ret;
-
- boot_start_lmb(images);
-
- flags = BOOTM_STATE_START;
-
- argc--; argv++;
- boot_go_set_os(cmdtp, flag, argc, argv, images);
-
- if (IS_ENABLED(CONFIG_OF_LIBFDT)) {
- /* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images,
- &images->ft_addr, &images->ft_len);
- if (ret) {
- puts("Could not find a valid device tree\n");
- return 1;
- }
- set_working_fdt_addr((ulong)images->ft_addr);
- }
-
- if (!IS_ENABLED(CONFIG_OF_LIBFDT))
- flags |= BOOTM_STATE_OS_GO;
-
- boot_fn = do_bootm_linux;
- ret = boot_fn(flags, argc, argv, images);
-
- if (ret == BOOTM_ERR_UNIMPLEMENTED)
- show_boot_progress(BOOTSTAGE_ID_DECOMP_UNIMPL);
- else if (ret == BOOTM_ERR_RESET)
- do_reset(cmdtp, flag, argc, argv);
-
- return ret;
-}
-
-U_BOOT_CMD(bootl, CONFIG_SYS_MAXARGS, 1, do_boot_linux,
- "boot linux image from memory",
- "[addr [arg ...]]\n - boot linux image stored in memory\n"
- "\tuse a '-' for the DTB address\n"
-);
-#endif
-
-#if defined(CONFIG_CMD_BOOTD) && !defined(CONFIG_CMD_BOOTM)
-int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- return run_command(env_get("bootcmd"), flag);
-}
-
-U_BOOT_CMD(boot, 1, 1, do_bootd,
- "boot default, i.e., run 'bootcmd'",
- ""
-);
-
-/* keep old command name "bootd" for backward compatibility */
-U_BOOT_CMD(bootd, 1, 1, do_bootd,
- "boot default, i.e., run 'bootcmd'",
- ""
-);
-#endif
diff --git a/arch/arm/mach-octeontx/cpu.c b/arch/arm/mach-octeontx/cpu.c
index ce5f2b4..7bd74fe 100644
--- a/arch/arm/mach-octeontx/cpu.c
+++ b/arch/arm/mach-octeontx/cpu.c
@@ -72,6 +72,6 @@
return 0x80000;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/arch/arm/mach-octeontx2/cpu.c b/arch/arm/mach-octeontx2/cpu.c
index 8786815..afa458c 100644
--- a/arch/arm/mach-octeontx2/cpu.c
+++ b/arch/arm/mach-octeontx2/cpu.c
@@ -68,6 +68,6 @@
return 0x80000;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/arch/arm/mach-omap2/omap-cache.c b/arch/arm/mach-omap2/omap-cache.c
index 1b246f8..36db588 100644
--- a/arch/arm/mach-omap2/omap-cache.c
+++ b/arch/arm/mach-omap2/omap-cache.c
@@ -41,9 +41,6 @@
#define ARMV7_DCACHE_POLICY DCACHE_WRITEBACK & ~TTB_SECT_XN_MASK
#endif
-#define ARMV7_DOMAIN_CLIENT 1
-#define ARMV7_DOMAIN_MASK (0x3 << 0)
-
void enable_caches(void)
{
@@ -67,17 +64,3 @@
for (i = start; i < end; i++)
set_section_dcache(i, ARMV7_DCACHE_POLICY);
}
-
-void arm_init_domains(void)
-{
- u32 reg;
-
- reg = get_dacr();
- /*
- * Set DOMAIN to client access so that all permissions
- * set in pagetables are validated by the mmu.
- */
- reg &= ~ARMV7_DOMAIN_MASK;
- reg |= ARMV7_DOMAIN_CLIENT;
- set_dacr(reg);
-}
diff --git a/arch/arm/mach-omap2/omap5/hwinit.c b/arch/arm/mach-omap2/omap5/hwinit.c
index 47ac865..edab9a9 100644
--- a/arch/arm/mach-omap2/omap5/hwinit.c
+++ b/arch/arm/mach-omap2/omap5/hwinit.c
@@ -417,7 +417,7 @@
die_id[3] = readl((*ctrl)->control_std_fuse_die_id_3);
}
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
u32 omap_rev = omap_revision();
diff --git a/arch/arm/mach-omap2/reset.c b/arch/arm/mach-omap2/reset.c
index 2bbd5fc..1fd79c2 100644
--- a/arch/arm/mach-omap2/reset.c
+++ b/arch/arm/mach-omap2/reset.c
@@ -14,7 +14,7 @@
#include <asm/arch/cpu.h>
#include <linux/compiler.h>
-void __weak reset_cpu(unsigned long ignored)
+void __weak reset_cpu(void)
{
writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
}
diff --git a/arch/arm/mach-orion5x/cpu.c b/arch/arm/mach-orion5x/cpu.c
index beae7b8..ffae9a0 100644
--- a/arch/arm/mach-orion5x/cpu.c
+++ b/arch/arm/mach-orion5x/cpu.c
@@ -20,7 +20,7 @@
#define BUFLEN 16
-void reset_cpu(unsigned long ignored)
+void reset_cpu(void)
{
struct orion5x_cpu_registers *cpureg =
(struct orion5x_cpu_registers *)ORION5X_CPU_REG_BASE;
diff --git a/arch/arm/mach-owl/soc.c b/arch/arm/mach-owl/soc.c
index 4d2b9d0..4baef2e 100644
--- a/arch/arm/mach-owl/soc.c
+++ b/arch/arm/mach-owl/soc.c
@@ -74,7 +74,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h
index 8c25325..1d68034 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h
@@ -8,7 +8,7 @@
phys_addr_t socfpga_get_rstmgr_addr(void);
-void reset_cpu(ulong addr);
+void reset_cpu(void);
void socfpga_per_reset(u32 reset, int set);
void socfpga_per_reset_all(void);
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index bc2db53..897ec13 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -212,6 +212,35 @@
}
/*
+ * weak function overidde: set the DDR/SYSRAM executable before to enable the
+ * MMU and configure DACR, for early early_enable_caches (SPL or pre-reloc)
+ */
+void dram_bank_mmu_setup(int bank)
+{
+ struct bd_info *bd = gd->bd;
+ int i;
+ phys_addr_t start;
+ phys_size_t size;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD)) {
+ start = ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE);
+ size = ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE);
+ } else if (gd->flags & GD_FLG_RELOC) {
+ /* bd->bi_dram is available only after relocation */
+ start = bd->bi_dram[bank].start;
+ size = bd->bi_dram[bank].size;
+ } else {
+ /* mark cacheable and executable the beggining of the DDR */
+ start = STM32_DDR_BASE;
+ size = CONFIG_DDR_CACHEABLE_SIZE;
+ }
+
+ for (i = start >> MMU_SECTION_SHIFT;
+ i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT);
+ i++)
+ set_section_dcache(i, DCACHE_DEFAULT_OPTION);
+}
+/*
* initialize the MMU and activate cache in SPL or in U-Boot pre-reloc stage
* MMU/TLB is updated in enable_caches() for U-Boot after relocation
* or is deactivated in U-Boot entry function start.S::cpu_init_cp15
@@ -228,17 +257,8 @@
gd->arch.tlb_addr = (unsigned long)&early_tlb;
}
+ /* enable MMU (default configuration) */
dcache_enable();
-
- if (IS_ENABLED(CONFIG_SPL_BUILD))
- mmu_set_region_dcache_behaviour(
- ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE),
- ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE),
- DCACHE_DEFAULT_OPTION);
- else
- mmu_set_region_dcache_behaviour(STM32_DDR_BASE,
- CONFIG_DDR_CACHEABLE_SIZE,
- DCACHE_DEFAULT_OPTION);
}
/*
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index ad6977f..66e81ba 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -13,6 +13,7 @@
#include <log.h>
#include <ram.h>
#include <asm/global_data.h>
+#include <asm/system.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -41,6 +42,7 @@
ulong board_get_usable_ram_top(ulong total_size)
{
+ phys_size_t size;
phys_addr_t reg;
struct lmb lmb;
@@ -48,10 +50,13 @@
lmb_init(&lmb);
lmb_add(&lmb, gd->ram_base, gd->ram_size);
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
- reg = lmb_alloc(&lmb, CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K);
+ size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE),
+ reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
- if (reg)
- return ALIGN(reg + CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K);
+ if (!reg)
+ reg = gd->ram_top - size;
- return gd->ram_top;
+ mmu_set_region_dcache_behaviour(reg, size, DCACHE_DEFAULT_OPTION);
+
+ return reg + size;
}
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 0135575..a29d115 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -816,13 +816,14 @@
depends on !MACH_SUN9I
depends on !MACH_SUN50I
depends on !SUN50I_GEN_H6
- select VIDEO
+ select DM_VIDEO
+ select DISPLAY
imply VIDEO_DT_SIMPLEFB
default y
---help---
- Say Y here to add support for using a cfb console on the HDMI, LCD
- or VGA output found on most sunxi devices. See doc/README.video for
- info on how to select the video output and mode.
+ Say Y here to add support for using a graphical console on the HDMI,
+ LCD or VGA output found on older sunxi devices. This will also provide
+ a simple_framebuffer device for Linux.
config VIDEO_HDMI
bool "HDMI output support"
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index fa2b6fc..503538e 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -338,7 +338,7 @@
}
#endif
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
#if defined(CONFIG_SUNXI_GEN_SUN4I) || defined(CONFIG_MACH_SUN8I_R40)
static const struct sunxi_wdog *wdog =
diff --git a/arch/arm/mach-tegra/cmd_enterrcm.c b/arch/arm/mach-tegra/cmd_enterrcm.c
index 25df31a..92ff6cb 100644
--- a/arch/arm/mach-tegra/cmd_enterrcm.c
+++ b/arch/arm/mach-tegra/cmd_enterrcm.c
@@ -40,7 +40,7 @@
tegra_pmc_writel(2, PMC_SCRATCH0);
disable_interrupts();
- reset_cpu(0);
+ reset_cpu();
return 0;
}
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index 93db63e..8d617be 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -85,7 +85,7 @@
writel(value, NV_PA_PMC_BASE + offset);
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
u32 value;
diff --git a/arch/arm/mach-uniphier/arm32/psci.c b/arch/arm/mach-uniphier/arm32/psci.c
index a4d260a..fbb6ebc 100644
--- a/arch/arm/mach-uniphier/arm32/psci.c
+++ b/arch/arm/mach-uniphier/arm32/psci.c
@@ -158,5 +158,5 @@
void __secure psci_system_reset(void)
{
- reset_cpu(0);
+ reset_cpu();
}
diff --git a/arch/arm/mach-uniphier/reset.c b/arch/arm/mach-uniphier/reset.c
index 5fffd23..dddb48e 100644
--- a/arch/arm/mach-uniphier/reset.c
+++ b/arch/arm/mach-uniphier/reset.c
@@ -18,7 +18,7 @@
#define __SECURE
#endif
-void __SECURE reset_cpu(unsigned long ignored)
+void __SECURE reset_cpu(void)
{
u32 tmp;
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index 3befc12..69b818f 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -78,7 +78,7 @@
>> ZYNQ_SILICON_VER_SHIFT;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
zynq_slcr_cpu_reset();
while (1)
diff --git a/arch/arm/mach-zynqmp-r5/cpu.c b/arch/arm/mach-zynqmp-r5/cpu.c
index d841c3a..0d36844 100644
--- a/arch/arm/mach-zynqmp-r5/cpu.c
+++ b/arch/arm/mach-zynqmp-r5/cpu.c
@@ -30,7 +30,7 @@
/*
* Perform the low-level reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
while (1)
;
diff --git a/arch/nds32/cpu/n1213/ag101/cpu.c b/arch/nds32/cpu/n1213/ag101/cpu.c
index 9d99c83..91c3574 100644
--- a/arch/nds32/cpu/n1213/ag101/cpu.c
+++ b/arch/nds32/cpu/n1213/ag101/cpu.c
@@ -46,7 +46,7 @@
/*
* reset to the base addr of andesboot.
* currently no ROM loader at addr 0.
- * do not use reset_cpu(0);
+ * do not use reset_cpu();
*/
#ifdef CONFIG_FTWDT010_WATCHDOG
/*
diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S
index 386c199..3395721 100644
--- a/arch/nds32/cpu/n1213/start.S
+++ b/arch/nds32/cpu/n1213/start.S
@@ -500,25 +500,3 @@
bal do_interruption
.align 5
-
-/*
- * void reset_cpu(ulong addr);
- * $r0: input address to jump to
- */
-.globl reset_cpu
-reset_cpu:
-/* No need to disable MMU because we never enable it */
-
- bal invalidate_icac
- bal invalidate_dcac
- mfsr $p0, $MMU_CFG
- andi $p0, $p0, 0x3 ! MMPS
- li $p1, 0x2 ! TLB MMU
- bne $p0, $p1, 1f
- tlbop flushall ! Flush TLB
-1:
- mfsr $p0, MR_CAC_CTL ! Get the $CACHE_CTL reg
- li $p1, DIS_DCAC
- and $p0, $p0, $p1 ! Clear the DC_EN bit
- mtsr $p0, MR_CAC_CTL ! Write back the $CACHE_CTL reg
- br $r0 ! Jump to the input address
diff --git a/arch/nds32/lib/interrupts.c b/arch/nds32/lib/interrupts.c
index 1481e05..0ec72d1 100644
--- a/arch/nds32/lib/interrupts.c
+++ b/arch/nds32/lib/interrupts.c
@@ -66,7 +66,7 @@
void bad_mode(void)
{
panic("Resetting CPU ...\n");
- reset_cpu(0);
+ reset_cpu();
}
void show_regs(struct pt_regs *regs)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 3d8af0a..2d9583c 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -153,7 +153,7 @@
printf("Cannot seek to start of file '%s'\n", fname);
goto err;
}
- *bufp = malloc(size);
+ *bufp = os_malloc(size);
if (!*bufp) {
printf("Not enough memory to read file '%s'\n", fname);
ret = -ENOMEM;
@@ -267,11 +267,18 @@
signal(SIGINT, os_sigint_handler);
}
+/*
+ * Provide our own malloc so we don't use space in the sandbox ram_buf for
+ * allocations that are internal to sandbox, or need to be done before U-Boot's
+ * malloc() is ready.
+ */
void *os_malloc(size_t length)
{
int page_size = getpagesize();
struct os_mem_hdr *hdr;
+ if (!length)
+ return NULL;
/*
* Use an address that is hopefully available to us so that pointers
* to this memory are fairly obvious. If we end up with a different
@@ -298,6 +305,47 @@
}
}
+/* These macros are from kernel.h but not accessible in this file */
+#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1)
+#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+/*
+ * Provide our own malloc so we don't use space in the sandbox ram_buf for
+ * allocations that are internal to sandbox, or need to be done before U-Boot's
+ * malloc() is ready.
+ */
+void *os_realloc(void *ptr, size_t length)
+{
+ int page_size = getpagesize();
+ struct os_mem_hdr *hdr;
+ void *new_ptr;
+
+ /* Reallocating a NULL pointer is just an alloc */
+ if (!ptr)
+ return os_malloc(length);
+
+ /* Changing a length to 0 is just a free */
+ if (length) {
+ os_free(ptr);
+ return NULL;
+ }
+
+ /*
+ * If the new size is the same number of pages as the old, nothing to
+ * do. There isn't much point in shrinking things
+ */
+ hdr = ptr - page_size;
+ if (ALIGN(length, page_size) <= ALIGN(hdr->length, page_size))
+ return ptr;
+
+ /* We have to grow it, so allocate something new */
+ new_ptr = os_malloc(length);
+ memcpy(new_ptr, ptr, hdr->length);
+ os_free(ptr);
+
+ return new_ptr;
+}
+
void os_usleep(unsigned long usec)
{
usleep(usec);
@@ -343,8 +391,8 @@
state->argv = argv;
/* dynamically construct the arguments to the system getopt_long */
- short_opts = malloc(sizeof(*short_opts) * num_options * 2 + 1);
- long_opts = malloc(sizeof(*long_opts) * (num_options + 1));
+ short_opts = os_malloc(sizeof(*short_opts) * num_options * 2 + 1);
+ long_opts = os_malloc(sizeof(*long_opts) * (num_options + 1));
if (!short_opts || !long_opts)
return 1;
@@ -423,7 +471,7 @@
while (node) {
next = node->next;
- free(node);
+ os_free(node);
node = next;
}
}
@@ -448,7 +496,7 @@
/* Create a buffer upfront, with typically sufficient size */
dirlen = strlen(dirname) + 2;
len = dirlen + 256;
- fname = malloc(len);
+ fname = os_malloc(len);
if (!fname) {
ret = -ENOMEM;
goto done;
@@ -461,7 +509,7 @@
ret = errno;
break;
}
- next = malloc(sizeof(*node) + strlen(entry->d_name) + 1);
+ next = os_malloc(sizeof(*node) + strlen(entry->d_name) + 1);
if (!next) {
os_dirent_free(head);
ret = -ENOMEM;
@@ -470,10 +518,10 @@
if (dirlen + strlen(entry->d_name) > len) {
len = dirlen + strlen(entry->d_name);
old_fname = fname;
- fname = realloc(fname, len);
+ fname = os_realloc(fname, len);
if (!fname) {
- free(old_fname);
- free(next);
+ os_free(old_fname);
+ os_free(next);
os_dirent_free(head);
ret = -ENOMEM;
goto done;
@@ -507,7 +555,7 @@
done:
closedir(dir);
- free(fname);
+ os_free(fname);
return ret;
}
@@ -624,7 +672,7 @@
for (argc = 0; (*argvp)[argc]; argc++)
;
- argv = malloc((argc + count + 1) * sizeof(char *));
+ argv = os_malloc((argc + count + 1) * sizeof(char *));
if (!argv) {
printf("Out of memory for %d argv\n", count);
return -ENOMEM;
@@ -707,7 +755,7 @@
os_exit(2);
err = execv(fname, argv);
- free(argv);
+ os_free(argv);
if (err) {
perror("Unable to run image");
printf("Image filename '%s'\n", fname);
@@ -729,7 +777,7 @@
return os_jump_to_file(fname);
}
-int os_find_u_boot(char *fname, int maxlen)
+int os_find_u_boot(char *fname, int maxlen, bool use_img)
{
struct sandbox_state *state = state_get_current();
const char *progname = state->argv[0];
@@ -753,8 +801,8 @@
return 0;
}
- /* Look for 'u-boot-tpl' in the tpl/ directory */
- p = strstr(fname, "/tpl/");
+ /* Look for 'u-boot-spl' in the spl/ directory */
+ p = strstr(fname, "/spl/");
if (p) {
p[1] = 's';
fd = os_open(fname, O_RDONLY);
@@ -781,6 +829,8 @@
if (p) {
/* Remove the "spl" characters */
memmove(p, p + 4, strlen(p + 4) + 1);
+ if (use_img)
+ strcat(p, ".img");
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index d4dab36..8102649 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -69,14 +69,14 @@
* We don't want to include common.h in this file since it uses
* system headers. So add a declation here.
*/
- extern void reset_cpu(unsigned long addr);
+ extern void reset_cpu(void);
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
puts("LCD window closed - quitting\n");
- reset_cpu(1);
+ reset_cpu();
break;
}
}
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index e7b4b50..f82b0d3 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -13,7 +13,7 @@
#include <asm/global_data.h>
#include <asm/spl.h>
#include <asm/state.h>
-#include <test/test.h>
+#include <test/ut.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -37,16 +37,20 @@
char fname[256];
int ret;
- ret = os_find_u_boot(fname, sizeof(fname));
+ ret = os_find_u_boot(fname, sizeof(fname), false);
if (ret) {
printf("(%s not found, error %d)\n", fname, ret);
return ret;
}
- /* Set up spl_image to boot from jump_to_image_no_args() */
- spl_image->arg = strdup(fname);
+ /*
+ * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
+ * outsdide the RAM buffer (i.e. don't use strdup()).
+ */
+ spl_image->arg = os_malloc(strlen(fname) + 1);
if (!spl_image->arg)
- return log_msg_ret("Setup exec filename", -ENOMEM);
+ return log_msg_ret("exec", -ENOMEM);
+ strcpy(spl_image->arg, fname);
return 0;
}
@@ -59,9 +63,12 @@
preloader_console_init();
if (state->run_unittests) {
+ struct unit_test *tests = UNIT_TEST_ALL_START();
+ const int count = UNIT_TEST_ALL_COUNT();
int ret;
- ret = dm_test_main(state->select_unittests);
+ ret = ut_run_list("spl", NULL, tests, count,
+ state->select_unittests);
/* continue execution into U-Boot */
}
}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 483a264..e87365e 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -88,7 +88,7 @@
/* Sort the options */
size = sizeof(*sorted_opt) * num_options;
- sorted_opt = malloc(size);
+ sorted_opt = os_malloc(size);
if (!sorted_opt) {
printf("No memory to sort options\n");
os_exit(1);
@@ -188,7 +188,7 @@
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
- fname = malloc(len);
+ fname = os_malloc(len);
if (!fname)
return -ENOMEM;
snprintf(fname, len, fmt, state->argv[0]);
@@ -208,7 +208,7 @@
int len;
len = strlen(state->argv[0]) + strlen(fmt) + 1;
- fname = malloc(len);
+ fname = os_malloc(len);
if (!fname)
return -ENOMEM;
strcpy(fname, state->argv[0]);
@@ -436,16 +436,18 @@
{
struct sandbox_state *state;
gd_t data;
+ int size;
int ret;
/*
* Copy argv[] so that we can pass the arguments in the original
* sequence when resetting the sandbox.
*/
- os_argv = calloc(argc + 1, sizeof(char *));
+ size = sizeof(char *) * (argc + 1);
+ os_argv = os_malloc(size);
if (!os_argv)
os_exit(1);
- memcpy(os_argv, argv, sizeof(char *) * (argc + 1));
+ memcpy(os_argv, argv, size);
memset(&data, '\0', sizeof(data));
gd = &data;
@@ -489,7 +491,6 @@
gd->reloc_off = (ulong)gd->arch.text_base;
/* sandbox test: log functions called before log_init in board_init_f */
- log_info("sandbox: starting...\n");
log_debug("debug: %s\n", __func__);
/* Do pre- and post-relocation init */
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index b2901b7..f63cfd3 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <bloblist.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
@@ -29,17 +30,17 @@
return 0;
size = used + extra_size;
- buf = malloc(size);
+ buf = os_malloc(size);
if (!buf)
return -ENOMEM;
ret = fdt_open_into(blob, buf, size);
if (ret) {
- free(buf);
+ os_free(buf);
return -EIO;
}
- free(blob);
+ os_free(blob);
state->state_fdt = buf;
return 0;
}
@@ -55,7 +56,7 @@
printf("Cannot find sandbox state file '%s'\n", fname);
return -ENOENT;
}
- state->state_fdt = malloc(size);
+ state->state_fdt = os_malloc(size);
if (!state->state_fdt) {
puts("No memory to read sandbox state\n");
return -ENOMEM;
@@ -77,7 +78,7 @@
err_read:
os_close(fd);
err_open:
- free(state->state_fdt);
+ os_free(state->state_fdt);
state->state_fdt = NULL;
return ret;
@@ -244,7 +245,7 @@
/* Create a state FDT if we don't have one */
if (!state->state_fdt) {
size = 0x4000;
- state->state_fdt = malloc(size);
+ state->state_fdt = os_malloc(size);
if (!state->state_fdt) {
puts("No memory to create FDT\n");
return -ENOMEM;
@@ -302,7 +303,7 @@
err_write:
os_close(fd);
err_create:
- free(state->state_fdt);
+ os_free(state->state_fdt);
return ret;
}
@@ -398,8 +399,12 @@
{
int err;
+ log_info("Writing sandbox state\n");
state = &main_state;
+ /* Finish the bloblist, so that it is correct before writing memory */
+ bloblist_finish();
+
if (state->write_ram_buf) {
err = os_write_ram_buf(state->ram_buf_fname);
if (err) {
@@ -419,8 +424,8 @@
if (state->jumped_fname)
os_unlink(state->jumped_fname);
- if (state->state_fdt)
- free(state->state_fdt);
+ os_free(state->state_fdt);
+ os_free(state->ram_buf);
memset(state, '\0', sizeof(*state));
return 0;
diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index df4ba4f..9e10052 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -23,6 +23,15 @@
*/
#include <asm-generic/gpio.h>
+/* Our own private GPIO flags, which musn't conflict with GPIOD_... */
+#define GPIOD_EXT_HIGH BIT(31) /* external source is high (else low) */
+#define GPIOD_EXT_DRIVEN BIT(30) /* external source is driven */
+#define GPIOD_EXT_PULL_UP BIT(29) /* GPIO has external pull-up */
+#define GPIOD_EXT_PULL_DOWN BIT(28) /* GPIO has external pull-down */
+
+#define GPIOD_EXT_PULL (BIT(28) | BIT(29))
+#define GPIOD_SANDBOX_MASK GENMASK(31, 28)
+
/**
* Return the simulated value of a GPIO (used only in sandbox test code)
*
@@ -69,17 +78,17 @@
* @param offset GPIO offset within bank
* @return dir_flags: bitfield accesses by GPIOD_ defines
*/
-ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset);
+ulong sandbox_gpio_get_flags(struct udevice *dev, unsigned int offset);
/**
* Set the simulated flags of a GPIO (used only in sandbox test code)
*
* @param dev device to use
* @param offset GPIO offset within bank
- * @param flags dir_flags: bitfield accesses by GPIOD_ defines
+ * @param flags bitfield accesses by GPIOD_ defines
* @return -1 on error, 0 if ok
*/
-int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
- ulong flags);
+int sandbox_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags);
#endif
diff --git a/arch/sh/cpu/sh4/cpu.c b/arch/sh/cpu/sh4/cpu.c
index 801102f..1b2f50d 100644
--- a/arch/sh/cpu/sh4/cpu.c
+++ b/arch/sh/cpu/sh4/cpu.c
@@ -32,7 +32,7 @@
int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
disable_interrupts();
- reset_cpu(0);
+ reset_cpu();
return 0;
}
diff --git a/arch/sh/cpu/sh4/watchdog.c b/arch/sh/cpu/sh4/watchdog.c
index 1de32cd..bf403d3 100644
--- a/arch/sh/cpu/sh4/watchdog.c
+++ b/arch/sh/cpu/sh4/watchdog.c
@@ -51,7 +51,7 @@
}
#endif
-void reset_cpu(unsigned long ignored)
+void reset_cpu(void)
{
/* Address error with SR.BL=1 first. */
trigger_address_error();
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index bddba3e..a02f4f9 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -143,7 +143,7 @@
/* System is not happy after keyboard reset... */
debug("Issuing CF9 warm reset\n");
- reset_cpu(0);
+ reset_cpu();
}
ret = cpu_common_init();
diff --git a/arch/x86/include/asm/intel_pinctrl_defs.h b/arch/x86/include/asm/intel_pinctrl_defs.h
index 1ea141f..5d83d24 100644
--- a/arch/x86/include/asm/intel_pinctrl_defs.h
+++ b/arch/x86/include/asm/intel_pinctrl_defs.h
@@ -11,6 +11,11 @@
/* This file is included by device trees, so avoid BIT() macros */
+#define GPIO_DW_SIZE(x) (sizeof(u32) * (x))
+#define PAD_CFG_OFFSET(x, dw_num) ((x) + GPIO_DW_SIZE(dw_num))
+#define PAD_CFG0_OFFSET(x) PAD_CFG_OFFSET(x, 0)
+#define PAD_CFG1_OFFSET(x) PAD_CFG_OFFSET(x, 1)
+
#define PAD_CFG0_TX_STATE_BIT 0
#define PAD_CFG0_TX_STATE (1 << PAD_CFG0_TX_STATE_BIT)
#define PAD_CFG0_RX_STATE_BIT 1
diff --git a/board/BuR/brppt2/board.c b/board/BuR/brppt2/board.c
index e6eb403..ee006f0 100644
--- a/board/BuR/brppt2/board.c
+++ b/board/BuR/brppt2/board.c
@@ -540,7 +540,7 @@
spl_dram_init();
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
#endif /* CONFIG_SPL_BUILD */
diff --git a/board/abilis/tb100/tb100.c b/board/abilis/tb100/tb100.c
index 52dc5b8..89e7322 100644
--- a/board/abilis/tb100/tb100.c
+++ b/board/abilis/tb100/tb100.c
@@ -9,7 +9,7 @@
#include <netdev.h>
#include <asm/io.h>
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
#define CRM_SWRESET 0xff101044
writel(0x1, (void *)CRM_SWRESET);
diff --git a/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c b/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c
index 8492e76..ace18b2 100644
--- a/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c
+++ b/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c
@@ -115,7 +115,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c
index 01c65e4..b7eaab0 100644
--- a/board/armltd/total_compute/total_compute.c
+++ b/board/armltd/total_compute/total_compute.c
@@ -63,6 +63,6 @@
}
/* Nothing to be done here as handled by PSCI interface */
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/armltd/vexpress/vexpress_common.c b/board/armltd/vexpress/vexpress_common.c
index df4cbd3..ba3278a 100644
--- a/board/armltd/vexpress/vexpress_common.c
+++ b/board/armltd/vexpress/vexpress_common.c
@@ -174,7 +174,7 @@
}
/* Use the ARM Watchdog System to cause reset */
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
printf("Unable to reboot\n");
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
index 9d29490..2e42602 100644
--- a/board/armltd/vexpress64/vexpress64.c
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -143,7 +143,7 @@
#endif
/* Actual reset is done via PSCI. */
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/atmark-techno/armadillo-800eva/armadillo-800eva.c b/board/atmark-techno/armadillo-800eva/armadillo-800eva.c
index 1bae283..c1c3dfd 100644
--- a/board/atmark-techno/armadillo-800eva/armadillo-800eva.c
+++ b/board/atmark-techno/armadillo-800eva/armadillo-800eva.c
@@ -322,6 +322,6 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/beacon/beacon-rzg2m/beacon-rzg2m.c b/board/beacon/beacon-rzg2m/beacon-rzg2m.c
index c343de5..0c7f8e5 100644
--- a/board/beacon/beacon-rzg2m/beacon-rzg2m.c
+++ b/board/beacon/beacon-rzg2m/beacon-rzg2m.c
@@ -47,7 +47,7 @@
#define RST_CA57RESCNT (RST_BASE + 0x40)
#define RST_CODE 0xA5A5000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(RST_CODE, RST_CA57RESCNT);
}
diff --git a/board/bosch/shc/board.c b/board/bosch/shc/board.c
index bfce291..e893781 100644
--- a/board/bosch/shc/board.c
+++ b/board/bosch/shc/board.c
@@ -486,7 +486,7 @@
printf("Resetting ...\n");
writel(RESET_MASK, GPIO1_BASE + OMAP_GPIO_IRQSTATUS_SET_0);
disable_interrupts();
- reset_cpu(0);
+ reset_cpu();
/*NOTREACHED*/
}
}
diff --git a/board/broadcom/bcmns2/northstar2.c b/board/broadcom/bcmns2/northstar2.c
index 494e457..ee586d5 100644
--- a/board/broadcom/bcmns2/northstar2.c
+++ b/board/broadcom/bcmns2/northstar2.c
@@ -57,7 +57,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c
index 9d2df92..758a358 100644
--- a/board/broadcom/bcmns3/ns3.c
+++ b/board/broadcom/bcmns3/ns3.c
@@ -15,9 +15,6 @@
#include <dt-bindings/memory/bcm-ns3-mc.h>
#include <broadcom/chimp.h>
-/* Default reset-level = 3 and strap-val = 0 */
-#define L3_RESET 30
-
#define BANK_OFFSET(bank) ((u64)BCM_NS3_DDR_INFO_BASE + 8 + ((bank) * 16))
/*
@@ -188,25 +185,10 @@
return BCM_NS3_MEM_END;
}
-void reset_cpu(ulong level)
+void reset_cpu(void)
{
- u32 reset_level, strap_val;
-
- /* Default reset type is L3 reset */
- if (!level) {
- /*
- * Encoding: U-Boot reset command expects decimal argument,
- * Boot strap val: Bits[3:0]
- * reset level: Bits[7:4]
- */
- strap_val = L3_RESET % 10;
- level = L3_RESET / 10;
- reset_level = level % 10;
- psci_system_reset2(reset_level, strap_val);
- } else {
- /* U-Boot cmd "reset" with any arg will trigger L1 reset */
- psci_system_reset();
- }
+ /* Perform a level 3 reset */
+ psci_system_reset2(3, 0);
}
#ifdef CONFIG_OF_BOARD_SETUP
diff --git a/board/broadcom/bcmstb/bcmstb.c b/board/broadcom/bcmstb/bcmstb.c
index f6bdf1f..ee0a341 100644
--- a/board/broadcom/bcmstb/bcmstb.c
+++ b/board/broadcom/bcmstb/bcmstb.c
@@ -43,7 +43,7 @@
return 0;
}
-void reset_cpu(ulong ignored)
+void reset_cpu(void)
{
}
diff --git a/board/cavium/thunderx/thunderx.c b/board/cavium/thunderx/thunderx.c
index b09f72c..a7dc5c6 100644
--- a/board/cavium/thunderx/thunderx.c
+++ b/board/cavium/thunderx/thunderx.c
@@ -110,7 +110,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/compulab/cm_t335/spl.c b/board/compulab/cm_t335/spl.c
index 8662632..33264df 100644
--- a/board/compulab/cm_t335/spl.c
+++ b/board/compulab/cm_t335/spl.c
@@ -96,7 +96,7 @@
break;
default:
puts("Failed configuring DRAM, resetting...\n\n");
- reset_cpu(0);
+ reset_cpu();
}
debug("%s: setting DRAM size to %ldM\n", __func__, size >> 20);
config_ddr(303, &ioregs, &ddr3_data,
diff --git a/board/cortina/presidio-asic/presidio.c b/board/cortina/presidio-asic/presidio.c
index 5c73522..f344622 100644
--- a/board/cortina/presidio-asic/presidio.c
+++ b/board/cortina/presidio-asic/presidio.c
@@ -115,7 +115,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}
diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c
index c677220..682099a 100644
--- a/board/freescale/imx8qm_mek/imx8qm_mek.c
+++ b/board/freescale/imx8qm_mek/imx8qm_mek.c
@@ -105,7 +105,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c
index 7179823..21cfa14 100644
--- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c
+++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c
@@ -129,7 +129,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c
index c82b532..61d0ca3 100644
--- a/board/freescale/mx6memcal/spl.c
+++ b/board/freescale/mx6memcal/spl.c
@@ -425,7 +425,7 @@
is_cpu_type(MXC_CPU_MX6SL)) {
printf("cpu type 0x%x doesn't support 64-bit bus\n",
get_cpu_type());
- reset_cpu(0);
+ reset_cpu();
}
}
#ifdef CONFIG_MX6SL
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 4f1dc3b..dc424f2 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -288,8 +288,8 @@
ccdc_eth_init();
#endif
ret = get_tpm(&tpm);
- if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) ||
- tpm_continue_self_test(tpm)) {
+ if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR) ||
+ tpm1_continue_self_test(tpm)) {
return 1;
}
diff --git a/board/gdsys/a38x/hre.c b/board/gdsys/a38x/hre.c
index 699241b..de5411a 100644
--- a/board/gdsys/a38x/hre.c
+++ b/board/gdsys/a38x/hre.c
@@ -107,8 +107,8 @@
uint8_t *ptr;
uint16_t v16;
- err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index,
- info, sizeof(info));
+ err = tpm1_get_capability(tpm, TPM_CAP_NV_INDEX, index, info,
+ sizeof(info));
if (err) {
printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
index, err);
@@ -150,8 +150,8 @@
unsigned int i;
/* fetch list of already loaded keys in the TPM */
- err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
- sizeof(buf));
+ err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+ sizeof(buf));
if (err)
return -1;
key_count = get_unaligned_be16(buf);
@@ -162,8 +162,8 @@
/* now search a(/ the) key which we can access with the given auth */
for (i = 0; i < key_count; ++i) {
buf_len = sizeof(buf);
- err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
- &buf_len);
+ err = tpm1_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
+ &buf_len);
if (err && err != TPM_AUTHFAIL)
return -1;
if (err)
@@ -192,8 +192,8 @@
if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) ||
size < NV_COMMON_DATA_MIN_SIZE)
return 1;
- err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX,
- buf, min(sizeof(buf), size));
+ err = tpm1_nv_read_value(tpm, NV_COMMON_DATA_INDEX, buf,
+ min(sizeof(buf), size));
if (err) {
printf("tpm_nv_read_value() failed: %u\n", err);
return 1;
@@ -270,8 +270,8 @@
if (mode & HREG_RD) {
if (!result->valid) {
if (IS_PCR_HREG(spec)) {
- hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec),
- result->digest, 20);
+ hre_tpm_err = tpm1_pcr_read(tpm, HREG_IDX(spec),
+ result->digest, 20);
result->valid = (hre_tpm_err == TPM_SUCCESS);
} else if (IS_FIX_HREG(spec)) {
switch (HREG_IDX(spec)) {
@@ -357,8 +357,8 @@
return -1;
if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle))
return -1;
- hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size,
- src_reg->digest, &key_handle);
+ hre_tpm_err = tpm1_load_key2_oiap(tpm, parent_handle, key, key_size,
+ src_reg->digest, &key_handle);
if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return -1;
@@ -474,8 +474,8 @@
}
if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
- hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec),
- dst_reg->digest, dst_reg->digest);
+ hre_tpm_err = tpm1_extend(tpm, HREG_IDX(dst_spec),
+ dst_reg->digest, dst_reg->digest);
if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return NULL;
diff --git a/board/gdsys/a38x/keyprogram.c b/board/gdsys/a38x/keyprogram.c
index 853981a..7020fae 100644
--- a/board/gdsys/a38x/keyprogram.c
+++ b/board/gdsys/a38x/keyprogram.c
@@ -23,15 +23,15 @@
uint i;
/* fetch list of already loaded keys in the TPM */
- err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
- sizeof(buf));
+ err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+ sizeof(buf));
if (err)
return -1;
key_count = get_unaligned_be16(buf);
ptr = buf + 2;
for (i = 0; i < key_count; ++i, ptr += 4) {
- err = tpm_flush_specific(tpm, get_unaligned_be32(ptr),
- TPM_RT_KEY);
+ err = tpm1_flush_specific(tpm, get_unaligned_be32(ptr),
+ TPM_RT_KEY);
if (err && err != TPM_KEY_OWNER_CONTROL)
return err;
}
diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c
index 4e974c5..3d4a7e5 100644
--- a/board/gdsys/mpc8308/gazerbeam.c
+++ b/board/gdsys/mpc8308/gazerbeam.c
@@ -145,8 +145,8 @@
env_set_ulong("fpga_hw_rev", fpga_hw_rev);
ret = get_tpm(&tpm);
- if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) ||
- tpm_continue_self_test(tpm)) {
+ if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR) ||
+ tpm1_continue_self_test(tpm)) {
printf("TPM init failed\n");
}
diff --git a/board/gdsys/p1022/controlcenterd-id.c b/board/gdsys/p1022/controlcenterd-id.c
index 1b5aa90..87b346a 100644
--- a/board/gdsys/p1022/controlcenterd-id.c
+++ b/board/gdsys/p1022/controlcenterd-id.c
@@ -273,8 +273,8 @@
uint8_t *ptr;
uint16_t v16;
- err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index,
- info, sizeof(info));
+ err = tpm1_get_capability(tpm, TPM_CAP_NV_INDEX, index, info,
+ sizeof(info));
if (err) {
printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
index, err);
@@ -315,8 +315,8 @@
unsigned int i;
/* fetch list of already loaded keys in the TPM */
- err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
- sizeof(buf));
+ err = tpm1_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
+ sizeof(buf));
if (err)
return -1;
key_count = get_unaligned_be16(buf);
@@ -327,8 +327,8 @@
/* now search a(/ the) key which we can access with the given auth */
for (i = 0; i < key_count; ++i) {
buf_len = sizeof(buf);
- err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
- &buf_len);
+ err = tpm1_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
+ &buf_len);
if (err && err != TPM_AUTHFAIL)
return -1;
if (err)
@@ -356,8 +356,8 @@
if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) ||
size < NV_COMMON_DATA_MIN_SIZE)
return 1;
- err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX,
- buf, min(sizeof(buf), size));
+ err = tpm1_nv_read_value(tpm, NV_COMMON_DATA_INDEX, buf,
+ min(sizeof(buf), size));
if (err) {
printf("tpm_nv_read_value() failed: %u\n", err);
return 1;
@@ -508,8 +508,8 @@
if (mode & HREG_RD) {
if (!result->valid) {
if (IS_PCR_HREG(spec)) {
- hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec),
- result->digest, 20);
+ hre_tpm_err = tpm1_pcr_read(tpm, HREG_IDX(spec),
+ result->digest, 20);
result->valid = (hre_tpm_err == TPM_SUCCESS);
} else if (IS_FIX_HREG(spec)) {
switch (HREG_IDX(spec)) {
@@ -601,8 +601,8 @@
return -1;
if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle))
return -1;
- hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size,
- src_reg->digest, &key_handle);
+ hre_tpm_err = tpm1_load_key2_oiap(tpm, parent_handle, key, key_size,
+ src_reg->digest, &key_handle);
if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return -1;
@@ -718,8 +718,8 @@
}
if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
- hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec),
- dst_reg->digest, dst_reg->digest);
+ hre_tpm_err = tpm1_extend(tpm, HREG_IDX(dst_spec),
+ dst_reg->digest, dst_reg->digest);
if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return NULL;
@@ -964,10 +964,10 @@
puts("CCDM S1: start actions\n");
#ifndef CCDM_SECOND_STAGE
- if (tpm_continue_self_test(tpm))
+ if (tpm1_continue_self_test(tpm))
goto failure;
#else
- tpm_continue_self_test(tpm);
+ tpm1_continue_self_test(tpm);
#endif
mdelay(37);
@@ -1003,7 +1003,7 @@
puts("CCDM S1\n");
ret = get_tpm(&tpm);
- if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR))
+ if (ret || tpm_init(tpm) || tpm1_startup(tpm, TPM_ST_CLEAR))
return 1;
ret = first_stage_actions(tpm);
#ifndef CCDM_SECOND_STAGE
@@ -1061,7 +1061,7 @@
ret = get_tpm(&tpm);
if (ret || tpm_init(tpm))
return 1;
- err = tpm_startup(tpm, TPM_ST_CLEAR);
+ err = tpm1_startup(tpm, TPM_ST_CLEAR);
if (err != TPM_INVALID_POSTINIT)
did_first_stage_run = false;
diff --git a/board/ge/b1x5v2/spl.c b/board/ge/b1x5v2/spl.c
index 2e6f905..52c80f7 100644
--- a/board/ge/b1x5v2/spl.c
+++ b/board/ge/b1x5v2/spl.c
@@ -436,7 +436,7 @@
return 1024;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c
index a790d45..906bd9b 100644
--- a/board/highbank/highbank.c
+++ b/board/highbank/highbank.c
@@ -128,7 +128,7 @@
return (midr & 0xfff0) == 0xc090;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(HB_PWR_HARD_RESET, HB_SREG_A9_PWR_REQ);
if (is_highbank())
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c
index afe324c..c9a2d60 100644
--- a/board/hisilicon/hikey/hikey.c
+++ b/board/hisilicon/hikey/hikey.c
@@ -486,7 +486,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(0x48698284, &ao_sc->stat0);
wfi();
diff --git a/board/hisilicon/hikey960/hikey960.c b/board/hisilicon/hikey960/hikey960.c
index 62073aa..f41fabb 100644
--- a/board/hisilicon/hikey960/hikey960.c
+++ b/board/hisilicon/hikey960/hikey960.c
@@ -185,7 +185,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/board/hisilicon/poplar/poplar.c b/board/hisilicon/poplar/poplar.c
index fda9a34..6cc79d9 100644
--- a/board/hisilicon/poplar/poplar.c
+++ b/board/hisilicon/poplar/poplar.c
@@ -60,7 +60,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/board/kmc/kzm9g/kzm9g.c b/board/kmc/kzm9g/kzm9g.c
index 02c87a0..dccf469 100644
--- a/board/kmc/kzm9g/kzm9g.c
+++ b/board/kmc/kzm9g/kzm9g.c
@@ -366,7 +366,7 @@
return ret;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* Soft Power On Reset */
writel((1 << 31), RESCNT2);
diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c
index b8658c8..39f70f5 100644
--- a/board/liebherr/display5/spl.c
+++ b/board/liebherr/display5/spl.c
@@ -376,7 +376,7 @@
#endif
}
-void reset_cpu(ulong addr) {}
+void reset_cpu(void) {}
#ifdef CONFIG_SPL_LOAD_FIT
int board_fit_config_name_match(const char *name)
diff --git a/board/phytium/durian/durian.c b/board/phytium/durian/durian.c
index 8a82a45..ef13f7c 100644
--- a/board/phytium/durian/durian.c
+++ b/board/phytium/durian/durian.c
@@ -42,7 +42,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct arm_smccc_res res;
diff --git a/board/qualcomm/dragonboard410c/dragonboard410c.c b/board/qualcomm/dragonboard410c/dragonboard410c.c
index 646013c..0d282de 100644
--- a/board/qualcomm/dragonboard410c/dragonboard410c.c
+++ b/board/qualcomm/dragonboard410c/dragonboard410c.c
@@ -203,7 +203,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/board/qualcomm/dragonboard820c/dragonboard820c.c b/board/qualcomm/dragonboard820c/dragonboard820c.c
index 877e34c..4ccb1a0 100644
--- a/board/qualcomm/dragonboard820c/dragonboard820c.c
+++ b/board/qualcomm/dragonboard820c/dragonboard820c.c
@@ -127,7 +127,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
psci_system_reset();
}
diff --git a/board/renesas/alt/alt.c b/board/renesas/alt/alt.c
index 854c476..3b60afc 100644
--- a/board/renesas/alt/alt.c
+++ b/board/renesas/alt/alt.c
@@ -111,7 +111,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 7;
diff --git a/board/renesas/alt/alt_spl.c b/board/renesas/alt/alt_spl.c
index 2de236f..cdaa04e 100644
--- a/board/renesas/alt/alt_spl.c
+++ b/board/renesas/alt/alt_spl.c
@@ -408,6 +408,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c
index 9671382..a365269 100644
--- a/board/renesas/blanche/blanche.c
+++ b/board/renesas/blanche/blanche.c
@@ -360,7 +360,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 6;
diff --git a/board/renesas/condor/condor.c b/board/renesas/condor/condor.c
index 4454061..e930de3 100644
--- a/board/renesas/condor/condor.c
+++ b/board/renesas/condor/condor.c
@@ -34,7 +34,7 @@
#define RST_CA57_CODE 0xA5A5000F
#define RST_CA53_CODE 0x5A5A000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
unsigned long midr, cputype;
diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c
index ffd52eb..1d76f95 100644
--- a/board/renesas/draak/draak.c
+++ b/board/renesas/draak/draak.c
@@ -75,7 +75,7 @@
#define RST_CA53RESCNT (RST_BASE + 0x44)
#define RST_CA53_CODE 0x5A5A000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(RST_CA53_CODE, RST_CA53RESCNT);
}
diff --git a/board/renesas/eagle/eagle.c b/board/renesas/eagle/eagle.c
index f9e553f..bb32e3d 100644
--- a/board/renesas/eagle/eagle.c
+++ b/board/renesas/eagle/eagle.c
@@ -78,7 +78,7 @@
#define RST_CA57_CODE 0xA5A5000F
#define RST_CA53_CODE 0x5A5A000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
unsigned long midr, cputype;
diff --git a/board/renesas/ebisu/ebisu.c b/board/renesas/ebisu/ebisu.c
index 82cd2a5..9d4af8d 100644
--- a/board/renesas/ebisu/ebisu.c
+++ b/board/renesas/ebisu/ebisu.c
@@ -42,7 +42,7 @@
#define RST_CA53RESCNT (RST_BASE + 0x44)
#define RST_CA53_CODE 0x5A5A000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(RST_CA53_CODE, RST_CA53RESCNT);
}
diff --git a/board/renesas/gose/gose.c b/board/renesas/gose/gose.c
index 56cdc73..51768c3 100644
--- a/board/renesas/gose/gose.c
+++ b/board/renesas/gose/gose.c
@@ -117,7 +117,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 6;
diff --git a/board/renesas/gose/gose_spl.c b/board/renesas/gose/gose_spl.c
index 624ba5d..c0bf720 100644
--- a/board/renesas/gose/gose_spl.c
+++ b/board/renesas/gose/gose_spl.c
@@ -405,6 +405,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/grpeach/grpeach.c b/board/renesas/grpeach/grpeach.c
index ac989eb..199ec4a 100644
--- a/board/renesas/grpeach/grpeach.c
+++ b/board/renesas/grpeach/grpeach.c
@@ -40,7 +40,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* Dummy read (must read WRCSR:WOVF at least once before clearing) */
readb(RZA1_WDT_BASE + WRCSR);
diff --git a/board/renesas/koelsch/koelsch.c b/board/renesas/koelsch/koelsch.c
index b0a66ea..7e94bd8 100644
--- a/board/renesas/koelsch/koelsch.c
+++ b/board/renesas/koelsch/koelsch.c
@@ -119,7 +119,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 6;
diff --git a/board/renesas/koelsch/koelsch_spl.c b/board/renesas/koelsch/koelsch_spl.c
index 449bbfa..b377f70 100644
--- a/board/renesas/koelsch/koelsch_spl.c
+++ b/board/renesas/koelsch/koelsch_spl.c
@@ -407,6 +407,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/lager/lager.c b/board/renesas/lager/lager.c
index add4eef..87c5e01 100644
--- a/board/renesas/lager/lager.c
+++ b/board/renesas/lager/lager.c
@@ -128,7 +128,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 2;
diff --git a/board/renesas/lager/lager_spl.c b/board/renesas/lager/lager_spl.c
index 1ca857c..d3d397e 100644
--- a/board/renesas/lager/lager_spl.c
+++ b/board/renesas/lager/lager_spl.c
@@ -393,6 +393,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/porter/porter.c b/board/renesas/porter/porter.c
index b3e4c08..b0f8505 100644
--- a/board/renesas/porter/porter.c
+++ b/board/renesas/porter/porter.c
@@ -117,7 +117,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 6;
diff --git a/board/renesas/porter/porter_spl.c b/board/renesas/porter/porter_spl.c
index f10c6cf..8595770 100644
--- a/board/renesas/porter/porter_spl.c
+++ b/board/renesas/porter/porter_spl.c
@@ -488,6 +488,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c
index fd6e505..b02a946 100644
--- a/board/renesas/rcar-common/gen3-spl.c
+++ b/board/renesas/rcar-common/gen3-spl.c
@@ -55,6 +55,6 @@
{
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c
index 08ed725..071076a 100644
--- a/board/renesas/salvator-x/salvator-x.c
+++ b/board/renesas/salvator-x/salvator-x.c
@@ -76,7 +76,7 @@
#define RST_RSTOUTCR (RST_BASE + 0x58)
#define RST_CODE 0xA5A5000F
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
#if defined(CONFIG_SYS_I2C) && defined(CONFIG_SYS_I2C_SH)
i2c_reg_write(CONFIG_SYS_I2C_POWERIC_ADDR, 0x20, 0x80);
diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c
index 05af5f4..4558070 100644
--- a/board/renesas/silk/silk.c
+++ b/board/renesas/silk/silk.c
@@ -112,7 +112,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
const u8 pmic_bus = 1;
diff --git a/board/renesas/silk/silk_spl.c b/board/renesas/silk/silk_spl.c
index f10f84a..afb9f85 100644
--- a/board/renesas/silk/silk_spl.c
+++ b/board/renesas/silk/silk_spl.c
@@ -422,6 +422,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/renesas/stout/cpld.c b/board/renesas/stout/cpld.c
index b56ed17..ac8048c 100644
--- a/board/renesas/stout/cpld.c
+++ b/board/renesas/stout/cpld.c
@@ -163,7 +163,7 @@
"cpld write addr val\n"
);
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
cpld_write(CPLD_ADDR_RESET, 1);
}
diff --git a/board/renesas/stout/stout_spl.c b/board/renesas/stout/stout_spl.c
index 57c1fab..c37c055 100644
--- a/board/renesas/stout/stout_spl.c
+++ b/board/renesas/stout/stout_spl.c
@@ -474,6 +474,6 @@
spl_boot_list[2] = BOOT_DEVICE_NONE;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/siemens/capricorn/board.c b/board/siemens/capricorn/board.c
index 56973a1..dcbab8e 100644
--- a/board/siemens/capricorn/board.c
+++ b/board/siemens/capricorn/board.c
@@ -232,7 +232,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c
index 997120e..a3cee23 100644
--- a/board/synopsys/emsdp/emsdp.c
+++ b/board/synopsys/emsdp/emsdp.c
@@ -98,7 +98,7 @@
/* Bits in CREG_BOOT register */
#define CREG_BOOT_WP_BIT BIT(8)
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(1, CREG_IP_SW_RESET);
while (1)
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
index c605136..650958f 100644
--- a/board/synopsys/iot_devkit/iot_devkit.c
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -151,7 +151,7 @@
#define IOTDK_RESET_SEQ 0x55AA6699
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
writel(IOTDK_RESET_SEQ, RESET_REG);
}
diff --git a/board/technexion/pico-imx6ul/spl.c b/board/technexion/pico-imx6ul/spl.c
index 3807779..251f5a1 100644
--- a/board/technexion/pico-imx6ul/spl.c
+++ b/board/technexion/pico-imx6ul/spl.c
@@ -147,7 +147,7 @@
board_init_r(NULL, 0);
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/technexion/pico-imx7d/spl.c b/board/technexion/pico-imx7d/spl.c
index bed0f21..df5f058 100644
--- a/board/technexion/pico-imx7d/spl.c
+++ b/board/technexion/pico-imx7d/spl.c
@@ -127,7 +127,7 @@
board_init_r(NULL, 0);
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
index 76faa6e..04877fc 100644
--- a/board/toradex/apalis-imx8/apalis-imx8.c
+++ b/board/toradex/apalis-imx8/apalis-imx8.c
@@ -117,7 +117,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/toradex/apalis-imx8x/apalis-imx8x.c b/board/toradex/apalis-imx8x/apalis-imx8x.c
index b6f3bdd..ac3bac6 100644
--- a/board/toradex/apalis-imx8x/apalis-imx8x.c
+++ b/board/toradex/apalis-imx8x/apalis-imx8x.c
@@ -127,7 +127,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c
index 0c857b5..74060da 100644
--- a/board/toradex/apalis_imx6/apalis_imx6.c
+++ b/board/toradex/apalis_imx6/apalis_imx6.c
@@ -1139,7 +1139,7 @@
}
#endif
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/toradex/colibri-imx8x/colibri-imx8x.c b/board/toradex/colibri-imx8x/colibri-imx8x.c
index 562199a..169d4d0 100644
--- a/board/toradex/colibri-imx8x/colibri-imx8x.c
+++ b/board/toradex/colibri-imx8x/colibri-imx8x.c
@@ -129,7 +129,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
/* TODO */
}
diff --git a/board/toradex/colibri_imx6/colibri_imx6.c b/board/toradex/colibri_imx6/colibri_imx6.c
index 74d59e5..c0e7754 100644
--- a/board/toradex/colibri_imx6/colibri_imx6.c
+++ b/board/toradex/colibri_imx6/colibri_imx6.c
@@ -1081,7 +1081,7 @@
board_init_r(NULL, 0);
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/toradex/colibri_imx7/colibri_imx7.c b/board/toradex/colibri_imx7/colibri_imx7.c
index 8f7ef99..301b07d 100644
--- a/board/toradex/colibri_imx7/colibri_imx7.c
+++ b/board/toradex/colibri_imx7/colibri_imx7.c
@@ -237,7 +237,7 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct udevice *dev;
diff --git a/board/xen/xenguest_arm64/xenguest_arm64.c b/board/xen/xenguest_arm64/xenguest_arm64.c
index 7d0d782..21363d8 100644
--- a/board/xen/xenguest_arm64/xenguest_arm64.c
+++ b/board/xen/xenguest_arm64/xenguest_arm64.c
@@ -171,7 +171,7 @@
/*
* Board specific reset that is system reset.
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index c644fe8..e2f9d13 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -242,6 +242,6 @@
return 0;
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 4466717..23c12f4 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -436,7 +436,7 @@
}
#endif
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
}
diff --git a/cmd/Kconfig b/cmd/Kconfig
index eff238c..e4bb1d4 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2030,12 +2030,19 @@
help
Add -v option to verify data against a hash.
+config CMD_SCP03
+ bool "scp03 - SCP03 enable and rotate/provision operations"
+ depends on SCP03
+ help
+ This command provides access to a Trusted Application
+ running in a TEE to request Secure Channel Protocol 03
+ (SCP03) enablement and/or rotation of its SCP03 keys.
+
config CMD_TPM_V1
bool
config CMD_TPM_V2
bool
- select CMD_LOG
config CMD_TPM
bool "Enable the 'tpm' command"
diff --git a/cmd/Makefile b/cmd/Makefile
index 567e2b7..e606ac4 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -194,6 +194,9 @@
# Android Verified Boot 2.0
obj-$(CONFIG_CMD_AVB) += avb.o
+# Foundries.IO SCP03
+obj-$(CONFIG_CMD_SCP03) += scp03.o
+
obj-$(CONFIG_ARM) += arm/
obj-$(CONFIG_RISCV) += riscv/
obj-$(CONFIG_SANDBOX) += sandbox/
diff --git a/cmd/scp03.c b/cmd/scp03.c
new file mode 100644
index 0000000..655e0bb
--- /dev/null
+++ b/cmd/scp03.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <scp03.h>
+
+int do_scp03_enable(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 1)
+ return CMD_RET_USAGE;
+
+ if (tee_enable_scp03()) {
+ printf("TEE failed to enable SCP03\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("SCP03 is enabled\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+int do_scp03_provision(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 1)
+ return CMD_RET_USAGE;
+
+ if (tee_provision_scp03()) {
+ printf("TEE failed to provision SCP03 keys\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("SCP03 is provisioned\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+static char text[] =
+ "provides a command to enable SCP03 and provision the SCP03 keys\n"
+ " enable - enable SCP03 on the TEE\n"
+ " provision - provision SCP03 on the TEE\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(scp03, "Secure Channel Protocol 03 control", text,
+ U_BOOT_SUBCMD_MKENT(enable, 1, 1, do_scp03_enable),
+ U_BOOT_SUBCMD_MKENT(provision, 1, 1, do_scp03_provision));
+
diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c
index 0e2168a..3a7e35d 100644
--- a/cmd/tpm-v1.c
+++ b/cmd/tpm-v1.c
@@ -11,6 +11,7 @@
#include <tpm-common.h>
#include <tpm-v1.h>
#include "tpm-user-utils.h"
+#include <tpm_api.h>
static int do_tpm_startup(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
@@ -55,7 +56,7 @@
perm = simple_strtoul(argv[2], NULL, 0);
size = simple_strtoul(argv[3], NULL, 0);
- return report_return_code(tpm_nv_define_space(dev, index, perm, size));
+ return report_return_code(tpm1_nv_define_space(dev, index, perm, size));
}
static int do_tpm_nv_read_value(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -130,7 +131,7 @@
return CMD_RET_FAILURE;
}
- rc = tpm_extend(dev, index, in_digest, out_digest);
+ rc = tpm_pcr_extend(dev, index, in_digest, out_digest);
if (!rc) {
puts("PCR value after execution of the command:\n");
print_byte_string(out_digest, sizeof(out_digest));
@@ -304,7 +305,7 @@
index = simple_strtoul(argv[2], NULL, 0);
perm = simple_strtoul(argv[3], NULL, 0);
- return report_return_code(tpm_nv_define_space(dev, index, perm, size));
+ return report_return_code(tpm1_nv_define_space(dev, index, perm, size));
}
static int do_tpm_nv_read(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -389,7 +390,7 @@
if (rc)
return rc;
- err = tpm_oiap(dev, &auth_handle);
+ err = tpm1_oiap(dev, &auth_handle);
return report_return_code(err);
}
@@ -461,8 +462,8 @@
return CMD_RET_FAILURE;
parse_byte_string(argv[4], usage_auth, NULL);
- err = tpm_load_key2_oiap(dev, parent_handle, key, key_len, usage_auth,
- &key_handle);
+ err = tpm1_load_key2_oiap(dev, parent_handle, key, key_len, usage_auth,
+ &key_handle);
if (!err)
printf("Key handle is 0x%x\n", key_handle);
@@ -491,8 +492,8 @@
return CMD_RET_FAILURE;
parse_byte_string(argv[2], usage_auth, NULL);
- err = tpm_get_pub_key_oiap(dev, key_handle, usage_auth, pub_key_buffer,
- &pub_key_len);
+ err = tpm1_get_pub_key_oiap(dev, key_handle, usage_auth, pub_key_buffer,
+ &pub_key_len);
if (!err) {
printf("dump of received pub key structure:\n");
print_byte_string(pub_key_buffer, pub_key_len);
@@ -500,7 +501,7 @@
return report_return_code(err);
}
-TPM_COMMAND_NO_ARG(tpm_end_oiap)
+TPM_COMMAND_NO_ARG(tpm1_end_oiap)
#endif /* CONFIG_TPM_AUTH_SESSIONS */
@@ -562,7 +563,7 @@
res_count = get_unaligned_be16(buf);
ptr = buf + 2;
for (i = 0; i < res_count; ++i, ptr += 4)
- tpm_flush_specific(dev, get_unaligned_be32(ptr), type);
+ tpm1_flush_specific(dev, get_unaligned_be32(ptr), type);
} else {
u32 handle = simple_strtoul(argv[2], NULL, 0);
@@ -570,7 +571,7 @@
printf("Illegal resource handle %s\n", argv[2]);
return -1;
}
- tpm_flush_specific(dev, cpu_to_be32(handle), type);
+ tpm1_flush_specific(dev, cpu_to_be32(handle), type);
}
return 0;
@@ -691,7 +692,7 @@
U_BOOT_CMD_MKENT(oiap, 0, 1,
do_tpm_oiap, "", ""),
U_BOOT_CMD_MKENT(end_oiap, 0, 1,
- do_tpm_end_oiap, "", ""),
+ do_tpm1_end_oiap, "", ""),
U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1,
do_tpm_load_key2_oiap, "", ""),
#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c
index ebfb25c..a3ccb12 100644
--- a/cmd/tpm_test.c
+++ b/cmd/tpm_test.c
@@ -9,6 +9,7 @@
#include <log.h>
#include <tpm-v1.h>
#include "tpm-user-utils.h"
+#include <tpm_api.h>
/* Prints error and returns on failure */
#define TPM_CHECK(tpm_command) do { \
@@ -49,7 +50,7 @@
struct tpm_permanent_flags pflags;
uint32_t result;
- result = tpm_get_permanent_flags(dev, &pflags);
+ result = tpm1_get_permanent_flags(dev, &pflags);
if (result)
return result;
if (disable)
@@ -90,7 +91,7 @@
tpm_init(dev);
TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
TPM_CHECK(tpm_continue_self_test(dev));
- TPM_CHECK(tpm_extend(dev, 1, value_in, value_out));
+ TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, value_out));
printf("done\n");
return 0;
}
@@ -146,7 +147,7 @@
#define reboot() do { \
printf("\trebooting...\n"); \
- reset_cpu(0); \
+ reset_cpu(); \
} while (0)
static int test_fast_enable(struct udevice *dev)
@@ -238,18 +239,18 @@
uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
printf("\tInitialising spaces\n");
- tpm_nv_set_locked(dev); /* useful only the first time */
- tpm_nv_define_space(dev, INDEX0, perm, 4);
+ tpm1_nv_set_locked(dev); /* useful only the first time */
+ tpm1_nv_define_space(dev, INDEX0, perm, 4);
tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4);
- tpm_nv_define_space(dev, INDEX1, perm, 4);
+ tpm1_nv_define_space(dev, INDEX1, perm, 4);
tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4);
- tpm_nv_define_space(dev, INDEX2, perm, 4);
+ tpm1_nv_define_space(dev, INDEX2, perm, 4);
tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4);
- tpm_nv_define_space(dev, INDEX3, perm, 4);
+ tpm1_nv_define_space(dev, INDEX3, perm, 4);
tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4);
perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
TPM_NV_PER_PPWRITE;
- tpm_nv_define_space(dev, INDEX_INITIALISED, perm, 1);
+ tpm1_nv_define_space(dev, INDEX_INITIALISED, perm, 1);
}
static int test_readonly(struct udevice *dev)
@@ -325,30 +326,33 @@
/* Redefines spaces a couple of times. */
perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
- TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm,
+ 2 * sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)));
perm = TPM_NV_PER_PPWRITE;
- TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
+ 2 * sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
/* Sets the global lock */
tpm_set_global_lock(dev);
/* Verifies that index0 cannot be redefined */
- result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
+ result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
assert(result == TPM_AREA_LOCKED);
/* Checks that index1 can */
- TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
+ 2 * sizeof(uint32_t)));
+ TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));
/* Turns off PP */
tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
/* Verifies that neither index0 nor index1 can be redefined */
- result = tpm_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
+ result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
assert(result == TPM_BAD_PRESENCE);
- result = tpm_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t));
+ result = tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t));
assert(result == TPM_BAD_PRESENCE);
printf("done\n");
@@ -434,7 +438,7 @@
100);
TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
100);
- TTPM_CHECK(tpm_extend(dev, 0, in, out), 200);
+ TTPM_CHECK(tpm_pcr_extend(dev, 0, in, out), 200);
TTPM_CHECK(tpm_set_global_lock(dev), 50);
TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100);
printf("done\n");
diff --git a/common/Kconfig b/common/Kconfig
index 2bb3798..482f123 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -588,6 +588,14 @@
endif # AVB_VERIFY
+config SCP03
+ bool "Build SCP03 - Secure Channel Protocol O3 - controls"
+ depends on OPTEE || SANDBOX
+ depends on TEE
+ help
+ This option allows U-Boot to enable and or provision SCP03 on an OPTEE
+ controlled Secured Element.
+
config SPL_HASH
bool # "Support hashing API (SHA1, SHA256, etc.)"
help
diff --git a/common/Makefile b/common/Makefile
index daeea67..215b8b2 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -137,3 +137,4 @@
obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
obj-$(CONFIG_AVB_VERIFY) += avb_verify.o
+obj-$(CONFIG_SCP03) += scp03.o
diff --git a/common/bootm.c b/common/bootm.c
index defaed8..dab7c36 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -586,7 +586,7 @@
if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && (flags & BOOTM_CL_SUBST)) {
ret = process_subst(buf, maxlen);
if (ret)
- return log_msg_ret("silent", ret);
+ return log_msg_ret("subst", ret);
}
return 0;
diff --git a/common/log.c b/common/log.c
index 6b0034c..ea407c6 100644
--- a/common/log.c
+++ b/common/log.c
@@ -153,7 +153,7 @@
{
struct log_filter *filt;
- if (rec->force_debug)
+ if (rec->flags & LOGRECF_FORCE_DEBUG)
return true;
/* If there are no filters, filter on the default log level */
@@ -218,8 +218,11 @@
if ((ldev->flags & LOGDF_ENABLE) &&
log_passes_filters(ldev, rec)) {
if (!rec->msg) {
- vsnprintf(buf, sizeof(buf), fmt, args);
+ int len;
+
+ len = vsnprintf(buf, sizeof(buf), fmt, args);
rec->msg = buf;
+ gd->log_cont = len && buf[len - 1] != '\n';
}
ldev->drv->emit(ldev, rec);
}
@@ -245,7 +248,11 @@
rec.cat = cat;
rec.level = level & LOGL_LEVEL_MASK;
- rec.force_debug = level & LOGL_FORCE_DEBUG;
+ rec.flags = 0;
+ if (level & LOGL_FORCE_DEBUG)
+ rec.flags |= LOGRECF_FORCE_DEBUG;
+ if (gd->log_cont)
+ rec.flags |= LOGRECF_CONT;
rec.file = file;
rec.line = line;
rec.func = func;
@@ -255,7 +262,8 @@
gd->log_drop_count++;
/* display dropped traces with console puts and DEBUG_UART */
- if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL || rec.force_debug) {
+ if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL ||
+ rec.flags & LOGRECF_FORCE_DEBUG) {
char buf[CONFIG_SYS_CBSIZE];
va_start(args, fmt);
diff --git a/common/log_console.c b/common/log_console.c
index 6abb13c..3f61774 100644
--- a/common/log_console.c
+++ b/common/log_console.c
@@ -15,6 +15,7 @@
static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
{
int fmt = gd->log_fmt;
+ bool add_space = false;
/*
* The output format is designed to give someone a fighting chance of
@@ -26,18 +27,21 @@
* - function is an identifier and ends with ()
* - message has a space before it unless it is on its own
*/
- if (fmt & BIT(LOGF_LEVEL))
- printf("%s.", log_get_level_name(rec->level));
- if (fmt & BIT(LOGF_CAT))
- printf("%s,", log_get_cat_name(rec->cat));
- if (fmt & BIT(LOGF_FILE))
- printf("%s:", rec->file);
- if (fmt & BIT(LOGF_LINE))
- printf("%d-", rec->line);
- if (fmt & BIT(LOGF_FUNC))
- printf("%s()", rec->func);
+ if (!(rec->flags & LOGRECF_CONT) && fmt != BIT(LOGF_MSG)) {
+ add_space = true;
+ if (fmt & BIT(LOGF_LEVEL))
+ printf("%s.", log_get_level_name(rec->level));
+ if (fmt & BIT(LOGF_CAT))
+ printf("%s,", log_get_cat_name(rec->cat));
+ if (fmt & BIT(LOGF_FILE))
+ printf("%s:", rec->file);
+ if (fmt & BIT(LOGF_LINE))
+ printf("%d-", rec->line);
+ if (fmt & BIT(LOGF_FUNC))
+ printf("%s()", rec->func);
+ }
if (fmt & BIT(LOGF_MSG))
- printf("%s%s", fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
+ printf("%s%s", add_space ? " " : "", rec->msg);
return 0;
}
diff --git a/common/scp03.c b/common/scp03.c
new file mode 100644
index 0000000..09ef7b5
--- /dev/null
+++ b/common/scp03.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#include <common.h>
+#include <scp03.h>
+#include <tee.h>
+#include <tee/optee_ta_scp03.h>
+
+static int scp03_enable(bool provision)
+{
+ const struct tee_optee_ta_uuid uuid = PTA_SCP03_UUID;
+ struct tee_open_session_arg session;
+ struct tee_invoke_arg invoke;
+ struct tee_param param;
+ struct udevice *tee = NULL;
+
+ tee = tee_find_device(tee, NULL, NULL, NULL);
+ if (!tee)
+ return -ENODEV;
+
+ memset(&session, 0, sizeof(session));
+ tee_optee_ta_uuid_to_octets(session.uuid, &uuid);
+ if (tee_open_session(tee, &session, 0, NULL))
+ return -ENXIO;
+
+ memset(¶m, 0, sizeof(param));
+ param.attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
+ param.u.value.a = provision;
+
+ memset(&invoke, 0, sizeof(invoke));
+ invoke.func = PTA_CMD_ENABLE_SCP03;
+ invoke.session = session.session;
+
+ if (tee_invoke_func(tee, &invoke, 1, ¶m))
+ return -EIO;
+
+ tee_close_session(tee, session.session);
+
+ return 0;
+}
+
+int tee_enable_scp03(void)
+{
+ return scp03_enable(false);
+}
+
+int tee_provision_scp03(void)
+{
+ return scp03_enable(true);
+}
diff --git a/common/spl/spl.c b/common/spl/spl.c
index e3d8408..5f51098 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -16,6 +16,7 @@
#include <init.h>
#include <irq_func.h>
#include <log.h>
+#include <mapmem.h>
#include <serial.h>
#include <spl.h>
#include <asm/global_data.h>
@@ -168,7 +169,7 @@
__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
{
- return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset);
+ return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0);
}
void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
@@ -694,7 +695,7 @@
#endif
switch (spl_image.os) {
case IH_OS_U_BOOT:
- debug("Jumping to U-Boot\n");
+ debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
break;
#if CONFIG_IS_ENABLED(ATF)
case IH_OS_ARM_TRUSTED_FIRMWARE:
@@ -741,7 +742,6 @@
debug("Failed to stash bootstage: err=%d\n", ret);
#endif
- debug("loaded - jumping to %s...\n", spl_phase_name(spl_next_phase()));
spl_board_prepare_for_boot();
jump_to_image_no_args(&spl_image);
}
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 75c8ff0..49508fc 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -11,6 +11,7 @@
#include <image.h>
#include <log.h>
#include <malloc.h>
+#include <mapmem.h>
#include <spl.h>
#include <sysinfo.h>
#include <asm/cache.h>
@@ -235,11 +236,11 @@
size_t length;
int len;
ulong size;
- ulong load_addr, load_ptr;
+ ulong load_addr;
+ void *load_ptr;
void *src;
ulong overhead;
int nr_sectors;
- int align_len = ARCH_DMA_MINALIGN - 1;
uint8_t image_comp = -1, type = -1;
const void *data;
const void *fit = ctx->fit;
@@ -269,11 +270,13 @@
}
if (external_data) {
+ void *src_ptr;
+
/* External data */
if (fit_image_get_data_size(fit, node, &len))
return -ENOENT;
- load_ptr = (load_addr + align_len) & ~align_len;
+ src_ptr = map_sysmem(ALIGN(load_addr, ARCH_DMA_MINALIGN), len);
length = len;
overhead = get_aligned_image_overhead(info, offset);
@@ -281,12 +284,12 @@
if (info->read(info,
sector + get_aligned_image_offset(info, offset),
- nr_sectors, (void *)load_ptr) != nr_sectors)
+ nr_sectors, src_ptr) != nr_sectors)
return -EIO;
- debug("External data: dst=%lx, offset=%x, size=%lx\n",
- load_ptr, offset, (unsigned long)length);
- src = (void *)load_ptr + overhead;
+ debug("External data: dst=%p, offset=%x, size=%lx\n",
+ src_ptr, offset, (unsigned long)length);
+ src = src_ptr + overhead;
} else {
/* Embedded data */
if (fit_image_get_data(fit, node, &data, &length)) {
@@ -295,7 +298,7 @@
}
debug("Embedded data: dst=%lx, size=%lx\n", load_addr,
(unsigned long)length);
- src = (void *)data;
+ src = (void *)data; /* cast away const */
}
if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
@@ -309,16 +312,16 @@
if (CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS))
board_fit_image_post_process(&src, &length);
+ load_ptr = map_sysmem(load_addr, length);
if (IS_ENABLED(CONFIG_SPL_GZIP) && image_comp == IH_COMP_GZIP) {
size = length;
- if (gunzip((void *)load_addr, CONFIG_SYS_BOOTM_LEN,
- src, &size)) {
+ if (gunzip(load_ptr, CONFIG_SYS_BOOTM_LEN, src, &size)) {
puts("Uncompressing error\n");
return -EIO;
}
length = size;
} else {
- memcpy((void *)load_addr, src, length);
+ memcpy(load_ptr, src, length);
}
if (image_info) {
@@ -383,7 +386,7 @@
}
/* Make the load-address of the FDT available for the SPL framework */
- spl_image->fdt_addr = (void *)image_info.load_addr;
+ spl_image->fdt_addr = map_sysmem(image_info.load_addr, 0);
if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY))
return 0;
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index c011870..2696d0b 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -1,4 +1,4 @@
-CONFIG_SYS_TEXT_BASE=0
+CONFIG_SYS_TEXT_BASE=0x200000
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=1
diff --git a/doc/Makefile b/doc/Makefile
index a686d47..683e4b5 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -56,7 +56,6 @@
PYTHONDONTWRITEBYTECODE=1 \
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
$(SPHINXBUILD) \
- -W \
-b $2 \
-c $(abspath $(srctree)/$(src)) \
-d $(abspath $(BUILDDIR)/.doctrees/$3) \
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 60ee1e0..8b18a22 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -17,6 +17,12 @@
all the generic code, not specific to any one architecture. The idea is to
create unit tests which we can run to test this upper level code.
+Sandbox allows development of many types of new features in a traditional way,
+rather than needing to test each iteration on real hardware. Many U-Boot
+features were developed on sandbox, including the core driver model, most
+uclasses, verified boot, bloblist, logging and dozens of others. Sandbox has
+enabled many large-scale code refactors as well.
+
CONFIG_SANDBOX is defined when building a native board.
The board name is 'sandbox' but the vendor name is unset, so there is a
@@ -76,7 +82,7 @@
You can issue commands as your would normally. If the command you want is
not supported you can add it to include/configs/sandbox.h.
-To exit, type 'reset' or press Ctrl-C.
+To exit, type 'poweroff' or press Ctrl-C.
Console / LCD support
@@ -486,42 +492,10 @@
-------
U-Boot sandbox can be used to run various tests, mostly in the test/
-directory. These include:
+directory.
-command_ut:
- Unit tests for command parsing and handling
-compression:
- Unit tests for U-Boot's compression algorithms, useful for
- security checking. It supports gzip, bzip2, lzma and lzo.
-driver model:
- Run this pytest::
-
- ./test/py/test.py --bd sandbox --build -k ut_dm -v
-
-image:
- Unit tests for images:
- test/image/test-imagetools.sh - multi-file images
- test/image/test-fit.py - FIT images
-tracing:
- test/trace/test-trace.sh tests the tracing system (see README.trace)
-verified boot:
- See test/vboot/vboot_test.sh for this
-
-If you change or enhance any of the above subsystems, you shold write or
-expand a test and include it with your patch series submission. Test
-coverage in U-Boot is limited, as we need to work to improve it.
-
-Note that many of these tests are implemented as commands which you can
-run natively on your board if desired (and enabled).
-
-To run all tests use "make check".
-
-To run a single test in an existing sandbox build, you can use -T to use the
-test device tree, and -c to select the test:
-
- /tmp/b/sandbox/u-boot -T -c "ut dm pci_busdev"
-
-This runs dm_test_pci_busdev() which is in test/dm/pci.c
+See :doc:`../develop/tests_sandbox` for more information and
+:doc:`../develop/testing` for information about testing generally.
Memory Map
@@ -537,5 +511,7 @@
e000 CONFIG_BLOBLIST_ADDR Blob list
10000 CONFIG_MALLOC_F_ADDR Early memory allocation
f0000 CONFIG_PRE_CON_BUF_ADDR Pre-console buffer
- 100000 CONFIG_TRACE_EARLY_ADDR Early trace buffer (if enabled)
+ 100000 CONFIG_TRACE_EARLY_ADDR Early trace buffer (if enabled). Also used
+ as the SPL load buffer in spl_test_load().
+ 200000 CONFIG_SYS_TEXT_BASE Load buffer for U-Boot (sandbox_spl only)
======= ======================== ===============================
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index ac57fdb..41c0ba1 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -33,3 +33,5 @@
coccinelle
testing
py_testing
+ tests_writing
+ tests_sandbox
diff --git a/doc/develop/logging.rst b/doc/develop/logging.rst
index 60c18c5..f4e9250 100644
--- a/doc/develop/logging.rst
+++ b/doc/develop/logging.rst
@@ -96,16 +96,45 @@
as the category, so you should #define this right at the top of the source
file to ensure the category is correct.
+Generally each log format_string ends with a newline. If it does not, then the
+next log statement will have the LOGRECF_CONT flag set. This can be used to
+continue the statement on the same line as the previous one without emitting
+new header information (such as category/level). This behaviour is implemented
+with log_console. Here is an example that prints a list all on one line with
+the tags at the start:
+
+.. code-block:: c
+
+ log_debug("Here is a list:");
+ for (i = 0; i < count; i++)
+ log_debug(" item %d", i);
+ log_debug("\n");
+
+Also see the special category LOGL_CONT and level LOGC_CONT.
+
You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This
can be used whenever your function returns an error value:
.. code-block:: c
- return log_ret(uclass_first_device(UCLASS_MMC, &dev));
+ return log_ret(uclass_first_device_err(UCLASS_MMC, &dev));
This will write a log record when an error code is detected (a value < 0). This
can make it easier to trace errors that are generated deep in the call stack.
+The log_msg_ret() variant will print a short string if CONFIG_LOG_ERROR_RETURN
+is enabled. So long as the string is unique within the function you can normally
+determine exactly which call failed:
+
+.. code-block:: c
+
+ ret = gpio_request_by_name(dev, "cd-gpios", 0, &desc, GPIOD_IS_IN);
+ if (ret)
+ return log_msg_ret("gpio", ret);
+
+Some functions return 0 for success and any other value is an error. For these,
+log_retz() and log_msg_retz() are available.
+
Convenience functions
~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst
index 7f01858..c4cecc0 100644
--- a/doc/develop/py_testing.rst
+++ b/doc/develop/py_testing.rst
@@ -13,7 +13,8 @@
U-Boot; there can be no disconnect.
- There is no need to write or embed test-related code into U-Boot itself.
It is asserted that writing test-related code in Python is simpler and more
- flexible than writing it all in C.
+ flexible than writing it all in C. But see :doc:`tests_writing` for caveats
+ and more discussion / analysis.
- It is reasonably simple to interact with U-Boot in this way.
Requirements
diff --git a/doc/develop/testing.rst b/doc/develop/testing.rst
index 4bc9ca3..ced13ac 100644
--- a/doc/develop/testing.rst
+++ b/doc/develop/testing.rst
@@ -8,17 +8,27 @@
Running tests
-------------
-To run most tests on sandbox, type this:
+To run most tests on sandbox, type this::
make check
in the U-Boot directory. Note that only the pytest suite is run using this
command.
-Some tests take ages to run. To run just the quick ones, type this:
+Some tests take ages to run and are marked with @pytest.mark.slow. To run just
+the quick ones, type this::
make qcheck
+It is also possible to run just the tests for tools (patman, binman, etc.).
+Such tests are included with those tools, i.e. no actual U-Boot unit tests are
+run. Type this::
+
+ make tcheck
+
+All of the above use the test/run script with a paremeter to select which tests
+are run.
+
Sandbox
-------
@@ -26,6 +36,7 @@
allows test to be executed without needing target hardware. The 'sandbox'
target provides this feature and it is widely used in tests.
+See :doc:`tests_sandbox` for more information.
Pytest Suite
------------
@@ -35,14 +46,27 @@
inject test commands and check the result. It is slower to run than C code,
but provides the ability to unify lots of tests and summarise their results.
-You can run the tests on sandbox with:
+You can run the tests on sandbox with::
- ./test/py/test.py --bd sandbox --build
+ ./test/py/test.py --bd sandbox --build
This will produce HTML output in build-sandbox/test-log.html
+Some tests run with other versions of sandbox. For example sandbox_flattree
+runs the tests with livetree (the hierachical devicetree) disabled. You can
+also select particular tests with -k::
+
+ ./test/py/test.py --bd sandbox_flattree --build -k hello
+
+There are some special tests that run in SPL. For this you need the sandbox_spl
+build::
+
+ ./test/py/test.py --bd sandbox_spl --build -k test_spl
+
See test/py/README.md for more information about the pytest suite.
+See :doc:`tests_sandbox` for how to run tests directly (not through pytest).
+
tbot
----
@@ -58,10 +82,14 @@
There are several ad-hoc tests which run outside the pytest environment:
- test/fs - File system test (shell script)
- test/image - FIT and legacy image tests (shell script and Python)
- test/stdint - A test that stdint.h can be used in U-Boot (shell script)
- trace - Test for the tracing feature (shell script)
+test/fs
+ File system test (shell script)
+test/image
+ FIT and legacy image tests (shell script and Python)
+test/stdint
+ A test that stdint.h can be used in U-Boot (shell script)
+trace
+ Test for the tracing feature (shell script)
TODO: Move these into pytest.
@@ -89,6 +117,8 @@
is much easier to add onto a test - writing a new large test can seem
daunting to most contributors.
+See doc:`tests_writing` for how to write tests.
+
Future work
-----------
diff --git a/doc/develop/tests_sandbox.rst b/doc/develop/tests_sandbox.rst
new file mode 100644
index 0000000..84608dc
--- /dev/null
+++ b/doc/develop/tests_sandbox.rst
@@ -0,0 +1,209 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Sandbox tests
+=============
+
+Test Design
+-----------
+
+Most uclasses and many functions of U-Boot have sandbox tests. This allows much
+of the code to be checked in an developer-friendly environment.
+
+Sandbox provides a way to write and run unit tests. The traditional approach to
+unit tests is to build lots of little executables, one for each test or
+category of tests. With sandbox, so far as possible, all the tests share a
+small number of executables (e.g. 'u-boot' for sandbox, 'u-boot-spl' and
+'u-boot' for sandbox_spl) and can be run very quickly. The vast majority of
+tests can run on the 'sandbox' build,
+
+Available tests
+---------------
+
+Some of the available tests are:
+
+ - command_ut: Unit tests for command parsing and handling
+ - compression: Unit tests for U-Boot's compression algorithms, useful for
+ security checking. It supports gzip, bzip2, lzma and lzo.
+ - image: Unit tests for images:
+
+ - test/image/test-imagetools.sh - multi-file images
+ - test/py/tests/test-fit.py - FIT images
+ - tracing: test/trace/test-trace.sh tests the tracing system (see
+ README.trace)
+ - verified boot: test/py/tests/test_vboot.py
+
+If you change or enhance any U-Boot subsystem, you should write or expand a
+test and include it with your patch series submission. Test coverage in some
+older areas of U-Boot is still somewhat limited and we need to work to improve
+it.
+
+Note that many of these tests are implemented as commands which you can
+run natively on your board if desired (and enabled).
+
+To run all tests, use 'make check'.
+
+
+Running sandbox tests directly
+------------------------------
+
+Typically tests are run using the pytest suite. Running pytests on sandbox is
+easy and always gets things right. For example some tests require files to be
+set up before they can work.
+
+But it is also possible to run some sandbox tests directly. For example, this
+runs the dm_test_gpio() test which you can find in test/dm/gpio.c::
+
+ $ ./u-boot -T -c "ut dm gpio"
+
+
+ U-Boot 2021.01
+
+ Model: sandbox
+ DRAM: 128 MiB
+ WDT: Started with servicing (60s timeout)
+ MMC: mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD)
+ In: serial
+ Out: vidconsole
+ Err: vidconsole
+ Model: sandbox
+ SCSI:
+ Net: eth0: eth@10002000, eth5: eth@10003000, eth3: sbe5, eth6: eth@10004000
+ Test: dm_test_gpio: gpio.c
+ Test: dm_test_gpio: gpio.c (flat tree)
+ Failures: 0
+
+The -T option tells the U-Boot sandbox to run with the 'test' devicetree
+(test.dts) instead of -D which selects the normal sandbox.dts - this is
+necessary because many tests rely on nodes or properties in the test devicetree.
+If you try running tests without -T then you may see failures, like::
+
+ $ ./u-boot -c "ut dm gpio"
+
+
+ U-Boot 2021.01
+
+ DRAM: 128 MiB
+ WDT: Not found!
+ MMC:
+ In: serial
+ Out: serial
+ Err: serial
+ SCSI:
+ Net: No ethernet found.
+ Please run with test device tree:
+ ./u-boot -d arch/sandbox/dts/test.dtb
+ Test: dm_test_gpio: gpio.c
+ test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
+ Test: dm_test_gpio: gpio.c (flat tree)
+ test/dm/gpio.c:37, dm_test_gpio(): 0 == gpio_lookup_name("b4", &dev, &offset, &gpio): Expected 0x0 (0), got 0xffffffea (-22)
+ Failures: 2
+
+The message above should provide a hint if you forget to use the -T flag. Even
+running with -D will produce different results.
+
+You can easily use gdb on these tests, without needing --gdbserver::
+
+ $ gdb u-boot --args -T -c "ut dm gpio"
+ ...
+ (gdb) break dm_test_gpio
+ Breakpoint 1 at 0x1415bd: file test/dm/gpio.c, line 37.
+ (gdb) run -T -c "ut dm gpio"
+ Starting program: u-boot -T -c "ut dm gpio"
+ Test: dm_test_gpio: gpio.c
+
+ Breakpoint 1, dm_test_gpio (uts=0x5555558029a0 <global_dm_test_state>)
+ at files/test/dm/gpio.c:37
+ 37 ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio));
+ (gdb)
+
+You can then single-step and look at variables as needed.
+
+
+Running sandbox_spl tests directly
+----------------------------------
+
+SPL is the phase before U-Boot proper. It is present in the sandbox_spl build,
+so you can run SPL like this::
+
+ ./spl/u-boot-spl
+
+SPL tests are special in that they run (only in the SPL phase, of course) if the
+-u flag is given::
+
+ ./spl/u-boot-spl -u
+
+ U-Boot SPL 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
+ Running 5 driver model tests
+ Test: dm_test_of_plat_base: of_platdata.c (flat tree)
+ Test: dm_test_of_plat_dev: of_platdata.c (flat tree)
+ Test: dm_test_of_plat_parent: of_platdata.c (flat tree)
+ Test: dm_test_of_plat_phandle: of_platdata.c (flat tree)
+ Test: dm_test_of_plat_props: of_platdata.c (flat tree)
+ Failures: 0
+
+
+ U-Boot 2021.01-00723-g43c77b51be5-dirty (Jan 24 2021 - 16:38:24 -0700)
+
+ DRAM: 128 MiB
+ ...
+
+It is not possible to run SPL tests in U-Boot proper, firstly because they are
+not built into U-Boot proper and secondly because the environment is very
+different, e.g. some SPL tests rely on of-platdata which is only available in
+SPL.
+
+Note that after running, SPL continues to boot into U-Boot proper. You can add
+'-c exit' to make U-Boot quit without doing anything further. It is not
+currently possible to run SPL tests and then stop, since the pytests require
+that U-Boot produces the expected banner.
+
+You can use the -k flag to select which tests run::
+
+ ./spl/u-boot-spl -u -k dm_test_of_plat_parent
+
+Of course you can use gdb with sandbox_spl, just as with sandbox.
+
+
+Running all tests directly
+--------------------------
+
+A fast way to run all sandbox tests is::
+
+ ./u-boot -T -c "ut all"
+
+It typically runs single-thread in 6 seconds on 2021 hardware, with 2s of that
+to the delays in the time test.
+
+This should not be considered a substitute for 'make check', but can be helpful
+for git bisect, etc.
+
+
+What tests are built in?
+------------------------
+
+Whatever sandbox build is used, which tests are present is determined by which
+source files are built. For sandbox_spl, the of_platdata tests are built
+because of the build rule in test/dm/Makefile::
+
+ ifeq ($(CONFIG_SPL_BUILD),y)
+ obj-$(CONFIG_SPL_OF_PLATDATA) += of_platdata.o
+ else
+ ...other tests for non-spl
+ endif
+
+You can get a list of tests in a U-Boot ELF file by looking for the
+linker_list::
+
+ $ nm /tmp/b/sandbox_spl/spl/u-boot-spl |grep 2_dm_test
+ 000000000001f200 D _u_boot_list_2_dm_test_2_dm_test_of_plat_base
+ 000000000001f220 D _u_boot_list_2_dm_test_2_dm_test_of_plat_dev
+ 000000000001f240 D _u_boot_list_2_dm_test_2_dm_test_of_plat_parent
+ 000000000001f260 D _u_boot_list_2_dm_test_2_dm_test_of_plat_phandle
+ 000000000001f280 D _u_boot_list_2_dm_test_2_dm_test_of_plat_props
+
+
+Writing tests
+-------------
+
+See :doc:`tests_writing` for how to write new tests.
+
diff --git a/doc/develop/tests_writing.rst b/doc/develop/tests_writing.rst
new file mode 100644
index 0000000..1ddf7a3
--- /dev/null
+++ b/doc/develop/tests_writing.rst
@@ -0,0 +1,346 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2021 Google LLC
+.. sectionauthor:: Simon Glass <sjg@chromium.org>
+
+Writing Tests
+=============
+
+This describes how to write tests in U-Boot and describes the possible options.
+
+Test types
+----------
+
+There are two basic types of test in U-Boot:
+
+ - Python tests, in test/py/tests
+ - C tests, in test/ and its subdirectories
+
+(there are also UEFI tests in lib/efi_selftest/ not considered here.)
+
+Python tests talk to U-Boot via the command line. They support both sandbox and
+real hardware. They typically do not require building test code into U-Boot
+itself. They are fairly slow to run, due to the command-line interface and there
+being two separate processes. Python tests are fairly easy to write. They can
+be a little tricky to debug sometimes due to the voluminous output of pytest.
+
+C tests are written directly in U-Boot. While they can be used on boards, they
+are more commonly used with sandbox, as they obviously add to U-Boot code size.
+C tests are easy to write so long as the required facilities exist. Where they
+do not it can involve refactoring or adding new features to sandbox. They are
+fast to run and easy to debug.
+
+Regardless of which test type is used, all tests are collected and run by the
+pytest framework, so there is typically no need to run them separately. This
+means that C tests can be used when it makes sense, and Python tests when it
+doesn't.
+
+
+This table shows how to decide whether to write a C or Python test:
+
+===================== =========================== =============================
+Attribute C test Python test
+===================== =========================== =============================
+Fast to run? Yes No (two separate processes)
+Easy to write? Yes, if required test Yes
+ features exist in sandbox
+ or the target system
+Needs code in U-Boot? Yes No, provided the test can be
+ executed and the result
+ determined using the command
+ line
+Easy to debug? Yes No, since access to the U-Boot
+ state is not available and the
+ amount of output can
+ sometimes require a bit of
+ digging
+Can use gdb? Yes, directly Yes, with --gdbserver
+Can run on boards? Some can, but only if Some
+ compiled in and not
+ dependent on sandboxau
+===================== =========================== =============================
+
+
+Python or C
+-----------
+
+Typically in U-Boot we encourage C test using sandbox for all features. This
+allows fast testing, easy development and allows contributors to make changes
+without needing dozens of boards to test with.
+
+When a test requires setup or interaction with the running host (such as to
+generate images and then running U-Boot to check that they can be loaded), or
+cannot be run on sandbox, Python tests should be used. These should typically
+NOT rely on running with sandbox, but instead should function correctly on any
+board supported by U-Boot.
+
+
+How slow are Python tests?
+--------------------------
+
+Under the hood, when running on sandbox, Python tests work by starting a sandbox
+test and connecting to it via a pipe. Each interaction with the U-Boot process
+requires at least a context switch to handle the pipe interaction. The test
+sends a command to U-Boot, which then reacts and shows some output, then the
+test sees that and continues. Of course on real hardware, communications delays
+(e.g. with a serial console) make this slower.
+
+For comparison, consider a test that checks the 'md' (memory dump). All times
+below are approximate, as measured on an AMD 2950X system. Here is is the test
+in Python::
+
+ @pytest.mark.buildconfigspec('cmd_memory')
+ def test_md(u_boot_console):
+ """Test that md reads memory as expected, and that memory can be modified
+ using the mw command."""
+
+ ram_base = u_boot_utils.find_ram_base(u_boot_console)
+ addr = '%08x' % ram_base
+ val = 'a5f09876'
+ expected_response = addr + ': ' + val
+ u_boot_console.run_command('mw ' + addr + ' 0 10')
+ response = u_boot_console.run_command('md ' + addr + ' 10')
+ assert(not (expected_response in response))
+ u_boot_console.run_command('mw ' + addr + ' ' + val)
+ response = u_boot_console.run_command('md ' + addr + ' 10')
+ assert(expected_response in response)
+
+This runs a few commands and checks the output. Note that it runs a command,
+waits for the response and then checks it agains what is expected. If run by
+itself it takes around 800ms, including test collection. For 1000 runs it takes
+19 seconds, or 19ms per run. Of course 1000 runs it not that useful since we
+only want to run it once.
+
+There is no exactly equivalent C test, but here is a similar one that tests 'ms'
+(memory search)::
+
+ /* Test 'ms' command with bytes */
+ static int mem_test_ms_b(struct unit_test_state *uts)
+ {
+ u8 *buf;
+
+ buf = map_sysmem(0, BUF_SIZE + 1);
+ memset(buf, '\0', BUF_SIZE);
+ buf[0x0] = 0x12;
+ buf[0x31] = 0x12;
+ buf[0xff] = 0x12;
+ buf[0x100] = 0x12;
+ ut_assertok(console_record_reset_enable());
+ run_command("ms.b 1 ff 12", 0);
+ ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................");
+ ut_assert_nextline("--");
+ ut_assert_nextline("000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 ................");
+ ut_assert_nextline("2 matches");
+ ut_assert_console_end();
+
+ ut_asserteq(2, env_get_hex("memmatches", 0));
+ ut_asserteq(0xff, env_get_hex("memaddr", 0));
+ ut_asserteq(0xfe, env_get_hex("mempos", 0));
+
+ unmap_sysmem(buf);
+
+ return 0;
+ }
+ MEM_TEST(mem_test_ms_b, UT_TESTF_CONSOLE_REC);
+
+This runs the command directly in U-Boot, then checks the console output, also
+directly in U-Boot. If run by itself this takes 100ms. For 1000 runs it takes
+660ms, or 0.66ms per run.
+
+So overall running a C test is perhaps 8 times faster individually and the
+interactions are perhaps 25 times faster.
+
+It should also be noted that the C test is fairly easy to debug. You can set a
+breakpoint on do_mem_search(), which is what implements the 'ms' command,
+single step to see what might be wrong, etc. That is also possible with the
+pytest, but requires two terminals and --gdbserver.
+
+
+Why does speed matter?
+----------------------
+
+Many development activities rely on running tests:
+
+ - 'git bisect run make qcheck' can be used to find a failing commit
+ - test-driven development relies on quick iteration of build/test
+ - U-Boot's continuous integration (CI) systems make use of tests. Running
+ all sandbox tests typically takes 90 seconds and running each qemu test
+ takes about 30 seconds. This is currently dwarfed by the time taken to
+ build all boards
+
+As U-Boot continues to grow its feature set, fast and reliable tests are a
+critical factor factor in developer productivity and happiness.
+
+
+Writing C tests
+---------------
+
+C tests are arranged into suites which are typically executed by the 'ut'
+command. Each suite is in its own file. This section describes how to accomplish
+some common test tasks.
+
+(there are also UEFI C tests in lib/efi_selftest/ not considered here.)
+
+Add a new driver model test
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use this when adding a test for a new or existing uclass, adding new operations
+or features to a uclass, adding new ofnode or dev_read_() functions, or anything
+else related to driver model.
+
+Find a suitable place for your test, perhaps near other test functions in
+existing code, or in a new file. Each uclass should have its own test file.
+
+Declare the test with::
+
+ /* Test that ... */
+ static int dm_test_uclassname_what(struct unit_test_state *uts)
+ {
+ /* test code here */
+
+ return 0;
+ }
+ DM_TEST(dm_test_uclassname_what, UT_TESTF_SCAN_FDT);
+
+Replace 'uclassname' with the name of your uclass, if applicable. Replace 'what'
+with what you are testing.
+
+The flags for DM_TEST() are defined in test/test.h and you typically want
+UT_TESTF_SCAN_FDT so that the devicetree is scanned and all devices are bound
+and ready for use. The DM_TEST macro adds UT_TESTF_DM automatically so that
+the test runner knows it is a driver model test.
+
+Driver model tests are special in that the entire driver model state is
+recreated anew for each test. This ensures that if a previous test deletes a
+device, for example, it does not affect subsequent tests. Driver model tests
+also run both with livetree and flattree, to ensure that both devicetree
+implementations work as expected.
+
+Example commit: c48cb7ebfb4 ("sandbox: add ADC unit tests") [1]
+
+[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/c48cb7ebfb4
+
+
+Add a C test to an existing suite
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use this when you are adding to or modifying an existing feature outside driver
+model. An example is bloblist.
+
+Add a new function in the same file as the rest of the suite and register it
+with the suite. For example, to add a new mem_search test::
+
+ /* Test 'ms' command with 32-bit values */
+ static int mem_test_ms_new_thing(struct unit_test_state *uts)
+ {
+ /* test code here*/
+
+ return 0;
+ }
+ MEM_TEST(mem_test_ms_new_thing, UT_TESTF_CONSOLE_REC);
+
+Note that the MEM_TEST() macros is defined at the top of the file.
+
+Example commit: 9fe064646d2 ("bloblist: Support relocating to a larger space") [1]
+
+[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/9fe064646d2
+
+
+Add a new test suite
+~~~~~~~~~~~~~~~~~~~~
+
+Each suite should focus on one feature or subsystem, so if you are writing a
+new one of those, you should add a new suite.
+
+Create a new file in test/ or a subdirectory and define a macro to register the
+suite. For example::
+
+ #include <common.h>
+ #include <console.h>
+ #include <mapmem.h>
+ #include <dm/test.h>
+ #include <test/ut.h>
+
+ /* Declare a new wibble test */
+ #define WIBBLE_TEST(_name, _flags) UNIT_TEST(_name, _flags, wibble_test)
+
+ /* Tetss go here */
+
+ /* At the bottom of the file: */
+
+ int do_ut_wibble(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+ {
+ struct unit_test *tests = UNIT_TEST_SUITE_START(wibble_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(wibble_test);
+
+ return cmd_ut_category("cmd_wibble", "wibble_test_", tests, n_ents, argc, argv);
+ }
+
+Then add new tests to it as above.
+
+Register this new suite in test/cmd_ut.c by adding to cmd_ut_sub[]::
+
+ /* Within cmd_ut_sub[]... */
+
+ U_BOOT_CMD_MKENT(wibble, CONFIG_SYS_MAXARGS, 1, do_ut_wibble, "", ""),
+
+and adding new help to ut_help_text[]::
+
+ "ut wibble - Test the wibble feature\n"
+
+If your feature is conditional on a particular Kconfig, then you can use #ifdef
+to control that.
+
+Finally, add the test to the build by adding to the Makefile in the same
+directory::
+
+ obj-$(CONFIG_$(SPL_)CMDLINE) += wibble.o
+
+Note that CMDLINE is never enabled in SPL, so this test will only be present in
+U-Boot proper. See below for how to do SPL tests.
+
+As before, you can add an extra Kconfig check if needed::
+
+ ifneq ($(CONFIG_$(SPL_)WIBBLE),)
+ obj-$(CONFIG_$(SPL_)CMDLINE) += wibble.o
+ endif
+
+
+Example commit: 919e7a8fb64 ("test: Add a simple test for bloblist") [1]
+
+[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/919e7a8fb64
+
+
+Making the test run from pytest
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All C tests must run from pytest. Typically this is automatic, since pytest
+scans the U-Boot executable for available tests to run. So long as you have a
+'ut' subcommand for your test suite, it will run. The same applies for driver
+model tests since they use the 'ut dm' subcommand.
+
+See test/py/tests/test_ut.py for how unit tests are run.
+
+
+Add a C test for SPL
+~~~~~~~~~~~~~~~~~~~~
+
+Note: C tests are only available for sandbox_spl at present. There is currently
+no mechanism in other boards to existing SPL tests even if they are built into
+the image.
+
+SPL tests cannot be run from the 'ut' command since there are no commands
+available in SPL. Instead, sandbox (only) calls ut_run_list() on start-up, when
+the -u flag is given. This runs the available unit tests, no matter what suite
+they are in.
+
+To create a new SPL test, follow the same rules as above, either adding to an
+existing suite or creating a new one.
+
+An example SPL test is spl_test_load().
+
+
+Writing Python tests
+--------------------
+
+See :doc:`py_testing` for brief notes how to write Python tests. You
+should be able to use the existing tests in test/py/tests as examples.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 9169fff..637b73c 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -29,7 +29,9 @@
load
loady
mbr
+ md
pstore
qfw
sbi
true
+ scp03
diff --git a/doc/usage/md.rst b/doc/usage/md.rst
new file mode 100644
index 0000000..4c1073e
--- /dev/null
+++ b/doc/usage/md.rst
@@ -0,0 +1,106 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+md command
+==========
+
+Synopis
+-------
+
+::
+
+ md <address>[<data_size>] [<length>]
+
+Description
+-----------
+
+The md command is used to dump the contents of memory. It uses a standard
+format that includes the address, hex data and ASCII display. It supports
+various data sizes and uses the endianness of the target.
+
+The specified data_size and length become the defaults for future memory
+commands commands.
+
+address
+ start address to display
+
+data_size
+ size of each value to display (defaults to .l):
+
+ ========= ===================
+ data_size Output size
+ ========= ===================
+ .b byte
+ .w word (16 bits)
+ .l long (32 bits)
+ .q quadword (64 bits)
+ ========= ===================
+
+length
+ number of values to dump. Defaults to 40 (0d64). Note that this is not
+ the same as the number of bytes, unless .b is used.
+
+Note that the format of 'md.b' can be emulated from linux with::
+
+ # This works but requires using sed to get the extra spaces
+ # <addr> is the address, <f> is the filename
+ xxd -o <addr> -g1 <f> |sed 's/ / /' >bad
+
+ # This uses a single tool but the offset always starts at 0
+ # <f> is the filename
+ hexdump -v -e '"%08.8_ax: " 16/1 "%02x " " "' -e '16/1 "%_p" "\n" ' <f>
+
+
+Example
+-------
+
+::
+
+ => md 10000
+ 00010000: 00010000 00000000 f0f30f00 00005596 .............U..
+ 00010010: 10011010 00000000 10011010 00000000 ................
+ 00010020: 10011050 00000000 b96d4cd8 00007fff P........Lm.....
+ 00010030: 00000000 00000000 f0f30f18 00005596 .............U..
+ 00010040: 10011040 00000000 10011040 00000000 @.......@.......
+ 00010050: b96d4cd8 00007fff 10011020 00000000 .Lm..... .......
+ 00010060: 00000003 000000c3 00000000 00000000 ................
+ 00010070: 00000000 00000000 f0e892f3 00005596 .............U..
+ 00010080: 00000000 000000a1 00000000 00000000 ................
+ 00010090: 00000000 00000000 f0e38aa6 00005596 .............U..
+ 000100a0: 00000000 000000a6 00000022 00000000 ........".......
+ 000100b0: 00000001 00000000 f0e38aa1 00005596 .............U..
+ 000100c0: 00000000 000000be 00000000 00000000 ................
+ 000100d0: 00000000 00000000 00000000 00000000 ................
+ 000100e0: 00000000 00000000 00000000 00000000 ................
+ 000100f0: 00000000 00000000 00000000 00000000 ................
+ => md.b 10000
+ 00010000: 00 00 01 00 00 00 00 00 00 0f f3 f0 96 55 00 00 .............U..
+ 00010010: 10 10 01 10 00 00 00 00 10 10 01 10 00 00 00 00 ................
+ 00010020: 50 10 01 10 00 00 00 00 d8 4c 6d b9 ff 7f 00 00 P........Lm.....
+ 00010030: 00 00 00 00 00 00 00 00 18 0f f3 f0 96 55 00 00 .............U..
+ => md.b 10000 10
+ 00010000: 00 00 01 00 00 00 00 00 00 0f f3 f0 96 55 00 00 .............U..
+ =>
+ 00010010: 10 10 01 10 00 00 00 00 10 10 01 10 00 00 00 00 ................
+ =>
+ 00010020: 50 10 01 10 00 00 00 00 d8 4c 6d b9 ff 7f 00 00 P........Lm.....
+ =>
+ => md.q 10000
+ 00010000: 0000000000010000 00005596f0f30f00 .............U..
+ 00010010: 0000000010011010 0000000010011010 ................
+ 00010020: 0000000010011050 00007fffb96d4cd8 P........Lm.....
+ 00010030: 0000000000000000 00005596f0f30f18 .............U..
+ 00010040: 0000000010011040 0000000010011040 @.......@.......
+ 00010050: 00007fffb96d4cd8 0000000010011020 .Lm..... .......
+ 00010060: 000000c300000003 0000000000000000 ................
+ 00010070: 0000000000000000 00005596f0e892f3 .............U..
+
+The empty commands cause a 'repeat', so that md shows the next available data
+in the same format as before.
+
+
+Return value
+------------
+
+The return value $? is always 0 (true).
+
+
diff --git a/doc/usage/scp03.rst b/doc/usage/scp03.rst
new file mode 100644
index 0000000..7ff87ed
--- /dev/null
+++ b/doc/usage/scp03.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+scp03 command
+=============
+
+Synopsis
+--------
+
+::
+
+ scp03 enable
+ scp03 provision
+
+Description
+-----------
+
+The *scp03* command calls into a Trusted Application executing in a
+Trusted Execution Environment to enable (if present) the Secure
+Channel Protocol 03 stablished between the processor and the secure
+element.
+
+This protocol encrypts all the communication between the processor and
+the secure element using a set of pre-defined keys. These keys can be
+rotated (provisioned) using the *provision* request.
+
+See also
+--------
+
+For some information on the internals implemented in the TEE, please
+check the GlobalPlatform documentation on `Secure Channel Protocol '03'`_
+
+.. _Secure Channel Protocol '03':
+ https://globalplatform.org/wp-content/uploads/2014/07/GPC_2.3_D_SCP03_v1.1.2_PublicRelease.pdf
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 4a9b74e..f24db87 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -3,6 +3,8 @@
* Copyright (c) 2013 Google, Inc
*/
+#define LOG_CATEGORY UCLASS_GPIO
+
#include <common.h>
#include <dm.h>
#include <log.h>
@@ -21,6 +23,7 @@
#include <dm/device_compat.h>
#include <linux/bug.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -220,7 +223,7 @@
static int gpio_find_and_xlate(struct gpio_desc *desc,
struct ofnode_phandle_args *args)
{
- struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+ const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
if (ops->xlate)
return ops->xlate(desc->dev, desc, args);
@@ -353,6 +356,7 @@
int dm_gpio_request(struct gpio_desc *desc, const char *label)
{
+ const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
struct udevice *dev = desc->dev;
struct gpio_dev_priv *uc_priv;
char *str;
@@ -364,8 +368,8 @@
str = strdup(label);
if (!str)
return -ENOMEM;
- if (gpio_get_ops(dev)->request) {
- ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
+ if (ops->request) {
+ ret = ops->request(dev, desc->offset, label);
if (ret) {
free(str);
return ret;
@@ -442,14 +446,15 @@
int _dm_gpio_free(struct udevice *dev, uint offset)
{
+ const struct dm_gpio_ops *ops = gpio_get_ops(dev);
struct gpio_dev_priv *uc_priv;
int ret;
uc_priv = dev_get_uclass_priv(dev);
if (!uc_priv->name[offset])
return -ENXIO;
- if (gpio_get_ops(dev)->rfree) {
- ret = gpio_get_ops(dev)->rfree(dev, offset);
+ if (ops->rfree) {
+ ret = ops->rfree(dev, offset);
if (ret)
return ret;
}
@@ -515,11 +520,8 @@
ret = gpio_to_device(gpio, &desc);
if (ret)
return ret;
- ret = check_reserved(&desc, "dir_input");
- if (ret)
- return ret;
- return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
+ return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
}
/**
@@ -534,24 +536,25 @@
int gpio_direction_output(unsigned gpio, int value)
{
struct gpio_desc desc;
+ ulong flags;
int ret;
ret = gpio_to_device(gpio, &desc);
if (ret)
return ret;
- ret = check_reserved(&desc, "dir_output");
- if (ret)
- return ret;
- return gpio_get_ops(desc.dev)->direction_output(desc.dev,
- desc.offset, value);
+ flags = GPIOD_IS_OUT;
+ if (value)
+ flags |= GPIOD_IS_OUT_ACTIVE;
+ return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
}
static int _gpio_get_value(const struct gpio_desc *desc)
{
+ const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
int value;
- value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
+ value = ops->get_value(desc->dev, desc->offset);
return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
}
@@ -569,6 +572,7 @@
int dm_gpio_set_value(const struct gpio_desc *desc, int value)
{
+ const struct dm_gpio_ops *ops;
int ret;
ret = check_reserved(desc, "set_value");
@@ -578,21 +582,33 @@
if (desc->flags & GPIOD_ACTIVE_LOW)
value = !value;
+ /* GPIOD_ are directly managed by driver in set_flags */
+ ops = gpio_get_ops(desc->dev);
+ if (ops->set_flags) {
+ ulong flags = desc->flags;
+
+ if (value)
+ flags |= GPIOD_IS_OUT_ACTIVE;
+ else
+ flags &= ~GPIOD_IS_OUT_ACTIVE;
+ return ops->set_flags(desc->dev, desc->offset, flags);
+ }
+
/*
* Emulate open drain by not actively driving the line high or
* Emulate open source by not actively driving the line low
*/
if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
(desc->flags & GPIOD_OPEN_SOURCE && !value))
- return gpio_get_ops(desc->dev)->direction_input(desc->dev,
- desc->offset);
+ return ops->direction_input(desc->dev, desc->offset);
else if (desc->flags & GPIOD_OPEN_DRAIN ||
desc->flags & GPIOD_OPEN_SOURCE)
- return gpio_get_ops(desc->dev)->direction_output(desc->dev,
- desc->offset,
- value);
+ return ops->direction_output(desc->dev, desc->offset, value);
- gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
+ ret = ops->set_value(desc->dev, desc->offset, value);
+ if (ret)
+ return ret;
+
return 0;
}
@@ -620,10 +636,21 @@
return 0;
}
-static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+/**
+ * _dm_gpio_set_flags() - Send flags to the driver
+ *
+ * This uses the best available method to send the given flags to the driver.
+ * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
+ * of GPIOD_IS_OUT_ACTIVE.
+ *
+ * @desc: GPIO description
+ * @flags: flags value to set
+ * @return 0 if OK, -ve on error
+ */
+static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
{
struct udevice *dev = desc->dev;
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ const struct dm_gpio_ops *ops = gpio_get_ops(dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
int ret = 0;
@@ -638,38 +665,52 @@
return ret;
}
- /* GPIOD_ are directly managed by driver in set_dir_flags*/
- if (ops->set_dir_flags) {
- ret = ops->set_dir_flags(dev, desc->offset, flags);
+ /* If active low, invert the output state */
+ if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
+ (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
+ flags ^= GPIOD_IS_OUT_ACTIVE;
+
+ /* GPIOD_ are directly managed by driver in set_flags */
+ if (ops->set_flags) {
+ ret = ops->set_flags(dev, desc->offset, flags);
} else {
if (flags & GPIOD_IS_OUT) {
- ret = ops->direction_output(dev, desc->offset,
- GPIOD_FLAGS_OUTPUT(flags));
+ bool value = flags & GPIOD_IS_OUT_ACTIVE;
+
+ ret = ops->direction_output(dev, desc->offset, value);
} else if (flags & GPIOD_IS_IN) {
ret = ops->direction_input(dev, desc->offset);
}
}
- /* save the flags also in descriptor */
- if (!ret)
- desc->flags = flags;
-
return ret;
}
-int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
{
+ ulong flags;
int ret;
ret = check_reserved(desc, "set_dir_flags");
if (ret)
return ret;
- /* combine the requested flags (for IN/OUT) and the descriptor flags */
- flags |= desc->flags;
- ret = _dm_gpio_set_dir_flags(desc, flags);
+ flags = (desc->flags & ~clr) | set;
- return ret;
+ ret = _dm_gpio_set_flags(desc, flags);
+ if (ret)
+ return ret;
+
+ /* save the flags also in descriptor */
+ desc->flags = flags;
+
+ return 0;
+}
+
+int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+{
+ /* combine the requested flags (for IN/OUT) and the descriptor flags */
+ return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
}
int dm_gpio_set_dir(struct gpio_desc *desc)
@@ -680,42 +721,57 @@
if (ret)
return ret;
- return _dm_gpio_set_dir_flags(desc, desc->flags);
+ return _dm_gpio_set_flags(desc, desc->flags);
}
-int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
+int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
+ ulong set)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ ret = dm_gpio_clrset_flags(&desc[i], clr, set);
+ if (ret)
+ return log_ret(ret);
+ }
+
+ return 0;
+}
+
+int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
{
struct udevice *dev = desc->dev;
int ret, value;
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
- ulong dir_flags;
+ const struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ ulong flags;
- ret = check_reserved(desc, "get_dir_flags");
+ ret = check_reserved(desc, "get_flags");
if (ret)
return ret;
/* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
- if (ops->get_dir_flags) {
- ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
+ if (ops->get_flags) {
+ ret = ops->get_flags(dev, desc->offset, &flags);
if (ret)
return ret;
/* GPIOD_ACTIVE_LOW is saved in desc->flags */
- value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
+ value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
if (desc->flags & GPIOD_ACTIVE_LOW)
value = !value;
- dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
- dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
+ flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
+ flags |= (desc->flags & GPIOD_ACTIVE_LOW);
if (value)
- dir_flags |= GPIOD_IS_OUT_ACTIVE;
+ flags |= GPIOD_IS_OUT_ACTIVE;
} else {
- dir_flags = desc->flags;
+ flags = desc->flags;
/* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
- dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
+ flags &= ~GPIOD_IS_OUT_ACTIVE;
if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
- dir_flags |= GPIOD_IS_OUT_ACTIVE;
+ flags |= GPIOD_IS_OUT_ACTIVE;
}
- *flags = dir_flags;
+ *flagsp = flags;
return 0;
}
@@ -785,7 +841,7 @@
const char **namep)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ const struct dm_gpio_ops *ops = gpio_get_ops(dev);
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
if (!device_active(dev))
@@ -822,7 +878,7 @@
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
{
- struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ const struct dm_gpio_ops *ops = gpio_get_ops(dev);
struct gpio_dev_priv *priv;
char *str = buf;
int func;
@@ -862,7 +918,7 @@
#if CONFIG_IS_ENABLED(ACPIGEN)
int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
{
- struct dm_gpio_ops *ops;
+ const struct dm_gpio_ops *ops;
memset(gpio, '\0', sizeof(*gpio));
if (!dm_gpio_is_valid(desc)) {
@@ -949,6 +1005,71 @@
return vector;
}
+int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
+ int count)
+{
+ static const char tristate[] = "01z";
+ enum {
+ PULLUP,
+ PULLDOWN,
+
+ NUM_OPTIONS,
+ };
+ int vals[NUM_OPTIONS];
+ uint mask;
+ uint vector = 0;
+ int ret, i;
+
+ /*
+ * Limit to 19 digits which should be plenty. This avoids overflow of a
+ * 32-bit int
+ */
+ assert(count < 20);
+
+ for (i = 0; i < NUM_OPTIONS; i++) {
+ uint flags = GPIOD_IS_IN;
+
+ flags |= (i == PULLDOWN) ? GPIOD_PULL_DOWN : GPIOD_PULL_UP;
+ ret = dm_gpios_clrset_flags(desc_list, count, GPIOD_MASK_PULL,
+ flags);
+ if (ret)
+ return log_msg_ret("pu", ret);
+
+ /* Give the lines time to settle */
+ udelay(10);
+
+ ret = dm_gpio_get_values_as_int(desc_list, count);
+ if (ret < 0)
+ return log_msg_ret("get1", ret);
+ vals[i] = ret;
+ }
+
+ log_debug("values: %x %x, count = %d\n", vals[0], vals[1], count);
+ for (i = count - 1, mask = 1 << i; i >= 0; i--, mask >>= 1) {
+ uint pd = vals[PULLDOWN] & mask ? 1 : 0;
+ uint pu = vals[PULLUP] & mask ? 1 : 0;
+ uint digit;
+
+ /*
+ * Get value with internal pulldown active. If this is 1 then
+ * there is a stronger external pullup, which we call 1. If not
+ * then call it 0.
+ *
+ * If the values differ then the pin is floating so we call
+ * this a 2.
+ */
+ if (pu == pd)
+ digit = pd;
+ else
+ digit = 2;
+ log_debug("%c ", tristate[digit]);
+ vector = 3 * vector + digit;
+ }
+ log_debug("vector=%d\n", vector);
+
+ return vector;
+}
+
/**
* gpio_request_tail: common work for requesting a gpio.
*
@@ -1011,7 +1132,10 @@
debug("%s: dm_gpio_requestf failed\n", __func__);
goto err;
}
- ret = dm_gpio_set_dir_flags(desc, flags);
+
+ /* Keep any direction flags provided by the devicetree */
+ ret = dm_gpio_set_dir_flags(desc,
+ flags | (desc->flags & GPIOD_MASK_DIR));
if (ret) {
debug("%s: dm_gpio_set_dir failed\n", __func__);
goto err;
@@ -1024,6 +1148,7 @@
return ret;
}
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
int index, struct gpio_desc *desc,
int flags, bool add_index)
@@ -1110,6 +1235,7 @@
return ret;
}
+#endif /* OF_PLATDATA */
int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
{
@@ -1306,10 +1432,10 @@
ops->get_function += gd->reloc_off;
if (ops->xlate)
ops->xlate += gd->reloc_off;
- if (ops->set_dir_flags)
- ops->set_dir_flags += gd->reloc_off;
- if (ops->get_dir_flags)
- ops->get_dir_flags += gd->reloc_off;
+ if (ops->set_flags)
+ ops->set_flags += gd->reloc_off;
+ if (ops->get_flags)
+ ops->get_flags += gd->reloc_off;
reloc_done++;
}
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index eda9548..ab46a94 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -3,6 +3,8 @@
* Copyright 2019 Google LLC
*/
+#define LOG_CATEGORY UCLASS_GPIO
+
#include <common.h>
#include <dm.h>
#include <errno.h>
@@ -23,38 +25,6 @@
#include <dm/acpi.h>
#include <dt-bindings/gpio/x86-gpio.h>
-static int intel_gpio_direction_input(struct udevice *dev, uint offset)
-{
- struct udevice *pinctrl = dev_get_parent(dev);
- uint config_offset;
-
- config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
-
- pcr_clrsetbits32(pinctrl, config_offset,
- PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
- PAD_CFG0_RX_DISABLE,
- PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE);
-
- return 0;
-}
-
-static int intel_gpio_direction_output(struct udevice *dev, uint offset,
- int value)
-{
- struct udevice *pinctrl = dev_get_parent(dev);
- uint config_offset;
-
- config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
-
- pcr_clrsetbits32(pinctrl, config_offset,
- PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
- PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
- PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
- (value ? PAD_CFG0_TX_STATE : 0));
-
- return 0;
-}
-
static int intel_gpio_get_value(struct udevice *dev, uint offset)
{
struct udevice *pinctrl = dev_get_parent(dev);
@@ -130,6 +100,41 @@
return 0;
}
+static int intel_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
+{
+ struct udevice *pinctrl = dev_get_parent(dev);
+ u32 bic0 = 0, bic1 = 0;
+ u32 or0, or1;
+ uint config_offset;
+
+ config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
+
+ if (flags & GPIOD_IS_OUT) {
+ bic0 |= PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
+ PAD_CFG0_TX_DISABLE;
+ or0 |= PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE;
+ } else if (flags & GPIOD_IS_IN) {
+ bic0 |= PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
+ PAD_CFG0_RX_DISABLE;
+ or0 |= PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE;
+ }
+ if (flags & GPIOD_PULL_UP) {
+ bic1 |= PAD_CFG1_PULL_MASK;
+ or1 |= PAD_CFG1_PULL_UP_20K;
+ } else if (flags & GPIOD_PULL_DOWN) {
+ bic1 |= PAD_CFG1_PULL_MASK;
+ or1 |= PAD_CFG1_PULL_DN_20K;
+ }
+
+ pcr_clrsetbits32(pinctrl, PAD_CFG0_OFFSET(config_offset), bic0, or0);
+ pcr_clrsetbits32(pinctrl, PAD_CFG1_OFFSET(config_offset), bic1, or1);
+ log_debug("%s: flags=%lx, offset=%x, config_offset=%x, %x/%x %x/%x\n",
+ dev->name, flags, offset, config_offset, bic0, or0, bic1, or1);
+
+ return 0;
+}
+
#if CONFIG_IS_ENABLED(ACPIGEN)
static int intel_gpio_get_acpi(const struct gpio_desc *desc,
struct acpi_gpio *gpio)
@@ -177,12 +182,11 @@
}
static const struct dm_gpio_ops gpio_intel_ops = {
- .direction_input = intel_gpio_direction_input,
- .direction_output = intel_gpio_direction_output,
.get_value = intel_gpio_get_value,
.set_value = intel_gpio_set_value,
.get_function = intel_gpio_get_function,
.xlate = intel_gpio_xlate,
+ .set_flags = intel_gpio_set_flags,
#if CONFIG_IS_ENABLED(ACPIGEN)
.get_acpi = intel_gpio_get_acpi,
#endif
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index dc8d506..d008fdd 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -19,42 +19,51 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/sandbox-gpio.h>
-
struct gpio_state {
const char *label; /* label given by requester */
- ulong dir_flags; /* dir_flags (GPIOD_...) */
+ ulong flags; /* flags (GPIOD_...) */
};
-/* Access routines for GPIO dir flags */
-static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
+/* Access routines for GPIO info */
+static struct gpio_state *get_gpio_state(struct udevice *dev, uint offset)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct gpio_state *state = dev_get_priv(dev);
if (offset >= uc_priv->gpio_count) {
- static ulong invalid_dir_flags;
printf("sandbox_gpio: error: invalid gpio %u\n", offset);
- return &invalid_dir_flags;
+ return NULL;
}
- return &state[offset].dir_flags;
+ return &state[offset];
+}
+
+/* Access routines for GPIO flags */
+static ulong *get_gpio_flags(struct udevice *dev, unsigned int offset)
+{
+ struct gpio_state *state = get_gpio_state(dev, offset);
+
+ if (!state)
+ return NULL;
+
+ return &state->flags;
}
static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
{
- return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
+ return (*get_gpio_flags(dev, offset) & flag) != 0;
}
static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
int value)
{
- ulong *gpio = get_gpio_dir_flags(dev, offset);
+ struct gpio_state *state = get_gpio_state(dev, offset);
if (value)
- *gpio |= flag;
+ state->flags |= flag;
else
- *gpio &= ~flag;
+ state->flags &= ~flag;
return 0;
}
@@ -65,14 +74,31 @@
int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
{
+ struct gpio_state *state = get_gpio_state(dev, offset);
+ bool val;
+
if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
debug("sandbox_gpio: get_value on output gpio %u\n", offset);
- return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
+
+ if (state->flags & GPIOD_EXT_DRIVEN) {
+ val = state->flags & GPIOD_EXT_HIGH;
+ } else {
+ if (state->flags & GPIOD_EXT_PULL_UP)
+ val = true;
+ else if (state->flags & GPIOD_EXT_PULL_DOWN)
+ val = false;
+ else
+ val = state->flags & GPIOD_PULL_UP;
+ }
+
+ return val;
}
int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
- return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
+ set_gpio_flag(dev, offset, GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
+
+ return 0;
}
int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
@@ -83,20 +109,23 @@
int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
{
set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
- set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
+ set_gpio_flag(dev, offset, GPIOD_IS_IN, !output);
return 0;
}
-ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
+ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset)
{
- return *get_gpio_dir_flags(dev, offset);
+ ulong flags = *get_gpio_flags(dev, offset);
+
+ return flags & ~GPIOD_SANDBOX_MASK;
}
-int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
- ulong flags)
+int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
{
- *get_gpio_dir_flags(dev, offset) = flags;
+ struct gpio_state *state = get_gpio_state(dev, offset);
+
+ state->flags = flags;
return 0;
}
@@ -117,10 +146,19 @@
static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
+ int ret;
+
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
- return sandbox_gpio_set_direction(dev, offset, 1) |
- sandbox_gpio_set_value(dev, offset, value);
+ ret = sandbox_gpio_set_direction(dev, offset, 1);
+ if (ret)
+ return ret;
+ ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
+ GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
+ if (ret)
+ return ret;
+
+ return 0;
}
/* read GPIO IN value of port 'offset' */
@@ -134,6 +172,8 @@
/* write GPIO OUT value to port 'offset' */
static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
+ int ret;
+
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
if (!sandbox_gpio_get_direction(dev, offset)) {
@@ -142,7 +182,12 @@
return -1;
}
- return sandbox_gpio_set_value(dev, offset, value);
+ ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
+ GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
+ if (ret)
+ return ret;
+
+ return 0;
}
static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
@@ -177,33 +222,30 @@
return 0;
}
-static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
- ulong flags)
+static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
{
- ulong *dir_flags;
+ debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
+ struct gpio_state *state = get_gpio_state(dev, offset);
- debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
-
- dir_flags = get_gpio_dir_flags(dev, offset);
-
- /*
- * For testing purposes keep the output value when switching to input.
- * This allows us to manipulate the input value via the gpio command.
- */
- if (flags & GPIOD_IS_IN)
- *dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
- (*dir_flags & GPIOD_IS_OUT_ACTIVE);
- else
- *dir_flags = flags;
+ if (flags & GPIOD_IS_OUT) {
+ flags |= GPIOD_EXT_DRIVEN;
+ if (flags & GPIOD_IS_OUT_ACTIVE)
+ flags |= GPIOD_EXT_HIGH;
+ else
+ flags &= ~GPIOD_EXT_HIGH;
+ } else {
+ flags |= state->flags & GPIOD_SANDBOX_MASK;
+ }
+ state->flags = flags;
return 0;
}
-static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
- ulong *flags)
+static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
{
debug("%s: offset:%u\n", __func__, offset);
- *flags = *get_gpio_dir_flags(dev, offset);
+ *flagsp = *get_gpio_flags(dev, offset) & ~GPIOD_SANDBOX_MASK;
return 0;
}
@@ -272,8 +314,8 @@
.set_value = sb_gpio_set_value,
.get_function = sb_gpio_get_function,
.xlate = sb_gpio_xlate,
- .set_dir_flags = sb_gpio_set_dir_flags,
- .get_dir_flags = sb_gpio_get_dir_flags,
+ .set_flags = sb_gpio_set_flags,
+ .get_flags = sb_gpio_get_flags,
#if CONFIG_IS_ENABLED(ACPIGEN)
.get_acpi = sb_gpio_get_acpi,
#endif
@@ -456,7 +498,7 @@
return pin_name;
}
-static char *get_dir_flags_string(ulong flags)
+static char *get_flags_string(ulong flags)
{
if (flags & GPIOD_OPEN_DRAIN)
return "drive-open-drain";
@@ -475,7 +517,7 @@
{
struct udevice *gpio_dev;
unsigned int gpio_idx;
- ulong dir_flags;
+ ulong flags;
int function;
/* look up for the bank which owns the requested pin */
@@ -484,11 +526,11 @@
snprintf(buf, size, "Error");
} else {
function = sb_gpio_get_function(gpio_dev, gpio_idx);
- dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
+ flags = *get_gpio_flags(gpio_dev, gpio_idx);
snprintf(buf, size, "gpio %s %s",
function == GPIOF_OUTPUT ? "output" : "input",
- get_dir_flags_string(dir_flags));
+ get_flags_string(flags));
}
return 0;
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index 7184db3..125c237 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -191,8 +191,8 @@
return GPIOF_FUNC;
}
-static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
- ulong flags)
+static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
@@ -203,12 +203,13 @@
return idx;
if (flags & GPIOD_IS_OUT) {
- int value = GPIOD_FLAGS_OUTPUT(flags);
+ bool value = flags & GPIOD_IS_OUT_ACTIVE;
if (flags & GPIOD_OPEN_DRAIN)
stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
else
stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
+
stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
writel(BSRR_BIT(idx, value), ®s->bsrr);
@@ -223,8 +224,8 @@
return 0;
}
-static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
- ulong *flags)
+static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset,
+ ulong *flagsp)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
struct stm32_gpio_regs *regs = priv->regs;
@@ -259,7 +260,7 @@
default:
break;
}
- *flags = dir_flags;
+ *flagsp = dir_flags;
return 0;
}
@@ -270,8 +271,8 @@
.get_value = stm32_gpio_get_value,
.set_value = stm32_gpio_set_value,
.get_function = stm32_gpio_get_function,
- .set_dir_flags = stm32_gpio_set_dir_flags,
- .get_dir_flags = stm32_gpio_get_dir_flags,
+ .set_flags = stm32_gpio_set_flags,
+ .get_flags = stm32_gpio_get_flags,
};
static int gpio_stm32_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
index 1a8d0a3..fe7a59d 100644
--- a/drivers/pinctrl/pinctrl-stmfx.c
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -163,12 +163,14 @@
return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1);
}
-static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
- ulong flags)
+static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
{
int ret = -ENOTSUPP;
if (flags & GPIOD_IS_OUT) {
+ bool value = flags & GPIOD_IS_OUT_ACTIVE;
+
if (flags & GPIOD_OPEN_SOURCE)
return -ENOTSUPP;
if (flags & GPIOD_OPEN_DRAIN)
@@ -177,8 +179,7 @@
ret = stmfx_conf_set_type(dev, offset, 1);
if (ret)
return ret;
- ret = stmfx_gpio_direction_output(dev, offset,
- GPIOD_FLAGS_OUTPUT(flags));
+ ret = stmfx_gpio_direction_output(dev, offset, value);
} else if (flags & GPIOD_IS_IN) {
ret = stmfx_gpio_direction_input(dev, offset);
if (ret)
@@ -199,8 +200,8 @@
return ret;
}
-static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
- ulong *flags)
+static int stmfx_gpio_get_flags(struct udevice *dev, unsigned int offset,
+ ulong *flagsp)
{
ulong dir_flags = 0;
int ret;
@@ -233,7 +234,7 @@
dir_flags |= GPIOD_PULL_DOWN;
}
}
- *flags = dir_flags;
+ *flagsp = dir_flags;
return 0;
}
@@ -266,8 +267,8 @@
.get_function = stmfx_gpio_get_function,
.direction_input = stmfx_gpio_direction_input,
.direction_output = stmfx_gpio_direction_output,
- .set_dir_flags = stmfx_gpio_set_dir_flags,
- .get_dir_flags = stmfx_gpio_get_dir_flags,
+ .set_flags = stmfx_gpio_set_flags,
+ .get_flags = stmfx_gpio_get_flags,
};
U_BOOT_DRIVER(stmfx_gpio) = {
diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index 6c9dc7a..9512f68 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -113,7 +113,7 @@
/**
* reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
*/
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
sysreset_walk_halt(SYSRESET_WARM);
}
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index 65622f3..d030280 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -31,6 +31,12 @@
permits to test reverse RPC calls to TEE supplicant. Should
be used only in sandbox env.
+config OPTEE_TA_SCP03
+ bool "Support SCP03 TA"
+ default y
+ help
+ Enables support for controlling (enabling, provisioning) the
+ Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA.
endmenu
endif
diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c
index 3a1d34d..35e8542 100644
--- a/drivers/tee/sandbox.c
+++ b/drivers/tee/sandbox.c
@@ -8,6 +8,7 @@
#include <tee.h>
#include <tee/optee_ta_avb.h>
#include <tee/optee_ta_rpc_test.h>
+#include <tee/optee_ta_scp03.h>
#include "optee/optee_msg.h"
#include "optee/optee_private.h"
@@ -68,6 +69,7 @@
return NULL;
}
+#if defined(CONFIG_OPTEE_TA_SCP03) || defined(CONFIG_OPTEE_TA_AVB)
static u32 get_attr(uint n, uint num_params, struct tee_param *params)
{
if (n >= num_params)
@@ -79,7 +81,7 @@
static u32 check_params(u8 p0, u8 p1, u8 p2, u8 p3, uint num_params,
struct tee_param *params)
{
- u8 p[] = { p0, p1, p2, p3};
+ u8 p[] = { p0, p1, p2, p3 };
uint n;
for (n = 0; n < ARRAY_SIZE(p); n++)
@@ -97,6 +99,50 @@
return TEE_ERROR_BAD_PARAMETERS;
}
+#endif
+
+#ifdef CONFIG_OPTEE_TA_SCP03
+static u32 pta_scp03_open_session(struct udevice *dev, uint num_params,
+ struct tee_param *params)
+{
+ /*
+ * We don't expect additional parameters when opening a session to
+ * this TA.
+ */
+ return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+}
+
+static u32 pta_scp03_invoke_func(struct udevice *dev, u32 func, uint num_params,
+ struct tee_param *params)
+{
+ u32 res;
+ static bool enabled;
+
+ switch (func) {
+ case PTA_CMD_ENABLE_SCP03:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ if (!enabled) {
+ enabled = true;
+ } else {
+ }
+
+ if (params[0].u.value.a)
+
+ return TEE_SUCCESS;
+ default:
+ return TEE_ERROR_NOT_SUPPORTED;
+ }
+}
+#endif
#ifdef CONFIG_OPTEE_TA_AVB
static u32 ta_avb_open_session(struct udevice *dev, uint num_params,
@@ -357,6 +403,12 @@
.invoke_func = ta_rpc_test_invoke_func,
},
#endif
+#ifdef CONFIG_OPTEE_TA_SCP03
+ { .uuid = PTA_SCP03_UUID,
+ .open_session = pta_scp03_open_session,
+ .invoke_func = pta_scp03_invoke_func,
+ },
+#endif
};
static void sandbox_tee_get_version(struct udevice *dev,
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index 8f075b9..f64d200 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -10,7 +10,7 @@
obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o
-obj-$(CONFIG_TPM2_CR50_I2C) += cr50_i2c.o
+obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o
obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o
obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o
obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o
diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c
index b103a6f..76432bd 100644
--- a/drivers/tpm/cr50_i2c.c
+++ b/drivers/tpm/cr50_i2c.c
@@ -309,7 +309,7 @@
int status;
int ret;
- log_debug("%s: len=%x\n", __func__, buf_len);
+ log_debug("%s: buf_len=%x\n", __func__, buf_len);
if (buf_len < TPM_HEADER_SIZE)
return -E2BIG;
@@ -386,7 +386,7 @@
ulong timeout;
int ret;
- log_debug("%s: len=%x\n", __func__, len);
+ log_debug("len=%x\n", len);
timeout = timer_get_us() + TIMEOUT_LONG_US;
do {
ret = cr50_i2c_status(dev);
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index beb0fa3..35774a6 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -4,6 +4,8 @@
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_CATEGORY UCLASS_TPM
+
#include <common.h>
#include <dm.h>
#include <log.h>
@@ -87,15 +89,15 @@
ordinal = get_unaligned_be32(sendbuf + TPM_CMD_ORDINAL_BYTE);
if (count == 0) {
- debug("no data\n");
+ log_debug("no data\n");
return -ENODATA;
}
if (count > send_size) {
- debug("invalid count value %x %zx\n", count, send_size);
+ log_debug("invalid count value %x %zx\n", count, send_size);
return -E2BIG;
}
- debug("%s: Calling send\n", __func__);
+ log_debug("%s: Calling send\n", __func__);
ret = ops->send(dev, sendbuf, send_size);
if (ret < 0)
return ret;
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index c74bacf..24c804a 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -285,7 +285,7 @@
length = get_unaligned_be32(sent);
sent += sizeof(length);
if (length != send_size) {
- printf("TPM2: Unmatching length, received: %ld, expected: %d\n",
+ printf("TPM2: Unmatching length, received: %zd, expected: %d\n",
send_size, length);
rc = TPM2_RC_SIZE;
sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index f52aba4..4361a58 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -7,6 +7,8 @@
*/
#include <common.h>
+#include <display.h>
+#include <dm.h>
#include <cpu_func.h>
#include <efi_loader.h>
#include <init.h>
@@ -28,7 +30,9 @@
#include <fdt_support.h>
#include <i2c.h>
#include <malloc.h>
+#include <video.h>
#include <video_fb.h>
+#include <dm/uclass-internal.h>
#include "../videomodes.h"
#include "../anx9804.h"
#include "../hitachi_tx18d42vm_lcd.h"
@@ -45,6 +49,11 @@
DECLARE_GLOBAL_DATA_PTR;
+/* Maximum LCD size we support */
+#define LCD_MAX_WIDTH 3840
+#define LCD_MAX_HEIGHT 2160
+#define LCD_MAX_LOG2_BPP VIDEO_BPP32
+
enum sunxi_monitor {
sunxi_monitor_none,
sunxi_monitor_dvi,
@@ -58,13 +67,12 @@
};
#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
-struct sunxi_display {
- GraphicDevice graphic_device;
+struct sunxi_display_priv {
enum sunxi_monitor monitor;
unsigned int depth;
unsigned int fb_addr;
unsigned int fb_size;
-} sunxi_display;
+};
const struct ctfb_res_modes composite_video_modes[2] = {
/* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */
@@ -214,7 +222,8 @@
return r;
}
-static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
+static int sunxi_hdmi_edid_get_mode(struct sunxi_display_priv *sunxi_display,
+ struct ctfb_res_modes *mode,
bool verbose_mode)
{
struct edid1_info edid1;
@@ -291,14 +300,14 @@
}
/* Check for basic audio support, if found enable hdmi output */
- sunxi_display.monitor = sunxi_monitor_dvi;
+ sunxi_display->monitor = sunxi_monitor_dvi;
for (i = 0; i < ext_blocks; i++) {
if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
cea681[i].revision < 2)
continue;
if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
- sunxi_display.monitor = sunxi_monitor_hdmi;
+ sunxi_display->monitor = sunxi_monitor_hdmi;
}
return 0;
@@ -414,9 +423,9 @@
static void sunxi_frontend_enable(void) {}
#endif
-static bool sunxi_is_composite(void)
+static bool sunxi_is_composite(enum sunxi_monitor monitor)
{
- switch (sunxi_display.monitor) {
+ switch (monitor) {
case sunxi_monitor_none:
case sunxi_monitor_dvi:
case sunxi_monitor_hdmi:
@@ -473,7 +482,8 @@
};
static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
- unsigned int address)
+ unsigned int address,
+ enum sunxi_monitor monitor)
{
struct sunxi_de_be_reg * const de_be =
(struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
@@ -502,7 +512,7 @@
#endif
SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
- if (sunxi_is_composite()) {
+ if (sunxi_is_composite(monitor)) {
writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
&de_be->output_color_ctrl);
for (i = 0; i < 12; i++)
@@ -616,7 +626,8 @@
gpio_direction_output(pin, PWM_ON);
}
-static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
+static void sunxi_lcdc_tcon0_mode_set(struct sunxi_display_priv *sunxi_display,
+ const struct ctfb_res_modes *mode,
bool for_ext_vga_dac)
{
struct sunxi_lcdc_reg * const lcdc =
@@ -643,17 +654,18 @@
}
lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
- sunxi_is_composite());
+ sunxi_is_composite(sunxi_display->monitor));
video_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
- sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
+ sunxi_display->depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
}
#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
int *clk_div, int *clk_double,
- bool use_portd_hvsync)
+ bool use_portd_hvsync,
+ enum sunxi_monitor monitor)
{
struct sunxi_lcdc_reg * const lcdc =
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
@@ -663,7 +675,7 @@
video_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync,
- sunxi_is_composite());
+ sunxi_is_composite(monitor));
if (use_portd_hvsync) {
sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
@@ -671,7 +683,7 @@
}
lcdc_pll_set(ccm, 1, mode->pixclock_khz, clk_div, clk_double,
- sunxi_is_composite());
+ sunxi_is_composite(monitor));
}
#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
@@ -725,7 +737,8 @@
}
static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
- int clk_div, int clk_double)
+ int clk_div, int clk_double,
+ enum sunxi_monitor monitor)
{
struct sunxi_hdmi_reg * const hdmi =
(struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
@@ -734,7 +747,7 @@
/* Write clear interrupt status bits */
writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
- if (sunxi_display.monitor == sunxi_monitor_hdmi)
+ if (monitor == sunxi_monitor_hdmi)
sunxi_hdmi_setup_info_frames(mode);
/* Set input sync enable */
@@ -789,7 +802,7 @@
#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
-static void sunxi_tvencoder_mode_set(void)
+static void sunxi_tvencoder_mode_set(enum sunxi_monitor monitor)
{
struct sunxi_ccm_reg * const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -801,7 +814,7 @@
/* Clock on */
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
- switch (sunxi_display.monitor) {
+ switch (monitor) {
case sunxi_monitor_vga:
tvencoder_mode_set(tve, tve_mode_vga);
break;
@@ -896,26 +909,28 @@
sunxi_drc_init();
}
-static void sunxi_mode_set(const struct ctfb_res_modes *mode,
+static void sunxi_mode_set(struct sunxi_display_priv *sunxi_display,
+ const struct ctfb_res_modes *mode,
unsigned int address)
{
+ enum sunxi_monitor monitor = sunxi_display->monitor;
int __maybe_unused clk_div, clk_double;
struct sunxi_lcdc_reg * const lcdc =
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
struct sunxi_tve_reg * __maybe_unused const tve =
(struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
- switch (sunxi_display.monitor) {
+ switch (sunxi_display->monitor) {
case sunxi_monitor_none:
break;
case sunxi_monitor_dvi:
case sunxi_monitor_hdmi:
#ifdef CONFIG_VIDEO_HDMI
- sunxi_composer_mode_set(mode, address);
- sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
- sunxi_hdmi_mode_set(mode, clk_div, clk_double);
+ sunxi_composer_mode_set(mode, address, monitor);
+ sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
+ sunxi_hdmi_mode_set(mode, clk_div, clk_double, monitor);
sunxi_composer_enable();
- lcdc_enable(lcdc, sunxi_display.depth);
+ lcdc_enable(lcdc, sunxi_display->depth);
sunxi_hdmi_enable();
#endif
break;
@@ -930,7 +945,7 @@
axp_set_eldo(3, 1800);
anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
ANX9804_DATA_RATE_1620M,
- sunxi_display.depth);
+ sunxi_display->depth);
}
if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
mdelay(50); /* Wait for lcd controller power on */
@@ -942,10 +957,10 @@
i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
i2c_set_bus_num(orig_i2c_bus);
}
- sunxi_composer_mode_set(mode, address);
- sunxi_lcdc_tcon0_mode_set(mode, false);
+ sunxi_composer_mode_set(mode, address, monitor);
+ sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, false);
sunxi_composer_enable();
- lcdc_enable(lcdc, sunxi_display.depth);
+ lcdc_enable(lcdc, sunxi_display->depth);
#ifdef CONFIG_VIDEO_LCD_SSD2828
sunxi_ssd2828_init(mode);
#endif
@@ -953,17 +968,17 @@
break;
case sunxi_monitor_vga:
#ifdef CONFIG_VIDEO_VGA
- sunxi_composer_mode_set(mode, address);
- sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
- sunxi_tvencoder_mode_set();
+ sunxi_composer_mode_set(mode, address, monitor);
+ sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1, monitor);
+ sunxi_tvencoder_mode_set(monitor);
sunxi_composer_enable();
- lcdc_enable(lcdc, sunxi_display.depth);
+ lcdc_enable(lcdc, sunxi_display->depth);
tvencoder_enable(tve);
#elif defined CONFIG_VIDEO_VGA_VIA_LCD
- sunxi_composer_mode_set(mode, address);
- sunxi_lcdc_tcon0_mode_set(mode, true);
+ sunxi_composer_mode_set(mode, address, monitor);
+ sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, true);
sunxi_composer_enable();
- lcdc_enable(lcdc, sunxi_display.depth);
+ lcdc_enable(lcdc, sunxi_display->depth);
sunxi_vga_external_dac_enable();
#endif
break;
@@ -972,11 +987,11 @@
case sunxi_monitor_composite_pal_m:
case sunxi_monitor_composite_pal_nc:
#ifdef CONFIG_VIDEO_COMPOSITE
- sunxi_composer_mode_set(mode, address);
- sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
- sunxi_tvencoder_mode_set();
+ sunxi_composer_mode_set(mode, address, monitor);
+ sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
+ sunxi_tvencoder_mode_set(monitor);
sunxi_composer_enable();
- lcdc_enable(lcdc, sunxi_display.depth);
+ lcdc_enable(lcdc, sunxi_display->depth);
tvencoder_enable(tve);
#endif
break;
@@ -999,11 +1014,6 @@
}
}
-ulong board_get_usable_ram_top(ulong total_size)
-{
- return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
-}
-
static bool sunxi_has_hdmi(void)
{
#ifdef CONFIG_VIDEO_HDMI
@@ -1052,9 +1062,11 @@
return sunxi_monitor_none;
}
-void *video_hw_init(void)
+static int sunxi_de_probe(struct udevice *dev)
{
- static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+ struct sunxi_display_priv *sunxi_display = dev_get_priv(dev);
const struct ctfb_res_modes *mode;
struct ctfb_res_modes custom;
const char *options;
@@ -1067,10 +1079,8 @@
char mon[16];
char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
- memset(&sunxi_display, 0, sizeof(struct sunxi_display));
-
video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
- &sunxi_display.depth, &options);
+ &sunxi_display->depth, &options);
#ifdef CONFIG_VIDEO_HDMI
hpd = video_get_option_int(options, "hpd", 1);
hpd_delay = video_get_option_int(options, "hpd_delay", 500);
@@ -1078,35 +1088,35 @@
#endif
overscan_x = video_get_option_int(options, "overscan_x", -1);
overscan_y = video_get_option_int(options, "overscan_y", -1);
- sunxi_display.monitor = sunxi_get_default_mon(true);
+ sunxi_display->monitor = sunxi_get_default_mon(true);
video_get_option_string(options, "monitor", mon, sizeof(mon),
- sunxi_get_mon_desc(sunxi_display.monitor));
+ sunxi_get_mon_desc(sunxi_display->monitor));
for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
- sunxi_display.monitor = i;
+ sunxi_display->monitor = i;
break;
}
}
if (i > SUNXI_MONITOR_LAST)
printf("Unknown monitor: '%s', falling back to '%s'\n",
- mon, sunxi_get_mon_desc(sunxi_display.monitor));
+ mon, sunxi_get_mon_desc(sunxi_display->monitor));
#ifdef CONFIG_VIDEO_HDMI
/* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
- if (sunxi_display.monitor == sunxi_monitor_dvi ||
- sunxi_display.monitor == sunxi_monitor_hdmi) {
+ if (sunxi_display->monitor == sunxi_monitor_dvi ||
+ sunxi_display->monitor == sunxi_monitor_hdmi) {
/* Always call hdp_detect, as it also enables clocks, etc. */
hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1);
if (hdmi_present && edid) {
printf("HDMI connected: ");
- if (sunxi_hdmi_edid_get_mode(&custom, true) == 0)
+ if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, true) == 0)
mode = &custom;
else
hdmi_present = false;
}
/* Fall back to EDID in case HPD failed */
if (edid && !hdmi_present) {
- if (sunxi_hdmi_edid_get_mode(&custom, false) == 0) {
+ if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, false) == 0) {
mode = &custom;
hdmi_present = true;
}
@@ -1114,38 +1124,39 @@
/* Shut down when display was not found */
if ((hpd || edid) && !hdmi_present) {
sunxi_hdmi_shutdown();
- sunxi_display.monitor = sunxi_get_default_mon(false);
+ sunxi_display->monitor = sunxi_get_default_mon(false);
} /* else continue with hdmi/dvi without a cable connected */
}
#endif
- switch (sunxi_display.monitor) {
+ switch (sunxi_display->monitor) {
case sunxi_monitor_none:
- return NULL;
+ printf("Unknown monitor\n");
+ return -EINVAL;
case sunxi_monitor_dvi:
case sunxi_monitor_hdmi:
if (!sunxi_has_hdmi()) {
printf("HDMI/DVI not supported on this board\n");
- sunxi_display.monitor = sunxi_monitor_none;
- return NULL;
+ sunxi_display->monitor = sunxi_monitor_none;
+ return -EINVAL;
}
break;
case sunxi_monitor_lcd:
if (!sunxi_has_lcd()) {
printf("LCD not supported on this board\n");
- sunxi_display.monitor = sunxi_monitor_none;
- return NULL;
+ sunxi_display->monitor = sunxi_monitor_none;
+ return -EINVAL;
}
- sunxi_display.depth = video_get_params(&custom, lcd_mode);
+ sunxi_display->depth = video_get_params(&custom, lcd_mode);
mode = &custom;
break;
case sunxi_monitor_vga:
if (!sunxi_has_vga()) {
printf("VGA not supported on this board\n");
- sunxi_display.monitor = sunxi_monitor_none;
- return NULL;
+ sunxi_display->monitor = sunxi_monitor_none;
+ return -EINVAL;
}
- sunxi_display.depth = 18;
+ sunxi_display->depth = 18;
break;
case sunxi_monitor_composite_pal:
case sunxi_monitor_composite_ntsc:
@@ -1153,85 +1164,99 @@
case sunxi_monitor_composite_pal_nc:
if (!sunxi_has_composite()) {
printf("Composite video not supported on this board\n");
- sunxi_display.monitor = sunxi_monitor_none;
- return NULL;
+ sunxi_display->monitor = sunxi_monitor_none;
+ return -EINVAL;
}
- if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
- sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
+ if (sunxi_display->monitor == sunxi_monitor_composite_pal ||
+ sunxi_display->monitor == sunxi_monitor_composite_pal_nc)
mode = &composite_video_modes[0];
else
mode = &composite_video_modes[1];
- sunxi_display.depth = 24;
+ sunxi_display->depth = 24;
break;
}
/* Yes these defaults are quite high, overscan on composite sucks... */
if (overscan_x == -1)
- overscan_x = sunxi_is_composite() ? 32 : 0;
+ overscan_x = sunxi_is_composite(sunxi_display->monitor) ? 32 : 0;
if (overscan_y == -1)
- overscan_y = sunxi_is_composite() ? 20 : 0;
+ overscan_y = sunxi_is_composite(sunxi_display->monitor) ? 20 : 0;
- sunxi_display.fb_size =
- (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
+ sunxi_display->fb_size = plat->size;
overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
/* We want to keep the fb_base for simplefb page aligned, where as
* the sunxi dma engines will happily accept an unaligned address. */
if (overscan_offset)
- sunxi_display.fb_size += 0x1000;
-
- if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
- printf("Error need %dkB for fb, but only %dkB is reserved\n",
- sunxi_display.fb_size >> 10,
- CONFIG_SUNXI_MAX_FB_SIZE >> 10);
- return NULL;
- }
+ sunxi_display->fb_size += 0x1000;
printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
mode->xres, mode->yres,
(mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
- sunxi_get_mon_desc(sunxi_display.monitor),
+ sunxi_get_mon_desc(sunxi_display->monitor),
overscan_x, overscan_y);
- gd->fb_base = gd->bd->bi_dram[0].start +
- gd->bd->bi_dram[0].size - sunxi_display.fb_size;
+ sunxi_display->fb_addr = plat->base;
sunxi_engines_init();
#ifdef CONFIG_EFI_LOADER
- efi_add_memory_map(gd->fb_base, sunxi_display.fb_size,
+ efi_add_memory_map(sunxi_display->fb_addr, sunxi_display->fb_size,
EFI_RESERVED_MEMORY_TYPE);
#endif
- fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
- sunxi_display.fb_addr = gd->fb_base;
+ fb_dma_addr = sunxi_display->fb_addr - CONFIG_SYS_SDRAM_BASE;
if (overscan_offset) {
fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
- sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
- memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
- flush_cache(gd->fb_base, sunxi_display.fb_size);
+ sunxi_display->fb_addr += ALIGN(overscan_offset, 0x1000);
+ memset((void *)sunxi_display->fb_addr, 0, sunxi_display->fb_size);
+ flush_cache(sunxi_display->fb_addr, sunxi_display->fb_size);
}
- sunxi_mode_set(mode, fb_dma_addr);
+ sunxi_mode_set(sunxi_display, mode, fb_dma_addr);
- /*
- * These are the only members of this structure that are used. All the
- * others are driver specific. The pitch is stored in plnSizeX.
- */
- graphic_device->frameAdrs = sunxi_display.fb_addr;
- graphic_device->gdfIndex = GDF_32BIT_X888RGB;
- graphic_device->gdfBytesPP = 4;
- graphic_device->winSizeX = mode->xres - 2 * overscan_x;
- graphic_device->winSizeY = mode->yres - 2 * overscan_y;
- graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
+ /* The members of struct video_priv to be set by the driver. */
+ uc_priv->bpix = VIDEO_BPP32;
+ uc_priv->xsize = mode->xres;
+ uc_priv->ysize = mode->yres;
- return graphic_device;
+ video_set_flush_dcache(dev, true);
+
+ return 0;
}
+static int sunxi_de_bind(struct udevice *dev)
+{
+ struct video_uc_plat *plat = dev_get_uclass_plat(dev);
+
+ plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * VNBYTES(LCD_MAX_LOG2_BPP);
+
+ return 0;
+}
+
+static const struct video_ops sunxi_de_ops = {
+};
+
+U_BOOT_DRIVER(sunxi_de) = {
+ .name = "sunxi_de",
+ .id = UCLASS_VIDEO,
+ .ops = &sunxi_de_ops,
+ .bind = sunxi_de_bind,
+ .probe = sunxi_de_probe,
+ .priv_auto = sizeof(struct sunxi_display_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRVINFO(sunxi_de) = {
+ .name = "sunxi_de"
+};
+
/*
* Simplefb support.
*/
#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
int sunxi_simplefb_setup(void *blob)
{
- static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
+ struct sunxi_display_priv *sunxi_display;
+ struct video_priv *uc_priv;
+ struct udevice *de;
int offset, ret;
u64 start, size;
const char *pipeline = NULL;
@@ -1242,7 +1267,19 @@
#define PIPELINE_PREFIX
#endif
- switch (sunxi_display.monitor) {
+ ret = uclass_find_device_by_name(UCLASS_VIDEO, "sunxi_de", &de);
+ if (ret) {
+ printf("DE not present\n");
+ return 0;
+ } else if (!device_active(de)) {
+ printf("DE is present but not probed\n");
+ return 0;
+ }
+
+ uc_priv = dev_get_uclass_priv(de);
+ sunxi_display = dev_get_priv(de);
+
+ switch (sunxi_display->monitor) {
case sunxi_monitor_none:
return 0;
case sunxi_monitor_dvi:
@@ -1280,16 +1317,17 @@
* linux/arch/arm/mm/ioremap.c around line 301.
*/
start = gd->bd->bi_dram[0].start;
- size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
+ size = sunxi_display->fb_addr - start;
ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
if (ret) {
eprintf("Cannot setup simplefb: Error reserving memory\n");
return ret;
}
- ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr,
- graphic_device->winSizeX, graphic_device->winSizeY,
- graphic_device->plnSizeX, "x8r8g8b8");
+ ret = fdt_setup_simplefb_node(blob, offset, sunxi_display->fb_addr,
+ uc_priv->xsize, uc_priv->ysize,
+ VNBYTES(uc_priv->bpix) * uc_priv->xsize,
+ "x8r8g8b8");
if (ret)
eprintf("Cannot setup simplefb: Error setting properties\n");
diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
index 5e0a096..3586246 100644
--- a/drivers/watchdog/imx_watchdog.c
+++ b/drivers/watchdog/imx_watchdog.c
@@ -44,7 +44,7 @@
#if !defined(CONFIG_IMX_WATCHDOG) || \
(defined(CONFIG_IMX_WATCHDOG) && !CONFIG_IS_ENABLED(WDT))
-void __attribute__((weak)) reset_cpu(ulong addr)
+void __attribute__((weak)) reset_cpu(void)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c
index 7533fc6..6f63b11 100644
--- a/drivers/watchdog/ulp_wdog.c
+++ b/drivers/watchdog/ulp_wdog.c
@@ -77,7 +77,7 @@
hw_watchdog_reset();
}
-void reset_cpu(ulong addr)
+void reset_cpu(void)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index b6a9991..c24f5e0 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -410,6 +410,12 @@
* This value is used as logging level for continuation messages.
*/
int logl_prev;
+ /**
+ * @log_cont: Previous log line did not finished wtih \n
+ *
+ * This allows for chained log messages on the same line
+ */
+ bool log_cont;
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 82294cb..2cb0500 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -128,6 +128,12 @@
#define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */
#define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */
+/* Flags for updating the above */
+#define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \
+ GPIOD_IS_OUT_ACTIVE)
+#define GPIOD_MASK_DSTYPE (GPIOD_OPEN_DRAIN | GPIOD_OPEN_SOURCE)
+#define GPIOD_MASK_PULL (GPIOD_PULL_UP | GPIOD_PULL_DOWN)
+
uint offset; /* GPIO offset within the device */
/*
* We could consider adding the GPIO label in here. Possibly we could
@@ -135,12 +141,6 @@
*/
};
-/* helper to compute the value of the gpio output */
-#define GPIOD_FLAGS_OUTPUT_MASK (GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE)
-#define GPIOD_FLAGS_OUTPUT(flags) \
- (((((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_IS_OUT_ACTIVE) || \
- (((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_ACTIVE_LOW)))
-
/**
* dm_gpio_is_valid() - Check if a GPIO is valid
*
@@ -260,10 +260,32 @@
struct dm_gpio_ops {
int (*request)(struct udevice *dev, unsigned offset, const char *label);
int (*rfree)(struct udevice *dev, unsigned int offset);
+
+ /**
+ * direction_input() - deprecated
+ *
+ * Equivalent to set_flags(...GPIOD_IS_IN)
+ */
int (*direction_input)(struct udevice *dev, unsigned offset);
+
+ /**
+ * direction_output() - deprecated
+ *
+ * Equivalent to set_flags(...GPIOD_IS_OUT) with GPIOD_IS_OUT_ACTIVE
+ * also set if @value
+ */
int (*direction_output)(struct udevice *dev, unsigned offset,
int value);
+
int (*get_value)(struct udevice *dev, unsigned offset);
+
+ /**
+ * set_value() - Sets the GPIO value of an output
+ *
+ * If the driver provides an @set_flags() method then that is used
+ * in preference to this, with GPIOD_IS_OUT_ACTIVE set according to
+ * @value.
+ */
int (*set_value)(struct udevice *dev, unsigned offset, int value);
/**
* get_function() Get the GPIO function
@@ -301,35 +323,54 @@
struct ofnode_phandle_args *args);
/**
- * set_dir_flags() - Set GPIO dir flags
+ * set_flags() - Adjust GPIO flags
*
* This function should set up the GPIO configuration according to the
- * information provide by the direction flags bitfield.
+ * information provided by @flags.
*
- * This method is optional.
+ * If any flags cannot be set (e.g. the driver or hardware does not
+ * support them or this particular GPIO does not have the requested
+ * feature), the driver should return -EINVAL.
+ *
+ * The uclass checks that flags do not obviously conflict (e.g. input
+ * and output). If the driver finds other conflicts it should return
+ * -ERECALLCONFLICT
+ *
+ * Note that GPIOD_ACTIVE_LOW should be ignored, since the uclass
+ * adjusts for it automatically. For example, for an output GPIO,
+ * GPIOD_ACTIVE_LOW causes GPIOD_IS_OUT_ACTIVE to be inverted by the
+ * uclass, so the driver always sees the value that should be set at the
+ * pin (1=high, 0=low).
+ *
+ * This method is required and should be implemented by new drivers. At
+ * some point, it will supersede direction_input() and
+ * direction_output(), which wil be removed.
*
* @dev: GPIO device
* @offset: GPIO offset within that device
- * @flags: GPIO configuration to use
- * @return 0 if OK, -ve on error
+ * @flags: New flags value (GPIOD_...)
+ *
+ * @return 0 if OK, -EINVAL if unsupported, -ERECALLCONFLICT if flags
+ * conflict in some * non-obvious way and were not applied,
+ * other -ve on error
*/
- int (*set_dir_flags)(struct udevice *dev, unsigned int offset,
- ulong flags);
+ int (*set_flags)(struct udevice *dev, unsigned int offset, ulong flags);
/**
- * get_dir_flags() - Get GPIO dir flags
+ * get_flags() - Get GPIO flags
*
- * This function return the GPIO direction flags used.
+ * This function return the GPIO flags used. It should read this from
+ * the hardware directly.
*
* This method is optional.
*
* @dev: GPIO device
* @offset: GPIO offset within that device
- * @flags: place to put the used direction flags by GPIO
+ * @flagsp: place to put the current flags value
* @return 0 if OK, -ve on error
*/
- int (*get_dir_flags)(struct udevice *dev, unsigned int offset,
- ulong *flags);
+ int (*get_flags)(struct udevice *dev, unsigned int offset,
+ ulong *flagsp);
#if CONFIG_IS_ENABLED(ACPIGEN)
/**
@@ -457,6 +498,31 @@
int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count);
/**
+ * dm_gpio_get_values_as_int_base3() - Create a base-3 int from a list of GPIOs
+ *
+ * This uses pull-ups/pull-downs to figure out whether a GPIO line is externally
+ * pulled down, pulled up or floating. This allows three different strap values
+ * for each pin:
+ * 0 : external pull-down
+ * 1 : external pull-up
+ * 2 : floating
+ *
+ * With this it is possible to obtain more combinations from the same number of
+ * strapping pins, when compared to dm_gpio_get_values_as_int(). The external
+ * pull resistors should be made stronger that the internal SoC pull resistors,
+ * for this to work.
+ *
+ * With 2 pins, 6 combinations are possible, compared with 4
+ * With 3 pins, 27 are possible, compared with 8
+ *
+ * @desc_list: List of GPIOs to collect
+ * @count: Number of GPIOs
+ * @return resulting integer value, or -ve on error
+ */
+int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
+ int count);
+
+/**
* gpio_claim_vector() - claim a number of GPIOs for input
*
* @gpio_num_array: array of gpios to claim, terminated by -1
@@ -652,6 +718,25 @@
int dm_gpio_set_dir(struct gpio_desc *desc);
/**
+ * dm_gpio_clrset_flags() - Update flags
+ *
+ * This updates the flags as directled. Note that desc->flags is updated by this
+ * function on success. If any changes cannot be made, best efforts are made.
+ *
+ * By use of @clr and @set any of flags can be individually updated, or left
+ * alone
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @clr: Flags to clear (GPIOD_...)
+ * @set: Flags to set (GPIOD_...)
+ * @return 0 if OK, -EINVAL if the flags had obvious conflicts,
+ * -ERECALLCONFLICT if there was a non-obvious hardware conflict when attempting
+ * to set the flags
+ */
+int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set);
+
+/**
* dm_gpio_set_dir_flags() - Set direction using description and added flags
*
* This sets up the direction according to the provided flags and the GPIO
@@ -666,16 +751,31 @@
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
/**
- * dm_gpio_get_dir_flags() - Get direction flags
+ * dm_gpios_clrset_flags() - Sets flags for a set of GPIOs
*
- * read the current direction flags
+ * This clears and sets flags individually for each GPIO.
+ *
+ * @desc: List of GPIOs to update
+ * @count: Number of GPIOs in the list
+ * @clr: Flags to clear (GPIOD_...), e.g. GPIOD_MASK_DIR if you are
+ * changing the direction
+ * @set: Flags to set (GPIOD_...)
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
+ ulong set);
+
+/**
+ * dm_gpio_get_flags() - Get flags
+ *
+ * Read the current flags
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* @flags: place to put the used flags
* @return 0 if OK, -ve on error, in which case desc->flags is not updated
*/
-int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
+int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flags);
/**
* gpio_get_number() - Get the global GPIO number of a GPIO
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 7b602dd..33a4d7b 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -223,23 +223,6 @@
#define CONFIG_VIDEO_LCD_I2C_BUS -1 /* NA, but necessary to compile */
#endif
-#ifdef CONFIG_VIDEO_SUNXI
-/*
- * The amount of RAM to keep free at the top of RAM when relocating u-boot,
- * to use as framebuffer. This must be a multiple of 4096.
- */
-#define CONFIG_SUNXI_MAX_FB_SIZE (16 << 20)
-
-#define CONFIG_VIDEO_LOGO
-#define CONFIG_VIDEO_STD_TIMINGS
-#define CONFIG_I2C_EDID
-#define VIDEO_LINE_LEN (pGD->plnSizeX)
-
-/* allow both serial and cfb console. */
-/* stop x86 thinking in cfbconsole from trying to init a pc keyboard */
-
-#endif /* CONFIG_VIDEO_SUNXI */
-
/* Ethernet support */
#ifdef CONFIG_USB_EHCI_HCD
@@ -401,11 +384,7 @@
"stdin=serial\0"
#endif
-#ifdef CONFIG_VIDEO
-#define CONSOLE_STDOUT_SETTINGS \
- "stdout=serial,vga\0" \
- "stderr=serial,vga\0"
-#elif CONFIG_DM_VIDEO
+#ifdef CONFIG_DM_VIDEO
#define CONSOLE_STDOUT_SETTINGS \
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"
diff --git a/include/cpu_func.h b/include/cpu_func.h
index 8aa825d..c3a66f0 100644
--- a/include/cpu_func.h
+++ b/include/cpu_func.h
@@ -84,6 +84,6 @@
*/
int cleanup_before_linux_select(int flags);
-void reset_cpu(ulong addr);
-;
+void reset_cpu(void);
+
#endif
diff --git a/include/dm/test.h b/include/dm/test.h
index 6ac6672..fe1cc2e 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -125,25 +125,9 @@
extern struct unit_test_state global_dm_test_state;
-/*
- * struct dm_test_state - Entire state of dm test system
- *
- * This is often abreviated to dms.
- *
- * @root: Root device
- * @testdev: Test device
- * @force_fail_alloc: Force all memory allocs to fail
- * @skip_post_probe: Skip uclass post-probe processing
- */
-struct dm_test_state {
- struct udevice *root;
- struct udevice *testdev;
- int force_fail_alloc;
- int skip_post_probe;
-};
-
/* Declare a new driver model test */
-#define DM_TEST(_name, _flags) UNIT_TEST(_name, _flags, dm_test)
+#define DM_TEST(_name, _flags) \
+ UNIT_TEST(_name, UT_TESTF_DM | UT_TESTF_CONSOLE_REC | (_flags), dm_test)
/*
* struct sandbox_sdl_plat - Platform data for the SDL video driver
diff --git a/include/log.h b/include/log.h
index 2d27f9f..6ef891d 100644
--- a/include/log.h
+++ b/include/log.h
@@ -316,12 +316,40 @@
__ret); \
__ret; \
})
+
+/*
+ * Similar to the above, but any non-zero value is consider an error, not just
+ * values less than 0.
+ */
+#define log_retz(_ret) ({ \
+ int __ret = (_ret); \
+ if (__ret) \
+ log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
+ __ret; \
+ })
+#define log_msg_retz(_msg, _ret) ({ \
+ int __ret = (_ret); \
+ if (__ret) \
+ log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \
+ __ret); \
+ __ret; \
+ })
#else
/* Non-logging versions of the above which just return the error code */
#define log_ret(_ret) (_ret)
#define log_msg_ret(_msg, _ret) ((void)(_msg), _ret)
+#define log_retz(_ret) (_ret)
+#define log_msg_retz(_msg, _ret) ((void)(_msg), _ret)
#endif
+/** * enum log_rec_flags - Flags for a log record */
+enum log_rec_flags {
+ /** @LOGRECF_FORCE_DEBUG: Force output of debug record */
+ LOGRECF_FORCE_DEBUG = BIT(0),
+ /** @LOGRECF_CONT: Continuation of previous log record */
+ LOGRECF_CONT = BIT(1),
+};
+
/**
* struct log_rec - a single log record
*
@@ -337,18 +365,18 @@
*
* @cat: Category, representing a uclass or part of U-Boot
* @level: Severity level, less severe is higher
- * @force_debug: Force output of debug
- * @file: Name of file where the log record was generated (not allocated)
* @line: Line number where the log record was generated
+ * @flags: Flags for log record (enum log_rec_flags)
+ * @file: Name of file where the log record was generated (not allocated)
* @func: Function where the log record was generated (not allocated)
* @msg: Log message (allocated)
*/
struct log_rec {
enum log_category_t cat;
enum log_level_t level;
- bool force_debug;
+ u16 line;
+ u8 flags;
const char *file;
- int line;
const char *func;
const char *msg;
};
diff --git a/include/os.h b/include/os.h
index 65bcb23..77d8bd8 100644
--- a/include/os.h
+++ b/include/os.h
@@ -114,7 +114,7 @@
* os_malloc() - aquires some memory from the underlying os.
*
* @length: Number of bytes to be allocated
- * Return: Pointer to length bytes or NULL on error
+ * Return: Pointer to length bytes or NULL if @length is 0 or on error
*/
void *os_malloc(size_t length);
@@ -123,11 +123,22 @@
*
* This returns the memory to the OS.
*
- * @ptr: Pointer to memory block to free
+ * @ptr: Pointer to memory block to free. If this is NULL then this
+ * function does nothing
*/
void os_free(void *ptr);
/**
+ * os_realloc() - reallocate memory
+ *
+ * This follows the semantics of realloc(), so can perform an os_malloc() or
+ * os_free() depending on @ptr and @length.
+ *
+ * Return: Pointer to reallocated memory or NULL if @length is 0
+ */
+void *os_realloc(void *ptr, size_t length);
+
+/**
* os_usleep() - access to the usleep function of the os
*
* @usec: time to sleep in micro seconds
@@ -313,9 +324,10 @@
*
* @fname: place to put full path to U-Boot
* @maxlen: maximum size of @fname
+ * @use_img: select the 'u-boot.img' file instead of the 'u-boot' ELF file
* Return: 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found
*/
-int os_find_u_boot(char *fname, int maxlen);
+int os_find_u_boot(char *fname, int maxlen, bool use_img);
/**
* os_spl_to_uboot() - Run U-Boot proper
diff --git a/include/scp03.h b/include/scp03.h
new file mode 100644
index 0000000..729667c
--- /dev/null
+++ b/include/scp03.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#ifndef _SCP03_H
+#define _SCP03_H
+
+/*
+ * Requests to OPTEE to enable or provision the Secure Channel Protocol on its
+ * Secure Element
+ *
+ * If key provisioning is requested, OPTEE shall generate new SCP03 keys and
+ * write them to the Secure Element.
+ *
+ * Both functions return < 0 on error else 0.
+ */
+int tee_enable_scp03(void);
+int tee_provision_scp03(void);
+#endif /* _SCP03_H */
diff --git a/include/spl.h b/include/spl.h
index 0d13458..4f6e0e5 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -222,6 +222,15 @@
void *priv;
int bl_len;
const char *filename;
+ /**
+ * read() - Read from device
+ *
+ * @load: Information about the load state
+ * @sector: Sector number to read from (each @load->bl_len bytes)
+ * @count: Number of sectors to read
+ * @buf: Buffer to read into
+ * @return number of sectors read, 0 on error
+ */
ulong (*read)(struct spl_load_info *load, ulong sector, ulong count,
void *buf);
};
diff --git a/include/sysreset.h b/include/sysreset.h
index 8bb094d..701e4f5 100644
--- a/include/sysreset.h
+++ b/include/sysreset.h
@@ -116,6 +116,6 @@
/**
* reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
*/
-void reset_cpu(ulong addr);
+void reset_cpu(void);
#endif
diff --git a/include/tee/optee_ta_scp03.h b/include/tee/optee_ta_scp03.h
new file mode 100644
index 0000000..13f9956
--- /dev/null
+++ b/include/tee/optee_ta_scp03.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+#ifndef __TA_SCP03_H
+#define __TA_SCP03_H
+
+#define PTA_SCP03_UUID { 0xbe0e5821, 0xe718, 0x4f77, \
+ { 0xab, 0x3e, 0x8e, 0x6c, 0x73, 0xa9, 0xc7, 0x35 } }
+
+/*
+ * Enable Secure Channel Protocol functionality (SCP03) on the Secure Element.
+ * Setting the operation value to something different than NULL will trigger
+ * the SCP03 provisioning request.
+ *
+ * in params[0].a = operation
+ */
+#define PTA_CMD_ENABLE_SCP03 0
+
+#endif /*__TA_SCP03_H*/
diff --git a/include/test/test.h b/include/test/test.h
index 3fdaa2b..0b124ed 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -14,16 +14,24 @@
*
* @fail_count: Number of tests that failed
* @start: Store the starting mallinfo when doing leak test
- * @priv: A pointer to some other info some suites want to track
+ * @of_live: true to use livetree if available, false to use flattree
* @of_root: Record of the livetree root node (used for setting up tests)
+ * @root: Root device
+ * @testdev: Test device
+ * @force_fail_alloc: Force all memory allocs to fail
+ * @skip_post_probe: Skip uclass post-probe processing
* @expect_str: Temporary string used to hold expected string value
* @actual_str: Temporary string used to hold actual string value
*/
struct unit_test_state {
int fail_count;
struct mallinfo start;
- void *priv;
struct device_node *of_root;
+ bool of_live;
+ struct udevice *root;
+ struct udevice *testdev;
+ int force_fail_alloc;
+ int skip_post_probe;
char expect_str[256];
char actual_str[256];
};
@@ -36,6 +44,8 @@
UT_TESTF_FLAT_TREE = BIT(3), /* test needs flat DT */
UT_TESTF_LIVE_TREE = BIT(4), /* needs live device tree */
UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */
+ /* do extra driver model init and uninit */
+ UT_TESTF_DM = BIT(6),
};
/**
@@ -76,13 +86,24 @@
* @_suite: name of the test suite concatenated with "_test"
*/
#define UNIT_TEST(_name, _flags, _suite) \
- ll_entry_declare(struct unit_test, _name, _suite) = { \
+ ll_entry_declare(struct unit_test, _name, ut_ ## _suite) = { \
.file = __FILE__, \
.name = #_name, \
.flags = _flags, \
.func = _name, \
}
+/* Get the start of a list of unit tests for a particular suite */
+#define UNIT_TEST_SUITE_START(_suite) \
+ ll_entry_start(struct unit_test, ut_ ## _suite)
+#define UNIT_TEST_SUITE_COUNT(_suite) \
+ ll_entry_count(struct unit_test, ut_ ## _suite)
+
+/* Use ! and ~ so that all tests will be sorted between these two values */
+#define UNIT_TEST_ALL_START() ll_entry_start(struct unit_test, ut_!)
+#define UNIT_TEST_ALL_END() ll_entry_start(struct unit_test, ut_~)
+#define UNIT_TEST_ALL_COUNT() (UNIT_TEST_ALL_END() - UNIT_TEST_ALL_START())
+
/* Sizes for devres tests */
enum {
TEST_DEVRES_SIZE = 100,
@@ -103,15 +124,4 @@
*/
struct udevice *testbus_get_clear_removed(void);
-/**
- * dm_test_main() - Run driver model tests
- *
- * Run all the available driver model tests, or a selection
- *
- * @test_name: Name of single test to run (e.g. "dm_test_fdt_pre_reloc" or just
- * "fdt_pre_reloc"), or NULL to run all
- * @return 0 if all tests passed, 1 if not
- */
-int dm_test_main(const char *test_name);
-
#endif /* __TEST_TEST_H */
diff --git a/include/test/ut.h b/include/test/ut.h
index 17400c7..fbbba28 100644
--- a/include/test/ut.h
+++ b/include/test/ut.h
@@ -356,4 +356,49 @@
*/
void ut_unsilence_console(struct unit_test_state *uts);
+/**
+ * ut_set_skip_delays() - Sets whether delays should be skipped
+ *
+ * Normally functions like mdelay() cause U-Boot to wait for a while. This
+ * allows all such delays to be skipped on sandbox, to speed up tests
+ *
+ * @uts: Test state (in case in future we want to keep state here)
+ * @skip_delays: true to skip delays, false to process them normally
+ */
+void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays);
+
+/**
+ * test_get_state() - Get the active test state
+ *
+ * @return the currently active test state, or NULL if none
+ */
+struct unit_test_state *test_get_state(void);
+
+/**
+ * test_set_state() - Set the active test state
+ *
+ * @uts: Test state to use as currently active test state, or NULL if none
+ */
+void test_set_state(struct unit_test_state *uts);
+
+/**
+ * ut_run_tests() - Run a set of tests
+ *
+ * This runs the test, handling any preparation and clean-up needed. It prints
+ * the name of each test before running it.
+ *
+ * @category: Category of these tests. This is a string printed at the start to
+ * announce the the number of tests
+ * @prefix: String prefix for the tests. Any tests that have this prefix will be
+ * printed without the prefix, so that it is easier to see the unique part
+ * of the test name. If NULL, no prefix processing is done
+ * @tests: List of tests to run
+ * @count: Number of tests to run
+ * @select_name: Name of a single test to run (from the list provided). If NULL
+ * then all tests are run
+ * @return 0 if all tests passed, -1 if any failed
+ */
+int ut_run_list(const char *name, const char *prefix, struct unit_test *tests,
+ int count, const char *select_name);
+
#endif
diff --git a/include/tpm-common.h b/include/tpm-common.h
index c1309a2..998b4fb 100644
--- a/include/tpm-common.h
+++ b/include/tpm-common.h
@@ -55,6 +55,8 @@
* @buf: Buffer used during the exchanges with the chip
* @pcr_count: Number of PCR per bank
* @pcr_select_min: Minimum size in bytes of the pcrSelect array
+ * @plat_hier_disabled: Platform hierarchy has been disabled (TPM is locked
+ * down until next reboot)
*/
struct tpm_chip_priv {
enum tpm_version version;
@@ -66,6 +68,7 @@
/* TPM v2 specific data */
uint pcr_count;
uint pcr_select_min;
+ bool plat_hier_disabled;
};
/**
diff --git a/include/tpm-v1.h b/include/tpm-v1.h
index 8f6cc28..fcfe1f0 100644
--- a/include/tpm-v1.h
+++ b/include/tpm-v1.h
@@ -289,7 +289,7 @@
* @param mode TPM startup mode
* @return return code of the operation
*/
-u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode);
+u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode);
/**
* Issue a TPM_SelfTestFull command.
@@ -297,7 +297,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_self_test_full(struct udevice *dev);
+u32 tpm1_self_test_full(struct udevice *dev);
/**
* Issue a TPM_ContinueSelfTest command.
@@ -305,7 +305,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_continue_self_test(struct udevice *dev);
+u32 tpm1_continue_self_test(struct udevice *dev);
/**
* Issue a TPM_NV_DefineSpace command. The implementation is limited
@@ -318,7 +318,7 @@
* @param size size of the area
* @return return code of the operation
*/
-u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size);
+u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size);
/**
* Issue a TPM_NV_ReadValue command. This implementation is limited
@@ -331,7 +331,7 @@
* @param count size of output buffer
* @return return code of the operation
*/
-u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count);
+u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count);
/**
* Issue a TPM_NV_WriteValue command. This implementation is limited
@@ -344,8 +344,8 @@
* @param length length of data bytes of input buffer
* @return return code of the operation
*/
-u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
- u32 length);
+u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 length);
/**
* Issue a TPM_Extend command.
@@ -358,8 +358,8 @@
* command
* @return return code of the operation
*/
-u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest,
- void *out_digest);
+u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
+ void *out_digest);
/**
* Issue a TPM_PCRRead command.
@@ -370,7 +370,7 @@
* @param count size of output buffer
* @return return code of the operation
*/
-u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count);
+u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count);
/**
* Issue a TSC_PhysicalPresence command. TPM physical presence flag
@@ -380,7 +380,7 @@
* @param presence TPM physical presence flag
* @return return code of the operation
*/
-u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence);
+u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence);
/**
* Issue a TPM_ReadPubek command.
@@ -390,7 +390,7 @@
* @param count size of output buffer
* @return return code of the operation
*/
-u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count);
+u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count);
/**
* Issue a TPM_ForceClear command.
@@ -398,7 +398,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_force_clear(struct udevice *dev);
+u32 tpm1_force_clear(struct udevice *dev);
/**
* Issue a TPM_PhysicalEnable command.
@@ -406,7 +406,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_physical_enable(struct udevice *dev);
+u32 tpm1_physical_enable(struct udevice *dev);
/**
* Issue a TPM_PhysicalDisable command.
@@ -414,7 +414,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_physical_disable(struct udevice *dev);
+u32 tpm1_physical_disable(struct udevice *dev);
/**
* Issue a TPM_PhysicalSetDeactivated command.
@@ -423,7 +423,7 @@
* @param state boolean state of the deactivated flag
* @return return code of the operation
*/
-u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state);
+u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state);
/**
* Issue a TPM_GetCapability command. This implementation is limited
@@ -437,8 +437,8 @@
* @param count size of output buffer
* @return return code of the operation
*/
-u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
- void *cap, size_t count);
+u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+ void *cap, size_t count);
/**
* Issue a TPM_FlushSpecific command for a AUTH resource.
@@ -447,7 +447,7 @@
* @param auth_handle handle of the auth session
* @return return code of the operation
*/
-u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle);
+u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle);
/**
* Issue a TPM_OIAP command to setup an object independent authorization
@@ -460,7 +460,7 @@
* @param auth_handle pointer to the (new) auth handle or NULL.
* @return return code of the operation
*/
-u32 tpm_oiap(struct udevice *dev, u32 *auth_handle);
+u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle);
/**
* Ends an active OIAP session.
@@ -468,7 +468,7 @@
* @param dev TPM device
* @return return code of the operation
*/
-u32 tpm_end_oiap(struct udevice *dev);
+u32 tpm1_end_oiap(struct udevice *dev);
/**
* Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating
@@ -482,9 +482,9 @@
* @param key_handle pointer to the key handle
* @return return code of the operation
*/
-u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
- size_t key_length, const void *parent_key_usage_auth,
- u32 *key_handle);
+u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
+ size_t key_length, const void *parent_key_usage_auth,
+ u32 *key_handle);
/**
* Issue a TPM_GetPubKey (Auth1) command using an OIAP session for
@@ -500,9 +500,9 @@
* of the stored TPM_PUBKEY structure (iff pubkey != NULL).
* @return return code of the operation
*/
-u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
- const void *usage_auth, void *pubkey,
- size_t *pubkey_len);
+u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
+ const void *usage_auth, void *pubkey,
+ size_t *pubkey_len);
/**
* Get the TPM permanent flags value
@@ -511,8 +511,8 @@
* @param pflags Place to put permanent flags
* @return return code of the operation
*/
-u32 tpm_get_permanent_flags(struct udevice *dev,
- struct tpm_permanent_flags *pflags);
+u32 tpm1_get_permanent_flags(struct udevice *dev,
+ struct tpm_permanent_flags *pflags);
/**
* Get the TPM permissions
@@ -521,7 +521,7 @@
* @param perm Returns permissions value
* @return return code of the operation
*/
-u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm);
+u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm);
/**
* Flush a resource with a given handle and type from the TPM
@@ -531,7 +531,7 @@
* @param resource_type type of the resource
* @return return code of the operation
*/
-u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type);
+u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type);
#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
/**
@@ -543,8 +543,8 @@
* @param[out] handle The handle of the key (Non-null iff found)
* @return 0 if key was found in TPM; != 0 if not.
*/
-u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
- const u8 pubkey_digest[20], u32 *handle);
+u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
+ const u8 pubkey_digest[20], u32 *handle);
#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
/**
@@ -557,7 +557,7 @@
* @param count size of output buffer
* @return return code of the operation
*/
-u32 tpm_get_random(struct udevice *dev, void *data, u32 count);
+u32 tpm1_get_random(struct udevice *dev, void *data, u32 count);
/**
* tpm_finalise_physical_presence() - Finalise physical presence
@@ -565,15 +565,15 @@
* @param dev TPM device
* @return return code of the operation (0 = success)
*/
-u32 tpm_finalise_physical_presence(struct udevice *dev);
+u32 tpm1_finalise_physical_presence(struct udevice *dev);
/**
- * tpm_nv_set_locked() - lock the non-volatile space
+ * tpm_nv_enable_locking() - lock the non-volatile space
*
* @param dev TPM device
* @return return code of the operation (0 = success)
*/
-u32 tpm_nv_set_locked(struct udevice *dev);
+u32 tpm1_nv_set_locked(struct udevice *dev);
/**
* tpm_set_global_lock() - set the global lock
@@ -589,6 +589,6 @@
* @param dev TPM device
* @return return code of the operation (0 = success)
*/
-u32 tpm_resume(struct udevice *dev);
+u32 tpm1_resume(struct udevice *dev);
#endif /* __TPM_V1_H */
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 56eaa65..df67a19 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -237,10 +237,14 @@
enum tpm2_command_codes {
TPM2_CC_STARTUP = 0x0144,
TPM2_CC_SELF_TEST = 0x0143,
+ TPM2_CC_HIER_CONTROL = 0x0121,
TPM2_CC_CLEAR = 0x0126,
TPM2_CC_CLEARCONTROL = 0x0127,
TPM2_CC_HIERCHANGEAUTH = 0x0129,
+ TPM2_CC_NV_DEFINE_SPACE = 0x012a,
TPM2_CC_PCR_SETAUTHPOL = 0x012C,
+ TPM2_CC_NV_WRITE = 0x0137,
+ TPM2_CC_NV_WRITELOCK = 0x0138,
TPM2_CC_DAM_RESET = 0x0139,
TPM2_CC_DAM_PARAMETERS = 0x013A,
TPM2_CC_NV_READ = 0x014E,
@@ -271,6 +275,7 @@
TPM2_RC_COMMAND_CODE = TPM2_RC_VER1 + 0x0043,
TPM2_RC_AUTHSIZE = TPM2_RC_VER1 + 0x0044,
TPM2_RC_AUTH_CONTEXT = TPM2_RC_VER1 + 0x0045,
+ TPM2_RC_NV_DEFINED = TPM2_RC_VER1 + 0x004c,
TPM2_RC_NEEDS_TEST = TPM2_RC_VER1 + 0x0053,
TPM2_RC_WARN = 0x0900,
TPM2_RC_TESTING = TPM2_RC_WARN + 0x000A,
@@ -355,6 +360,20 @@
TPM_MAX_BUF_SIZE = 1260,
};
+enum {
+ /* Secure storage for firmware settings */
+ TPM_HT_PCR = 0,
+ TPM_HT_NV_INDEX,
+ TPM_HT_HMAC_SESSION,
+ TPM_HT_POLICY_SESSION,
+
+ HR_SHIFT = 24,
+ HR_PCR = TPM_HT_PCR << HR_SHIFT,
+ HR_HMAC_SESSION = TPM_HT_HMAC_SESSION << HR_SHIFT,
+ HR_POLICY_SESSION = TPM_HT_POLICY_SESSION << HR_SHIFT,
+ HR_NV_INDEX = TPM_HT_NV_INDEX << HR_SHIFT,
+};
+
/**
* Issue a TPM2_Startup command.
*
@@ -389,6 +408,23 @@
const ssize_t pw_sz);
/**
+ * Issue a TPM_NV_DefineSpace command
+ *
+ * This allows a space to be defined with given attributes and policy
+ *
+ * @dev TPM device
+ * @space_index index of the area
+ * @space_size size of area in bytes
+ * @nv_attributes TPM_NV_ATTRIBUTES of the area
+ * @nv_policy policy to use
+ * @nv_policy_size size of the policy
+ * @return return code of the operation
+ */
+u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index,
+ size_t space_size, u32 nv_attributes,
+ const u8 *nv_policy, size_t nv_policy_size);
+
+/**
* Issue a TPM2_PCR_Extend command.
*
* @dev TPM device
@@ -403,6 +439,29 @@
const u8 *digest, u32 digest_len);
/**
+ * Read data from the secure storage
+ *
+ * @dev TPM device
+ * @index Index of data to read
+ * @data Place to put data
+ * @count Number of bytes of data
+ * @return code of the operation
+ */
+u32 tpm2_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count);
+
+/**
+ * Write data to the secure storage
+ *
+ * @dev TPM device
+ * @index Index of data to write
+ * @data Data to write
+ * @count Number of bytes of data
+ * @return code of the operation
+ */
+u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 count);
+
+/**
* Issue a TPM2_PCR_Read command.
*
* @dev TPM device
@@ -516,4 +575,26 @@
*/
u32 tpm2_get_random(struct udevice *dev, void *data, u32 count);
+/**
+ * Lock data in the TPM
+ *
+ * Once locked the data cannot be written until after a reboot
+ *
+ * @dev TPM device
+ * @index Index of data to lock
+ * @return code of the operation
+ */
+u32 tpm2_write_lock(struct udevice *dev, u32 index);
+
+/**
+ * Disable access to any platform data
+ *
+ * This can be called to close off access to the firmware data in the data,
+ * before calling the kernel.
+ *
+ * @dev TPM device
+ * @return code of the operation
+ */
+u32 tpm2_disable_platform_hierarchy(struct udevice *dev);
+
#endif /* __TPM_V2_H */
diff --git a/include/tpm_api.h b/include/tpm_api.h
new file mode 100644
index 0000000..f13d98c
--- /dev/null
+++ b/include/tpm_api.h
@@ -0,0 +1,322 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_API_H
+#define __TPM_API_H
+
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include <tpm-v2.h>
+
+/**
+ * Issue a TPM_Startup command.
+ *
+ * @param dev TPM device
+ * @param mode TPM startup mode
+ * @return return code of the operation
+ */
+u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode);
+
+/**
+ * Issue a TPM_SelfTestFull command.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_self_test_full(struct udevice *dev);
+
+/**
+ * Issue a TPM_ContinueSelfTest command.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_continue_self_test(struct udevice *dev);
+
+/**
+ * Issue a TPM_NV_DefineSpace command. The implementation is limited
+ * to specify TPM_NV_ATTRIBUTES and size of the area. The area index
+ * could be one of the special value listed in enum tpm_nv_index.
+ *
+ * @param dev TPM device
+ * @param index index of the area
+ * @param perm TPM_NV_ATTRIBUTES of the area
+ * @param size size of the area
+ * @return return code of the operation
+ */
+u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size);
+
+/**
+ * Issue a TPM_NV_ReadValue command. This implementation is limited
+ * to read the area from offset 0. The area index could be one of
+ * the special value listed in enum tpm_nv_index.
+ *
+ * @param dev TPM device
+ * @param index index of the area
+ * @param data output buffer of the area contents
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count);
+
+/**
+ * Issue a TPM_NV_WriteValue command. This implementation is limited
+ * to write the area from offset 0. The area index could be one of
+ * the special value listed in enum tpm_nv_index.
+ *
+ * @param dev TPM device
+ * @param index index of the area
+ * @param data input buffer to be wrote to the area
+ * @param length length of data bytes of input buffer
+ * @return return code of the operation
+ */
+u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 length);
+
+/**
+ * Issue a TPM_Extend command.
+ *
+ * @param dev TPM device
+ * @param index index of the PCR
+ * @param in_digest 160-bit value representing the event to be
+ * recorded
+ * @param out_digest 160-bit PCR value after execution of the
+ * command
+ * @return return code of the operation
+ */
+u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest,
+ void *out_digest);
+
+/**
+ * Issue a TPM_PCRRead command.
+ *
+ * @param dev TPM device
+ * @param index index of the PCR
+ * @param data output buffer for contents of the named PCR
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count);
+
+/**
+ * Issue a TSC_PhysicalPresence command. TPM physical presence flag
+ * is bit-wise OR'ed of flags listed in enum tpm_physical_presence.
+ *
+ * @param dev TPM device
+ * @param presence TPM physical presence flag
+ * @return return code of the operation
+ */
+u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence);
+
+/**
+ * Issue a TPM_ReadPubek command.
+ *
+ * @param dev TPM device
+ * @param data output buffer for the public endorsement key
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count);
+
+/**
+ * Issue a TPM_ForceClear command.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_force_clear(struct udevice *dev);
+
+/**
+ * Issue a TPM_PhysicalEnable command.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_physical_enable(struct udevice *dev);
+
+/**
+ * Issue a TPM_PhysicalDisable command.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_physical_disable(struct udevice *dev);
+
+/**
+ * Issue a TPM_PhysicalSetDeactivated command.
+ *
+ * @param dev TPM device
+ * @param state boolean state of the deactivated flag
+ * @return return code of the operation
+ */
+u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state);
+
+/**
+ * Issue a TPM_GetCapability command. This implementation is limited
+ * to query sub_cap index that is 4-byte wide.
+ *
+ * @param dev TPM device
+ * @param cap_area partition of capabilities
+ * @param sub_cap further definition of capability, which is
+ * limited to be 4-byte wide
+ * @param cap output buffer for capability information
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+ void *cap, size_t count);
+
+/**
+ * Issue a TPM_FlushSpecific command for a AUTH resource.
+ *
+ * @param dev TPM device
+ * @param auth_handle handle of the auth session
+ * @return return code of the operation
+ */
+u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle);
+
+/**
+ * Issue a TPM_OIAP command to setup an object independent authorization
+ * session.
+ * Information about the session is stored internally.
+ * If there was already an OIAP session active it is terminated and a new
+ * session is set up.
+ *
+ * @param dev TPM device
+ * @param auth_handle pointer to the (new) auth handle or NULL.
+ * @return return code of the operation
+ */
+u32 tpm_oiap(struct udevice *dev, u32 *auth_handle);
+
+/**
+ * Ends an active OIAP session.
+ *
+ * @param dev TPM device
+ * @return return code of the operation
+ */
+u32 tpm_end_oiap(struct udevice *dev);
+
+/**
+ * Issue a TPM_LoadKey2 (Auth1) command using an OIAP session for authenticating
+ * the usage of the parent key.
+ *
+ * @param dev TPM device
+ * @param parent_handle handle of the parent key.
+ * @param key pointer to the key structure (TPM_KEY or TPM_KEY12).
+ * @param key_length size of the key structure
+ * @param parent_key_usage_auth usage auth for the parent key
+ * @param key_handle pointer to the key handle
+ * @return return code of the operation
+ */
+u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
+ size_t key_length, const void *parent_key_usage_auth,
+ u32 *key_handle);
+
+/**
+ * Issue a TPM_GetPubKey (Auth1) command using an OIAP session for
+ * authenticating the usage of the key.
+ *
+ * @param dev TPM device
+ * @param key_handle handle of the key
+ * @param usage_auth usage auth for the key
+ * @param pubkey pointer to the pub key buffer; may be NULL if the pubkey
+ * should not be stored.
+ * @param pubkey_len pointer to the pub key buffer len. On entry: the size of
+ * the provided pubkey buffer. On successful exit: the size
+ * of the stored TPM_PUBKEY structure (iff pubkey != NULL).
+ * @return return code of the operation
+ */
+u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
+ const void *usage_auth, void *pubkey,
+ size_t *pubkey_len);
+
+/**
+ * Get the TPM permissions
+ *
+ * @param dev TPM device
+ * @param perm Returns permissions value
+ * @return return code of the operation
+ */
+u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm);
+
+/**
+ * Flush a resource with a given handle and type from the TPM
+ *
+ * @param dev TPM device
+ * @param key_handle handle of the resource
+ * @param resource_type type of the resource
+ * @return return code of the operation
+ */
+u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type);
+
+#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
+/**
+ * Search for a key by usage AuthData and the hash of the parent's pub key.
+ *
+ * @param dev TPM device
+ * @param auth Usage auth of the key to search for
+ * @param pubkey_digest SHA1 hash of the pub key structure of the key
+ * @param[out] handle The handle of the key (Non-null iff found)
+ * @return 0 if key was found in TPM; != 0 if not.
+ */
+u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
+ const u8 pubkey_digest[20], u32 *handle);
+#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
+
+/**
+ * Read random bytes from the TPM RNG. The implementation deals with the fact
+ * that the TPM may legally return fewer bytes than requested by retrying
+ * until @p count bytes have been received.
+ *
+ * @param dev TPM device
+ * @param data output buffer for the random bytes
+ * @param count size of output buffer
+ * @return return code of the operation
+ */
+u32 tpm_get_random(struct udevice *dev, void *data, u32 count);
+
+/**
+ * tpm_finalise_physical_presence() - Finalise physical presence
+ *
+ * @param dev TPM device
+ * @return return code of the operation (0 = success)
+ */
+u32 tpm_finalise_physical_presence(struct udevice *dev);
+
+/**
+ * tpm_nv_enable_locking() - lock the non-volatile space
+ *
+ * @param dev TPM device
+ * @return return code of the operation (0 = success)
+ */
+u32 tpm_nv_enable_locking(struct udevice *dev);
+
+/**
+ * tpm_set_global_lock() - set the global lock
+ *
+ * @param dev TPM device
+ * @return return code of the operation (0 = success)
+ */
+u32 tpm_set_global_lock(struct udevice *dev);
+
+/**
+ * tpm_write_lock() - lock the non-volatile space
+ *
+ * @param dev TPM device
+ * @param index Index of space to lock
+ * @return return code of the operation (0 = success)
+ */
+u32 tpm_write_lock(struct udevice *dev, u32 index);
+
+/**
+ * tpm_resume() - start up the TPM from resume (after suspend)
+ *
+ * @param dev TPM device
+ * @return return code of the operation (0 = success)
+ */
+u32 tpm_resume(struct udevice *dev);
+
+#endif /* __TPM_API_H */
diff --git a/lib/Makefile b/lib/Makefile
index edc1c3d..c42d4e1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -53,6 +53,7 @@
obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-common.o
ifeq ($(CONFIG_$(SPL_TPL_)TPM),y)
obj-y += crc8.o
+obj-$(CONFIG_TPM) += tpm_api.o
obj-$(CONFIG_TPM_V1) += tpm-v1.o
obj-$(CONFIG_TPM_V2) += tpm-v2.o
endif
diff --git a/lib/tpm-common.c b/lib/tpm-common.c
index e4af87f..4277846 100644
--- a/lib/tpm-common.c
+++ b/lib/tpm-common.c
@@ -166,6 +166,7 @@
u8 response_buffer[COMMAND_BUFFER_SIZE];
size_t response_length;
int i;
+ uint size;
if (response) {
response_length = *size_ptr;
@@ -174,8 +175,13 @@
response_length = sizeof(response_buffer);
}
- err = tpm_xfer(dev, command, tpm_command_size(command),
- response, &response_length);
+ size = tpm_command_size(command);
+ log_debug("TPM request [size:%d]: ", size);
+ for (i = 0; i < size; i++)
+ log_debug("%02x ", ((u8 *)command)[i]);
+ log_debug("\n");
+
+ err = tpm_xfer(dev, command, size, response, &response_length);
if (err < 0)
return err;
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
index a846fe0..8dc1440 100644
--- a/lib/tpm-v1.c
+++ b/lib/tpm-v1.c
@@ -32,7 +32,7 @@
#endif /* CONFIG_TPM_AUTH_SESSIONS */
-u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
+u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode)
{
const u8 command[12] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
@@ -48,12 +48,12 @@
return tpm_sendrecv_command(dev, buf, NULL, NULL);
}
-u32 tpm_resume(struct udevice *dev)
+u32 tpm1_resume(struct udevice *dev)
{
- return tpm_startup(dev, TPM_ST_STATE);
+ return tpm1_startup(dev, TPM_ST_STATE);
}
-u32 tpm_self_test_full(struct udevice *dev)
+u32 tpm1_self_test_full(struct udevice *dev)
{
const u8 command[10] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
@@ -61,7 +61,7 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_continue_self_test(struct udevice *dev)
+u32 tpm1_continue_self_test(struct udevice *dev)
{
const u8 command[10] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
@@ -69,35 +69,33 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_clear_and_reenable(struct udevice *dev)
+u32 tpm1_clear_and_reenable(struct udevice *dev)
{
u32 ret;
log_info("TPM: Clear and re-enable\n");
- ret = tpm_force_clear(dev);
+ ret = tpm1_force_clear(dev);
if (ret != TPM_SUCCESS) {
log_err("Can't initiate a force clear\n");
return ret;
}
- if (tpm_get_version(dev) == TPM_V1) {
- ret = tpm_physical_enable(dev);
- if (ret != TPM_SUCCESS) {
- log_err("TPM: Can't set enabled state\n");
- return ret;
- }
+ ret = tpm1_physical_enable(dev);
+ if (ret != TPM_SUCCESS) {
+ log_err("TPM: Can't set enabled state\n");
+ return ret;
+ }
- ret = tpm_physical_set_deactivated(dev, 0);
- if (ret != TPM_SUCCESS) {
- log_err("TPM: Can't set deactivated state\n");
- return ret;
- }
+ ret = tpm1_physical_set_deactivated(dev, 0);
+ if (ret != TPM_SUCCESS) {
+ log_err("TPM: Can't set deactivated state\n");
+ return ret;
}
return TPM_SUCCESS;
}
-u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
+u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
{
const u8 command[101] = {
0x0, 0xc1, /* TPM_TAG */
@@ -140,12 +138,12 @@
return tpm_sendrecv_command(dev, buf, NULL, NULL);
}
-u32 tpm_nv_set_locked(struct udevice *dev)
+u32 tpm1_nv_set_locked(struct udevice *dev)
{
- return tpm_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
+ return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
}
-u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
+u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
{
const u8 command[22] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
@@ -179,8 +177,8 @@
return 0;
}
-u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
- u32 length)
+u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 length)
{
const u8 command[256] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
@@ -210,13 +208,8 @@
return 0;
}
-uint32_t tpm_set_global_lock(struct udevice *dev)
-{
- return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0);
-}
-
-u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest,
- void *out_digest)
+u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
+ void *out_digest)
{
const u8 command[34] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
@@ -247,7 +240,7 @@
return 0;
}
-u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
+u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
{
const u8 command[14] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
@@ -275,7 +268,7 @@
return 0;
}
-u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence)
+u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
{
const u8 command[12] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
@@ -291,7 +284,7 @@
return tpm_sendrecv_command(dev, buf, NULL, NULL);
}
-u32 tpm_finalise_physical_presence(struct udevice *dev)
+u32 tpm1_finalise_physical_presence(struct udevice *dev)
{
const u8 command[12] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
@@ -300,7 +293,7 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count)
+u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
{
const u8 command[30] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
@@ -331,7 +324,7 @@
return 0;
}
-u32 tpm_force_clear(struct udevice *dev)
+u32 tpm1_force_clear(struct udevice *dev)
{
const u8 command[10] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
@@ -340,7 +333,7 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_physical_enable(struct udevice *dev)
+u32 tpm1_physical_enable(struct udevice *dev)
{
const u8 command[10] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
@@ -349,7 +342,7 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_physical_disable(struct udevice *dev)
+u32 tpm1_physical_disable(struct udevice *dev)
{
const u8 command[10] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
@@ -358,7 +351,7 @@
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
-u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state)
+u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
{
const u8 command[11] = {
0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
@@ -374,8 +367,8 @@
return tpm_sendrecv_command(dev, buf, NULL, NULL);
}
-u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
- void *cap, size_t count)
+u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+ void *cap, size_t count)
{
const u8 command[22] = {
0x0, 0xc1, /* TPM_TAG */
@@ -414,8 +407,8 @@
return 0;
}
-u32 tpm_get_permanent_flags(struct udevice *dev,
- struct tpm_permanent_flags *pflags)
+u32 tpm1_get_permanent_flags(struct udevice *dev,
+ struct tpm_permanent_flags *pflags)
{
const u8 command[22] = {
0x0, 0xc1, /* TPM_TAG */
@@ -453,7 +446,7 @@
return 0;
}
-u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm)
+u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
{
const u8 command[22] = {
0x0, 0xc1, /* TPM_TAG */
@@ -482,7 +475,7 @@
}
#ifdef CONFIG_TPM_FLUSH_RESOURCES
-u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
+u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
{
const u8 command[18] = {
0x00, 0xc1, /* TPM_TAG */
@@ -641,7 +634,7 @@
return TPM_SUCCESS;
}
-u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle)
+u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
{
const u8 command[18] = {
0x00, 0xc1, /* TPM_TAG */
@@ -663,16 +656,16 @@
return tpm_sendrecv_command(dev, request, NULL, NULL);
}
-u32 tpm_end_oiap(struct udevice *dev)
+u32 tpm1_end_oiap(struct udevice *dev)
{
u32 err = TPM_SUCCESS;
if (oiap_session.valid)
- err = tpm_terminate_auth_session(dev, oiap_session.handle);
+ err = tpm1_terminate_auth_session(dev, oiap_session.handle);
return err;
}
-u32 tpm_oiap(struct udevice *dev, u32 *auth_handle)
+u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
{
const u8 command[10] = {
0x00, 0xc1, /* TPM_TAG */
@@ -686,7 +679,7 @@
u32 err;
if (oiap_session.valid)
- tpm_terminate_auth_session(dev, oiap_session.handle);
+ tpm1_terminate_auth_session(dev, oiap_session.handle);
err = tpm_sendrecv_command(dev, command, response, &response_length);
if (err)
@@ -702,9 +695,9 @@
return 0;
}
-u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
- size_t key_length, const void *parent_key_usage_auth,
- u32 *key_handle)
+u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
+ size_t key_length, const void *parent_key_usage_auth,
+ u32 *key_handle)
{
const u8 command[14] = {
0x00, 0xc2, /* TPM_TAG */
@@ -723,7 +716,7 @@
u32 err;
if (!oiap_session.valid) {
- err = tpm_oiap(dev, NULL);
+ err = tpm1_oiap(dev, NULL);
if (err)
return err;
}
@@ -768,9 +761,9 @@
return 0;
}
-u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
- const void *usage_auth, void *pubkey,
- size_t *pubkey_len)
+u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
+ const void *usage_auth, void *pubkey,
+ size_t *pubkey_len)
{
const u8 command[14] = {
0x00, 0xc2, /* TPM_TAG */
@@ -788,7 +781,7 @@
u32 err;
if (!oiap_session.valid) {
- err = tpm_oiap(dev, NULL);
+ err = tpm1_oiap(dev, NULL);
if (err)
return err;
}
@@ -834,8 +827,8 @@
}
#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
-u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
- const u8 pubkey_digest[20], u32 *handle)
+u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
+ const u8 pubkey_digest[20], u32 *handle)
{
u16 key_count;
u32 key_handles[10];
@@ -876,7 +869,7 @@
#endif /* CONFIG_TPM_AUTH_SESSIONS */
-u32 tpm_get_random(struct udevice *dev, void *data, u32 count)
+u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
{
const u8 command[14] = {
0x0, 0xc1, /* TPM_TAG */
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 1f3deb0..235f8c2 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -47,9 +47,11 @@
u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
const ssize_t pw_sz)
{
+ /* Length of the message header, up to start of password */
+ uint offset = 27;
u8 command_v2[COMMAND_BUFFER_SIZE] = {
tpm_u16(TPM2_ST_SESSIONS), /* TAG */
- tpm_u32(27 + pw_sz), /* Length */
+ tpm_u32(offset + pw_sz), /* Length */
tpm_u32(TPM2_CC_CLEAR), /* Command code */
/* HANDLE */
@@ -64,7 +66,6 @@
tpm_u16(pw_sz), /* Size of <hmac/password> */
/* STRING(pw) <hmac/password> (if any) */
};
- unsigned int offset = 27;
int ret;
/*
@@ -80,12 +81,61 @@
return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
}
+u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index,
+ size_t space_size, u32 nv_attributes,
+ const u8 *nv_policy, size_t nv_policy_size)
+{
+ /*
+ * Calculate the offset of the nv_policy piece by adding each of the
+ * chunks below.
+ */
+ uint offset = 10 + 8 + 13 + 14;
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ /* header 10 bytes */
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(offset + nv_policy_size),/* Length */
+ tpm_u32(TPM2_CC_NV_DEFINE_SPACE),/* Command code */
+
+ /* handles 8 bytes */
+ tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
+
+ /* session header 13 bytes */
+ tpm_u32(9), /* Header size */
+ tpm_u32(TPM2_RS_PW), /* Password authorisation */
+ tpm_u16(0), /* nonce_size */
+ 0, /* session_attrs */
+ tpm_u16(0), /* auth_size */
+
+ /* message 14 bytes + policy */
+ tpm_u16(12 + nv_policy_size), /* size */
+ tpm_u32(space_index),
+ tpm_u16(TPM2_ALG_SHA256),
+ tpm_u32(nv_attributes),
+ tpm_u16(nv_policy_size),
+ /* nv_policy */
+ };
+ int ret;
+
+ /*
+ * Fill the command structure starting from the first buffer:
+ * - the password (if any)
+ */
+ ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+ offset, nv_policy, nv_policy_size);
+ if (ret)
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
+}
+
u32 tpm2_pcr_extend(struct udevice *dev, u32 index, u32 algorithm,
const u8 *digest, u32 digest_len)
{
+ /* Length of the message header, up to start of digest */
+ uint offset = 33;
u8 command_v2[COMMAND_BUFFER_SIZE] = {
tpm_u16(TPM2_ST_SESSIONS), /* TAG */
- tpm_u32(33 + digest_len), /* Length */
+ tpm_u32(offset + digest_len), /* Length */
tpm_u32(TPM2_CC_PCR_EXTEND), /* Command code */
/* HANDLE */
@@ -99,11 +149,12 @@
0, /* Attributes: Cont/Excl/Rst */
tpm_u16(0), /* Size of <hmac/password> */
/* <hmac/password> (if any) */
+
+ /* hashes */
tpm_u32(1), /* Count (number of hashes) */
tpm_u16(algorithm), /* Algorithm of the hash */
/* STRING(digest) Digest */
};
- unsigned int offset = 33;
int ret;
/*
@@ -112,13 +163,96 @@
*/
ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
offset, digest, digest_len);
- offset += digest_len;
if (ret)
return TPM_LIB_ERROR;
return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
}
+u32 tpm2_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
+{
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ /* header 10 bytes */
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(10 + 8 + 4 + 9 + 4), /* Length */
+ tpm_u32(TPM2_CC_NV_READ), /* Command code */
+
+ /* handles 8 bytes */
+ tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
+ tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+
+ /* AUTH_SESSION */
+ tpm_u32(9), /* Authorization size */
+ tpm_u32(TPM2_RS_PW), /* Session handle */
+ tpm_u16(0), /* Size of <nonce> */
+ /* <nonce> (if any) */
+ 0, /* Attributes: Cont/Excl/Rst */
+ tpm_u16(0), /* Size of <hmac/password> */
+ /* <hmac/password> (if any) */
+
+ tpm_u16(count), /* Number of bytes */
+ tpm_u16(0), /* Offset */
+ };
+ size_t response_len = COMMAND_BUFFER_SIZE;
+ u8 response[COMMAND_BUFFER_SIZE];
+ int ret;
+ u16 tag;
+ u32 size, code;
+
+ ret = tpm_sendrecv_command(dev, command_v2, response, &response_len);
+ if (ret)
+ return log_msg_ret("read", ret);
+ if (unpack_byte_string(response, response_len, "wdds",
+ 0, &tag, 2, &size, 6, &code,
+ 16, data, count))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 count)
+{
+ struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
+ uint offset = 10 + 8 + 4 + 9 + 2;
+ uint len = offset + count + 2;
+ /* Use empty password auth if platform hierarchy is disabled */
+ u32 auth = priv->plat_hier_disabled ? HR_NV_INDEX + index :
+ TPM2_RH_PLATFORM;
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ /* header 10 bytes */
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(len), /* Length */
+ tpm_u32(TPM2_CC_NV_WRITE), /* Command code */
+
+ /* handles 8 bytes */
+ tpm_u32(auth), /* Primary platform seed */
+ tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+
+ /* AUTH_SESSION */
+ tpm_u32(9), /* Authorization size */
+ tpm_u32(TPM2_RS_PW), /* Session handle */
+ tpm_u16(0), /* Size of <nonce> */
+ /* <nonce> (if any) */
+ 0, /* Attributes: Cont/Excl/Rst */
+ tpm_u16(0), /* Size of <hmac/password> */
+ /* <hmac/password> (if any) */
+
+ tpm_u16(count),
+ };
+ size_t response_len = COMMAND_BUFFER_SIZE;
+ u8 response[COMMAND_BUFFER_SIZE];
+ int ret;
+
+ ret = pack_byte_string(command_v2, sizeof(command_v2), "sw",
+ offset, data, count,
+ offset + count, 0);
+ if (ret)
+ return TPM_LIB_ERROR;
+
+ return tpm_sendrecv_command(dev, command_v2, response, &response_len);
+}
+
u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
void *data, unsigned int *updates)
{
@@ -467,3 +601,61 @@
return 0;
}
+
+u32 tpm2_write_lock(struct udevice *dev, u32 index)
+{
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ /* header 10 bytes */
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(10 + 8 + 13), /* Length */
+ tpm_u32(TPM2_CC_NV_WRITELOCK), /* Command code */
+
+ /* handles 8 bytes */
+ tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
+ tpm_u32(HR_NV_INDEX + index), /* Password authorisation */
+
+ /* session header 9 bytes */
+ tpm_u32(9), /* Header size */
+ tpm_u32(TPM2_RS_PW), /* Password authorisation */
+ tpm_u16(0), /* nonce_size */
+ 0, /* session_attrs */
+ tpm_u16(0), /* auth_size */
+ };
+
+ return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
+}
+
+u32 tpm2_disable_platform_hierarchy(struct udevice *dev)
+{
+ struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
+ u8 command_v2[COMMAND_BUFFER_SIZE] = {
+ /* header 10 bytes */
+ tpm_u16(TPM2_ST_SESSIONS), /* TAG */
+ tpm_u32(10 + 4 + 13 + 5), /* Length */
+ tpm_u32(TPM2_CC_HIER_CONTROL), /* Command code */
+
+ /* 4 bytes */
+ tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */
+
+ /* session header 9 bytes */
+ tpm_u32(9), /* Header size */
+ tpm_u32(TPM2_RS_PW), /* Password authorisation */
+ tpm_u16(0), /* nonce_size */
+ 0, /* session_attrs */
+ tpm_u16(0), /* auth_size */
+
+ /* payload 5 bytes */
+ tpm_u32(TPM2_RH_PLATFORM), /* Hierarchy to disable */
+ 0, /* 0=disable */
+ };
+ int ret;
+
+ ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL);
+ log_info("ret=%s, %x\n", dev->name, ret);
+ if (ret)
+ return ret;
+
+ priv->plat_hier_disabled = true;
+
+ return 0;
+}
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
new file mode 100644
index 0000000..4c66264
--- /dev/null
+++ b/lib/tpm_api.c
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <tpm_api.h>
+#include <tpm-v1.h>
+#include <tpm-v2.h>
+#include <tpm_api.h>
+
+static bool is_tpm1(struct udevice *dev)
+{
+ return IS_ENABLED(CONFIG_TPM_V1) && tpm_get_version(dev) == TPM_V1;
+}
+
+static bool is_tpm2(struct udevice *dev)
+{
+ return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
+}
+
+u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
+{
+ if (is_tpm1(dev)) {
+ return tpm1_startup(dev, mode);
+ } else if (is_tpm2(dev)) {
+ enum tpm2_startup_types type;
+
+ switch (mode) {
+ case TPM_ST_CLEAR:
+ type = TPM2_SU_CLEAR;
+ break;
+ case TPM_ST_STATE:
+ type = TPM2_SU_STATE;
+ break;
+ default:
+ case TPM_ST_DEACTIVATED:
+ return -EINVAL;
+ }
+ return tpm2_startup(dev, type);
+ } else {
+ return -ENOSYS;
+ }
+}
+
+u32 tpm_resume(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_startup(dev, TPM_ST_STATE);
+ else if (is_tpm2(dev))
+ return tpm2_startup(dev, TPM2_SU_STATE);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_self_test_full(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_self_test_full(dev);
+ else if (is_tpm2(dev))
+ return tpm2_self_test(dev, TPMI_YES);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_continue_self_test(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_continue_self_test(dev);
+ else if (is_tpm2(dev))
+ return tpm2_self_test(dev, TPMI_NO);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_clear_and_reenable(struct udevice *dev)
+{
+ u32 ret;
+
+ log_info("TPM: Clear and re-enable\n");
+ ret = tpm_force_clear(dev);
+ if (ret != TPM_SUCCESS) {
+ log_err("Can't initiate a force clear\n");
+ return ret;
+ }
+
+ if (is_tpm1(dev)) {
+ ret = tpm1_physical_enable(dev);
+ if (ret != TPM_SUCCESS) {
+ log_err("TPM: Can't set enabled state\n");
+ return ret;
+ }
+
+ ret = tpm1_physical_set_deactivated(dev, 0);
+ if (ret != TPM_SUCCESS) {
+ log_err("TPM: Can't set deactivated state\n");
+ return ret;
+ }
+ }
+
+ return TPM_SUCCESS;
+}
+
+u32 tpm_nv_enable_locking(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
+ else if (is_tpm2(dev))
+ return -ENOSYS;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
+{
+ if (is_tpm1(dev))
+ return tpm1_nv_read_value(dev, index, data, count);
+ else if (is_tpm2(dev))
+ return tpm2_nv_read_value(dev, index, data, count);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
+ u32 count)
+{
+ if (is_tpm1(dev))
+ return tpm1_nv_write_value(dev, index, data, count);
+ else if (is_tpm2(dev))
+ return tpm2_nv_write_value(dev, index, data, count);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_set_global_lock(struct udevice *dev)
+{
+ return tpm_nv_write_value(dev, TPM_NV_INDEX_0, NULL, 0);
+}
+
+u32 tpm_write_lock(struct udevice *dev, u32 index)
+{
+ if (is_tpm1(dev))
+ return -ENOSYS;
+ else if (is_tpm2(dev))
+ return tpm2_write_lock(dev, index);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest,
+ void *out_digest)
+{
+ if (is_tpm1(dev))
+ return tpm1_extend(dev, index, in_digest, out_digest);
+ else if (is_tpm2(dev))
+ return tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, in_digest,
+ TPM2_DIGEST_LEN);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
+{
+ if (is_tpm1(dev))
+ return tpm1_pcr_read(dev, index, data, count);
+ else if (is_tpm2(dev))
+ return -ENOSYS;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence)
+{
+ if (is_tpm1(dev))
+ return tpm1_tsc_physical_presence(dev, presence);
+
+ /*
+ * Nothing to do on TPM2 for this; use platform hierarchy availability
+ * instead.
+ */
+ else if (is_tpm2(dev))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_finalise_physical_presence(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_finalise_physical_presence(dev);
+
+ /* Nothing needs to be done with tpm2 */
+ else if (is_tpm2(dev))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count)
+{
+ if (is_tpm1(dev))
+ return tpm1_read_pubek(dev, data, count);
+ else if (is_tpm2(dev))
+ return -ENOSYS; /* not implemented yet */
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_force_clear(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_force_clear(dev);
+ else if (is_tpm2(dev))
+ return tpm2_clear(dev, TPM2_RH_PLATFORM, NULL, 0);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_physical_enable(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_physical_enable(dev);
+
+ /* Nothing needs to be done with tpm2 */
+ else if (is_tpm2(dev))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_physical_disable(struct udevice *dev)
+{
+ if (is_tpm1(dev))
+ return tpm1_physical_disable(dev);
+
+ /* Nothing needs to be done with tpm2 */
+ else if (is_tpm2(dev))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state)
+{
+ if (is_tpm1(dev))
+ return tpm1_physical_set_deactivated(dev, state);
+ /* Nothing needs to be done with tpm2 */
+ else if (is_tpm2(dev))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
+ void *cap, size_t count)
+{
+ if (is_tpm1(dev))
+ return tpm1_get_capability(dev, cap_area, sub_cap, cap, count);
+ else if (is_tpm2(dev))
+ return tpm2_get_capability(dev, cap_area, sub_cap, cap, count);
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm)
+{
+ if (is_tpm1(dev))
+ return tpm1_get_permissions(dev, index, perm);
+ else if (is_tpm2(dev))
+ return -ENOSYS; /* not implemented yet */
+ else
+ return -ENOSYS;
+}
+
+u32 tpm_get_random(struct udevice *dev, void *data, u32 count)
+{
+ if (is_tpm1(dev))
+ return tpm1_get_random(dev, data, count);
+ else if (is_tpm2(dev))
+ return -ENOSYS; /* not implemented yet */
+ else
+ return -ENOSYS;
+}
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 43295ee..85857a7 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1629,7 +1629,6 @@
CONFIG_STV0991_HZ
CONFIG_STV0991_HZ_CLOCK
CONFIG_ST_SMI
-CONFIG_SUNXI_MAX_FB_SIZE
CONFIG_SXNI855T
CONFIG_SYSFLAGS_ADDR
CONFIG_SYSFS
diff --git a/test/Makefile b/test/Makefile
index 932e517..a26e915 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -2,6 +2,9 @@
#
# (C) Copyright 2012 The Chromium Authors
+obj-y += test-main.o
+obj-$(CONFIG_SANDBOX) += image/
+
ifneq ($(CONFIG_$(SPL_)BLOBLIST),)
obj-$(CONFIG_$(SPL_)CMDLINE) += bloblist.o
obj-$(CONFIG_$(SPL_)CMDLINE) += bootm.o
diff --git a/test/bloblist.c b/test/bloblist.c
index 6953d30..d876b63 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -387,9 +387,8 @@
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- bloblist_test);
- const int n_ents = ll_entry_count(struct unit_test, bloblist_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(bloblist_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(bloblist_test);
return cmd_ut_category("bloblist", "bloblist_test_",
tests, n_ents, argc, argv);
diff --git a/test/bootm.c b/test/bootm.c
index 563d6eb..8528982 100644
--- a/test/bootm.c
+++ b/test/bootm.c
@@ -240,8 +240,8 @@
int do_ut_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, bootm_test);
- const int n_ents = ll_entry_count(struct unit_test, bootm_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(bootm_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(bootm_test);
return cmd_ut_category("bootm", "bootm_test_", tests, n_ents,
argc, argv);
diff --git a/test/cmd/mem.c b/test/cmd/mem.c
index fbaa8a4..d76f47c 100644
--- a/test/cmd/mem.c
+++ b/test/cmd/mem.c
@@ -12,8 +12,8 @@
int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, mem_test);
- const int n_ents = ll_entry_count(struct unit_test, mem_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(mem_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(mem_test);
return cmd_ut_category("cmd_mem", "mem_test_", tests, n_ents, argc,
argv);
diff --git a/test/cmd/setexpr.c b/test/cmd/setexpr.c
index fd6d869..27113c0 100644
--- a/test/cmd/setexpr.c
+++ b/test/cmd/setexpr.c
@@ -306,8 +306,8 @@
ut_asserteq(1, run_command("setexpr.s fred 0", 0));
ut_assertok(ut_check_delta(start_mem));
- start_mem = ut_check_free();
ut_assertok(env_set("fred", "12345"));
+ start_mem = ut_check_free();
ut_assertok(run_command("setexpr.s fred *0", 0));
ut_asserteq_str("hello", env_get("fred"));
ut_assertok(ut_check_delta(start_mem));
@@ -345,7 +345,22 @@
start_mem = ut_check_free();
ut_assertok(run_command("setexpr.s fred *0 + *10", 0));
ut_asserteq_str("hello there", env_get("fred"));
- ut_assertok(ut_check_delta(start_mem));
+
+ /*
+ * This check does not work with sandbox_flattree, apparently due to
+ * memory allocations in env_set().
+ *
+ * The truetype console produces lots of memory allocations even though
+ * the LCD display is not visible. But even without these, it does not
+ * work.
+ *
+ * A better test would be for dlmalloc to record the allocs and frees
+ * for a particular caller, but that is not supported.
+ *
+ * For now, drop this test.
+ *
+ * ut_assertok(ut_check_delta(start_mem));
+ */
unmap_sysmem(buf);
@@ -375,10 +390,9 @@
int do_ut_setexpr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- setexpr_test);
- const int n_ents = ll_entry_count(struct unit_test, setexpr_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(setexpr_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(setexpr_test);
- return cmd_ut_category("cmd_setexpr", "cmd_mem_", tests, n_ents, argc,
- argv);
+ return cmd_ut_category("cmd_setexpr", "setexpr_test_", tests, n_ents,
+ argc, argv);
}
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index 8728cc8..b9c1660 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -9,6 +9,7 @@
#include <console.h>
#include <test/suites.h>
#include <test/test.h>
+#include <test/ut.h>
static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]);
@@ -17,41 +18,12 @@
struct unit_test *tests, int n_ents,
int argc, char *const argv[])
{
- struct unit_test_state uts = { .fail_count = 0 };
- struct unit_test *test;
- int prefix_len = prefix ? strlen(prefix) : 0;
+ int ret;
- if (argc == 1)
- printf("Running %d %s tests\n", n_ents, name);
+ ret = ut_run_list(name, prefix, tests, n_ents,
+ argc > 1 ? argv[1] : NULL);
- for (test = tests; test < tests + n_ents; test++) {
- const char *test_name = test->name;
-
- /* Remove the prefix */
- if (prefix && !strncmp(test_name, prefix, prefix_len))
- test_name += prefix_len;
-
- if (argc > 1 && strcmp(argv[1], test_name))
- continue;
- printf("Test: %s\n", test->name);
-
- if (test->flags & UT_TESTF_CONSOLE_REC) {
- int ret = console_record_reset_enable();
-
- if (ret) {
- printf("Skipping: Console recording disabled\n");
- continue;
- }
- }
-
- uts.start = mallinfo();
-
- test->func(&uts);
- }
-
- printf("Failures: %d\n", uts.fail_count);
-
- return uts.fail_count ? CMD_RET_FAILURE : 0;
+ return ret ? CMD_RET_FAILURE : 0;
}
static struct cmd_tbl cmd_ut_sub[] = {
diff --git a/test/compression.c b/test/compression.c
index a2a4b9f..4cd1be5 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -539,9 +539,8 @@
int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- compression_test);
- const int n_ents = ll_entry_count(struct unit_test, compression_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(compression_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(compression_test);
return cmd_ut_category("compression", "compression_test_",
tests, n_ents, argc, argv);
diff --git a/test/dm/Makefile b/test/dm/Makefile
index fd14551..f5cc554 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -2,7 +2,7 @@
#
# Copyright (c) 2013 Google, Inc
-obj-$(CONFIG_UT_DM) += test-main.o
+obj-$(CONFIG_UT_DM) += test-dm.o
# Tests for particular subsystems - when enabling driver model for a new
# subsystem you must add sandbox tests here.
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index 240187c..2edab7be 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -360,24 +360,24 @@
run_command("acpi list", 0);
addr = (ulong)map_to_sysmem(buf);
ut_assert_nextline("ACPI tables start at %lx", addr);
- ut_assert_nextline("RSDP %08lx %06lx (v02 U-BOOT)", addr,
+ ut_assert_nextline("RSDP %08lx %06zx (v02 U-BOOT)", addr,
sizeof(struct acpi_rsdp));
addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16);
- ut_assert_nextline("RSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("RSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_table_header) +
3 * sizeof(u32), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16);
- ut_assert_nextline("XSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("XSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_table_header) +
3 * sizeof(u64), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
ut_assert_console_end();
diff --git a/test/dm/core.c b/test/dm/core.c
index 35ca689..2210345 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -117,14 +117,13 @@
/* Test that binding with plat occurs correctly */
static int dm_test_autobind(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *dev;
/*
* We should have a single class (UCLASS_ROOT) and a single root
* device with no children.
*/
- ut_assert(dms->root);
+ ut_assert(uts->root);
ut_asserteq(1, list_count_items(gd->uclass_root));
ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
@@ -207,7 +206,6 @@
/* Test that autoprobe finds all the expected devices */
static int dm_test_autoprobe(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
int expected_base_add;
struct udevice *dev;
struct uclass *uc;
@@ -221,7 +219,7 @@
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
/* The root device should not be activated until needed */
- ut_assert(dev_get_flags(dms->root) & DM_FLAG_ACTIVATED);
+ ut_assert(dev_get_flags(uts->root) & DM_FLAG_ACTIVATED);
/*
* We should be able to find the three test devices, and they should
@@ -241,7 +239,7 @@
/* Activating a device should activate the root device */
if (!i)
- ut_assert(dev_get_flags(dms->root) & DM_FLAG_ACTIVATED);
+ ut_assert(dev_get_flags(uts->root) & DM_FLAG_ACTIVATED);
}
/*
@@ -293,7 +291,6 @@
/* Test that we can bind, probe, remove, unbind a driver */
static int dm_test_lifecycle(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
int op_count[DM_TEST_OP_COUNT];
struct udevice *dev, *test_dev;
int pingret;
@@ -301,7 +298,7 @@
memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
@@ -309,7 +306,7 @@
ut_assert(!dev_get_priv(dev));
/* Probe the device - it should fail allocating private data */
- dms->force_fail_alloc = 1;
+ uts->force_fail_alloc = 1;
ret = device_probe(dev);
ut_assert(ret == -ENOMEM);
ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
@@ -317,7 +314,7 @@
ut_assert(!dev_get_priv(dev));
/* Try again without the alloc failure */
- dms->force_fail_alloc = 0;
+ uts->force_fail_alloc = 0;
ut_assertok(device_probe(dev));
ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
== op_count[DM_TEST_OP_PROBE] + 2);
@@ -349,19 +346,18 @@
/* Test that we can bind/unbind and the lists update correctly */
static int dm_test_ordering(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *dev, *dev_penultimate, *dev_last, *test_dev;
int pingret;
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
/* Bind two new devices (numbers 4 and 5) */
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev_penultimate));
ut_assert(dev_penultimate);
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev_last));
ut_assert(dev_last);
@@ -376,7 +372,7 @@
ut_assert(dev_last == test_dev);
/* Add back the original device 3, now in position 5 */
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
@@ -568,7 +564,6 @@
static int dm_test_children(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *top[NODE_COUNT];
struct udevice *child[NODE_COUNT];
struct udevice *grandchild[NODE_COUNT];
@@ -578,12 +573,12 @@
int i;
/* We don't care about the numbering for this test */
- dms->skip_post_probe = 1;
+ uts->skip_post_probe = 1;
ut_assert(NODE_COUNT > 5);
/* First create 10 top-level children */
- ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top));
+ ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
/* Now a few have their own children */
ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
@@ -654,7 +649,6 @@
static int dm_test_device_reparent(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *top[NODE_COUNT];
struct udevice *child[NODE_COUNT];
struct udevice *grandchild[NODE_COUNT];
@@ -664,12 +658,12 @@
int i;
/* We don't care about the numbering for this test */
- dms->skip_post_probe = 1;
+ uts->skip_post_probe = 1;
ut_assert(NODE_COUNT > 5);
/* First create 10 top-level children */
- ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top));
+ ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
/* Now a few have their own children */
ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
@@ -815,15 +809,14 @@
/* Test that pre-relocation devices work as expected */
static int dm_test_pre_reloc(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *dev;
/* The normal driver should refuse to bind before relocation */
- ut_asserteq(-EPERM, device_bind_by_name(dms->root, true,
+ ut_asserteq(-EPERM, device_bind_by_name(uts->root, true,
&driver_info_manual, &dev));
/* But this one is marked pre-reloc */
- ut_assertok(device_bind_by_name(dms->root, true,
+ ut_assertok(device_bind_by_name(uts->root, true,
&driver_info_pre_reloc, &dev));
return 0;
@@ -836,10 +829,9 @@
*/
static int dm_test_remove_active_dma(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *dev;
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_act_dma,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
&dev));
ut_assert(dev);
@@ -872,7 +864,7 @@
* the active DMA remove call
*/
ut_assertok(device_unbind(dev));
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&dev));
ut_assert(dev);
@@ -895,25 +887,24 @@
/* Test removal of 'vital' devices */
static int dm_test_remove_vital(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *normal, *dma, *vital, *dma_vital;
/* Skip the behaviour in test_post_probe() */
- dms->skip_post_probe = 1;
+ uts->skip_post_probe = 1;
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
&normal));
ut_assertnonnull(normal);
- ut_assertok(device_bind_by_name(dms->root, false, &driver_info_act_dma,
+ ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
&dma));
ut_assertnonnull(dma);
- ut_assertok(device_bind_by_name(dms->root, false,
+ ut_assertok(device_bind_by_name(uts->root, false,
&driver_info_vital_clk, &vital));
ut_assertnonnull(vital);
- ut_assertok(device_bind_by_name(dms->root, false,
+ ut_assertok(device_bind_by_name(uts->root, false,
&driver_info_act_dma_vital_clk,
&dma_vital));
ut_assertnonnull(dma_vital);
@@ -1133,11 +1124,10 @@
static int dm_test_inactive_child(struct unit_test_state *uts)
{
- struct dm_test_state *dms = uts->priv;
struct udevice *parent, *dev1, *dev2;
/* Skip the behaviour in test_post_probe() */
- dms->skip_post_probe = 1;
+ uts->skip_post_probe = 1;
ut_assertok(uclass_first_device_err(UCLASS_TEST, &parent));
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index d7b85e7..33ae987 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -80,15 +80,15 @@
/* Make it an open drain output, and reset it */
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
- sandbox_gpio_get_dir_flags(dev, offset));
- ut_assertok(ops->set_dir_flags(dev, offset,
- GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
+ sandbox_gpio_get_flags(dev, offset));
+ ut_assertok(ops->set_flags(dev, offset,
+ GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
- sandbox_gpio_get_dir_flags(dev, offset));
- ut_assertok(ops->set_dir_flags(dev, offset,
- GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
+ sandbox_gpio_get_flags(dev, offset));
+ ut_assertok(ops->set_flags(dev, offset,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
- sandbox_gpio_get_dir_flags(dev, offset));
+ sandbox_gpio_get_flags(dev, offset));
/* Make it an input */
ut_assertok(ops->direction_input(dev, offset));
@@ -176,54 +176,64 @@
/* GPIO 0 is (GPIO_OUT|GPIO_OPEN_DRAIN) */
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
- sandbox_gpio_get_dir_flags(gpio_c, 0));
+ sandbox_gpio_get_flags(gpio_c, 0));
- /* Set it as output high, should become an input */
+ /* Set it as output high */
ut_assertok(dm_gpio_set_value(&desc_list[0], 1));
- ut_assertok(gpio_get_status(gpio_c, 0, buf, sizeof(buf)));
- ut_asserteq_str("c0: input: 0 [x] a-test.test3-gpios0", buf);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN | GPIOD_IS_OUT_ACTIVE,
+ sandbox_gpio_get_flags(gpio_c, 0));
- /* Set it as output low, should become output low */
+ /* Set it as output low */
ut_assertok(dm_gpio_set_value(&desc_list[0], 0));
- ut_assertok(gpio_get_status(gpio_c, 0, buf, sizeof(buf)));
- ut_asserteq_str("c0: output: 0 [x] a-test.test3-gpios0", buf);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
+ sandbox_gpio_get_flags(gpio_c, 0));
/* GPIO 1 is (GPIO_OUT|GPIO_OPEN_SOURCE) */
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
- sandbox_gpio_get_dir_flags(gpio_c, 1));
+ sandbox_gpio_get_flags(gpio_c, 1));
/* Set it as output high, should become output high */
ut_assertok(dm_gpio_set_value(&desc_list[1], 1));
ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
ut_asserteq_str("c1: output: 1 [x] a-test.test3-gpios1", buf);
- /* Set it as output low, should become an input */
+ /* Set it as output low */
ut_assertok(dm_gpio_set_value(&desc_list[1], 0));
- ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
- ut_asserteq_str("c1: input: 1 [x] a-test.test3-gpios1", buf);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
+ sandbox_gpio_get_flags(gpio_c, 1));
- /* GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN) */
- ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
- sandbox_gpio_get_dir_flags(gpio_c, 6));
+ ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
+ ut_asserteq_str("c1: output: 0 [x] a-test.test3-gpios1", buf);
+
+ /*
+ * GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN). Looking at it
+ * directlt from the driver, we get GPIOD_IS_OUT_ACTIVE also, since it
+ * is active low
+ */
+ ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
+ GPIOD_IS_OUT_ACTIVE,
+ sandbox_gpio_get_flags(gpio_c, 6));
/* Set it as output high, should become output low */
ut_assertok(dm_gpio_set_value(&desc_list[6], 1));
ut_assertok(gpio_get_status(gpio_c, 6, buf, sizeof(buf)));
ut_asserteq_str("c6: output: 0 [x] a-test.test3-gpios6", buf);
- /* Set it as output low, should become an input */
+ /* Set it as output low */
ut_assertok(dm_gpio_set_value(&desc_list[6], 0));
- ut_assertok(gpio_get_status(gpio_c, 6, buf, sizeof(buf)));
- ut_asserteq_str("c6: input: 0 [x] a-test.test3-gpios6", buf);
+ ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
+ GPIOD_IS_OUT_ACTIVE,
+ sandbox_gpio_get_flags(gpio_c, 6));
/* GPIO 7 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE) */
- ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
- sandbox_gpio_get_dir_flags(gpio_c, 7));
+ ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE |
+ GPIOD_IS_OUT_ACTIVE,
+ sandbox_gpio_get_flags(gpio_c, 7));
- /* Set it as output high, should become an input */
+ /* Set it as output high */
ut_assertok(dm_gpio_set_value(&desc_list[7], 1));
- ut_assertok(gpio_get_status(gpio_c, 7, buf, sizeof(buf)));
- ut_asserteq_str("c7: input: 0 [x] a-test.test3-gpios7", buf);
+ ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
+ sandbox_gpio_get_flags(gpio_c, 7));
/* Set it as output low, should become output high */
ut_assertok(dm_gpio_set_value(&desc_list[7], 0));
@@ -363,12 +373,12 @@
ut_assertok(gpio_free_list(dev, desc_list, 3));
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
- sandbox_gpio_get_dir_flags(gpio_a, 1));
+ sandbox_gpio_get_flags(gpio_a, 1));
ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list,
ARRAY_SIZE(desc_list), 0));
/* This was set to output previously but flags resetted to 0 = INPUT */
- ut_asserteq(0, sandbox_gpio_get_dir_flags(gpio_a, 1));
+ ut_asserteq(0, sandbox_gpio_get_flags(gpio_a, 1));
ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 1, NULL));
/* Active low should invert the input value */
@@ -397,22 +407,22 @@
ut_asserteq(6, gpio_request_list_by_name(dev, "test3-gpios", desc_list,
ARRAY_SIZE(desc_list), 0));
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[0], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[0], &flags));
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, flags);
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[1], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[1], &flags));
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE, flags);
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[2], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[2], &flags));
ut_asserteq(GPIOD_IS_OUT, flags);
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[3], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[3], &flags));
ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[4], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[4], &flags));
ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_DOWN, flags);
- ut_assertok(dm_gpio_get_dir_flags(&desc_list[5], &flags));
+ ut_assertok(dm_gpio_get_flags(&desc_list[5], &flags));
ut_asserteq(GPIOD_IS_IN, flags);
ut_assertok(gpio_free_list(dev, desc_list, 6));
@@ -582,3 +592,189 @@
return 0;
}
DM_TEST(dm_test_gpio_devm, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_clrset_flags(struct unit_test_state *uts)
+{
+ struct gpio_desc desc;
+ struct udevice *dev;
+ ulong flags;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+ ut_asserteq_str("a-test", dev->name);
+ ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_OUT));
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_OUT, flags);
+ ut_asserteq(GPIOD_IS_OUT, desc.flags);
+ ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, flags);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, desc.flags);
+ ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+ ut_asserteq(1, dm_gpio_get_value(&desc));
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN));
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_IN, flags & GPIOD_MASK_DIR);
+ ut_asserteq(GPIOD_IS_IN, desc.flags & GPIOD_MASK_DIR);
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_PULL,
+ GPIOD_PULL_UP));
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
+ ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, desc.flags);
+
+ /* Check we cannot set both PULL_UP and PULL_DOWN */
+ ut_asserteq(-EINVAL, dm_gpio_clrset_flags(&desc, 0, GPIOD_PULL_DOWN));
+
+ return 0;
+}
+DM_TEST(dm_test_clrset_flags, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_clrset_flags_invert(struct unit_test_state *uts)
+{
+ struct gpio_desc desc;
+ struct udevice *dev;
+ ulong flags;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+ ut_asserteq_str("a-test", dev->name);
+ ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc,
+ GPIOD_IS_OUT | GPIOD_ACTIVE_LOW));
+
+ /*
+ * From this size we see it as 0 (active low), but the sandbox driver
+ * sees the pin value high
+ */
+ ut_asserteq(0, dm_gpio_get_value(&desc));
+ ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+ ut_assertok(dm_gpio_set_value(&desc, 1));
+ ut_asserteq(1, dm_gpio_get_value(&desc));
+ ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+ /* Do the same with dm_gpio_clrset_flags() */
+ ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
+ ut_asserteq(0, dm_gpio_get_value(&desc));
+ ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
+ ut_asserteq(1, dm_gpio_get_value(&desc));
+ ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
+ flags);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
+ desc.flags);
+
+ ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
+ ut_assertok(dm_gpio_get_flags(&desc, &flags));
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, flags);
+ ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, desc.flags);
+
+ return 0;
+}
+DM_TEST(dm_test_clrset_flags_invert, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int set_gpios(struct unit_test_state *uts, struct gpio_desc *desc,
+ int count, uint value)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ const uint mask = 1 << i;
+
+ ut_assertok(sandbox_gpio_set_value(desc[i].dev, desc[i].offset,
+ value & mask));
+ }
+
+ return 0;
+}
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_gpio_get_values_as_int(struct unit_test_state *uts)
+{
+ const int gpio_count = 3;
+ struct gpio_desc desc[gpio_count];
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+ ut_asserteq_str("a-test", dev->name);
+
+ ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
+ gpio_count, GPIOD_IS_IN));
+ ut_assertok(set_gpios(uts, desc, gpio_count, 0));
+ ut_asserteq(0, dm_gpio_get_values_as_int(desc, gpio_count));
+
+ ut_assertok(set_gpios(uts, desc, gpio_count, 5));
+ ut_asserteq(5, dm_gpio_get_values_as_int(desc, gpio_count));
+
+ ut_assertok(set_gpios(uts, desc, gpio_count, 7));
+ ut_asserteq(7, dm_gpio_get_values_as_int(desc, gpio_count));
+
+ return 0;
+}
+DM_TEST(dm_test_gpio_get_values_as_int,
+ UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts)
+{
+ const int gpio_count = 3;
+ struct gpio_desc desc[gpio_count];
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+ ut_asserteq_str("a-test", dev->name);
+
+ ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
+ gpio_count, GPIOD_IS_IN));
+
+ /*
+ * First test the sandbox GPIO driver works as expected. The external
+ * pull resistor should be stronger than the internal one.
+ */
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
+ GPIOD_IS_IN | GPIOD_EXT_PULL_UP | GPIOD_PULL_UP);
+ ut_asserteq(1, dm_gpio_get_value(desc));
+
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_IS_IN |
+ GPIOD_EXT_PULL_DOWN | GPIOD_PULL_UP);
+ ut_asserteq(0, dm_gpio_get_value(desc));
+
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
+ GPIOD_IS_IN | GPIOD_PULL_UP);
+ ut_asserteq(1, dm_gpio_get_value(desc));
+
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_PULL_DOWN);
+ ut_asserteq(0, dm_gpio_get_value(desc));
+
+ /*
+ * Set up pins: pull-up (1), pull-down (0) and floating (2). This should
+ * result in digits 2 0 1, i.e. 2 * 9 + 1 * 3 = 19
+ */
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_EXT_PULL_UP);
+ sandbox_gpio_set_flags(desc[1].dev, desc[1].offset,
+ GPIOD_EXT_PULL_DOWN);
+ sandbox_gpio_set_flags(desc[2].dev, desc[2].offset, 0);
+ ut_asserteq(19, dm_gpio_get_values_as_int_base3(desc, gpio_count));
+
+ /*
+ * Set up pins: floating (2), pull-up (1) and pull-down (0). This should
+ * result in digits 0 1 2, i.e. 1 * 3 + 2 = 5
+ */
+ sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, 0);
+ sandbox_gpio_set_flags(desc[1].dev, desc[1].offset, GPIOD_EXT_PULL_UP);
+ sandbox_gpio_set_flags(desc[2].dev, desc[2].offset,
+ GPIOD_EXT_PULL_DOWN);
+ ut_asserteq(5, dm_gpio_get_values_as_int_base3(desc, gpio_count));
+
+ return 0;
+}
+DM_TEST(dm_test_gpio_get_values_as_int_base3,
+ UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c
new file mode 100644
index 0000000..9ba2ba2
--- /dev/null
+++ b/test/dm/test-dm.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 Google, Inc
+ */
+
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <asm/state.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+#include <test/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * dm_test_run() - Run driver model tests
+ *
+ * Run all the available driver model tests, or a selection
+ *
+ * @test_name: Name of single test to run (e.g. "dm_test_fdt_pre_reloc" or just
+ * "fdt_pre_reloc"), or NULL to run all
+ * @return 0 if all tests passed, 1 if not
+ */
+static int dm_test_run(const char *test_name)
+{
+ struct unit_test *tests = UNIT_TEST_SUITE_START(dm_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(dm_test);
+ int ret;
+
+ ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name);
+
+ return ret ? CMD_RET_FAILURE : 0;
+}
+
+int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ const char *test_name = NULL;
+
+ if (argc > 1)
+ test_name = argv[1];
+
+ return dm_test_run(test_name);
+}
diff --git a/test/dm/test-driver.c b/test/dm/test-driver.c
index ca7626a..02cb974 100644
--- a/test/dm/test-driver.c
+++ b/test/dm/test-driver.c
@@ -18,7 +18,6 @@
#include <test/ut.h>
int dm_testdrv_op_count[DM_TEST_OP_COUNT];
-static struct unit_test_state *uts = &global_dm_test_state;
static int testdrv_ping(struct udevice *dev, int pingval, int *pingret)
{
@@ -37,6 +36,8 @@
static int test_bind(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
+
/* Private data should not be allocated */
ut_assert(!dev_get_priv(dev));
@@ -46,6 +47,7 @@
static int test_probe(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
struct dm_test_priv *priv = dev_get_priv(dev);
/* Private data should be allocated */
@@ -58,6 +60,8 @@
static int test_remove(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
+
/* Private data should still be allocated */
ut_assert(dev_get_priv(dev));
@@ -67,6 +71,8 @@
static int test_unbind(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
+
/* Private data should not be allocated */
ut_assert(!dev_get_priv(dev));
@@ -116,10 +122,10 @@
static int test_manual_probe(struct udevice *dev)
{
- struct dm_test_state *dms = uts->priv;
+ struct unit_test_state *uts = test_get_state();
dm_testdrv_op_count[DM_TEST_OP_PROBE]++;
- if (!dms->force_fail_alloc)
+ if (!uts->force_fail_alloc)
dev_set_priv(dev, calloc(1, sizeof(struct dm_test_priv)));
if (!dev_get_priv(dev))
return -ENOMEM;
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
deleted file mode 100644
index 560f8d6..0000000
--- a/test/dm/test-main.c
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013 Google, Inc
- */
-
-#include <common.h>
-#include <command.h>
-#include <console.h>
-#include <dm.h>
-#include <errno.h>
-#include <log.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-#include <asm/state.h>
-#include <dm/test.h>
-#include <dm/root.h>
-#include <dm/uclass-internal.h>
-#include <test/test.h>
-#include <test/test.h>
-#include <test/ut.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct unit_test_state global_dm_test_state;
-static struct dm_test_state _global_priv_dm_test_state;
-
-/* Get ready for testing */
-static int dm_test_init(struct unit_test_state *uts, bool of_live)
-{
- struct dm_test_state *dms = uts->priv;
-
- memset(dms, '\0', sizeof(*dms));
- gd->dm_root = NULL;
- if (!CONFIG_IS_ENABLED(OF_PLATDATA))
- memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
- state_reset_for_test(state_get_current());
-
- /* Determine whether to make the live tree available */
- gd_set_of_root(of_live ? uts->of_root : NULL);
- ut_assertok(dm_init(of_live));
- dms->root = dm_root();
-
- return 0;
-}
-
-/* Ensure all the test devices are probed */
-static int do_autoprobe(struct unit_test_state *uts)
-{
- struct udevice *dev;
- int ret;
-
- /* Scanning the uclass is enough to probe all the devices */
- for (ret = uclass_first_device(UCLASS_TEST, &dev);
- dev;
- ret = uclass_next_device(&dev))
- ;
-
- return ret;
-}
-
-static int dm_test_destroy(struct unit_test_state *uts)
-{
- int id;
-
- for (id = 0; id < UCLASS_COUNT; id++) {
- struct uclass *uc;
-
- /*
- * If the uclass doesn't exist we don't want to create it. So
- * check that here before we call uclass_find_device().
- */
- uc = uclass_find(id);
- if (!uc)
- continue;
- ut_assertok(uclass_destroy(uc));
- }
-
- return 0;
-}
-
-static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
- bool of_live)
-{
- struct sandbox_state *state = state_get_current();
- const char *fname = strrchr(test->file, '/') + 1;
-
- printf("Test: %s: %s%s\n", test->name, fname,
- !of_live ? " (flat tree)" : "");
- ut_assertok(dm_test_init(uts, of_live));
-
- uts->start = mallinfo();
- if (test->flags & UT_TESTF_SCAN_PDATA)
- ut_assertok(dm_scan_plat(false));
- if (test->flags & UT_TESTF_PROBE_TEST)
- ut_assertok(do_autoprobe(uts));
- if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
- (test->flags & UT_TESTF_SCAN_FDT))
- ut_assertok(dm_extended_scan(false));
-
- /*
- * Silence the console and rely on console recording to get
- * our output.
- */
- console_record_reset_enable();
- if (!state->show_test_output)
- gd->flags |= GD_FLG_SILENT;
- test->func(uts);
- gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
- state_set_skip_delays(false);
-
- ut_assertok(dm_test_destroy(uts));
-
- return 0;
-}
-
-/**
- * dm_test_run_on_flattree() - Check if we should run a test with flat DT
- *
- * This skips long/slow tests where there is not much value in running a flat
- * DT test in addition to a live DT test.
- *
- * @return true to run the given test on the flat device tree
- */
-static bool dm_test_run_on_flattree(struct unit_test *test)
-{
- const char *fname = strrchr(test->file, '/') + 1;
-
- return !strstr(fname, "video") || strstr(test->name, "video_base");
-}
-
-static bool test_matches(const char *test_name, const char *find_name)
-{
- if (!find_name)
- return true;
-
- if (!strcmp(test_name, find_name))
- return true;
-
- /* All tests have this prefix */
- if (!strncmp(test_name, "dm_test_", 8))
- test_name += 8;
-
- if (!strcmp(test_name, find_name))
- return true;
-
- return false;
-}
-
-int dm_test_main(const char *test_name)
-{
- struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
- const int n_ents = ll_entry_count(struct unit_test, dm_test);
- struct unit_test_state *uts = &global_dm_test_state;
- struct unit_test *test;
- int found;
-
- uts->priv = &_global_priv_dm_test_state;
- uts->fail_count = 0;
-
- if (!CONFIG_IS_ENABLED(OF_PLATDATA)) {
- /*
- * If we have no device tree, or it only has a root node, then
- * these * tests clearly aren't going to work...
- */
- if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
- puts("Please run with test device tree:\n"
- " ./u-boot -d arch/sandbox/dts/test.dtb\n");
- ut_assert(gd->fdt_blob);
- }
- }
-
- if (!test_name)
- printf("Running %d driver model tests\n", n_ents);
- else
-
- found = 0;
- uts->of_root = gd_of_root();
- for (test = tests; test < tests + n_ents; test++) {
- const char *name = test->name;
- int runs;
-
- if (!test_matches(name, test_name))
- continue;
-
- /* Run with the live tree if possible */
- runs = 0;
- if (CONFIG_IS_ENABLED(OF_LIVE)) {
- if (!(test->flags & UT_TESTF_FLAT_TREE)) {
- ut_assertok(dm_do_test(uts, test, true));
- runs++;
- }
- }
-
- /*
- * Run with the flat tree if we couldn't run it with live tree,
- * or it is a core test.
- */
- if (!(test->flags & UT_TESTF_LIVE_TREE) &&
- (!runs || dm_test_run_on_flattree(test))) {
- ut_assertok(dm_do_test(uts, test, false));
- runs++;
- }
- found++;
- }
-
- if (test_name && !found)
- printf("Test '%s' not found\n", test_name);
- else
- printf("Failures: %d\n", uts->fail_count);
-
- /* Put everything back to normal so that sandbox works as expected */
- gd_set_of_root(uts->of_root);
- gd->dm_root = NULL;
- ut_assertok(dm_init(CONFIG_IS_ENABLED(OF_LIVE)));
- dm_scan_plat(false);
- if (!CONFIG_IS_ENABLED(OF_PLATDATA))
- dm_scan_fdt(false);
-
- return uts->fail_count ? CMD_RET_FAILURE : 0;
-}
-
-int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- const char *test_name = NULL;
-
- if (argc > 1)
- test_name = argv[1];
-
- return dm_test_main(test_name);
-}
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index f1b7aaa..0677017 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -17,8 +17,6 @@
#include <test/test.h>
#include <test/ut.h>
-static struct unit_test_state *uts = &global_dm_test_state;
-
int test_ping(struct udevice *dev, int pingval, int *pingret)
{
const struct test_ops *ops = device_get_ops(dev);
@@ -31,6 +29,7 @@
static int test_post_bind(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
struct dm_test_perdev_uc_pdata *uc_pdata;
dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++;
@@ -56,6 +55,7 @@
static int test_pre_probe(struct udevice *dev)
{
struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
+ struct unit_test_state *uts = test_get_state();
dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++;
ut_assert(priv);
@@ -66,18 +66,18 @@
static int test_post_probe(struct udevice *dev)
{
+ struct unit_test_state *uts = test_get_state();
struct udevice *prev = list_entry(dev->uclass_node.prev,
struct udevice, uclass_node);
struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
struct uclass *uc = dev->uclass;
- struct dm_test_state *dms = uts->priv;
dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]++;
ut_assert(priv);
ut_assert(device_active(dev));
priv->base_add = 0;
- if (dms->skip_post_probe)
+ if (uts->skip_post_probe)
return 0;
if (&prev->uclass_node != &uc->dev_head) {
struct dm_test_uclass_perdev_priv *prev_uc_priv
@@ -101,6 +101,8 @@
static int test_init(struct uclass *uc)
{
+ struct unit_test_state *uts = test_get_state();
+
dm_testdrv_op_count[DM_TEST_OP_INIT]++;
ut_assert(uclass_get_priv(uc));
diff --git a/test/env/cmd_ut_env.c b/test/env/cmd_ut_env.c
index a440b1b..d65a321 100644
--- a/test/env/cmd_ut_env.c
+++ b/test/env/cmd_ut_env.c
@@ -12,8 +12,8 @@
int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, env_test);
- const int n_ents = ll_entry_count(struct unit_test, env_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(env_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(env_test);
return cmd_ut_category("environment", "env_test_",
tests, n_ents, argc, argv);
diff --git a/test/image/Makefile b/test/image/Makefile
new file mode 100644
index 0000000..c4039df
--- /dev/null
+++ b/test/image/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2021 Google LLC
+
+obj-$(CONFIG_SPL_BUILD) += spl_load.o
diff --git a/test/image/spl_load.c b/test/image/spl_load.c
new file mode 100644
index 0000000..851603d
--- /dev/null
+++ b/test/image/spl_load.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <image.h>
+#include <mapmem.h>
+#include <os.h>
+#include <spl.h>
+#include <test/ut.h>
+
+/* Declare a new SPL test */
+#define SPL_TEST(_name, _flags) UNIT_TEST(_name, _flags, spl_test)
+
+/* Context used for this test */
+struct text_ctx {
+ int fd;
+};
+
+static ulong read_fit_image(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ struct text_ctx *text_ctx = load->priv;
+ off_t offset, ret;
+ ssize_t res;
+
+ offset = sector * load->bl_len;
+ ret = os_lseek(text_ctx->fd, offset, OS_SEEK_SET);
+ if (ret != offset) {
+ printf("Failed to seek to %zx, got %zx (errno=%d)\n", offset,
+ ret, errno);
+ return 0;
+ }
+
+ res = os_read(text_ctx->fd, buf, count * load->bl_len);
+ if (res == -1) {
+ printf("Failed to read %lx bytes, got %ld (errno=%d)\n",
+ count * load->bl_len, res, errno);
+ return 0;
+ }
+
+ return count;
+}
+
+int board_fit_config_name_match(const char *name)
+{
+ return 0;
+}
+
+struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
+{
+ return map_sysmem(0x100000, 0);
+}
+
+static int spl_test_load(struct unit_test_state *uts)
+{
+ struct spl_image_info image;
+ struct image_header *header;
+ struct text_ctx text_ctx;
+ struct spl_load_info load;
+ char fname[256];
+ int ret;
+ int fd;
+
+ memset(&load, '\0', sizeof(load));
+ load.bl_len = 512;
+ load.read = read_fit_image;
+
+ ret = os_find_u_boot(fname, sizeof(fname), true);
+ if (ret) {
+ printf("(%s not found, error %d)\n", fname, ret);
+ return ret;
+ }
+ load.filename = fname;
+
+ header = spl_get_load_buffer(-sizeof(*header), sizeof(*header));
+
+ fd = os_open(fname, OS_O_RDONLY);
+ ut_assert(fd >= 0);
+ ut_asserteq(512, os_read(fd, header, 512));
+ text_ctx.fd = fd;
+
+ load.priv = &text_ctx;
+
+ ut_assertok(spl_load_simple_fit(&image, &load, 0, header));
+
+ return 0;
+}
+SPL_TEST(spl_test_load, 0);
diff --git a/test/lib/cmd_ut_lib.c b/test/lib/cmd_ut_lib.c
index f5c7bf3..f1ac015 100644
--- a/test/lib/cmd_ut_lib.c
+++ b/test/lib/cmd_ut_lib.c
@@ -13,8 +13,8 @@
int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, lib_test);
- const int n_ents = ll_entry_count(struct unit_test, lib_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(lib_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(lib_test);
return cmd_ut_category("lib", "lib_test_", tests, n_ents, argc, argv);
}
diff --git a/test/log/Makefile b/test/log/Makefile
index 3f09deb..a3dedac 100644
--- a/test/log/Makefile
+++ b/test/log/Makefile
@@ -7,7 +7,7 @@
ifdef CONFIG_UT_LOG
-obj-y += test-main.o
+obj-y += log_ut.o
ifdef CONFIG_SANDBOX
obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o
diff --git a/test/log/cont_test.c b/test/log/cont_test.c
index 16379a7..de7b7f0 100644
--- a/test/log/cont_test.c
+++ b/test/log/cont_test.c
@@ -15,8 +15,6 @@
DECLARE_GLOBAL_DATA_PTR;
-#define BUFFSIZE 64
-
static int log_test_cont(struct unit_test_state *uts)
{
int log_fmt;
@@ -29,12 +27,13 @@
gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
gd->default_log_level = LOGL_INFO;
console_record_reset_enable();
- log(LOGC_ARCH, LOGL_ERR, "ea%d ", 1);
+ log(LOGC_ARCH, LOGL_ERR, "ea%d\n", 1);
log(LOGC_CONT, LOGL_CONT, "cc%d\n", 2);
gd->default_log_level = log_level;
gd->log_fmt = log_fmt;
gd->flags &= ~GD_FLG_RECORD;
- ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1 ERR.arch, cc2"));
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1"));
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, cc2"));
ut_assertok(ut_check_console_end(uts));
/* Write a third message which is not a continuation */
@@ -48,6 +47,18 @@
ut_assertok(ut_check_console_line(uts, "INFO.efi, ie3"));
ut_assertok(ut_check_console_end(uts));
+ /* Write two messages without a newline between them */
+ gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
+ gd->default_log_level = LOGL_INFO;
+ console_record_reset_enable();
+ log(LOGC_ARCH, LOGL_ERR, "ea%d ", 1);
+ log(LOGC_CONT, LOGL_CONT, "cc%d\n", 2);
+ gd->default_log_level = log_level;
+ gd->log_fmt = log_fmt;
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1 cc2"));
+ ut_assertok(ut_check_console_end(uts));
+
return 0;
}
LOG_TEST(log_test_cont);
diff --git a/test/log/test-main.c b/test/log/log_ut.c
similarity index 75%
rename from test/log/test-main.c
rename to test/log/log_ut.c
index c534add..5aa3a18 100644
--- a/test/log/test-main.c
+++ b/test/log/log_ut.c
@@ -13,8 +13,8 @@
int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, log_test);
- const int n_ents = ll_entry_count(struct unit_test, log_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(log_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(log_test);
return cmd_ut_category("log", "log_test_",
tests, n_ents, argc, argv);
diff --git a/test/optee/cmd_ut_optee.c b/test/optee/cmd_ut_optee.c
index 9fa4c91..c3887ab 100644
--- a/test/optee/cmd_ut_optee.c
+++ b/test/optee/cmd_ut_optee.c
@@ -94,9 +94,8 @@
int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- optee_test);
- const int n_ents = ll_entry_count(struct unit_test, optee_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(optee_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(optee_test);
struct unit_test_state *uts;
void *fdt_optee = &__dtb_test_optee_optee_begin;
void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
diff --git a/test/overlay/cmd_ut_overlay.c b/test/overlay/cmd_ut_overlay.c
index c001fb1..56a3df1 100644
--- a/test/overlay/cmd_ut_overlay.c
+++ b/test/overlay/cmd_ut_overlay.c
@@ -213,9 +213,8 @@
int do_ut_overlay(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- overlay_test);
- const int n_ents = ll_entry_count(struct unit_test, overlay_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(overlay_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(overlay_test);
struct unit_test_state *uts;
void *fdt_base = &__dtb_test_fdt_base_begin;
void *fdt_overlay = &__dtb_test_fdt_overlay_begin;
diff --git a/test/py/conftest.py b/test/py/conftest.py
index 9bfd926..1b909cd 100644
--- a/test/py/conftest.py
+++ b/test/py/conftest.py
@@ -226,7 +226,7 @@
import u_boot_console_exec_attach
console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig)
-re_ut_test_list = re.compile(r'_u_boot_list_2_(.*)_test_2_\1_test_(.*)\s*$')
+re_ut_test_list = re.compile(r'_u_boot_list_2_ut_(.*)_test_2_\1_test_(.*)\s*$')
def generate_ut_subtest(metafunc, fixture_name, sym_path):
"""Provide parametrization for a ut_subtest fixture.
diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py
index f889120..140dcb9 100644
--- a/test/py/tests/test_log.py
+++ b/test/py/tests/test_log.py
@@ -45,5 +45,4 @@
cons = u_boot_console
cons.restart_uboot()
output = cons.get_spawn_output().replace('\r', '')
- assert 'sandbox: starting...' in output
assert (not 'debug: main' in output)
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 92d09b7..e9cce4d 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -4,7 +4,7 @@
import pytest
import u_boot_utils as util
-@pytest.mark.boardspec('sandbox')
+@pytest.mark.boardspec('sandbox_spl')
@pytest.mark.buildconfigspec('spl_of_platdata')
def test_spl_devicetree(u_boot_console):
"""Test content of spl device-tree"""
diff --git a/test/py/tests/test_scp03.py b/test/py/tests/test_scp03.py
new file mode 100644
index 0000000..1f68925
--- /dev/null
+++ b/test/py/tests/test_scp03.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2021 Foundries.io Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# SCP03 command test
+
+"""
+This tests SCP03 command in U-boot.
+
+For additional details check doc/usage/scp03.rst
+"""
+
+import pytest
+import u_boot_utils as util
+
+@pytest.mark.buildconfigspec('cmd_scp03')
+def test_scp03(u_boot_console):
+ """Enable and provision keys with SCP03
+ """
+
+ success_str1 = "SCP03 is enabled"
+ success_str2 = "SCP03 is provisioned"
+
+ response = u_boot_console.run_command('scp03 enable')
+ assert success_str1 in response
+ response = u_boot_console.run_command('scp03 provision')
+ assert success_str2 in response
diff --git a/test/str_ut.c b/test/str_ut.c
index cd50455..359d7d4 100644
--- a/test/str_ut.c
+++ b/test/str_ut.c
@@ -107,9 +107,8 @@
int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test,
- str_test);
- const int n_ents = ll_entry_count(struct unit_test, str_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(str_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(str_test);
return cmd_ut_category("str", "str_", tests, n_ents, argc, argv);
}
diff --git a/test/test-main.c b/test/test-main.c
new file mode 100644
index 0000000..e1b49e0
--- /dev/null
+++ b/test/test-main.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <console.h>
+#include <dm.h>
+#include <asm/state.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* This is valid when a test is running, NULL otherwise */
+static struct unit_test_state *cur_test_state;
+
+struct unit_test_state *test_get_state(void)
+{
+ return cur_test_state;
+}
+
+void test_set_state(struct unit_test_state *uts)
+{
+ cur_test_state = uts;
+}
+
+/**
+ * dm_test_pre_run() - Get ready to run a driver model test
+ *
+ * This clears out the driver model data structures. For sandbox it resets the
+ * state structure
+ *
+ * @uts: Test state
+ */
+static int dm_test_pre_run(struct unit_test_state *uts)
+{
+ bool of_live = uts->of_live;
+
+ uts->root = NULL;
+ uts->testdev = NULL;
+ uts->force_fail_alloc = false;
+ uts->skip_post_probe = false;
+ gd->dm_root = NULL;
+ if (!CONFIG_IS_ENABLED(OF_PLATDATA))
+ memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count));
+ state_reset_for_test(state_get_current());
+
+ /* Determine whether to make the live tree available */
+ gd_set_of_root(of_live ? uts->of_root : NULL);
+ ut_assertok(dm_init(of_live));
+ uts->root = dm_root();
+
+ return 0;
+}
+
+static int dm_test_post_run(struct unit_test_state *uts)
+{
+ int id;
+
+ for (id = 0; id < UCLASS_COUNT; id++) {
+ struct uclass *uc;
+
+ /*
+ * If the uclass doesn't exist we don't want to create it. So
+ * check that here before we call uclass_find_device().
+ */
+ uc = uclass_find(id);
+ if (!uc)
+ continue;
+ ut_assertok(uclass_destroy(uc));
+ }
+
+ return 0;
+}
+
+/* Ensure all the test devices are probed */
+static int do_autoprobe(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* Scanning the uclass is enough to probe all the devices */
+ for (ret = uclass_first_device(UCLASS_TEST, &dev);
+ dev;
+ ret = uclass_next_device(&dev))
+ ;
+
+ return ret;
+}
+
+/*
+ * ut_test_run_on_flattree() - Check if we should run a test with flat DT
+ *
+ * This skips long/slow tests where there is not much value in running a flat
+ * DT test in addition to a live DT test.
+ *
+ * @return true to run the given test on the flat device tree
+ */
+static bool ut_test_run_on_flattree(struct unit_test *test)
+{
+ const char *fname = strrchr(test->file, '/') + 1;
+
+ if (!(test->flags & UT_TESTF_DM))
+ return false;
+
+ return !strstr(fname, "video") || strstr(test->name, "video_base");
+}
+
+/**
+ * test_matches() - Check if a test should be run
+ *
+ * This checks if the a test should be run. In the normal case of running all
+ * tests, @select_name is NULL.
+ *
+ * @prefix: String prefix for the tests. Any tests that have this prefix will be
+ * printed without the prefix, so that it is easier to see the unique part
+ * of the test name. If NULL, any suite name (xxx_test) is considered to be
+ * a prefix.
+ * @test_name: Name of current test
+ * @select_name: Name of test to run (or NULL for all)
+ * @return true to run this test, false to skip it
+ */
+static bool test_matches(const char *prefix, const char *test_name,
+ const char *select_name)
+{
+ if (!select_name)
+ return true;
+
+ if (!strcmp(test_name, select_name))
+ return true;
+
+ if (!prefix) {
+ const char *p = strstr(test_name, "_test_");
+
+ /* convert xxx_test_yyy to yyy, i.e. remove the suite name */
+ if (p)
+ test_name = p + 6;
+ } else {
+ /* All tests have this prefix */
+ if (!strncmp(test_name, prefix, strlen(prefix)))
+ test_name += strlen(prefix);
+ }
+
+ if (!strcmp(test_name, select_name))
+ return true;
+
+ return false;
+}
+
+/**
+ * ut_list_has_dm_tests() - Check if a list of tests has driver model ones
+ *
+ * @tests: List of tests to run
+ * @count: Number of tests to ru
+ * @return true if any of the tests have the UT_TESTF_DM flag
+ */
+static bool ut_list_has_dm_tests(struct unit_test *tests, int count)
+{
+ struct unit_test *test;
+
+ for (test = tests; test < tests + count; test++) {
+ if (test->flags & UT_TESTF_DM)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * dm_test_restore() Put things back to normal so sandbox works as expected
+ *
+ * @of_root: Value to set for of_root
+ * @return 0 if OK, -ve on error
+ */
+static int dm_test_restore(struct device_node *of_root)
+{
+ int ret;
+
+ gd_set_of_root(of_root);
+ gd->dm_root = NULL;
+ ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE));
+ if (ret)
+ return ret;
+ dm_scan_plat(false);
+ if (!CONFIG_IS_ENABLED(OF_PLATDATA))
+ dm_scan_fdt(false);
+
+ return 0;
+}
+
+/**
+ * test_pre_run() - Handle any preparation needed to run a test
+ *
+ * @uts: Test state
+ * @test: Test to prepare for
+ * @return 0 if OK, -EAGAIN to skip this test since some required feature is not
+ * available, other -ve on error (meaning that testing cannot likely
+ * continue)
+ */
+static int test_pre_run(struct unit_test_state *uts, struct unit_test *test)
+{
+ if (test->flags & UT_TESTF_DM)
+ ut_assertok(dm_test_pre_run(uts));
+
+ ut_set_skip_delays(uts, false);
+
+ uts->start = mallinfo();
+
+ if (test->flags & UT_TESTF_SCAN_PDATA)
+ ut_assertok(dm_scan_plat(false));
+
+ if (test->flags & UT_TESTF_PROBE_TEST)
+ ut_assertok(do_autoprobe(uts));
+
+ if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
+ (test->flags & UT_TESTF_SCAN_FDT))
+ ut_assertok(dm_extended_scan(false));
+
+ if (test->flags & UT_TESTF_CONSOLE_REC) {
+ int ret = console_record_reset_enable();
+
+ if (ret) {
+ printf("Skipping: Console recording disabled\n");
+ return -EAGAIN;
+ }
+ }
+ ut_silence_console(uts);
+
+ return 0;
+}
+
+/**
+ * test_post_run() - Handle cleaning up after a test
+ *
+ * @uts: Test state
+ * @test: Test to clean up after
+ * @return 0 if OK, -ve on error (meaning that testing cannot likely continue)
+ */
+static int test_post_run(struct unit_test_state *uts, struct unit_test *test)
+{
+ ut_unsilence_console(uts);
+ if (test->flags & UT_TESTF_DM)
+ ut_assertok(dm_test_post_run(uts));
+
+ return 0;
+}
+
+/**
+ * ut_run_test() - Run a single test
+ *
+ * This runs the test, handling any preparation and clean-up needed. It prints
+ * the name of each test before running it.
+ *
+ * @uts: Test state to update. The caller should ensure that this is zeroed for
+ * the first call to this function. On exit, @uts->fail_count is
+ * incremented by the number of failures (0, one hopes)
+ * @test_name: Test to run
+ * @name: Name of test, possibly skipping a prefix that should not be displayed
+ * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
+ * any failed
+ */
+static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
+ const char *test_name)
+{
+ const char *fname = strrchr(test->file, '/') + 1;
+ const char *note = "";
+ int ret;
+
+ if ((test->flags & UT_TESTF_DM) && !uts->of_live)
+ note = " (flat tree)";
+ printf("Test: %s: %s%s\n", test_name, fname, note);
+
+ /* Allow access to test state from drivers */
+ test_set_state(uts);
+
+ ret = test_pre_run(uts, test);
+ if (ret == -EAGAIN)
+ return -EAGAIN;
+ if (ret)
+ return ret;
+
+ test->func(uts);
+
+ ret = test_post_run(uts, test);
+ if (ret)
+ return ret;
+
+ test_set_state( NULL);
+
+ return 0;
+}
+
+/**
+ * ut_run_test_live_flat() - Run a test with both live and flat tree
+ *
+ * This calls ut_run_test() with livetree enabled, which is the standard setup
+ * for runnig tests. Then, for driver model test, it calls it again with
+ * livetree disabled. This allows checking of flattree being used when OF_LIVE
+ * is enabled, as is the case in U-Boot proper before relocation, as well as in
+ * SPL.
+ *
+ * @uts: Test state to update. The caller should ensure that this is zeroed for
+ * the first call to this function. On exit, @uts->fail_count is
+ * incremented by the number of failures (0, one hopes)
+ * @test: Test to run
+ * @name: Name of test, possibly skipping a prefix that should not be displayed
+ * @return 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
+ * any failed
+ */
+static int ut_run_test_live_flat(struct unit_test_state *uts,
+ struct unit_test *test, const char *name)
+{
+ int runs;
+
+ /* Run with the live tree if possible */
+ runs = 0;
+ if (CONFIG_IS_ENABLED(OF_LIVE)) {
+ if (!(test->flags & UT_TESTF_FLAT_TREE)) {
+ uts->of_live = true;
+ ut_assertok(ut_run_test(uts, test, test->name));
+ runs++;
+ }
+ }
+
+ /*
+ * Run with the flat tree if we couldn't run it with live tree,
+ * or it is a core test.
+ */
+ if (!(test->flags & UT_TESTF_LIVE_TREE) &&
+ (!runs || ut_test_run_on_flattree(test))) {
+ uts->of_live = false;
+ ut_assertok(ut_run_test(uts, test, test->name));
+ runs++;
+ }
+
+ return 0;
+}
+
+/**
+ * ut_run_tests() - Run a set of tests
+ *
+ * This runs the tests, handling any preparation and clean-up needed. It prints
+ * the name of each test before running it.
+ *
+ * @uts: Test state to update. The caller should ensure that this is zeroed for
+ * the first call to this function. On exit, @uts->fail_count is
+ * incremented by the number of failures (0, one hopes)
+ * @prefix: String prefix for the tests. Any tests that have this prefix will be
+ * printed without the prefix, so that it is easier to see the unique part
+ * of the test name. If NULL, no prefix processing is done
+ * @tests: List of tests to run
+ * @count: Number of tests to run
+ * @select_name: Name of a single test to run (from the list provided). If NULL
+ * then all tests are run
+ * @return 0 if all tests passed, -ENOENT if test @select_name was not found,
+ * -EBADF if any failed
+ */
+static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
+ struct unit_test *tests, int count,
+ const char *select_name)
+{
+ struct unit_test *test;
+ int found = 0;
+
+ for (test = tests; test < tests + count; test++) {
+ const char *test_name = test->name;
+ int ret;
+
+ if (!test_matches(prefix, test_name, select_name))
+ continue;
+ ret = ut_run_test_live_flat(uts, test, select_name);
+ found++;
+ if (ret == -EAGAIN)
+ continue;
+ if (ret)
+ return ret;
+ }
+ if (select_name && !found)
+ return -ENOENT;
+
+ return uts->fail_count ? -EBADF : 0;
+}
+
+int ut_run_list(const char *category, const char *prefix,
+ struct unit_test *tests, int count, const char *select_name)
+{
+ struct unit_test_state uts = { .fail_count = 0 };
+ bool has_dm_tests = false;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
+ ut_list_has_dm_tests(tests, count)) {
+ has_dm_tests = true;
+ /*
+ * If we have no device tree, or it only has a root node, then
+ * these * tests clearly aren't going to work...
+ */
+ if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
+ puts("Please run with test device tree:\n"
+ " ./u-boot -d arch/sandbox/dts/test.dtb\n");
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ if (!select_name)
+ printf("Running %d %s tests\n", count, category);
+
+ uts.of_root = gd_of_root();
+ ret = ut_run_tests(&uts, prefix, tests, count, select_name);
+
+ if (ret == -ENOENT)
+ printf("Test '%s' not found\n", select_name);
+ else
+ printf("Failures: %d\n", uts.fail_count);
+
+ /* Best efforts only...ignore errors */
+ if (has_dm_tests)
+ dm_test_restore(uts.of_root);
+
+ return ret;
+}
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 6f6aea5..617eed8 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -729,8 +729,8 @@
int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
- struct unit_test *tests = ll_entry_start(struct unit_test, unicode_test);
- const int n_ents = ll_entry_count(struct unit_test, unicode_test);
+ struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test);
+ const int n_ents = UNIT_TEST_SUITE_COUNT(unicode_test);
return cmd_ut_category("Unicode", "unicode_test_",
tests, n_ents, argc, argv);
diff --git a/test/ut.c b/test/ut.c
index 7328338..ea0af15 100644
--- a/test/ut.c
+++ b/test/ut.c
@@ -133,3 +133,10 @@
{
gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
}
+
+void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays)
+{
+#ifdef CONFIG_SANDBOX
+ state_set_skip_delays(skip_delays);
+#endif
+}
diff --git a/tools/binman/README b/tools/binman/README
index a00c902..45f0a0c 100644
--- a/tools/binman/README
+++ b/tools/binman/README
@@ -637,7 +637,8 @@
Binman normally operates silently unless there is an error, in which case it
just displays the error. The -D/--debug option can be used to create a full
-backtrace when errors occur.
+backtrace when errors occur. You can use BINMAN_DEBUG=1 when building to select
+this.
Internally binman logs some output while it is running. This can be displayed
by increasing the -v/--verbosity from the default of 1:
@@ -649,6 +650,7 @@
4: detailed information about each operation
5: debug (all output)
+You can use BINMAN_VERBOSE=5 (for example) when building to select this.
Hashing Entries
---------------