[v3] [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements
Firmwares before U-Boot may be capable of doing tpm measurements and passing them to U-Boot in the form of eventlog. However there may be scenarios where the firmwares don't have TPM driver and are not capable of extending the measurements in the PCRs. Based on TCG spec, if previous firnware has extended PCR's, PCR0 would not be 0. So, read the PCR0 to determine if the PCR's need to be extended as eventlog is parsed or not. Signed-off-by: Ruchika Gupta --- v3 : Rebase changes on top of changes made in first patch of series v2 : Removed check for PCR0 in eventlog lib/efi_loader/efi_tcg2.c | 75 +++ 1 file changed, 75 insertions(+) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index ebd7847957..b5343bf039 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -199,6 +199,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, return EFI_SUCCESS; } +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values + * + * @dev: device + * @digest_list: list of digest algorithms to extend + * + * @Return: status code + */ +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + struct tpm_chip_priv *priv; + unsigned int updates, pcr_select_min; + u32 rc; + size_t i; + + priv = dev_get_uclass_priv(dev); + if (!priv) + return EFI_DEVICE_ERROR; + + pcr_select_min = priv->pcr_select_min; + + for (i = 0; i < digest_list->count; i++) { + u16 hash_alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, + hash_alg, digest, alg_to_len(hash_alg), + &updates); + if (rc) { + EFI_PRINT("Failed to read PCR\n"); + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + /* put_event - Append an agile event to an eventlog * * @pcr_index: PCR index @@ -1428,6 +1465,8 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, u32 pcr, pos; u64 base; u32 sz; + bool extend_pcr = false; + int i; ret = platform_get_eventlog(dev, &base, &sz); if (ret != EFI_SUCCESS) @@ -1449,6 +1488,26 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, return EFI_COMPROMISED_DATA; } + ret = tcg2_pcr_read(dev, 0, &digest_list); + if (ret) { + log_err("Error reading PCR 0\n"); + return ret; + } + + /* +* If PCR0 is 0, previous firmware didn't have the capability +* to extend the PCR. In this scenario, extend the PCR as +* the eventlog is parsed. +*/ + for (i = 0; i < digest_list.count; i++) { + u8 buffer[TPM2_DIGEST_LEN] = { 0 }; + u16 hash_alg = digest_list.digests[i].hash_alg; + + if (!memcmp((u8 *)&digest_list.digests[i].digest, buffer, + alg_to_len(hash_alg))) + extend_pcr = true; + } + while (pos < sz) { ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, &pcr); @@ -1456,6 +1515,22 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, log_err("Error parsing event\n"); return ret; } + if (extend_pcr) { + ret = tcg2_pcr_extend(dev, pcr, &digest_list); + if (ret != EFI_SUCCESS) { + log_err("Error in extending PCR\n"); + return ret; + } + + /* Clear the digest for next event */ + for (i = 0; i < digest_list.count; i++) { + u16 hash_alg = digest_list.digests[i].hash_alg; + u8 *digest = + (u8 *)&digest_list.digests[i].digest; + + memset(digest, 0, alg_to_len(hash_alg)); + } + } } memcpy(log_buffer, buffer, sz); -- 2.25.1
[v3][PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read
The current tpm2_pcr_read is hardcoded using SHA256. Make the actual command to TPM configurable to use wider range of algorithms. The current command line is kept as is i.e limited to SHA-256 only. Signed-off-by: Ruchika Gupta --- v3: No change v2: Change algorithm from u32 to u16 Add parameter description in function declaration cmd/tpm-v2.c | 3 ++- include/tpm-v2.h | 5 - lib/tpm-v2.c | 12 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index daae91100a..4ea5f9f094 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); - rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); + rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, + data, TPM2_DIGEST_LEN, &updates); if (!rc) { printf("PCR #%u content (%u known updates):\n", index, updates); print_byte_string(data, TPM2_DIGEST_LEN); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ceff7d245e..4e9dd52cb6 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, * @devTPM device * @idxIndex of the PCR * @idx_min_sz Minimum size in bytes of the pcrSelect array + * @algorithm Algorithm used, defined in 'enum tpm2_algorithms' * @data Output buffer for contents of the named PCR + * @digest_len len of the data * @updatesOptional out parameter: number of updates for this PCR * * @return code of the operation */ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates); + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates); /** * Issue a TPM2_GetCapability command. This implementation is limited diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 2e7b27bd6b..1bf627853a 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, } u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates) + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates) { u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, /* TPML_PCR_SELECTION */ tpm_u32(1), /* Number of selections */ - tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + tpm_u16(algorithm), /* Algorithm of the hash */ idx_array_sz, /* Array size for selection */ /* bitmap(idx) Selected PCR bitmap */ }; @@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, if (ret) return ret; + if (digest_len > response_len) + return TPM_LIB_ERROR; + if (unpack_byte_string(response, response_len, "ds", 10, &counter, - response_len - TPM2_DIGEST_LEN, data, - TPM2_DIGEST_LEN)) + response_len - digest_len, data, + digest_len)) return TPM_LIB_ERROR; if (updates) -- 2.25.1
[v3][PATCH 1/3] efi_loader: Add check for event log passed from firmware
Platforms may have support to measure their initial firmware components and pass the event log to u-boot. The event log address can be passed in property tpm_event_log_addr and tpm_event_log_size of the tpm node. Platforms may choose their own specific mechanism to do so. A weak function is added to check if even log has been passed to u-boot from earlier firmware components. If available, the eventlog is parsed to check for its correctness and further event logs are appended to the passed log. Signed-off-by: Ruchika Gupta --- v3: Return as soon as you detect error v2: Moved firmware eventlog code parsing to tcg2_get_fw_eventlog() lib/efi_loader/efi_tcg2.c | 322 -- 1 file changed, 311 insertions(+), 11 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 8c1f22e337..ebd7847957 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -324,6 +324,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev) return EFI_NOT_FOUND; } +/** + * platform_get_eventlog() - retrieve the eventlog address and size + * + * This function retrieves the eventlog address and size if the underlying + * firmware has done some measurements and passed them. + * + * This function may be overridden based on platform specific method of + * passing the eventlog address and size. + * + * @dev: udevice + * @addr: eventlog address + * @sz:eventlog size + * Return: status code + */ +__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, + u32 *sz) +{ + const u64 *basep; + const u32 *sizep; + + basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); + if (!basep) + return EFI_NOT_FOUND; + + *addr = be64_to_cpup((__force __be64 *)basep); + + sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); + if (!sizep) + return EFI_NOT_FOUND; + + *sz = be32_to_cpup((__force __be32 *)sizep); + if (*sz == 0) { + log_debug("event log empty\n"); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + /** * tpm2_get_max_command_size() - get the supported max command size * @@ -1181,6 +1220,250 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = { .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, }; +/** + * parse_event_log_header() - Parse and verify the event log header fields + * + * @buffer:Pointer to the event header + * @size: Size of the eventlog + * @pos: Position in buffer after event log header + * + * Return: status code + */ +efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) +{ + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + int i = 0; + + if (size < sizeof(*event_header)) + return EFI_COMPROMISED_DATA; + + if (get_unaligned_le32(&event_header->pcr_index) != 0 || + get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) + return EFI_COMPROMISED_DATA; + + for (i = 0; i < sizeof(event_header->digest); i++) { + if (event_header->digest[i] != 0) + return EFI_COMPROMISED_DATA; + } + + *pos += sizeof(*event_header); + + return EFI_SUCCESS; +} + +/** + * parse_specid_event() - Parse and verify the specID Event in the eventlog + * + * @dev: udevice + * @buffer:Pointer to the start of the eventlog + * @log_size: Size of the eventlog + * @pos: Offset in the evenlog where specID event starts + * + * Return: status code + * @posOffset in the eventlog where the specID event ends + * @digest_list: list of digests in the event + */ +efi_status_t parse_specid_event(struct udevice *dev, void *buffer, u32 log_size, + u32 *pos, + struct tpml_digest_values *digest_list) +{ + struct tcg_efi_spec_id_event *spec_event; + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + size_t spec_event_size; + u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; + u32 spec_active = 0; + u16 hash_alg, hash_sz; + u8 vendor_sz; + int err, i; + + /* Check specID event data */ + spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos); + /* Check for signature */ + if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { + log_err("specID Event: Signature mismatch\n"); + return EFI_COMPROMISED_DATA; + } + + if (spec_event->spec_version_minor != + TCG_EFI_SPEC_I
[PATCH v2 1/1] efi_loader: segfault in efi_clear_os_indications()
If we call efi_clear_os_indications() before initializing the memory store for UEFI variables a NULL pointer dereference occurs. The error was observed on the sandbox with: usb start host bind 0 sandbox.img load host 0:1 $kernel_addr_r helloworld.efi bootefi $kernel_addr_r Here efi_resister_disk() failed due to an error in the BTRFS implementation. Move the logic to clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED to the rest of the capsule code. If CONFIG_EFI_IGNORE_OSINDICATIONS=y, we should still clear the flag. If OsIndications does not exist, we should not create it as it is owned by the operating system. Fixes: 149108a3eb59 ("efi_loader: clear OsIndications") Signed-off-by: Heinrich Schuchardt --- v2: move the logic to the rest of the capsule code --- lib/efi_loader/efi_capsule.c | 45 lib/efi_loader/efi_setup.c | 36 + 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 502bcfca6e..8301eed631 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -1037,30 +1037,45 @@ efi_status_t __weak efi_load_capsule_drivers(void) } /** - * check_run_capsules - Check whether capsule update should run + * check_run_capsules() - check whether capsule update should run * * The spec says OsIndications must be set in order to run the capsule update * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected + * + * Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise */ -static bool check_run_capsules(void) +static efi_status_t check_run_capsules(void) { u64 os_indications; efi_uintn_t size; - efi_status_t ret; - - if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) - return true; + efi_status_t r; size = sizeof(os_indications); - ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, - NULL, &size, &os_indications, NULL); - if (ret == EFI_SUCCESS && - (os_indications - & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) - return true; - - return false; + r = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, +NULL, &size, &os_indications, NULL); + if (r != EFI_SUCCESS || size != sizeof(os_indications)) + return EFI_NOT_FOUND; + + if (os_indications & + EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) { + os_indications &= + ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; + r = efi_set_variable_int(L"OsIndications", +&efi_global_variable_guid, +EFI_VARIABLE_NON_VOLATILE | +EFI_VARIABLE_BOOTSERVICE_ACCESS | +EFI_VARIABLE_RUNTIME_ACCESS, +sizeof(os_indications), +&os_indications, false); + if (r != EFI_SUCCESS) + log_err("Setting %ls failed\n", L"OsIndications"); + return EFI_SUCCESS; + } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) { + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } } /** @@ -1078,7 +1093,7 @@ efi_status_t efi_launch_capsules(void) unsigned int nfiles, index, i; efi_status_t ret; - if (!check_run_capsules()) + if (check_run_capsules() != EFI_SUCCESS) return EFI_SUCCESS; index = get_last_capsule(); diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index a2338d74af..1aba71cd96 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -175,36 +175,6 @@ static efi_status_t efi_init_os_indications(void) } -/** - * efi_clear_os_indications() - clear OsIndications - * - * Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED - */ -static efi_status_t efi_clear_os_indications(void) -{ - efi_uintn_t size; - u64 os_indications; - efi_status_t ret; - - size = sizeof(os_indications); - ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, - NULL, &size, &os_indications, NULL); - if (ret != EFI_SUCCESS) - os_indications = 0; - else - os_indications &= - ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; - ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSER
Re: [PATCH] clk: Add myself as a maintainer for the clock subsystem
Hi Sean, > Lukasz has not been very responsive Unfortunately, this is true. I do have some personal issues which reduced my time budget. > in reviewing clock patches. Add > myself as a maintainer. Thanks for offering your help. > > Signed-off-by: Sean Anderson > --- > > MAINTAINERS | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 6db5354322..d30daff724 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -667,6 +667,7 @@ F:drivers/mtd/jedec_flash.c > > CLOCK > M: Lukasz Majewski > +M: Sean Anderson > S: Maintained > T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git > F: drivers/clk/ Acked-by: Lukasz Majewski Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lu...@denx.de pgpd9AB5PkWNo.pgp Description: OpenPGP digital signature
Re: [v2][PATCH 1/3] efi_loader: Add check for event log passed from firmware
Hi Ruchika, Ilias, On Tue, 23 Nov 2021 at 20:53, Ruchika Gupta wrote: > > Platforms may have support to measure their initial firmware components > and pass the event log to u-boot. The event log address can be passed > in property tpm_event_log_addr and tpm_event_log_size of the tpm node. > Platforms may choose their own specific mechanism to do so. A weak > function is added to check if even log has been passed to u-boot > from earlier firmware components. If available, the eventlog is parsed > to check for its correctness and further event logs are appended to the > passed log. It implies that U-Boot is no longer s-crtm, so existing efi_append_scrtm_version() call shall be skipped in this case. Thanks, Masahisa Kojima > > Signed-off-by: Ruchika Gupta > --- > v2: > Moved firmware eventlog code parsing to tcg2_get_fw_eventlog() > > lib/efi_loader/efi_tcg2.c | 322 -- > 1 file changed, 308 insertions(+), 14 deletions(-) > > diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c > index 8c1f22e337..c3ebdf92f5 100644 > --- a/lib/efi_loader/efi_tcg2.c > +++ b/lib/efi_loader/efi_tcg2.c > @@ -324,6 +324,45 @@ __weak efi_status_t platform_get_tpm2_device(struct > udevice **dev) > return EFI_NOT_FOUND; > } > > +/** > + * platform_get_eventlog() - retrieve the eventlog address and size > + * > + * This function retrieves the eventlog address and size if the underlying > + * firmware has done some measurements and passed them. > + * > + * This function may be overridden based on platform specific method of > + * passing the eventlog address and size. > + * > + * @dev: udevice > + * @addr: eventlog address > + * @sz:eventlog size > + * Return: status code > + */ > +__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, > + u32 *sz) > +{ > + const u64 *basep; > + const u32 *sizep; > + > + basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); > + if (!basep) > + return EFI_NOT_FOUND; > + > + *addr = be64_to_cpup((__force __be64 *)basep); > + > + sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); > + if (!sizep) > + return EFI_NOT_FOUND; > + > + *sz = be32_to_cpup((__force __be32 *)sizep); > + if (*sz == 0) { > + log_debug("event log empty\n"); > + return EFI_NOT_FOUND; > + } > + > + return EFI_SUCCESS; > +} > + > /** > * tpm2_get_max_command_size() - get the supported max command size > * > @@ -1181,6 +1220,249 @@ static const struct efi_tcg2_protocol > efi_tcg2_protocol = { > .get_result_of_set_active_pcr_banks = > efi_tcg2_get_result_of_set_active_pcr_banks, > }; > > +/** > + * parse_event_log_header() - Parse and verify the event log header fields > + * > + * @buffer:Pointer to the event header > + * @size: Size of the eventlog > + * @pos: Position in buffer after event log header > + * > + * Return: status code > + */ > +efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) > +{ > + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; > + int i = 0; > + > + if (size < sizeof(*event_header)) > + return EFI_COMPROMISED_DATA; > + > + if (get_unaligned_le32(&event_header->pcr_index) != 0 || > + get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) > + return EFI_COMPROMISED_DATA; > + > + for (i = 0; i < sizeof(event_header->digest); i++) { > + if (event_header->digest[i] != 0) > + return EFI_COMPROMISED_DATA; > + } > + > + *pos += sizeof(*event_header); > + > + return EFI_SUCCESS; > +} > + > +/** > + * parse_specid_event() - Parse and verify the specID Event in the eventlog > + * > + * @dev: udevice > + * @buffer:Pointer to the start of the eventlog > + * @log_size: Size of the eventlog > + * @pos: Offset in the evenlog where specID event starts > + * > + * Return: status code > + * @posOffset in the eventlog where the specID event > ends > + * @digest_list: list of digests in the event > + */ > +efi_status_t parse_specid_event(struct udevice *dev, void *buffer, u32 > log_size, > + u32 *pos, > + struct tpml_digest_values *digest_list) > +{ > + struct tcg_efi_spec_id_event *spec_event; > + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; > + size_t spec_event_size; > + u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; > + u32 spec_active = 0; > + u16 hash_alg, hash_sz; > + u8 vendor_sz; > + int err, i; > + > + /* Check specID event data */ > + spec_event = (
Re: [U-BOOT-TEST-HOOKS PATCH 1/1] Enable TPMv2 emulation
On 11/24/21 08:23, Ilias Apalodimas wrote: Hi Heinrich, On Mon, 15 Nov 2021 at 12:11, Heinrich Schuchardt wrote: Provide a QEMU helper script to launch swtpm and add extra parameters to conf.qemu_arm64_na and conf.qemu_arm_na to provide an emulated TPMv2. Signed-off-by: Heinrich Schuchardt --- bin/qemu.swtpm | 19 +++ bin/travis-ci/conf.qemu_arm64_na | 3 ++- bin/travis-ci/conf.qemu_arm_na | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100755 bin/qemu.swtpm diff --git a/bin/qemu.swtpm b/bin/qemu.swtpm new file mode 100755 index 000..089feba --- /dev/null +++ b/bin/qemu.swtpm @@ -0,0 +1,19 @@ +#!/bin/sh +# SPDX-License-Identifier: BSD-2 +# +# This script launches swtpm to emulate a TPMv2. The parameter -t makes it +# unload when the connection to QEMU is terminated. To make use of it add +# +# qemu_helper_script="swtpm" +# +# to the board script and the following arguments to qemu_extra_args +# +# -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock \ +# -tpmdev emulator,id=tpm0,chardev=chrtpm \ +# -device tpm-tis-device,tpmdev=tpm0 +# +# U-Boot must be built with CONFIG_TPM2_MMIO=y. + +mkdir -p /tmp/tpm +swtpm socket -t --tpmstate dir=/tmp/tpm --tpm2 \ +--ctrl type=unixio,path=/tmp/tpm/swtpm-sock & Nit pick the & can be '-d' Daemonizing will ensure that we don't get console output. I will change this. diff --git a/bin/travis-ci/conf.qemu_arm64_na b/bin/travis-ci/conf.qemu_arm64_na index e7c9426..14577d8 100644 --- a/bin/travis-ci/conf.qemu_arm64_na +++ b/bin/travis-ci/conf.qemu_arm64_na @@ -22,8 +22,9 @@ console_impl=qemu qemu_machine="virt" +qemu_helper_script="swtpm" qemu_binary="qemu-system-aarch64" -qemu_extra_args="-cpu cortex-a57 -nographic -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device virtio-rng-pci" +qemu_extra_args="-cpu cortex-a57 -nographic -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device virtio-rng-pci -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis-device,tpmdev=tpm0" qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/u-boot.bin" reset_impl=none flash_impl=none diff --git a/bin/travis-ci/conf.qemu_arm_na b/bin/travis-ci/conf.qemu_arm_na index 0f07c80..de0694d 100644 --- a/bin/travis-ci/conf.qemu_arm_na +++ b/bin/travis-ci/conf.qemu_arm_na @@ -22,8 +22,9 @@ console_impl=qemu qemu_machine="virt" +qemu_helper_script="swtpm" qemu_binary="qemu-system-arm" -qemu_extra_args="-nographic -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device virtio-rng-pci" +qemu_extra_args="-nographic -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device virtio-rng-pci -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis-device,tpmdev=tpm0" Just a note here 'tpm-tis-device' works for arm. If we evenr need this on x86 it's 'tpm-tis' This file is ARM specific. Best regards Heinrich qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/u-boot.bin" reset_impl=none flash_impl=none -- 2.32.0 Other than that Reviewed-by: Ilias Apalodimas
[PATCH] tools/mxsimage: Remove fclose on empty FILE pointer
If `sb_load_cmdfile()` fails to open the configuration file it will jump to error handling where the code will try to `fclose()` the FILE pointer which is NULL causing `mkimage` to segfault. This patch removes the `fclose()` since `fopen()` always returns NULL instead of the file descriptor when failing. Signed-off-by: Mattias Hansson --- tools/mxsimage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/mxsimage.c b/tools/mxsimage.c index 002f4b525a..c7bd86ce52 100644 --- a/tools/mxsimage.c +++ b/tools/mxsimage.c @@ -1618,7 +1618,6 @@ static int sb_load_cmdfile(struct sb_image_ctx *ictx) return 0; err_file: - fclose(fp); fprintf(stderr, "ERR: Failed to load file \"%s\"\n", ictx->cfg_filename); return -EINVAL; -- 2.27.0
Re: [U-BOOT-TEST-HOOKS PATCH 1/1] Enable TPMv2 emulation
Hi Heinrich, On Mon, 15 Nov 2021 at 12:11, Heinrich Schuchardt wrote: > > Provide a QEMU helper script to launch swtpm and add extra parameters to > conf.qemu_arm64_na and conf.qemu_arm_na to provide an emulated TPMv2. > > Signed-off-by: Heinrich Schuchardt > --- > bin/qemu.swtpm | 19 +++ > bin/travis-ci/conf.qemu_arm64_na | 3 ++- > bin/travis-ci/conf.qemu_arm_na | 3 ++- > 3 files changed, 23 insertions(+), 2 deletions(-) > create mode 100755 bin/qemu.swtpm > > diff --git a/bin/qemu.swtpm b/bin/qemu.swtpm > new file mode 100755 > index 000..089feba > --- /dev/null > +++ b/bin/qemu.swtpm > @@ -0,0 +1,19 @@ > +#!/bin/sh > +# SPDX-License-Identifier: BSD-2 > +# > +# This script launches swtpm to emulate a TPMv2. The parameter -t makes it > +# unload when the connection to QEMU is terminated. To make use of it add > +# > +# qemu_helper_script="swtpm" > +# > +# to the board script and the following arguments to qemu_extra_args > +# > +# -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock \ > +# -tpmdev emulator,id=tpm0,chardev=chrtpm \ > +# -device tpm-tis-device,tpmdev=tpm0 > +# > +# U-Boot must be built with CONFIG_TPM2_MMIO=y. > + > +mkdir -p /tmp/tpm > +swtpm socket -t --tpmstate dir=/tmp/tpm --tpm2 \ > +--ctrl type=unixio,path=/tmp/tpm/swtpm-sock & Nit pick the & can be '-d' > diff --git a/bin/travis-ci/conf.qemu_arm64_na > b/bin/travis-ci/conf.qemu_arm64_na > index e7c9426..14577d8 100644 > --- a/bin/travis-ci/conf.qemu_arm64_na > +++ b/bin/travis-ci/conf.qemu_arm64_na > @@ -22,8 +22,9 @@ > > console_impl=qemu > qemu_machine="virt" > +qemu_helper_script="swtpm" > qemu_binary="qemu-system-aarch64" > -qemu_extra_args="-cpu cortex-a57 -nographic -netdev > user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device > virtio-rng-pci" > +qemu_extra_args="-cpu cortex-a57 -nographic -netdev > user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device > virtio-rng-pci -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock -tpmdev > emulator,id=tpm0,chardev=chrtpm -device tpm-tis-device,tpmdev=tpm0" > qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/u-boot.bin" > reset_impl=none > flash_impl=none > diff --git a/bin/travis-ci/conf.qemu_arm_na b/bin/travis-ci/conf.qemu_arm_na > index 0f07c80..de0694d 100644 > --- a/bin/travis-ci/conf.qemu_arm_na > +++ b/bin/travis-ci/conf.qemu_arm_na > @@ -22,8 +22,9 @@ > > console_impl=qemu > qemu_machine="virt" > +qemu_helper_script="swtpm" > qemu_binary="qemu-system-arm" > -qemu_extra_args="-nographic -netdev > user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device > virtio-rng-pci" > +qemu_extra_args="-nographic -netdev > user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0 -device > virtio-rng-pci -chardev socket,id=chrtpm,path=/tmp/tpm/swtpm-sock -tpmdev > emulator,id=tpm0,chardev=chrtpm -device tpm-tis-device,tpmdev=tpm0" Just a note here 'tpm-tis-device' works for arm. If we evenr need this on x86 it's 'tpm-tis' > qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/u-boot.bin" > reset_impl=none > flash_impl=none > -- > 2.32.0 > Other than that Reviewed-by: Ilias Apalodimas
Re: [v2] [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements
On Tue, Nov 23, 2021 at 05:23:35PM +0530, Ruchika Gupta wrote: > Firmwares before U-Boot may be capable of doing tpm measurements > and passing them to U-Boot in the form of eventlog. However there > may be scenarios where the firmwares don't have TPM driver and > are not capable of extending the measurements in the PCRs. > Based on TCG spec, if previous firnware has extended PCR's, PCR0 > would not be 0. So, read the PCR0 to determine if the PCR's need > to be extended as eventlog is parsed or not. > > Signed-off-by: Ruchika Gupta > --- > v2 : Removed check for PCR0 in eventlog > > lib/efi_loader/efi_tcg2.c | 77 +++ > 1 file changed, 77 insertions(+) > > diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c > index c3ebdf92f5..133fe8291a 100644 > --- a/lib/efi_loader/efi_tcg2.c > +++ b/lib/efi_loader/efi_tcg2.c > @@ -199,6 +199,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, > u32 pcr_index, > return EFI_SUCCESS; > } > > +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values > + * > + * @dev: device > + * @digest_list: list of digest algorithms to extend > + * > + * @Return: status code > + */ > +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, > + struct tpml_digest_values *digest_list) > +{ > + struct tpm_chip_priv *priv; > + unsigned int updates, pcr_select_min; > + u32 rc; > + size_t i; > + > + priv = dev_get_uclass_priv(dev); > + if (!priv) > + return EFI_DEVICE_ERROR; > + > + pcr_select_min = priv->pcr_select_min; > + > + for (i = 0; i < digest_list->count; i++) { > + u16 hash_alg = digest_list->digests[i].hash_alg; > + u8 *digest = (u8 *)&digest_list->digests[i].digest; > + > + rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, > +hash_alg, digest, alg_to_len(hash_alg), > +&updates); > + if (rc) { > + EFI_PRINT("Failed to read PCR\n"); > + return EFI_DEVICE_ERROR; > + } > + } > + > + return EFI_SUCCESS; > +} > + > /* put_event - Append an agile event to an eventlog > * > * @pcr_index: PCR index > @@ -1427,6 +1464,8 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, > void *log_buffer, > u32 pcr, pos; > u64 base; > u32 sz; > + bool extend_pcr = false; > + int i; > > ret = platform_get_eventlog(dev, &base, &sz); > if (ret == EFI_SUCCESS) { > @@ -1447,6 +1486,26 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, > void *log_buffer, > return EFI_COMPROMISED_DATA; > } > > + ret = tcg2_pcr_read(dev, 0, &digest_list); > + if (ret) { > + log_err("Error reading PCR 0\n"); > + return ret; > + } > + > + /* > + * If PCR0 is 0, previous firmware didn't have the capability > + * to extend the PCR. In this scenario, extend the PCR as > + * the eventlog is parsed. > + */ > + for (i = 0; i < digest_list.count; i++) { > + u8 buffer[TPM2_DIGEST_LEN] = { 0 }; > + u16 hash_alg = digest_list.digests[i].hash_alg; > + > + if (!memcmp((u8 *)&digest_list.digests[i].digest, > + buffer, alg_to_len(hash_alg))) > + extend_pcr = true; > + } > + > while (pos < sz) { > ret = tcg2_parse_event(dev, buffer, sz, &pos, > &digest_list, &pcr); > @@ -1454,6 +1513,24 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, > void *log_buffer, > log_err("Error parsing event\n"); > return ret; > } > + > + if (extend_pcr) { > + ret = tcg2_pcr_extend(dev, pcr, &digest_list); > + if (ret != EFI_SUCCESS) { > + log_err("Error in extending PCR\n"); > + return ret; > + } > + > + /* Clear the digest for next event */ > + for (i = 0; i < digest_list.count; i++) { > + u16 hash_alg = > + digest_list.digests[i].hash_alg; > + u8 *digest = > +(u8 *)&digest_list.digests[i].digest; > + > + memset(digest, 0, alg_to_len(hash_alg)); > + } > + } > } >
Re: [v2] [PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read
On Tue, Nov 23, 2021 at 05:23:34PM +0530, Ruchika Gupta wrote: > The current tpm2_pcr_read is hardcoded using SHA256. Make the > actual command to TPM configurable to use wider range of algorithms. > The current command line is kept as is i.e limited to SHA-256 only. > > Signed-off-by: Ruchika Gupta > --- > v2: > Change algorithm from u32 to u16 > Add parameter description in function declaration > > cmd/tpm-v2.c | 3 ++- > include/tpm-v2.h | 5 - > lib/tpm-v2.c | 12 > 3 files changed, 14 insertions(+), 6 deletions(-) > > diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c > index daae91100a..4ea5f9f094 100644 > --- a/cmd/tpm-v2.c > +++ b/cmd/tpm-v2.c > @@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int > flag, int argc, > > data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); > > - rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); > + rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, > +data, TPM2_DIGEST_LEN, &updates); > if (!rc) { > printf("PCR #%u content (%u known updates):\n", index, updates); > print_byte_string(data, TPM2_DIGEST_LEN); > diff --git a/include/tpm-v2.h b/include/tpm-v2.h > index ceff7d245e..4e9dd52cb6 100644 > --- a/include/tpm-v2.h > +++ b/include/tpm-v2.h > @@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, > const void *data, > * @dev TPM device > * @idx Index of the PCR > * @idx_min_sz Minimum size in bytes of the pcrSelect array > + * @algorithmAlgorithm used, defined in 'enum tpm2_algorithms' > * @data Output buffer for contents of the named PCR > + * @digest_len len of the data > * @updates Optional out parameter: number of updates for this PCR > * > * @return code of the operation > */ > u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, > - void *data, unsigned int *updates); > + u16 algorithm, void *data, u32 digest_len, > + unsigned int *updates); > > /** > * Issue a TPM2_GetCapability command. This implementation is limited > diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c > index 2e7b27bd6b..1bf627853a 100644 > --- a/lib/tpm-v2.c > +++ b/lib/tpm-v2.c > @@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, > const void *data, > } > > u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, > - void *data, unsigned int *updates) > + u16 algorithm, void *data, u32 digest_len, > + unsigned int *updates) > { > u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); > u8 command_v2[COMMAND_BUFFER_SIZE] = { > @@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned > int idx_min_sz, > > /* TPML_PCR_SELECTION */ > tpm_u32(1), /* Number of selections */ > - tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ > + tpm_u16(algorithm), /* Algorithm of the hash */ > idx_array_sz, /* Array size for selection */ > /* bitmap(idx) Selected PCR bitmap */ > }; > @@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, > unsigned int idx_min_sz, > if (ret) > return ret; > > + if (digest_len > response_len) > + return TPM_LIB_ERROR; > + > if (unpack_byte_string(response, response_len, "ds", > 10, &counter, > -response_len - TPM2_DIGEST_LEN, data, > -TPM2_DIGEST_LEN)) > +response_len - digest_len, data, > +digest_len)) > return TPM_LIB_ERROR; > > if (updates) > -- > 2.25.1 > Reviewed-by: Ilias Apalodimas
Re: [v2][PATCH 1/3] efi_loader: Add check for event log passed from firmware
Hi Ruchika, > + [...] > + ret = platform_get_eventlog(dev, &base, &sz); > + if (ret == EFI_SUCCESS) { Can we invert the logic here? if (ret != EFI_SUCCESS) return ret; etc... > + void *buffer = (void *)base; > + > + if (sz > TPM2_EVENT_LOG_SIZE) > + return EFI_VOLUME_FULL; > + > + pos = 0; > + /* Parse the eventlog to check for its validity */ > + ret = parse_event_log_header(buffer, sz, &pos); > + if (ret || pos > sz) > + return EFI_COMPROMISED_DATA; > + > + ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list); > + if (ret || pos > sz) { > + log_err("Error parsing SPEC ID Event\n"); > + return EFI_COMPROMISED_DATA; > + } > + > + while (pos < sz) { > + ret = tcg2_parse_event(dev, buffer, sz, &pos, > +&digest_list, &pcr); > + if (ret) { > + log_err("Error parsing event\n"); > + return ret; > + } > + } > + > + memcpy(log_buffer, buffer, sz); > + *log_sz = sz; > + } > + > + return ret; > +} > + > /** > * create_specid_event() - Create the first event in the eventlog > * > @@ -1340,6 +1622,12 @@ static efi_status_t efi_init_event_log(void) >* last log entry >*/ > memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); > + > + /* > + * The log header is defined to be in SHA1 event log entry format. > + * Setup event header > + */ > + event_header = (struct tcg_pcr_event *)event_log.buffer; > event_log.pos = 0; > event_log.last_event_size = 0; > event_log.get_event_called = false; > @@ -1347,22 +1635,28 @@ static efi_status_t efi_init_event_log(void) > event_log.truncated = false; > > /* > - * The log header is defined to be in SHA1 event log entry format. > - * Setup event header > + * Check if earlier firmware have passed any eventlog. Different > + * platforms can use different ways to do so >*/ > - event_header = (struct tcg_pcr_event *)event_log.buffer; > - put_unaligned_le32(0, &event_header->pcr_index); > - put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); > - memset(&event_header->digest, 0, sizeof(event_header->digest)); > - ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + > sizeof(*event_header)), > - &spec_event_size); > - if (ret != EFI_SUCCESS) > - goto free_pool; > - put_unaligned_le32(spec_event_size, &event_header->event_size); > - event_log.pos = spec_event_size + sizeof(*event_header); > - event_log.last_event_size = event_log.pos; > + ret = tcg2_get_fw_eventlog(dev, event_log.buffer, &event_log.pos); > + if (ret == EFI_NOT_FOUND) { > + put_unaligned_le32(0, &event_header->pcr_index); > + put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); > + memset(&event_header->digest, 0, sizeof(event_header->digest)); > + ret = create_specid_event(dev, > + (void *)((uintptr_t)event_log.buffer + > +sizeof(*event_header)), > + &spec_event_size); > + if (ret != EFI_SUCCESS) > + goto free_pool; > + put_unaligned_le32(spec_event_size, &event_header->event_size); > + event_log.pos = spec_event_size + sizeof(*event_header); > + event_log.last_event_size = event_log.pos; > + } > + > + if (ret == EFI_SUCCESS) > + ret = create_final_event(); Same here please. Check for != EFI_SUCCESS and exit before creating the final eventlog config table. > > - ret = create_final_event(); > if (ret != EFI_SUCCESS) > goto free_pool; > > -- > 2.25.1 > Thanks /lias
Re: [PATCH v2 1/2] riscv: Support booting SiFive Unmatched from SPI.
On 11/23/21 11:27 PM, Thomas Skibo wrote: Configure SPI flash devices into SPL. Add SPI boot option to spl.c. Document how to format flash for booting. Signed-off-by: Thomas Skibo --- .../dts/hifive-unmatched-a00-u-boot.dtsi | 11 +++ board/sifive/unmatched/spl.c | 3 ++ configs/sifive_unmatched_defconfig| 6 doc/board/sifive/unmatched.rst| 29 +++ 4 files changed, 49 insertions(+) diff --git a/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi index c5475aa149..1ee8ab1868 100644 --- a/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi +++ b/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi @@ -16,6 +16,10 @@ u-boot,dm-spl; }; + config { + u-boot,spl-payload-offset = <0x105000>; /* loader2 @1044KB */ + }; + hfclk { u-boot,dm-spl; }; @@ -30,6 +34,13 @@ clocks = <&rtcclk>; }; +&qspi0 { + u-boot,dm-spl; + flash@0 { + u-boot,dm-spl; + }; +}; + &spi0 { mmc@0 { u-boot,dm-spl; diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c index d5663274cd..7c0beedc08 100644 --- a/board/sifive/unmatched/spl.c +++ b/board/sifive/unmatched/spl.c @@ -22,6 +22,7 @@ #define GEM_PHY_RESET SIFIVE_GENERIC_GPIO_NR(0, 12) #define MODE_SELECT_REG 0x1000 +#define MODE_SELECT_SPI0x6 #define MODE_SELECT_SD0xb #define MODE_SELECT_MASK GENMASK(3, 0) @@ -123,6 +124,8 @@ u32 spl_boot_device(void) u32 boot_device = mode_select & MODE_SELECT_MASK; switch (boot_device) { + case MODE_SELECT_SPI: + return BOOT_DEVICE_SPI; case MODE_SELECT_SD: return BOOT_DEVICE_MMC1; default: diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig index 9cc18b029c..d400ed0b23 100644 --- a/configs/sifive_unmatched_defconfig +++ b/configs/sifive_unmatched_defconfig @@ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00" CONFIG_SPL_MMC=y CONFIG_SPL=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y CONFIG_AHCI=y CONFIG_TARGET_SIFIVE_UNMATCHED=y @@ -23,17 +24,22 @@ CONFIG_DISPLAY_BOARDINFO=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_ID_EEPROM=y CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y +CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_EEPROM=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_PWM=y CONFIG_CMD_GPT_RENAME=y CONFIG_CMD_PCI=y CONFIG_CMD_USB=y +CONFIG_USE_ENV_SPI_BUS=y +CONFIG_ENV_SPI_BUS=1 CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SCSI_AHCI=y CONFIG_AHCI_PCI=y CONFIG_SPL_CLK=y +CONFIG_SPI_FLASH_ISSI=y CONFIG_SYS_I2C_EEPROM_ADDR=0x54 CONFIG_E1000=y CONFIG_NVME=y diff --git a/doc/board/sifive/unmatched.rst b/doc/board/sifive/unmatched.rst index 6b024f07f6..387785d76b 100644 --- a/doc/board/sifive/unmatched.rst +++ b/doc/board/sifive/unmatched.rst @@ -534,3 +534,32 @@ Sample boot log from HiFive Unmatched board OpenEmbedded nodistro.0 unmatched ttySIF0 unmatched login: + + +Booting from SPI + + +Use Building steps from "Booting from uSD using U-Boot SPL" section. + +Partition the SPI in Linux via mtdblock. + +.. code-block:: none + + sgdisk --clear -a 1 \ + --new=1:40:2087 --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \ + --new=2:2088:10279 --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \ + --new=3:10280:10535 --change-name=3:env --typecode=3:0FC63DAF-8483-4772-8E79-3D69D8477DE4 \ nit: Please use hexcodes as printed with sgdisk -L. And also document what the type is. Documentation is for us humans after all :) --Sean + /dev/mtdblock0 + +Write U-boot SPL and U-boot to their partitions. + +.. code-block:: none + + dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync + dd if=u-boot.itb of=/dev/mtdblock0 bs=4096 seek=261 conv=sync + +Power off the board. + +Change DIP switches MSEL[3:0] to 0110. + +Power up the board.
[PATCH] fastboot: Add maintainers entry
Add an entry in maintainers for fastboot. It is starting off orphaned, but hopefully someone can pick it up. Signed-off-by: Sean Anderson --- I would maintain this, but I don't have any boards which use fastboot at home. In the future I may come across something appropriate, but for now I'm not set up to test changes. MAINTAINERS | 12 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6db5354322..c17a51dba3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -760,6 +760,18 @@ F: test/env/ F: tools/env* F: tools/mkenvimage.c +FASTBOOT +S: Orphaned +F: cmd/fastboot.c +F: doc/android/fastboot*.rst +F: include/fastboot.h +F: include/fastboot-internal.h +F: include/net/fastboot.h +F: drivers/fastboot/ +F: drivers/usb/gadget/f_fastboot.c +F: net/fastboot.c +F: test/dm/fastboot.c + FPGA M: Michal Simek S: Maintained -- 2.33.0
[PATCH v2 1/2] riscv: Support booting SiFive Unmatched from SPI.
Configure SPI flash devices into SPL. Add SPI boot option to spl.c. Document how to format flash for booting. Signed-off-by: Thomas Skibo --- .../dts/hifive-unmatched-a00-u-boot.dtsi | 11 +++ board/sifive/unmatched/spl.c | 3 ++ configs/sifive_unmatched_defconfig| 6 doc/board/sifive/unmatched.rst| 29 +++ 4 files changed, 49 insertions(+) diff --git a/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi b/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi index c5475aa149..1ee8ab1868 100644 --- a/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi +++ b/arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi @@ -16,6 +16,10 @@ u-boot,dm-spl; }; + config { + u-boot,spl-payload-offset = <0x105000>; /* loader2 @1044KB */ + }; + hfclk { u-boot,dm-spl; }; @@ -30,6 +34,13 @@ clocks = <&rtcclk>; }; +&qspi0 { + u-boot,dm-spl; + flash@0 { + u-boot,dm-spl; + }; +}; + &spi0 { mmc@0 { u-boot,dm-spl; diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c index d5663274cd..7c0beedc08 100644 --- a/board/sifive/unmatched/spl.c +++ b/board/sifive/unmatched/spl.c @@ -22,6 +22,7 @@ #define GEM_PHY_RESET SIFIVE_GENERIC_GPIO_NR(0, 12) #define MODE_SELECT_REG0x1000 +#define MODE_SELECT_SPI0x6 #define MODE_SELECT_SD 0xb #define MODE_SELECT_MASK GENMASK(3, 0) @@ -123,6 +124,8 @@ u32 spl_boot_device(void) u32 boot_device = mode_select & MODE_SELECT_MASK; switch (boot_device) { + case MODE_SELECT_SPI: + return BOOT_DEVICE_SPI; case MODE_SELECT_SD: return BOOT_DEVICE_MMC1; default: diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig index 9cc18b029c..d400ed0b23 100644 --- a/configs/sifive_unmatched_defconfig +++ b/configs/sifive_unmatched_defconfig @@ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00" CONFIG_SPL_MMC=y CONFIG_SPL=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y CONFIG_AHCI=y CONFIG_TARGET_SIFIVE_UNMATCHED=y @@ -23,17 +24,22 @@ CONFIG_DISPLAY_BOARDINFO=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_ID_EEPROM=y CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y +CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_EEPROM=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_PWM=y CONFIG_CMD_GPT_RENAME=y CONFIG_CMD_PCI=y CONFIG_CMD_USB=y +CONFIG_USE_ENV_SPI_BUS=y +CONFIG_ENV_SPI_BUS=1 CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SCSI_AHCI=y CONFIG_AHCI_PCI=y CONFIG_SPL_CLK=y +CONFIG_SPI_FLASH_ISSI=y CONFIG_SYS_I2C_EEPROM_ADDR=0x54 CONFIG_E1000=y CONFIG_NVME=y diff --git a/doc/board/sifive/unmatched.rst b/doc/board/sifive/unmatched.rst index 6b024f07f6..387785d76b 100644 --- a/doc/board/sifive/unmatched.rst +++ b/doc/board/sifive/unmatched.rst @@ -534,3 +534,32 @@ Sample boot log from HiFive Unmatched board OpenEmbedded nodistro.0 unmatched ttySIF0 unmatched login: + + +Booting from SPI + + +Use Building steps from "Booting from uSD using U-Boot SPL" section. + +Partition the SPI in Linux via mtdblock. + +.. code-block:: none + + sgdisk --clear -a 1 \ + --new=1:40:2087 --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \ + --new=2:2088:10279 --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \ + --new=3:10280:10535 --change-name=3:env --typecode=3:0FC63DAF-8483-4772-8E79-3D69D8477DE4 \ + /dev/mtdblock0 + +Write U-boot SPL and U-boot to their partitions. + +.. code-block:: none + + dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync + dd if=u-boot.itb of=/dev/mtdblock0 bs=4096 seek=261 conv=sync + +Power off the board. + +Change DIP switches MSEL[3:0] to 0110. + +Power up the board. -- 2.25.1
[PATCH v2 0/2] riscv: Support booting SiFive Unmatched from SPI flash.
This patch set adds support for booting the SiFive Unmatched board from SPI flash memory and saving the environment to flash. Thomas Skibo (2): riscv: Support booting SiFive Unmatched from SPI. riscv: Enable SPI flash env for SiFive Unmatched. arch/riscv/cpu/fu740/Kconfig | 13 + .../dts/hifive-unmatched-a00-u-boot.dtsi | 11 +++ board/sifive/unmatched/Kconfig| 1 + board/sifive/unmatched/spl.c | 3 ++ configs/sifive_unmatched_defconfig| 6 doc/board/sifive/unmatched.rst| 29 +++ 6 files changed, 63 insertions(+) -- 2.25.1
[PATCH v2 2/2] riscv: Enable SPI flash env for SiFive Unmatched.
Enable saving environment to SPI flash memory on SiFive Unmatched. Signed-off-by: Thomas Skibo --- arch/riscv/cpu/fu740/Kconfig | 13 + board/sifive/unmatched/Kconfig | 1 + 2 files changed, 14 insertions(+) diff --git a/arch/riscv/cpu/fu740/Kconfig b/arch/riscv/cpu/fu740/Kconfig index 049a0a0584..3e0c1fddc8 100644 --- a/arch/riscv/cpu/fu740/Kconfig +++ b/arch/riscv/cpu/fu740/Kconfig @@ -40,3 +40,16 @@ config SIFIVE_FU740 imply DM_I2C imply SYS_I2C_OCORES imply SPL_I2C + +if ENV_IS_IN_SPI_FLASH + +config ENV_OFFSET + default 0x505000 + +config ENV_SIZE + default 0x2 + +config ENV_SECT_SIZE + default 0x1 + +endif # ENV_IS_IN_SPI_FLASH diff --git a/board/sifive/unmatched/Kconfig b/board/sifive/unmatched/Kconfig index fb2c1fbb58..fe213fd504 100644 --- a/board/sifive/unmatched/Kconfig +++ b/board/sifive/unmatched/Kconfig @@ -26,6 +26,7 @@ config SPL_OPENSBI_LOAD_ADDR config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select SIFIVE_FU740 + select ENV_IS_IN_SPI_FLASH select SUPPORT_SPL select RESET_SIFIVE select BINMAN -- 2.25.1
[PATCH] clk: Add myself as a maintainer for the clock subsystem
Lukasz has not been very responsive in reviewing clock patches. Add myself as a maintainer. Signed-off-by: Sean Anderson --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6db5354322..d30daff724 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -667,6 +667,7 @@ F: drivers/mtd/jedec_flash.c CLOCK M: Lukasz Majewski +M: Sean Anderson S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-clk.git F: drivers/clk/ -- 2.33.0
[PATCH 7/7] RFC: Move Odroid-C2 to use binman to produce the image
This shows how binman can be used to replace the long and complicated instructions with an automated build. It is still complicated to read but users don't have to worry about the details. It needs some tidying up and only supports Odroid-C2 at present. Signed-off-by: Simon Glass --- arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 arch/arm/mach-meson/Kconfig | 1 + doc/board/amlogic/odroid-c4.rst | 127 +-- scripts/pylint.base | 1 + tools/binman/etype/aml_encrypt.py| 124 ++ tools/binman/ftest.py| 3 + tools/binman/missing-blob-help | 6 + tools/binman/test/213_aml_encrypt.dts| 38 ++ tools/binman/test/214_list_no_dtb.dts| 23 9 files changed, 338 insertions(+), 92 deletions(-) create mode 100644 tools/binman/etype/aml_encrypt.py create mode 100644 tools/binman/test/213_aml_encrypt.dts create mode 100644 tools/binman/test/214_list_no_dtb.dts diff --git a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi index 963bf96b256..b221ce6920b 100644 --- a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi +++ b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi @@ -6,6 +6,113 @@ #include "meson-sm1-u-boot.dtsi" +/{ + binman { + /* run --bootmk on all the included inputs */ + aml-encrypt { + missing-msg = "aml-encrypt"; + aml-algo = "g12a"; + aml-op = "bootmk"; + aml-level = "v3"; + + /* produce a bl2, containing signed bl2 binaries */ + bl2 { + type = "aml-encrypt"; + aml-algo = "g12a"; + aml-op = "bl2sig"; + + /* sign the binary contaiing bl2 and acs */ + aml-input { + type = "section"; + bl2 { + type = "blob-ext"; + size = <0xe000>; + filename = "bl2.bin"; + }; + acs { + type = "blob-ext"; + size = <0x1000>; + filename = "acs.bin"; + }; + }; + }; + + /* produce a bl30, containing signed bl30 binaries */ + bl30 { + type = "aml-encrypt"; + aml-algo = "g12a"; + aml-op = "bl3sig"; + aml-level = "v3"; + aml-type = "bl30"; + + /* sign the binary contaiing bl30 and bl301 */ + aml-input { + type = "aml-encrypt"; + aml-algo = "g12a"; + aml-op = "bl30sig"; + aml-level = "v3"; + + /* +* put bl30 and bl301 together, with +* the necessary paddiung +*/ + aml-input { + type = "section"; + bl30 { + type = "blob-ext"; + size = <0xa000>; + filename = "bl30.bin"; + }; + bl301 { + type = "blob-ext"; + size = <0x3400>; + filename = "bl301.bin"; + }; + }; + }; + }; + + /* sign the bl31 binary */ + bl31 { + type = "aml-encrypt"; + aml-algo = "g12a"; + aml-op = "bl3sig"; + aml-input = "bl31.img"; + aml-level = "v3"; + aml-type = "bl31"; +
[PATCH 3/7] binman: Allow extracting a file in an alternative format
In some cases entries encapsulate other data and it is useful to access the data within. An example is the fdtmap which consists of a 16-byte header, followed by a devicetree. Provide an option to specify an alternative format when extracting files. In the case of fdtmap, this is 'fdt', which produces an FDT file which can be viewed with fdtdump. Signed-off-by: Simon Glass --- tools/binman/binman.rst | 29 tools/binman/cmdline.py | 2 ++ tools/binman/control.py | 28 +--- tools/binman/entries.rst| 11 +- tools/binman/entry.py | 37 + tools/binman/etype/atf_fip.py | 16 - tools/binman/etype/cbfs.py | 8 ++--- tools/binman/etype/fdtmap.py| 12 +++ tools/binman/etype/section.py | 23 ++--- tools/binman/ftest.py | 34 +++ tools/binman/image.py | 2 +- tools/binman/test/213_fdtmap_alt_format.dts | 15 + tools/binman/test/214_no_alt_format.dts | 13 13 files changed, 208 insertions(+), 22 deletions(-) create mode 100644 tools/binman/test/213_fdtmap_alt_format.dts create mode 100644 tools/binman/test/214_no_alt_format.dts diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 26f462ae16f..10389a52c4b 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -942,6 +942,35 @@ or just a selection:: $ binman extract -i image.bin "*u-boot*" -O outdir +Some entry types have alternative formats, for example fdtmap which allows +extracted just the devicetree binary without the fdtmap header:: + +$ binman extract -i /tmp/b/odroid-c4/image.bin -f out.dtb -F fdt fdtmap +$ fdtdump out.dtb +/dts-v1/; +// magic: 0xd00dfeed +// totalsize: 0x8ab (2219) +// off_dt_struct: 0x38 +// off_dt_strings: 0x82c +// off_mem_rsvmap: 0x28 +// version: 17 +// last_comp_version: 2 +// boot_cpuid_phys: 0x0 +// size_dt_strings: 0x7f +// size_dt_struct: 0x7f4 + +/ { +image-node = "binman"; +image-pos = <0x>; +size = <0x0011162b>; +... + +Use `-F list` to see what alternative formats are available:: + +$ binman extract -i /tmp/b/odroid-c4/image.bin -F list +Flag (-F) Entry typeDescription +fdt fdtmapExtract the devicetree blob from the fdtmap + Replacing files in an image --- diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index 2229316f10e..adc17547ae6 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -17,6 +17,8 @@ def make_extract_parser(subparsers): """ extract_parser = subparsers.add_parser('extract', help='Extract files from an image') +extract_parser.add_argument('-F', '--format', type=str, +help='Select an alternative format for extracted data') extract_parser.add_argument('-i', '--image', type=str, required=True, help='Image filename to extract') extract_parser.add_argument('-f', '--filename', type=str, diff --git a/tools/binman/control.py b/tools/binman/control.py index 304fc70f56f..7288a2639d5 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -200,8 +200,24 @@ def ReadEntry(image_fname, entry_path, decomp=True): return entry.ReadData(decomp) +def ShowAltFormats(image): +"""Show alternative formats available for entries in the image + +This shows a list of formats available. + +Args: +image (Image): Image to check +""" +alt_formats = {} +image.CheckAltFormats(alt_formats) +print('%-10s %-20s %s' % ('Flag (-F)', 'Entry type', 'Description')) +for name, val in alt_formats.items(): +entry, helptext = val +print('%-10s %-20s %s' % (name, entry.etype, helptext)) + + def ExtractEntries(image_fname, output_fname, outdir, entry_paths, - decomp=True): + decomp=True, alt_format=None): """Extract the data from one or more entries and write it to files Args: @@ -217,6 +233,10 @@ def ExtractEntries(image_fname, output_fname, outdir, entry_paths, """ image = Image.FromFile(image_fname) +if alt_format == 'list': +ShowAltFormats(image) +return + # Output an entry to a single file, as a special case if output_fname: if not entry_paths: @@ -224,7 +244,7 @@ def ExtractEntries(image_fname, output_fname, outdir, entry_paths, if len(entry_paths) != 1: raise ValueError('Must specify exactly one entry path to write with -f') entry = image.FindEntryPath(entry_paths[0]) -data = entry.ReadData(decomp)
[PATCH 6/7] binman: Rename _ReadSubnodes() to ReadEntries()
This method name is more commonly used for this function. Use it consistently. Signed-off-by: Simon Glass --- tools/binman/etype/fit.py| 4 ++-- tools/binman/etype/intel_ifwi.py | 4 ++-- tools/binman/etype/mkimage.py| 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index 6936f5736a6..b41187df80a 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -136,10 +136,10 @@ class Entry_fit(Entry): str)])[0] def ReadNode(self): -self._ReadSubnodes() +self.ReadEntries() super().ReadNode() -def _ReadSubnodes(self): +def ReadEntries(self): def _AddNode(base_node, depth, node): """Add a node to the FIT diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index 903d39bdbeb..ecbd78df5e5 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -50,7 +50,7 @@ class Entry_intel_ifwi(Entry_blob_ext): self._ifwi_entries = OrderedDict() def ReadNode(self): -self._ReadSubnodes() +self.ReadEntries() super().ReadNode() def _BuildIfwi(self): @@ -117,7 +117,7 @@ class Entry_intel_ifwi(Entry_blob_ext): same = orig_data == self.data return same -def _ReadSubnodes(self): +def ReadEntries(self): """Read the subnodes to find out what should go in this IFWI""" for node in self._node.subnodes: entry = Entry.Create(self.section, node) diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py index e49977522e3..c08fd9dc0b6 100644 --- a/tools/binman/etype/mkimage.py +++ b/tools/binman/etype/mkimage.py @@ -37,7 +37,7 @@ class Entry_mkimage(Entry): self._args = fdt_util.GetString(self._node, 'args').split(' ') self._mkimage_entries = OrderedDict() self.align_default = None -self._ReadSubnodes() +self.ReadEntries() def ObtainContents(self): data = b'' @@ -55,7 +55,7 @@ class Entry_mkimage(Entry): self.SetContents(tools.ReadFile(output_fname)) return True -def _ReadSubnodes(self): +def ReadEntries(self): """Read the subnodes to find out what should go in this image""" for node in self._node.subnodes: entry = Entry.Create(self, node) -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 5/7] binman: Support lists of external blobs
Sometimes it is useful to have a list of related external blobs in a single entry. An example is the DDR binaries used by meson. There are 9 files in total. Add support for this, so we don't have to have a separate entry for each. Signed-off-by: Simon Glass --- scripts/pylint.base | 1 + tools/binman/entries.rst | 14 + tools/binman/etype/blob.py| 16 - tools/binman/etype/blob_ext_list.py | 58 +++ tools/binman/ftest.py | 20 +++ tools/binman/test/215_blob_ext_list.dts | 14 + .../binman/test/216_blob_ext_list_missing.dts | 14 + 7 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 tools/binman/etype/blob_ext_list.py create mode 100644 tools/binman/test/215_blob_ext_list.dts create mode 100644 tools/binman/test/216_blob_ext_list_missing.dts diff --git a/scripts/pylint.base b/scripts/pylint.base index 3d891edf261..1b320e421e3 100644 --- a/scripts/pylint.base +++ b/scripts/pylint.base @@ -22,6 +22,7 @@ binman.state 3.30 blob -1.94 blob_dtb -10.00 blob_ext -20.00 +blob_ext_list -0.32 blob_named_by_arg -7.78 blob_phase -5.00 buildman.board 7.11 diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index cf3a6e69599..c47f7df0980 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -223,6 +223,20 @@ See 'blob' for Properties / Entry arguments. +Entry: blob-ext-list: List of externally built binary blobs +--- + +This is like blob-ext except that a number of blobs can be provided, +typically with some sort of relationship, e.g. all are DDC parameters. + +If any of the external files needed by this llist is missing, binman can +optionally ignore it and produce a broken image with a warning. + +Args: +filenames: List of filenames to read and include + + + Entry: blob-named-by-arg: A blob entry which gets its filename property from its subclass - diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index fae86ca3ec0..8c1b809e8da 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -48,10 +48,10 @@ class Entry_blob(Entry): self.ReadBlobContents() return True -def ReadBlobContents(self): +def ReadFileContents(self, pathname): """Read blob contents into memory -This function compresses the data before storing if needed. +This function compresses the data before returning if needed. We assume the data is small enough to fit into memory. If this is used for large filesystem image that might not be true. @@ -59,13 +59,23 @@ class Entry_blob(Entry): new Entry method which can read in chunks. Then we could copy the data in chunks and avoid reading it all at once. For now this seems like an unnecessary complication. + +Args: +pathname (str): Pathname to read from + +Returns: +bytes: Data read """ state.TimingStart('read') -indata = tools.ReadFile(self._pathname) +indata = tools.ReadFile(pathname) state.TimingAccum('read') state.TimingStart('compress') data = self.CompressData(indata) state.TimingAccum('compress') +return data + +def ReadBlobContents(self): +data = self.ReadFileContents(self._pathname) self.SetContents(data) return True diff --git a/tools/binman/etype/blob_ext_list.py b/tools/binman/etype/blob_ext_list.py new file mode 100644 index 000..136ae819946 --- /dev/null +++ b/tools/binman/etype/blob_ext_list.py @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass +# +# Entry-type module for a list of external blobs, not built by U-Boot +# + +import os + +from binman.etype.blob import Entry_blob +from dtoc import fdt_util +from patman import tools +from patman import tout + +class Entry_blob_ext_list(Entry_blob): +"""List of externally built binary blobs + +This is like blob-ext except that a number of blobs can be provided, +typically with some sort of relationship, e.g. all are DDC parameters. + +If any of the external files needed by this llist is missing, binman can +optionally ignore it and produce a broken image with a warning. + +Args: +filenames: List of filenames to read and include +""" +def __init__(self, section, etype, node): +Entry_blob.__init__(self, section, etype, node) +self.external = True + +def ReadNode(self): +super().ReadNode() +self._filenames = fdt_util.GetStringList(self._node, 'filenames') +self._pathnames = [] + +def ObtainContents(self): +missing = False +pathnames = [] +
[PATCH 4/7] dtoc: Add support for reading string-list properties
Add a function to read a list of strings from the devicetree. Signed-off-by: Simon Glass --- tools/dtoc/fdt_util.py | 21 + tools/dtoc/test_fdt.py | 9 + 2 files changed, 30 insertions(+) diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index 51bdbdcd3b2..19eb13aef33 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -163,6 +163,27 @@ def GetString(node, propname, default=None): "a single string" % (node.name, propname)) return value +def GetStringList(node, propname, default=None): +"""Get a string list from a property + +Args: +node (Node): Node object to read from +propname (str): property name to read +default (list of str): Default value to use if the node/property do not +exist, or None + +Returns: +String value read, or default if none +""" +prop = node.props.get(propname) +if not prop: +return default +value = prop.value +if not isinstance(value, list): +strval = GetString(node, propname) +return [strval] +return value + def GetBool(node, propname, default=False): """Get an boolean from a property diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 7a4c7efaa4a..55b70e98764 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -615,6 +615,15 @@ class TestFdtUtil(unittest.TestCase): self.assertIn("property 'stringarray' has list value: expecting a " 'single string', str(e.exception)) +def testGetStringList(self): +self.assertEqual(['message'], + fdt_util.GetStringList(self.node, 'stringval')) +self.assertEqual( +['multi-word', 'message'], +fdt_util.GetStringList(self.node, 'stringarray')) +self.assertEqual(['test'], + fdt_util.GetStringList(self.node, 'missing', ['test'])) + def testGetBool(self): self.assertEqual(True, fdt_util.GetBool(self.node, 'boolval')) self.assertEqual(False, fdt_util.GetBool(self.node, 'missing')) -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 2/7] binman: Allow listing an image created by a newer version
If an older version of binman is used to list images created by a newer one, it is possible that it will contain entry types that are not supported. At present this produces an error. Adjust binman to use a plain 'blob' entry type to cope with this, so the image can at least be listed. Signed-off-by: Simon Glass --- tools/binman/binman.rst | 5 +++ tools/binman/entry.py | 65 +++ tools/binman/entry_test.py| 9 + tools/binman/etype/section.py | 3 +- tools/binman/image.py | 10 -- 5 files changed, 74 insertions(+), 18 deletions(-) diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 210d0c5c51b..26f462ae16f 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -913,6 +913,11 @@ or with wildcards:: u-boot-dtb180 108 u-boot-dtb80 3b5 image-header bf8 8 image-header bf8 +If an older version of binman is used to list images created by a newer one, it +is possible that it will contain entry types that are not supported. These still +show with the correct type, but binman just sees them as blobs (plain binary +data). Any special features of that etype are not supported by the old binman. + Extracting files from images diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 2205bc8d923..e7a8365fd51 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -102,7 +102,7 @@ class Entry(object): self.allow_missing = False @staticmethod -def Lookup(node_path, etype, expanded): +def FindEntryClass(etype, expanded): """Look up the entry class for a node. Args: @@ -113,10 +113,9 @@ class Entry(object): Returns: The entry class object if found, else None if not found and expanded -is True - -Raise: -ValueError if expanded is False and the class is not found +is True, else a tuple: +module name that could not be found +exception received """ # Convert something like 'u-boot@0' to 'u_boot' since we are only # interested in the type. @@ -137,30 +136,66 @@ class Entry(object): except ImportError as e: if expanded: return None -raise ValueError("Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" % - (etype, node_path, module_name, e)) +return module_name, e modules[module_name] = module # Look up the expected class name return getattr(module, 'Entry_%s' % module_name) @staticmethod -def Create(section, node, etype=None, expanded=False): +def Lookup(node_path, etype, expanded, missing_etype=False): +"""Look up the entry class for a node. + +Args: +node_node (str): Path name of Node object containing information +about the entry to create (used for errors) +etype (str): Entry type to use +expanded (bool): Use the expanded version of etype +missing_etype (bool): True to default to a blob etype if the +requested etype is not found + +Returns: +The entry class object if found, else None if not found and expanded +is True + +Raise: +ValueError if expanded is False and the class is not found +""" +# Convert something like 'u-boot@0' to 'u_boot' since we are only +# interested in the type. +cls = Entry.FindEntryClass(etype, expanded) +if cls is None: +return None +elif isinstance(cls, tuple): +if missing_etype: +cls = Entry.FindEntryClass('blob', False) +if isinstance(cls, tuple): # This should not fail +module_name, e = cls +raise ValueError( +"Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" % +(etype, node_path, module_name, e)) +return cls + +@staticmethod +def Create(section, node, etype=None, expanded=False, missing_etype=False): """Create a new entry for a node. Args: -section: Section object containing this node -node: Node object containing information about the entry to - create -etype:Entry type to use, or None to work it out (used for tests) -expanded: True to use expanded versions of entries, where available +section (entry_Section): Section object containing this node +node (Node): Node object containing information about the entry to +create +etype (str): Entry type to use, or None to work it out (used for +te
[PATCH 1/7] binman: Allow providing tools and blob directories
At present it is necessary to symlink files containing external blobs into the U-Boot tree in order for binman to find them. This is not very convenient. Add two new environment/Makefile variables to help with this. Add documentation as well, fixing a related nit. Signed-off-by: Simon Glass --- Makefile| 2 ++ tools/binman/binman.rst | 31 ++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0b08b2669f9..0c163d0545c 100644 --- a/Makefile +++ b/Makefile @@ -1303,11 +1303,13 @@ 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) \ + $(foreach f,$(BINMAN_TOOLPATHS),--toolpath $(f)) \ --toolpath $(objtree)/tools \ $(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \ build -u -d u-boot.dtb -O . -m --allow-missing \ -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \ -I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \ + $(foreach f,$(BINMAN_INDIRS),-I $(f)) \ -a atf-bl31-path=${BL31} \ -a opensbi-path=${OPENSBI} \ -a default-dt=$(default_dt) \ diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 35de93bd898..210d0c5c51b 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -942,7 +942,7 @@ Replacing files in an image --- You can replace files in an existing firmware image created by binman, provided -that there is an 'fdtmap' entry in the image. For example: +that there is an 'fdtmap' entry in the image. For example:: $ binman replace -i image.bin section/cbfs/u-boot @@ -1081,6 +1081,35 @@ the tool's output will be used for the target or for the host machine. If those aren't given, it will also try to derive target-specific versions from the CROSS_COMPILE environment variable during a cross-compilation. +If the tool is not available in the path you can use BINMAN_TOOLPATHS to specify +a space-separated list of paths to search, e.g.:: + + BINMAN_TOOLPATHS="/tools/g12a /tools/tegra" binman ... + + +External blobs +-- + +Binary blobs, even if the source code is available, complicate building +firmware. The instructions can involve multiple steps and the binaries may be +hard to build or obtain. Binman at least provides a unified description of how +to build the final image, no matter what steps are needed to get there. + +Binman also provides a `blob-ext` entry type that pulls in a binary blob from an +external file. If the file is missing, binman can optionally complete the build +and just report a warning. Use the `-M/--allow-missing` option to enble this. +This is useful in CI systems which want to check that everything is correct but +don't have access to the blobs. + +If the blobs are in a different directory, you can specify this with the `-I` +option. + +For U-Boot, you can use set the BINMAN_INDIRS environment variable to provide a +space-separated list of directories to search for binary blobs:: + + BINMAN_INDIRS="odroid-c4/fip/g12a \ + odroid-c4/build/board/hardkernel/odroidc4/firmware \ + odroid-c4/build/scp_task" binman ... Code coverage - -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 0/7] meson: Demonstration of using binman to produce the image
The Odroid-C2 is quite a complicated image with many steps. It is an ideal example for how Binman can be used. Add a binman description and update the instructions accordingly. Simon Glass (7): binman: Allow providing tools and blob directories binman: Allow listing an image created by a newer version binman: Allow extracting a file in an alternative format dtoc: Add support for reading string-list properties binman: Support lists of external blobs binman: Rename _ReadSubnodes() to ReadEntries() RFC: Move Odroid-C2 to use binman to produce the image Makefile | 2 + arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 +++ arch/arm/mach-meson/Kconfig | 1 + doc/board/amlogic/odroid-c4.rst | 127 +- scripts/pylint.base | 2 + tools/binman/binman.rst | 65 - tools/binman/cmdline.py | 2 + tools/binman/control.py | 28 +++- tools/binman/entries.rst | 25 +++- tools/binman/entry.py | 102 +++--- tools/binman/entry_test.py| 9 ++ tools/binman/etype/aml_encrypt.py | 124 + tools/binman/etype/atf_fip.py | 16 ++- tools/binman/etype/blob.py| 16 ++- tools/binman/etype/blob_ext_list.py | 58 tools/binman/etype/cbfs.py| 8 +- tools/binman/etype/fdtmap.py | 12 ++ tools/binman/etype/fit.py | 4 +- tools/binman/etype/intel_ifwi.py | 4 +- tools/binman/etype/mkimage.py | 4 +- tools/binman/etype/section.py | 26 +++- tools/binman/ftest.py | 57 tools/binman/image.py | 12 +- tools/binman/missing-blob-help| 6 + tools/binman/test/213_aml_encrypt.dts | 38 ++ tools/binman/test/213_fdtmap_alt_format.dts | 15 +++ tools/binman/test/214_list_no_dtb.dts | 23 tools/binman/test/214_no_alt_format.dts | 13 ++ tools/binman/test/215_blob_ext_list.dts | 14 ++ .../binman/test/216_blob_ext_list_missing.dts | 14 ++ tools/dtoc/fdt_util.py| 21 +++ tools/dtoc/test_fdt.py| 9 ++ 32 files changed, 822 insertions(+), 142 deletions(-) create mode 100644 tools/binman/etype/aml_encrypt.py create mode 100644 tools/binman/etype/blob_ext_list.py create mode 100644 tools/binman/test/213_aml_encrypt.dts create mode 100644 tools/binman/test/213_fdtmap_alt_format.dts create mode 100644 tools/binman/test/214_list_no_dtb.dts create mode 100644 tools/binman/test/214_no_alt_format.dts create mode 100644 tools/binman/test/215_blob_ext_list.dts create mode 100644 tools/binman/test/216_blob_ext_list_missing.dts -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 2/2] binman: Add support for ATF FIP
This format is used in firmware binaries so we may as well supported it. With this patch binman supports creating, listing and updating FIPs, as well as extracting files from one, provided that an FDTMAP is also present somewhere in the image. Signed-off-by: Simon Glass --- scripts/pylint.base | 1 + tools/binman/entries.rst | 154 + tools/binman/etype/atf_fip.py| 273 +++ tools/binman/ftest.py| 217 ++ tools/binman/test/203_fip.dts| 21 ++ tools/binman/test/204_fip_other.dts | 22 ++ tools/binman/test/205_fip_no_type.dts| 15 ++ tools/binman/test/206_fip_uuid.dts | 22 ++ tools/binman/test/207_fip_ls.dts | 25 +++ tools/binman/test/208_fip_replace.dts| 33 +++ tools/binman/test/209_fip_missing.dts| 19 ++ tools/binman/test/210_fip_size.dts | 19 ++ tools/binman/test/211_fip_bad_align.dts | 18 ++ tools/binman/test/212_fip_collection.dts | 24 ++ 14 files changed, 863 insertions(+) create mode 100644 tools/binman/etype/atf_fip.py create mode 100644 tools/binman/test/203_fip.dts create mode 100644 tools/binman/test/204_fip_other.dts create mode 100644 tools/binman/test/205_fip_no_type.dts create mode 100644 tools/binman/test/206_fip_uuid.dts create mode 100644 tools/binman/test/207_fip_ls.dts create mode 100644 tools/binman/test/208_fip_replace.dts create mode 100644 tools/binman/test/209_fip_missing.dts create mode 100644 tools/binman/test/210_fip_size.dts create mode 100644 tools/binman/test/211_fip_bad_align.dts create mode 100644 tools/binman/test/212_fip_collection.dts diff --git a/scripts/pylint.base b/scripts/pylint.base index a35dbe34d2d..3d891edf261 100644 --- a/scripts/pylint.base +++ b/scripts/pylint.base @@ -1,5 +1,6 @@ _testing 0.83 atf_bl31 -6.00 +atf_fip 0.44 binman.cbfs_util 7.70 binman.cbfs_util_test 9.19 binman.cmdline 9.06 diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index 748277c1cde..84f828a6352 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -25,6 +25,160 @@ about ATF. +Entry: atf-fip: ARM Trusted Firmware's Firmware Image Package (FIP) +--- + +A FIP_ provides a way to group binaries in a firmware image, used by ARM's +Trusted Firmware A (TF-A) code. It is a simple format consisting of a +table of contents with information about the type, offset and size of the +binaries in the FIP. It is quite similar to FMAP, with the major difference +that it uses UUIDs to indicate the type of each entry. + +Note: It is recommended to always add an fdtmap to every image, as well as +any FIPs so that binman and other tools can access the entire image +correctly. + +The UUIDs correspond to useful names in `fiptool`, provided by ATF to +operate on FIPs. Binman uses these names to make it easier to understand +what is going on, although it is possible to provide a UUID if needed. + +The contents of the FIP are defined by subnodes of the atf-fip entry, e.g.:: + +atf-fip { +soc-fw { +filename = "bl31.bin"; +}; + +scp-fwu-cfg { +filename = "bl2u.bin"; +}; + +u-boot { +fip-type = "nt-fw"; +}; +}; + +This describes a FIP with three entries: soc-fw, scp-fwu-cfg and nt-fw. +You can use normal (non-external) binaries like U-Boot simply by adding a +FIP type, with the `fip-type` property, as above. + +Since FIP exists to bring blobs together, Binman assumes that all FIP +entries are external binaries. If a binary may not exist, you can use the +`--allow-missing` flag to Binman, in which case the image is still created, +even though it will not actually work. + +The size of the FIP depends on the size of the binaries. There is currently +no way to specify a fixed size. If the `atf-fip` node has a `size` entry, +this affects the space taken up by the `atf-fip` entry, but the FIP itself +does not expand to use that space. + +Some other FIP features are available with Binman. The header and the +entries have 64-bit flag works. The flag flags do not seem to be defined +anywhere, but you can use `fip-hdr-flags` and fip-flags` to set the values +of the header and entries respectively. + +FIP entries can be aligned to a particular power-of-two boundary. Use +fip-align for this. + +Binman only understands the entry types that are included in its +implementation. It is possible to specify a 16-byte UUID instead, using the +fip-uuid property. In this case Binman doesn't know what its type is, so +just uses the UUID. See the `u-boot` node in this example:: + +binman { +atf-fip { +fip-hdr-flags = /bits/ 64 <0x123>; +fip-align = <16>; +soc-fw { +fip-flags = /bits/ 64 <0x456>; +filename = "bl31.bin"; +}; + +scp-fwu-cfg { +
[PATCH 1/2] binman: Add a utility module for ATF FIP
Add support for this format which is used by ARM Trusted Firmware to find firmware binaries to load. FIP is like a simpler version of FMAP but uses a UUID instead of a name, for each entry. It supports reading a FIP, writing a FIP and parsing the ATF source code to get a list of supported UUIDs. Signed-off-by: Simon Glass --- scripts/pylint.base | 8 +- tools/binman/fip_util.py | 653 ++ tools/binman/fip_util_test.py | 405 + tools/binman/main.py | 4 +- 4 files changed, 1066 insertions(+), 4 deletions(-) create mode 100755 tools/binman/fip_util.py create mode 100755 tools/binman/fip_util_test.py diff --git a/scripts/pylint.base b/scripts/pylint.base index 4e82dd4a616..a35dbe34d2d 100644 --- a/scripts/pylint.base +++ b/scripts/pylint.base @@ -9,11 +9,13 @@ binman.elf_test 5.41 binman.entry 2.39 binman.entry_test 5.29 binman.fdt_test 3.23 +binman.fip_util 9.86 +binman.fip_util_test 9.75 binman.fmap_util 6.67 binman.ftest 7.38 binman.image 6.39 binman.image_test 4.48 -binman.main 4.26 +binman.main 4.03 binman.setup 5.00 binman.state 3.30 blob -1.94 @@ -33,7 +35,7 @@ buildman.main 1.43 buildman.test 6.10 buildman.toolchain 5.81 capsule_defs 5.00 -cbfs -1.52 +cbfs -1.44 collection 2.33 concurrencytest 6.77 conftest -3.84 @@ -107,7 +109,7 @@ powerpc_mpc85xx_bootpg_resetvec -10.00 rkmux 6.76 rmboard 7.76 scp -6.00 -section 4.25 +section 4.31 sqfs_common 8.12 test 8.18 test_000_version 7.50 diff --git a/tools/binman/fip_util.py b/tools/binman/fip_util.py new file mode 100755 index 000..5f7dbc04d56 --- /dev/null +++ b/tools/binman/fip_util.py @@ -0,0 +1,653 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2021 Google LLC +# Written by Simon Glass + +"""Support for ARM's Firmware Image Package (FIP) format + +FIP is a format similar to FMAP[1] but with fewer features and an obscure UUID +instead of the region name. + +It consists of a header and a table of entries, each pointing to a place in the +firmware image where something can be found. + +[1] https://chromium.googlesource.com/chromiumos/third_party/flashmap/+/refs/heads/master/lib/fmap.h + +If ATF updates, run this program to update the FIT_TYPE_LIST. + +ARM Trusted Firmware is available at: + +https://github.com/ARM-software/arm-trusted-firmware.git +""" + +from argparse import ArgumentParser +import collections +import io +import os +import re +import struct +import sys +from uuid import UUID + +OUR_FILE = os.path.realpath(__file__) +OUR_PATH = os.path.dirname(OUR_FILE) + +# Bring in the patman and dtoc libraries (but don't override the first path +# in PYTHONPATH) +sys.path.insert(2, os.path.join(OUR_PATH, '..')) + +# pylint: disable=C0413 +from patman import command +from patman import tools + +# The TOC header, at the start of the FIP +HEADER_FORMAT = 'https://github.com/ARM-software/arm-trusted-firmware.git +dstfile (str): File to write new code to, if an update is needed +oldfile (str): Python source file to compare against + +Raises: +ValueError: srcdir readme.rst is missing or the first line does not +match what is expected +""" +# We expect a readme file +readme_fname = os.path.join(srcdir, 'readme.rst') +if not os.path.exists(readme_fname): +raise ValueError( +f"Expected file '{readme_fname}' - try using -s to specify the " +'arm-trusted-firmware directory') +readme = tools.ReadFile(readme_fname, binary=False) +first_line = 'Trusted Firmware-A' +if readme.splitlines()[0] != first_line: +raise ValueError(f"'{readme_fname}' does not start with '{first_line}'") +macros = parse_macros(srcdir) +names = parse_names(srcdir) +output = create_code_output(macros, names) +orig = tools.ReadFile(oldfile, binary=False) +re_fip_list = re.compile(r'(.*FIP_TYPE_LIST = \[).*?(] # end.*)', re.S) +mat = re_fip_list.match(orig) +new_code = mat.group(1) + '\n' + output + mat.group(2) if mat else output +if new_code == orig: +print(f"Existing code in '{oldfile}' is up-to-date") +else: +tools.WriteFile(dstfile, new_code, binary=False) +print(f'Needs update, try:\n\tmeld {dstfile} {oldfile}') + + +def main(argv, oldfile): +"""Main program for this tool + +Args: +argv (list): List of str command-line arguments +oldfile (str): Python source file to compare against + +Returns: +int: 0 (exit code) +""" +parser = ArgumentParser(epilog='''Creates an updated version of this code, +with a table of FIP-entry types parsed from the arm-trusted-firmware source +directory''') +parser.add_argument( +'-D', '--debug', action='store_true', +help='Enabling debugging (provides a full traceback on error)') +parser.add_argument( +'-o', '--outfile', type=str, default='fip_util.py.out', +help='Out
[PATCH 0/2] binman: Add support for ATF Firmware Image Package (FIP)
This series adds support for the FIP format as used by ARM Trusted Firmware (in particular TF-A). This allows images to be created containing a FIP, which itself contains various binaries. With this, image creation can be handled from an in-tree image description instead of needing to perform a lot of manual steps or custom scripts to build the FIP. Simon Glass (2): binman: Add a utility module for ATF FIP binman: Add support for ATF FIP scripts/pylint.base | 9 +- tools/binman/entries.rst | 154 ++ tools/binman/etype/atf_fip.py| 273 ++ tools/binman/fip_util.py | 653 +++ tools/binman/fip_util_test.py| 405 ++ tools/binman/ftest.py| 217 tools/binman/main.py | 4 +- tools/binman/test/203_fip.dts| 21 + tools/binman/test/204_fip_other.dts | 22 + tools/binman/test/205_fip_no_type.dts| 15 + tools/binman/test/206_fip_uuid.dts | 22 + tools/binman/test/207_fip_ls.dts | 25 + tools/binman/test/208_fip_replace.dts| 33 ++ tools/binman/test/209_fip_missing.dts| 19 + tools/binman/test/210_fip_size.dts | 19 + tools/binman/test/211_fip_bad_align.dts | 18 + tools/binman/test/212_fip_collection.dts | 24 + 17 files changed, 1929 insertions(+), 4 deletions(-) create mode 100644 tools/binman/etype/atf_fip.py create mode 100755 tools/binman/fip_util.py create mode 100755 tools/binman/fip_util_test.py create mode 100644 tools/binman/test/203_fip.dts create mode 100644 tools/binman/test/204_fip_other.dts create mode 100644 tools/binman/test/205_fip_no_type.dts create mode 100644 tools/binman/test/206_fip_uuid.dts create mode 100644 tools/binman/test/207_fip_ls.dts create mode 100644 tools/binman/test/208_fip_replace.dts create mode 100644 tools/binman/test/209_fip_missing.dts create mode 100644 tools/binman/test/210_fip_size.dts create mode 100644 tools/binman/test/211_fip_bad_align.dts create mode 100644 tools/binman/test/212_fip_collection.dts -- 2.34.0.rc2.393.gf8c9666880-goog
Re: [PATCH v2] clk: fix clk_get_rate() documentation
On 2/13/21 9:17 PM, Giulio Benetti wrote: Improve clk_get_rate() @return documentation that otherwise is a bit ambiguous. At the moment I expect to return 0 as error since the return type is 'ulong', instead the function really returns negative value in case the corresponding function pointer is null and returns 0 if the clock is invalid. Signed-off-by: Giulio Benetti --- V1->V2: * previous comment was wrong, this function returns negative value, so let's improve it's @return documentation as suggested by Simon Glass --- include/clk.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/clk.h b/include/clk.h index ca6b85fa6f..5a8c7244d0 100644 --- a/include/clk.h +++ b/include/clk.h @@ -344,7 +344,8 @@ int clk_free(struct clk *clk); * * @clk: A clock struct that was previously successfully requested by *clk_request/get_by_*(). - * @return clock rate in Hz, or -ve error code. + * @return clock rate in Hz on success, 0 for invalid clock, or -ve error code + *for other errors. */ ulong clk_get_rate(struct clk *clk); Reviewed-by: Sean Anderson
Re: [BUG] efi_loader: incorrect creation of device paths
On Sat, Nov 20, 2021 at 01:54:30PM +0100, Heinrich Schuchardt wrote: > Hello Takahiro, > > in a prior mail we have discussed the creation of device paths for USB > mass storage devices. > > On the sand boxyou get the following devices after 'usb start': > > Class Index Probed DriverName > --- > usb 0 [ + ] usb_sandbox |-- usb@1 > usb_hub 0 [ + ] usb_hub | `-- hub > usb_mass_s0 [ + ] usb_mass_storage | |-- > usb_mass_storage > blk 3 [ ] usb_storage_blk | | `-- > usb_mass_storage.lun0 > usb_mass_s1 [ + ] usb_mass_storage | |-- > usb_mass_storage > blk 4 [ ] usb_storage_blk | | `-- > usb_mass_storage.lun0 > usb_mass_s2 [ + ] usb_mass_storage | `-- > usb_mass_storage > blk 5 [ ] usb_storage_blk | `-- > usb_mass_storage.lun0 > > For of these storage devices we try to create the same device path which > is not allowable: > > => usb start > starting USB... > Bus usb@1: scanning bus usb@1 for devices... 5 USB Device(s) found >scanning usb for storage devices... 3 Storage Device(s) found > => > => efidebug dh > Scanning disk mmc2.blk... > handle 15e34f00, > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(2)/SD(0) > Scanning disk mmc1.blk... > handle 15e36b30, > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(1)/SD(1) > Scanning disk mmc0.blk... > handle 15e35b00, > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/SD(0)/SD(2) > Scanning disk usb_mass_storage.lun0... > handle 15e35c10, > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x1234,0x5678,0x9,0x0,0x0)/UsbClass(0x1234,0x5678,0x0,0x0,0x0) > fs_devread read outside partition 2 > Failed to mount ext2 filesystem... > BTRFS: superblock end 69632 is larger than device size 512 > Scanning disk usb_mass_storage.lun0... > handle 15e361f0, > /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/UsbClass(0x1234,0x5678,0x9,0x0,0x0)/UsbClass(0x1234,0x5678,0x0,0x0,0x0) > ERROR: failure to add disk device usb_mass_storage.lun0, r = 20 > Error: Cannot initialize UEFI sub-system, r = 20 > > I will provide a patch that will allow the first USB device to be used > and avoids stopping the boot process. But we really have to walk the dm > tree to create a device patch for USB devices based on port IDs. > > We should add a new field to struct uclass_driver: > > struct efi_device_path *get_node(udevice *dev); > > This function shall return a pointer to an freshly allocated buffer with > the device node for the device. To build the devicepath we can then walk > the dm tree. I'm not sure this is an acceptable solution. Let me make sure: The goal would be to create a device path like .../USB(0x1,0x0)/HD(1,...) instead of .../UsbHub(0x0,0x0,0x0,0x3)/UsbMassStorage(0x46f4,0x1,0x0,0x0)/HD(1,...) as we already see this format for SCSI: .../Scsi(0,0)/HD(1,..) Right? -Takahiro Akashi > To make migration easier: If the function pointer or the return value is > NULL we can create a CTRL() node as dummy using the uclass_id and the > device number. > > Best regards > > Heinrich
Re: [PATCH 1/1] efi_loader: segfault in efi_clear_os_indications()
On Sat, Nov 20, 2021 at 12:02:25PM +0100, Heinrich Schuchardt wrote: > If we call efi_clear_os_indications() before initializing the memory store > for UEFI variables a NULL pointer dereference occurs. > > The error was observed on the sandbox with: > > usb start > host bind 0 sandbox.img > load host 0:1 $kernel_addr_r helloworld.efi > bootefi $kernel_addr_r > > Here efi_resister_disk() failed due to an error in the BTRFS implementation. > > It is enough to clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED > if we have successfully initialized the UEFI sub-system. I think that it would be better move this function into efi_launch_capsules() as we should defer to a responsible sub-component, capsule support in this case, on whether a particular bit should be cleared. -Takahiro Akashi > Fixes: 149108a3eb59 ("efi_loader: clear OsIndications") > Signed-off-by: Heinrich Schuchardt > --- > lib/efi_loader/efi_setup.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c > index a2338d74af..661868811f 100644 > --- a/lib/efi_loader/efi_setup.c > +++ b/lib/efi_loader/efi_setup.c > @@ -331,11 +331,10 @@ efi_status_t efi_init_obj_list(void) > if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && > !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) > ret = efi_launch_capsules(); > - > -out: > r = efi_clear_os_indications(); > if (ret == EFI_SUCCESS) > ret = r; > +out: > efi_obj_list_initialized = ret; > return ret; > } > -- > 2.32.0 >
Re: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults
On 11/22/21 10:02 PM, Peng Fan (OSS) wrote: Subject: Re: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults On Mon, Nov 22, 2021 at 11:33:27AM +0800, Peng Fan (OSS) wrote: + Rob On 2021/11/20 20:57, Tom Rini wrote: On Sat, Nov 20, 2021 at 12:10:54PM +, Peng Fan (OSS) wrote: Subject: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults From: Peng Fan Current code has a force clk_set_defaults in multiple stages, U-Boot reuse the same device tree and Linux Kernel device tree, but we not register all the clks as Linux Kernel, so clk_set_defaults will fail and cause the clk provider registeration fail. So introduce a new property to ignore the default settings which could be used by any node that wanna ignore default settings. Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- V2: Add R-b tag Tom, Simon After a thought, I think still put it as a u-boot thing. assigned-clock-x is actually Linux specific, however I could not add the new property to Linux, because we are supporting SystemReady-IR, we need the assigned-clock-x property in linux working and ignore it in U-Boot. Any more thoughts? Just my continued request that you treat this as generic and submit the binding upstream so it can be in the device tree for the platform. As Sean said, this is to serve cast that linux and U-Boot use the same device tree, I mean U-Boot runtime export device tree to linux for SR-IR (system-ready IR) booting. Linux needs assigned-clocks to some reason, but U-Boot not need that because the driver not added the support or not a must to have that. Because assigned-clocks failure in U-Boot will cause probe fail now, the device driver will report failure. You mean rename this to "ignore-clk-defaults" or keep "u-boot,ignore-clk-defauls" or "firmware,ignore-clk-defaults" to linux device tree binding? I could try to send to linux kernel with "firmware" as a prefix. What I mean is that first I'm not seeing the description of the property as being clear enough, either in commit message or the binding itself. That's why in my mind I keep seeing this as "we set the properties linux,assigned-clocks and u-boot,ignore-clk-defaults" and I don't know why we need both. Is there not something we can do based on seeing linux,assigned-clocks ? Showing something that makes use of the property you're wishing to add would be helpful. In fact, some specific dts snippets would be helpful to understand what's going on here. clk: clock-controller@3038 { compatible = "fsl,imx8mp-ccm"; reg = <0x3038 0x1>; #clock-cells = <1>; clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>, <&clk_ext3>, <&clk_ext4>; clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4"; assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>, <&clk IMX8MP_CLK_A53_CORE>, <&clk IMX8MP_CLK_NOC>, <&clk IMX8MP_CLK_NOC_IO>, <&clk IMX8MP_CLK_GIC>, <&clk IMX8MP_CLK_AUDIO_AHB>, <&clk IMX8MP_CLK_AUDIO_AXI_SRC>, <&clk IMX8MP_CLK_IPG_AUDIO_ROOT>, <&clk IMX8MP_AUDIO_PLL1>, <&clk IMX8MP_AUDIO_PLL2>; assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, <&clk IMX8MP_ARM_PLL_OUT>, <&clk IMX8MP_SYS_PLL2_1000M>, <&clk IMX8MP_SYS_PLL1_800M>, <&clk IMX8MP_SYS_PLL2_500M>, <&clk IMX8MP_SYS_PLL1_800M>, <&clk IMX8MP_SYS_PLL1_800M>; assigned-clock-rates = <0>, <0>, <10>, <8>, <5>, <4>, <8>, <4>, <393216000>, <361267200>; u-boot,ignore-clk-defaults; }; The above node is that I wanna have in U-Boot device tree. This node is same as the one used in linux device tree except the new property introduced here. In i.MX U-Boot, we not support the clks here in the clk driver, but linux needs the assigned-clocks property, so I could not delete it because U-Boot runtime export the device tree to Linux. So add a new property here for U-Boot specific usage, if the property is there, U-Boot ignore the assigned-clock settings for a node. I hope this is clear and please suggest what to do next. Hm. Well perhaps we can designate a specific return code to indicate that we have a valid clock ID but it is just unimplemented. So in your driver you would do ulong
Re: [PATCH] binman: Fix extract command for using non-absolute image paths
Hi Jan, On Thu, 11 Nov 2021 at 00:14, Jan Kiszka wrote: > > From: Jan Kiszka > > Otherwise the updated image will end up in the temporary folder that is > purged after completion. Reviewed-by: Simon Glass I'd like to add a test for this. Regards, Simon > > Signed-off-by: Jan Kiszka > --- > tools/binman/control.py | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/tools/binman/control.py b/tools/binman/control.py > index 8b5085152a..c112b404ab 100644 > --- a/tools/binman/control.py > +++ b/tools/binman/control.py > @@ -355,6 +355,7 @@ def ReplaceEntries(image_fname, input_fname, indir, > entry_paths, > Returns: > List of EntryInfo records that were written > """ > +image_fname = os.path.abspath(image_fname) > image = Image.FromFile(image_fname) > > # Replace an entry from a single file, as a special case > -- > 2.31.1
Re: [PATCH v3 1/5] reset: scmi: define LOG_CATEGORY
On Thu, Oct 28, 2021 at 07:13:12PM +0200, Patrick Delaunay wrote: > Define LOG_CATEGORY to allow filtering with log command. > > Signed-off-by: Patrick Delaunay > Acked-by: Etienne Carriere For the series, applied to u-boot/next, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH v2 1/5] tee: define session login identifiers
On Tue, Nov 09, 2021 at 05:08:20PM +0100, Etienne Carriere wrote: > Define identifiers for clnt_login field in struct tee_open_session_arg > based in GlobalPlatform Device TEE IDs and on the REE_KERNEL identifier > extension from OP-TEE OS. > > Cc: Jens Wiklander > Reviewed-by: Patrick Delaunay > Reviewed-by: Jens Wiklander > Signed-off-by: Etienne Carriere For the series, applied to u-boot/next, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH 1/5] firmware: scmi: fix description of an API function
On Mon, Nov 08, 2021 at 08:56:07AM +0100, Etienne Carriere wrote: > Correct inline comment describing API function devm_scmi_process_msg(). > > Signed-off-by: Etienne Carriere > Reviewed-by: Patrick Delaunay For the series, applied to u-boot/next, thanks! -- Tom signature.asc Description: PGP signature
Re: [PATCH v2 1/3] usb: f_mass_storage: Check bh->state in sleep_thread
On 10/28/21 3:40 PM, Sean Anderson wrote: On 7/22/21 2:38 PM, Sean Anderson wrote: Every caller of sleep_thread except one wraps it in a second loop which waits for a buffer head to be filled. Since sleep_thread is already (infinitely) looping, we can move this check down. Some parts of the code have been reorganized to better take advantage of this property and and be structured closer to their Linux counterparts. In addition, sleep_thread now returns -EINTR if we need to wake up, mirroring Linux. This takes advantage of the existing logic regarding sleep_thread, which typically returns immediately on error. With this change, any exception causes the current operation to be backed out of immediately. Lastly, we only clear thread_wakeup_needed in handle_exception, mirroring Linux's signal-handling logic. Any subsequent calls to sleep_thread will still wake up. While these changes are conceptually different, their implementation is interdependent, so they are all performed at once. These changes are primarily inspired by Linux commit 225785aec726 ("USB: f_mass_storage: improve memory barriers and synchronization"). Signed-off-by: Sean Anderson --- Changes in v2: - Fix some checkpatch lint - Make comment for sleep thread match loop condition drivers/usb/gadget/f_mass_storage.c | 228 drivers/usb/gadget/storage_common.c | 2 +- 2 files changed, 101 insertions(+), 129 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 45f0504b6e..6f39c24503 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -652,15 +652,17 @@ static void busy_indicator(void) state = 0; } -static int sleep_thread(struct fsg_common *common) +static int sleep_thread(struct fsg_common *common, struct fsg_buffhd *bh) { -intrc = 0; int i = 0, k = 0; -/* Wait until a signal arrives or we are woken up */ -for (;;) { -if (common->thread_wakeup_needed) -break; +/* + * Wait until a signal arrives, we are woken up, or the buffer is no + * longer busy. + */ +while (!bh || bh->state == BUF_STATE_BUSY) { +if (exception_in_progress(common)) +return -EINTR; if (++i == 2) { busy_indicator(); @@ -682,8 +684,7 @@ static int sleep_thread(struct fsg_common *common) usb_gadget_handle_interrupts(controller_index); } -common->thread_wakeup_needed = 0; -return rc; +return 0; } /*-*/ @@ -744,11 +745,9 @@ static int do_read(struct fsg_common *common) /* Wait for the next buffer to become available */ bh = common->next_buffhd_to_fill; -while (bh->state != BUF_STATE_EMPTY) { -rc = sleep_thread(common); -if (rc) -return rc; -} +rc = sleep_thread(common, bh); +if (rc) +return rc; /* If we were asked to read past the end of file, * end with an empty buffer. */ @@ -922,67 +921,63 @@ static int do_write(struct fsg_common *common) bh = common->next_buffhd_to_drain; if (bh->state == BUF_STATE_EMPTY && !get_some_more) break;/* We stopped early */ -if (bh->state == BUF_STATE_FULL) { -common->next_buffhd_to_drain = bh->next; -bh->state = BUF_STATE_EMPTY; -/* Did something go wrong with the transfer? */ -if (bh->outreq->status != 0) { -curlun->sense_data = SS_COMMUNICATION_FAILURE; -curlun->info_valid = 1; -break; -} +rc = sleep_thread(common, bh); +if (rc) +return rc; -amount = bh->outreq->actual; +common->next_buffhd_to_drain = bh->next; +bh->state = BUF_STATE_EMPTY; -/* Perform the write */ -rc = ums[common->lun].write_sector(&ums[common->lun], - file_offset / SECTOR_SIZE, - amount / SECTOR_SIZE, - (char __user *)bh->buf); -if (!rc) -return -EIO; -nwritten = rc * SECTOR_SIZE; - -VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, -(unsigned long long) file_offset, -(int) nwritten); - -if (nwritten < 0) { -LDBG(curlun, "error in file write: %d\n", -(int) nwritten); -nwritten = 0; -} else if (nwritten < amount) { -LDBG(curlun, "partial file write: %d/%u\n", -(int) nwritten, amount); -nwritten -= (nwritten & 511); -/* Round down to a block */ -} -file_offset += nwritten; -amount_left_to_write -= nwri
[PATCH v3 11/12] mmc: fsl_esdhc_imx: Replace more #ifdefs by if
This builds on the previous patch by converting yet more preprocessor macros to C ifs. This is split off so that the changes adapted from Micheal's patch may be clearly distinguished from the ones I have authored myself. MMC_SUPPORTS_TUNING should really get a Kconfig conversion. And DM_GPIO needs some -ENOSYS stubs when it isn't defined. Signed-off-by: Sean Anderson --- Changes in v3: - New drivers/mmc/fsl_esdhc_imx.c | 152 1 file changed, 69 insertions(+), 83 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 2da70663cb..25e912ba95 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -164,10 +164,8 @@ struct fsl_esdhc_priv { u32 strobe_dll_delay_target; u32 signal_voltage; u32 signal_voltage_switch_extra_delay_ms; -#if CONFIG_IS_ENABLED(DM_REGULATOR) struct udevice *vqmmc_dev; struct udevice *vmmc_dev; -#endif #if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; @@ -386,7 +384,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, return 0; } -#ifdef CONFIG_MCF5441x +#if IS_ENABLED(CONFIG_MCF5441x) /* * Swaps 32-bit words to little-endian byte order. */ @@ -455,14 +453,16 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, /* Send the command */ esdhc_write32(®s->cmdarg, cmd->cmdarg); -#if defined(CONFIG_FSL_USDHC) - esdhc_write32(®s->mixctrl, - (esdhc_read32(®s->mixctrl) & 0xFF80) | (xfertyp & 0x7F) - | (mmc->ddr_mode ? XFERTYP_DDREN : 0)); - esdhc_write32(®s->xfertyp, xfertyp & 0x); -#else - esdhc_write32(®s->xfertyp, xfertyp); -#endif + if IS_ENABLED(CONFIG_FSL_USDHC) { + u32 mixctrl = esdhc_read32(®s->mixctrl); + + esdhc_write32(®s->mixctrl, + (mixctrl & 0xFF80) | (xfertyp & 0x7F) + | (mmc->ddr_mode ? XFERTYP_DDREN : 0)); + esdhc_write32(®s->xfertyp, xfertyp & 0x); + } else { + esdhc_write32(®s->xfertyp, xfertyp); + } if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) || (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)) @@ -597,7 +597,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) uint clk; if (IS_ENABLED(ARCH_MXC)) { -#ifdef CONFIG_MX53 +#if IS_ENABLED(CONFIG_MX53) /* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */ pre_div = (regs == (struct fsl_esdhc *)MMC_SDHC3_BASE_ADDR) ? 2 : 1; #else @@ -758,26 +758,23 @@ static int esdhc_set_voltage(struct mmc *mmc) { struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev); struct fsl_esdhc *regs = priv->esdhc_regs; -#if CONFIG_IS_ENABLED(DM_REGULATOR) int ret; -#endif priv->signal_voltage = mmc->signal_voltage; switch (mmc->signal_voltage) { case MMC_SIGNAL_VOLTAGE_330: if (priv->vs18_enable) return -ENOTSUPP; -#if CONFIG_IS_ENABLED(DM_REGULATOR) - if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) { - ret = regulator_set_value(priv->vqmmc_dev, 330); + if (CONFIG_IS_ENABLED(DM_REGULATOR) && + !IS_ERR_OR_NULL(priv->vqmmc_dev)) { + ret = regulator_set_value(priv->vqmmc_dev, + 330); if (ret) { printf("Setting to 3.3V error"); return -EIO; } - /* Wait for 5ms */ mdelay(5); } -#endif esdhc_clrbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); if (!(esdhc_read32(®s->vendorspec) & @@ -786,15 +783,15 @@ static int esdhc_set_voltage(struct mmc *mmc) return -EAGAIN; case MMC_SIGNAL_VOLTAGE_180: -#if CONFIG_IS_ENABLED(DM_REGULATOR) - if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) { - ret = regulator_set_value(priv->vqmmc_dev, 180); + if (CONFIG_IS_ENABLED(DM_REGULATOR) && + !IS_ERR_OR_NULL(priv->vqmmc_dev)) { + ret = regulator_set_value(priv->vqmmc_dev, + 180); if (ret) { printf("Setting to 1.8V error"); return -EIO; } } -#endif esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT); /* * some board like imx8mm-evk need about 18ms to switch @@ -936,18 +933,16 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *p
[PATCH v3 12/12] mmc: fsl_esdhc_imx: set sysctl register for clock initialization
[ fsl_esdhc commit 263ddfc3454ead3a988adef39b962479adce2b28 ] The initial clock setting should be through sysctl register only, while the mmc_set_clock() will call mmc_set_ios() introduce other configurations like bus width, mode, and so on. Signed-off-by: Yangbo Lu Signed-off-by: Sean Anderson --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 25e912ba95..9299635f50 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -1020,7 +1020,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN); /* Set the initial clock speed */ - mmc_set_clock(mmc, 40, MMC_CLK_ENABLE); + set_sysctl(priv, mmc, 40); /* Disable the BRR and BWR bits in IRQSTAT */ esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR); -- 2.25.1
[PATCH v3 10/12] mmc: fsl_esdhc_imx: replace most #ifdefs by IS_ENABLED()
[ fsl_esdhc commit 52faec31827ec1a1837977e29c067424426634c5 ] Make the code cleaner and drop the old-style #ifdef constructs where it is possible. Signed-off-by: Michael Walle Signed-off-by: Sean Anderson --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 209 +--- include/fsl_esdhc_imx.h | 2 - 2 files changed, 100 insertions(+), 111 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 6c25a77c79..2da70663cb 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -182,15 +182,15 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) if (data) { xfertyp |= XFERTYP_DPSEL; -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - xfertyp |= XFERTYP_DMAEN; -#endif + if (!IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO) && + cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK && + cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200) + xfertyp |= XFERTYP_DMAEN; if (data->blocks > 1) { xfertyp |= XFERTYP_MSBSEL; xfertyp |= XFERTYP_BCEN; -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 - xfertyp |= XFERTYP_AC12EN; -#endif + if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC111)) + xfertyp |= XFERTYP_AC12EN; } if (data->flags & MMC_DATA_READ) @@ -214,7 +214,6 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) return XFERTYP_CMD(cmd->cmdidx) | xfertyp; } -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO /* * PIO Read/Write Mode reduce the performace as DMA is not used in this mode. */ @@ -277,9 +276,7 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv, } } } -#endif -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO static void esdhc_setup_watermark_level(struct fsl_esdhc_priv *priv, struct mmc_data *data) { @@ -299,7 +296,6 @@ static void esdhc_setup_watermark_level(struct fsl_esdhc_priv *priv, wml_value << 16); } } -#endif static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data) { @@ -342,11 +338,10 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, } } -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO - esdhc_setup_watermark_level(priv, data); -#else - esdhc_setup_dma(priv, data); -#endif + if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO)) + esdhc_setup_watermark_level(priv, data); + else + esdhc_setup_dma(priv, data); /* Calculate the timeout period for data transactions */ /* @@ -379,14 +374,13 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, if (timeout < 0) timeout = 0; -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001 - if ((timeout == 4) || (timeout == 8) || (timeout == 12)) + if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC_A001) && + (timeout == 4 || timeout == 8 || timeout == 12)) timeout++; -#endif -#ifdef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE - timeout = 0xE; -#endif + if (IS_ENABLED(ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE)) + timeout = 0xE; + esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16); return 0; @@ -409,6 +403,11 @@ static inline void sd_swap_dma_buff(struct mmc_data *data) } } } +#else +static inline void sd_swap_dma_buff(struct mmc_data *data) +{ + return; +} #endif /* @@ -425,10 +424,9 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, struct fsl_esdhc *regs = priv->esdhc_regs; unsigned long start; -#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111 - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + if (IS_ENABLED(CONFIG_SYS_FSL_ERRATUM_ESDHC111) && + cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) return 0; -#endif esdhc_write32(®s->irqstat, -1); @@ -526,42 +524,40 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, /* Wait until all of the blocks are transferred */ if (data) { -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO - esdhc_pio_read_write(priv, data); -#else - flags = DATA_COMPLETE; - if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) || - (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)) { - flags = IRQSTAT_BRR; + if (IS_ENABLED(CONFIG_SYS_FSL_ESDHC_USE_PIO)) { + esdhc_pio_read_write(priv, data); + } else { + flags = DATA_COMPLETE; + if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK || + cmd->
[PATCH v3 05/12] mmc: fsl_esdhc_imx: drop redundant code for non-removable feature
[ fsl_esdhc commit commit 08197cb8dff7cd097ab07a325093043c39d19bbd ] Drop redundant code for non-removable feature. "non-removable" property has been read in mmc_of_parse(). Signed-off-by: Yangbo Lu [ set MMC_CAP_NONREMOVABLE in plat->cfg.host_caps ] Signed-off-by: Sean Anderson --- Changes in v3: - Fix build error caused by unconverted OF_PLATDATA code drivers/mmc/fsl_esdhc_imx.c | 34 +- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 98b3db737b..4d2d757723 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -130,7 +130,6 @@ struct esdhc_soc_data { * @mmc: mmc * Following is used when Driver Model is enabled for MMC * @dev: pointer for the device - * @non_removable: 0: removable; 1: non-removable * @broken_cd: 0: use GPIO for card detect; 1: Do not use GPIO for card detect * @wp_enable: 1: enable checking wp; 0: no check * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V @@ -154,7 +153,6 @@ struct fsl_esdhc_priv { struct mmc *mmc; #endif struct udevice *dev; - int non_removable; int broken_cd; int wp_enable; int vs18_enable; @@ -1086,9 +1084,6 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) #endif #if CONFIG_IS_ENABLED(DM_MMC) - if (priv->non_removable) - return 1; - if (priv->broken_cd) return 1; #if CONFIG_IS_ENABLED(DM_GPIO) @@ -1419,25 +1414,18 @@ static int fsl_esdhc_of_to_plat(struct udevice *dev) if (dev_read_bool(dev, "broken-cd")) priv->broken_cd = 1; - if (dev_read_bool(dev, "non-removable")) { - priv->non_removable = 1; -} else { - priv->non_removable = 0; -#if CONFIG_IS_ENABLED(DM_GPIO) - gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, -GPIOD_IS_IN); -#endif - } - if (dev_read_prop(dev, "fsl,wp-controller", NULL)) { priv->wp_enable = 1; } else { priv->wp_enable = 0; + } + #if CONFIG_IS_ENABLED(DM_GPIO) - gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, - GPIOD_IS_IN); + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, +GPIOD_IS_IN); + gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, +GPIOD_IS_IN); #endif - } priv->vs18_enable = 0; @@ -1481,11 +1469,11 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->esdhc_regs = map_sysmem(dtplat->reg[0], dtplat->reg[1]); if (dtplat->non_removable) - priv->non_removable = 1; + plat->cfg.host_caps |= MMC_CAP_NONREMOVABLE; else - priv->non_removable = 0; + plat->cfg.host_caps &= ~MMC_CAP_NONREMOVABLE; - if (CONFIG_IS_ENABLED(DM_GPIO) && !priv->non_removable) { + if (CONFIG_IS_ENABLED(DM_GPIO) && !dtplat->non_removable) { struct udevice *gpiodev; ret = device_get_by_ofplat_idx(dtplat->cd_gpios->idx, &gpiodev); @@ -1571,8 +1559,12 @@ static int fsl_esdhc_probe(struct udevice *dev) static int fsl_esdhc_get_cd(struct udevice *dev) { + struct fsl_esdhc_plat *plat = dev_get_plat(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); + if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) + return 1; + return esdhc_getcd_common(priv); } -- 2.25.1
[PATCH v3 09/12] mmc: fsl_esdhc_imx: simplify esdhc_setup_data()
[ fsl_esdhc commit 7e48a028a42c111ba38a90b86e5f57dace980fa0 ] First, we need the waterlevel setting for PIO mode only. Secondy, both DMA setup code is identical for both directions, except for the data pointer. Thus, unify them. Signed-off-by: Michael Walle Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 89 ++--- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 283af35a81..6c25a77c79 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -279,59 +279,74 @@ static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv, } #endif -static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, - struct mmc_data *data) +#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO +static void esdhc_setup_watermark_level(struct fsl_esdhc_priv *priv, + struct mmc_data *data) { - int timeout; - uint trans_bytes = data->blocksize * data->blocks; struct fsl_esdhc *regs = priv->esdhc_regs; - uint wml_value; - - wml_value = data->blocksize/4; + uint wml_value = data->blocksize / 4; if (data->flags & MMC_DATA_READ) { if (wml_value > WML_RD_WML_MAX) wml_value = WML_RD_WML_MAX_VAL; esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - priv->dma_addr = dma_map_single(data->dest, trans_bytes, - mmc_get_dma_dir(data)); - if (upper_32_bits(priv->dma_addr)) - printf("Cannot use 64 bit addresses with SDMA\n"); - esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); -#endif } else { if (wml_value > WML_WR_WML_MAX) wml_value = WML_WR_WML_MAX_VAL; - if (priv->wp_enable) { - if ((esdhc_read32(®s->prsstat) & - PRSSTAT_WPSPL) == 0) { - printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); - return -ETIMEDOUT; - } - } else { -#if CONFIG_IS_ENABLED(DM_GPIO) - if (dm_gpio_is_valid(&priv->wp_gpio) && - dm_gpio_get_value(&priv->wp_gpio)) { - printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); - return -ETIMEDOUT; - } -#endif - } esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, - wml_value << 16); -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - priv->dma_addr = dma_map_single((void *)data->src, trans_bytes, - mmc_get_dma_dir(data)); - if (upper_32_bits(priv->dma_addr)) - printf("Cannot use 64 bit addresses with SDMA\n"); - esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); -#endif + wml_value << 16); } +} +#endif +static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data) +{ + uint trans_bytes = data->blocksize * data->blocks; + struct fsl_esdhc *regs = priv->esdhc_regs; + void *buf; + + if (data->flags & MMC_DATA_WRITE) + buf = (void *)data->src; + else + buf = data->dest; + + priv->dma_addr = dma_map_single(buf, trans_bytes, + mmc_get_dma_dir(data)); + if (upper_32_bits(priv->dma_addr)) + printf("Cannot use 64 bit addresses with SDMA\n"); + esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize); +} + +static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, + struct mmc_data *data) +{ + int timeout; + bool is_write = data->flags & MMC_DATA_WRITE; + struct fsl_esdhc *regs = priv->esdhc_regs; + + if (is_write) { + if (priv->wp_enable && !(esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL)) { + printf("Cannot write to locked SD card.\n"); + return -EINVAL; + } else { +#if CONFIG_IS_ENABLED(DM_GPIO) + if (dm_gpio_is_valid(&priv->wp_gpio) && + dm_gpio_get_value(&priv->wp_gpio)) { + printf("Cannot write to locked SD card.\n"); + return -EINVAL; + } +#endif + } + } + +#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO + esdhc_setup_watermark_level(priv, data
[PATCH v3 06/12] mmc: fsl_esdhc_imx: fix mmc->clock with actual clock
[ fsl_esdhc commit 30f6444d024a74ee48aa6969c1531aecd3c59deb ] Fix mmc->clock with actual clock which is divided by the controller, and record it with priv->clock. Signed-off-by: Yangbo Lu Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 4d2d757723..72f3eec205 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -665,6 +665,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); #endif + mmc->clock = sdhc_clk / pre_div / div; priv->clock = clock; } -- 2.25.1
[PATCH v3 07/12] mmc: fsl_esdhc_imx: simplify 64bit check for SDMA transfers
[ fsl_esdhc commit da86e8cfcb03ed5c1d8e0718bc8bc8583e60ced8 ] SDMA can only do DMA with 32 bit addresses. This is true for all architectures (just doesn't apply to 32 bit ones). Simplify the code and remove unnecessary CONFIG_FSL_LAYERSCAPE. Also make the error message more concise. Signed-off-by: Michael Walle Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 33 ++--- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 72f3eec205..84df131c9f 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -282,10 +282,7 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, { int timeout; struct fsl_esdhc *regs = priv->esdhc_regs; -#if defined(CONFIG_S32V234) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) || \ - defined(CONFIG_IMX8ULP) dma_addr_t addr; -#endif uint wml_value; wml_value = data->blocksize/4; @@ -296,16 +293,10 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO -#if defined(CONFIG_S32V234) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) || \ - defined(CONFIG_IMX8ULP) addr = virt_to_phys((void *)(data->dest)); if (upper_32_bits(addr)) - printf("Error found for upper 32 bits\n"); - else - esdhc_write32(®s->dsaddr, lower_32_bits(addr)); -#else - esdhc_write32(®s->dsaddr, (u32)data->dest); -#endif + printf("Cannot use 64 bit addresses with SDMA\n"); + esdhc_write32(®s->dsaddr, lower_32_bits(addr)); #endif } else { #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO @@ -334,16 +325,10 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, wml_value << 16); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO -#if defined(CONFIG_S32V234) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) || \ - defined(CONFIG_IMX8ULP) addr = virt_to_phys((void *)(data->src)); if (upper_32_bits(addr)) - printf("Error found for upper 32 bits\n"); - else - esdhc_write32(®s->dsaddr, lower_32_bits(addr)); -#else - esdhc_write32(®s->dsaddr, (u32)data->src); -#endif + printf("Cannot use 64 bit addresses with SDMA\n"); + esdhc_write32(®s->dsaddr, lower_32_bits(addr)); #endif } @@ -400,18 +385,12 @@ static void check_and_invalidate_dcache_range unsigned end = 0; unsigned size = roundup(ARCH_DMA_MINALIGN, data->blocks*data->blocksize); -#if defined(CONFIG_S32V234) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) || \ - defined(CONFIG_IMX8ULP) dma_addr_t addr; addr = virt_to_phys((void *)(data->dest)); if (upper_32_bits(addr)) - printf("Error found for upper 32 bits\n"); - else - start = lower_32_bits(addr); -#else - start = (unsigned)data->dest; -#endif + printf("Cannot use 64 bit addresses with SDMA\n"); + start = lower_32_bits(addr); end = start + size; invalidate_dcache_range(start, end); } -- 2.25.1
[PATCH v3 08/12] mmc: fsl_esdhc_imx: use dma-mapping API
[ fsl_esdhc commit b1ba1460a445bcc67972a617625d0349e4f22b31 ] Use the dma_{map,unmap}_single() calls. These will take care of the flushing and invalidation of caches. Signed-off-by: Michael Walle Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 50 +++-- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 84df131c9f..283af35a81 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -38,6 +38,7 @@ #include #include #include +#include #ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE #ifdef CONFIG_FSL_USDHC @@ -171,6 +172,7 @@ struct fsl_esdhc_priv { struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; #endif + dma_addr_t dma_addr; }; /* Return the XFERTYP flags for a given command and data packet */ @@ -281,8 +283,8 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, struct mmc_data *data) { int timeout; + uint trans_bytes = data->blocksize * data->blocks; struct fsl_esdhc *regs = priv->esdhc_regs; - dma_addr_t addr; uint wml_value; wml_value = data->blocksize/4; @@ -293,17 +295,13 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - addr = virt_to_phys((void *)(data->dest)); - if (upper_32_bits(addr)) + priv->dma_addr = dma_map_single(data->dest, trans_bytes, + mmc_get_dma_dir(data)); + if (upper_32_bits(priv->dma_addr)) printf("Cannot use 64 bit addresses with SDMA\n"); - esdhc_write32(®s->dsaddr, lower_32_bits(addr)); + esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); #endif } else { -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - flush_dcache_range((ulong)data->src, - (ulong)data->src+data->blocks -*data->blocksize); -#endif if (wml_value > WML_WR_WML_MAX) wml_value = WML_WR_WML_MAX_VAL; if (priv->wp_enable) { @@ -325,10 +323,11 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, wml_value << 16); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO - addr = virt_to_phys((void *)(data->src)); - if (upper_32_bits(addr)) + priv->dma_addr = dma_map_single((void *)data->src, trans_bytes, + mmc_get_dma_dir(data)); + if (upper_32_bits(priv->dma_addr)) printf("Cannot use 64 bit addresses with SDMA\n"); - esdhc_write32(®s->dsaddr, lower_32_bits(addr)); + esdhc_write32(®s->dsaddr, lower_32_bits(priv->dma_addr)); #endif } @@ -378,23 +377,6 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, return 0; } -static void check_and_invalidate_dcache_range - (struct mmc_cmd *cmd, -struct mmc_data *data) { - unsigned start = 0; - unsigned end = 0; - unsigned size = roundup(ARCH_DMA_MINALIGN, - data->blocks*data->blocksize); - dma_addr_t addr; - - addr = virt_to_phys((void *)(data->dest)); - if (upper_32_bits(addr)) - printf("Cannot use 64 bit addresses with SDMA\n"); - start = lower_32_bits(addr); - end = start + size; - invalidate_dcache_range(start, end); -} - #ifdef CONFIG_MCF5441x /* * Swaps 32-bit words to little-endian byte order. @@ -450,9 +432,6 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, err = esdhc_setup_data(priv, mmc, data); if(err) return err; - - if (data->flags & MMC_DATA_READ) - check_and_invalidate_dcache_range(cmd, data); } /* Figure out the transfer arguments */ @@ -560,12 +539,13 @@ static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc, * cache-fill during the DMA operations such as the * speculative pre-fetching etc. */ - if (data->flags & MMC_DATA_READ) { - check_and_invalidate_dcache_range(cmd, data); + dma_unmap_single(priv->dma_addr, +data->blocks * data->blocksize, +mmc_get_dma_dir(data)); #ifdef CONFIG_MCF5441x + if (data->flags & MMC_DATA_READ)
[PATCH v3 04/12] mmc: fsl_esdhc_imx: clean up bus width configuration code
[ fsl_esdhc commit 07bae1de382723b94244096953b05225572728cd ] This patch is to clean up bus width setting code. - For DM_MMC, remove getting "bus-width" from device tree. This has been done in mmc_of_parse(). - For non-DM_MMC, move bus width configuration from fsl_esdhc_init() to fsl_esdhc_initialize() which is non-DM_MMC specific. And fix up bus width configuration to support only 1-bit, 4-bit, or 8-bit. Keep using 8-bit if it's not set because many platforms use driver without providing max bus width. - Remove bus_width member from fsl_esdhc_priv structure. Signed-off-by: Yangbo Lu [ converted if statement to switch ] Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v2) Changes in v2: - Use a switch statement instead of ifs for max_bus_width - Only default to 8 bit width when max_bus_width is not set drivers/mmc/fsl_esdhc_imx.c | 83 - 1 file changed, 26 insertions(+), 57 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index f4ccb19d9f..98b3db737b 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -126,7 +126,6 @@ struct esdhc_soc_data { * * @esdhc_regs: registers of the sdhc controller * @sdhc_clk: Current clk of the sdhc controller - * @bus_width: bus width, 1bit, 4bit or 8bit * @cfg: mmc config * @mmc: mmc * Following is used when Driver Model is enabled for MMC @@ -151,7 +150,6 @@ struct fsl_esdhc_priv { struct clk per_clk; unsigned int clock; unsigned int mode; - unsigned int bus_width; #if !CONFIG_IS_ENABLED(DM_MMC) struct mmc *mmc; #endif @@ -1235,31 +1233,13 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, #if !CONFIG_IS_ENABLED(DM_MMC) cfg->ops = &esdhc_ops; #endif - if (priv->bus_width == 8) - cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; - else if (priv->bus_width == 4) - cfg->host_caps = MMC_MODE_4BIT; - - cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; #ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE cfg->host_caps |= MMC_MODE_DDR_52MHz; #endif - if (priv->bus_width > 0) { - if (priv->bus_width < 8) - cfg->host_caps &= ~MMC_MODE_8BIT; - if (priv->bus_width < 4) - cfg->host_caps &= ~MMC_MODE_4BIT; - } - if (caps & HOSTCAPBLT_HSS) cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; -#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK - if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) - cfg->host_caps &= ~MMC_MODE_8BIT; -#endif - cfg->host_caps |= priv->caps; cfg->f_min = 40; @@ -1297,25 +1277,11 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, } #if !CONFIG_IS_ENABLED(DM_MMC) -static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, -struct fsl_esdhc_priv *priv) -{ - if (!cfg || !priv) - return -EINVAL; - - priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base); - priv->bus_width = cfg->max_bus_width; - priv->sdhc_clk = cfg->sdhc_clk; - priv->wp_enable = cfg->wp_enable; - priv->vs18_enable = cfg->vs18_enable; - - return 0; -}; - int fsl_esdhc_initialize(struct bd_info *bis, struct fsl_esdhc_cfg *cfg) { struct fsl_esdhc_plat *plat; struct fsl_esdhc_priv *priv; + struct mmc_config *mmc_cfg; struct mmc *mmc; int ret; @@ -1331,14 +1297,33 @@ int fsl_esdhc_initialize(struct bd_info *bis, struct fsl_esdhc_cfg *cfg) return -ENOMEM; } - ret = fsl_esdhc_cfg_to_priv(cfg, priv); - if (ret) { - debug("%s xlate failure\n", __func__); - free(plat); - free(priv); - return ret; + priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base); + priv->sdhc_clk = cfg->sdhc_clk; + priv->wp_enable = cfg->wp_enable; + + mmc_cfg = &plat->cfg; + + switch (cfg->max_bus_width) { + case 0: /* Not set in config; assume everything is supported */ + case 8: + mmc_cfg->host_caps |= MMC_MODE_8BIT; + fallthrough; + case 4: + mmc_cfg->host_caps |= MMC_MODE_4BIT; + fallthrough; + case 1: + mmc_cfg->host_caps |= MMC_MODE_1BIT; + break; + default: + printf("invalid max bus width %u\n", cfg->max_bus_width); + return -EINVAL; } +#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK + if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) + mmc_cfg->host_caps &= ~MMC_MODE_8BIT; +#endif + ret = fsl_esdhc_init(priv, plat); if (ret) { debug("%s init failure\n", __func__); @@ -1420,14 +1405,6 @@ static int fsl_esdhc_of_to_plat(struct udevice *dev) priv->dev = dev; p
[PATCH v3 03/12] mmc: fsl_esdhc_imx: fix voltage validation
[ fsl_esdhc commit 5b05fc0310cd933acf76ee661577c6b07a95e684 ] Voltage validation should be done by CMD8. Current comparison between mmc_cfg voltages and host voltage capabilities is meaningless. So drop current comparison and let voltage validation is through CMD8. Signed-off-by: Yangbo Lu Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 35 +-- include/fsl_esdhc_imx.h | 12 ++-- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 121f9182f6..f4ccb19d9f 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -1167,7 +1167,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, { struct mmc_config *cfg; struct fsl_esdhc *regs; - u32 caps, voltage_caps; + u32 caps; int ret; if (!priv) @@ -1206,9 +1206,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, memset(cfg, '\0', sizeof(*cfg)); #endif - voltage_caps = 0; caps = esdhc_read32(®s->hostcapblt); - #ifdef CONFIG_MCF5441x /* * MCF5441x RM declares in more points that sdhc clock speed must @@ -1219,31 +1217,24 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, #endif #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135 - caps = caps & ~(ESDHC_HOSTCAPBLT_SRS | - ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30); + caps &= ~(HOSTCAPBLT_SRS | HOSTCAPBLT_VS18 | HOSTCAPBLT_VS30); #endif - if (caps & ESDHC_HOSTCAPBLT_VS18) - voltage_caps |= MMC_VDD_165_195; - if (caps & ESDHC_HOSTCAPBLT_VS30) - voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31; - if (caps & ESDHC_HOSTCAPBLT_VS33) - voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; +#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33 + caps |= HOSTCAPBLT_VS33; +#endif + + if (caps & HOSTCAPBLT_VS18) + cfg->voltages |= MMC_VDD_165_195; + if (caps & HOSTCAPBLT_VS30) + cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; + if (caps & HOSTCAPBLT_VS33) + cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; cfg->name = "FSL_SDHC"; #if !CONFIG_IS_ENABLED(DM_MMC) cfg->ops = &esdhc_ops; #endif -#ifdef CONFIG_SYS_SD_VOLTAGE - cfg->voltages = CONFIG_SYS_SD_VOLTAGE; -#else - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; -#endif - if ((cfg->voltages & voltage_caps) == 0) { - printf("voltage not supported by controller\n"); - return -1; - } - if (priv->bus_width == 8) cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; else if (priv->bus_width == 4) @@ -1261,7 +1252,7 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, cfg->host_caps &= ~MMC_MODE_4BIT; } - if (caps & ESDHC_HOSTCAPBLT_HSS) + if (caps & HOSTCAPBLT_HSS) cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; #ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK diff --git a/include/fsl_esdhc_imx.h b/include/fsl_esdhc_imx.h index 12e9163382..4ae932858e 100644 --- a/include/fsl_esdhc_imx.h +++ b/include/fsl_esdhc_imx.h @@ -164,12 +164,12 @@ #define BLKATTR_SIZE(x)(x & 0x1fff) #define MAX_BLK_CNT0x7fff /* so malloc will have enough room with 32M */ -#define ESDHC_HOSTCAPBLT_VS18 0x0400 -#define ESDHC_HOSTCAPBLT_VS30 0x0200 -#define ESDHC_HOSTCAPBLT_VS33 0x0100 -#define ESDHC_HOSTCAPBLT_SRS 0x0080 -#define ESDHC_HOSTCAPBLT_DMAS 0x0040 -#define ESDHC_HOSTCAPBLT_HSS 0x0020 +#define HOSTCAPBLT_VS180x0400 +#define HOSTCAPBLT_VS300x0200 +#define HOSTCAPBLT_VS330x0100 +#define HOSTCAPBLT_SRS 0x0080 +#define HOSTCAPBLT_DMAS0x0040 +#define HOSTCAPBLT_HSS 0x0020 #define ESDHC_VENDORSPEC_VSELECT 0x0002 /* Use 1.8V */ -- 2.25.1
[PATCH v3 02/12] mmc: fsl_esdhc_imx: remove redundant DM_MMC checking
[ fsl_esdhc commit 2913926f3b3dec282f8773e3c02377c9600d8267 ] Remove redundant DM_MMC checking which is already in DM_MMC conditional compile block. Signed-off-by: Yangbo Lu Signed-off-by: Sean Anderson Reviewed-by: Jaehoon Chung --- (no changes since v1) drivers/mmc/fsl_esdhc_imx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 85cd72a796..121f9182f6 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -1609,7 +1609,6 @@ static int fsl_esdhc_probe(struct udevice *dev) return esdhc_init_common(priv, mmc); } -#if CONFIG_IS_ENABLED(DM_MMC) static int fsl_esdhc_get_cd(struct udevice *dev) { struct fsl_esdhc_priv *priv = dev_get_priv(dev); @@ -1675,7 +1674,6 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { #endif .wait_dat0 = fsl_esdhc_wait_dat0, }; -#endif static struct esdhc_soc_data usdhc_imx7d_data = { .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING -- 2.25.1
[PATCH v3 01/12] mmc: fsl_esdhc_imx: make BLK as hard requirement of DM_MMC
[ fsl_esdhc commit 41dec2fe99512e941261594f522b2e7d485c314b ] U-boot prefers DM_MMC + BLK for MMC. Now eSDHC driver has already support it, so let's force to use it. - Drop non-BLK support for DM_MMC introduced by below patch. 66fa035 mmc: fsl_esdhc: fix probe issue without CONFIG_BLK enabled - Support only DM_MMC + BLK (assuming BLK is always enabled for DM_MMC). - Use DM_MMC instead of BLK for conditional compile. Signed-off-by: Yangbo Lu Signed-off-by: Sean Anderson --- Changes in v3: - Drop Kconfig BLK dependency drivers/mmc/fsl_esdhc_imx.c | 33 + 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 4c06361bee..85cd72a796 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -39,10 +39,6 @@ #include #include -#if !CONFIG_IS_ENABLED(BLK) -#include "mmc_private.h" -#endif - #ifndef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE #ifdef CONFIG_FSL_USDHC #define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE 1 @@ -58,7 +54,6 @@ DECLARE_GLOBAL_DATA_PTR; IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \ IRQSTATEN_DINT) #define MAX_TUNING_LOOP 40 -#define ESDHC_DRIVER_STAGE_VALUE 0x struct fsl_esdhc { uintdsaddr; /* SDMA system address register */ @@ -157,7 +152,7 @@ struct fsl_esdhc_priv { unsigned int clock; unsigned int mode; unsigned int bus_width; -#if !CONFIG_IS_ENABLED(BLK) +#if !CONFIG_IS_ENABLED(DM_MMC) struct mmc *mmc; #endif struct udevice *dev; @@ -1510,9 +1505,6 @@ static int fsl_esdhc_probe(struct udevice *dev) struct esdhc_soc_data *data = (struct esdhc_soc_data *)dev_get_driver_data(dev); struct mmc *mmc; -#if !CONFIG_IS_ENABLED(BLK) - struct blk_desc *bdesc; -#endif int ret; #if CONFIG_IS_ENABLED(OF_PLATDATA) @@ -1611,25 +1603,6 @@ static int fsl_esdhc_probe(struct udevice *dev) mmc = &plat->mmc; mmc->cfg = &plat->cfg; mmc->dev = dev; -#if !CONFIG_IS_ENABLED(BLK) - mmc->priv = priv; - - /* Setup dsr related values */ - mmc->dsr_imp = 0; - mmc->dsr = ESDHC_DRIVER_STAGE_VALUE; - /* Setup the universal parts of the block interface just once */ - bdesc = mmc_get_blk_desc(mmc); - bdesc->if_type = IF_TYPE_MMC; - bdesc->removable = 1; - bdesc->devnum = mmc_get_next_devnum(); - bdesc->block_read = mmc_bread; - bdesc->block_write = mmc_bwrite; - bdesc->block_erase = mmc_berase; - - /* setup initial part type */ - bdesc->part_type = mmc->cfg->part_type; - mmc_list_add(mmc); -#endif upriv->mmc = mmc; @@ -1740,14 +1713,12 @@ static const struct udevice_id fsl_esdhc_ids[] = { { /* sentinel */ } }; -#if CONFIG_IS_ENABLED(BLK) static int fsl_esdhc_bind(struct udevice *dev) { struct fsl_esdhc_plat *plat = dev_get_plat(dev); return mmc_bind(dev, &plat->mmc, &plat->cfg); } -#endif U_BOOT_DRIVER(fsl_esdhc) = { .name = "fsl_esdhc", @@ -1755,9 +1726,7 @@ U_BOOT_DRIVER(fsl_esdhc) = { .of_match = fsl_esdhc_ids, .of_to_plat = fsl_esdhc_of_to_plat, .ops= &fsl_esdhc_ops, -#if CONFIG_IS_ENABLED(BLK) .bind = fsl_esdhc_bind, -#endif .probe = fsl_esdhc_probe, .plat_auto = sizeof(struct fsl_esdhc_plat), .priv_auto = sizeof(struct fsl_esdhc_priv), -- 2.25.1
[PATCH v3 00/12] fsl_esdhc_imx: port several patches from fsl_esdhc
This series ports some of the patches from fsl_esdhc to fsl_esdhc_imx. Because these drivers share a common lineage, many of these patches apply with minor changes. For each one, I have noted the originating commit in the style of linux stable backports. Where I have had to modify patches, I have noted the changes I have made before my SoB. In fa33d20749 ("mmc: split fsl_esdhc driver for i.MX"), Yangbo says > For the two series processors, the eSDHCs are becoming more and more > different However, these drivers are still extremely similar; the differences between them are not major. NXP has not done a good job of porting patches which apply to both drivers. This causes the fsl_esdhc_imx driver to rot, as the fsl_esdhc gets more general fixes. For this reason, I think that the fsl_esdhc_imx driver should be removed unless NXP can commit to creating series like this which port patches which apply to both drivers. Changes in v3: - Drop Kconfig BLK dependency - Fix build error caused by unconverted OF_PLATDATA code - Replace more #ifdefs by if Changes in v2: - Use a switch statement instead of ifs for max_bus_width - Only default to 8 bit width when max_bus_width is not set Sean Anderson (12): mmc: fsl_esdhc_imx: make BLK as hard requirement of DM_MMC mmc: fsl_esdhc_imx: remove redundant DM_MMC checking mmc: fsl_esdhc_imx: fix voltage validation mmc: fsl_esdhc_imx: clean up bus width configuration code mmc: fsl_esdhc_imx: drop redundant code for non-removable feature mmc: fsl_esdhc_imx: fix mmc->clock with actual clock mmc: fsl_esdhc_imx: simplify 64bit check for SDMA transfers mmc: fsl_esdhc_imx: use dma-mapping API mmc: fsl_esdhc_imx: simplify esdhc_setup_data() mmc: fsl_esdhc_imx: replace most #ifdefs by IS_ENABLED() mmc: fsl_esdhc_imx: Replace more #ifdefs by if mmc: fsl_esdhc_imx: set sysctl register for clock initialization drivers/mmc/fsl_esdhc_imx.c | 643 ++-- include/fsl_esdhc_imx.h | 14 +- 2 files changed, 263 insertions(+), 394 deletions(-) -- 2.25.1
Re: [PATCH] tools/mxsimage: Remove fclose on empty FILE pointer
Hi Mattias, On Tue, Nov 23, 2021 at 4:10 PM Mattias Hansson wrote: > > If `sb_load_cmdfile()` fails to open the configuration file it will jump > to error handling where the code will try to `fclose()` the FILE pointer > which is NULL causing `mkimage` to segfault. > > This patch removes the `fclose()` since `fopen()` always returns NULL > instead of the file descriptor when failing. You missed your Signed-off-line tag.
[PATCH] board: ast2500/ast2600: initialize LEDs
Add option to initialize LEDs in board_init stage for aspeed-based boards. Signed-off-by: Andrei Kartashev --- board/aspeed/evb_ast2500/evb_ast2500.c | 8 board/aspeed/evb_ast2600/evb_ast2600.c | 8 2 files changed, 16 insertions(+) diff --git a/board/aspeed/evb_ast2500/evb_ast2500.c b/board/aspeed/evb_ast2500/evb_ast2500.c index ed162c4095..9612513bfc 100644 --- a/board/aspeed/evb_ast2500/evb_ast2500.c +++ b/board/aspeed/evb_ast2500/evb_ast2500.c @@ -3,3 +3,11 @@ * Copyright (c) 2016 Google, Inc */ #include + +int board_init(void) +{ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c index e6dc8c7952..9041798896 100644 --- a/board/aspeed/evb_ast2600/evb_ast2600.c +++ b/board/aspeed/evb_ast2600/evb_ast2600.c @@ -3,3 +3,11 @@ * Copyright (c) Aspeed Technology Inc. */ #include + +int board_init(void) +{ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} -- 2.32.0
[PATCH] tools/mxsimage: Remove fclose on empty FILE pointer
If `sb_load_cmdfile()` fails to open the configuration file it will jump to error handling where the code will try to `fclose()` the FILE pointer which is NULL causing `mkimage` to segfault. This patch removes the `fclose()` since `fopen()` always returns NULL instead of the file descriptor when failing. --- tools/mxsimage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/mxsimage.c b/tools/mxsimage.c index 002f4b525a..c7bd86ce52 100644 --- a/tools/mxsimage.c +++ b/tools/mxsimage.c @@ -1618,7 +1618,6 @@ static int sb_load_cmdfile(struct sb_image_ctx *ictx) return 0; err_file: - fclose(fp); fprintf(stderr, "ERR: Failed to load file \"%s\"\n", ictx->cfg_filename); return -EINVAL; -- 2.27.0
[PATCH 15/17] binman: cbfs: Refactor the init process
Update the constructor to work in the recommended way, where the node properties are read in a separate function. This makes it more similar to entry_Section. Signed-off-by: Simon Glass --- tools/binman/etype/cbfs.py | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 873b199a91d..a5120127059 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -168,12 +168,16 @@ class Entry_cbfs(Entry): from binman import state super().__init__(section, etype, node) -self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') self.align_default = None self._entries = OrderedDict() -self.ReadEntries() self.reader = None +def ReadNode(self): +"""Read properties from the atf-fip node""" +super().ReadNode() +self._cbfs_arg = fdt_util.GetString(self._node, 'cbfs-arch', 'x86') +self.ReadEntries() + def ReadEntries(self): """Read the subnodes to find out what should go in this CBFS""" for node in self._node.subnodes: -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 14/17] binman: Use normal entries in cbfs
This currently uses _cbfs_entries[] to store entries. Since the entries are in fact valid etypes, we may as well use the same name as entry_Section uses, which is _entries. This allows reusing more of the code there (in a future patch). Signed-off-by: Simon Glass --- tools/binman/etype/cbfs.py | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 9e04897d71e..873b199a91d 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -170,7 +170,7 @@ class Entry_cbfs(Entry): super().__init__(section, etype, node) self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') self.align_default = None -self._cbfs_entries = OrderedDict() +self._entries = OrderedDict() self.ReadEntries() self.reader = None @@ -187,7 +187,7 @@ class Entry_cbfs(Entry): if entry._cbfs_compress is None: self.Raise("Invalid compression in '%s': '%s'" % (node.name, compress)) -self._cbfs_entries[entry._cbfs_name] = entry +self._entries[entry._cbfs_name] = entry def ObtainContents(self, skip=None): arch = cbfs_util.find_arch(self._cbfs_arg) @@ -196,7 +196,7 @@ class Entry_cbfs(Entry): if self.size is None: self.Raise("'cbfs' entry must have a size property") cbfs = CbfsWriter(self.size, arch) -for entry in self._cbfs_entries.values(): +for entry in self._entries.values(): # First get the input data and put it in a file. If not available, # try later. if entry != skip and not entry.ObtainContents(): @@ -230,7 +230,7 @@ class Entry_cbfs(Entry): super().SetImagePos(image_pos) # Now update the entries with info from the CBFS entries -for entry in self._cbfs_entries.values(): +for entry in self._entries.values(): cfile = entry._cbfs_file entry.size = cfile.data_len entry.offset = cfile.calced_cbfs_offset @@ -240,7 +240,7 @@ class Entry_cbfs(Entry): def AddMissingProperties(self, have_image_pos): super().AddMissingProperties(have_image_pos) -for entry in self._cbfs_entries.values(): +for entry in self._entries.values(): entry.AddMissingProperties(have_image_pos) if entry._cbfs_compress: state.AddZeroProp(entry._node, 'uncomp-size') @@ -252,7 +252,7 @@ class Entry_cbfs(Entry): def SetCalculatedProperties(self): """Set the value of device-tree properties calculated by binman""" super().SetCalculatedProperties() -for entry in self._cbfs_entries.values(): +for entry in self._entries.values(): state.SetInt(entry._node, 'offset', entry.offset) state.SetInt(entry._node, 'size', entry.size) state.SetInt(entry._node, 'image-pos', entry.image_pos) @@ -262,11 +262,11 @@ class Entry_cbfs(Entry): def ListEntries(self, entries, indent): """Override this method to list all files in the section""" super().ListEntries(entries, indent) -for entry in self._cbfs_entries.values(): +for entry in self._entries.values(): entry.ListEntries(entries, indent + 1) def GetEntries(self): -return self._cbfs_entries +return self._entries def ReadData(self, decomp=True): data = super().ReadData(True) -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 13/17] binman: Move cbfs.ObtainContents() down a bit
It is easier to understand this file if reading the entries comes before obtaining the contents, since that is the order in which Binman proceeds. Move the function down a bit. Signed-off-by: Simon Glass --- tools/binman/etype/cbfs.py | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 0a858b8b849..9e04897d71e 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -174,6 +174,21 @@ class Entry_cbfs(Entry): self.ReadEntries() self.reader = None +def ReadEntries(self): +"""Read the subnodes to find out what should go in this CBFS""" +for node in self._node.subnodes: +entry = Entry.Create(self, node) +entry.ReadNode() +entry._cbfs_name = fdt_util.GetString(node, 'cbfs-name', entry.name) +entry._type = fdt_util.GetString(node, 'cbfs-type') +compress = fdt_util.GetString(node, 'cbfs-compress', 'none') +entry._cbfs_offset = fdt_util.GetInt(node, 'cbfs-offset') +entry._cbfs_compress = cbfs_util.find_compress(compress) +if entry._cbfs_compress is None: +self.Raise("Invalid compression in '%s': '%s'" % + (node.name, compress)) +self._cbfs_entries[entry._cbfs_name] = entry + def ObtainContents(self, skip=None): arch = cbfs_util.find_arch(self._cbfs_arg) if arch is None: @@ -204,21 +219,6 @@ class Entry_cbfs(Entry): self.SetContents(data) return True -def ReadEntries(self): -"""Read the subnodes to find out what should go in this CBFS""" -for node in self._node.subnodes: -entry = Entry.Create(self, node) -entry.ReadNode() -entry._cbfs_name = fdt_util.GetString(node, 'cbfs-name', entry.name) -entry._type = fdt_util.GetString(node, 'cbfs-type') -compress = fdt_util.GetString(node, 'cbfs-compress', 'none') -entry._cbfs_offset = fdt_util.GetInt(node, 'cbfs-offset') -entry._cbfs_compress = cbfs_util.find_compress(compress) -if entry._cbfs_compress is None: -self.Raise("Invalid compression in '%s': '%s'" % - (node.name, compress)) -self._cbfs_entries[entry._cbfs_name] = entry - def SetImagePos(self, image_pos): """Override this function to set all the entry properties from CBFS -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 17/17] binman: Rename testCbfsNoCOntents()
Use a lower-case O as was intended. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 3982560c47c..0f4330b6807 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -2251,7 +2251,7 @@ class TestFunctional(unittest.TestCase): self._DoReadFile('107_cbfs_no_size.dts') self.assertIn('entry must have a size property', str(e.exception)) -def testCbfsNoCOntents(self): +def testCbfsNoContents(self): """Test handling of a CBFS entry which does not provide contentsy""" with self.assertRaises(ValueError) as e: self._DoReadFile('108_cbfs_no_contents.dts') -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 16/17] binman: cfbs: Refactor ObtainContents() for consistency
Update this to use the same arguments as entry_Section uses. Signed-off-by: Simon Glass --- tools/binman/etype/cbfs.py | 40 ++ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index a5120127059..2459388f842 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -193,7 +193,24 @@ class Entry_cbfs(Entry): (node.name, compress)) self._entries[entry._cbfs_name] = entry -def ObtainContents(self, skip=None): +def ObtainCfile(self, cbfs, entry): +# First get the input data and put it in a file. If not available, +# try later. +data = entry.GetData() +cfile = None +if entry._type == 'raw': +cfile = cbfs.add_file_raw(entry._cbfs_name, data, + entry._cbfs_offset, + entry._cbfs_compress) +elif entry._type == 'stage': +cfile = cbfs.add_file_stage(entry._cbfs_name, data, +entry._cbfs_offset) +else: +entry.Raise("Unknown cbfs-type '%s' (use 'raw', 'stage')" % +entry._type) +return cfile + +def ObtainContents(self, skip_entry=None): arch = cbfs_util.find_arch(self._cbfs_arg) if arch is None: self.Raise("Invalid architecture '%s'" % self._cbfs_arg) @@ -201,22 +218,9 @@ class Entry_cbfs(Entry): self.Raise("'cbfs' entry must have a size property") cbfs = CbfsWriter(self.size, arch) for entry in self._entries.values(): -# First get the input data and put it in a file. If not available, -# try later. -if entry != skip and not entry.ObtainContents(): +if entry != skip_entry and not entry.ObtainContents(): return False -data = entry.GetData() -cfile = None -if entry._type == 'raw': -cfile = cbfs.add_file_raw(entry._cbfs_name, data, - entry._cbfs_offset, - entry._cbfs_compress) -elif entry._type == 'stage': -cfile = cbfs.add_file_stage(entry._cbfs_name, data, -entry._cbfs_offset) -else: -entry.Raise("Unknown cbfs-type '%s' (use 'raw', 'stage')" % -entry._type) +cfile = self.ObtainCfile(cbfs, entry) if cfile: entry._cbfs_file = cfile data = cbfs.get_data() @@ -285,5 +289,7 @@ class Entry_cbfs(Entry): return cfile.data if decomp else cfile.orig_data def WriteChildData(self, child): -self.ObtainContents(skip=child) +# Recreate the data structure, leaving the data for this child alone, +# so that child.data is used to pack into the FIP. +self.ObtainContents(skip_entry=child) return True -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 12/17] binman: Update the section documentation
Expand this to explain subclassing better and also to tidy up formatting for rST. Fix a few pylint warnings to avoid dropping the score. Signed-off-by: Simon Glass --- tools/binman/entries.rst | 149 +++--- tools/binman/etype/section.py | 148 +++-- 2 files changed, 242 insertions(+), 55 deletions(-) diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index dcac700c461..748277c1cde 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -799,39 +799,130 @@ This entry holds firmware for an external platform-specific coprocessor. Entry: section: Entry that contains other entries - -Properties / Entry arguments: (see binman README for more information): -pad-byte: Pad byte to use when padding -sort-by-offset: True if entries should be sorted by offset, False if -they must be in-order in the device tree description - -end-at-4gb: Used to build an x86 ROM which ends at 4GB (2^32) - -skip-at-start: Number of bytes before the first entry starts. These -effectively adjust the starting offset of entries. For example, -if this is 16, then the first entry would start at 16. An entry -with offset = 20 would in fact be written at offset 4 in the image -file, since the first 16 bytes are skipped when writing. -name-prefix: Adds a prefix to the name of every entry in the section -when writing out the map -align_default: Default alignment for this section, if no alignment is -given in the entry - -Properties: -allow_missing: True if this section permits external blobs to be -missing their contents. The second will produce an image but of -course it will not work. - -Properties: -_allow_missing: True if this section permits external blobs to be -missing their contents. The second will produce an image but of -course it will not work. +A section is an entry which can contain other entries, thus allowing +hierarchical images to be created. See 'Sections and hierarchical images' +in the binman README for more information. + +The base implementation simply joins the various entries together, using +various rules about alignment, etc. + +Subclassing +~~~ + +This class can be subclassed to support other file formats which hold +multiple entries, such as CBFS. To do this, override the following +functions. The documentation here describes what your function should do. +For example code, see etypes which subclass `Entry_section`, or `cbfs.py` +for a more involved example:: + + $ grep -l \(Entry_section tools/binman/etype/*.py + +ReadNode() +Call `super().ReadNode()`, then read any special properties for the +section. Then call `self.ReadEntries()` to read the entries. + +Binman calls this at the start when reading the image description. + +ReadEntries() +Read in the subnodes of the section. This may involve creating entries +of a particular etype automatically, as well as reading any special +properties in the entries. For each entry, entry.ReadNode() should be +called, to read the basic entry properties. The properties should be +added to `self._entries[]`, in the correct order, with a suitable name. + +Binman calls this at the start when reading the image description. + +BuildSectionData(required) +Create the custom file format that you want and return it as bytes. +This likely sets up a file header, then loops through the entries, +adding them to the file. For each entry, call `entry.GetData()` to +obtain the data. If that returns None, and `required` is False, then +this method must give up and return None. But if `required` is True then +it should assume that all data is valid. + +Binman calls this when packing the image, to find out the size of +everything. It is called again at the end when building the final image. + +SetImagePos(image_pos): +Call `super().SetImagePos(image_pos)`, then set the `image_pos` values +for each of the entries. This should use the custom file format to find +the `start offset` (and `image_pos`) of each entry. If the file format +uses compression in such a way that there is no offset available (other +than reading the whole file and decompressing it), then the offsets for +affected entries can remain unset (`None`). The size should also be set +if possible. + +Binman calls this after the image has been packed, to update the +location that all the entries ended up at. + +ReadChildData(child, decomp): +The default version of this may be good enough, if you are able to +implement SetImagePos() correctly. But that is a bit of a bypass, so +you can override this method to read from your custom file format. It +should read the entire entry containing the custom file using +`super().ReadData(True)`, then parse th
[PATCH 11/17] binman: Allow control of which entries to read
The ObtainContents() and GetEntryContents() methods in this file read every single entry in the section. This is the common case. However when one of the entries has had its data updated (e.g. with 'binman replace') we don't want to read it again from the file. Allow the entry to be skipped, for this purpose. This is currently done in the CBFS implementation, so adding it here will allow that to use more of the entry_Section code. Signed-off-by: Simon Glass --- tools/binman/etype/section.py | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 334240384ea..76e5eb19648 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -143,8 +143,8 @@ class Entry_section(Entry): for entry in self._entries.values(): entry.AddMissingProperties(have_image_pos) -def ObtainContents(self): -return self.GetEntryContents() +def ObtainContents(self, skip_entry=None): +return self.GetEntryContents(skip_entry=skip_entry) def GetPaddedDataForEntry(self, entry, entry_data): """Get the data for an entry including any padding @@ -527,12 +527,13 @@ class Entry_section(Entry): return entry return None -def GetEntryContents(self): +def GetEntryContents(self, skip_entry=None): """Call ObtainContents() for each entry in the section """ def _CheckDone(entry): -if not entry.ObtainContents(): -next_todo.append(entry) +if entry != skip_entry: +if not entry.ObtainContents(): +next_todo.append(entry) return entry todo = self._entries.values() @@ -620,7 +621,7 @@ class Entry_section(Entry): def ListEntries(self, entries, indent): """List the files in the section""" -Entry.AddEntryInfo(entries, indent, self.name, 'section', self.size, +Entry.AddEntryInfo(entries, indent, self.name, self.etype, self.size, self.image_pos, None, self.offset, self) for entry in self._entries.values(): entry.ListEntries(entries, indent + 1) -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 10/17] binman: Allow overriding BuildSectionData()
This method is currently marked private. However it is useful to be able to subclass it, since much of the entry_Section code can be reused. Rename it. Also document one confusing part of this code, so people can understand how to add a test for this case. Fix up a few pylint warnings to avoid regressing the score. Signed-off-by: Simon Glass --- tools/binman/etype/section.py | 16 tools/binman/ftest.py | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 952c01de186..334240384ea 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -182,7 +182,7 @@ class Entry_section(Entry): return data -def _BuildSectionData(self, required): +def BuildSectionData(self, required): """Build the contents of a section This places all entries at the right place, dealing with padding before @@ -190,6 +190,9 @@ class Entry_section(Entry): pad-before and pad-after properties in the section items) since that is handled by the parent section. +This should be overridden by subclasses which want to build their own +data structure for the section. + Args: required: True if the data must be present, False if it is OK to return None @@ -201,6 +204,9 @@ class Entry_section(Entry): for entry in self._entries.values(): entry_data = entry.GetData(required) + +# This can happen when this section is referenced from a collection +# earlier in the image description. See testCollectionSection(). if not required and entry_data is None: return None data = self.GetPaddedDataForEntry(entry, entry_data) @@ -250,7 +256,7 @@ class Entry_section(Entry): This excludes any padding. If the section is compressed, the compressed data is returned """ -data = self._BuildSectionData(required) +data = self.BuildSectionData(required) if data is None: return None self.SetContents(data) @@ -278,7 +284,7 @@ class Entry_section(Entry): self._SortEntries() self._ExpandEntries() -data = self._BuildSectionData(True) +data = self.BuildSectionData(True) self.SetContents(data) self.CheckSize() @@ -735,7 +741,9 @@ class Entry_section(Entry): nothing. Args: -missing: List of missing properties / entry args, each a string +entry (Entry): Entry to raise the error on +missing (list of str): List of missing properties / entry args, each +a string """ if not self._ignore_missing: missing = ', '.join(missing) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 6a36e8f3158..3982560c47c 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4533,7 +4533,7 @@ class TestFunctional(unittest.TestCase): def testCollectionSection(self): """Test a collection where a section must be built first""" # Sections never have their contents when GetData() is called, but when -# _BuildSectionData() is called with required=True, a section will force +# BuildSectionData() is called with required=True, a section will force # building the contents, producing an error is anything is still # missing. data = self._DoReadFile('199_collection_section.dts') -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 09/17] binman: Drop the filename property in entry_Section
This is not used and does nothing. Drop it. Add a tweak to avoid reducing the pylint score. Signed-off-by: Simon Glass --- tools/binman/etype/section.py | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 281a228cd0e..952c01de186 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -81,9 +81,6 @@ class Entry_section(Entry): self._skip_at_start = 0 self._name_prefix = fdt_util.GetString(self._node, 'name-prefix') self.align_default = fdt_util.GetInt(self._node, 'align-default', 0) -filename = fdt_util.GetString(self._node, 'filename') -if filename: -self._filename = filename self.ReadEntries() @@ -661,7 +658,7 @@ class Entry_section(Entry): return data def ReadChildData(self, child, decomp=True): -tout.Debug("ReadChildData for child '%s'" % child.GetPath()) +tout.Debug(f"ReadChildData for child '{child.GetPath()}'") parent_data = self.ReadData(True) offset = child.offset - self._skip_at_start tout.Debug("Extract for child '%s': offset %#x, skip_at_start %#x, result %#x" % -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 08/17] binman: Drop the underscore in _ReadEntries()
This function can be overridden so should not have an underscore. Drop it. Signed-off-by: Simon Glass --- tools/binman/etype/blob_phase.py | 2 +- tools/binman/etype/cbfs.py | 4 ++-- tools/binman/etype/files.py | 2 +- tools/binman/etype/section.py| 8 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/binman/etype/blob_phase.py b/tools/binman/etype/blob_phase.py index 54ca54c50c1..ed25e467a13 100644 --- a/tools/binman/etype/blob_phase.py +++ b/tools/binman/etype/blob_phase.py @@ -48,4 +48,4 @@ class Entry_blob_phase(Entry_section): subnode = state.AddSubnode(self._node, name) # Read entries again, now that we have some -self._ReadEntries() +self.ReadEntries() diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 44db7b9bb20..0a858b8b849 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -171,7 +171,7 @@ class Entry_cbfs(Entry): self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') self.align_default = None self._cbfs_entries = OrderedDict() -self._ReadSubnodes() +self.ReadEntries() self.reader = None def ObtainContents(self, skip=None): @@ -204,7 +204,7 @@ class Entry_cbfs(Entry): self.SetContents(data) return True -def _ReadSubnodes(self): +def ReadEntries(self): """Read the subnodes to find out what should go in this CBFS""" for node in self._node.subnodes: entry = Entry.Create(self, node) diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py index 9b04a496a85..927d0f071df 100644 --- a/tools/binman/etype/files.py +++ b/tools/binman/etype/files.py @@ -64,4 +64,4 @@ class Entry_files(Entry_section): state.AddInt(subnode, 'align', self._files_align) # Read entries again, now that we have some -self._ReadEntries() +self.ReadEntries() diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index e2949fc9163..281a228cd0e 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -85,9 +85,9 @@ class Entry_section(Entry): if filename: self._filename = filename -self._ReadEntries() +self.ReadEntries() -def _ReadEntries(self): +def ReadEntries(self): for node in self._node.subnodes: if node.name.startswith('hash') or node.name.startswith('signature'): continue @@ -741,5 +741,5 @@ class Entry_section(Entry): missing: List of missing properties / entry args, each a string """ if not self._ignore_missing: -entry.Raise('Missing required properties/entry args: %s' % - (', '.join(missing))) +missing = ', '.join(missing) +entry.Raise(f'Missing required properties/entry args: {missing}') -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 04/17] binman: Tidy up style in cmdline
Update this file to improve the pylint score a little. The remaining item is: Function name "ParseArgs" doesn't conform to snake_case naming style which needs some binman-wide renaming. Signed-off-by: Simon Glass --- scripts/pylint.base | 2 +- tools/binman/cmdline.py | 45 - 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/scripts/pylint.base b/scripts/pylint.base index f4f226799c1..4e82dd4a616 100644 --- a/scripts/pylint.base +++ b/scripts/pylint.base @@ -2,7 +2,7 @@ _testing 0.83 atf_bl31 -6.00 binman.cbfs_util 7.70 binman.cbfs_util_test 9.19 -binman.cmdline 8.87 +binman.cmdline 9.06 binman.control 4.39 binman.elf 6.42 binman.elf_test 5.41 diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index e73ff780956..14ec95c25be 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -2,18 +2,38 @@ # Copyright (c) 2016 Google, Inc # Written by Simon Glass # -# Command-line parser for binman -# + +"""Command-line parser for binman""" from argparse import ArgumentParser +def make_extract_parser(subparsers): +"""make_extract_parser: Make a subparser for the 'extract' command + +Args: +subparsers (ArgumentParser): parser to add this one to +""" +extract_parser = subparsers.add_parser('extract', + help='Extract files from an image') +extract_parser.add_argument('-i', '--image', type=str, required=True, +help='Image filename to extract') +extract_parser.add_argument('-f', '--filename', type=str, +help='Output filename to write to') +extract_parser.add_argument('-O', '--outdir', type=str, default='', +help='Path to directory to use for output files') +extract_parser.add_argument('paths', type=str, nargs='*', +help='Paths within file to extract (wildcard)') +extract_parser.add_argument('-U', '--uncompressed', action='store_true', +help='Output raw uncompressed data for compressed entries') + def ParseArgs(argv): """Parse the binman command-line arguments Args: -argv: List of string arguments +argv (list of str): List of string arguments + Returns: -Tuple (options, args) with the command-line options and arugments. +tuple: (options, args) with the command-line options and arugments. options provides access to the options (e.g. option.debug) args is a list of string arguments """ @@ -74,8 +94,8 @@ controlled by a description in the board device tree.''' build_parser.add_argument('--update-fdt-in-elf', type=str, help='Update an ELF file with the output dtb: infile,outfile,begin_sym,end_sym') -entry_parser = subparsers.add_parser('entry-docs', -help='Write out entry documentation (see entries.rst)') +subparsers.add_parser( +'entry-docs', help='Write out entry documentation (see entries.rst)') list_parser = subparsers.add_parser('ls', help='List files in an image') list_parser.add_argument('-i', '--image', type=str, required=True, @@ -83,18 +103,7 @@ controlled by a description in the board device tree.''' list_parser.add_argument('paths', type=str, nargs='*', help='Paths within file to list (wildcard)') -extract_parser = subparsers.add_parser('extract', - help='Extract files from an image') -extract_parser.add_argument('-i', '--image', type=str, required=True, -help='Image filename to extract') -extract_parser.add_argument('-f', '--filename', type=str, -help='Output filename to write to') -extract_parser.add_argument('-O', '--outdir', type=str, default='', -help='Path to directory to use for output files') -extract_parser.add_argument('paths', type=str, nargs='*', -help='Paths within file to extract (wildcard)') -extract_parser.add_argument('-U', '--uncompressed', action='store_true', -help='Output raw uncompressed data for compressed entries') +make_extract_parser(subparsers) replace_parser = subparsers.add_parser('replace', help='Replace entries in an image') -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 05/17] binman: Add a way to obtain the version
Add a -V option which shows the version number of binman. For now this just uses a local 'version' file. Once the tool is packaged in some way we can figure out an approach that suits. Signed-off-by: Simon Glass --- tools/binman/cmdline.py | 29 + tools/binman/ftest.py | 20 tools/binman/state.py | 18 ++ 3 files changed, 67 insertions(+) diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index 14ec95c25be..2229316f10e 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -5,7 +5,9 @@ """Command-line parser for binman""" +import argparse from argparse import ArgumentParser +import state def make_extract_parser(subparsers): """make_extract_parser: Make a subparser for the 'extract' command @@ -26,6 +28,32 @@ def make_extract_parser(subparsers): extract_parser.add_argument('-U', '--uncompressed', action='store_true', help='Output raw uncompressed data for compressed entries') + +#pylint: disable=R0903 +class BinmanVersion(argparse.Action): +"""Handles the -V option to binman + +This reads the version information from a file called 'version' in the same +directory as this file. + +If not present it assumes this is running from the U-Boot tree and collects +the version from the Makefile. + +The format of the version information is three VAR = VALUE lines, for +example: + +VERSION = 2022 +PATCHLEVEL = 01 +EXTRAVERSION = -rc2 +""" +def __init__(self, nargs=0, **kwargs): +super().__init__(nargs=nargs, **kwargs) + +def __call__(self, parser, namespace, values, option_string=None): +parser._print_message(f'Binman {state.GetVersion()}\n') +parser.exit() + + def ParseArgs(argv): """Parse the binman command-line arguments @@ -59,6 +87,7 @@ controlled by a description in the board device tree.''' parser.add_argument('-v', '--verbosity', default=1, type=int, help='Control verbosity: 0=silent, 1=warnings, 2=notices, ' '3=info, 4=detail, 5=debug') +parser.add_argument('-V', '--version', nargs=0, action=BinmanVersion) subparsers = parser.add_subparsers(dest='cmd') subparsers.required = True diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 6be003786e8..6a36e8f3158 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4661,6 +4661,26 @@ class TestFunctional(unittest.TestCase): str(e.exception), "Not enough space in '.*u_boot_binman_embed_sm' for data length.*") +def testVersion(self): +"""Test we can get the binman version""" +version = '(unreleased)' +self.assertEqual(version, state.GetVersion(self._indir)) + +with self.assertRaises(SystemExit): +with test_util.capture_sys_output() as (_, stderr): +self._DoBinman('-V') +self.assertEqual('Binman %s\n' % version, stderr.getvalue()) + +# Try running the tool too, just to be safe +result = self._RunBinman('-V') +self.assertEqual('Binman %s\n' % version, result.stderr) + +# Set up a version file to make sure that works +version = 'v2025.01-rc2' +tools.WriteFile(os.path.join(self._indir, 'version'), version, +binary=False) +self.assertEqual(version, state.GetVersion(self._indir)) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/state.py b/tools/binman/state.py index 9e5b8a39310..af0a65e8418 100644 --- a/tools/binman/state.py +++ b/tools/binman/state.py @@ -16,6 +16,8 @@ import os from patman import tools from patman import tout +OUR_PATH = os.path.dirname(os.path.realpath(__file__)) + # Map an dtb etype to its expected filename DTB_TYPE_FNAME = { 'u-boot-spl-dtb': 'spl/u-boot-spl.dtb', @@ -515,3 +517,19 @@ def TimingShow(): for name, seconds in duration.items(): print('%10s: %10.1fms' % (name, seconds * 1000)) + +def GetVersion(path=OUR_PATH): +"""Get the version string for binman + +Args: +path: Path to 'version' file + +Returns: +str: String version, e.g. 'v2021.10' +""" +version_fname = os.path.join(path, 'version') +if os.path.exists(version_fname): +version = tools.ReadFile(version_fname, binary=False) +else: +version = '(unreleased)' +return version -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 06/17] binman: Correct init of entry in Entry class
This should not have an underscore. Drop it so that derived classes can rely on it being set correctly. Signed-off-by: Simon Glass --- tools/binman/entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 70222718ea9..5e66aa4fa54 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -95,7 +95,7 @@ class Entry(object): self.pad_after = 0 self.offset_unset = False self.image_pos = None -self._expand_size = False +self.expand_size = False self.compress = 'none' self.missing = False self.external = False -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 03/17] dtoc: Add support for reading fixed-length bytes properties
Add functions to read a sequence of bytes from the devicetree. Signed-off-by: Simon Glass --- scripts/pylint.base| 4 ++-- tools/dtoc/fdt_util.py | 20 tools/dtoc/test_fdt.py | 17 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/scripts/pylint.base b/scripts/pylint.base index d848ebe9058..f4f226799c1 100644 --- a/scripts/pylint.base +++ b/scripts/pylint.base @@ -44,12 +44,12 @@ cros_ec_rw -6.00 defs 6.67 dtoc.dtb_platdata 7.82 dtoc.fdt 3.47 -dtoc.fdt_util 4.53 +dtoc.fdt_util 4.95 dtoc.main 7.33 dtoc.setup 5.00 dtoc.src_scan 8.75 dtoc.test_dtoc 8.54 -dtoc.test_fdt 6.92 +dtoc.test_fdt 6.93 dtoc.test_src_scan 9.43 efivar 6.71 endian-swap 8.93 diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index 51d0eb52423..51bdbdcd3b2 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -202,6 +202,26 @@ def GetByte(node, propname, default=None): (node.name, propname, len(value), 1)) return ord(value[0]) +def GetBytes(node, propname, size, default=None): +"""Get a set of bytes from a property + +Args: +node (Node): Node object to read from +propname (str): property name to read +size (int): Number of bytes to expect +default (bytes): Default value or None + +Returns: +bytes: Bytes value read, or default if none +""" +prop = node.props.get(propname) +if not prop: +return default +if len(prop.bytes) != size: +raise ValueError("Node '%s' property '%s' has length %d, expecting %d" % + (node.name, propname, len(prop.bytes), size)) +return prop.bytes + def GetPhandleList(node, propname): """Get a list of phandles from a property diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 21a9a7ca063..7a4c7efaa4a 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -635,6 +635,23 @@ class TestFdtUtil(unittest.TestCase): self.assertIn("property 'intval' has length 4, expecting 1", str(e.exception)) +def testGetBytes(self): +self.assertEqual(bytes([5]), fdt_util.GetBytes(self.node, 'byteval', 1)) +self.assertEqual(None, fdt_util.GetBytes(self.node, 'missing', 3)) +self.assertEqual( +bytes([3]), fdt_util.GetBytes(self.node, 'missing', 3, bytes([3]))) + +with self.assertRaises(ValueError) as e: +fdt_util.GetBytes(self.node, 'longbytearray', 7) +self.assertIn( +"Node 'spl-test' property 'longbytearray' has length 9, expecting 7", + str(e.exception)) + +self.assertEqual( +bytes([0, 0, 0, 1]), fdt_util.GetBytes(self.node, 'intval', 4)) +self.assertEqual( +bytes([3]), fdt_util.GetBytes(self.node, 'missing', 3, bytes([3]))) + def testGetPhandleList(self): dtb = fdt.FdtScan(find_dtb_file('dtoc_test_phandle.dts')) node = dtb.GetNode('/phandle-source2') -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 07/17] binman: Correct comments for ReadChildData()
The comment here is incomplete. Fix it. Signed-off-by: Simon Glass --- tools/binman/entry.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 5e66aa4fa54..2205bc8d923 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -860,7 +860,8 @@ features to produce new behaviours. """Handle writing the data in a child entry This should be called on the child's parent section after the child's -data has been updated. It +data has been updated. It should update any data structures needed to +validate that the update is successful. This base-class implementation does nothing, since the base Entry object does not have any children. @@ -870,7 +871,7 @@ features to produce new behaviours. Returns: True if the section could be updated successfully, False if the -data is such that the section could not updat +data is such that the section could not update """ return True -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 01/17] dtoc: Bring in the libfdt module automatically
Use the same technique as with binman to load this module from the U-Boot tree if available. This allows running tests without having to specify the PYTHONPATH variable. Signed-off-by: Simon Glass --- tools/dtoc/test_fdt.py | 6 ++ 1 file changed, 6 insertions(+) diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index d104f3c7745..d86fc86187e 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -16,6 +16,12 @@ import unittest our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(1, os.path.join(our_path, '..')) +# Bring in the libfdt module +sys.path.insert(2, 'scripts/dtc/pylibfdt') +sys.path.insert(2, os.path.join(our_path, '../../scripts/dtc/pylibfdt')) +sys.path.insert(2, os.path.join(our_path, +'../../build-sandbox_spl/scripts/dtc/pylibfdt')) + from dtoc import fdt from dtoc import fdt_util from dtoc.fdt_util import fdt32_to_cpu -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH 02/17] dtoc: Add support for reading 64-bit ints
Add functions to read a 64-bit integer property from the devicetree. Signed-off-by: Simon Glass --- tools/dtoc/fdt_util.py | 35 tools/dtoc/test/dtoc_test_simple.dts | 1 + tools/dtoc/test_dtoc.py | 2 ++ tools/dtoc/test_fdt.py | 21 ++--- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index 37e96b98642..51d0eb52423 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -27,6 +27,18 @@ def fdt32_to_cpu(val): """ return struct.unpack('>I', val)[0] +def fdt64_to_cpu(val): +"""Convert a device tree cell to an integer + +Args: +val (list): Value to convert (list of 2 4-character strings representing +the cell value) + +Return: +int: A native-endian integer value +""" +return fdt32_to_cpu(val[0]) << 32 | fdt32_to_cpu(val[1]) + def fdt_cells_to_cpu(val, cells): """Convert one or two cells to a long integer @@ -108,6 +120,29 @@ def GetInt(node, propname, default=None): value = fdt32_to_cpu(prop.value) return value +def GetInt64(node, propname, default=None): +"""Get a 64-bit integer from a property + +Args: +node (Node): Node object to read from +propname (str): property name to read +default (int): Default value to use if the node/property do not exist + +Returns: +int: value read, or default if none + +Raises: +ValueError: Property is not of the correct size +""" +prop = node.props.get(propname) +if not prop: +return default +if not isinstance(prop.value, list) or len(prop.value) != 2: +raise ValueError("Node '%s' property '%s' should be a list with 2 items for 64-bit values" % + (node.name, propname)) +value = fdt64_to_cpu(prop.value) +return value + def GetString(node, propname, default=None): """Get a string from a property diff --git a/tools/dtoc/test/dtoc_test_simple.dts b/tools/dtoc/test/dtoc_test_simple.dts index 5a6fa88d5cc..4c2c70af222 100644 --- a/tools/dtoc/test/dtoc_test_simple.dts +++ b/tools/dtoc/test/dtoc_test_simple.dts @@ -16,6 +16,7 @@ boolval; maybe-empty-int = <>; intval = <1>; + int64val = /bits/ 64 <0x123456789abcdef0>; intarray = <2 3 4>; byteval = [05]; bytearray = [06]; diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 752061f27a4..ee17b8daf9a 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -296,6 +296,7 @@ struct dtd_sandbox_spl_test { \tbool\t\tboolval; \tunsigned char\tbytearray[3]; \tunsigned char\tbyteval; +\tfdt32_t\t\tint64val[2]; \tfdt32_t\t\tintarray[3]; \tfdt32_t\t\tintval; \tunsigned char\tlongbytearray[9]; @@ -355,6 +356,7 @@ static struct dtd_sandbox_spl_test dtv_spl_test = { \t.boolval\t\t= true, \t.bytearray\t\t= {0x6, 0x0, 0x0}, \t.byteval\t\t= 0x5, +\t.int64val\t\t= {0x12345678, 0x9abcdef0}, \t.intarray\t\t= {0x2, 0x3, 0x4}, \t.intval\t\t\t= 0x1, \t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index d86fc86187e..21a9a7ca063 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -24,7 +24,7 @@ sys.path.insert(2, os.path.join(our_path, from dtoc import fdt from dtoc import fdt_util -from dtoc.fdt_util import fdt32_to_cpu +from dtoc.fdt_util import fdt32_to_cpu, fdt64_to_cpu from fdt import Type, BytesToValue import libfdt from patman import command @@ -128,7 +128,7 @@ class TestFdt(unittest.TestCase): node = self.dtb.GetNode('/spl-test') props = self.dtb.GetProps(node) self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible', - 'intarray', 'intval', 'longbytearray', + 'int64val', 'intarray', 'intval', 'longbytearray', 'maybe-empty-int', 'notstring', 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'], sorted(props.keys())) @@ -335,6 +335,10 @@ class TestProp(unittest.TestCase): self.assertEqual(Type.INT, prop.type) self.assertEqual(1, fdt32_to_cpu(prop.value)) +prop = self._ConvertProp('int64val') +self.assertEqual(Type.INT, prop.type) +self.assertEqual(0x123456789abcdef0, fdt64_to_cpu(prop.value)) + prop = self._ConvertProp('intarray') self.assertEqual(Type.INT, prop.type) val = [fdt32_to_cpu(val) for val in prop.value] @@ -586,10 +590,21 @@ class TestFdtUtil(unittest.TestCase): self.assertEqual(3, fdt_util.GetInt(self.node, 'missing', 3)) with self.assertRaises(ValueError) as e: -self.assertEqual(3, fdt_util.GetInt(self.node, 'intarray')) +fdt_util.GetInt(self.node, 'int
[PATCH 00/17] binman: Various tidy-ups and refactors
This series improves the implementation of the entry_Section class so that it is easier to subclass it. It also updates the documentation in this area and adds support for a few more types in the Fdt class. Using this, the CBFS implementation is tidied up a bit, but is not yet updated to use entry_Section as a base class. That needs a bit more work. Still, this provides a better basis for new file formats. Simon Glass (17): dtoc: Bring in the libfdt module automatically dtoc: Add support for reading 64-bit ints dtoc: Add support for reading fixed-length bytes properties binman: Tidy up style in cmdline binman: Add a way to obtain the version binman: Correct init of entry in Entry class binman: Correct comments for ReadChildData() binman: Drop the underscore in _ReadEntries() binman: Drop the filename property in entry_Section binman: Allow overriding BuildSectionData() binman: Allow control of which entries to read binman: Update the section documentation binman: Move cbfs.ObtainContents() down a bit binman: Use normal entries in cbfs binman: cbfs: Refactor the init process binman: cfbs: Refactor ObtainContents() for consistency binman: Rename testCbfsNoCOntents() scripts/pylint.base | 6 +- tools/binman/cmdline.py | 74 --- tools/binman/entries.rst | 149 + tools/binman/entry.py| 7 +- tools/binman/etype/blob_phase.py | 2 +- tools/binman/etype/cbfs.py | 90 +++-- tools/binman/etype/files.py | 2 +- tools/binman/etype/section.py| 190 --- tools/binman/ftest.py| 24 +++- tools/binman/state.py| 18 +++ tools/dtoc/fdt_util.py | 55 tools/dtoc/test/dtoc_test_simple.dts | 1 + tools/dtoc/test_dtoc.py | 2 + tools/dtoc/test_fdt.py | 44 ++- 14 files changed, 520 insertions(+), 144 deletions(-) -- 2.34.0.rc2.393.gf8c9666880-goog
[PATCH v2 2/2] bsh: imx8mn-smm-s2/pro: Add iMX8MN BSH SMM S2 boards
Introduce BSH SystemMaster (SMM) S2 board family, which consists of: iMX8MN SMM S2 and iMX8MN SMM S2 PRO boards. Add support for iMX8MN BSH SMM S2 board: - 256 MiB DDR3 RAM - 512MiB Nand - USBOTG1 peripheral - fastboot. Add support for iMX8MN BSH SMM S2 PRO board: - 512 MiB DDR3 RAM - 8 GiB eMMC - USBOTG1 peripheral - fastboot. Signed-off-by: Ariel D'Alessandro Signed-off-by: Michael Trimarchi --- arch/arm/dts/Makefile | 2 + arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi| 423 .../dts/imx8mn-bsh-smm-s2-u-boot-common.dtsi | 225 + arch/arm/dts/imx8mn-bsh-smm-s2-u-boot.dtsi| 15 + arch/arm/dts/imx8mn-bsh-smm-s2.dts| 48 + arch/arm/dts/imx8mn-bsh-smm-s2pro-u-boot.dtsi | 15 + arch/arm/dts/imx8mn-bsh-smm-s2pro.dts | 80 ++ arch/arm/mach-imx/imx8m/Kconfig | 15 + board/bsh/imx8mn_smm_s2/Kconfig | 38 + board/bsh/imx8mn_smm_s2/MAINTAINERS | 8 + board/bsh/imx8mn_smm_s2/Makefile | 13 + board/bsh/imx8mn_smm_s2/ddr3l_timing_256m.c | 941 ++ board/bsh/imx8mn_smm_s2/ddr3l_timing_512m.c | 941 ++ board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c | 23 + board/bsh/imx8mn_smm_s2/imximage-8mn-ddr3.cfg | 10 + board/bsh/imx8mn_smm_s2/spl.c | 93 ++ configs/imx8mn_bsh_smm_s2_defconfig | 92 ++ configs/imx8mn_bsh_smm_s2pro_defconfig| 89 ++ doc/board/bsh/imx8mn_bsh_smm_s2.rst | 62 ++ doc/board/bsh/index.rst | 9 + doc/board/index.rst | 1 + include/configs/imx8mn_bsh_smm_s2.h | 52 + include/configs/imx8mn_bsh_smm_s2_common.h| 62 ++ include/configs/imx8mn_bsh_smm_s2pro.h| 35 + 24 files changed, 3292 insertions(+) create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-u-boot-common.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2.dts create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2pro-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2pro.dts create mode 100644 board/bsh/imx8mn_smm_s2/Kconfig create mode 100644 board/bsh/imx8mn_smm_s2/MAINTAINERS create mode 100644 board/bsh/imx8mn_smm_s2/Makefile create mode 100644 board/bsh/imx8mn_smm_s2/ddr3l_timing_256m.c create mode 100644 board/bsh/imx8mn_smm_s2/ddr3l_timing_512m.c create mode 100644 board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c create mode 100644 board/bsh/imx8mn_smm_s2/imximage-8mn-ddr3.cfg create mode 100644 board/bsh/imx8mn_smm_s2/spl.c create mode 100644 configs/imx8mn_bsh_smm_s2_defconfig create mode 100644 configs/imx8mn_bsh_smm_s2pro_defconfig create mode 100644 doc/board/bsh/imx8mn_bsh_smm_s2.rst create mode 100644 doc/board/bsh/index.rst create mode 100644 include/configs/imx8mn_bsh_smm_s2.h create mode 100644 include/configs/imx8mn_bsh_smm_s2_common.h create mode 100644 include/configs/imx8mn_bsh_smm_s2pro.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7f622fedbd..25a3a6f713 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -899,6 +899,8 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mm-venice-gw7902.dtb \ imx8mm-verdin.dtb \ phycore-imx8mm.dtb \ + imx8mn-bsh-smm-s2.dtb \ + imx8mn-bsh-smm-s2pro.dtb \ imx8mn-ddr4-evk.dtb \ imx8mq-cm.dtb \ imx8mn-evk.dtb \ diff --git a/arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi b/arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi new file mode 100644 index 00..184c715bd3 --- /dev/null +++ b/arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi @@ -0,0 +1,423 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Collabora Ltd. + * Copyright 2021 BSH Hausgeraete GmbH + */ + +#include "imx8mn.dtsi" + +/ { + chosen { + stdout-path = &uart4; + }; + + fec_supply: fec_supply_en { + compatible = "regulator-fixed"; + regulator-name = "tja1101_en"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; + vin-supply = <&buck4_reg>; + enable-active-high; + }; + + usdhc2_pwrseq: usdhc2_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2_pwrseq>; + reset-gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_espi2>; + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + ph
[PATCH v2 1/2] imx8m: add regs used by GPMI
From: Michael Trimarchi Add regs used by GPMI Signed-off-by: Michael Trimarchi Signed-off-by: Ariel D'Alessandro --- arch/arm/include/asm/arch-imx8m/imx-regs.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h index b800da13a1..14955d1090 100644 --- a/arch/arm/include/asm/arch-imx8m/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h @@ -58,6 +58,13 @@ #define SRC_DDRC_RCR_ADDR 0x30391000 #define SRC_DDRC2_RCR_ADDR 0x30391004 +#define APBH_DMA_ARB_BASE_ADDR 0x3300 +#define APBH_DMA_ARB_END_ADDR 0x33007FFF +#define MXS_APBH_BASE APBH_DMA_ARB_BASE_ADDR + +#define MXS_GPMI_BASE (APBH_DMA_ARB_BASE_ADDR + 0x02000) +#define MXS_BCH_BASE (APBH_DMA_ARB_BASE_ADDR + 0x04000) + #define DDRC_DDR_SS_GPR0 0x3d00 #define DDRC_IPS_BASE_ADDR(X) (0x3d40 + ((X) * 0x200)) #define DDR_CSD1_BASE_ADDR 0x4000 -- 2.30.2
[PATCH v2 0/2] imx8mn-smm-s2/pro: Add iMX8MN BSH SMM S2 boards
Changes in v2: * Properly added MAINTAINERS entry. * Fixed binman configuration. * Picked device tree from kernel. * Removed CONFIG_SPL_BUILD anti-pattern in board config. * Removed downstream stuff in bootargs. * Added board documentation. Ariel D'Alessandro (1): bsh: imx8mn-smm-s2/pro: Add iMX8MN BSH SMM S2 boards Michael Trimarchi (1): imx8m: add regs used by GPMI arch/arm/dts/Makefile | 2 + arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi| 423 .../dts/imx8mn-bsh-smm-s2-u-boot-common.dtsi | 225 + arch/arm/dts/imx8mn-bsh-smm-s2-u-boot.dtsi| 15 + arch/arm/dts/imx8mn-bsh-smm-s2.dts| 48 + arch/arm/dts/imx8mn-bsh-smm-s2pro-u-boot.dtsi | 15 + arch/arm/dts/imx8mn-bsh-smm-s2pro.dts | 80 ++ arch/arm/include/asm/arch-imx8m/imx-regs.h| 7 + arch/arm/mach-imx/imx8m/Kconfig | 15 + board/bsh/imx8mn_smm_s2/Kconfig | 38 + board/bsh/imx8mn_smm_s2/MAINTAINERS | 8 + board/bsh/imx8mn_smm_s2/Makefile | 13 + board/bsh/imx8mn_smm_s2/ddr3l_timing_256m.c | 941 ++ board/bsh/imx8mn_smm_s2/ddr3l_timing_512m.c | 941 ++ board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c | 23 + board/bsh/imx8mn_smm_s2/imximage-8mn-ddr3.cfg | 10 + board/bsh/imx8mn_smm_s2/spl.c | 93 ++ configs/imx8mn_bsh_smm_s2_defconfig | 92 ++ configs/imx8mn_bsh_smm_s2pro_defconfig| 89 ++ doc/board/bsh/imx8mn_bsh_smm_s2.rst | 62 ++ doc/board/bsh/index.rst | 9 + doc/board/index.rst | 1 + include/configs/imx8mn_bsh_smm_s2.h | 52 + include/configs/imx8mn_bsh_smm_s2_common.h| 62 ++ include/configs/imx8mn_bsh_smm_s2pro.h| 35 + 25 files changed, 3299 insertions(+) create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-common.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-u-boot-common.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2.dts create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2pro-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-bsh-smm-s2pro.dts create mode 100644 board/bsh/imx8mn_smm_s2/Kconfig create mode 100644 board/bsh/imx8mn_smm_s2/MAINTAINERS create mode 100644 board/bsh/imx8mn_smm_s2/Makefile create mode 100644 board/bsh/imx8mn_smm_s2/ddr3l_timing_256m.c create mode 100644 board/bsh/imx8mn_smm_s2/ddr3l_timing_512m.c create mode 100644 board/bsh/imx8mn_smm_s2/imx8mn_smm_s2.c create mode 100644 board/bsh/imx8mn_smm_s2/imximage-8mn-ddr3.cfg create mode 100644 board/bsh/imx8mn_smm_s2/spl.c create mode 100644 configs/imx8mn_bsh_smm_s2_defconfig create mode 100644 configs/imx8mn_bsh_smm_s2pro_defconfig create mode 100644 doc/board/bsh/imx8mn_bsh_smm_s2.rst create mode 100644 doc/board/bsh/index.rst create mode 100644 include/configs/imx8mn_bsh_smm_s2.h create mode 100644 include/configs/imx8mn_bsh_smm_s2_common.h create mode 100644 include/configs/imx8mn_bsh_smm_s2pro.h -- 2.30.2
[PATCH v6 1/1] imx8mn_var_som: Add support for Variscite VAR-SOM-MX8M-NANO board
Add support for iMX8MN VAR-SOM-MX8M-NANO board. Enables support for: - 1GiB DDR4 RAM - 16 GiB eMMC - SD card - Gigabit ethernet - USBOTG1 peripheral - fastboot Signed-off-by: Ariel D'Alessandro Reviewed-by: Tom Rini Reviewed-by: Fabio Estevam --- arch/arm/dts/Makefile | 1 + .../dts/imx8mn-var-som-symphony-u-boot.dtsi | 256 arch/arm/dts/imx8mn-var-som-symphony.dts | 240 arch/arm/dts/imx8mn-var-som.dtsi | 547 ++ arch/arm/mach-imx/imx8m/Kconfig | 8 + board/variscite/imx8mn_var_som/Kconfig| 17 + board/variscite/imx8mn_var_som/MAINTAINERS| 7 + board/variscite/imx8mn_var_som/Makefile | 12 + board/variscite/imx8mn_var_som/ddr4_timing.c | 528 + .../variscite/imx8mn_var_som/imx8mn_var_som.c | 30 + .../imx8mn_var_som/imximage-8mn-ddr4.cfg | 10 + board/variscite/imx8mn_var_som/spl.c | 93 +++ configs/imx8mn_var_som_defconfig | 98 doc/board/index.rst | 1 + doc/board/variscite/imx8mn_var_som.rst| 56 ++ doc/board/variscite/index.rst | 9 + include/configs/imx8mn_var_som.h | 90 +++ 17 files changed, 2003 insertions(+) create mode 100644 arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-var-som-symphony.dts create mode 100644 arch/arm/dts/imx8mn-var-som.dtsi create mode 100644 board/variscite/imx8mn_var_som/Kconfig create mode 100644 board/variscite/imx8mn_var_som/MAINTAINERS create mode 100644 board/variscite/imx8mn_var_som/Makefile create mode 100644 board/variscite/imx8mn_var_som/ddr4_timing.c create mode 100644 board/variscite/imx8mn_var_som/imx8mn_var_som.c create mode 100644 board/variscite/imx8mn_var_som/imximage-8mn-ddr4.cfg create mode 100644 board/variscite/imx8mn_var_som/spl.c create mode 100644 configs/imx8mn_var_som_defconfig create mode 100644 doc/board/variscite/imx8mn_var_som.rst create mode 100644 doc/board/variscite/index.rst create mode 100644 include/configs/imx8mn_var_som.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7f622fedbd..3794b424c6 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -902,6 +902,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mn-ddr4-evk.dtb \ imx8mq-cm.dtb \ imx8mn-evk.dtb \ + imx8mn-var-som-symphony.dtb \ imx8mq-evk.dtb \ imx8mm-beacon-kit.dtb \ imx8mn-beacon-kit.dtb \ diff --git a/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi new file mode 100644 index 00..ce475885df --- /dev/null +++ b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Collabora Ltd. + */ + +/ { + binman: binman { + multiple-images; + }; + + wdt-reboot { + compatible = "wdt-reboot"; + wdt = <&wdog1>; + u-boot,dm-spl; + }; +}; + +&{/soc@0} { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&{/soc@0/bus@3080/i2c@30a2/pmic@4b} { + u-boot,dm-spl; +}; + +&{/soc@0/bus@3080/i2c@30a2/pmic@4b/regulators} { + u-boot,dm-spl; +}; + +&aips1 { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&aips3 { + u-boot,dm-spl; +}; + +&aips4 { + u-boot,dm-spl; +}; + +&clk { + u-boot,dm-pre-reloc; + u-boot,dm-spl; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ assigned-clock-rates; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&i2c1 { + u-boot,dm-spl; +}; + +&iomuxc { + u-boot,dm-spl; +}; + +&osc_24m { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&pinctrl_i2c1 { + u-boot,dm-spl; +}; + +&pinctrl_pmic { + u-boot,dm-spl; +}; + +&pinctrl_reg_usdhc2_vmmc { + u-boot,dm-spl; +}; + +&pinctrl_uart4 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc2 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc3 { + u-boot,dm-spl; +}; + +&pinctrl_wdog { + u-boot,dm-spl; +}; + +&uart4 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc3 { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; + +&binman { + u-boot-spl-ddr { + align = <4>; + align-size = <4>; + filename = "u-boot-spl-ddr.bin"; + pad-byte = <0xff>; + + u-boot-spl { + align-end = <4>; + filename = "u-boot-spl.bin"; + }; + + 1d-imem { + filename = "ddr4_imem_1d.bin"; + size = <0x8000>; + type = "blob-ext"; + }; + + 1d_dmem { + f
[PATCH v6 0/1] imx8mn_var_som: Add support for Variscite VAR-SOM-MX8M-NANO board
Changes in v6: * Fixed typo in documentation. * Removed downstream config option IMX8M_BOARD_INIT_DRAM. Changes in v5: * Fixed documentation. Changes in v4: * Added board documentation. * Cleaned up board config. Changes in v3: * Picked device tree from kernel. * Properly added MAINTAINERS entry. * Removed CONFIG_SPL_BUILD anti-pattern in board config. Changes in v2: * Reordered dt properties alphabetically. * Removed downstream stuff in bootargs. * Fixed binman configuration. * Several code styling fixes. Ariel D'Alessandro (1): imx8mn_var_som: Add support for Variscite VAR-SOM-MX8M-NANO board arch/arm/dts/Makefile | 1 + .../dts/imx8mn-var-som-symphony-u-boot.dtsi | 256 arch/arm/dts/imx8mn-var-som-symphony.dts | 240 arch/arm/dts/imx8mn-var-som.dtsi | 547 ++ arch/arm/mach-imx/imx8m/Kconfig | 8 + board/variscite/imx8mn_var_som/Kconfig| 17 + board/variscite/imx8mn_var_som/MAINTAINERS| 7 + board/variscite/imx8mn_var_som/Makefile | 12 + board/variscite/imx8mn_var_som/ddr4_timing.c | 528 + .../variscite/imx8mn_var_som/imx8mn_var_som.c | 30 + .../imx8mn_var_som/imximage-8mn-ddr4.cfg | 10 + board/variscite/imx8mn_var_som/spl.c | 93 +++ configs/imx8mn_var_som_defconfig | 98 doc/board/index.rst | 1 + doc/board/variscite/imx8mn_var_som.rst| 56 ++ doc/board/variscite/index.rst | 9 + include/configs/imx8mn_var_som.h | 90 +++ 17 files changed, 2003 insertions(+) create mode 100644 arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mn-var-som-symphony.dts create mode 100644 arch/arm/dts/imx8mn-var-som.dtsi create mode 100644 board/variscite/imx8mn_var_som/Kconfig create mode 100644 board/variscite/imx8mn_var_som/MAINTAINERS create mode 100644 board/variscite/imx8mn_var_som/Makefile create mode 100644 board/variscite/imx8mn_var_som/ddr4_timing.c create mode 100644 board/variscite/imx8mn_var_som/imx8mn_var_som.c create mode 100644 board/variscite/imx8mn_var_som/imximage-8mn-ddr4.cfg create mode 100644 board/variscite/imx8mn_var_som/spl.c create mode 100644 configs/imx8mn_var_som_defconfig create mode 100644 doc/board/variscite/imx8mn_var_som.rst create mode 100644 doc/board/variscite/index.rst create mode 100644 include/configs/imx8mn_var_som.h -- 2.30.2
[PATCH] efi_loader: Check for pointers before appending to the eventlog
The TCG protocol returns EFI_SUCCESS even when it fails to install. If the protocol is not installed there should be no calls to tcg2_agile_log_append(). However there are calls to this function occurring outside the TCG protocol invocation (e.g tcg2_measure_pe_image). Let's deal with this and shield the code from crashing while complaining, so buggy code can be spotted and fixed. Signed-off-by: Ilias Apalodimas --- Heinrich this is rebased on top of https://lore.kernel.org/u-boot/20211123115335.125252-1-ruchika.gu...@linaro.org/ lib/efi_loader/efi_tcg2.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 133fe8291a92..57a1f37695f6 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -311,6 +311,17 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, struct efi_tcg2_final_events_table *final_event; efi_status_t ret = EFI_SUCCESS; + /* +* This should never happen. This function should only be invoked if +* the TCG2 protocol has been installed. However since we always +* return EFI_SUCCESS from efi_tcg2_register shield callers against +* crashing and complain +*/ + if (!event_log.final_buffer || !event_log.buffer) { + log_err("EFI TCG2 protocol not installed\n"); + return EFI_INVALID_PARAMETER; + } + /* if ExitBootServices hasn't been called update the normal log */ if (!event_log.ebs_called) { if (event_log.truncated || -- 2.34.0
Re: [RFC] binman: add support for creating dummy files for external blobs
Hi Heiko, On Tue, 16 Nov 2021 at 03:47, Heiko Thiery wrote: > > While converting to binman for an imx8mq board, it has been found that > building in the u-boot CI fails. This is because an imx8mq requires an > external binary (signed_hdmi_imx8m.bin). If this file cannot be found > mkimage fails. > To be able to build this board in the u-boot CI a binman option > (--fake-ext-blobs) is introduced that can be switched on via the u-boot > makefile option BINMAN_FAKE_EXT_BLOBS. With that the needed dummy files are > created. > > Signed-off-by: Heiko Thiery > --- > Makefile | 1 + > tools/binman/cmdline.py| 2 ++ > tools/binman/control.py| 16 > tools/binman/entry.py | 1 + > tools/binman/etype/blob_ext.py | 1 + > 5 files changed, 21 insertions(+) This seems like a reasonable solution to me. > > diff --git a/Makefile b/Makefile > index f911f70344..1a833a1637 100644 > --- a/Makefile > +++ b/Makefile > @@ -1307,6 +1307,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if > $(BINMAN_DEBUG),-D) \ > -a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \ > -a spl-dtb=$(CONFIG_SPL_OF_REAL) \ > -a tpl-dtb=$(CONFIG_SPL_OF_REAL) \ > + $(if $(BINMAN_FAKE_EXT_BLOBS),--fake-ext-blobs) \ > $(BINMAN_$(@F)) > > OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex > diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py > index d6156df408..2b29981cb4 100644 > --- a/tools/binman/cmdline.py > +++ b/tools/binman/cmdline.py > @@ -52,6 +52,8 @@ controlled by a description in the board device tree.''' > help='Configuration file (.dtb) to use') > build_parser.add_argument('--fake-dtb', action='store_true', > help='Use fake device tree contents (for testing only)') > +build_parser.add_argument('--fake-ext-blobs', action='store_true', > +help='Create fake ext blobs with dummy content (for testing > only)') > build_parser.add_argument('-i', '--image', type=str, action='append', > help='Image filename to build (if not specified, build all)') > build_parser.add_argument('-I', '--indir', action='append', > diff --git a/tools/binman/control.py b/tools/binman/control.py > index 0dbcbc28e9..f95aadd1f3 100644 > --- a/tools/binman/control.py > +++ b/tools/binman/control.py > @@ -8,6 +8,7 @@ > from collections import OrderedDict > import glob > import os > +import pathlib > import pkg_resources > import re > > @@ -401,6 +402,17 @@ def ReplaceEntries(image_fname, input_fname, indir, > entry_paths, > return image > > > +def PrepareFakeExtBlobs(images): Please add a function comment > +for (_, image) in images.items(): > +for entry in image._entries.values(): > +if entry.allow_dummy: > +if not pathlib.Path(entry._filename).is_file(): > +tout.Warning("Missing external blob '%s', fake it" % > + entry._filename) > +with open(entry._filename, "wb") as out: > +out.truncate(1024) Won't this create files for all external blobs that are missing? Is that the intent? If so, we can do this in Entry_blob.ObtainContents(). Should we use a size of 0? Or will that make some tools complain? > + > + > def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded): > """Prepare the images to be processed and select the device tree > > @@ -629,6 +641,10 @@ def Binman(args): > > images = PrepareImagesAndDtbs(dtb_fname, args.image, >args.update_fdt, use_expanded) > + > +if args.fake_ext_blobs: > +PrepareFakeExtBlobs(images) This should go in ProcessImage(). See the SetAllowMissing() and see if you can follow the same pattern. Basically we tell each section that it should allow missing blobs, then check that in Entry_blot.ObtainContents() > + > if args.test_section_timeout: > # Set the first image to timeout, used in testThreadTimeout() > images[list(images.keys())[0]].test_section_timeout = True > diff --git a/tools/binman/entry.py b/tools/binman/entry.py > index 70222718ea..2f5c38d15a 100644 > --- a/tools/binman/entry.py > +++ b/tools/binman/entry.py > @@ -100,6 +100,7 @@ class Entry(object): > self.missing = False > self.external = False > self.allow_missing = False > +self.allow_dummy = False Please add a comment about this above. > > @staticmethod > def Lookup(node_path, etype, expanded): > diff --git a/tools/binman/etype/blob_ext.py b/tools/binman/etype/blob_ext.py > index d6b0ca17c3..85bc9fe6b8 100644 > --- a/tools/binman/etype/blob_ext.py > +++ b/tools/binman/etype/blob_ext.py > @@ -26,3 +26,4 @@ class Entry_blob_ext(Entry_blob): > def __init__(self, section, etype, node): > Ent
Re: [PATCH u-boot-marvell 02/10] arm: mvebu: a38x: serdes: Move non-serdes PCIe code to pci_mvebu.c
On Friday 19 November 2021 07:55:00 Stefan Roese wrote: > On 11/18/21 19:01, Pali Rohár wrote: > > On Friday 12 November 2021 15:01:57 Stefan Roese wrote: > > > On 11/11/21 16:35, Marek Behún wrote: > > > > From: Pali Rohár > > > > > > > > As explained in commit 3bedbcc3aa18 ("arm: mvebu: a38x: serdes: Don't > > > > overwrite read-only SAR PCIe registers") it is required to set Maximum > > > > Link > > > > Width bits of PCIe Root Port Link Capabilities Register depending of > > > > number > > > > of used serdes lanes. As this register is part of PCIe address space and > > > > not serdes address space, move it into pci_mvebu.c driver. > > > > > > > > Read number of PCIe lanes from DT propery "num-lanes" which is used > > > > also by > > > > other PCIe controller drivers in Linux kernel. If this property is > > > > absent. > > > > default to 1. This property needs to be set to 4 for every mvebu board > > > > which use PEX_ROOT_COMPLEX_X4. Currently in U-Boot there is no such > > > > board. > > > > > > > > Signed-off-by: Pali Rohár > > > > Signed-off-by: Marek Behún > > > > --- > > > >arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 4 > > > >.../serdes/a38x/high_speed_env_spec.c | 15 --- > > > >drivers/pci/pci_mvebu.c| 18 > > > > ++ > > > >3 files changed, 18 insertions(+), 19 deletions(-) > > > > > > I'm wondering now, if and how this works on Armada XP, which uses the > > > same PCIe driver but a different serdes/axp/*. Did you take this into > > > account? > > > > It looks like that axp serdes code also touches register of PCIe Root > > Ports, e.g. in section /* 6.2 PCI Express Link Capabilities */. So it is > > something which could be improved and cleaned. But it should not cause > > any issue if registers are configures two times, once in serdes code and > > once in pci-mvebu.c code. Moreover registers in pci-mvebu space, > > including config space of PCIe Root Ports are reconfigured by kernel, so > > I think that it should not cause any issue. > > I assume that the AXP serdes code is very similar to the A38x code that > you recently overhauled very thoroughly. For the AXP serdes code, I know > that the PCIe link is already established in the serdes code right now. > And since we had some link-up issues on the theadorable AXP board, we > have been trying to optimize / tune this in this ugly serdes code at few > years ago. From what I understand, you've removed all this PCIe specific > code in the A38x serdes part, so that the link establishment now happens > in the PCIe driver itself (pci_mvebu.c). Which makes perfect sense IMHO. > > Since A38x and AXP share the same PCIe driver in U-Boot, I would very > much like to see some similar changes being made to the AXP serdes code > as well, so that the link establishment solely will happen for all > these platforms in the PCIe driver. I have looked into AXP serdes code and seems to be similar mess like it was in A38x serdes code. Unfortunately I do not want to touch this code and do movement without heavy hardware testing as it can be easy to break. And I do not have Theadorable board for testing. Anyway, all changes done in pci_mvebu.c driver just configures registers to correct or expected values, so they should have low probability of breaking existing hardware... > > But what could cause issues is X1 vs X4 configuration in pci-mvebu.c if > > "num-lanes" property is not properly set. As is mentioned in commit > > message there is no A38x board in U-Boot which uses X4. > > > > Now with your comment for Armada XP I checked that serdes code and find > > out that AXP uses macro 'PEX_BUS_MODE_X4' for X4 mode (A38x serdes uses > > PEX_ROOT_COMPLEX_X4). And in U-Boot there are two boards which sets this > > macro: board/Synology/ds414/ds414.c and board/theadorable/theadorable.c > > > > So it would be needed to adjust this patch for these two boards. Please > > hold this one patch for now. I will try to prepare new fixed version. > > Other patches should be OK and independent of this one. > > Thanks. And yes, theadorable has one x4 and one x1. I think that this change should be enough: diff --git a/arch/arm/dts/armada-xp-synology-ds414.dts b/arch/arm/dts/armada-xp-synology-ds414.dts index 861967cd7e87..35909e3c69c6 100644 --- a/arch/arm/dts/armada-xp-synology-ds414.dts +++ b/arch/arm/dts/armada-xp-synology-ds414.dts @@ -187,6 +187,7 @@ pcie@1,0 { /* Port 0, Lane 0 */ status = "okay"; + num-lanes = <4>; }; /* diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index 6a1df870ab56..726676b3e1d5 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -202,5 +202,6 @@ pcie@9,0 { /* Port 2, Lane 0 */ status = "okay"; + num-lanes = <4>; }; }; Aft
Re: [RFC] binman: add support for creating dummy files for external blobs
Hi Stefano, Am Di., 23. Nov. 2021 um 16:44 Uhr schrieb Stefano Babic : > > On 23.11.21 16:29, Tom Rini wrote: > > On Tue, Nov 16, 2021 at 11:47:10AM +0100, Heiko Thiery wrote: > > > >> While converting to binman for an imx8mq board, it has been found that > >> building in the u-boot CI fails. This is because an imx8mq requires an > >> external binary (signed_hdmi_imx8m.bin). If this file cannot be found > >> mkimage fails. > >> To be able to build this board in the u-boot CI a binman option > >> (--fake-ext-blobs) is introduced that can be switched on via the u-boot > >> makefile option BINMAN_FAKE_EXT_BLOBS. With that the needed dummy files are > >> created. > >> > >> Signed-off-by: Heiko Thiery > >> --- > >> Makefile | 1 + > >> tools/binman/cmdline.py| 2 ++ > >> tools/binman/control.py| 16 > >> tools/binman/entry.py | 1 + > >> tools/binman/etype/blob_ext.py | 1 + > >> 5 files changed, 21 insertions(+) > > > > Since this ends up being a problem for a number of boards, does anyone > > have comments on this? At first glance, this seems reasonable to me, > > and a follow-up making CI make use of this would be handy to finish > > evaluating. > > It looks reasonable for me and it is not different as we did before > binman reporting warnings that the binary does not work. Fine if thsi > can be merged, I will unblock some i.MX boards (Heiko's for example) > that I cannot currently merge due to CI failures. Before you add my patch for the imx8mq board we need to make a change in buildman to make the binman flag option "--fake-ext-blobs" usable. I haven't done that yet, because I wanted to wait if this patch will be accepted. -- Heiko
Re: [RFC] binman: add support for creating dummy files for external blobs
On 23.11.21 16:29, Tom Rini wrote: On Tue, Nov 16, 2021 at 11:47:10AM +0100, Heiko Thiery wrote: While converting to binman for an imx8mq board, it has been found that building in the u-boot CI fails. This is because an imx8mq requires an external binary (signed_hdmi_imx8m.bin). If this file cannot be found mkimage fails. To be able to build this board in the u-boot CI a binman option (--fake-ext-blobs) is introduced that can be switched on via the u-boot makefile option BINMAN_FAKE_EXT_BLOBS. With that the needed dummy files are created. Signed-off-by: Heiko Thiery --- Makefile | 1 + tools/binman/cmdline.py| 2 ++ tools/binman/control.py| 16 tools/binman/entry.py | 1 + tools/binman/etype/blob_ext.py | 1 + 5 files changed, 21 insertions(+) Since this ends up being a problem for a number of boards, does anyone have comments on this? At first glance, this seems reasonable to me, and a follow-up making CI make use of this would be handy to finish evaluating. It looks reasonable for me and it is not different as we did before binman reporting warnings that the binary does not work. Fine if thsi can be merged, I will unblock some i.MX boards (Heiko's for example) that I cannot currently merge due to CI failures. Regards, Stefano -- = DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de =
Re: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults
On Tue, Nov 23, 2021 at 03:02:45AM +, Peng Fan (OSS) wrote: > > Subject: Re: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults > > > > On Mon, Nov 22, 2021 at 11:33:27AM +0800, Peng Fan (OSS) wrote: > > > + Rob > > > > > > On 2021/11/20 20:57, Tom Rini wrote: > > > > On Sat, Nov 20, 2021 at 12:10:54PM +, Peng Fan (OSS) wrote: > > > > > > Subject: [PATCH V2] clk: introduce u-boot,ignore-clk-defaults > > > > > > > > > > > > From: Peng Fan > > > > > > > > > > > > Current code has a force clk_set_defaults in multiple stages, > > > > > > U-Boot reuse the same device tree and Linux Kernel device tree, > > > > > > but we not register all the clks as Linux Kernel, so > > > > > > clk_set_defaults will fail and cause the clk provider registeration > > > > > > fail. > > > > > > > > > > > > So introduce a new property to ignore the default settings which > > > > > > could be used by any node that wanna ignore default settings. > > > > > > > > > > > > Reviewed-by: Simon Glass > > > > > > Signed-off-by: Peng Fan > > > > > > --- > > > > > > > > > > > > V2: > > > > > > Add R-b tag > > > > > > Tom, Simon > > > > > > After a thought, I think still put it as a u-boot thing. > > assigned-clock-x is > > > > > > actually Linux specific, however I could not add the new > > > > > > property > > to Linux, > > > > > > because we are supporting SystemReady-IR, we need the > > > > > > assigned-clock-x property > > > > > > in linux working and ignore it in U-Boot. > > > > > > > > > > Any more thoughts? > > > > > > > > Just my continued request that you treat this as generic and submit > > > > the binding upstream so it can be in the device tree for the platform. > > > > > > > > > > As Sean said, this is to serve cast that linux and U-Boot use the same > > > device tree, I mean U-Boot runtime export device tree to linux for > > > SR-IR (system-ready IR) booting. > > > > > > Linux needs assigned-clocks to some reason, but U-Boot not need that > > > because the driver not added the support or not a must to have that. > > > > > > Because assigned-clocks failure in U-Boot will cause probe fail now, > > > the device driver will report failure. > > > > > > You mean rename this to "ignore-clk-defaults" or keep > > > "u-boot,ignore-clk-defauls" or "firmware,ignore-clk-defaults" to linux > > > device tree binding? > > > > > > I could try to send to linux kernel with "firmware" as a prefix. > > > > What I mean is that first I'm not seeing the description of the property as > > being clear enough, either in commit message or the binding itself. > > That's why in my mind I keep seeing this as "we set the properties > > linux,assigned-clocks and u-boot,ignore-clk-defaults" and I don't know why > > we need both. Is there not something we can do based on seeing > > linux,assigned-clocks ? Showing something that makes use of the property > > you're wishing to add would be helpful. In fact, some specific dts snippets > > would be helpful to understand what's going on here. > > clk: clock-controller@3038 { > compatible = "fsl,imx8mp-ccm"; > reg = <0x3038 0x1>; > #clock-cells = <1>; > clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>, > <&clk_ext3>, <&clk_ext4>; > clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", > "clk_ext3", "clk_ext4"; > assigned-clocks = <&clk IMX8MP_CLK_A53_SRC>, > <&clk IMX8MP_CLK_A53_CORE>, > <&clk IMX8MP_CLK_NOC>, > <&clk IMX8MP_CLK_NOC_IO>, > <&clk IMX8MP_CLK_GIC>, > <&clk IMX8MP_CLK_AUDIO_AHB>, > <&clk IMX8MP_CLK_AUDIO_AXI_SRC>, > <&clk IMX8MP_CLK_IPG_AUDIO_ROOT>, > <&clk IMX8MP_AUDIO_PLL1>, > <&clk IMX8MP_AUDIO_PLL2>; > assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, > <&clk IMX8MP_ARM_PLL_OUT>, > <&clk IMX8MP_SYS_PLL2_1000M>, > <&clk IMX8MP_SYS_PLL1_800M>, > <&clk IMX8MP_SYS_PLL2_500M>, > <&clk IMX8MP_SYS_PLL1_800M>, > <&clk IMX8MP_SYS_PLL1_800M>; > assigned-clock-rates = <0>, <0>, ><10>, ><8>, ><5>, ><4>, ><8>, ><4>, ><393216000>, ><361267200>; > u-boot,ignore-clk-defaults; > }; > > The above node is that I wanna have in U-Boot device tree. > This node is same as the one used in linux device tree except the new > pro
Re: Please pull u-boot-net/next [v3]
On Tue, Nov 23, 2021 at 11:04:18AM +0200, Ramon Fried wrote: > Hi, Tom. > > this PR includes the following net changes for next: > > - Various DSA additions > - bootp: fix for VCI string > - tsec: support for promiscuous mode > - add Aspeed MDIO driver > > Changed: > v2: removed netlist patch. > v3: rebased on origin/next > > > The following changes since commit f9bab982ae9e459b4e64c8a4ca8569aac32bb3bf: > > Revert "nvme: Enable FUA" (2021-11-18 20:18:34 -0500) > > are available in the Git repository at: > > https://source.denx.de/u-boot/custodians/u-boot-net.git/ > > for you to fetch changes up to f11513d9978719820998ac05ed5a5da32465f926: > > net: phy: realtek: Add tx/rx delay config for 8211e (2021-11-23 > 09:57:56 +0200) > Applied to u-boot/next, thanks! -- Tom signature.asc Description: PGP signature
Re: [RFC] binman: add support for creating dummy files for external blobs
On Tue, Nov 16, 2021 at 11:47:10AM +0100, Heiko Thiery wrote: > While converting to binman for an imx8mq board, it has been found that > building in the u-boot CI fails. This is because an imx8mq requires an > external binary (signed_hdmi_imx8m.bin). If this file cannot be found > mkimage fails. > To be able to build this board in the u-boot CI a binman option > (--fake-ext-blobs) is introduced that can be switched on via the u-boot > makefile option BINMAN_FAKE_EXT_BLOBS. With that the needed dummy files are > created. > > Signed-off-by: Heiko Thiery > --- > Makefile | 1 + > tools/binman/cmdline.py| 2 ++ > tools/binman/control.py| 16 > tools/binman/entry.py | 1 + > tools/binman/etype/blob_ext.py | 1 + > 5 files changed, 21 insertions(+) Since this ends up being a problem for a number of boards, does anyone have comments on this? At first glance, this seems reasonable to me, and a follow-up making CI make use of this would be handy to finish evaluating. -- Tom signature.asc Description: PGP signature
Re: [RFC PATCH 0/5] Exception handling in HYP mode on ARMv7-A
On Sun, Oct 24, 2021 at 07:58:03PM -0400, Jim Posen wrote: > Currently, when U-Boot is running in hypervisor mode on ARMv7-A CPUs > with virtualization extensions, the exception handling does not work. > A couple things need to change which are detailed in my earlier > message to the u-boot mailing list with the subject "Exception > handling in HYP mode on ARMv7-A". > > I have verified that this patch series works on the ODroid XU4 and > the Raspberry Pi 3B in Aarch32 mode when running in hypervisor mode. > One simple way to verify is by running the miscellaneous "exception" > command (CMD_EXCEPTION). > > > Jim Posen (5): > Compile for ARMv7-A with virtualization extensions > Hypervisor mode interrupt vector table > Set HVBAR register correctly > Remove dead code > Fix PC adjustment logic in exception handlers > > arch/arm/Makefile | 4 + > arch/arm/cpu/armv7/start.S| 5 ++ > arch/arm/include/asm/u-boot-arm.h | 14 ++-- > arch/arm/lib/interrupts.c | 26 +++--- > arch/arm/lib/relocate.S | 8 ++ > arch/arm/lib/vectors.S| 129 +++--- > arch/arm/mach-bcm283x/Kconfig | 3 + > arch/arm/mach-exynos/Kconfig | 1 + > 8 files changed, 139 insertions(+), 51 deletions(-) This all seems fine, but I don't know enough about the specifics here to comment on the implementation. Is there any we we could also test this via QEMU for example? -- Tom signature.asc Description: PGP signature
Re: [PATCH v2] board: stemmy: Increase boot image to 64 MB
On Sat, Nov 20, 2021 at 11:55:42PM +0100, Linus Walleij wrote: > When using a recent kernel with a bunch of compiled-in > stuff the kernel image easily becomes bigger than 8 MB > yielding this error: > > Loading Kernel Image > Image too large: increase CONFIG_SYS_BOOTM_LEN > Must RESET board to recover > > Fix this by bumping to SZ_64MB. > > Cc: Stephan Gerhold > Signed-off-by: Linus Walleij Great, thanks for changing it! :) Reviewed-by: Stephan Gerhold > --- > ChangeLog v1->v2: > - Bump to 64MB instead of 16MB > --- > include/configs/stemmy.h | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/include/configs/stemmy.h b/include/configs/stemmy.h > index ed79b1203901..4bba2a627259 100644 > --- a/include/configs/stemmy.h > +++ b/include/configs/stemmy.h > @@ -14,6 +14,7 @@ > * bootloader. New images are loaded at the same address for compatibility. > */ > #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE > +#define CONFIG_SYS_BOOTM_LEN SZ_64M > > /* FIXME: This should be loaded from device tree... */ > #define CONFIG_SYS_L2_PL310 > -- > 2.31.1 >
RE: [EXT] RE: [PATCH v5 11/16] crypto/fsl: Fix kick_trng
Hello Michael > -Original Message- > From: Michael Walle > Sent: Tuesday, November 23, 2021 4:22 PM > To: Gaurav Jain > Cc: ZHIZHIKIN Andrey ; u- > b...@lists.denx.de; Stefano Babic ; Fabio Estevam > ; Peng Fan ; Simon Glass > ; Priyanka Jain ; Ye Li > ; Horia Geanta ; Ji Luo > ; Franck Lenormand ; > Silvano Di Ninno ; Sahil Malhotra > ; Pankaj Gupta ; Varun > Sethi ; dl-uboot-imx ; Shengzhou > Liu ; Mingkai Hu ; Rajesh > Bhagat ; Meenakshi Aggarwal > ; Wasim Khan ; > Alison Wang ; Pramod Kumar > ; Andy Tang ; Adrian > Alonso ; Vladimir Oltean > Subject: Re: [EXT] RE: [PATCH v5 11/16] crypto/fsl: Fix kick_trng > > Caution: EXT Email > > Hi Gaurav, > > Am 2021-11-23 11:44, schrieb Gaurav Jain: > >> > fix hwrng performance issue in kernel. > >> > >> This patch is missing some context information, specifically which > >> performance issue does exist in the Kernel (with some > >> quantification), and how is it addressed here. > >> > >> This function introduced with this patch already exist in the Kernel > >> [1], and the implementation does differ from Kernel one. > >> Specifically, this patch lowers the number of test samples that are > >> run to decide whether the entropy generated by TRNG is sufficiently > >> random: it reduces the monobit count range, poker test limits, and > >> number or runs for consecutive 0's and 1's. > >> > >> Considering the fact that after TRNG is initialized - JDKEK, TDKEK > >> and TDSK are preloaded from the RNG and are locked until the next > >> PoR, Kernel will not re- initialize the TRNG (in fact, there is a > >> check that is done in the Kernel not to touch RNG if it is already > >> initialized [2]), and this would leave the Crypto facilities running > >> in the Kernel to use entropy model that is defined here. In this > >> case, at least a justification of this change should be made clear - > >> e.g. > >> significant speed > >> improvement over reduced entropy (with quantifiable numbers). > >> > >> In addition, with those new parameter set, would the RNG pass FIPS > >> 140-2 test? > > TRNG is configured to pass FIPS certification, but will double check > > and confirm you. > > > > You are correct if RNG is instantiated in Uboot then kernel will not > > reinitialize. > > 77% performance drop was observed on IMX6/7/8 platforms (0.3 kB/s) > > compared to 1.3kB/s. > > With this change hwrng performance improved to 1.3 kB/s. > > Did you test on other platforms like layerscape, too? Can we be sure there > will no impact with this change on other platforms which uses the CAAM > TRNG? > Yes I tested Layerscape as well. I tested hwrng, blob encap/decap which works good. > I have to agree with Andrey, there is little information *why* this is done in > exactly this way. I'd love to see a proper commit description and comments > here. I just see a bunch of magic numbers in the code. > Will update the commit description in next version of this patch series. Regards Gaurav Jain > -michael
[v2] [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements
Firmwares before U-Boot may be capable of doing tpm measurements and passing them to U-Boot in the form of eventlog. However there may be scenarios where the firmwares don't have TPM driver and are not capable of extending the measurements in the PCRs. Based on TCG spec, if previous firnware has extended PCR's, PCR0 would not be 0. So, read the PCR0 to determine if the PCR's need to be extended as eventlog is parsed or not. Signed-off-by: Ruchika Gupta --- v2 : Removed check for PCR0 in eventlog lib/efi_loader/efi_tcg2.c | 77 +++ 1 file changed, 77 insertions(+) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index c3ebdf92f5..133fe8291a 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -199,6 +199,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, return EFI_SUCCESS; } +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values + * + * @dev: device + * @digest_list: list of digest algorithms to extend + * + * @Return: status code + */ +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + struct tpm_chip_priv *priv; + unsigned int updates, pcr_select_min; + u32 rc; + size_t i; + + priv = dev_get_uclass_priv(dev); + if (!priv) + return EFI_DEVICE_ERROR; + + pcr_select_min = priv->pcr_select_min; + + for (i = 0; i < digest_list->count; i++) { + u16 hash_alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, + hash_alg, digest, alg_to_len(hash_alg), + &updates); + if (rc) { + EFI_PRINT("Failed to read PCR\n"); + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + /* put_event - Append an agile event to an eventlog * * @pcr_index: PCR index @@ -1427,6 +1464,8 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, u32 pcr, pos; u64 base; u32 sz; + bool extend_pcr = false; + int i; ret = platform_get_eventlog(dev, &base, &sz); if (ret == EFI_SUCCESS) { @@ -1447,6 +1486,26 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, return EFI_COMPROMISED_DATA; } + ret = tcg2_pcr_read(dev, 0, &digest_list); + if (ret) { + log_err("Error reading PCR 0\n"); + return ret; + } + + /* +* If PCR0 is 0, previous firmware didn't have the capability +* to extend the PCR. In this scenario, extend the PCR as +* the eventlog is parsed. +*/ + for (i = 0; i < digest_list.count; i++) { + u8 buffer[TPM2_DIGEST_LEN] = { 0 }; + u16 hash_alg = digest_list.digests[i].hash_alg; + + if (!memcmp((u8 *)&digest_list.digests[i].digest, + buffer, alg_to_len(hash_alg))) + extend_pcr = true; + } + while (pos < sz) { ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, &pcr); @@ -1454,6 +1513,24 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, log_err("Error parsing event\n"); return ret; } + + if (extend_pcr) { + ret = tcg2_pcr_extend(dev, pcr, &digest_list); + if (ret != EFI_SUCCESS) { + log_err("Error in extending PCR\n"); + return ret; + } + + /* Clear the digest for next event */ + for (i = 0; i < digest_list.count; i++) { + u16 hash_alg = + digest_list.digests[i].hash_alg; + u8 *digest = + (u8 *)&digest_list.digests[i].digest; + + memset(digest, 0, alg_to_len(hash_alg)); + } + } } memcpy(log_buffer, buffer, sz); -- 2.25.1
[v2] [PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read
The current tpm2_pcr_read is hardcoded using SHA256. Make the actual command to TPM configurable to use wider range of algorithms. The current command line is kept as is i.e limited to SHA-256 only. Signed-off-by: Ruchika Gupta --- v2: Change algorithm from u32 to u16 Add parameter description in function declaration cmd/tpm-v2.c | 3 ++- include/tpm-v2.h | 5 - lib/tpm-v2.c | 12 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index daae91100a..4ea5f9f094 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); - rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); + rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, + data, TPM2_DIGEST_LEN, &updates); if (!rc) { printf("PCR #%u content (%u known updates):\n", index, updates); print_byte_string(data, TPM2_DIGEST_LEN); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ceff7d245e..4e9dd52cb6 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, * @devTPM device * @idxIndex of the PCR * @idx_min_sz Minimum size in bytes of the pcrSelect array + * @algorithm Algorithm used, defined in 'enum tpm2_algorithms' * @data Output buffer for contents of the named PCR + * @digest_len len of the data * @updatesOptional out parameter: number of updates for this PCR * * @return code of the operation */ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates); + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates); /** * Issue a TPM2_GetCapability command. This implementation is limited diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 2e7b27bd6b..1bf627853a 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, } u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates) + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates) { u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, /* TPML_PCR_SELECTION */ tpm_u32(1), /* Number of selections */ - tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + tpm_u16(algorithm), /* Algorithm of the hash */ idx_array_sz, /* Array size for selection */ /* bitmap(idx) Selected PCR bitmap */ }; @@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, if (ret) return ret; + if (digest_len > response_len) + return TPM_LIB_ERROR; + if (unpack_byte_string(response, response_len, "ds", 10, &counter, - response_len - TPM2_DIGEST_LEN, data, - TPM2_DIGEST_LEN)) + response_len - digest_len, data, + digest_len)) return TPM_LIB_ERROR; if (updates) -- 2.25.1
[v2][PATCH 1/3] efi_loader: Add check for event log passed from firmware
Platforms may have support to measure their initial firmware components and pass the event log to u-boot. The event log address can be passed in property tpm_event_log_addr and tpm_event_log_size of the tpm node. Platforms may choose their own specific mechanism to do so. A weak function is added to check if even log has been passed to u-boot from earlier firmware components. If available, the eventlog is parsed to check for its correctness and further event logs are appended to the passed log. Signed-off-by: Ruchika Gupta --- v2: Moved firmware eventlog code parsing to tcg2_get_fw_eventlog() lib/efi_loader/efi_tcg2.c | 322 -- 1 file changed, 308 insertions(+), 14 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 8c1f22e337..c3ebdf92f5 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -324,6 +324,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev) return EFI_NOT_FOUND; } +/** + * platform_get_eventlog() - retrieve the eventlog address and size + * + * This function retrieves the eventlog address and size if the underlying + * firmware has done some measurements and passed them. + * + * This function may be overridden based on platform specific method of + * passing the eventlog address and size. + * + * @dev: udevice + * @addr: eventlog address + * @sz:eventlog size + * Return: status code + */ +__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, + u32 *sz) +{ + const u64 *basep; + const u32 *sizep; + + basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); + if (!basep) + return EFI_NOT_FOUND; + + *addr = be64_to_cpup((__force __be64 *)basep); + + sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); + if (!sizep) + return EFI_NOT_FOUND; + + *sz = be32_to_cpup((__force __be32 *)sizep); + if (*sz == 0) { + log_debug("event log empty\n"); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + /** * tpm2_get_max_command_size() - get the supported max command size * @@ -1181,6 +1220,249 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = { .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, }; +/** + * parse_event_log_header() - Parse and verify the event log header fields + * + * @buffer:Pointer to the event header + * @size: Size of the eventlog + * @pos: Position in buffer after event log header + * + * Return: status code + */ +efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) +{ + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + int i = 0; + + if (size < sizeof(*event_header)) + return EFI_COMPROMISED_DATA; + + if (get_unaligned_le32(&event_header->pcr_index) != 0 || + get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) + return EFI_COMPROMISED_DATA; + + for (i = 0; i < sizeof(event_header->digest); i++) { + if (event_header->digest[i] != 0) + return EFI_COMPROMISED_DATA; + } + + *pos += sizeof(*event_header); + + return EFI_SUCCESS; +} + +/** + * parse_specid_event() - Parse and verify the specID Event in the eventlog + * + * @dev: udevice + * @buffer:Pointer to the start of the eventlog + * @log_size: Size of the eventlog + * @pos: Offset in the evenlog where specID event starts + * + * Return: status code + * @posOffset in the eventlog where the specID event ends + * @digest_list: list of digests in the event + */ +efi_status_t parse_specid_event(struct udevice *dev, void *buffer, u32 log_size, + u32 *pos, + struct tpml_digest_values *digest_list) +{ + struct tcg_efi_spec_id_event *spec_event; + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + size_t spec_event_size; + u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; + u32 spec_active = 0; + u16 hash_alg, hash_sz; + u8 vendor_sz; + int err, i; + + /* Check specID event data */ + spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos); + /* Check for signature */ + if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { + log_err("specID Event: Signature mismatch\n"); + return EFI_COMPROMISED_DATA; + } + + if (spec_event->spec_version_minor != + TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || +
[v2] [PATCH 3/3] efi_loader: Extend PCR's for firmware measurements
Firmwares before U-Boot may be capable of doing tpm measurements and passing them to U-Boot in the form of eventlog. However there may be scenarios where the firmwares don't have TPM driver and are not capable of extending the measurements in the PCRs. Based on TCG spec, if previous firnware has extended PCR's, PCR0 would not be 0. So, read the PCR0 to determine if the PCR's need to be extended as eventlog is parsed or not. Signed-off-by: Ruchika Gupta --- v2 : Removed check for PCR0 in eventlog lib/efi_loader/efi_tcg2.c | 77 +++ 1 file changed, 77 insertions(+) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index c3ebdf92f5..133fe8291a 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -199,6 +199,43 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, return EFI_SUCCESS; } +/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values + * + * @dev: device + * @digest_list: list of digest algorithms to extend + * + * @Return: status code + */ +static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + struct tpm_chip_priv *priv; + unsigned int updates, pcr_select_min; + u32 rc; + size_t i; + + priv = dev_get_uclass_priv(dev); + if (!priv) + return EFI_DEVICE_ERROR; + + pcr_select_min = priv->pcr_select_min; + + for (i = 0; i < digest_list->count; i++) { + u16 hash_alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, + hash_alg, digest, alg_to_len(hash_alg), + &updates); + if (rc) { + EFI_PRINT("Failed to read PCR\n"); + return EFI_DEVICE_ERROR; + } + } + + return EFI_SUCCESS; +} + /* put_event - Append an agile event to an eventlog * * @pcr_index: PCR index @@ -1427,6 +1464,8 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, u32 pcr, pos; u64 base; u32 sz; + bool extend_pcr = false; + int i; ret = platform_get_eventlog(dev, &base, &sz); if (ret == EFI_SUCCESS) { @@ -1447,6 +1486,26 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, return EFI_COMPROMISED_DATA; } + ret = tcg2_pcr_read(dev, 0, &digest_list); + if (ret) { + log_err("Error reading PCR 0\n"); + return ret; + } + + /* +* If PCR0 is 0, previous firmware didn't have the capability +* to extend the PCR. In this scenario, extend the PCR as +* the eventlog is parsed. +*/ + for (i = 0; i < digest_list.count; i++) { + u8 buffer[TPM2_DIGEST_LEN] = { 0 }; + u16 hash_alg = digest_list.digests[i].hash_alg; + + if (!memcmp((u8 *)&digest_list.digests[i].digest, + buffer, alg_to_len(hash_alg))) + extend_pcr = true; + } + while (pos < sz) { ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, &pcr); @@ -1454,6 +1513,24 @@ efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, log_err("Error parsing event\n"); return ret; } + + if (extend_pcr) { + ret = tcg2_pcr_extend(dev, pcr, &digest_list); + if (ret != EFI_SUCCESS) { + log_err("Error in extending PCR\n"); + return ret; + } + + /* Clear the digest for next event */ + for (i = 0; i < digest_list.count; i++) { + u16 hash_alg = + digest_list.digests[i].hash_alg; + u8 *digest = + (u8 *)&digest_list.digests[i].digest; + + memset(digest, 0, alg_to_len(hash_alg)); + } + } } memcpy(log_buffer, buffer, sz); -- 2.25.1
[v2] [PATCH 2/3] tpm: use more algorithms than sha256 on pcr_read
The current tpm2_pcr_read is hardcoded using SHA256. Make the actual command to TPM configurable to use wider range of algorithms. The current command line is kept as is i.e limited to SHA-256 only. Signed-off-by: Ruchika Gupta --- v2: Change algorithm from u32 to u16 Add parameter description in function declaration cmd/tpm-v2.c | 3 ++- include/tpm-v2.h | 5 - lib/tpm-v2.c | 12 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index daae91100a..4ea5f9f094 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); - rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); + rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, + data, TPM2_DIGEST_LEN, &updates); if (!rc) { printf("PCR #%u content (%u known updates):\n", index, updates); print_byte_string(data, TPM2_DIGEST_LEN); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ceff7d245e..4e9dd52cb6 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, * @devTPM device * @idxIndex of the PCR * @idx_min_sz Minimum size in bytes of the pcrSelect array + * @algorithm Algorithm used, defined in 'enum tpm2_algorithms' * @data Output buffer for contents of the named PCR + * @digest_len len of the data * @updatesOptional out parameter: number of updates for this PCR * * @return code of the operation */ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates); + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates); /** * Issue a TPM2_GetCapability command. This implementation is limited diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 2e7b27bd6b..1bf627853a 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, } u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, - void *data, unsigned int *updates) + u16 algorithm, void *data, u32 digest_len, + unsigned int *updates) { u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); u8 command_v2[COMMAND_BUFFER_SIZE] = { @@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, /* TPML_PCR_SELECTION */ tpm_u32(1), /* Number of selections */ - tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + tpm_u16(algorithm), /* Algorithm of the hash */ idx_array_sz, /* Array size for selection */ /* bitmap(idx) Selected PCR bitmap */ }; @@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, if (ret) return ret; + if (digest_len > response_len) + return TPM_LIB_ERROR; + if (unpack_byte_string(response, response_len, "ds", 10, &counter, - response_len - TPM2_DIGEST_LEN, data, - TPM2_DIGEST_LEN)) + response_len - digest_len, data, + digest_len)) return TPM_LIB_ERROR; if (updates) -- 2.25.1
[v2][PATCH 1/3] efi_loader: Add check for event log passed from firmware
Platforms may have support to measure their initial firmware components and pass the event log to u-boot. The event log address can be passed in property tpm_event_log_addr and tpm_event_log_size of the tpm node. Platforms may choose their own specific mechanism to do so. A weak function is added to check if even log has been passed to u-boot from earlier firmware components. If available, the eventlog is parsed to check for its correctness and further event logs are appended to the passed log. Signed-off-by: Ruchika Gupta --- v2: Moved firmware eventlog code parsing to tcg2_get_fw_eventlog() lib/efi_loader/efi_tcg2.c | 322 -- 1 file changed, 308 insertions(+), 14 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 8c1f22e337..c3ebdf92f5 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -324,6 +324,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev) return EFI_NOT_FOUND; } +/** + * platform_get_eventlog() - retrieve the eventlog address and size + * + * This function retrieves the eventlog address and size if the underlying + * firmware has done some measurements and passed them. + * + * This function may be overridden based on platform specific method of + * passing the eventlog address and size. + * + * @dev: udevice + * @addr: eventlog address + * @sz:eventlog size + * Return: status code + */ +__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, + u32 *sz) +{ + const u64 *basep; + const u32 *sizep; + + basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); + if (!basep) + return EFI_NOT_FOUND; + + *addr = be64_to_cpup((__force __be64 *)basep); + + sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); + if (!sizep) + return EFI_NOT_FOUND; + + *sz = be32_to_cpup((__force __be32 *)sizep); + if (*sz == 0) { + log_debug("event log empty\n"); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + /** * tpm2_get_max_command_size() - get the supported max command size * @@ -1181,6 +1220,249 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = { .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, }; +/** + * parse_event_log_header() - Parse and verify the event log header fields + * + * @buffer:Pointer to the event header + * @size: Size of the eventlog + * @pos: Position in buffer after event log header + * + * Return: status code + */ +efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) +{ + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + int i = 0; + + if (size < sizeof(*event_header)) + return EFI_COMPROMISED_DATA; + + if (get_unaligned_le32(&event_header->pcr_index) != 0 || + get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) + return EFI_COMPROMISED_DATA; + + for (i = 0; i < sizeof(event_header->digest); i++) { + if (event_header->digest[i] != 0) + return EFI_COMPROMISED_DATA; + } + + *pos += sizeof(*event_header); + + return EFI_SUCCESS; +} + +/** + * parse_specid_event() - Parse and verify the specID Event in the eventlog + * + * @dev: udevice + * @buffer:Pointer to the start of the eventlog + * @log_size: Size of the eventlog + * @pos: Offset in the evenlog where specID event starts + * + * Return: status code + * @posOffset in the eventlog where the specID event ends + * @digest_list: list of digests in the event + */ +efi_status_t parse_specid_event(struct udevice *dev, void *buffer, u32 log_size, + u32 *pos, + struct tpml_digest_values *digest_list) +{ + struct tcg_efi_spec_id_event *spec_event; + struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; + size_t spec_event_size; + u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; + u32 spec_active = 0; + u16 hash_alg, hash_sz; + u8 vendor_sz; + int err, i; + + /* Check specID event data */ + spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos); + /* Check for signature */ + if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { + log_err("specID Event: Signature mismatch\n"); + return EFI_COMPROMISED_DATA; + } + + if (spec_event->spec_version_minor != + TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || +
[PATCH] pci: layerscape: update the searching compatible of LX2160A PCIe
From: Hou Zhiqiang The current fixup of LX2160A PCIe nodes is based on non-production rev1 silicon, and in Linux the nodes have been updated for rev2 silicon, so update the searching compatible string to match the kernel changes. And for compatibility with the rev1 nodes, move forward the board specific fixup. Signed-off-by: Hou Zhiqiang --- drivers/pci/Kconfig | 4 +--- drivers/pci/pcie_layerscape_fixup.c | 7 +++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index ba41787f64..16647bed54 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -219,8 +219,7 @@ config FSL_PCIE_COMPAT default "fsl,ls1046a-pcie" if ARCH_LS1046A default "fsl,ls2080a-pcie" if ARCH_LS2080A default "fsl,ls1088a-pcie" if ARCH_LS1088A - default "fsl,lx2160a-pcie" if ARCH_LX2160A - default "fsl,ls2088a-pcie" if ARCH_LX2162A + default "fsl,ls2088a-pcie" if ARCH_LX2160A || ARCH_LX2162A default "fsl,ls1021a-pcie" if ARCH_LS1021A help This compatible is used to find pci controller node in Kernel DT @@ -229,7 +228,6 @@ config FSL_PCIE_COMPAT config FSL_PCIE_EP_COMPAT string "PCIe EP compatible of Kernel DT" depends on PCIE_LAYERSCAPE_RC || PCIE_LAYERSCAPE_GEN4 - default "fsl,lx2160a-pcie-ep" if ARCH_LX2160A default "fsl,ls-pcie-ep" help This compatible is used to find pci controller ep node in Kernel DT diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index 48aeb50e68..6fdb0ac1d6 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -527,7 +527,7 @@ static void fdt_fixup_pcie_ls(void *blob) } if (!IS_ENABLED(CONFIG_PCI_IOMMU_EXTRA_MAPPINGS)) - goto skip; + return; list_for_each_entry(pcie_rc, &ls_pcie_list, list) { nodeoffset = fdt_pcie_get_nodeoffset(blob, pcie_rc); @@ -568,9 +568,6 @@ static void fdt_fixup_pcie_ls(void *blob) } free(entries); } - -skip: - pcie_board_fix_fdt(blob); } #endif @@ -619,6 +616,8 @@ void ft_pci_setup_ls(void *blob, struct bd_info *bd) { struct ls_pcie_rc *pcie_rc; + pcie_board_fix_fdt(blob); + list_for_each_entry(pcie_rc, &ls_pcie_list, list) ft_pcie_ls_setup(blob, pcie_rc); -- 2.25.1
Re: [EXT] RE: [PATCH v5 11/16] crypto/fsl: Fix kick_trng
Hi Gaurav, Am 2021-11-23 11:44, schrieb Gaurav Jain: > fix hwrng performance issue in kernel. This patch is missing some context information, specifically which performance issue does exist in the Kernel (with some quantification), and how is it addressed here. This function introduced with this patch already exist in the Kernel [1], and the implementation does differ from Kernel one. Specifically, this patch lowers the number of test samples that are run to decide whether the entropy generated by TRNG is sufficiently random: it reduces the monobit count range, poker test limits, and number or runs for consecutive 0's and 1's. Considering the fact that after TRNG is initialized - JDKEK, TDKEK and TDSK are preloaded from the RNG and are locked until the next PoR, Kernel will not re- initialize the TRNG (in fact, there is a check that is done in the Kernel not to touch RNG if it is already initialized [2]), and this would leave the Crypto facilities running in the Kernel to use entropy model that is defined here. In this case, at least a justification of this change should be made clear - e.g. significant speed improvement over reduced entropy (with quantifiable numbers). In addition, with those new parameter set, would the RNG pass FIPS 140-2 test? TRNG is configured to pass FIPS certification, but will double check and confirm you. You are correct if RNG is instantiated in Uboot then kernel will not reinitialize. 77% performance drop was observed on IMX6/7/8 platforms (0.3 kB/s) compared to 1.3kB/s. With this change hwrng performance improved to 1.3 kB/s. Did you test on other platforms like layerscape, too? Can we be sure there will no impact with this change on other platforms which uses the CAAM TRNG? I have to agree with Andrey, there is little information *why* this is done in exactly this way. I'd love to see a proper commit description and comments here. I just see a bunch of magic numbers in the code. -michael
RE: [EXT] RE: [PATCH v5 11/16] crypto/fsl: Fix kick_trng
Hello Andrey > -Original Message- > From: ZHIZHIKIN Andrey > Sent: Tuesday, November 23, 2021 1:15 AM > To: Gaurav Jain ; u-boot@lists.denx.de > Cc: Stefano Babic ; Fabio Estevam ; > Peng Fan ; Simon Glass ; Priyanka > Jain ; Ye Li ; Horia Geanta > ; Ji Luo ; Franck Lenormand > ; Silvano Di Ninno ; > Sahil Malhotra ; Pankaj Gupta > ; Varun Sethi ; dl-uboot-imx > ; Shengzhou Liu ; Mingkai Hu > ; Rajesh Bhagat ; Meenakshi > Aggarwal ; Wasim Khan > ; Alison Wang ; Pramod > Kumar ; Andy Tang ; > Adrian Alonso ; Vladimir Oltean > ; Michael Walle > Subject: [EXT] RE: [PATCH v5 11/16] crypto/fsl: Fix kick_trng > > Caution: EXT Email > > Hello Gaurav, > > > -Original Message- > > From: U-Boot On Behalf Of Gaurav Jain > > Sent: Monday, November 15, 2021 8:00 AM > > To: u-boot@lists.denx.de > > Cc: Stefano Babic ; Fabio Estevam > > ; Peng Fan ; Simon Glass > > ; Priyanka Jain ; Ye Li > > ; Horia Geanta ; Ji Luo > > ; Franck Lenormand ; Silvano > > Di Ninno ; Sahil malhotra > > ; Pankaj Gupta ; Varun > > Sethi ; NXP i . MX U-Boot Team ; > > Shengzhou Liu ; Mingkai Hu > > ; Rajesh Bhagat ; > Meenakshi > > Aggarwal ; Wasim Khan > > ; Alison Wang ; Pramod > Kumar > > ; Tang Yuantian ; Adrian > > Alonso ; Vladimir Oltean > > Subject: [PATCH v5 11/16] crypto/fsl: Fix kick_trng > > > > > > From: Ye Li > > > > fix hwrng performance issue in kernel. > > This patch is missing some context information, specifically which performance > issue does exist in the Kernel (with some quantification), and how is it > addressed > here. > > This function introduced with this patch already exist in the Kernel [1], and > the > implementation does differ from Kernel one. Specifically, this patch lowers > the > number of test samples that are run to decide whether the entropy generated by > TRNG is sufficiently random: it reduces the monobit count range, poker test > limits, and number or runs for consecutive 0's and 1's. > > Considering the fact that after TRNG is initialized - JDKEK, TDKEK and TDSK > are > preloaded from the RNG and are locked until the next PoR, Kernel will not re- > initialize the TRNG (in fact, there is a check that is done in the Kernel not > to > touch RNG if it is already initialized [2]), and this would leave the Crypto > facilities > running in the Kernel to use entropy model that is defined here. In this > case, at > least a justification of this change should be made clear - e.g. significant > speed > improvement over reduced entropy (with quantifiable numbers). > > In addition, with those new parameter set, would the RNG pass FIPS 140-2 test? TRNG is configured to pass FIPS certification, but will double check and confirm you. You are correct if RNG is instantiated in Uboot then kernel will not reinitialize. 77% performance drop was observed on IMX6/7/8 platforms (0.3 kB/s) compared to 1.3kB/s. With this change hwrng performance improved to 1.3 kB/s. > > > > > Signed-off-by: Ye Li > > Acked-by: Gaurav Jain > > > --- > > drivers/crypto/fsl/jr.c | 109 ++-- > > include/fsl_sec.h | 1 + > > 2 files changed, 94 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index > > 9b751aca9b..ef136988b6 100644 > > --- a/drivers/crypto/fsl/jr.c > > +++ b/drivers/crypto/fsl/jr.c > > @@ -602,30 +602,107 @@ static u8 get_rng_vid(ccsr_sec_t *sec) > > */ > > static void kick_trng(int ent_delay, ccsr_sec_t *sec) { > > + u32 samples = 512; /* number of bits to generate and test */ > > + u32 mono_min = 195; > > + u32 mono_max = 317; > > + u32 mono_range = mono_max - mono_min; > > + u32 poker_min = 1031; > > + u32 poker_max = 1600; > > + u32 poker_range = poker_max - poker_min + 1; > > + u32 retries= 2; > > + u32 lrun_max = 32; > > + s32 run_1_min = 27; > > + s32 run_1_max = 107; > > + s32 run_1_range = run_1_max - run_1_min; > > + s32 run_2_min = 7; > > + s32 run_2_max = 62; > > + s32 run_2_range = run_2_max - run_2_min; > > + s32 run_3_min = 0; > > + s32 run_3_max = 39; > > + s32 run_3_range = run_3_max - run_3_min; > > + s32 run_4_min = -1; > > + s32 run_4_max = 26; > > + s32 run_4_range = run_4_max - run_4_min; > > + s32 run_5_min = -1; > > + s32 run_5_max = 18; > > + s32 run_5_range = run_5_max - run_5_min; > > + s32 run_6_min = -1; > > + s32 run_6_max = 17; > > + s32 run_6_range = run_6_max - run_6_min; > > + u32 val; > > Why does those values are lowered with respect to what is provided by default? > A bit more explanation on why those primes are chosen here would be good to > have, together with documenting default values (so people can compare). For TRNG to generate 256 bits of entropy, recommended RTSDCTL[SAMP_SIZE] is 512. RTSDCTL[SAMP_SIZE] is changed from default POR value 2500 to 5
Re: [PATCH 1/2] riscv: Support booting SiFive Unmatched from SPI.
Hi Thomas, This patch does not apply. Could you rebase this patchset onto master and then send it again? Thanks! Best regards, Leo On Mon, Sep 27, 2021 at 12:59:37PM -0700, Thomas Skibo wrote: > Configure SPI flash devices into SPL. Add SPI boot option to spl.c. > Document how to format flash for booting. > > Signed-off-by: Thomas Skibo > Reviewed-by: Leo Yu-Chi Liang > --- > .../dts/hifive-unmatched-a00-u-boot.dtsi | 11 +++ > board/sifive/unmatched/spl.c | 3 ++ > configs/sifive_unmatched_defconfig| 6 > doc/board/sifive/unmatched.rst| 29 +++ > 4 files changed, 49 insertions(+)
RE: [PATCH] board: ls1043ardb: force PCI device enumeration
> -Original Message- > From: U-Boot On Behalf Of Martin Schiller > Sent: Tuesday, November 23, 2021 8:28 > To: u-boot@lists.denx.de > Cc: Martin Schiller ; Priyanka Jain > ; Camelia Alexandra Groza > > Subject: [PATCH] board: ls1043ardb: force PCI device enumeration > > Commit eb1986804d1d ("configs: enable DM_ETH support for LS1043ARDB") > resulted in the PCI bus no longer being implicitly enumerated. > > However, this is necessary for the fdt pcie fixups to work. > > Therefore, similar to commit 8b6558bd4187 ("board: ls1088ardb: > transition to DM_ETH"), pci_init() is now called in the board_init() > routine when CONFIG_DM_ETH is active. > > Signed-off-by: Martin Schiller > CC: Priyanka Jain > CC: Camelia Groza > --- > board/freescale/ls1043ardb/ls1043ardb.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/board/freescale/ls1043ardb/ls1043ardb.c > b/board/freescale/ls1043ardb/ls1043ardb.c > index beef26b084..1764c9336c 100644 > --- a/board/freescale/ls1043ardb/ls1043ardb.c > +++ b/board/freescale/ls1043ardb/ls1043ardb.c > @@ -219,6 +219,10 @@ int board_init(void) > ppa_init(); > #endif > > +#if !defined(CONFIG_SYS_EARLY_PCI_INIT) && defined(CONFIG_DM_ETH) > + pci_init(); > +#endif > + > #ifdef CONFIG_U_QE > u_qe_init(); > #endif Thanks for the fix. Acked-by: Camelia Groza
RE: [EXT] RE: [PATCH v5 01/16] crypto/fsl: Add support for CAAM Job ring driver model
Hello Gaurav, > -Original Message- > From: Gaurav Jain > Sent: Tuesday, November 23, 2021 8:22 AM > To: ZHIZHIKIN Andrey ; u- > b...@lists.denx.de > Cc: Stefano Babic ; Fabio Estevam ; Peng > Fan > ; Simon Glass ; Priyanka Jain > ; Ye Li ; Horia Geanta > ; Ji Luo ; Franck Lenormand > ; Silvano Di Ninno ; Sahil > Malhotra ; Pankaj Gupta ; Varun > Sethi ; dl-uboot-imx ; Shengzhou Liu > ; Mingkai Hu ; Rajesh Bhagat > ; Meenakshi Aggarwal ; > Wasim > Khan ; Alison Wang ; Pramod Kumar > ; Andy Tang ; Adrian Alonso > ; Vladimir Oltean ; Michael Walle > > Subject: RE: [EXT] RE: [PATCH v5 01/16] crypto/fsl: Add support for CAAM Job > ring > driver model > > > Hello Andrey > [snip] > > > > > > HAB is a code that is part of the ROM code which set the JR DID for all > i.mx8M. > > > I took the dumps on SPL boot which actually shows the JR DID set by HAB. > > > Dump taken by you on kernel boot does not show the values set by ROM. > > > IMX8MM > > > JR0DID_MS = 0x8011 > > > JR1DID_MS = 0x8011 > > > JR2DID_MS = 0x0 > > > > > > IMX8MN > > > JR0DID_MS = 0x8011 > > > JR1DID_MS = 0x8011 > > > JR2DID_MS = 0x0 > > > > > > IMX8MP > > > JR0DID_MS = 0x8011 > > > JR1DID_MS = 0x8011 > > > JR2DID_MS = 0x0 > > > > This is an interesting piece of information, thanks a lot for the readout! > > So > it > > does look like that BootROM on all derivatives reserves JR0 and JR1 at the > > beginning, letting the ATF to release only JR1 to NS world... > > > > Does IMX8MQ have the same reservation as well? > > > > > > > > > > > With New implementation CAAM is enabled for i.MX8M derivative. Any > > > > > JR whose DID is written in ATF, can be used in Uboot. > > > > > JR0 is reserved for HAB so JR1 will be used for all i.MX8M > > > > > derivatives. > > > > > > > > > > > > > > > > > I'm wondering about several points here: > > > > > > 1. Why does current implementation on have this reservation done > > > > > > on imx8mm and > > > > > >where does this happen? None of the code pieces suggests that > > > > > > it is > > > > done in > > > > > >U-Boot, is it performed in BootROM? > > > > > > > > > > I cannot see if current implementation(SPL/Uboot) has reservation > > > > > done for imx8mm. > > > > > In ATF, we are reserving the JR0. > > > > > > > > I was not able to identify which part of ATF code is responsible to > > > > program JR0DID_MS on imx8mm, the only thing I saw was the part where > > > > the JR0 is held in S World *if* the JR0DID_MS is set to 0x8011. Can > > > > you point out where is this performed in ATF code? > > > > > > > > If it is not in the ATF, then my question above still stands: which > > > > component (HW or SW) programs JR0DID_MS, and why is it only done on > > > > imx8mm derivative? > > > HAB which is part of the ROM code sets the JR DID for all i.mx8M. > > > > > > > > > > > > > > > 2. What is the intention of having JR0 reserved for all > > > > > > derivatives? Is > > > this > > > > > >the part of a bigger change that stretches across different > > > > > > SW > > > > components > > > > > >(e.g. ATF, OP-TEE, etc.)? If that is the case - then a more > > > > > > detailed > > > > > >description would be appreciated here. > > > > > > > > > > > > ATF code already accounts for this reservation in commit: > > > > > > a83a7c65e ("TEE-639 plat: imx8m: Do not release JR0 to NS if HAB > > > > > > is using it") [1], but there is no description on why is this > > > > > > required > though. > > > > > > > > > > > > If this is required for HAB feature, then the question is: > > > > > > should it be kept in > > > > > S > > > > > > World when U-Boot starts, or SPL can release it after the binary > > > > > > is verified > > > > > and > > > > > > crypto facilities are not in use anymore? > > > > > > > > > > Commit: a83a7c65e reserves JR0 for HAB and not released to NS but > > > > > JR1, > > > > > JR2 are released to NS. > > > > > > > > Then I believe this change should be in-sync with ATF > > > > implementation, because of the fact that your change can have any > > > > arbitrary JR to be held in S World. > > > > > > > > What would happen if for example JR1 is programmed with TZ_OWN, but > > > > ATF releases it to NS world? Can it be used by Kernel afterwards? Or > > > > should the node be disabled here so that Kernel does not even see JR1 > during > > boot? > > > > > > > Since JR0 is marked as disabled in DT, so SPL is only accessing single > > > job ring and setting the JR1 DID as 0x8011. > > > After SPL boots successfully, ATF is releasing JR1 and JR2 to NS by > > > modifying the JRDID_MS as 0x1. > > > Uboot is also accessing single jobring which is JR1. > > > JR0 is only reserved for secure boot. > > > > Is it safe to assume that JR1 is then accessible from both S and NS Worlds? > > > > If that is the case, then that would actually mean that JRx status on DT > > should > be > > set as following: > > > > &sec_jr0 { > > status = "disabled"; > > secure-status = "okay"; > > }; > > > > &sec