diff --git a/arch/Kconfig b/arch/Kconfig index 27843cd79c..7023223927 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -142,6 +142,8 @@ config SANDBOX 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/cmd/Kconfig b/cmd/Kconfig index 4defbd9cf9..960080d6d4 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2022,12 +2022,19 @@ config HASH_VERIFY 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 176bf925fd..a7017e8452 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -193,6 +193,9 @@ obj-$(CONFIG_CMD_BLOB) += blob.o # 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 0000000000..655e0bba08 --- /dev/null +++ b/cmd/scp03.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021, Foundries.IO + * + */ + +#include +#include +#include +#include + +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/common/Kconfig b/common/Kconfig index 2bb3798f80..482f123534 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -588,6 +588,14 @@ config AVB_BUF_SIZE 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 daeea67cf2..215b8b26fd 100644 --- a/common/Makefile +++ b/common/Makefile @@ -137,3 +137,4 @@ obj-$(CONFIG_CMD_LOADB) += xyzModem.o obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_AVB_VERIFY) += avb_verify.o +obj-$(CONFIG_SCP03) += scp03.o diff --git a/common/log.c b/common/log.c index 6b0034c3ba..ea407c6db9 100644 --- a/common/log.c +++ b/common/log.c @@ -153,7 +153,7 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec) { 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 @@ static int log_dispatch(struct log_rec *rec, const char *fmt, va_list args) 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 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, 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 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, 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 6abb13c93b..3f6177499e 100644 --- a/common/log_console.c +++ b/common/log_console.c @@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; 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 @@ static int log_console_emit(struct log_device *ldev, struct log_rec *rec) * - 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 0000000000..09ef7b5ba3 --- /dev/null +++ b/common/scp03.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021, Foundries.IO + * + */ + +#include +#include +#include +#include + +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/doc/arch/sandbox.rst b/doc/arch/sandbox.rst index 1638b05000..8b18a22117 100644 --- a/doc/arch/sandbox.rst +++ b/doc/arch/sandbox.rst @@ -82,7 +82,7 @@ console:: 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 diff --git a/doc/develop/logging.rst b/doc/develop/logging.rst index 60c18c5b3a..f4e925048e 100644 --- a/doc/develop/logging.rst +++ b/doc/develop/logging.rst @@ -96,16 +96,45 @@ Also debug() and error() will generate log records - these use LOG_CATEGORY 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/usage/index.rst b/doc/usage/index.rst index f7b706f916..7fac2e4f27 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -33,3 +33,4 @@ Shell commands qfw sbi true + scp03 diff --git a/doc/usage/scp03.rst b/doc/usage/scp03.rst new file mode 100644 index 0000000000..7ff87ed85a --- /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/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index 65622f30b1..d03028070b 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -31,6 +31,12 @@ config OPTEE_TA_RPC_TEST 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 3a1d34d6fc..35e8542fa3 100644 --- a/drivers/tee/sandbox.c +++ b/drivers/tee/sandbox.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "optee/optee_msg.h" #include "optee/optee_private.h" @@ -68,6 +69,7 @@ void *optee_alloc_and_init_page_list(void *buf, ulong len, 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 get_attr(uint n, uint num_params, struct tee_param *params) 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 @@ bad_params: 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 @@ static const struct ta_entry ta_entries[] = { .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/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c index c74bacfd71..24c804a564 100644 --- a/drivers/tpm/tpm2_tis_sandbox.c +++ b/drivers/tpm/tpm2_tis_sandbox.c @@ -285,7 +285,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf, 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/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index b6a9991fc9..c24f5e0e97 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -410,6 +410,12 @@ struct global_data { * 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/log.h b/include/log.h index 2d27f9f657..6ef891d4d2 100644 --- a/include/log.h +++ b/include/log.h @@ -316,12 +316,40 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, __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 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, * * @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/scp03.h b/include/scp03.h new file mode 100644 index 0000000000..729667ccd1 --- /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/tee/optee_ta_scp03.h b/include/tee/optee_ta_scp03.h new file mode 100644 index 0000000000..13f9956d98 --- /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/test/dm/acpi.c b/test/dm/acpi.c index 240187c523..2edab7be54 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -360,24 +360,24 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts) 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/log/cont_test.c b/test/log/cont_test.c index 16379a74be..de7b7f064c 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 @@ static int log_test_cont(struct unit_test_state *uts) 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 @@ static int log_test_cont(struct unit_test_state *uts) 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/py/tests/test_scp03.py b/test/py/tests/test_scp03.py new file mode 100644 index 0000000000..1f689252dd --- /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