[U-Boot] [PATCH 00/21] Various patches for verified boot support

This is (for now) the last series to enable Chromium OS verified boot in U-Boot. It includes:
- Sandbox valgrind spport - Minor TPM enhancements and fixes - Resurection of inttypes.h - Args checking for log functions - Sandbox fix for time jitter - Various other minir things
Simon Glass (21): sandbox: Fix up the debug message for the image filename sandbox: Check the filename in jump_to_image_no_args() sandbox: physmem: Use mapping to support sandbox sandbox: net: Correct name copy in eth_raw_bus_post_bind() sandbox: sysreset: Update to support power-on reset sandbox: Zero the ram buffer on startup sandbox: Use 'extras' to specify 'head' files sandbox: Allow running from valgrind tpm: Remove use of build-time TPM versions tpm: Export tpm_clear_and_reenable() tpm: Add non-volatile index attributes needed for v2 tpm: Fix a logging warning in unpack_byte_string() cros: Correct a printf() string and comment cros_ec: Adjust to use v1 vboot context only input: i8042: Use remove() instead of exported functions video: backlight: Fix log message in enable_sequence() time: Update mdelay() to delay in one large chunk log: Check printf() arguments Add UINT32_MAX and UINT64_MAX Add inttypes.h RFC: Makefile: Build U-Boot as a library
Makefile | 9 +- arch/sandbox/Makefile | 4 +- arch/sandbox/config.mk | 7 +- arch/sandbox/cpu/Makefile | 5 +- arch/sandbox/cpu/os.c | 39 ++-- arch/sandbox/cpu/spl.c | 8 +- arch/sandbox/cpu/start.c | 7 + arch/sandbox/include/asm/state.h | 1 + drivers/input/i8042.c | 35 ++-- drivers/misc/cros_ec.c | 4 +- drivers/misc/cros_ec_sandbox.c | 10 +- drivers/net/sandbox-raw-bus.c | 2 +- drivers/sysreset/sysreset_sandbox.c | 8 +- drivers/video/pwm_backlight.c | 2 +- include/i8042.h | 15 -- include/inttypes.h | 271 ++++++++++++++++++++++++++++ include/linux/delay.h | 3 +- include/linux/kernel.h | 4 + include/log.h | 3 +- include/tpm-common.h | 19 ++ include/tpm-v2.h | 33 ++++ lib/physmem.c | 4 +- lib/tpm-common.c | 9 +- lib/tpm-v1.c | 22 +-- scripts/Makefile.spl | 17 +- test/dm/sysreset.c | 4 +- 26 files changed, 462 insertions(+), 83 deletions(-) create mode 100644 include/inttypes.h

This currently prints out the wrong filename. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index aa926943427..58d9a46263e 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -668,7 +668,7 @@ static int os_jump_to_file(const char *fname) os_free(argv); if (err) { perror("Unable to run image"); - printf("Image filename '%s'\n", mem_fname); + printf("Image filename '%s'\n", fname); return err; }

This currently prints out the wrong filename. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-dm/master, thanks!

If the filename is NULL this function currently crashes. Update it to fail gracefully.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/spl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 5005ed2f54a..2ca4cd6e35e 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -69,7 +69,11 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { const char *fname = spl_image->arg;
- os_fd_restore(); - os_spl_to_uboot(fname); + if (fname) { + os_fd_restore(); + os_spl_to_uboot(fname); + } else { + printf("No filename provided for U-Boot\n"); + } hang(); }

If the filename is NULL this function currently crashes. Update it to fail gracefully.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/spl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
Applied to u-boot-dm/master, thanks!

Replace the raw cast with a map_sysmem() call so this code works with sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/physmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/physmem.c b/lib/physmem.c index f21ac243edc..84b191dae3e 100644 --- a/lib/physmem.c +++ b/lib/physmem.c @@ -9,14 +9,16 @@ */
#include <common.h> +#include <mapmem.h> #include <physmem.h> #include <linux/compiler.h>
phys_addr_t __weak arch_phys_memset(phys_addr_t s, int c, phys_size_t n) { - void *s_ptr = (void *)(uintptr_t)s; + void *s_ptr = map_sysmem(s, n);
assert(((phys_addr_t)(uintptr_t)s) == s); assert(((phys_addr_t)(uintptr_t)(s + n)) == s + n); + return (phys_addr_t)(uintptr_t)memset(s_ptr, c, n); }

Replace the raw cast with a map_sysmem() call so this code works with sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/physmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Applied to u-boot-dm/master, thanks!

We cannot be sure that the interface name takes up the full length of the space available to it. Use strcpy() instead of memcpy() in this case. This corrects a valgrind warning.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/net/sandbox-raw-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sandbox-raw-bus.c b/drivers/net/sandbox-raw-bus.c index 76d65afe6c8..0086f25fc1f 100644 --- a/drivers/net/sandbox-raw-bus.c +++ b/drivers/net/sandbox-raw-bus.c @@ -42,7 +42,7 @@ static int eth_raw_bus_post_bind(struct udevice *dev) device_probe(child); priv = dev_get_priv(child); if (priv) { - memcpy(priv->host_ifname, i->if_name, IFNAMSIZ); + strcpy(priv->host_ifname, i->if_name); priv->host_ifindex = i->if_index; priv->local = local; }

We cannot be sure that the interface name takes up the full length of the space available to it. Use strcpy() instead of memcpy() in this case. This corrects a valgrind warning.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/net/sandbox-raw-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-dm/master, thanks!

If U-Boot is started from SPL or TPL, then those earlier phases deal with the reset cause. On real hardware this cause may be lost once it is read. Emulate that behaviour in sandbox by reporting a warm reset when a previous phase has run since start-up.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/sysreset/sysreset_sandbox.c | 8 +++++++- test/dm/sysreset.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c index 7f6d4186e16..38e2a7e241d 100644 --- a/drivers/sysreset/sysreset_sandbox.c +++ b/drivers/sysreset/sysreset_sandbox.c @@ -84,7 +84,13 @@ int sandbox_sysreset_get_status(struct udevice *dev, char *buf, int size)
int sandbox_sysreset_get_last(struct udevice *dev) { - return SYSRESET_COLD; + struct sandbox_state *state = state_get_current(); + + /* + * The first phase is a power reset, after that we assume we don't + * know. + */ + return state->jumped_fname ? SYSRESET_WARM : SYSRESET_POWER; }
static struct sysreset_ops sandbox_sysreset_ops = { diff --git a/test/dm/sysreset.c b/test/dm/sysreset.c index e1b7bf5277d..5b2358ef674 100644 --- a/test/dm/sysreset.c +++ b/test/dm/sysreset.c @@ -102,10 +102,10 @@ static int dm_test_sysreset_get_last(struct unit_test_state *uts)
/* Device 2 is the cold sysreset device */ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 2, &dev)); - ut_asserteq(SYSRESET_COLD, sysreset_get_last(dev)); + ut_asserteq(SYSRESET_POWER, sysreset_get_last(dev));
/* This is device 0, the non-DT one */ - ut_asserteq(SYSRESET_COLD, sysreset_get_last_walk()); + ut_asserteq(SYSRESET_POWER, sysreset_get_last_walk());
return 0; }

If U-Boot is started from SPL or TPL, then those earlier phases deal with the reset cause. On real hardware this cause may be lost once it is read. Emulate that behaviour in sandbox by reporting a warm reset when a previous phase has run since start-up.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/sysreset/sysreset_sandbox.c | 8 +++++++- test/dm/sysreset.c | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-)
Applied to u-boot-dm/master, thanks!

At present the RAM buffer is not inited unless it is read from a file, likely produced by an earlier phase of U-Boot. This causes valgrind warnings whenever the RAM buffer is used. Correct this by initing it if needed.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/start.c | 7 +++++++ arch/sandbox/include/asm/state.h | 1 + 2 files changed, 8 insertions(+)
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index b1566a81435..2f5e6e95182 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -180,6 +180,7 @@ static int sandbox_cmdline_cb_memory(struct sandbox_state *state, printf("Failed to read RAM buffer '%s': %d\n", arg, err); return err; } + state->ram_buf_read = true;
return 0; } @@ -301,6 +302,12 @@ int board_run_command(const char *cmdline)
static void setup_ram_buf(struct sandbox_state *state) { + /* Zero the RAM buffer if we didn't read it, to keep valgrind happy */ + if (!state->ram_buf_read) { + memset(state->ram_buf, '\0', state->ram_size); + printf("clear %p %x\n", state->ram_buf, state->ram_size); + } + gd->arch.ram_buf = state->ram_buf; gd->ram_size = state->ram_size; } diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 8fabe70a86d..5a144851025 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -90,6 +90,7 @@ struct sandbox_state { bool show_test_output; /* Don't suppress stdout in tests */ int default_log_level; /* Default log level for sandbox */ bool show_of_platdata; /* Show of-platdata in SPL */ + bool ram_buf_read; /* true if we read the RAM buffer */
/* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]

At present the RAM buffer is not inited unless it is read from a file, likely produced by an earlier phase of U-Boot. This causes valgrind warnings whenever the RAM buffer is used. Correct this by initing it if needed.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/start.c | 7 +++++++ arch/sandbox/include/asm/state.h | 1 + 2 files changed, 8 insertions(+)
Applied to u-boot-dm/master, thanks!

At present sandbox has a start.o in the 'start' target but also includes it in the normal target list. This is not how this is normally handled. It is needed because sandbox does not include the u-boot-init variable in its link rule.
Update the rule and move start.o from the normal target list to the 'extras' list.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/Makefile | 4 ++-- arch/sandbox/config.mk | 3 ++- arch/sandbox/cpu/Makefile | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile index 261079441cf..f6cf859f249 100644 --- a/arch/sandbox/Makefile +++ b/arch/sandbox/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+
-head-y := arch/sandbox/cpu/start.o - +head-y := arch/sandbox/cpu/start.o arch/sandbox/cpu/os.o +head-$(CONFIG_SANDBOX_SDL) += arch/sandbox/cpu/sdl.o libs-y += arch/sandbox/cpu/ libs-y += arch/sandbox/lib/ diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 95f9e3ff63f..7226b7be428 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -17,11 +17,12 @@ PLATFORM_CPPFLAGS += $(shell sdl-config --cflags) endif endif
-cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds \ +cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \ -Wl,--start-group $(u-boot-main) -Wl,--end-group \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections) diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile index 8fe681844d9..bac96447d51 100644 --- a/arch/sandbox/cpu/Makefile +++ b/arch/sandbox/cpu/Makefile @@ -5,10 +5,11 @@ # (C) Copyright 2000-2003 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-y := cpu.o os.o start.o state.o +obj-y := cpu.o state.o +extra-y := start.o os.o +extra-$(CONFIG_SANDBOX_SDL) += sdl.o obj-$(CONFIG_SPL_BUILD) += spl.o obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.o -obj-$(CONFIG_SANDBOX_SDL) += sdl.o
# os.c is build in the system environment, so needs standard includes # CFLAGS_REMOVE_os.o cannot be used to drop header include path

At present sandbox has a start.o in the 'start' target but also includes it in the normal target list. This is not how this is normally handled. It is needed because sandbox does not include the u-boot-init variable in its link rule.
Update the rule and move start.o from the normal target list to the 'extras' list.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/Makefile | 4 ++-- arch/sandbox/config.mk | 3 ++- arch/sandbox/cpu/Makefile | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-)
Applied to u-boot-dm/master, thanks!

It is useful to run sandbox from valgrind to find memory errors, etc. At present this works OK until U-Boot jumps into the next phase (e.g. from SPL to U-Boot). Update os_jump_to_file() to use valgrind for each subsequent phase also.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/os.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 58d9a46263e..fd0c688edfb 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -572,9 +572,11 @@ static int make_exec(char *fname, const void *data, int size) * @argvp: Returns newly allocated args list * @add_args: Arguments to add, each a string * @count: Number of arguments in @add_args + * @use_valgrind: Run the program with valgrind * @return 0 if OK, -ENOMEM if out of memory */ -static int add_args(char ***argvp, char *add_args[], int count) +static int add_args(char ***argvp, char *add_args[], int count, + bool use_valgrind) { char **argv, **ap; int argc; @@ -582,12 +584,15 @@ static int add_args(char ***argvp, char *add_args[], int count) for (argc = 0; (*argvp)[argc]; argc++) ;
- argv = os_malloc((argc + count + 1) * sizeof(char *)); + argv = os_malloc((argc + count + 2) * sizeof(char *)); if (!argv) { printf("Out of memory for %d argv\n", count); return -ENOMEM; } - for (ap = *argvp, argc = 0; *ap; ap++) { + argc = 0; + if (use_valgrind) + argv[argc++] = "valgrind"; + for (ap = *argvp; *ap; ap++) { char *arg = *ap;
/* Drop args that we don't want to propagate */ @@ -624,15 +629,18 @@ static int add_args(char ***argvp, char *add_args[], int count) static int os_jump_to_file(const char *fname) { struct sandbox_state *state = state_get_current(); + bool use_valgrind; char mem_fname[30]; int fd, err; - char *extra_args[5]; + char *extra_args[6]; char **argv = state->argv; int argc; #ifdef DEBUG int i; #endif
+ use_valgrind = strlen(argv[0]) >= 8 && + !strcmp(argv[0] + strlen(argv[0]) - 8, "valgrind"); strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); fd = mkstemp(mem_fname); if (fd < 0) @@ -644,17 +652,22 @@ static int os_jump_to_file(const char *fname)
os_fd_restore();
- extra_args[0] = "-j"; - extra_args[1] = (char *)fname; - extra_args[2] = "-m"; - extra_args[3] = mem_fname; - argc = 4; + argc = 0; + extra_args[argc++] = "-j"; + extra_args[argc++] = (char *)fname; + extra_args[argc++] = "-m"; + extra_args[argc++] = mem_fname; if (state->ram_buf_rm) extra_args[argc++] = "--rm_memory"; - err = add_args(&argv, extra_args, argc); + err = add_args(&argv, extra_args, argc, use_valgrind); if (err) return err; - argv[0] = (char *)fname; + if (use_valgrind) { + argv[0] = "/usr/bin/valgrind"; + argv[1] = (char *)fname; + } else { + argv[0] = (char *)fname; + }
#ifdef DEBUG for (i = 0; argv[i]; i++) @@ -664,7 +677,7 @@ static int os_jump_to_file(const char *fname) if (state_uninit()) os_exit(2);
- err = execv(fname, argv); + err = execv(argv[0], argv); os_free(argv); if (err) { perror("Unable to run image");

On 24.11.18 05:29, Simon Glass wrote:
It is useful to run sandbox from valgrind to find memory errors, etc. At present this works OK until U-Boot jumps into the next phase (e.g. from SPL to U-Boot). Update os_jump_to_file() to use valgrind for each subsequent phase also.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/os.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 58d9a46263e..fd0c688edfb 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -572,9 +572,11 @@ static int make_exec(char *fname, const void *data, int size)
- @argvp: Returns newly allocated args list
- @add_args: Arguments to add, each a string
- @count: Number of arguments in @add_args
*/
- @use_valgrind: Run the program with valgrind
- @return 0 if OK, -ENOMEM if out of memory
-static int add_args(char ***argvp, char *add_args[], int count) +static int add_args(char ***argvp, char *add_args[], int count,
bool use_valgrind)
{ char **argv, **ap; int argc; @@ -582,12 +584,15 @@ static int add_args(char ***argvp, char *add_args[], int count) for (argc = 0; (*argvp)[argc]; argc++) ;
- argv = os_malloc((argc + count + 1) * sizeof(char *));
- argv = os_malloc((argc + count + 2) * sizeof(char *)); if (!argv) { printf("Out of memory for %d argv\n", count); return -ENOMEM; }
- for (ap = *argvp, argc = 0; *ap; ap++) {
argc = 0;
if (use_valgrind)
argv[argc++] = "valgrind";
for (ap = *argvp; *ap; ap++) { char *arg = *ap;
/* Drop args that we don't want to propagate */
@@ -624,15 +629,18 @@ static int add_args(char ***argvp, char *add_args[], int count) static int os_jump_to_file(const char *fname) { struct sandbox_state *state = state_get_current();
- bool use_valgrind; char mem_fname[30]; int fd, err;
- char *extra_args[5];
- char *extra_args[6]; char **argv = state->argv; int argc;
#ifdef DEBUG int i; #endif
- use_valgrind = strlen(argv[0]) >= 8 &&
strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); fd = mkstemp(mem_fname); if (fd < 0)!strcmp(argv[0] + strlen(argv[0]) - 8, "valgrind");
@@ -644,17 +652,22 @@ static int os_jump_to_file(const char *fname)
os_fd_restore();
- extra_args[0] = "-j";
- extra_args[1] = (char *)fname;
- extra_args[2] = "-m";
- extra_args[3] = mem_fname;
- argc = 4;
- argc = 0;
- extra_args[argc++] = "-j";
- extra_args[argc++] = (char *)fname;
- extra_args[argc++] = "-m";
- extra_args[argc++] = mem_fname; if (state->ram_buf_rm) extra_args[argc++] = "--rm_memory";
- err = add_args(&argv, extra_args, argc);
- err = add_args(&argv, extra_args, argc, use_valgrind); if (err) return err;
- argv[0] = (char *)fname;
- if (use_valgrind) {
argv[0] = "/usr/bin/valgrind";
Is there a better way to exec into another program but preserve its valgrindness than to explicitly call valgrind - and worse - hard code the path to valgrind and its invocation type?
I would've expected valgrind has some way to make it inherit into child processes?
(I've added Christian to CC - he knows his way around valgrind quite a bit too)
Alex

On 24.11.2018 22:31, Alexander Graf wrote:
On 24.11.18 05:29, Simon Glass wrote:
It is useful to run sandbox from valgrind to find memory errors, etc. At present this works OK until U-Boot jumps into the next phase (e.g. from SPL to U-Boot). Update os_jump_to_file() to use valgrind for each subsequent phase also.
Signed-off-by: Simon Glass sjg@chromium.org
[...]
Is there a better way to exec into another program but preserve its valgrindness than to explicitly call valgrind - and worse - hard code the path to valgrind and its invocation type?
I would've expected valgrind has some way to make it inherit into child processes?
(I've added Christian to CC - he knows his way around valgrind quite a bit too)
valgrind follows all forks/clones, but it detaches execve. You can ask valgrind to also follow execve with the --trace-children=yes option. Is that what you want?
Christain

There is only one place in the code which assumes at build-time that we are using either a v1 or a v2 TPM. Fix this up and add a new function to return the version of a TPM.
Supported TPM versions (v1 and v2) can be enabled independently and it is possible to use both versions at once. This is useful for sandbox when running tests.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-common.h | 11 +++++++++++ lib/tpm-common.c | 7 +++++++ lib/tpm-v1.c | 22 +++++++++++----------- 3 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/include/tpm-common.h b/include/tpm-common.h index 3d88b44db7a..91a1484b3d6 100644 --- a/include/tpm-common.h +++ b/include/tpm-common.h @@ -274,4 +274,15 @@ static inline cmd_tbl_t *get_tpm2_commands(unsigned int *size) } #endif
+/** + * tpm_get_version() - Find the version of a TPM + * + * This checks the uclass data for a TPM device and returns the version number + * it supports. + * + * @dev: TPM device + * @return version number (TPM_V1 or TPMV2) + */ +enum tpm_version tpm_get_version(struct udevice *dev); + #endif /* __TPM_COMMON_H */ diff --git a/lib/tpm-common.c b/lib/tpm-common.c index 6afe59b1fec..2bf0b41e26f 100644 --- a/lib/tpm-common.c +++ b/lib/tpm-common.c @@ -12,6 +12,13 @@ #include <tpm-common.h> #include "tpm-utils.h"
+enum tpm_version tpm_get_version(struct udevice *dev) +{ + struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); + + return priv->version; +} + int pack_byte_string(u8 *str, size_t size, const char *format, ...) { va_list args; diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c index f29e62ff7b2..3e89f845441 100644 --- a/lib/tpm-v1.c +++ b/lib/tpm-v1.c @@ -79,19 +79,19 @@ u32 tpm_clear_and_reenable(struct udevice *dev) return ret; }
-#if IS_ENABLED(CONFIG_TPM_V1) - ret = tpm_physical_enable(dev); - if (ret != TPM_SUCCESS) { - log_err("TPM: Can't set enabled state\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 = tpm_physical_set_deactivated(dev, 0); - if (ret != TPM_SUCCESS) { - log_err("TPM: Can't set deactivated 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; + } } -#endif
return TPM_SUCCESS; }

There is only one place in the code which assumes at build-time that we are using either a v1 or a v2 TPM. Fix this up and add a new function to return the version of a TPM.
Supported TPM versions (v1 and v2) can be enabled independently and it is possible to use both versions at once. This is useful for sandbox when running tests.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-common.h | 11 +++++++++++ lib/tpm-common.c | 7 +++++++ lib/tpm-v1.c | 22 +++++++++++----------- 3 files changed, 29 insertions(+), 11 deletions(-)
Applied to u-boot-dm/master, thanks!

This function is intended to be exported but is not. Add it to the header file.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-common.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/tpm-common.h b/include/tpm-common.h index 91a1484b3d6..f9c2ca20539 100644 --- a/include/tpm-common.h +++ b/include/tpm-common.h @@ -209,6 +209,14 @@ int tpm_open(struct udevice *dev); */ int tpm_close(struct udevice *dev);
+/** + * tpm_clear_and_reenable() - Force clear the TPM and reenable it + * + * @dev: TPM device + * @return 0 on success, -ve on failure + */ +u32 tpm_clear_and_reenable(struct udevice *dev); + /** * tpm_get_desc() - Get a text description of the TPM *

This function is intended to be exported but is not. Add it to the header file.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-common.h | 8 ++++++++ 1 file changed, 8 insertions(+)
Applied to u-boot-dm/master, thanks!

Version-2 TPMs support attributes for nvdata. Add definitions to the header file so that clients can use it.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-v2.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/tpm-v2.h b/include/tpm-v2.h index 2f2e66de195..ae00803f6d9 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -128,6 +128,39 @@ enum tpm2_algorithms { TPM2_ALG_NULL = 0x10, };
+/* NV index attributes */ +enum tpm_index_attrs { + TPMA_NV_PPWRITE = 1UL << 0, + TPMA_NV_OWNERWRITE = 1UL << 1, + TPMA_NV_AUTHWRITE = 1UL << 2, + TPMA_NV_POLICYWRITE = 1UL << 3, + TPMA_NV_COUNTER = 1UL << 4, + TPMA_NV_BITS = 1UL << 5, + TPMA_NV_EXTEND = 1UL << 6, + TPMA_NV_POLICY_DELETE = 1UL << 10, + TPMA_NV_WRITELOCKED = 1UL << 11, + TPMA_NV_WRITEALL = 1UL << 12, + TPMA_NV_WRITEDEFINE = 1UL << 13, + TPMA_NV_WRITE_STCLEAR = 1UL << 14, + TPMA_NV_GLOBALLOCK = 1UL << 15, + TPMA_NV_PPREAD = 1UL << 16, + TPMA_NV_OWNERREAD = 1UL << 17, + TPMA_NV_AUTHREAD = 1UL << 18, + TPMA_NV_POLICYREAD = 1UL << 19, + TPMA_NV_NO_DA = 1UL << 25, + TPMA_NV_ORDERLY = 1UL << 26, + TPMA_NV_CLEAR_STCLEAR = 1UL << 27, + TPMA_NV_READLOCKED = 1UL << 28, + TPMA_NV_WRITTEN = 1UL << 29, + TPMA_NV_PLATFORMCREATE = 1UL << 30, + TPMA_NV_READ_STCLEAR = 1UL << 31, + + TPMA_NV_MASK_READ = TPMA_NV_PPREAD | TPMA_NV_OWNERREAD | + TPMA_NV_AUTHREAD | TPMA_NV_POLICYREAD, + TPMA_NV_MASK_WRITE = TPMA_NV_PPWRITE | TPMA_NV_OWNERWRITE | + TPMA_NV_AUTHWRITE | TPMA_NV_POLICYWRITE, +}; + /** * Issue a TPM2_Startup command. *

Version-2 TPMs support attributes for nvdata. Add definitions to the header file so that clients can use it.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/tpm-v2.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
Applied to u-boot-dm/master, thanks!

Fix the printf() string to avoid a warning.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/tpm-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/tpm-common.c b/lib/tpm-common.c index 2bf0b41e26f..86b4f413c2e 100644 --- a/lib/tpm-common.c +++ b/lib/tpm-common.c @@ -119,7 +119,7 @@ int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
if (offset + length > size) { va_end(args); - log_err("Failed to read: size=%d, offset=%x, len=%x\n", + log_err("Failed to read: size=%zd, offset=%zx, len=%zx\n", size, offset, length); return -1; }

Fix the printf() string to avoid a warning.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/tpm-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-dm/master, thanks!

Correct a warning that occurs on sandbox. Also fix the comment style in cros_ec_set_lid_shutdown_mask().
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/cros_ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 2dcdb3d8d61..565de040fe9 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -420,7 +420,7 @@ int cros_ec_read_id(struct udevice *dev, char *id, int maxlen) ret = ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, (uint8_t **)&r, sizeof(*r)); if (ret != sizeof(*r)) { - log_err("Got rc %d, expected %d\n", ret, sizeof(*r)); + log_err("Got rc %d, expected %u\n", ret, (uint)sizeof(*r)); return -1; }
@@ -1466,7 +1466,7 @@ int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable) if (ret < 0) return ret;
- // Set lid close event state in the EC SMI event mask + /* Set lid close event state in the EC SMI event mask */ if (enable) mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED); else

Correct a warning that occurs on sandbox. Also fix the comment style in cros_ec_set_lid_shutdown_mask().
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/cros_ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Applied to u-boot-dm/master, thanks!

At present there are no users of the 64-byte v2 context. The v1 context is only 16 bytes long and currently an error is raised if too much data is returned from the EC.
Update the code to limit the size to 16 bytes.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/cros_ec_sandbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index 429f1a9b269..4fcb2d96f51 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -313,13 +313,15 @@ static int process_cmd(struct ec_state *ec,
switch (req->op) { case EC_VBNV_CONTEXT_OP_READ: + /* TODO(sjg@chromium.org): Support full-size context */ memcpy(resp->block, ec->vbnv_context, - sizeof(resp->block)); - len = sizeof(*resp); + EC_VBNV_BLOCK_SIZE); + len = 16; break; case EC_VBNV_CONTEXT_OP_WRITE: - memcpy(ec->vbnv_context, resp->block, - sizeof(resp->block)); + /* TODO(sjg@chromium.org): Support full-size context */ + memcpy(ec->vbnv_context, req->block, + EC_VBNV_BLOCK_SIZE); len = 0; break; default:

At present there are no users of the 64-byte v2 context. The v1 context is only 16 bytes long and currently an error is raised if too much data is returned from the EC.
Update the code to limit the size to 16 bytes.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/cros_ec_sandbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
Applied to u-boot-dm/master, thanks!

We should not have exported functions in a driver. The i8042_disable() function is used to disable the keyboard. Provide a remove() method instead, which is the standard way of disabling a device.
We could potentially add a method to flush input but that does not seem necessary.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/input/i8042.c | 35 ++++++++++++++++++++--------------- include/i8042.h | 15 --------------- 2 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 5678f8e3cfb..9a5dc46207c 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -167,19 +167,8 @@ static int kbd_controller_present(void) return in8(I8042_STS_REG) != 0xff; }
-/* - * Implement a weak default function for boards that optionally - * need to skip the i8042 initialization. - * - * TODO(sjg@chromium.org): Use device tree for this? - */ -int __weak board_i8042_skip(void) -{ - /* As default, don't skip */ - return 0; -} - -void i8042_flush(void) +/** Flush all buffer from keyboard controller to host*/ +static void i8042_flush(void) { int timeout;
@@ -202,7 +191,13 @@ void i8042_flush(void) } }
-int i8042_disable(void) +/** + * Disables the keyboard so that key strokes no longer generate scancodes to + * the host. + * + * @return 0 if ok, -1 if keyboard input was found while disabling + */ +static int i8042_disable(void) { if (kbd_input_empty() == 0) return -1; @@ -266,7 +261,7 @@ static int i8042_start(struct udevice *dev) char *penv; int ret;
- if (!kbd_controller_present() || board_i8042_skip()) { + if (!kbd_controller_present()) { debug("i8042 keyboard controller is not present\n"); return -ENOENT; } @@ -294,6 +289,15 @@ static int i8042_start(struct udevice *dev) return 0; }
+static int i8042_kbd_remove(struct udevice *dev) +{ + if (i8042_disable()) + log_debug("i8042_disable() failed. fine, continue.\n"); + i8042_flush(); + + return 0; +} + /** * Set up the i8042 keyboard. This is called by the stdio device handler * @@ -348,6 +352,7 @@ U_BOOT_DRIVER(i8042_kbd) = { .id = UCLASS_KEYBOARD, .of_match = i8042_kbd_ids, .probe = i8042_kbd_probe, + .remove = i8042_kbd_remove, .ops = &i8042_kbd_ops, .priv_auto_alloc_size = sizeof(struct i8042_kbd_priv), }; diff --git a/include/i8042.h b/include/i8042.h index 2b9e5c4d371..8d69fa13bc2 100644 --- a/include/i8042.h +++ b/include/i8042.h @@ -72,19 +72,4 @@ #define BRK 0x0100 /* make break flag for keyboard */ #define ALT 0x0200 /* right alt */
-/* exports */ - -/** - * Flush all buffer from keyboard controller to host. - */ -void i8042_flush(void); - -/** - * Disables the keyboard so that key strokes no longer generate scancodes to - * the host. - * - * @return 0 if ok, -1 if keyboard input was found while disabling - */ -int i8042_disable(void); - #endif /* _I8042_H_ */

We should not have exported functions in a driver. The i8042_disable() function is used to disable the keyboard. Provide a remove() method instead, which is the standard way of disabling a device.
We could potentially add a method to flush input but that does not seem necessary.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/input/i8042.c | 35 ++++++++++++++++++++--------------- include/i8042.h | 15 --------------- 2 files changed, 20 insertions(+), 30 deletions(-)
Applied to u-boot-dm/master, thanks!

This has an extra argument. Remove it.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/video/pwm_backlight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index c13a9077090..bd733f5f1ca 100644 --- a/drivers/video/pwm_backlight.c +++ b/drivers/video/pwm_backlight.c @@ -78,7 +78,7 @@ static int enable_sequence(struct udevice *dev, int seq) ret = regulator_set_enable(priv->reg, true); if (ret) { log_debug("Cannot enable regulator for PWM '%s'\n", - __func__, dev->name); + dev->name); return log_ret(ret); } mdelay(120);

On Fri, 23 Nov 2018 21:29:39 -0700 Simon Glass sjg@chromium.org wrote:
This has an extra argument. Remove it.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Anatolij Gustschin agust@denx.de

On Fri, 23 Nov 2018 21:29:39 -0700 Simon Glass sjg@chromium.org wrote:
This has an extra argument. Remove it.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Anatolij Gustschin agust@denx.de
Applied to u-boot-dm/master, thanks!

The current function delays in one millisecond at a time. This does not work well on sandbox since it results in lots of calls to usleep(1000) in a tight loop. This makes the sleep duration quite variable since each call results in a sleep of *at least* 1000us, but possibly more. Depending on how busy the machine is, the sleep time can change quite a bit.
We cannot fix this in general, but we can reduce the effect by doing a single sleep. The multiplication works fine with an unsigned long argument up until a sleep time of about 4m milliseconds. This is over an hour and we can be sure that delays of that length are not useful.
Update the mdelay() function to call udelay() only once with the calculated delay value.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/delay.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/linux/delay.h b/include/linux/delay.h index 193603451a7..71a38e15fbd 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -10,8 +10,7 @@ void udelay(unsigned long usec);
static inline void mdelay(unsigned long msec) { - while (msec--) - udelay(1000); + udelay(1000 * msec); }
static inline void ndelay(unsigned long nsec)

The current function delays in one millisecond at a time. This does not work well on sandbox since it results in lots of calls to usleep(1000) in a tight loop. This makes the sleep duration quite variable since each call results in a sleep of *at least* 1000us, but possibly more. Depending on how busy the machine is, the sleep time can change quite a bit.
We cannot fix this in general, but we can reduce the effect by doing a single sleep. The multiplication works fine with an unsigned long argument up until a sleep time of about 4m milliseconds. This is over an hour and we can be sure that delays of that length are not useful.
Update the mdelay() function to call udelay() only once with the calculated delay value.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/delay.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Applied to u-boot-dm/master, thanks!

At present logging does not check printf() arguments. Now that all users have been corrected, enable this to prevent further problems.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/log.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/log.h b/include/log.h index 4f14937b7a2..310b2cf7ce5 100644 --- a/include/log.h +++ b/include/log.h @@ -73,7 +73,8 @@ static inline int log_uc_cat(enum uclass_id id) * @return 0 if log record was emitted, -ve on error */ int _log(enum log_category_t cat, enum log_level_t level, const char *file, - int line, const char *func, const char *fmt, ...); + int line, const char *func, const char *fmt, ...) + __attribute__ ((format (__printf__, 6, 7)));
/* Define this at the top of a file to add a prefix to debug messages */ #ifndef pr_fmt

At present logging does not check printf() arguments. Now that all users have been corrected, enable this to prevent further problems.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/log.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Applied to u-boot-dm/master, thanks!

These constants are defined by stdint.h but not by kernel.h, which is its stand-in in U-Boot. Add the definitions so that libraries which expect stdint.h constants can work.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/kernel.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 04a09eb4f64..bd88483b9f6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -33,6 +33,10 @@ #define S64_MAX ((s64)(U64_MAX>>1)) #define S64_MIN ((s64)(-S64_MAX - 1))
+/* Aliases defined by stdint.h */ +#define UINT32_MAX U32_MAX +#define UINT64_MAX U64_MAX + #define STACK_MAGIC 0xdeadbeef
#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))

These constants are defined by stdint.h but not by kernel.h, which is its stand-in in U-Boot. Add the definitions so that libraries which expect stdint.h constants can work.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/linux/kernel.h | 4 ++++ 1 file changed, 4 insertions(+)
Applied to u-boot-dm/master, thanks!

Even if U-Boot does not use this, some libraries do. Add back this header file so that the build does not fall back to using the host version, which may include stdint.h and break the build due to conflicts with uint64_t, etc.
This partially reverts commit dee37fc99d94 ("Remove <inttypes.h> includes and PRI* usages in printf() entirely")
The only change from the file that was in U-Boot until recently is that it now comes twice as close to passing checkpatch. The remaining warnings pertain to the typedefs, which checkpatch does not like.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/inttypes.h | 271 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 include/inttypes.h
diff --git a/include/inttypes.h b/include/inttypes.h new file mode 100644 index 00000000000..dcb6785228c --- /dev/null +++ b/include/inttypes.h @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 1997-2001, 2004, 2007 Free Software Foundation, Inc. + * + * This file is taken from the GNU C Library v2.15, with the unimplemented + * functions removed and a few style fixes. + */ + +/* + * ISO C99: 7.8 Format conversion of integer types <inttypes.h> + */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H 1 + +#include <linux/compiler.h> + +/* Get a definition for wchar_t. But we must not define wchar_t itself. */ +#ifndef ____gwchar_t_defined +# ifdef __cplusplus +# define __gwchar_t wchar_t +# elif defined __WCHAR_TYPE__ +typedef __WCHAR_TYPE__ __gwchar_t; +# else +# define __need_wchar_t +# include <linux/stddef.h> +typedef wchar_t __gwchar_t; +# endif +# define ____gwchar_t_defined 1 +#endif + +/* + * The ISO C99 standard specifies that these macros must only be defined if + * explicitly requested + */ +#if !defined __cplusplus || defined __STDC_FORMAT_MACROS + +/* linux/types.h always uses long long for 64-bit and long for uintptr_t */ +# define __PRI64_PREFIX "ll" +# define __PRIPTR_PREFIX "l" + +/* Macros for printing format specifiers. */ + +/* Decimal notation. */ +# define PRId8 "d" +# define PRId16 "d" +# define PRId32 "d" +# define PRId64 __PRI64_PREFIX "d" + +# define PRIdLEAST8 "d" +# define PRIdLEAST16 "d" +# define PRIdLEAST32 "d" +# define PRIdLEAST64 __PRI64_PREFIX "d" + +# define PRIdFAST8 "d" +# define PRIdFAST16 __PRIPTR_PREFIX "d" +# define PRIdFAST32 __PRIPTR_PREFIX "d" +# define PRIdFAST64 __PRI64_PREFIX "d" + +# define PRIi8 "i" +# define PRIi16 "i" +# define PRIi32 "i" +# define PRIi64 __PRI64_PREFIX "i" + +# define PRIiLEAST8 "i" +# define PRIiLEAST16 "i" +# define PRIiLEAST32 "i" +# define PRIiLEAST64 __PRI64_PREFIX "i" + +# define PRIiFAST8 "i" +# define PRIiFAST16 __PRIPTR_PREFIX "i" +# define PRIiFAST32 __PRIPTR_PREFIX "i" +# define PRIiFAST64 __PRI64_PREFIX "i" + +/* Octal notation. */ +# define PRIo8 "o" +# define PRIo16 "o" +# define PRIo32 "o" +# define PRIo64 __PRI64_PREFIX "o" + +# define PRIoLEAST8 "o" +# define PRIoLEAST16 "o" +# define PRIoLEAST32 "o" +# define PRIoLEAST64 __PRI64_PREFIX "o" + +# define PRIoFAST8 "o" +# define PRIoFAST16 __PRIPTR_PREFIX "o" +# define PRIoFAST32 __PRIPTR_PREFIX "o" +# define PRIoFAST64 __PRI64_PREFIX "o" + +/* Unsigned integers. */ +# define PRIu8 "u" +# define PRIu16 "u" +# define PRIu32 "u" +# define PRIu64 __PRI64_PREFIX "u" + +# define PRIuLEAST8 "u" +# define PRIuLEAST16 "u" +# define PRIuLEAST32 "u" +# define PRIuLEAST64 __PRI64_PREFIX "u" + +# define PRIuFAST8 "u" +# define PRIuFAST16 __PRIPTR_PREFIX "u" +# define PRIuFAST32 __PRIPTR_PREFIX "u" +# define PRIuFAST64 __PRI64_PREFIX "u" + +/* lowercase hexadecimal notation. */ +# define PRIx8 "x" +# define PRIx16 "x" +# define PRIx32 "x" +# define PRIx64 __PRI64_PREFIX "x" + +# define PRIxLEAST8 "x" +# define PRIxLEAST16 "x" +# define PRIxLEAST32 "x" +# define PRIxLEAST64 __PRI64_PREFIX "x" + +# define PRIxFAST8 "x" +# define PRIxFAST16 __PRIPTR_PREFIX "x" +# define PRIxFAST32 __PRIPTR_PREFIX "x" +# define PRIxFAST64 __PRI64_PREFIX "x" + +/* UPPERCASE hexadecimal notation. */ +# define PRIX8 "X" +# define PRIX16 "X" +# define PRIX32 "X" +# define PRIX64 __PRI64_PREFIX "X" + +# define PRIXLEAST8 "X" +# define PRIXLEAST16 "X" +# define PRIXLEAST32 "X" +# define PRIXLEAST64 __PRI64_PREFIX "X" + +# define PRIXFAST8 "X" +# define PRIXFAST16 __PRIPTR_PREFIX "X" +# define PRIXFAST32 __PRIPTR_PREFIX "X" +# define PRIXFAST64 __PRI64_PREFIX "X" + +/* Macros for printing `intmax_t' and `uintmax_t'. */ +# define PRIdMAX __PRI64_PREFIX "d" +# define PRIiMAX __PRI64_PREFIX "i" +# define PRIoMAX __PRI64_PREFIX "o" +# define PRIuMAX __PRI64_PREFIX "u" +# define PRIxMAX __PRI64_PREFIX "x" +# define PRIXMAX __PRI64_PREFIX "X" + +/* Macros for printing `intptr_t' and `uintptr_t'. */ +# define PRIdPTR __PRIPTR_PREFIX "d" +# define PRIiPTR __PRIPTR_PREFIX "i" +# define PRIoPTR __PRIPTR_PREFIX "o" +# define PRIuPTR __PRIPTR_PREFIX "u" +# define PRIxPTR __PRIPTR_PREFIX "x" +# define PRIXPTR __PRIPTR_PREFIX "X" + +/* Macros for scanning format specifiers. */ + +/* Signed decimal notation. */ +# define SCNd8 "hhd" +# define SCNd16 "hd" +# define SCNd32 "d" +# define SCNd64 __PRI64_PREFIX "d" + +# define SCNdLEAST8 "hhd" +# define SCNdLEAST16 "hd" +# define SCNdLEAST32 "d" +# define SCNdLEAST64 __PRI64_PREFIX "d" + +# define SCNdFAST8 "hhd" +# define SCNdFAST16 __PRIPTR_PREFIX "d" +# define SCNdFAST32 __PRIPTR_PREFIX "d" +# define SCNdFAST64 __PRI64_PREFIX "d" + +/* Signed decimal notation. */ +# define SCNi8 "hhi" +# define SCNi16 "hi" +# define SCNi32 "i" +# define SCNi64 __PRI64_PREFIX "i" + +# define SCNiLEAST8 "hhi" +# define SCNiLEAST16 "hi" +# define SCNiLEAST32 "i" +# define SCNiLEAST64 __PRI64_PREFIX "i" + +# define SCNiFAST8 "hhi" +# define SCNiFAST16 __PRIPTR_PREFIX "i" +# define SCNiFAST32 __PRIPTR_PREFIX "i" +# define SCNiFAST64 __PRI64_PREFIX "i" + +/* Unsigned decimal notation. */ +# define SCNu8 "hhu" +# define SCNu16 "hu" +# define SCNu32 "u" +# define SCNu64 __PRI64_PREFIX "u" + +# define SCNuLEAST8 "hhu" +# define SCNuLEAST16 "hu" +# define SCNuLEAST32 "u" +# define SCNuLEAST64 __PRI64_PREFIX "u" + +# define SCNuFAST8 "hhu" +# define SCNuFAST16 __PRIPTR_PREFIX "u" +# define SCNuFAST32 __PRIPTR_PREFIX "u" +# define SCNuFAST64 __PRI64_PREFIX "u" + +/* Octal notation. */ +# define SCNo8 "hho" +# define SCNo16 "ho" +# define SCNo32 "o" +# define SCNo64 __PRI64_PREFIX "o" + +# define SCNoLEAST8 "hho" +# define SCNoLEAST16 "ho" +# define SCNoLEAST32 "o" +# define SCNoLEAST64 __PRI64_PREFIX "o" + +# define SCNoFAST8 "hho" +# define SCNoFAST16 __PRIPTR_PREFIX "o" +# define SCNoFAST32 __PRIPTR_PREFIX "o" +# define SCNoFAST64 __PRI64_PREFIX "o" + +/* Hexadecimal notation. */ +# define SCNx8 "hhx" +# define SCNx16 "hx" +# define SCNx32 "x" +# define SCNx64 __PRI64_PREFIX "x" + +# define SCNxLEAST8 "hhx" +# define SCNxLEAST16 "hx" +# define SCNxLEAST32 "x" +# define SCNxLEAST64 __PRI64_PREFIX "x" + +# define SCNxFAST8 "hhx" +# define SCNxFAST16 __PRIPTR_PREFIX "x" +# define SCNxFAST32 __PRIPTR_PREFIX "x" +# define SCNxFAST64 __PRI64_PREFIX "x" + +/* Macros for scanning `intmax_t' and `uintmax_t'. */ +# define SCNdMAX __PRI64_PREFIX "d" +# define SCNiMAX __PRI64_PREFIX "i" +# define SCNoMAX __PRI64_PREFIX "o" +# define SCNuMAX __PRI64_PREFIX "u" +# define SCNxMAX __PRI64_PREFIX "x" + +/* Macros for scanning `intptr_t' and `uintptr_t'. */ +# define SCNdPTR __PRIPTR_PREFIX "d" +# define SCNiPTR __PRIPTR_PREFIX "i" +# define SCNoPTR __PRIPTR_PREFIX "o" +# define SCNuPTR __PRIPTR_PREFIX "u" +# define SCNxPTR __PRIPTR_PREFIX "x" + +#endif /* C++ && format macros */ + +#if __WORDSIZE == 64 + +/* We have to define the `uintmax_t' type using `ldiv_t'. */ +typedef struct { + long int quot; /* Quotient. */ + long int rem; /* Remainder. */ +} imaxdiv_t; + +#else + +/* We have to define the `uintmax_t' type using `lldiv_t'. */ +typedef struct { + long long int quot; /* Quotient. */ + long long int rem; /* Remainder. */ +} imaxdiv_t; + +#endif + +#endif /* inttypes.h */

Even if U-Boot does not use this, some libraries do. Add back this header file so that the build does not fall back to using the host version, which may include stdint.h and break the build due to conflicts with uint64_t, etc.
This partially reverts commit dee37fc99d94 ("Remove <inttypes.h> includes and PRI* usages in printf() entirely")
The only change from the file that was in U-Boot until recently is that it now comes twice as close to passing checkpatch. The remaining warnings pertain to the typedefs, which checkpatch does not like.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/inttypes.h | 271 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 include/inttypes.h
Applied to u-boot-dm/master, thanks!

On Sat, Nov 24, 2018 at 1:43 PM Simon Glass sjg@chromium.org wrote:
Even if U-Boot does not use this, some libraries do. Add back this header file so that the build does not fall back to using the host version, which may include stdint.h and break the build due to conflicts with uint64_t, etc.
The root cause of the problem might be, those libraries mix up <linux/types.h> from U-Boot and <inttypes.h> from the compiler.
Linux kernel has a different <linux/types.h> for user-space tools in tools/include/linux/types.h
I agree that U-Boot has been screwed up here to a hopeless level.

Hi Masahiro,
On Wed, 5 Dec 2018 at 22:51, Masahiro Yamada yamada.masahiro@socionext.com wrote:
On Sat, Nov 24, 2018 at 1:43 PM Simon Glass sjg@chromium.org wrote:
Even if U-Boot does not use this, some libraries do. Add back this header file so that the build does not fall back to using the host version, which may include stdint.h and break the build due to conflicts with uint64_t, etc.
The root cause of the problem might be, those libraries mix up <linux/types.h> from U-Boot and <inttypes.h> from the compiler.
Linux kernel has a different <linux/types.h> for user-space tools in tools/include/linux/types.h
Right, but how does it enforce those tools using that file? It is non-standard.
I agree that U-Boot has been screwed up here to a hopeless level.
The problem is not U-Boot. If a library that links against U-Boot includes stdint.h, it expects it to work.
Regards, Simon

As an experiment, build U-Boot as a library, u-boot.o, so it can be used by other open-source software. Update the sandbox build rules to suit.
This has not been tested in any meaningful way. It breaks sandbox_spl and all x86 boards.
I am interested in feedback as to how useful this might be.
Signed-off-by: Simon Glass sjg@chromium.org ---
Makefile | 9 ++++++++- arch/sandbox/config.mk | 10 ++++------ scripts/Makefile.spl | 17 +++++++++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile index d82772e7786..c8236de1463 100644 --- a/Makefile +++ b/Makefile @@ -1379,7 +1379,14 @@ cmd_smap = \ $(CC) $(c_flags) -DSYSTEM_MAP=""$${smap}"" \ -c $(srctree)/common/system_map.c -o common/system_map.o
-u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE +quiet_cmd_u-boot-lib ?= LIB $@ + cmd_u-boot-lib ?= $(LD) -r --exclude-libs ALL \ + --start-group $(u-boot-main) --end-group -o $@ + +u-boot.o: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE + +$(call if_changed,u-boot-lib) + +u-boot: u-boot.o FORCE +$(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y) $(call cmd,smap) diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 7226b7be428..0f30f9db0b2 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -17,14 +17,12 @@ PLATFORM_CPPFLAGS += $(shell sdl-config --cflags) endif endif
-cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \ - -Wl,--start-group $(u-boot-main) -Wl,--end-group \ - $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map +cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds \ + u-boot.o $(u-boot-init) \ + $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map \
cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \ - $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ - -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \ + u-boot-spl.o $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
CONFIG_ARCH_DEVICE_TREE := sandbox diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 7416abec62e..17c44424ceb 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -349,6 +349,20 @@ cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \ $(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin $(call if_changed,sunxi_spl_image_builder)
+quiet_cmd_u-boot-spl-lib ?= LIB $@ + cmd_u-boot-spl-lib ?= $(LD) -r --start-group $(u-boot-spl-main) \ + --end-group -o $@ + +$(obj)/u-boot-spl.o: $(u-boot-spl-platdata) $(u-boot-spl-init) \ + $(u-boot-spl-main) FORCE + (cd $(obj) && $(LD) -r $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ + --start-group \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + --end-group \ + -o $(patsubst $(obj)/%,%,$@)) + +$(call if_changed,u-boot-spl-lib) + # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk quiet_cmd_u-boot-spl ?= LD $@ @@ -359,8 +373,7 @@ quiet_cmd_u-boot-spl ?= LD $@ --end-group \ $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN))
-$(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \ - $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE +$(obj)/$(SPL_BIN): $(obj)/u-boot-spl.o $(obj)/u-boot-spl.lds FORCE $(call if_changed,u-boot-spl)
$(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ;
participants (6)
-
Alexander Graf
-
Anatolij Gustschin
-
Christian Borntraeger
-
Masahiro Yamada
-
Simon Glass
-
sjg@google.com