Merge tag 'efi-2025-01-rc1-2' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request efi-2025-01-rc1-2
CI: https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/22810
Documentation:
* Add document describing Ethernet boot on AM62x SoC
* Fix typo in blkmap command example
UEFI:
* Avoid #ifdef in efi_setup.c
* Reduce message noisiness if ESP is missing
* Remove ERROR:, WARNING: prefixes in messages
* Use blk_create_devicef() in block device driver
Others:
* Let CONFIG_CMD_WGET depend on CONFIG_CMD_NET
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 813640d..3ff1b44 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -1,7 +1,7 @@
variables:
- windows_vm: windows-2019
- ubuntu_vm: ubuntu-22.04
- macos_vm: macOS-12
+ windows_vm: windows-2022
+ ubuntu_vm: ubuntu-24.04
+ macos_vm: macOS-14
ci_runner_image: trini/u-boot-gitlab-ci-runner:jammy-20240808-21Aug2024
# Add '-u 0' options for Azure pipelines, otherwise we get "permission
# denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer",
diff --git a/.mailmap b/.mailmap
index 952e1da..4d48349 100644
--- a/.mailmap
+++ b/.mailmap
@@ -38,7 +38,8 @@
Christian Kohn <chris.kohn@amd.com> <christian.kohn@xilinx.com>
Dirk Behme <dirk.behme@googlemail.com>
Durga Challa <durga.challa@amd.com> <vnsl.durga.challa@xilinx.com>
-Eugen Hristev <eugen.hristev@collabora.com> <eugen.hristev@microchip.com>
+Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@microchip.com>
+Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@collabora.com>
Fabio Estevam <fabio.estevam@nxp.com>
Harini Katakam <harini.katakam@amd.com> <harini.katakam@xilinx.com>
Harsha <harsha.harsha@amd.com> <harsha.harsha@xilinx.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index eef6353..5734037 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -916,6 +916,7 @@
M: Simon Glass <sjg@chromium.org>
M: Alper Nebi Yasak <alpernebiyasak@gmail.com>
S: Maintained
+F: doc/develop/binman_tests.rst
F: tools/binman/
BLKMAP
diff --git a/Makefile b/Makefile
index 7f76292..6b9c00b 100644
--- a/Makefile
+++ b/Makefile
@@ -1384,7 +1384,11 @@
of_list_dirs := $(dir $(EXT_DTB))
else
of_list := $(CONFIG_OF_LIST)
+ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
+of_list_dirs := $(dt_dir) arch/$(ARCH)/dts
+else
of_list_dirs := $(dt_dir)
+endif
default_dt := $(if $(DEVICE_TREE),$(DEVICE_TREE),$(CONFIG_DEFAULT_DEVICE_TREE))
endif
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index bad7731..8b9ced1 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -961,8 +961,6 @@
imx8mp-dhcom-som-overlay-eth2xfast.dtbo \
imx8mp-dhcom-pdk-overlay-eth2xfast.dtbo \
imx8mp-dhcom-drc02.dtb \
- imx8mp-dhcom-pdk2.dtb \
- imx8mp-dhcom-pdk3.dtb \
imx8mp-dhcom-pdk3-overlay-rev100.dtbo \
imx8mp-dhcom-picoitx.dtb \
imx8mp-icore-mx8mp-edimm2.2.dtb \
diff --git a/arch/arm/dts/imx8mp-dhcom-pdk2.dts b/arch/arm/dts/imx8mp-dhcom-pdk2.dts
deleted file mode 100644
index 8f4eff3..0000000
--- a/arch/arm/dts/imx8mp-dhcom-pdk2.dts
+++ /dev/null
@@ -1,158 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2022 Marek Vasut <marex@denx.de>
- *
- * DHCOM iMX8MP variant:
- * DHCM-iMX8ML8-C160-R409-F1638-SPI16-GE-CAN2-SD-RTC-WBTA-ADC-T-RGB-CSI2-HS-I-01D2
- * DHCOM PCB number: 660-100 or newer
- * PDK2 PCB number: 516-400 or newer
- */
-
-/dts-v1/;
-
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/phy/phy-imx8-pcie.h>
-#include "imx8mp-dhcom-som.dtsi"
-
-/ {
- model = "DH electronics i.MX8M Plus DHCOM Premium Developer Kit (2)";
- compatible = "dh,imx8mp-dhcom-pdk2", "dh,imx8mp-dhcom-som",
- "fsl,imx8mp";
-
- chosen {
- stdout-path = &uart1;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- button-0 {
- gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; /* GPIO A */
- label = "TA1-GPIO-A";
- linux,code = <KEY_A>;
- pinctrl-0 = <&pinctrl_dhcom_a>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-1 {
- gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; /* GPIO B */
- label = "TA2-GPIO-B";
- linux,code = <KEY_B>;
- pinctrl-0 = <&pinctrl_dhcom_b>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-2 {
- gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; /* GPIO C */
- label = "TA3-GPIO-C";
- linux,code = <KEY_C>;
- pinctrl-0 = <&pinctrl_dhcom_c>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-3 {
- gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; /* GPIO D */
- label = "TA4-GPIO-D";
- linux,code = <KEY_D>;
- pinctrl-0 = <&pinctrl_dhcom_d>;
- pinctrl-names = "default";
- wakeup-source;
- };
- };
-
- led {
- compatible = "gpio-leds";
-
- led-0 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* GPIO E */
- pinctrl-0 = <&pinctrl_dhcom_e>;
- pinctrl-names = "default";
- };
-
- led-1 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* GPIO F */
- pinctrl-0 = <&pinctrl_dhcom_f>;
- pinctrl-names = "default";
- };
-
- led-2 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; /* GPIO H */
- pinctrl-0 = <&pinctrl_dhcom_h>;
- pinctrl-names = "default";
- };
-
- led-3 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* GPIO I */
- pinctrl-0 = <&pinctrl_dhcom_i>;
- pinctrl-names = "default";
- };
- };
-};
-
-&fec { /* Second ethernet */
- pinctrl-0 = <&pinctrl_fec_rgmii>;
- phy-handle = <ðphypdk>;
- phy-mode = "rgmii";
-
- mdio {
- ethphypdk: ethernet-phy@7 { /* KSZ 9021 */
- compatible = "ethernet-phy-ieee802.3-c22";
- pinctrl-0 = <&pinctrl_ethphy1>;
- pinctrl-names = "default";
- interrupt-parent = <&gpio4>;
- interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
- max-speed = <100>;
- reg = <7>;
- reset-assert-us = <1000>;
- reset-deassert-us = <1000>;
- reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
- rxc-skew-ps = <3000>;
- rxd0-skew-ps = <0>;
- rxd1-skew-ps = <0>;
- rxd2-skew-ps = <0>;
- rxd3-skew-ps = <0>;
- rxdv-skew-ps = <0>;
- txc-skew-ps = <3000>;
- txd0-skew-ps = <0>;
- txd1-skew-ps = <0>;
- txd2-skew-ps = <0>;
- txd3-skew-ps = <0>;
- txen-skew-ps = <0>;
- };
- };
-};
-
-&flexcan1 {
- status = "okay";
-};
-
-&usb3_1 {
- fsl,over-current-active-low;
-};
-
-&iomuxc {
- /*
- * GPIO_A,B,C,D are connected to buttons.
- * GPIO_E,F,H,I are connected to LEDs.
- * GPIO_M is connected to CLKOUT2.
- */
- pinctrl-0 = <&pinctrl_hog_base
- &pinctrl_dhcom_g &pinctrl_dhcom_j
- &pinctrl_dhcom_k &pinctrl_dhcom_l
- &pinctrl_dhcom_int>;
-};
diff --git a/arch/arm/dts/imx8mp-dhcom-pdk3.dts b/arch/arm/dts/imx8mp-dhcom-pdk3.dts
deleted file mode 100644
index 867d238..0000000
--- a/arch/arm/dts/imx8mp-dhcom-pdk3.dts
+++ /dev/null
@@ -1,317 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2023 Marek Vasut <marex@denx.de>
- *
- * DHCOM iMX8MP variant:
- * DHCM-iMX8ML8-C160-R409-F1638-SPI16-GE-CAN2-SD-RTC-WBTA-ADC-T-RGB-CSI2-HS-I-01D2
- * DHCOM PCB number: 660-100 or newer
- * PDK3 PCB number: 669-100 or newer
- */
-
-/dts-v1/;
-
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/phy/phy-imx8-pcie.h>
-#include "imx8mp-dhcom-som.dtsi"
-
-/ {
- model = "DH electronics i.MX8M Plus DHCOM Premium Developer Kit (3)";
- compatible = "dh,imx8mp-dhcom-pdk3", "dh,imx8mp-dhcom-som",
- "fsl,imx8mp";
-
- chosen {
- stdout-path = &uart1;
- };
-
- clk_ext_audio_codec: clock-codec {
- #clock-cells = <0>;
- clock-frequency = <24000000>;
- compatible = "fixed-clock";
- };
-
- clk_xtal25: clk-xtal25 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <25000000>;
- };
-
- connector {
- compatible = "usb-c-connector";
- label = "USB-C";
- data-role = "dual";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- usb_c_0_hs_ep: endpoint {
- remote-endpoint = <&dwc3_0_hs_ep>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- usb_c_0_ss_ep: endpoint {
- remote-endpoint = <&ptn5150_in_ep>;
- };
- };
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- button-0 {
- gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; /* GPIO A */
- label = "TA1-GPIO-A";
- linux,code = <KEY_A>;
- pinctrl-0 = <&pinctrl_dhcom_a>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-1 {
- gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; /* GPIO B */
- label = "TA2-GPIO-B";
- linux,code = <KEY_B>;
- pinctrl-0 = <&pinctrl_dhcom_b>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-2 {
- gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; /* GPIO C */
- label = "TA3-GPIO-C";
- linux,code = <KEY_C>;
- pinctrl-0 = <&pinctrl_dhcom_c>;
- pinctrl-names = "default";
- wakeup-source;
- };
-
- button-3 {
- gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; /* GPIO E */
- label = "TA4-GPIO-E";
- linux,code = <KEY_E>;
- pinctrl-0 = <&pinctrl_dhcom_e>;
- pinctrl-names = "default";
- wakeup-source;
- };
- };
-
- led {
- compatible = "gpio-leds";
-
- led-0 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <0>;
- gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; /* GPIO D */
- pinctrl-0 = <&pinctrl_dhcom_d>;
- pinctrl-names = "default";
- };
-
- led-1 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <1>;
- gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* GPIO F */
- pinctrl-0 = <&pinctrl_dhcom_f>;
- pinctrl-names = "default";
- };
-
- led-2 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <2>;
- gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; /* GPIO G */
- pinctrl-0 = <&pinctrl_dhcom_g>;
- pinctrl-names = "default";
- };
-
- led-3 {
- color = <LED_COLOR_ID_GREEN>;
- default-state = "off";
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <3>;
- gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* GPIO I */
- pinctrl-0 = <&pinctrl_dhcom_i>;
- pinctrl-names = "default";
- };
- };
-
- reg_avdd: regulator-avdd { /* AUDIO_VDD */
- compatible = "regulator-fixed";
- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-name = "AUDIO_VDD";
- };
-};
-
-&i2c5 {
- i2cmux@70 {
- compatible = "nxp,pca9540";
- reg = <0x70>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2cmuxed0: i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- typec@3d {
- compatible = "nxp,ptn5150";
- reg = <0x3d>;
- interrupt-parent = <&gpio4>;
- interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ptn5150>;
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- ptn5150_in_ep: endpoint {
- remote-endpoint = <&usb_c_0_ss_ep>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- ptn5150_out_ep: endpoint {
- remote-endpoint = <&dwc3_0_ss_ep>;
- };
- };
- };
- };
-
- power-sensor@40 {
- compatible = "ti,ina238";
- reg = <0x40>;
- shunt-resistor = <20000>; /* 0.02 R */
- ti,shunt-gain = <1>; /* Drop cca. 40mV */
- };
-
- eeprom_board: eeprom@54 {
- compatible = "atmel,24c04";
- pagesize = <16>;
- reg = <0x54>;
- };
-
- pcieclk: clk@6b {
- compatible = "skyworks,si52144";
- reg = <0x6b>;
- clocks = <&clk_xtal25>;
- #clock-cells = <1>;
- };
- };
-
- i2cmuxed1: i2c@1 { /* HDMI DDC I2C */
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
- };
-};
-
-&fec { /* Second ethernet */
- pinctrl-0 = <&pinctrl_fec_rgmii>;
- phy-handle = <ðphypdk>;
- phy-mode = "rgmii-id";
-
- mdio {
- ethphypdk: ethernet-phy@7 { /* Micrel KSZ9131RNXI */
- compatible = "ethernet-phy-id0022.1642",
- "ethernet-phy-ieee802.3-c22";
- interrupt-parent = <&gpio4>;
- interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-0 = <&pinctrl_ethphy1>;
- pinctrl-names = "default";
- reg = <7>;
- reset-assert-us = <1000>;
- /* RESET_N signal rise time ~100ms */
- reset-deassert-us = <120000>;
- reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
- status = "okay";
- };
- };
-};
-
-&flexcan1 {
- status = "okay";
-};
-
-&pcie_phy {
- clocks = <&pcieclk 1>;
- clock-names = "ref";
- fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
- status = "okay";
-};
-
-&pcie {
- fsl,max-link-speed = <3>;
- reset-gpio = <&gpio1 6 GPIO_ACTIVE_LOW>;
- status = "okay";
-};
-
-&usb_dwc3_0 {
- usb-role-switch;
-
- port {
- #address-cells = <1>;
- #size-cells = <0>;
-
- dwc3_0_hs_ep: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&usb_c_0_hs_ep>;
- };
-
- dwc3_0_ss_ep: endpoint@1 {
- reg = <1>;
- remote-endpoint = <&ptn5150_out_ep>;
- };
- };
-};
-
-&usb3_1 {
- fsl,disable-port-power-control;
- fsl,permanently-attached;
-};
-
-&usb_dwc3_1 {
- /* This port has USB5734 Hub connected to it, PWR/OC pins are unused */
- /delete-property/ pinctrl-names;
- /delete-property/ pinctrl-0;
-};
-
-&iomuxc {
- /*
- * GPIO_A,B,C,E are connected to buttons.
- * GPIO_D,F,G,I are connected to LEDs.
- * GPIO_H is connected to USB Hub RESET_N.
- * GPIO_M is connected to CLKOUT2.
- */
- pinctrl-0 = <&pinctrl_hog_base
- &pinctrl_dhcom_h &pinctrl_dhcom_j &pinctrl_dhcom_k
- &pinctrl_dhcom_l
- &pinctrl_dhcom_int>;
-
- pinctrl_ptn5150: ptn5150grp {
- fsl,pins = <
- MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25 0x40000000
- >;
- };
-};
diff --git a/arch/arm/mach-at91/include/mach/clk.h b/arch/arm/mach-at91/include/mach/clk.h
index c1d9273..09b8f05 100644
--- a/arch/arm/mach-at91/include/mach/clk.h
+++ b/arch/arm/mach-at91/include/mach/clk.h
@@ -11,6 +11,7 @@
#include <asm/arch/hardware.h>
#include <asm/arch/at91_pmc.h>
#include <asm/global_data.h>
+#include <asm/io.h>
#define GCK_CSS_SLOW_CLK 0
#define GCK_CSS_MAIN_CLK 1
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index c50df5f..7056cfd 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -55,9 +55,10 @@
void board_boot_order(u32 *spl_boot_list)
{
+ struct sandbox_state *state = state_get_current();
+
spl_boot_list[0] = BOOT_DEVICE_VBE;
- spl_boot_list[1] = BOOT_DEVICE_UPL;
- spl_boot_list[2] = BOOT_DEVICE_BOARD;
+ spl_boot_list[1] = state->upl ? BOOT_DEVICE_UPL : BOOT_DEVICE_BOARD;
}
static int spl_board_load_file(struct spl_image_info *spl_image,
diff --git a/arch/sandbox/dts/cedit.dtsi b/arch/sandbox/dts/cedit.dtsi
index 9bd84e6..facd7a4 100644
--- a/arch/sandbox/dts/cedit.dtsi
+++ b/arch/sandbox/dts/cedit.dtsi
@@ -39,6 +39,9 @@
/* IDs for the menu items */
item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+
+ /* values for the menu items */
+ item-value = <0 3 6>;
};
power-loss {
diff --git a/arch/sandbox/dts/sandbox_pmic.dtsi b/arch/sandbox/dts/sandbox_pmic.dtsi
index 565c382..ff2cb42 100644
--- a/arch/sandbox/dts/sandbox_pmic.dtsi
+++ b/arch/sandbox/dts/sandbox_pmic.dtsi
@@ -10,6 +10,7 @@
&sandbox_pmic {
compatible = "sandbox,pmic";
+ sandbox,emul = <&emul_pmic0>;
buck1 {
regulator-name = "SUPPLY_1.2V";
diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c
index 8746374..8127d31 100644
--- a/arch/x86/cpu/broadwell/cpu.c
+++ b/arch/x86/cpu/broadwell/cpu.c
@@ -88,18 +88,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- char processor_name[CPU_MAX_NAME_LEN];
- const char *name;
-
- /* Print processor name */
- name = cpu_get_name(processor_name);
- printf("CPU: %s\n", name);
-
- return 0;
-}
-
void board_debug_uart_init(void)
{
/* com1 / com2 decode range */
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
index c3d7442..fa7430b 100644
--- a/arch/x86/cpu/coreboot/coreboot.c
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -38,16 +38,6 @@
return 0;
}
-int checkcpu(void)
-{
- return 0;
-}
-
-int print_cpuinfo(void)
-{
- return default_print_cpuinfo();
-}
-
static void board_final_init(void)
{
/*
@@ -82,6 +72,8 @@
static int last_stage_init(void)
{
+ timestamp_add_to_bootstage();
+
if (IS_ENABLED(CONFIG_XPL_BUILD))
return 0;
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
index ec4003c..681191d 100644
--- a/arch/x86/cpu/coreboot/timestamp.c
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -6,13 +6,12 @@
*/
#include <bootstage.h>
+#include <errno.h>
#include <asm/arch/timestamp.h>
#include <asm/cb_sysinfo.h>
#include <asm/u-boot-x86.h>
#include <linux/compiler.h>
-static struct timestamp_table *ts_table __section(".data");
-
void timestamp_init(void)
{
timestamp_add_now(TS_U_BOOT_INITTED);
@@ -20,6 +19,8 @@
void timestamp_add(enum timestamp_id id, uint64_t ts_time)
{
+ const struct sysinfo_t *info = cb_get_sysinfo();
+ struct timestamp_table *ts_table = info->tstamp_table;
struct timestamp_entry *tse;
if (!ts_table || (ts_table->num_entries == ts_table->max_entries))
@@ -37,13 +38,15 @@
int timestamp_add_to_bootstage(void)
{
+ const struct sysinfo_t *info = cb_get_sysinfo();
+ const struct timestamp_table *ts_table = info->tstamp_table;
uint i;
if (!ts_table)
- return -1;
+ return -ENOENT;
for (i = 0; i < ts_table->num_entries; i++) {
- struct timestamp_entry *tse = &ts_table->entries[i];
+ const struct timestamp_entry *tse = &ts_table->entries[i];
const char *name = NULL;
switch (tse->entry_id) {
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index ea11b09..a8b2140 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -163,8 +163,11 @@
return ptr;
}
-int default_print_cpuinfo(void)
+#if !CONFIG_IS_ENABLED(CPU)
+int print_cpuinfo(void)
{
+ post_code(POST_CPU_INFO);
+
printf("CPU: %s, vendor %s, device %xh\n",
cpu_has_64bit() ? "x86_64" : "x86",
cpu_vendor_name(gd->arch.x86_vendor), gd->arch.x86_device);
@@ -176,6 +179,7 @@
return 0;
}
+#endif
#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
void show_boot_progress(int val)
@@ -336,7 +340,7 @@
}
#endif
-long detect_coreboot_table_at(ulong start, ulong size)
+static long detect_coreboot_table_at(ulong start, ulong size)
{
u32 *ptr, *end;
diff --git a/arch/x86/cpu/cpu_x86.c b/arch/x86/cpu/cpu_x86.c
index 6c53f0e..6c32ae4 100644
--- a/arch/x86/cpu/cpu_x86.c
+++ b/arch/x86/cpu/cpu_x86.c
@@ -7,6 +7,7 @@
#include <dm.h>
#include <errno.h>
#include <asm/cpu.h>
+#include <asm/cpu_x86.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/x86/cpu/efi/app.c b/arch/x86/cpu/efi/app.c
index 218a68c..84fe50e 100644
--- a/arch/x86/cpu/efi/app.c
+++ b/arch/x86/cpu/efi/app.c
@@ -19,11 +19,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- return default_print_cpuinfo();
-}
-
void board_final_init(void)
{
}
diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c
index 642a87a..6845ce7 100644
--- a/arch/x86/cpu/efi/payload.c
+++ b/arch/x86/cpu/efi/payload.c
@@ -144,11 +144,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- return default_print_cpuinfo();
-}
-
/* Find any available tables and copy them to a safe place */
int reserve_arch(void)
{
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c
index d837fb9..a51a244 100644
--- a/arch/x86/cpu/i386/cpu.c
+++ b/arch/x86/cpu/i386/cpu.c
@@ -263,6 +263,49 @@
}
#endif
+int x86_cpu_vendor_info(char *name)
+{
+ uint cpu_device;
+
+ cpu_device = 0;
+
+ /* gcc 7.3 does not want to drop x86_vendors, so use #ifdef */
+#ifndef CONFIG_TPL_BUILD
+ *name = '\0'; /* Unset */
+
+ /* Find the id and vendor_name */
+ if (!has_cpuid()) {
+ /* Its a 486 if we can modify the AC flag */
+ if (flag_is_changeable_p(X86_EFLAGS_AC))
+ cpu_device = 0x00000400; /* 486 */
+ else
+ cpu_device = 0x00000300; /* 386 */
+ if (cpu_device == 0x00000400 && test_cyrix_52div()) {
+ /* If we ever care we can enable cpuid here */
+ memcpy(name, "CyrixInstead", 13);
+
+ /* Detect NexGen with old hypercode */
+ } else if (deep_magic_nexgen_probe()) {
+ memcpy(name, "NexGenDriven", 13);
+ }
+ } else {
+ int cpuid_level;
+
+ cpuid_level = build_vendor_name(name);
+ name[12] = '\0';
+
+ /* Intel-defined flags: level 0x00000001 */
+ if (cpuid_level >= 0x00000001)
+ cpu_device = cpuid_eax(0x00000001);
+ else
+ /* Have CPUID level 0 only unheard of */
+ cpu_device = 0x00000400;
+ }
+#endif /* CONFIG_TPL_BUILD */
+
+ return cpu_device;
+}
+
static void identify_cpu(struct cpu_device_id *cpu)
{
cpu->device = 0; /* fix gcc 4.4.4 warning */
@@ -289,48 +332,21 @@
return;
}
-/* gcc 7.3 does not want to drop x86_vendors, so use #ifdef */
#ifndef CONFIG_TPL_BUILD
- char vendor_name[16];
- int i;
+ {
+ char vendor_name[16];
+ int i;
- vendor_name[0] = '\0'; /* Unset */
+ cpu->device = x86_cpu_vendor_info(vendor_name);
- /* Find the id and vendor_name */
- if (!has_cpuid()) {
- /* Its a 486 if we can modify the AC flag */
- if (flag_is_changeable_p(X86_EFLAGS_AC))
- cpu->device = 0x00000400; /* 486 */
- else
- cpu->device = 0x00000300; /* 386 */
- if ((cpu->device == 0x00000400) && test_cyrix_52div()) {
- memcpy(vendor_name, "CyrixInstead", 13);
- /* If we ever care we can enable cpuid here */
- }
- /* Detect NexGen with old hypercode */
- else if (deep_magic_nexgen_probe())
- memcpy(vendor_name, "NexGenDriven", 13);
- } else {
- int cpuid_level;
-
- cpuid_level = build_vendor_name(vendor_name);
- vendor_name[12] = '\0';
-
- /* Intel-defined flags: level 0x00000001 */
- if (cpuid_level >= 0x00000001) {
- cpu->device = cpuid_eax(0x00000001);
- } else {
- /* Have CPUID level 0 only unheard of */
- cpu->device = 0x00000400;
+ cpu->vendor = X86_VENDOR_UNKNOWN;
+ for (i = 0; i < ARRAY_SIZE(x86_vendors); i++) {
+ if (memcmp(vendor_name, x86_vendors[i].name, 12) == 0) {
+ cpu->vendor = x86_vendors[i].vendor;
+ break;
+ }
}
}
- cpu->vendor = X86_VENDOR_UNKNOWN;
- for (i = 0; i < ARRAY_SIZE(x86_vendors); i++) {
- if (memcmp(vendor_name, x86_vendors[i].name, 12) == 0) {
- cpu->vendor = x86_vendors[i].vendor;
- break;
- }
- }
#endif
}
@@ -485,6 +501,11 @@
return 0;
}
+void x86_get_identity_for_timer(void)
+{
+ setup_identity();
+}
+
void x86_enable_caches(void)
{
unsigned long cr0;
diff --git a/arch/x86/cpu/i386/interrupt.c b/arch/x86/cpu/i386/interrupt.c
index b3f4214..6f78b07 100644
--- a/arch/x86/cpu/i386/interrupt.c
+++ b/arch/x86/cpu/i386/interrupt.c
@@ -237,7 +237,7 @@
return &idt_ptr;
}
-void __do_irq(int irq)
+static void __do_irq(int irq)
{
printf("Unhandled IRQ : %d\n", irq);
}
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 05691a3..d299068 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -182,20 +182,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- char processor_name[CPU_MAX_NAME_LEN];
- const char *name;
-
- /* Print processor name */
- name = cpu_get_name(processor_name);
- printf("CPU: %s\n", name);
-
- post_code(POST_CPU_INFO);
-
- return 0;
-}
-
void board_debug_uart_init(void)
{
/* This enables the debug UART */
diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
index 50cba5f..07ea891 100644
--- a/arch/x86/cpu/mtrr.c
+++ b/arch/x86/cpu/mtrr.c
@@ -87,7 +87,7 @@
}
}
-void mtrr_write_all(struct mtrr_info *info)
+static void mtrr_write_all(struct mtrr_info *info)
{
int reg_count = mtrr_get_var_count();
struct mtrr_state state;
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 262584d..563f63e 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -109,12 +109,6 @@
{
return 0;
}
-
-int print_cpuinfo(void)
-{
- post_code(POST_CPU_INFO);
- return default_print_cpuinfo();
-}
#endif
int arch_early_init_r(void)
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index fdf92b2..07504fa 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -266,12 +266,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- post_code(POST_CPU_INFO);
- return default_print_cpuinfo();
-}
-
static void quark_pcie_init(void)
{
u32 val;
diff --git a/arch/x86/cpu/slimbootloader/slimbootloader.c b/arch/x86/cpu/slimbootloader/slimbootloader.c
index 142c934..8a5c785 100644
--- a/arch/x86/cpu/slimbootloader/slimbootloader.c
+++ b/arch/x86/cpu/slimbootloader/slimbootloader.c
@@ -54,8 +54,3 @@
{
return 0;
}
-
-int print_cpuinfo(void)
-{
- return default_print_cpuinfo();
-}
diff --git a/arch/x86/cpu/tangier/tangier.c b/arch/x86/cpu/tangier/tangier.c
index 8a8f7d2..b005bc7 100644
--- a/arch/x86/cpu/tangier/tangier.c
+++ b/arch/x86/cpu/tangier/tangier.c
@@ -19,8 +19,3 @@
{
return 0;
}
-
-int print_cpuinfo(void)
-{
- return default_print_cpuinfo();
-}
diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
index 80eab71..71bc07f 100644
--- a/arch/x86/cpu/x86_64/cpu.c
+++ b/arch/x86/cpu/x86_64/cpu.c
@@ -75,3 +75,9 @@
/* this was already done in SPL */
}
#endif
+
+void x86_get_identity_for_timer(void)
+{
+ /* set the vendor to Intel so that native_calibrate_tsc() works */
+ gd->arch.x86_vendor = X86_VENDOR_INTEL;
+}
diff --git a/arch/x86/cpu/x86_64/misc.c b/arch/x86/cpu/x86_64/misc.c
index 294511e..fc449ca 100644
--- a/arch/x86/cpu/x86_64/misc.c
+++ b/arch/x86/cpu/x86_64/misc.c
@@ -32,9 +32,4 @@
{
return 0;
}
-
-int print_cpuinfo(void)
-{
- return 0;
-}
#endif
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 87e0c6f..8c1ef4c 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -293,4 +293,11 @@
*/
int cpu_phys_address_size(void);
+void board_final_init(void);
+void board_final_cleanup(void);
+
+#ifndef CONFIG_EFI_STUB
+int reserve_arch(void);
+#endif
+
#endif
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 3acc58a..ed2f6aa 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -44,6 +44,15 @@
int x86_cpu_init_tpl(void);
/**
+ * x86_get_identity_for_timer() - Set up CPU identity for use by the early timer
+ *
+ * The timer can be needed early in board_f if bootstage is enabled. This
+ * function can be called from the TSC timer to make sure that the CPU-identity
+ * info has been set up
+ */
+void x86_get_identity_for_timer(void);
+
+/**
* cpu_reinit_fpu() - Reinit the FPU if something is wrong with it
*
* The FSP-M code can leave registers in use in the FPU. This functions reinits
@@ -51,6 +60,14 @@
*/
void cpu_reinit_fpu(void);
+/**
+ * x86_cpu_vendor_info() - Get the CPU-vendor name and device number
+ *
+ * @name: 13-byte area to hold the returned string
+ * Return: CPU device number read from cpuid
+ */
+int x86_cpu_vendor_info(char *name);
+
int cpu_init_f(void);
void setup_gdt(struct global_data *id, u64 *gdt_addr);
/*
@@ -78,7 +95,6 @@
void x86_disable_caches(void);
int x86_init_cache(void);
phys_addr_t board_get_usable_ram_top(phys_size_t total_size);
-int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */
int setup_internal_uart(int enable);
diff --git a/arch/x86/lib/bdinfo.c b/arch/x86/lib/bdinfo.c
index 165e8ab..2a78f57 100644
--- a/arch/x86/lib/bdinfo.c
+++ b/arch/x86/lib/bdinfo.c
@@ -19,7 +19,12 @@
bdinfo_print_num_l("clock_rate", gd->arch.clock_rate);
bdinfo_print_num_l("tsc_base", gd->arch.tsc_base);
bdinfo_print_num_l("vendor", gd->arch.x86_vendor);
- bdinfo_print_str(" name", cpu_vendor_name(gd->arch.x86_vendor));
+ if (!IS_ENABLED(CONFIG_X86_64)) {
+ char vendor_name[16];
+
+ x86_cpu_vendor_info(vendor_name);
+ bdinfo_print_str(" name", vendor_name);
+ }
bdinfo_print_num_l("model", gd->arch.x86_model);
bdinfo_print_num_l("phys_addr in bits", cpu_phys_address_size());
bdinfo_print_num_l("table start", gd->arch.table_start);
diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c
index c47e6ca..7e4c147 100644
--- a/arch/x86/lib/fsp/fsp_common.c
+++ b/arch/x86/lib/fsp/fsp_common.c
@@ -26,12 +26,6 @@
return 0;
}
-int print_cpuinfo(void)
-{
- post_code(POST_CPU_INFO);
- return default_print_cpuinfo();
-}
-
int fsp_init_phase_pci(void)
{
u32 status;
diff --git a/board/technexion/pico-imx7d/spl.c b/board/technexion/pico-imx7d/spl.c
index cb60d3b..fc97c58 100644
--- a/board/technexion/pico-imx7d/spl.c
+++ b/board/technexion/pico-imx7d/spl.c
@@ -89,11 +89,11 @@
static struct mx7_calibration calib_param = {
.num_val = 5,
.values = {
- 0x0E407304,
- 0x0E447304,
- 0x0E447306,
- 0x0E447304,
- 0x0E447304,
+ 0x0E207304,
+ 0x0E247304,
+ 0x0E247306,
+ 0x0E247304,
+ 0x0E207304,
},
};
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 807f8df..64ec4fd 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -434,6 +434,9 @@
struct uclass *uc;
enum uclass_id id;
+ if (!CONFIG_IS_ENABLED(BLK))
+ return -ENOSYS;
+
ret = label_to_uclass(label, &seq, &method_flags);
if (ret < 0)
return log_msg_ret("uc", ret);
diff --git a/boot/cedit.c b/boot/cedit.c
index c29a2be..d12892f 100644
--- a/boot/cedit.c
+++ b/boot/cedit.c
@@ -51,10 +51,11 @@
int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
{
+ struct expo_arrange_info arr;
struct scene_obj_txt *txt;
struct scene_obj *obj;
struct scene *scn;
- int y;
+ int y, ret;
scn = expo_lookup_scene_id(exp, scene_id);
if (!scn)
@@ -68,6 +69,11 @@
if (txt)
scene_obj_set_pos(scn, txt->obj.id, 200, 10);
+ memset(&arr, '\0', sizeof(arr));
+ ret = scene_calc_arrange(scn, &arr);
+ if (ret < 0)
+ return log_msg_ret("arr", ret);
+
y = 100;
list_for_each_entry(obj, &scn->obj_head, sibling) {
switch (obj->type) {
@@ -77,12 +83,13 @@
break;
case SCENEOBJT_MENU:
scene_obj_set_pos(scn, obj->id, 50, y);
- scene_menu_arrange(scn, (struct scene_obj_menu *)obj);
+ scene_menu_arrange(scn, &arr,
+ (struct scene_obj_menu *)obj);
y += 50;
break;
case SCENEOBJT_TEXTLINE:
scene_obj_set_pos(scn, obj->id, 50, y);
- scene_textline_arrange(scn,
+ scene_textline_arrange(scn, &arr,
(struct scene_obj_textline *)obj);
y += 50;
break;
@@ -147,7 +154,7 @@
struct video_priv *vid_priv;
uint scene_id;
struct scene *scn;
- bool done;
+ bool done, save;
int ret;
cli_ch_init(cch);
@@ -157,6 +164,7 @@
scene_id = ret;
done = false;
+ save = false;
do {
struct expo_action act;
int ichar, key;
@@ -201,6 +209,15 @@
case EXPOACT_OPEN:
scene_set_open(scn, act.select.id, true);
cedit_arange(exp, vid_priv, scene_id);
+ switch (scn->highlight_id) {
+ case EXPOID_SAVE:
+ done = true;
+ save = true;
+ break;
+ case EXPOID_DISCARD:
+ done = true;
+ break;
+ }
break;
case EXPOACT_CLOSE:
scene_set_open(scn, act.select.id, false);
@@ -222,6 +239,8 @@
if (ret)
return log_msg_ret("end", ret);
+ if (!save)
+ return -EACCES;
return 0;
}
@@ -274,11 +293,49 @@
return 0;
}
+/**
+ * get_cur_menuitem_val() - Get the value of a menu's current item
+ *
+ * Obtains the value of the current item in the menu. If no value, then
+ * enumerates the items of a menu (0, 1, 2) and returns the sequence number of
+ * the currently selected item. If the first item is selected, this returns 0;
+ * if the second, 1; etc.
+ *
+ * @menu: Menu to check
+ * @valp: Returns current-item value / sequence number
+ * Return: 0 on success, else -ve error value
+ */
+static int get_cur_menuitem_val(const struct scene_obj_menu *menu, int *valp)
+{
+ const struct scene_menitem *mi;
+ int seq;
+
+ seq = 0;
+ list_for_each_entry(mi, &menu->item_head, sibling) {
+ if (mi->id == menu->cur_item_id) {
+ *valp = mi->value == INT_MAX ? seq : mi->value;
+ return 0;
+ }
+ seq++;
+ }
+
+ return log_msg_ret("nf", -ENOENT);
+}
+
+/**
+ * write_dt_string() - Write a string to the devicetree, expanding if needed
+ *
+ * If this fails, it tries again after expanding the devicetree a little
+ *
+ * @buf: Buffer containing the devicetree
+ * @name: Property name to use
+ * @str: String value
+ * Return: 0 if OK, -EFAULT if something went horribly wrong
+ */
static int write_dt_string(struct abuf *buf, const char *name, const char *str)
{
int ret, i;
- /* write the text of the current item */
ret = -EAGAIN;
for (i = 0; ret && i < 2; i++) {
ret = fdt_property_string(abuf_data(buf), name, str);
@@ -296,6 +353,38 @@
return 0;
}
+/**
+ * write_dt_u32() - Write an int to the devicetree, expanding if needed
+ *
+ * If this fails, it tries again after expanding the devicetree a little
+ *
+ * @buf: Buffer containing the devicetree
+ * @name: Property name to use
+ * @lva: Integer value
+ * Return: 0 if OK, -EFAULT if something went horribly wrong
+ */
+static int write_dt_u32(struct abuf *buf, const char *name, uint val)
+{
+ int ret, i;
+
+ /* write the text of the current item */
+ ret = -EAGAIN;
+ for (i = 0; ret && i < 2; i++) {
+ ret = fdt_property_u32(abuf_data(buf), name, val);
+ if (!i) {
+ ret = check_space(ret, buf);
+ if (ret)
+ return log_msg_ret("rs2", -ENOMEM);
+ }
+ }
+
+ /* this should not happen */
+ if (ret)
+ return log_msg_ret("str", -EFAULT);
+
+ return 0;
+}
+
static int h_write_settings(struct scene_obj *obj, void *vpriv)
{
struct cedit_iter_priv *priv = vpriv;
@@ -320,23 +409,21 @@
const struct scene_obj_menu *menu;
const char *str;
char name[80];
- int i;
+ int val;
/* write the ID of the current item */
menu = (struct scene_obj_menu *)obj;
- ret = -EAGAIN;
- for (i = 0; ret && i < 2; i++) {
- ret = fdt_property_u32(abuf_data(buf), obj->name,
- menu->cur_item_id);
- if (!i) {
- ret = check_space(ret, buf);
- if (ret)
- return log_msg_ret("res", -ENOMEM);
- }
- }
- /* this should not happen */
+ ret = write_dt_u32(buf, obj->name, menu->cur_item_id);
if (ret)
- return log_msg_ret("wrt", -EFAULT);
+ return log_msg_ret("wrt", ret);
+
+ snprintf(name, sizeof(name), "%s-value", obj->name);
+ ret = get_cur_menuitem_val(menu, &val);
+ if (ret < 0)
+ return log_msg_ret("cur", ret);
+ ret = write_dt_u32(buf, name, val);
+ if (ret)
+ return log_msg_ret("wr2", ret);
ret = get_cur_menuitem_text(menu, &str);
if (ret)
@@ -470,6 +557,9 @@
const char *str;
int val, ret;
+ if (obj->id < EXPOID_BASE_ID)
+ return 0;
+
snprintf(var, sizeof(var), "c.%s", obj->name);
switch (obj->type) {
@@ -499,6 +589,14 @@
ret = env_set(name, str);
if (ret)
return log_msg_ret("st2", ret);
+
+ ret = get_cur_menuitem_val(menu, &val);
+ if (ret < 0)
+ return log_msg_ret("cur", ret);
+ snprintf(name, sizeof(name), "c.%s-value", obj->name);
+ if (priv->verbose)
+ printf("%s=%d\n", name, val);
+
break;
case SCENEOBJT_TEXTLINE: {
const struct scene_obj_textline *tline;
@@ -542,6 +640,9 @@
char var[60];
int val;
+ if (obj->id < EXPOID_BASE_ID)
+ return 0;
+
snprintf(var, sizeof(var), "c.%s", obj->name);
switch (obj->type) {
@@ -559,7 +660,7 @@
/*
* note that no validation is done here, to make sure the ID is
- * valid * and actually points to a menu item
+ * valid and actually points to a menu item
*/
menu->cur_item_id = val;
break;
@@ -599,55 +700,23 @@
return 0;
}
-/**
- * get_cur_menuitem_seq() - Get the sequence number of a menu's current item
- *
- * Enumerates the items of a menu (0, 1, 2) and returns the sequence number of
- * the currently selected item. If the first item is selected, this returns 0;
- * if the second, 1; etc.
- *
- * @menu: Menu to check
- * Return: Sequence number on success, else -ve error value
- */
-static int get_cur_menuitem_seq(const struct scene_obj_menu *menu)
-{
- const struct scene_menitem *mi;
- int seq, found;
-
- seq = 0;
- found = -1;
- list_for_each_entry(mi, &menu->item_head, sibling) {
- if (mi->id == menu->cur_item_id) {
- found = seq;
- break;
- }
- seq++;
- }
-
- if (found == -1)
- return log_msg_ret("nf", -ENOENT);
-
- return found;
-}
-
static int h_write_settings_cmos(struct scene_obj *obj, void *vpriv)
{
const struct scene_obj_menu *menu;
struct cedit_iter_priv *priv = vpriv;
int val, ret;
- uint i, seq;
+ uint i;
- if (obj->type != SCENEOBJT_MENU)
+ if (obj->type != SCENEOBJT_MENU || obj->id < EXPOID_BASE_ID)
return 0;
menu = (struct scene_obj_menu *)obj;
val = menu->cur_item_id;
- ret = get_cur_menuitem_seq(menu);
+ ret = get_cur_menuitem_val(menu, &val);
if (ret < 0)
return log_msg_ret("cur", ret);
- seq = ret;
- log_debug("%s: seq=%d\n", menu->obj.name, seq);
+ log_debug("%s: val=%d\n", menu->obj.name, val);
/* figure out where to place this item */
if (!obj->bit_length)
@@ -655,11 +724,11 @@
if (obj->start_bit + obj->bit_length > CMOS_MAX_BITS)
return log_msg_ret("bit", -E2BIG);
- for (i = 0; i < obj->bit_length; i++, seq >>= 1) {
+ for (i = 0; i < obj->bit_length; i++, val >>= 1) {
uint bitnum = obj->start_bit + i;
priv->mask[CMOS_BYTE(bitnum)] |= 1 << CMOS_BIT(bitnum);
- if (seq & 1)
+ if (val & 1)
priv->value[CMOS_BYTE(bitnum)] |= BIT(CMOS_BIT(bitnum));
log_debug("bit %x %x %x\n", bitnum,
priv->mask[CMOS_BYTE(bitnum)],
@@ -693,6 +762,7 @@
}
/* write the data to the RTC */
+ log_debug("Writing CMOS\n");
first = CMOS_MAX_BYTES;
last = -1;
for (i = 0, count = 0; i < CMOS_MAX_BYTES; i++) {
@@ -727,7 +797,7 @@
int val, ret;
uint i;
- if (obj->type != SCENEOBJT_MENU)
+ if (obj->type != SCENEOBJT_MENU || obj->id < EXPOID_BASE_ID)
return 0;
menu = (struct scene_obj_menu *)obj;
@@ -760,7 +830,8 @@
}
/* update the current item */
- mi = scene_menuitem_find_seq(menu, val);
+ log_debug("look for menuitem value %d in menu %d\n", val, menu->obj.id);
+ mi = scene_menuitem_find_val(menu, val);
if (!mi)
return log_msg_ret("seq", -ENOENT);
@@ -794,7 +865,7 @@
goto done;
}
- /* read the data to the RTC */
+ /* indicate what bytes were read from the RTC */
first = CMOS_MAX_BYTES;
last = -1;
for (i = 0, count = 0; i < CMOS_MAX_BYTES; i++) {
diff --git a/boot/expo.c b/boot/expo.c
index ed01483..786f665 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -29,6 +29,7 @@
exp->priv = priv;
INIT_LIST_HEAD(&exp->scene_head);
INIT_LIST_HEAD(&exp->str_head);
+ exp->next_id = EXPOID_BASE_ID;
*expp = exp;
@@ -258,6 +259,8 @@
ofnode_read_u32(node, "font-size", &theme->font_size);
ofnode_read_u32(node, "menu-inset", &theme->menu_inset);
ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y);
+ ofnode_read_u32(node, "menu-title-margin-x",
+ &theme->menu_title_margin_x);
list_for_each_entry(scn, &exp->scene_head, sibling) {
ret = scene_apply_theme(scn, theme);
diff --git a/boot/expo_build.c b/boot/expo_build.c
index a4df798..d97347e 100644
--- a/boot/expo_build.c
+++ b/boot/expo_build.c
@@ -46,7 +46,6 @@
const char *find_name, uint obj_id)
{
const char *text;
- uint str_id;
int ret;
info->err_prop = find_name;
@@ -67,14 +66,9 @@
return log_msg_ret("id", -EINVAL);
}
- ret = expo_str(scn->expo, find_name, 0, text);
+ ret = scene_txt_str(scn, find_name, obj_id, 0, text, NULL);
if (ret < 0)
return log_msg_ret("add", ret);
- str_id = ret;
-
- ret = scene_txt_str(scn, find_name, obj_id, str_id, text, NULL);
- if (ret < 0)
- return log_msg_ret("add", ret);
return ret;
}
@@ -94,7 +88,6 @@
const char *find_name, int index, uint obj_id)
{
const char *text;
- uint str_id;
int ret;
ret = ofnode_read_string_index(node, find_name, index, &text);
@@ -114,12 +107,7 @@
return log_msg_ret("id", -EINVAL);
}
- ret = expo_str(scn->expo, find_name, 0, text);
- if (ret < 0)
- return log_msg_ret("add", ret);
- str_id = ret;
-
- ret = scene_txt_str(scn, find_name, obj_id, str_id, text, NULL);
+ ret = scene_txt_str(scn, find_name, obj_id, 0, text, NULL);
if (ret < 0)
return log_msg_ret("add", ret);
@@ -227,10 +215,10 @@
static int menu_build(struct build_info *info, ofnode node, struct scene *scn,
uint id, struct scene_obj **objp)
{
+ const u32 *item_ids, *item_values;
struct scene_obj_menu *menu;
+ int ret, size, i, num_items;
uint title_id, menu_id;
- const u32 *item_ids;
- int ret, size, i;
const char *name;
name = ofnode_get_name(node);
@@ -254,9 +242,15 @@
return log_msg_ret("itm", -EINVAL);
if (!size || size % sizeof(u32))
return log_msg_ret("isz", -EINVAL);
- size /= sizeof(u32);
+ num_items = size / sizeof(u32);
- for (i = 0; i < size; i++) {
+ item_values = ofnode_read_prop(node, "item-value", &size);
+ if (item_values) {
+ if (size != num_items * sizeof(u32))
+ return log_msg_ret("vsz", -EINVAL);
+ }
+
+ for (i = 0; i < num_items; i++) {
struct scene_menitem *item;
uint label, key, desc;
@@ -280,6 +274,8 @@
desc, 0, 0, &item);
if (ret < 0)
return log_msg_ret("mi", ret);
+ if (item_values)
+ item->value = fdt32_to_cpu(item_values[i]);
}
*objp = &menu->obj;
@@ -408,7 +404,7 @@
if (ret < 0)
return log_msg_ret("tit", ret);
title_id = ret;
- scene_title_set(scn, title_id);
+ scn->title_id = title_id;
ret = add_txt_str(info, scn_node, scn, "prompt", 0);
if (ret < 0)
@@ -424,7 +420,7 @@
return 0;
}
-int build_it(struct build_info *info, ofnode root, struct expo **expp)
+static int build_it(struct build_info *info, ofnode root, struct expo **expp)
{
ofnode scenes, node;
struct expo *exp;
diff --git a/boot/scene.c b/boot/scene.c
index 270c9c6..3290a40 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -70,13 +70,6 @@
free(scn);
}
-int scene_title_set(struct scene *scn, uint id)
-{
- scn->title_id = id;
-
- return 0;
-}
-
int scene_obj_count(struct scene *scn)
{
return list_count_nodes(&scn->obj_head);
@@ -339,7 +332,7 @@
/* draw a background for the object */
if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
- fore = VID_BLACK;
+ fore = VID_DARK_GREY;
back = VID_WHITE;
} else {
fore = VID_LIGHT_GRAY;
@@ -471,11 +464,59 @@
return 0;
}
+int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr)
+{
+ struct scene_obj *obj;
+
+ arr->label_width = 0;
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ uint label_id = 0;
+ int width;
+
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_IMAGE:
+ case SCENEOBJT_TEXT:
+ break;
+ case SCENEOBJT_MENU: {
+ struct scene_obj_menu *menu;
+
+ menu = (struct scene_obj_menu *)obj,
+ label_id = menu->title_id;
+ break;
+ }
+ case SCENEOBJT_TEXTLINE: {
+ struct scene_obj_textline *tline;
+
+ tline = (struct scene_obj_textline *)obj,
+ label_id = tline->label_id;
+ break;
+ }
+ }
+
+ if (label_id) {
+ int ret;
+
+ ret = scene_obj_get_hw(scn, label_id, &width);
+ if (ret < 0)
+ return log_msg_ret("hei", ret);
+ arr->label_width = max(arr->label_width, width);
+ }
+ }
+
+ return 0;
+}
+
int scene_arrange(struct scene *scn)
{
+ struct expo_arrange_info arr;
struct scene_obj *obj;
int ret;
+ ret = scene_calc_arrange(scn, &arr);
+ if (ret < 0)
+ return log_msg_ret("arr", ret);
+
list_for_each_entry(obj, &scn->obj_head, sibling) {
switch (obj->type) {
case SCENEOBJT_NONE:
@@ -486,7 +527,7 @@
struct scene_obj_menu *menu;
menu = (struct scene_obj_menu *)obj,
- ret = scene_menu_arrange(scn, menu);
+ ret = scene_menu_arrange(scn, &arr, menu);
if (ret)
return log_msg_ret("arr", ret);
break;
@@ -495,7 +536,7 @@
struct scene_obj_textline *tline;
tline = (struct scene_obj_textline *)obj,
- ret = scene_textline_arrange(scn, tline);
+ ret = scene_textline_arrange(scn, &arr, tline);
if (ret)
return log_msg_ret("arr", ret);
break;
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index e72202c..ec9008e 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -96,10 +96,12 @@
* if not already done
*
* @scn: Scene to update
+ * @arr: Arrangement information
* @menu: Menu to process
* Returns: 0 if OK, -ve on error
*/
-int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu);
+int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_menu *menu);
/**
* scene_textline_arrange() - Set the position of things in a textline
@@ -108,10 +110,12 @@
* positioned correctly relative to the textline.
*
* @scn: Scene to update
+ * @arr: Arrangement information
* @tline: textline to process
* Returns: 0 if OK, -ve on error
*/
-int scene_textline_arrange(struct scene *scn, struct scene_obj_textline *tline);
+int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_textline *tline);
/**
* scene_apply_theme() - Apply a theme to a scene
@@ -278,6 +282,16 @@
uint seq);
/**
+ * scene_menuitem_find_val() - Find the menu item with a given value
+ *
+ * @menu: Menu to check
+ * @find_val: Value to look for
+ * Return: menu item if found, else NULL
+ */
+struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu,
+ int val);
+
+/**
* scene_bbox_union() - update bouding box with the demensions of an object
*
* Updates @bbox so that it encompasses the bounding box of object @id
@@ -358,4 +372,16 @@
*/
int scene_textline_close(struct scene *scn, struct scene_obj_textline *tline);
+/**
+ * scene_calc_arrange() - Calculate sizes needed to arrange a scene
+ *
+ * Checks the size of some objects and stores this info to help with a later
+ * scene arrangement
+ *
+ * @scn: Scene to check
+ * @arr: Place to put scene-arrangement info
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr);
+
#endif /* __SCENE_INTERNAL_H */
diff --git a/boot/scene_menu.c b/boot/scene_menu.c
index 80bd745..17150af 100644
--- a/boot/scene_menu.c
+++ b/boot/scene_menu.c
@@ -61,6 +61,22 @@
return NULL;
}
+struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu,
+ int val)
+{
+ struct scene_menitem *item;
+ uint i;
+
+ i = 0;
+ list_for_each_entry(item, &menu->item_head, sibling) {
+ if (item->value == INT_MAX ? val == i : item->value == val)
+ return item;
+ i++;
+ }
+
+ return NULL;
+}
+
/**
* update_pointers() - Update the pointer object and handle highlights
*
@@ -168,7 +184,8 @@
return 0;
}
-int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
+int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_menu *menu)
{
const bool open = menu->obj.flags & SCENEOF_OPEN;
struct expo *exp = scn->expo;
@@ -182,16 +199,18 @@
x = menu->obj.dim.x;
y = menu->obj.dim.y;
if (menu->title_id) {
+ int width;
+
ret = scene_obj_set_pos(scn, menu->title_id, menu->obj.dim.x, y);
if (ret < 0)
return log_msg_ret("tit", ret);
- ret = scene_obj_get_hw(scn, menu->title_id, NULL);
+ ret = scene_obj_get_hw(scn, menu->title_id, &width);
if (ret < 0)
return log_msg_ret("hei", ret);
if (stack)
- x += 200;
+ x += arr->label_width + theme->menu_title_margin_x;
else
y += ret * 2;
}
@@ -413,6 +432,7 @@
item->desc_id = desc_id;
item->preview_id = preview_id;
item->flags = flags;
+ item->value = INT_MAX;
list_add_tail(&item->sibling, &menu->item_head);
if (itemp)
diff --git a/boot/scene_textline.c b/boot/scene_textline.c
index bba8663..6adef7c 100644
--- a/boot/scene_textline.c
+++ b/boot/scene_textline.c
@@ -87,7 +87,8 @@
return 0;
}
-int scene_textline_arrange(struct scene *scn, struct scene_obj_textline *tline)
+int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_textline *tline)
{
const bool open = tline->obj.flags & SCENEOF_OPEN;
bool point;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2f63959..3ee70f3 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2292,6 +2292,7 @@
config CMD_RTC
bool "rtc"
depends on DM_RTC
+ default y if X86
help
Enable the 'rtc' command for low-level access to RTC devices.
diff --git a/cmd/font.c b/cmd/font.c
index eb13fb1..36e4120 100644
--- a/cmd/font.c
+++ b/cmd/font.c
@@ -55,9 +55,6 @@
uint size;
int ret;
- if (argc != 2)
- return CMD_RET_USAGE;
-
if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
return CMD_RET_FAILURE;
ret = vidconsole_get_font_size(dev, &font_name, &size);
@@ -66,12 +63,16 @@
return CMD_RET_FAILURE;
}
- size = dectoul(argv[1], NULL);
+ if (argc < 2) {
+ printf("%d\n", size);
+ } else {
+ size = dectoul(argv[1], NULL);
- ret = vidconsole_select_font(dev, font_name, size);
- if (ret) {
- printf("Failed (error %d)\n", ret);
- return CMD_RET_FAILURE;
+ ret = vidconsole_select_font(dev, font_name, size);
+ if (ret) {
+ printf("Failed (error %d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
}
return 0;
diff --git a/cmd/upl.c b/cmd/upl.c
index c974588..4996f36 100644
--- a/cmd/upl.c
+++ b/cmd/upl.c
@@ -72,7 +72,7 @@
return CMD_RET_FAILURE;
}
addr = map_to_sysmem(abuf_data(&buf));
- printf("UPL handoff written to %lx size %lx\n", addr, abuf_size(&buf));
+ printf("UPL handoff written to %lx size %zx\n", addr, abuf_size(&buf));
if (env_set_hex("upladdr", addr) ||
env_set_hex("uplsize", abuf_size(&buf))) {
printf("Cannot set env var\n");
diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile
index b1f39d3..9252152 100644
--- a/cmd/x86/Makefile
+++ b/cmd/x86/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_CMD_CBSYSINFO) += cbsysinfo.o
-obj-y += mtrr.o
+obj-y += cpuid.o msr.o mtrr.o
obj-$(CONFIG_CMD_EXCEPTION) += exception.o
obj-$(CONFIG_USE_HOB) += hob.o
obj-$(CONFIG_HAVE_FSP) += fsp.o
diff --git a/cmd/x86/cpuid.c b/cmd/x86/cpuid.c
new file mode 100644
index 0000000..222754b
--- /dev/null
+++ b/cmd/x86/cpuid.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'cpuid' command provides access to the CPU's cpuid information
+ *
+ * Copyright 2024 Google, LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <command.h>
+#include <vsprintf.h>
+#include <asm/cpu.h>
+
+static int do_cpuid(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct cpuid_result res;
+ ulong op;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ op = hextoul(argv[1], NULL);
+ res = cpuid(op);
+ printf("eax %08x\n", res.eax);
+ printf("ebx %08x\n", res.ebx);
+ printf("ecx %08x\n", res.ecx);
+ printf("edx %08x\n", res.edx);
+
+ return 0;
+}
+
+U_BOOT_LONGHELP(cpuid, "Show CPU Identification information");
+
+U_BOOT_CMD(
+ cpuid, 2, 1, do_cpuid,
+ "cpuid <op>", cpuid_help_text
+);
diff --git a/cmd/x86/msr.c b/cmd/x86/msr.c
new file mode 100644
index 0000000..3cb70d1
--- /dev/null
+++ b/cmd/x86/msr.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'cpuid' command provides access to the CPU's cpuid information
+ *
+ * Copyright 2024 Google, LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <command.h>
+#include <vsprintf.h>
+#include <asm/msr.h>
+
+static int do_read(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct msr_t msr;
+ ulong op;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ op = hextoul(argv[1], NULL);
+ msr = msr_read(op);
+ printf("%08x %08x\n", msr.hi, msr.lo);
+
+ return 0;
+}
+
+static int do_write(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct msr_t msr;
+ ulong op;
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+
+ op = hextoul(argv[1], NULL);
+ msr.hi = hextoul(argv[2], NULL);
+ msr.lo = hextoul(argv[3], NULL);
+ msr_write(op, msr);
+
+ return 0;
+}
+
+U_BOOT_LONGHELP(msr,
+ "read <op> - read a machine-status register (MSR) as <hi 32-bits> <lo 32-bits>\n"
+ "write <op< <hi> <lo> - write an MSR");
+
+U_BOOT_CMD_WITH_SUBCMDS(msr, "Machine Status Registers", msr_help_text,
+ U_BOOT_CMD_MKENT(read, CONFIG_SYS_MAXARGS, 1, do_read, "", ""),
+ U_BOOT_CMD_MKENT(write, CONFIG_SYS_MAXARGS, 1, do_write, "", ""));
diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig
index da42ad0..553f1dc 100644
--- a/configs/coreboot64_defconfig
+++ b/configs/coreboot64_defconfig
@@ -61,6 +61,9 @@
CONFIG_SOUND_I8254=y
CONFIG_VIDEO_COPY=y
CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_SIZE=20
+# CONFIG_CONSOLE_TRUETYPE_NIMBUS is not set
+CONFIG_CONSOLE_TRUETYPE_ANKACODER=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_SPL_ACPI=y
CONFIG_CMD_DHRYSTONE=y
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig
index 0b103ef..881bf8d 100644
--- a/configs/coreboot_defconfig
+++ b/configs/coreboot_defconfig
@@ -11,6 +11,7 @@
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_BOOTSTD_FULL=y
+CONFIG_BOOTSTAGE=y
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro"
@@ -30,6 +31,7 @@
CONFIG_BOOTP_BOOTFILESIZE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_SOUND=y
+CONFIG_CMD_BOOTSTAGE=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_MAC_PARTITION=y
CONFIG_ENV_OVERWRITE=y
@@ -55,6 +57,9 @@
CONFIG_SOUND_I8254=y
CONFIG_VIDEO_COPY=y
CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_SIZE=20
+# CONFIG_CONSOLE_TRUETYPE_NIMBUS is not set
+CONFIG_CONSOLE_TRUETYPE_ANKACODER=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_CMD_DHRYSTONE=y
# CONFIG_GZIP is not set
diff --git a/configs/imx8mp_dhcom_pdk2_defconfig b/configs/imx8mp_dhcom_pdk2_defconfig
index 9aa2faf..d72862c 100644
--- a/configs/imx8mp_dhcom_pdk2_defconfig
+++ b/configs/imx8mp_dhcom_pdk2_defconfig
@@ -12,7 +12,7 @@
CONFIG_ENV_OFFSET=0xFE0000
CONFIG_ENV_SECT_SIZE=0x1000
CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx8mp-dhcom-pdk2"
+CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mp-dhcom-pdk2"
CONFIG_SPL_TEXT_BASE=0x920000
CONFIG_TARGET_IMX8MP_DH_DHCOM_PDK2=y
CONFIG_DM_RESET=y
@@ -48,7 +48,7 @@
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run dh_update_env distro_bootcmd ; reset"
CONFIG_USE_PREBOOT=y
-CONFIG_DEFAULT_FDT_FILE="imx8mp-dhcom-pdk2.dtb"
+CONFIG_DEFAULT_FDT_FILE="freescale/imx8mp-dhcom-pdk2.dtb"
CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2081
CONFIG_CONSOLE_MUX=y
@@ -143,6 +143,8 @@
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_UPSTREAM=y
+CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
diff --git a/configs/imx8mp_dhcom_pdk3_defconfig b/configs/imx8mp_dhcom_pdk3_defconfig
index 03a0485..0460138 100644
--- a/configs/imx8mp_dhcom_pdk3_defconfig
+++ b/configs/imx8mp_dhcom_pdk3_defconfig
@@ -12,7 +12,7 @@
CONFIG_ENV_OFFSET=0xFE0000
CONFIG_ENV_SECT_SIZE=0x1000
CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="imx8mp-dhcom-pdk3"
+CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mp-dhcom-pdk3"
CONFIG_SPL_TEXT_BASE=0x920000
CONFIG_TARGET_IMX8MP_DH_DHCOM_PDK2=y
CONFIG_DM_RESET=y
@@ -50,7 +50,7 @@
CONFIG_BOOTCOMMAND="run dh_update_env distro_bootcmd ; reset"
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="gpio clear GPIO1_11 ; sleep 0.1 ; gpio set GPIO1_11 ; sleep 0.1 ; i2c dev 4 && i2c mw 0x70 0 4 && i2c probe 0x2d && i2c mw 0x2d 0xaa55.2 0"
-CONFIG_DEFAULT_FDT_FILE="imx8mp-dhcom-pdk3.dtb"
+CONFIG_DEFAULT_FDT_FILE="freescale/imx8mp-dhcom-pdk3.dtb"
CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2081
CONFIG_CONSOLE_MUX=y
@@ -146,6 +146,8 @@
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_UPSTREAM=y
+CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
diff --git a/doc/board/coreboot/coreboot.rst b/doc/board/coreboot/coreboot.rst
index 7154f59..a177265 100644
--- a/doc/board/coreboot/coreboot.rst
+++ b/doc/board/coreboot/coreboot.rst
@@ -181,16 +181,4 @@
CI runs tests using a pre-built coreboot image. This ensures that U-Boot can
boot as a coreboot payload, based on a known-good build of coreboot.
-To update the `coreboot.rom` file which is used:
-
-#. Build coreboot with `CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y`. If using
- `make menuconfig`, this is under
- `Devices->Display->Framebuffer mode->Linear "high resolution" framebuffer`.
-
-#. Compress the resulting `coreboot.rom`::
-
- xz -c /path/to/coreboot/build/coreboot.rom > coreboot.rom.xz
-
-#. Upload the file to Google drive
-
-#. Send a patch to change the file ID used by wget in the CI yaml files.
+To update the `coreboot.rom` file which is used, see ``tools/Dockerfile``
diff --git a/doc/develop/binman_tests.rst b/doc/develop/binman_tests.rst
new file mode 100644
index 0000000..a632694
--- /dev/null
+++ b/doc/develop/binman_tests.rst
@@ -0,0 +1,734 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+.. toctree::
+ :maxdepth: 1
+
+Binman Tests
+============
+
+.. contents::
+ :depth: 2
+ :local:
+
+There is some material on writing tests in the main Binman documentation
+(see :doc:`package/index`). This short guide is separate so people don't
+feel they have to read as much.
+
+Code and output is mostly included verbatim, which makes the doc longer, but
+avoids its becoming confusing when the output or referenced code changes in the
+future.
+
+Purpose
+-------
+
+The main purpose of tests in Binman is to make sure that Binman actually does
+what it is supposed to. Various people contribute code, refactoring is done
+over time, but U-Boot users (developers, SoC vendors, board vendors) rely on
+Binman producing images which function correctly. Without tests, a one-line
+change could unintentionally break a corner-case and the problem might not be
+noticed for months. Debugging an image-generation problem with a board you
+don't have can be very hard.
+
+A secondary purpose is productivity. U-Boot contributors are busy and often
+have too much on their plate. Trying to figure out why their patch broke
+some other vendor's workflow can be very time-consuming and frustrating. By
+building in tests from the start, this is largely avoided. If your change has
+full test coverage and doesn't break any test, all is well and no one can
+complain.
+
+A lessor purpose is to document what Binman actually does. If a test covers a
+feature, it works. If there is no test coverage, no one can say for sure
+whether it works in all expected situations, certainly not wihout manual
+effort.
+
+In fact, strictly speaking it isn't completely clear what 'works' even means in
+the case where these is no test to cover the code. We are often left guessing
+as to what the documentation means, what was actually intended, etc.
+
+Finally, code-coverage helps to remove 'zombie code', copied from elsewhere
+because it looks reasonable, but not actually needed. The same situation arises
+in silicon-chip design, where a part of the chip is not validated. If it isn't
+validated, it can be assumed not to work, either now or later, so it is best to
+remove that logic to avoid it causing problems.
+
+Setting up
+----------
+
+Binman tests use various utility programs. Most of these are documented in
+:doc:`../build/gcc`. But some are SoC-specific. To fetch these, tell Binman to
+fetch or build any missing tools:
+
+.. code-block:: bash
+
+ $ binman tool -f missing
+
+When this completes successfully, you can list the tools. You should see
+something like this:
+
+.. code-block:: bash
+
+ $ binman tool -l
+ Name Version Description Path
+ --------------- ----------- ------------------------- ------------------------------
+ bootgen ****** Bootg Xilinx Bootgen /home/sglass/.binman-tools/bootgen
+ bzip2 1.0.8 bzip2 compression /usr/bin/bzip2
+ cbfstool unknown Manipulate CBFS files /home/sglass/bin/cbfstool
+ fdt_add_pubkey unknown Generate image for U-Boot /home/sglass/bin/fdt_add_pubkey
+ fdtgrep unknown Grep devicetree files /home/sglass/bin/fdtgrep
+ fiptool v2.11.0(rele Manipulate ATF FIP files /home/sglass/.binman-tools/fiptool
+ futility v0.0.1-9f2e9 Chromium OS firmware utili /home/sglass/.binman-tools/futility
+ gzip 1.12 gzip compression /usr/bin/gzip
+ ifwitool unknown Manipulate Intel IFWI file /home/sglass/.binman-tools/ifwitool
+ lz4 v1.9.4 lz4 compression /usr/bin/lz4
+ lzma_alone 9.22 beta lzma_alone compression /usr/bin/lzma_alone
+ lzop v1.04 lzo compression /usr/bin/lzop
+ mkeficapsule 2024.10-rc5- mkeficapsule tool for gene /home/sglass/bin/mkeficapsule
+ mkimage 2024.10-rc5- Generate image for U-Boot /home/sglass/bin/mkimage
+ openssl 3.0.13 30 Ja openssl cryptography toolk /usr/bin/openssl
+ xz 5.4.5 xz compression /usr/bin/xz
+ zstd v1.5.5 zstd compression /usr/bin/zstd
+
+The tools are written to ``~/.binman-tools`` so add that to your ``PATH``.
+It's fine to have some of the tools elsewhere (e.g. ``~/bin``) so long as they
+are up-to-date. This allows you use the version of the tools intended for
+running tests.
+
+Now you should be able to actually run the tests:
+
+.. code-block:: bash
+
+ $ binman test
+ ======================== Running binman tests ========================
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ........
+ ----------------------------------------------------------------------
+ Ran 568 tests in 2.578s
+
+ OK
+
+If this doesn't work, see if you can have some missing tools. Check that the
+dependencies are all there as above. If it is very slow, try installing
+concurrencytest so that the tests run in parallel.
+
+The next thing to set up is code coverage, using the -T flag:
+
+.. code-block:: bash
+
+ $ binman test -T
+ ======================== Running binman tests ========================
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ......................................................................
+ ........
+ ----------------------------------------------------------------------
+ Ran 568 tests in 17.367s
+
+ OK
+
+ 99%
+ Name Stmts Miss Cover
+ ---------------------------------------------------------------------------
+ tools/binman/__init__.py 0 0 100%
+ tools/binman/bintool.py 263 0 100%
+ tools/binman/btool/bootgen.py 21 0 100%
+ tools/binman/btool/btool_gzip.py 5 0 100%
+ tools/binman/btool/bzip2.py 5 0 100%
+ tools/binman/btool/cbfstool.py 24 0 100%
+ tools/binman/btool/cst.py 15 4 73%
+ tools/binman/btool/fdt_add_pubkey.py 21 0 100%
+ tools/binman/btool/fdtgrep.py 26 0 100%
+ tools/binman/btool/fiptool.py 19 0 100%
+ tools/binman/btool/futility.py 19 0 100%
+ tools/binman/btool/ifwitool.py 22 0 100%
+ tools/binman/btool/lz4.py 22 0 100%
+ tools/binman/btool/lzma_alone.py 34 0 100%
+ tools/binman/btool/lzop.py 5 0 100%
+ tools/binman/btool/mkeficapsule.py 27 0 100%
+ tools/binman/btool/mkimage.py 23 0 100%
+ tools/binman/btool/openssl.py 42 0 100%
+ tools/binman/btool/xz.py 5 0 100%
+ tools/binman/btool/zstd.py 5 0 100%
+ tools/binman/cbfs_util.py 376 0 100%
+ tools/binman/cmdline.py 90 0 100%
+ tools/binman/control.py 409 0 100%
+ tools/binman/elf.py 241 0 100%
+ tools/binman/entry.py 548 0 100%
+ tools/binman/etype/alternates_fdt.py 58 0 100%
+ tools/binman/etype/atf_bl31.py 5 0 100%
+ tools/binman/etype/atf_fip.py 67 0 100%
+ tools/binman/etype/blob.py 49 0 100%
+ tools/binman/etype/blob_dtb.py 46 0 100%
+ tools/binman/etype/blob_ext.py 9 0 100%
+ tools/binman/etype/blob_ext_list.py 32 0 100%
+ tools/binman/etype/blob_named_by_arg.py 9 0 100%
+ tools/binman/etype/blob_phase.py 22 0 100%
+ tools/binman/etype/cbfs.py 101 0 100%
+ tools/binman/etype/collection.py 30 0 100%
+ tools/binman/etype/cros_ec_rw.py 5 0 100%
+ tools/binman/etype/efi_capsule.py 59 0 100%
+ tools/binman/etype/efi_empty_capsule.py 33 0 100%
+ tools/binman/etype/encrypted.py 34 0 100%
+ tools/binman/etype/fdtmap.py 62 0 100%
+ tools/binman/etype/files.py 35 0 100%
+ tools/binman/etype/fill.py 13 0 100%
+ tools/binman/etype/fit.py 311 0 100%
+ tools/binman/etype/fmap.py 37 0 100%
+ tools/binman/etype/gbb.py 37 0 100%
+ tools/binman/etype/image_header.py 53 0 100%
+ tools/binman/etype/intel_cmc.py 4 0 100%
+ tools/binman/etype/intel_descriptor.py 39 0 100%
+ tools/binman/etype/intel_fit.py 12 0 100%
+ tools/binman/etype/intel_fit_ptr.py 17 0 100%
+ tools/binman/etype/intel_fsp.py 4 0 100%
+ tools/binman/etype/intel_fsp_m.py 4 0 100%
+ tools/binman/etype/intel_fsp_s.py 4 0 100%
+ tools/binman/etype/intel_fsp_t.py 4 0 100%
+ tools/binman/etype/intel_ifwi.py 67 0 100%
+ tools/binman/etype/intel_me.py 4 0 100%
+ tools/binman/etype/intel_mrc.py 6 0 100%
+ tools/binman/etype/intel_refcode.py 6 0 100%
+ tools/binman/etype/intel_vbt.py 4 0 100%
+ tools/binman/etype/intel_vga.py 4 0 100%
+ tools/binman/etype/mkimage.py 84 0 100%
+ tools/binman/etype/null.py 9 0 100%
+ tools/binman/etype/nxp_imx8mcst.py 78 59 24%
+ tools/binman/etype/nxp_imx8mimage.py 38 6 84%
+ tools/binman/etype/opensbi.py 5 0 100%
+ tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py 6 0 100%
+ tools/binman/etype/pre_load.py 76 0 100%
+ tools/binman/etype/rockchip_tpl.py 5 0 100%
+ tools/binman/etype/scp.py 5 0 100%
+ tools/binman/etype/section.py 418 0 100%
+ tools/binman/etype/tee_os.py 31 0 100%
+ tools/binman/etype/text.py 21 0 100%
+ tools/binman/etype/ti_board_config.py 139 0 100%
+ tools/binman/etype/ti_dm.py 5 0 100%
+ tools/binman/etype/ti_secure.py 65 0 100%
+ tools/binman/etype/ti_secure_rom.py 117 0 100%
+ tools/binman/etype/u_boot.py 7 0 100%
+ tools/binman/etype/u_boot_dtb.py 9 0 100%
+ tools/binman/etype/u_boot_dtb_with_ucode.py 51 0 100%
+ tools/binman/etype/u_boot_elf.py 19 0 100%
+ tools/binman/etype/u_boot_env.py 27 0 100%
+ tools/binman/etype/u_boot_expanded.py 4 0 100%
+ tools/binman/etype/u_boot_img.py 7 0 100%
+ tools/binman/etype/u_boot_nodtb.py 7 0 100%
+ tools/binman/etype/u_boot_spl.py 8 0 100%
+ tools/binman/etype/u_boot_spl_bss_pad.py 14 0 100%
+ tools/binman/etype/u_boot_spl_dtb.py 9 0 100%
+ tools/binman/etype/u_boot_spl_elf.py 8 0 100%
+ tools/binman/etype/u_boot_spl_expanded.py 12 0 100%
+ tools/binman/etype/u_boot_spl_nodtb.py 8 0 100%
+ tools/binman/etype/u_boot_spl_pubkey_dtb.py 32 0 100%
+ tools/binman/etype/u_boot_spl_with_ucode_ptr.py 8 0 100%
+ tools/binman/etype/u_boot_tpl.py 8 0 100%
+ tools/binman/etype/u_boot_tpl_bss_pad.py 14 0 100%
+ tools/binman/etype/u_boot_tpl_dtb.py 9 0 100%
+ tools/binman/etype/u_boot_tpl_dtb_with_ucode.py 8 0 100%
+ tools/binman/etype/u_boot_tpl_elf.py 8 0 100%
+ tools/binman/etype/u_boot_tpl_expanded.py 12 0 100%
+ tools/binman/etype/u_boot_tpl_nodtb.py 8 0 100%
+ tools/binman/etype/u_boot_tpl_with_ucode_ptr.py 12 0 100%
+ tools/binman/etype/u_boot_ucode.py 33 0 100%
+ tools/binman/etype/u_boot_vpl.py 8 0 100%
+ tools/binman/etype/u_boot_vpl_bss_pad.py 14 0 100%
+ tools/binman/etype/u_boot_vpl_dtb.py 9 0 100%
+ tools/binman/etype/u_boot_vpl_elf.py 8 0 100%
+ tools/binman/etype/u_boot_vpl_expanded.py 12 0 100%
+ tools/binman/etype/u_boot_vpl_nodtb.py 8 0 100%
+ tools/binman/etype/u_boot_with_ucode_ptr.py 42 0 100%
+ tools/binman/etype/vblock.py 38 0 100%
+ tools/binman/etype/x86_reset16.py 7 0 100%
+ tools/binman/etype/x86_reset16_spl.py 7 0 100%
+ tools/binman/etype/x86_reset16_tpl.py 7 0 100%
+ tools/binman/etype/x86_start16.py 7 0 100%
+ tools/binman/etype/x86_start16_spl.py 7 0 100%
+ tools/binman/etype/x86_start16_tpl.py 7 0 100%
+ tools/binman/etype/x509_cert.py 71 0 100%
+ tools/binman/etype/xilinx_bootgen.py 72 0 100%
+ tools/binman/fip_util.py 202 0 100%
+ tools/binman/fmap_util.py 49 0 100%
+ tools/binman/image.py 181 0 100%
+ tools/binman/state.py 201 0 100%
+ ---------------------------------------------------------------------------
+ TOTAL 5954 69 99%
+
+ To get a report in 'htmlcov/index.html', type: python3-coverage html
+ Coverage error: 99%, but should be 100%
+ ValueError: Test coverage failure
+
+Unfortunately the run failed. As it suggests, create a report:
+
+.. code-block:: bash
+
+ $ python3-coverage html
+ Wrote HTML report to htmlcov/index.html
+
+If you open that file in the browser, you can see which files are not reaching
+100% and click on them. Here is ``nxp_imx8mimage.py``, for example:
+
+.. code-block:: python
+
+ 43 # Generate mkimage configuration file similar to imx8mimage.cfg
+ 44 # and pass it to mkimage to generate SPL image for us here.
+ 45 cfg_fname = tools.get_output_filename('nxp.imx8mimage.cfg.%s' % uniq)
+ 46 with open(cfg_fname, 'w') as outf:
+ 47 print('ROM_VERSION v%d' % self.rom_version, file=outf)
+ 48 print('BOOT_FROM %s' % self.boot_from, file=outf)
+ 49 print('LOADER %s %#x' % (input_fname, self.loader_address), file=outf)
+ 50
+ 51 output_fname = tools.get_output_filename(f'cfg-out.{uniq}')
+ 52 args = ['-d', input_fname, '-n', cfg_fname, '-T', 'imx8mimage',
+ 53 output_fname]
+ 54 if self.mkimage.run_cmd(*args) is not None:
+ 55 return tools.read_file(output_fname)
+ 56 else:
+ 57 # Bintool is missing; just use the input data as the output
+ 58 x self.record_missing_bintool(self.mkimage)
+ 59 x return data
+ 60
+ 61 def SetImagePos(self, image_pos):
+ 62 # Customized SoC specific SetImagePos which skips the mkimage etype
+ 63 # implementation and removes the 0x48 offset introduced there. That
+ 64 # offset is only used for uImage/fitImage, which is not the case in
+ 65 # here.
+ 66 upto = 0x00
+ 67 for entry in super().GetEntries().values():
+ 68 x entry.SetOffsetSize(upto, None)
+ 69
+ 70 # Give up if any entries lack a size
+ 71 x if entry.size is None:
+ 72 x return
+ 73 x upto += entry.size
+ 74
+ 75 Entry_section.SetImagePos(self, image_pos)
+
+Most of the file is covered, but the lines marked with ``x`` indicate missing
+coverage. The will show up red in your browser.
+
+What is a test?
+---------------
+
+A test is a function in ``ftest.py`` which uses an image description in
+``tools/binman/test`` to perform some operations and exercise the code. Some
+tests are just a few lines; some are more complicated.
+
+Here is a simple test:
+
+.. code-block:: python
+
+ def testSimple(self):
+ """Test a simple binman with a single file"""
+ data = self._DoReadFile('005_simple.dts')
+ self.assertEqual(U_BOOT_DATA, data)
+
+This test tells Binman to build an image using the description. Then it checks
+that the resulting image looks correct. The image description is:
+
+.. code-block:: devicetree
+
+ /dts-v1/;
+
+ / {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+ };
+ };
+
+As you will know from the Binman documentation, this says that there is
+one image and it contains the U-Boot binary. So this test builds an image
+consisting of a U-Boot binary, then checks that it does indeed have just a
+U-Boot binary in it.
+
+Test data
+---------
+
+Using real binaries (like ``u-boot.bin``) to test Binman would be quite tedious.
+Every output file would be large and it would be hard to tell by looking at the
+output (e.g. with a hex dump) if a particular entry contains ``u-boot.bin`` or
+``u-boot-spl.bin`` or something else.
+
+Binman gets around this by using simple placeholders. Here is the placeholder
+for u-boot.bin:
+
+.. code-block:: python
+
+ U_BOOT_DATA = b'1234'
+
+This is just bytes. So the test above checks that the output image contains
+these four bytes. This makes verification fast for Binman and very easy for
+humans.
+
+Even the devicetree is a placeholder:
+
+.. code-block:: python
+
+ U_BOOT_DTB_DATA = b'udtb'
+
+But for some tests you need to use the real devicetree. In that case you can
+use ``_DoReadFileRealDtb()``. See ``testUpdateFdtAll()`` for an example of how
+to check the devicetree updated by Binman.
+
+Test structure
+--------------
+
+Each test is designed to test just one thing. Binman tests are named according
+to what they are testing. Individually they don't do very much, but as a whole
+they test every line of code in Binman.
+
+So ``testSimple()`` is designed to check that Binman can build the
+simplest-possible image that isn't completely empty.
+
+Another type of test is one which checks error-handling, for example:
+
+.. code-block:: python
+
+ def testFillNoSize(self):
+ """Test for an fill entry type with no size"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('070_fill_no_size.dts')
+ self.assertIn("'fill' entry is missing properties: size",
+ str(e.exception))
+
+This test deliberately tries to provoke an error. The image description is:
+
+.. code-block:: devicetree
+
+ // SPDX-License-Identifier: GPL-2.0+
+ /dts-v1/;
+
+ / {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ size = <16>;
+ fill {
+ fill-byte = [ff];
+ };
+ };
+ };
+
+You can see that there is no size for the 'fill' entry, so we would expect
+Binman to complain. The test checks that it actually does. It also checks the
+error message produced by Binman. Sometimes you need to add several tests, each
+with their own broken image description, in order to check all the error cases.
+
+Sometimes you need to capture the console output of Binman, to check it is
+correct. You can to this with ``test_util.capture_sys_output()``, for example:
+
+.. code-block:: python
+
+ with test_util.capture_sys_output() as (_, stderr):
+ self._DoTestFile('071_gbb.dts', force_missing_bintools='futility',
+ entry_args=entry_args)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: futility")
+
+The test collects the output and checks it with a regular expression. If you
+need to see the test output (e.g. to debug it), you will have to remove that
+capture line.
+
+How to add a new test
+---------------------
+
+This section explains the process of writing a new test. It uses an example to
+help with this, but your code will be different.
+
+Generally you are adding a test because you are adding a new entry type
+('etype'). So start by creating the shortest and simplest image-description you
+can, which contains the new etype. Put it in a numbered file in
+``tool/binman/test`` so that it comes last. All the numbers are unique and there
+are no gaps.
+
+Example from ``tools/binman/test/339_nxp_imx8.dts``:
+
+.. code-block:: devicetree
+
+ // SPDX-License-Identifier: GPL-2.0+
+
+ /dts-v1/;
+
+ / {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "sd";
+ nxp,rom-version = <1>;
+ nxp,loader-address = <0x10>;
+ };
+ };
+ };
+
+Note that you should use tabs in the file, not spaces. You can see that this has
+been cut down to the bare minimum, just enough to include the etype and the
+arguments it needs. This is of course not a real image. It will not boot on
+anything. But that's fine; we are just trying to test this one etype. Try not
+to add any other sections and etypes unless they are absolutely essential for
+your test to work. This helps others too: they don't need to understand the full
+complexity of your etype just to read your test.
+
+Then create your test by adding a new function at the end of ``ftest.py``:
+
+.. code-block:: python
+
+ def testNxpImx8Image(self):
+ """Test that binman can produce an iMX8 image"""
+ self._DoTestFile('339_nxp_imx8.dts')
+
+This uses the test file that you created. It doesn't check anything, it just
+runs the image description through binman.
+
+Let's run it:
+
+.. code-block:: bash
+
+ $ binman test testNxpImx8Image
+ ======================== Running binman tests ========================
+ .
+ ----------------------------------------------------------------------
+ Ran 1 test in 0.242s
+
+ OK
+
+So the test passes. It doesn't really do a lot, but it does exercise the etype.
+The next step is to update it to actually check the output:
+
+.. code-block:: python
+
+ def testNxpImx8Image(self):
+ """Test that binman can produce an iMX8 image"""
+ data = self._DoReadFile('339_nxp_imx8.dts')
+ print('data', len(data))
+
+The ``_DoReadFile()`` function is documented in the code. It returns the image
+contents as the first part of a tuple.
+
+Running this we see:
+
+.. code-block:: bash
+
+ data 2200
+
+So it is producing a little over 8K of data. Your etype will be different, but
+in any case you can add Python code to check that this data is actually correct,
+based on your knowledge of your etype. Note that you should not be checking
+whether the external tools (called 'bintools' in Binman) are actually working,
+since presumably they have their own tests. You just need to check that the
+image seems reasonable, e.g. is not empty, contains the expected sections, etc.
+
+When your etype does use a bintool, it also needs tests, but generally it will
+be tested by virtue of the etype test. This is because your etype must call the
+bintool to create the image. Sometimes you might need to add a test for a
+bintool error-condition, though.
+
+Finishing code coverage
+-----------------------
+
+The objective is to have test-coverage for every line of code that you add to
+Binman. So how can you tell? First, get a coverage report as described above.
+Look through the output for any files which are not at 100%. Add more test cases
+(image descriptions and new functions in ``ftest.py``) until you have covered
+each line.
+
+In the above example, here are some possible steps:
+
+#. The first red bit is where the ``mkimage`` call returns None. This can be
+ traced to ``Bintoolmkimage.mkimage()`` which calls
+ ``Bintool.run_cmd_result()`` and ``None`` means that ``mkimage`` is missing.
+ So the etype has code to handle that case, but it is never used. You can
+ look for other examples of ``self.mkimage`` returning ``None`` - e.g.
+ ``Entry_mkimage.BuildSectionData()`` does this. The clue for finding this is
+ that the ``nxp-imx8mimage`` etype is based on ``Entry_mkimage``:
+
+ .. code-block:: python
+
+ class Entry_nxp_imx8mimage(Entry_mkimage):
+
+ It must be tested somewhere...in this case ``testMkimage()`` doesn't do it,
+ but ``testMkimageMissing()`` immediately below that does. So you can create a
+ similar test, e.g.:
+
+ .. code-block:: python
+
+ def testNxpImx8ImageMkimageMissing(self):
+ """Test that binman can produce an iMX8 image"""
+ with test_util.capture_sys_output() as (_, stderr):
+ self._DoTestFile('339_nxp_imx8.dts',
+ force_missing_bintools='mkimage')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: mkimage")
+
+ Note that this uses exactly the same image description as the first test.
+ It just checks what happens when the tool is missing. Checking the coverage
+ again, you will see that the first red bit has gone:
+
+ .. code-block:: bash
+
+ $ binman test -T
+ $ python3-coverage html
+
+#. The second red bit is for ``SetImagePos()``. You can see that it is iterating
+ through the sub-entries inside the ``nxp-imx8mimage`` entry. In the case of
+ the 339 file, there are no such entries, so this code inside the for() loop
+ isn't used:
+
+ .. code-block:: python
+
+ def SetImagePos(self, image_pos):
+ # Customized SoC specific SetImagePos which skips the mkimage etype
+ # implementation and removes the 0x48 offset introduced there. That
+ # offset is only used for uImage/fitImage, which is not the case in
+ # here.
+ upto = 0x00
+ for entry in super().GetEntries().values():
+ entry.SetOffsetSize(upto, None)
+
+ # Give up if any entries lack a size
+ if entry.size is None:
+ return
+ upto += entry.size
+
+ Entry_section.SetImagePos(self, image_pos)
+
+ The solution is to add an entry, e.g. in ``340_nxp_imx8_non_empty.dts``:
+
+ .. code-block:: devicetree
+
+ // SPDX-License-Identifier: GPL-2.0+
+
+ /dts-v1/;
+
+ / {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mimage {
+ args; /* TODO: Needed by mkimage etype superclass */
+ nxp,boot-from = "sd";
+ nxp,rom-version = <1>;
+ nxp,loader-address = <0x10>;
+
+ u-boot {
+ };
+ };
+ };
+ };
+
+ Now write a little test to use it:
+
+ .. code-block:: python
+
+ def testNxpImx8ImageNonEmpty(self):
+ """Test that binman can produce an iMX8 image with something in it"""
+ data = self._DoReadFile('340_nxp_imx8_non_empty.dts')
+ # check data here
+
+ With that, the second red bit goes away, because the for() loop is now used.
+
+#. There is one more red bit left, the ``return`` in ``SetImagePos()``. The
+ above effort got the for() loop to be executed, but it doesn't cover the
+ ``return``. It might have been copied from some other etype, e.g. the mkimage
+ one. See ``Entry_mkimage.SetImagePos()`` which contains the code:
+
+ .. code-block:: python
+
+ for entry in self.GetEntries().values():
+ entry.SetOffsetSize(upto, None)
+
+ # Give up if any entries lack a size
+ if entry.size is None:
+ return
+ upto += entry.size
+
+ But which test covers that code for mkimage? By figuring that out, you could
+ use a similar technique. One way to find out is to delete the two lines in
+ ``Entry_mkimage`` which check for entry.size being None and returning, then
+ see what breaks with ``binman test``:
+
+ .. code-block:: bash
+
+ ERROR: binman.ftest.TestFunctional.testMkimageCollection (subunit.RemotedTestCase)
+ binman.ftest.TestFunctional.testMkimageCollection
+ ----------------------------------------------------------------------
+ testtools.testresult.real._StringException: Traceback (most recent call last):
+ TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
+
+ ======================================================================
+ ERROR: binman.ftest.TestFunctional.testMkimageImage (subunit.RemotedTestCase)
+ binman.ftest.TestFunctional.testMkimageImage
+ ----------------------------------------------------------------------
+ testtools.testresult.real._StringException: Traceback (most recent call last):
+ TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
+
+ ======================================================================
+ ERROR: binman.ftest.TestFunctional.testMkimageSpecial (subunit.RemotedTestCase)
+ binman.ftest.TestFunctional.testMkimageSpecial
+ ----------------------------------------------------------------------
+ testtools.testresult.real._StringException: Traceback (most recent call last):
+ TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
+
+ We can verify that you got the right test, by putting the lines back in and
+ getting coverage for just that test:
+
+ .. code-block:: bash
+
+ binman test -T testMkimageCollection
+ python3-coverage html
+
+ You will see a lot of red since we are seeing test coverage just for one
+ test, but if you look in ``mkimage.py`` at ``SetImagePos()`` you will see
+ that the ``return`` is covered (i.e. it is marked green).
+
+ Looking at the ``.dts`` files for each of these tests, none jumps out as
+ being relevant to our case. It seems that this code just isn't needed, so the
+ best solution is to delete those two lines from the function:
+
+ .. code-block:: python
+
+ def SetImagePos(self, image_pos):
+ # Customized SoC specific SetImagePos which skips the mkimage etype
+ # implementation and removes the 0x48 offset introduced there. That
+ # offset is only used for uImage/fitImage, which is not the case in
+ # here.
+ upto = 0x00
+ for entry in super().GetEntries().values():
+ entry.SetOffsetSize(upto, None)
+ upto += entry.size
+
+ Entry_section.SetImagePos(self, image_pos)
+
+We should check the updated code on a real build, to make sure it really
+isn't needed, of course.
+
+Now, the test coverage is complete!
+
+If we later discover a case where those lines are needed, we can add the
+lines back, along with a test for this case.
+
+Getting help
+------------
+
+If you are stuck and cannot work out how to add test coverage for your entry
+type, ask on the U-Boot mailing list, cc ``Simon Glass <sjg@chromium.org>`` or
+on irc ``sjg1``
diff --git a/doc/develop/cedit.rst b/doc/develop/cedit.rst
index 82305b9..310be88 100644
--- a/doc/develop/cedit.rst
+++ b/doc/develop/cedit.rst
@@ -94,7 +94,7 @@
enum::
enum {
- ZERO,
+ ID_PROMPT = EXPOID_BASE_ID,
ID_PROMPT,
@@ -130,6 +130,11 @@
in the `.dts` file that is not mentioned in your enum. Check both files and try
again.
+Note that the first ID in your file must be no less that `EXPOID_BASE_ID` since
+IDs before that are reserved. The `expo.py` tool automatically obtains this
+value from the `expo.h` header file, but you must set the first ID to this
+enum value.
+
Use the command interface
-------------------------
diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst
index c87b6ec..cc7c361 100644
--- a/doc/develop/expo.rst
+++ b/doc/develop/expo.rst
@@ -88,8 +88,13 @@
handled by allocating space in the enum for a maximum number of items, then
adding the loop count to the enum values to obtain unique IDs.
-Where dynamic IDs are need, use expo_set_dynamic_start() to set the start value,
-so that they are allocated above the starting (enum) IDs.
+Some standard IDs are reserved for certain purposes. These are defined by
+`enum expo_id_t` and start at 1. `EXPOID_BASE_ID` defines the first ID which
+can be used for an expo.
+
+An ID of 0 is invalid. If this is specified in an expo call then a valid
+'dynamic IDs is allocated. Use expo_set_dynamic_start() to set the start
+value, so that they are allocated above the starting (enum) IDs.
All text strings are stored in a structure attached to the expo, referenced by
a text ID. This makes it easier at some point to implement multiple languages or
@@ -176,6 +181,10 @@
menuitem-gap-y
Number of pixels between menu items
+menu-title-margin-x
+ Number of pixels between right side of menu title to the left size of the
+ menu labels
+
Pop-up mode
-----------
@@ -352,6 +361,13 @@
Specifies the ID for each menu item. These are used for checking which item
has been selected.
+item-value
+ type: u32 list, optional
+
+ Specifies the value for each menu item. These are used for saving and
+ loading. If this is omitted the value is its position in the menu (0..n-1).
+ Valid values are positive and negative integers INT_MIN...(INT_MAX - 1).
+
item-label / item-label-id
type: string list / u32 list, required
@@ -413,8 +429,7 @@
/* this comment is parsed by the expo.py tool to insert the values below
enum {
- ZERO,
- ID_PROMPT,
+ ID_PROMPT = EXPOID_BASE_ID,
ID_SCENE1,
ID_SCENE1_TITLE,
@@ -466,6 +481,9 @@
/* IDs for the menu items */
item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+
+ /* values for the menu items */
+ item-value = <(-1) 3 6>;
};
power-loss {
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index c23192c..30f7fdb 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -83,6 +83,7 @@
py_testing
tests_writing
tests_sandbox
+ binman_tests
Refactoring
-----------
diff --git a/doc/git-mailrc b/doc/git-mailrc
index ca2f67a..1177e42 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -22,7 +22,7 @@
alias bmeng Bin Meng <bmeng.cn@gmail.com>
alias danielschwierzeck Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
alias dinh Dinh Nguyen <dinguyen@kernel.org>
-alias ehristev Eugen Hristev <eugen.hristev@collabora.com>
+alias ehristev Eugen Hristev <eugen.hristev@linaro.org>
alias hs Heiko Schocher <hs@denx.de>
alias freenix Peng Fan <peng.fan@nxp.com>
alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
diff --git a/doc/usage/cmd/cedit.rst b/doc/usage/cmd/cedit.rst
index 5670805..f29f1b3 100644
--- a/doc/usage/cmd/cedit.rst
+++ b/doc/usage/cmd/cedit.rst
@@ -107,8 +107,10 @@
/ {
cedit-values {
cpu-speed = <0x00000006>;
+ cpu-speed-value = <0x00000003>;
cpu-speed-str = "2 GHz";
power-loss = <0x0000000a>;
+ power-loss-value = <0x00000000>;
power-loss-str = "Always Off";
};
}
@@ -118,16 +120,23 @@
This shows settings being stored in the environment::
=> cedit write_env -v
- c.cpu-speed=7
+ c.cpu-speed=11
c.cpu-speed-str=2.5 GHz
- c.power-loss=12
- c.power-loss-str=Memory
+ c.cpu-speed-value=3
+ c.power-loss=14
+ c.power-loss-str=Always Off
+ c.power-loss-value=0
+ c.machine-name=my-machine
+ c.cpu-speed=11
+ c.power-loss=14
+ c.machine-name=my-machine
=> print
...
c.cpu-speed=6
c.cpu-speed-str=2 GHz
c.power-loss=10
c.power-loss-str=Always Off
+ c.machine-name=my-machine
...
=> cedit read_env -v
diff --git a/doc/usage/cmd/cpuid.rst b/doc/usage/cmd/cpuid.rst
new file mode 100644
index 0000000..cccf926
--- /dev/null
+++ b/doc/usage/cmd/cpuid.rst
@@ -0,0 +1,68 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+.. index::
+ single: cpuid (command)
+
+cpuid command
+=============
+
+Synopsis
+--------
+
+::
+
+ cpuid <op>
+
+Description
+-----------
+
+The cpuid command requests CPU-identification information on x86 CPUs. The
+operation <op> selects what information is returned. Up to four 32-bit registers
+can be update (eax-edx) depending on the operation.
+
+Configuration
+-------------
+
+The cpuid command is only available on x86.
+
+Return value
+------------
+
+The return value $? is 0 (true).
+
+Example
+-------
+
+::
+
+ => cpuid 1
+ eax 00060fb1
+ ebx 00040800
+ ecx 80002001
+ edx 178bfbfd
+
+This shows checking for 64-bit 'long' mode::
+
+ => cpuid 80000000
+ eax 8000000a
+ ebx 68747541
+ ecx 444d4163
+ edx 69746e65
+ => cpuid 80000001
+ eax 00060fb1
+ ebx 00000000
+ ecx 00000007
+ edx 2193fbfd # Bit 29 is set in edx, so long mode is available
+
+On a 32-bit-only CPU::
+
+ => cpuid 80000000
+ eax 80000004
+ ebx 756e6547
+ ecx 6c65746e
+ edx 49656e69
+ => cpuid 80000001
+ eax 00000663
+ ebx 00000000
+ ecx 00000000
+ edx 00000000 # Bit 29 is not set in edx, so long mode is not available
diff --git a/doc/usage/cmd/font.rst b/doc/usage/cmd/font.rst
index a8782546..44a04f5 100644
--- a/doc/usage/cmd/font.rst
+++ b/doc/usage/cmd/font.rst
@@ -13,7 +13,7 @@
font list
font select <name> [<size>]
- font size <size>
+ font size [<size>]
Description
-----------
@@ -34,7 +34,7 @@
font size
~~~~~~~~~
-This changes the font size only.
+This changes the font size only. With no argument it shows the current size.
Examples
--------
@@ -44,6 +44,8 @@
=> font list
nimbus_sans_l_regular
cantoraone_regular
+ => font size
+ 30
=> font size 40
=> font select cantoraone_regular 20
=>
diff --git a/doc/usage/cmd/msr.rst b/doc/usage/cmd/msr.rst
new file mode 100644
index 0000000..04ee52c
--- /dev/null
+++ b/doc/usage/cmd/msr.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+.. index::
+ single: msr (command)
+
+msr command
+===========
+
+Synopsis
+--------
+
+::
+
+ msr read <op>
+ msr write <op> <hi> <lo>
+
+Description
+-----------
+
+The msr command reads and writes machine-status registers (MSRs) on x86 CPUs.
+The information is a 64-bit value split into two parts, <hi> for the top 32
+bits and <lo> for the bottom 32 bits.
+
+The operation <op> selects what information is read or written.
+
+msr read
+~~~~~~~~
+
+This reads an MSR and displays the value obtained.
+
+msr write
+~~~~~~~~~
+
+This writes a value to an MSR.
+
+Configuration
+-------------
+
+The msr command is only available on x86.
+
+Return value
+------------
+
+The return value $? is 0 (true).
+
+Example
+-------
+
+This shows reading msr 0x194 which is MSR_FLEX_RATIO on Intel CPUs::
+
+ => msr read 194
+ 00000000 00011200 # Bits 16 (flex ratio enable) and 20 (lock) are set
+
+This shows adjusting the energy-performance bias on an Intel CPU::
+
+ => msr read 1b0
+ 00000000 00000006 # 6 means 'normal'
+
+ => msr write 1b0 0 f # change to power-save
+ => msr read 1b0
+ 00000000 0000000f
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index fcce125..b84d8ee 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -52,6 +52,7 @@
cmd/conitrace
cmd/cp
cmd/cpu
+ cmd/cpuid
cmd/cyclic
cmd/dm
cmd/ebtupdate
@@ -86,6 +87,7 @@
cmd/mbr
cmd/md
cmd/mmc
+ cmd/msr
cmd/mtest
cmd/mtrr
cmd/panic
diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c
index 62fed7e..466d717 100644
--- a/drivers/clk/imx/clk-imx8qm.c
+++ b/drivers/clk/imx/clk-imx8qm.c
@@ -48,6 +48,8 @@
debug("%s(#%lu)\n", __func__, clk->id);
switch (clk->id) {
+ case IMX8QM_CLK_DUMMY:
+ return 0;
case IMX8QM_A53_DIV:
resource = SC_R_A53;
pm_clk = SC_PM_CLK_CPU;
@@ -264,6 +266,8 @@
debug("%s(#%lu)\n", __func__, clk->id);
switch (clk->id) {
+ case IMX8QM_CLK_DUMMY:
+ return 0;
case IMX8QM_I2C0_IPG_CLK:
case IMX8QM_I2C0_CLK:
case IMX8QM_I2C0_DIV:
diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
index 18bdc08..7909862 100644
--- a/drivers/clk/imx/clk-imx8qxp.c
+++ b/drivers/clk/imx/clk-imx8qxp.c
@@ -51,6 +51,8 @@
debug("%s(#%lu)\n", __func__, clk->id);
switch (clk->id) {
+ case IMX8QXP_CLK_DUMMY:
+ return 0;
case IMX8QXP_A35_DIV:
resource = SC_R_A35;
pm_clk = SC_PM_CLK_CPU;
@@ -248,6 +250,8 @@
debug("%s(#%lu)\n", __func__, clk->id);
switch (clk->id) {
+ case IMX8QXP_CLK_DUMMY:
+ return 0;
case IMX8QXP_I2C0_CLK:
case IMX8QXP_I2C0_IPG_CLK:
resource = SC_R_I2C_0;
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c
index 6c0a8c0..51262be 100644
--- a/drivers/cpu/imx8_cpu.c
+++ b/drivers/cpu/imx8_cpu.c
@@ -20,10 +20,11 @@
DECLARE_GLOBAL_DATA_PTR;
+#define IMX_REV_LEN 4
struct cpu_imx_plat {
const char *name;
- const char *rev;
const char *type;
+ char rev[IMX_REV_LEN];
u32 cpu_rsrc;
u32 cpurev;
u32 freq_mhz;
@@ -69,28 +70,29 @@
}
}
-static const char *get_imx_rev_str(u32 rev)
+static void get_imx_rev_str(struct cpu_imx_plat *plat, u32 rev)
{
- static char revision[4];
-
if (IS_ENABLED(CONFIG_IMX8)) {
switch (rev) {
case CHIP_REV_A:
- return "A";
+ plat->rev[0] = 'A';
+ break;
case CHIP_REV_B:
- return "B";
+ plat->rev[0] = 'B';
+ break;
case CHIP_REV_C:
- return "C";
+ plat->rev[0] = 'C';
+ break;
default:
- return "?";
+ plat->rev[0] = '?';
+ break;
}
+ plat->rev[1] = '\0';
} else {
- revision[0] = '1' + (((rev & 0xf0) - CHIP_REV_1_0) >> 4);
- revision[1] = '.';
- revision[2] = '0' + (rev & 0xf);
- revision[3] = '\0';
-
- return revision;
+ plat->rev[0] = '1' + (((rev & 0xf0) - CHIP_REV_1_0) >> 4);
+ plat->rev[1] = '.';
+ plat->rev[2] = '0' + (rev & 0xf);
+ plat->rev[3] = '\0';
}
}
@@ -318,7 +320,7 @@
set_core_data(dev);
cpurev = get_cpu_rev();
plat->cpurev = cpurev;
- plat->rev = get_imx_rev_str(cpurev & 0xFFF);
+ get_imx_rev_str(plat, cpurev & 0xFFF);
plat->type = get_imx_type_str((cpurev & 0x1FF000) >> 12);
plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000;
plat->mpidr = dev_read_addr(dev);
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 80c084f..dd16ab3 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -83,7 +83,7 @@
if (cpuid_eax(0) < 0x16)
return 0;
- return cpuid_eax(0x16);
+ return cpuid_eax(0x15);
}
/*
@@ -299,10 +299,19 @@
if (!pit_expect_msb(0xff-i, &delta, &d2))
break;
+ delta -= tsc;
+
+ /*
+ * Extrapolate the error and fail fast if the error will
+ * never be below 500 ppm.
+ */
+ if (i == 1 &&
+ d1 + d2 >= (delta * MAX_QUICK_PIT_ITERATIONS) >> 11)
+ return 0;
+
/*
* Iterate until the error is less than 500 ppm
*/
- delta -= tsc;
if (d1+d2 >= delta >> 11)
continue;
@@ -403,6 +412,10 @@
if (!gd->arch.clock_rate) {
unsigned long fast_calibrate;
+ /* deal with this being called before x86_cpu_init_f() */
+ if (!gd->arch.x86_vendor)
+ x86_get_identity_for_timer();
+
/**
* There is no obvious way to obtain this information from EFI
* boot services. This value was measured on a Framework Laptop
@@ -438,6 +451,7 @@
return;
done:
+ fast_calibrate = min(fast_calibrate, 4000UL);
if (!gd->arch.clock_rate)
gd->arch.clock_rate = fast_calibrate * 1000000;
}
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 80e7adf..ebe96bf 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -94,7 +94,9 @@
priv->ycur += priv->y_charsize;
/* Check if we need to scroll the terminal */
- if ((priv->ycur + priv->y_charsize) / priv->y_charsize > priv->rows) {
+ if (vid_priv->rot % 2 ?
+ priv->ycur + priv->x_charsize > vid_priv->xsize :
+ priv->ycur + priv->y_charsize > vid_priv->ysize) {
vidconsole_move_rows(dev, 0, rows, priv->rows - rows);
for (i = 0; i < rows; i++)
vidconsole_set_row(dev, priv->rows - i - 1,
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index 9823673..a5b3e89 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -294,6 +294,9 @@
{ 0xff, 0x00, 0xff }, /* bright magenta */
{ 0x00, 0xff, 0xff }, /* bright cyan */
{ 0xff, 0xff, 0xff }, /* white */
+
+ /* an extra one for menus */
+ { 0x40, 0x40, 0x40 }, /* dark gray */
};
u32 video_index_to_colour(struct video_priv *priv, enum colour_idx idx)
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 3404f61..2f999fc 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -18,30 +18,82 @@
struct virtqueue *vq;
};
+static const u32 feature[] = {
+ VIRTIO_BLK_F_WRITE_ZEROES
+};
+
+static void virtio_blk_init_header_sg(struct udevice *dev, u64 sector, u32 type,
+ struct virtio_blk_outhdr *out_hdr, struct virtio_sg *sg)
+{
+ const bool sector_is_needed = type == VIRTIO_BLK_T_IN ||
+ type == VIRTIO_BLK_T_OUT;
+
+ out_hdr->type = cpu_to_virtio32(dev, type);
+ out_hdr->sector = cpu_to_virtio64(dev, sector_is_needed ? sector : 0);
+
+ sg->addr = out_hdr;
+ sg->length = sizeof(*out_hdr);
+}
+
+static void virtio_blk_init_write_zeroes_sg(struct udevice *dev, u64 sector, lbaint_t blkcnt,
+ struct virtio_blk_discard_write_zeroes *wz,
+ struct virtio_sg *sg)
+{
+ wz->sector = cpu_to_virtio64(dev, sector);
+ wz->num_sectors = cpu_to_virtio32(dev, blkcnt);
+ wz->flags = cpu_to_virtio32(dev, 0);
+
+ sg->addr = wz;
+ sg->length = sizeof(*wz);
+}
+
+static void virtio_blk_init_status_sg(u8 *status, struct virtio_sg *sg)
+{
+ sg->addr = status;
+ sg->length = sizeof(*status);
+}
+
+static void virtio_blk_init_data_sg(void *buffer, lbaint_t blkcnt, struct virtio_sg *sg)
+{
+ sg->addr = buffer;
+ sg->length = blkcnt * 512;
+}
+
static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
lbaint_t blkcnt, void *buffer, u32 type)
{
struct virtio_blk_priv *priv = dev_get_priv(dev);
+ struct virtio_blk_outhdr out_hdr;
+ struct virtio_blk_discard_write_zeroes wz_hdr;
unsigned int num_out = 0, num_in = 0;
+ struct virtio_sg hdr_sg, wz_sg, data_sg, status_sg;
struct virtio_sg *sgs[3];
u8 status;
int ret;
- struct virtio_blk_outhdr out_hdr = {
- .type = cpu_to_virtio32(dev, type),
- .sector = cpu_to_virtio64(dev, sector),
- };
- struct virtio_sg hdr_sg = { &out_hdr, sizeof(out_hdr) };
- struct virtio_sg data_sg = { buffer, blkcnt * 512 };
- struct virtio_sg status_sg = { &status, sizeof(status) };
-
+ virtio_blk_init_header_sg(dev, sector, type, &out_hdr, &hdr_sg);
sgs[num_out++] = &hdr_sg;
- if (type & VIRTIO_BLK_T_OUT)
- sgs[num_out++] = &data_sg;
- else
- sgs[num_out + num_in++] = &data_sg;
+ switch (type) {
+ case VIRTIO_BLK_T_IN:
+ case VIRTIO_BLK_T_OUT:
+ virtio_blk_init_data_sg(buffer, blkcnt, &data_sg);
+ if (type & VIRTIO_BLK_T_OUT)
+ sgs[num_out++] = &data_sg;
+ else
+ sgs[num_out + num_in++] = &data_sg;
+ break;
+ case VIRTIO_BLK_T_WRITE_ZEROES:
+ virtio_blk_init_write_zeroes_sg(dev, sector, blkcnt, &wz_hdr, &wz_sg);
+ sgs[num_out++] = &wz_sg;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ virtio_blk_init_status_sg(&status, &status_sg);
sgs[num_out + num_in++] = &status_sg;
log_debug("dev=%s, active=%d, priv=%p, priv->vq=%p\n", dev->name,
device_active(dev), priv, priv->vq);
@@ -75,6 +127,15 @@
VIRTIO_BLK_T_OUT);
}
+static ulong virtio_blk_erase(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt)
+{
+ if (!virtio_has_feature(dev, VIRTIO_BLK_F_WRITE_ZEROES))
+ return -EOPNOTSUPP;
+
+ return virtio_blk_do_req(dev, start, blkcnt, NULL, VIRTIO_BLK_T_WRITE_ZEROES);
+}
+
static int virtio_blk_bind(struct udevice *dev)
{
struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
@@ -104,7 +165,8 @@
desc->bdev = dev;
/* Indicate what driver features we support */
- virtio_driver_features_init(uc_priv, NULL, 0, NULL, 0);
+ virtio_driver_features_init(uc_priv, feature, ARRAY_SIZE(feature),
+ NULL, 0);
return 0;
}
@@ -131,6 +193,7 @@
static const struct blk_ops virtio_blk_ops = {
.read = virtio_blk_read,
.write = virtio_blk_write,
+ .erase = virtio_blk_erase,
};
U_BOOT_DRIVER(virtio_blk) = {
diff --git a/drivers/virtio/virtio_blk.h b/drivers/virtio/virtio_blk.h
index 8d8e02f..b37ba26 100644
--- a/drivers/virtio/virtio_blk.h
+++ b/drivers/virtio/virtio_blk.h
@@ -17,6 +17,8 @@
#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
#define VIRTIO_BLK_F_MQ 12 /* Support more than one vq */
+#define VIRTIO_BLK_F_DISCARD 13 /* Discard is supported */
+#define VIRTIO_BLK_F_WRITE_ZEROES 14 /* Write zeroes is supported */
/* Legacy feature bits */
#ifndef VIRTIO_BLK_NO_LEGACY
@@ -65,6 +67,39 @@
/* number of vqs, only available when VIRTIO_BLK_F_MQ is set */
__u16 num_queues;
+
+ /* the next 3 entries are guarded by VIRTIO_BLK_F_DISCARD */
+ /*
+ * The maximum discard sectors (in 512-byte sectors) for
+ * one segment.
+ */
+ __u32 max_discard_sectors;
+ /*
+ * The maximum number of discard segments in a
+ * discard command.
+ */
+ __u32 max_discard_seg;
+ /* Discard commands must be aligned to this number of sectors. */
+ __u32 discard_sector_alignment;
+
+ /* the next 3 entries are guarded by VIRTIO_BLK_F_WRITE_ZEROES */
+ /*
+ * The maximum number of write zeroes sectors (in 512-byte sectors) in
+ * one segment.
+ */
+ __u32 max_write_zeroes_sectors;
+ /*
+ * The maximum number of segments in a write zeroes
+ * command.
+ */
+ __u32 max_write_zeroes_seg;
+ /*
+ * Set if a VIRTIO_BLK_T_WRITE_ZEROES request may result in the
+ * deallocation of one or more of the sectors.
+ */
+ __u8 write_zeroes_may_unmap;
+
+ __u8 unused1[3];
};
/*
@@ -93,6 +128,9 @@
/* Get device ID command */
#define VIRTIO_BLK_T_GET_ID 8
+/* Write zeroes command */
+#define VIRTIO_BLK_T_WRITE_ZEROES 13
+
#ifndef VIRTIO_BLK_NO_LEGACY
/* Barrier before this op */
#define VIRTIO_BLK_T_BARRIER 0x80000000
@@ -112,6 +150,15 @@
__virtio64 sector;
};
+struct virtio_blk_discard_write_zeroes {
+ /* discard/write zeroes start sector */
+ __virtio64 sector;
+ /* number of discard/write zeroes sectors */
+ __virtio32 num_sectors;
+ /* flags for this range */
+ __virtio32 flags;
+};
+
#ifndef VIRTIO_BLK_NO_LEGACY
struct virtio_scsi_inhdr {
__virtio32 errors;
diff --git a/dts/Kconfig b/dts/Kconfig
index 7ea4fd5..ffd50c04 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -125,6 +125,22 @@
help
Select the vendor to build all devicetree files for.
+config OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS
+ bool "Build local DTBOs as fallback for DTBOs missing upstream"
+ default n
+ depends on OF_UPSTREAM
+ help
+ Enable building DTBOs from arch/$(ARCH)/dts as a fallback for
+ DTBOs which are not part of Linux kernel upstream yet. This is
+ a stopgap measure to expedite OF_UPSTREAM switch for platforms
+ which already have main DT in Linux kernel upstream, but still
+ have leftover DTBOs in U-Boot tree.
+
+ Do not use this option, upstream your DTs and DTBOs instead.
+ If the upstreaming is in progress, use with utmost caution.
+
+ If unsure, say N.
+
choice
prompt "Provider of DTB for DT control"
depends on OF_CONTROL
diff --git a/dts/Makefile b/dts/Makefile
index 62a6568..86bf8dc 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -20,6 +20,12 @@
dt_dir := arch/$(ARCH)/dts
endif
+ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
+local_dtbos := local-dtbos
+else
+local_dtbos :=
+endif
+
ifneq ($(EXT_DTB),)
DTB := $(EXT_DTB)
else
@@ -40,7 +46,7 @@
targets += dt.dtb
-$(DTB): arch-dtbs
+$(DTB): arch-dtbs $(local_dtbos)
$(Q)test -e $@ || ( \
echo >&2; \
echo >&2 "Device Tree Source ($@) is not correctly specified."; \
@@ -53,6 +59,12 @@
arch-dtbs:
$(Q)$(MAKE) $(build)=$(dt_dir) dtbs
+ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
+PHONY += local-dtbos
+local-dtbos:
+ $(Q)$(MAKE) $(build)=arch/$(ARCH)/dts dtbos
+endif
+
ifeq ($(CONFIG_XPL_BUILD),y)
obj-$(CONFIG_OF_EMBED) := dt-spl.dtb.o
# support "out-of-tree" build for dtb-spl
diff --git a/include/blk.h b/include/blk.h
index 1fc9a5b..eef6c86 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -197,7 +197,6 @@
#endif
-#if CONFIG_IS_ENABLED(BLK)
struct udevice;
/* Operations on block devices */
@@ -278,6 +277,8 @@
#endif /* CONFIG_BOUNCE_BUFFER */
};
+#if CONFIG_IS_ENABLED(BLK)
+
/*
* These functions should take struct udevice instead of struct blk_desc,
* but this is convenient for migration to driver model. Add a 'd' prefix
@@ -291,6 +292,8 @@
unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt);
+#endif /* BLK */
+
/**
* blk_read() - Read from a block device
*
@@ -528,8 +531,10 @@
*/
int blk_get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp);
-#else
+#if !CONFIG_IS_ENABLED(BLK)
+
#include <errno.h>
+
/*
* These functions should take struct udevice instead of struct blk_desc,
* but this is convenient for migration to driver model. Add a 'd' prefix
diff --git a/include/cedit.h b/include/cedit.h
index a31b424..856509f 100644
--- a/include/cedit.h
+++ b/include/cedit.h
@@ -14,6 +14,7 @@
struct abuf;
struct expo;
struct scene;
+struct udevice;
struct video_priv;
struct udevice;
diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h
index 9b6f03f..0935493 100644
--- a/include/configs/dh_imx6.h
+++ b/include/configs/dh_imx6.h
@@ -36,10 +36,9 @@
#endif
#define CFG_EXTRA_ENV_SETTINGS \
+ "bootm_size=0x10000000\0" \
"console=ttymxc0,115200\0" \
"fdt_addr=0x18000000\0" \
- "fdt_high=0xffffffff\0" \
- "initrd_high=0xffffffff\0" \
"kernel_addr_r=0x10008000\0" \
"fdt_addr_r=0x13000000\0" \
"ramdisk_addr_r=0x18000000\0" \
diff --git a/include/expo.h b/include/expo.h
index c235fa2..8cb3726 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -16,6 +16,26 @@
#include <cli.h>
/**
+ * enum expo_id_t - standard expo IDs
+ *
+ * These are assumed to be in use at all times. Expos should use IDs starting
+ * from EXPOID_BASE_ID,
+ *
+ * @EXPOID_NONE: Not used, invalid ID 0
+ * @EXPOID_SAVE: User has requested that the expo data be saved
+ * @EXPOID_DISCARD: User has requested that the expo data be discarded
+ * @EXPOID_BASE_ID: First ID which can be used for expo objects
+ */
+enum expo_id_t {
+ EXPOID_NONE,
+
+ EXPOID_SAVE,
+ EXPOID_DISCARD,
+
+ EXPOID_BASE_ID = 5,
+};
+
+/**
* enum expoact_type - types of actions reported by the expo
*
* @EXPOACT_NONE: no action
@@ -59,11 +79,14 @@
* @font_size: Default font size for all text
* @menu_inset: Inset width (on each side and top/bottom) for menu items
* @menuitem_gap_y: Gap between menu items in pixels
+ * @menu_title_margin_x: Gap between right side of menu title and left size of
+ * menu label
*/
struct expo_theme {
u32 font_size;
u32 menu_inset;
u32 menuitem_gap_y;
+ u32 menu_title_margin_x;
};
/**
@@ -307,6 +330,7 @@
* @desc_id: ID of text object to use as the description text
* @preview_id: ID of the preview object, or 0 if none
* @flags: Flags for this item
+ * @value: Value for this item, or INT_MAX to use sequence
* @sibling: Node to link this item to its siblings
*/
struct scene_menitem {
@@ -317,6 +341,7 @@
uint desc_id;
uint preview_id;
uint flags;
+ int value;
struct list_head sibling;
};
@@ -342,6 +367,15 @@
};
/**
+ * struct expo_arrange_info - Information used when arranging a scene
+ *
+ * @label_width: Maximum width of labels in scene
+ */
+struct expo_arrange_info {
+ int label_width;
+};
+
+/**
* expo_new() - create a new expo
*
* Allocates a new expo
@@ -507,15 +541,6 @@
int scene_set_open(struct scene *scn, uint id, bool open);
/**
- * scene_title_set() - set the scene title
- *
- * @scn: Scene to update
- * @title_id: Title ID to set
- * Returns: 0 if OK
- */
-int scene_title_set(struct scene *scn, uint title_id);
-
-/**
* scene_obj_count() - Count the number of objects in a scene
*
* @scn: Scene to check
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 1ae586b..655a6d1 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -182,15 +182,15 @@
/* Status Register 2 bits. */
#define SR2_QUAD_EN_BIT7 BIT(7)
+/* Status Register 3 bits. */
+#define SR3_WPS BIT(2)
+
/*
* Maximum number of flashes that can be connected
* in stacked/parallel configuration
*/
#define SNOR_FLASH_CNT_MAX 2
-/* Status Register 3 bits. */
-#define SR3_WPS BIT(2)
-
/* For Cypress flash. */
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
diff --git a/include/test/cedit-test.h b/include/test/cedit-test.h
index 475ecc9..0d38a95 100644
--- a/include/test/cedit-test.h
+++ b/include/test/cedit-test.h
@@ -9,24 +9,24 @@
#ifndef __cedit_test_h
#define __cedit_test_h
-#define ID_PROMPT 1
-#define ID_SCENE1 2
-#define ID_SCENE1_TITLE 3
+#define ID_PROMPT 5
+#define ID_SCENE1 6
+#define ID_SCENE1_TITLE 7
-#define ID_CPU_SPEED 4
-#define ID_CPU_SPEED_TITLE 5
-#define ID_CPU_SPEED_1 6
-#define ID_CPU_SPEED_2 7
-#define ID_CPU_SPEED_3 8
+#define ID_CPU_SPEED 8
+#define ID_CPU_SPEED_TITLE 9
+#define ID_CPU_SPEED_1 10
+#define ID_CPU_SPEED_2 11
+#define ID_CPU_SPEED_3 12
-#define ID_POWER_LOSS 9
-#define ID_AC_OFF 10
-#define ID_AC_ON 11
-#define ID_AC_MEMORY 12
+#define ID_POWER_LOSS 13
+#define ID_AC_OFF 14
+#define ID_AC_ON 15
+#define ID_AC_MEMORY 16
-#define ID_MACHINE_NAME 13
-#define ID_MACHINE_NAME_EDIT 14
+#define ID_MACHINE_NAME 17
+#define ID_MACHINE_NAME_EDIT 18
-#define ID_DYNAMIC_START 15
+#define ID_DYNAMIC_START 19
#endif
diff --git a/include/video.h b/include/video.h
index 606c8a3..c7afe22 100644
--- a/include/video.h
+++ b/include/video.h
@@ -78,7 +78,8 @@
*
* @xsize: Number of pixel columns (e.g. 1366)
* @ysize: Number of pixels rows (e.g.. 768)
- * @rot: Display rotation (0=none, 1=90 degrees clockwise, etc.)
+ * @rot: Display rotation (0=none, 1=90 degrees clockwise, etc.). THis
+ * does not affect @xsize and @ysize
* @bpix: Encoded bits per pixel (enum video_log2_bpp)
* @format: Pixel format (enum video_format)
* @vidconsole_drv_name: Driver to use for the text console, NULL to
@@ -181,6 +182,7 @@
VID_LIGHT_MAGENTA,
VID_LIGHT_CYAN,
VID_WHITE,
+ VID_DARK_GREY,
VID_COLOUR_COUNT
};
diff --git a/include/video_console.h b/include/video_console.h
index 8b5928d..723d231 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -27,6 +27,14 @@
* Drivers must set up @rows, @cols, @x_charsize, @y_charsize in their probe()
* method. Drivers may set up @xstart_frac if desired.
*
+ * Note that these values relate to the rotated console, so that an 80x25
+ * console which is rotated 90 degrees will have rows=80 and cols=25
+ *
+ * The xcur_frac and ycur values refer to the unrotated coordinates, that is
+ * xcur_frac always advances with each character, even if its limit might be
+ * vid_priv->ysize instead of vid_priv->xsize if the console is rotated 90 or
+ * 270 degrees.
+ *
* @sdev: stdio device, acting as an output sink
* @xcur_frac: Current X position, in fractional units (VID_TO_POS(x))
* @ycur: Current Y position in pixels (0=top)
diff --git a/lib/lmb.c b/lib/lmb.c
index 78fe2d4..7e90f17 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -487,7 +487,7 @@
struct alist *lmb_rgn_lst = &lmb.free_mem;
ret = lmb_add_region(lmb_rgn_lst, base, size);
- if (ret)
+ if (ret < 0)
return ret;
if (lmb_should_notify(LMB_NONE))
diff --git a/lib/mbedtls/pkcs7_parser.c b/lib/mbedtls/pkcs7_parser.c
index 69ca784..ecfcc46 100644
--- a/lib/mbedtls/pkcs7_parser.c
+++ b/lib/mbedtls/pkcs7_parser.c
@@ -206,9 +206,6 @@
p += seq_len;
}
- if (ret && ret != MBEDTLS_ERR_ASN1_OUT_OF_DATA)
- return ret;
-
msg->have_authattrs = true;
/*
@@ -361,8 +358,10 @@
signed_info->sig = s;
/* Save the Authenticate Attributes data if exists */
- if (!mb_sinfo->authattrs.data || !mb_sinfo->authattrs.data_len)
+ if (!mb_sinfo->authattrs.data || !mb_sinfo->authattrs.data_len) {
+ kfree(mctx);
goto no_authattrs;
+ }
mctx->authattrs_data = kmemdup(mb_sinfo->authattrs.data,
mb_sinfo->authattrs.data_len,
diff --git a/lib/mbedtls/x509_cert_parser.c b/lib/mbedtls/x509_cert_parser.c
index cb42018..e163e16 100644
--- a/lib/mbedtls/x509_cert_parser.c
+++ b/lib/mbedtls/x509_cert_parser.c
@@ -66,7 +66,7 @@
static char *x509_populate_dn_name_string(const mbedtls_x509_name *name)
{
size_t len = 256;
- size_t wb;
+ int wb;
char *name_str;
do {
diff --git a/scripts/Makefile.dts b/scripts/Makefile.dts
index 994098c..685e337 100644
--- a/scripts/Makefile.dts
+++ b/scripts/Makefile.dts
@@ -22,4 +22,10 @@
dtbs: $(addprefix $(obj)/, $(dtb-y))
@:
+ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),)
+PHONY += dtbos
+dtbos: $(addprefix $(obj)/, $(filter-out %.dtb,$(dtb-y)))
+ @:
+endif
+
clean-files := *.dtb *.dtbo */*.dtb */*.dtbo *_HS
diff --git a/test/boot/cedit.c b/test/boot/cedit.c
index 1f7af8e..4d1b99b 100644
--- a/test/boot/cedit.c
+++ b/test/boot/cedit.c
@@ -31,9 +31,11 @@
* ^N Move down to second item
* ^M Select item
* \e Quit
+ *
+ * cedit_run() returns -EACCESS so this command returns CMD_RET_FAILURE
*/
console_in_puts("\x0e\x0d\x0e\x0d\e");
- ut_assertok(run_command("cedit run", 0));
+ ut_asserteq(1, run_command("cedit run", 0));
exp = cur_exp;
scn = expo_lookup_scene_id(exp, exp->scene_id);
@@ -94,14 +96,16 @@
ut_asserteq(ID_CPU_SPEED_2,
ofnode_read_u32_default(node, "cpu-speed", 0));
+ ut_asserteq(3,
+ ofnode_read_u32_default(node, "cpu-speed-value", 0));
ut_asserteq_str("2.5 GHz", ofnode_read_string(node, "cpu-speed-str"));
ut_asserteq_str("my-machine", ofnode_read_string(node, "machine-name"));
- /* There should only be 5 properties */
+ /* There should only be 7 properties */
for (i = 0, ofnode_first_property(node, &prop); ofprop_valid(&prop);
i++, ofnode_next_property(&prop))
;
- ut_asserteq(5, i);
+ ut_asserteq(7, i);
ut_assert_console_end();
@@ -147,14 +151,16 @@
strcpy(str, "my-machine");
ut_assertok(run_command("cedit write_env -v", 0));
- ut_assert_nextlinen("c.cpu-speed=7");
+ ut_assert_nextlinen("c.cpu-speed=11");
ut_assert_nextlinen("c.cpu-speed-str=2.5 GHz");
- ut_assert_nextlinen("c.power-loss=10");
+ ut_assert_nextlinen("c.cpu-speed-value=3");
+ ut_assert_nextlinen("c.power-loss=14");
ut_assert_nextlinen("c.power-loss-str=Always Off");
+ ut_assert_nextlinen("c.power-loss-value=0");
ut_assert_nextlinen("c.machine-name=my-machine");
ut_assert_console_end();
- ut_asserteq(7, env_get_ulong("c.cpu-speed", 10, 0));
+ ut_asserteq(11, env_get_ulong("c.cpu-speed", 10, 0));
ut_asserteq_str("2.5 GHz", env_get("c.cpu-speed-str"));
ut_asserteq_str("my-machine", env_get("c.machine-name"));
@@ -163,8 +169,8 @@
*str = '\0';
ut_assertok(run_command("cedit read_env -v", 0));
- ut_assert_nextlinen("c.cpu-speed=7");
- ut_assert_nextlinen("c.power-loss=10");
+ ut_assert_nextlinen("c.cpu-speed=11");
+ ut_assert_nextlinen("c.power-loss=14");
ut_assert_nextlinen("c.machine-name=my-machine");
ut_assert_console_end();
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 9b4aa80..db14ff8 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -91,7 +91,7 @@
*name = '\0';
ut_assertnonnull(exp);
ut_asserteq(0, exp->scene_id);
- ut_asserteq(0, exp->next_id);
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
/* Make sure the name was allocated */
ut_assertnonnull(exp->name);
@@ -130,7 +130,7 @@
ut_assertok(expo_new(EXPO_NAME, NULL, &exp));
scn = NULL;
- ut_asserteq(0, exp->next_id);
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
strcpy(name, SCENE_NAME1);
id = scene_new(exp, name, SCENE1, &scn);
*name = '\0';
@@ -151,7 +151,7 @@
scn = NULL;
id = scene_new(exp, SCENE_NAME2, 0, &scn);
ut_assertnonnull(scn);
- ut_assertok(scene_title_set(scn, title_id));
+ scn->title_id = title_id;
ut_asserteq(STR_SCENE_TITLE + 1, id);
ut_asserteq(STR_SCENE_TITLE + 2, exp->next_id);
ut_asserteq_ptr(exp, scn->expo);
@@ -167,6 +167,25 @@
}
BOOTSTD_TEST(expo_scene, UTF_DM | UTF_SCAN_FDT);
+/* Check creating a scene with no ID */
+static int expo_scene_no_id(struct unit_test_state *uts)
+{
+ struct scene *scn;
+ struct expo *exp;
+ char name[100];
+ int id;
+
+ ut_assertok(expo_new(EXPO_NAME, NULL, &exp));
+ ut_asserteq(EXPOID_BASE_ID, exp->next_id);
+
+ strcpy(name, SCENE_NAME1);
+ id = scene_new(exp, SCENE_NAME1, 0, &scn);
+ ut_asserteq(EXPOID_BASE_ID, scn->id);
+
+ return 0;
+}
+BOOTSTD_TEST(expo_scene_no_id, UTF_DM | UTF_SCAN_FDT);
+
/* Check creating a scene with objects */
static int expo_object(struct unit_test_state *uts)
{
@@ -698,6 +717,7 @@
ut_asserteq(0, item->desc_id);
ut_asserteq(0, item->preview_id);
ut_asserteq(0, item->flags);
+ ut_asserteq(0, item->value);
txt = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE);
ut_asserteq_str("2 GHz", expo_get_str(exp, txt->str_id));
diff --git a/test/boot/files/expo_ids.h b/test/boot/files/expo_ids.h
index a86e0d0..ffb5113 100644
--- a/test/boot/files/expo_ids.h
+++ b/test/boot/files/expo_ids.h
@@ -4,8 +4,7 @@
*/
enum {
- ZERO,
- ID_PROMPT,
+ ID_PROMPT = EXPOID_BASE_ID,
ID_SCENE1,
ID_SCENE1_TITLE,
diff --git a/test/boot/files/expo_layout.dts b/test/boot/files/expo_layout.dts
index bed5522..9bc1e49 100644
--- a/test/boot/files/expo_layout.dts
+++ b/test/boot/files/expo_layout.dts
@@ -39,8 +39,11 @@
item-id = <ID_CPU_SPEED_1 ID_CPU_SPEED_2
ID_CPU_SPEED_3>;
+ /* values for the menu items */
+ item-value = <0 3 6>;
+
start-bit = <0x400>;
- bit-length = <2>;
+ bit-length = <3>;
};
power-loss {
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index dbee9b2..4080835 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -12,6 +12,7 @@
obj-$(CONFIG_CMD_PAUSE) += test_pause.o
endif
obj-y += exit.o mem.o
+obj-$(CONFIG_X86) += cpuid.o msr.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_FDT) += fdt.o
diff --git a/test/cmd/cpuid.c b/test/cmd/cpuid.c
new file mode 100644
index 0000000..e07f5fd
--- /dev/null
+++ b/test/cmd/cpuid.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for cpuid command
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <test/cmd.h>
+#include <test/ut.h>
+
+static int cmd_test_cpuid(struct unit_test_state *uts)
+{
+ ut_assertok(run_commandf("cpuid 1"));
+ ut_assert_nextline("eax 00060fb1");
+ ut_assert_nextline("ebx 00000800");
+ ut_assert_nextline("ecx 80002001");
+ ut_assert_nextline("edx 078bfbfd");
+
+ return 0;
+}
+CMD_TEST(cmd_test_cpuid, UTF_CONSOLE);
diff --git a/test/cmd/font.c b/test/cmd/font.c
index 25d365d..3335dd6 100644
--- a/test/cmd/font.c
+++ b/test/cmd/font.c
@@ -27,14 +27,20 @@
ut_assertok(uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev));
ut_assertok(run_command("font list", 0));
- ut_assert_nextline("nimbus_sans_l_regular");
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_NIMBUS))
+ ut_assert_nextline("nimbus_sans_l_regular");
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
+ ut_assert_nextline("ankacoder_c75_r");
if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_CANTORAONE))
ut_assert_nextline("cantoraone_regular");
ut_assert_console_end();
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
- ut_asserteq_str("nimbus_sans_l_regular", name);
- ut_asserteq(18, size);
+ if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER))
+ ut_asserteq_str("ankacoder_c75_r", name);
+ else
+ ut_asserteq_str("nimbus_sans_l_regular", name);
+ ut_asserteq(CONFIG_CONSOLE_TRUETYPE_SIZE, size);
if (!IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_CANTORAONE))
return 0;
@@ -58,10 +64,19 @@
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
ut_asserteq_str("cantoraone_regular", name);
ut_asserteq(40, size);
+ ut_assertok(ut_check_console_end(uts));
+
+ ut_assertok(run_command("font size", 0));
+ ut_assert_nextline("40");
+ ut_assertok(ut_check_console_end(uts));
ut_assertok(run_command("font size 30", 0));
ut_assert_console_end();
+ ut_assertok(run_command("font size", 0));
+ ut_assert_nextline("30");
+ ut_assertok(ut_check_console_end(uts));
+
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
ut_asserteq_str("cantoraone_regular", name);
ut_asserteq(30, size);
diff --git a/test/cmd/msr.c b/test/cmd/msr.c
new file mode 100644
index 0000000..e9a152e
--- /dev/null
+++ b/test/cmd/msr.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for msr command
+ *
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <test/cmd.h>
+#include <test/ut.h>
+
+static int cmd_test_msr(struct unit_test_state *uts)
+{
+ ut_assertok(run_commandf("msr read 200"));
+ ut_assert_nextline("00000000 ffe00006");
+ ut_assert_console_end();
+
+ /* change the first variable msr and see it reflected in the mtrr cmd */
+ ut_assertok(run_commandf("mtrr"));
+ ut_assert_nextline("CPU 65537:");
+ ut_assert_nextlinen("Reg");
+ ut_assert_nextlinen("0 Y Back 00000000ffe00000");
+ ut_assertok(console_record_reset_enable());
+
+ /* change the type from 6 to 5 */
+ ut_assertok(run_commandf("msr write 200 0 ffe00005"));
+ ut_assert_console_end();
+
+ /* Now it shows 'Protect' */
+ ut_assertok(run_commandf("mtrr"));
+ ut_assert_nextline("CPU 65537:");
+ ut_assert_nextlinen("Reg");
+ ut_assert_nextlinen("0 Y Protect 00000000ffe00000");
+ ut_assertok(console_record_reset_enable());
+
+ return 0;
+}
+CMD_TEST(cmd_test_msr, UTF_CONSOLE);
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index f9a3a42..381e556 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -2099,12 +2099,15 @@
-------------
Binman is a critical tool and is designed to be very testable. Entry
-implementations target 100% test coverage. Run 'binman test -T' to check this.
+implementations target 100% test coverage. Run ``binman test -T`` to check this.
To enable Python test coverage on Debian-type distributions (e.g. Ubuntu)::
$ sudo apt-get install python-coverage python3-coverage python-pytest
+You can also check the coverage provided by a single test, e.g.::
+
+ binman test -T testSimple
Exit status
-----------
@@ -2190,6 +2193,11 @@
Use '-P 1' to disable this. It is automatically disabled when code coverage is
being used (-T) since they are incompatible.
+
+Writing tests
+-------------
+
+See :doc:`../binman_tests`.
Debugging tests
---------------
diff --git a/tools/binman/btool/mkimage.py b/tools/binman/btool/mkimage.py
index 39a4c8c..78d3301 100644
--- a/tools/binman/btool/mkimage.py
+++ b/tools/binman/btool/mkimage.py
@@ -22,7 +22,7 @@
# pylint: disable=R0913
def run(self, reset_timestamp=False, output_fname=None, external=False,
- pad=None, align=None):
+ pad=None, align=None, priv_keys_dir=None):
"""Run mkimage
Args:
@@ -34,6 +34,7 @@
other things to be easily added later, if required, such as
signatures
align: Bytes to use for alignment of the FIT and its external data
+ priv_keys_dir: Path to directory containing private keys
version: True to get the mkimage version
"""
args = []
@@ -45,6 +46,8 @@
args += ['-B', f'{align:x}']
if reset_timestamp:
args.append('-t')
+ if priv_keys_dir:
+ args += ['-k', f'{priv_keys_dir}']
if output_fname:
args += ['-F', output_fname]
return self.run_cmd(*args)
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 3006c59..e918162 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -864,6 +864,13 @@
fit,fdt-list-dir = "arch/arm/dts
+ fit,sign
+ Enable signing FIT images via mkimage as described in
+ verified-boot.rst. If the property is found, the private keys path is
+ detected among binman include directories and passed to mkimage via
+ -k flag. All the keys required for signing FIT must be available at
+ time of signing and must be located in single include directory.
+
Substitutions
~~~~~~~~~~~~~
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index 0abe1c7..b5afbda 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -9,6 +9,7 @@
import os
import libfdt
+import os
from binman.entry import Entry, EntryArg
from binman.etype.section import Entry_section
@@ -101,6 +102,14 @@
In this case the input directories are ignored and all devicetree
files must be in that directory.
+ fit,sign
+ Enable signing FIT images via mkimage as described in
+ verified-boot.rst. If the property is found, the private keys path
+ is detected among binman include directories and passed to mkimage
+ via -k flag. All the keys required for signing FIT must be
+ available at time of signing and must be located in single include
+ directory.
+
Substitutions
~~~~~~~~~~~~~
@@ -426,6 +435,7 @@
self._remove_props = props.split()
self.mkimage = None
self.fdtgrep = None
+ self._fit_sign = None
def ReadNode(self):
super().ReadNode()
@@ -508,6 +518,45 @@
# are removed from self._entries later.
self._priv_entries = dict(self._entries)
+ def _get_priv_keys_dir(self, data):
+ """Detect private keys path among binman include directories
+
+ Args:
+ data: FIT image in binary format
+
+ Returns:
+ str: Single path containing all private keys found or None
+
+ Raises:
+ ValueError: Filename 'rsa2048.key' not found in input path
+ ValueError: Multiple key paths found
+ """
+ def _find_keys_dir(node):
+ for subnode in node.subnodes:
+ if subnode.name.startswith('signature'):
+ if subnode.props.get('key-name-hint') is None:
+ continue
+ hint = subnode.props['key-name-hint'].value
+ name = tools.get_input_filename(f"{hint}.key")
+ path = os.path.dirname(name)
+ if path not in paths:
+ paths.append(path)
+ else:
+ _find_keys_dir(subnode)
+ return None
+
+ fdt = Fdt.FromData(data)
+ fdt.Scan()
+
+ paths = []
+
+ _find_keys_dir(fdt.GetRoot())
+
+ if len(paths) > 1:
+ self.Raise("multiple key paths found (%s)" % ",".join(paths))
+
+ return paths[0] if len(paths) else None
+
def BuildSectionData(self, required):
"""Build FIT entry contents
@@ -538,6 +587,8 @@
align = self._fit_props.get('fit,align')
if align is not None:
args.update({'align': fdt_util.fdt32_to_cpu(align.value)})
+ if self._fit_props.get('fit,sign') is not None:
+ args.update({'priv_keys_dir': self._get_priv_keys_dir(data)})
if self.mkimage.run(reset_timestamp=True, output_fname=output_fname,
**args) is None:
if not self.GetAllowMissing():
@@ -637,8 +688,8 @@
"""
val = fdt_util.GetStringList(node, 'fit,firmware')
if val is None:
- return None, self._loadables
- valid_entries = list(self._loadables)
+ return None, loadables
+ valid_entries = list(loadables)
for name, entry in self.GetEntries().items():
missing = []
entry.CheckMissing(missing)
@@ -653,7 +704,7 @@
firmware = name
elif name not in result:
result.append(name)
- for name in self._loadables:
+ for name in loadables:
if name != firmware and name not in result:
result.append(name)
return firmware, result
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index e3f231e..156567a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7804,6 +7804,101 @@
"""Test that binman can produce an iMX8 image"""
self._DoTestFile('339_nxp_imx8.dts')
+ def testFitSignSimple(self):
+ """Test that image with FIT and signature nodes can be signed"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys/rsa2048.key", data)
+
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ keys_subdir = os.path.join(self._indir, "keys")
+ data = self._DoReadFileDtb(
+ '340_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir, keys_subdir])[0]
+
+ dtb = fdt.Fdt.FromData(data)
+ dtb.Scan()
+
+ conf = dtb.GetNode('/configurations/conf-uboot-1')
+ self.assertIsNotNone(conf)
+ signature = conf.FindNode('signature')
+ self.assertIsNotNone(signature)
+ self.assertIsNotNone(signature.props.get('value'))
+
+ images = dtb.GetNode('/images')
+ self.assertIsNotNone(images)
+ for subnode in images.subnodes:
+ signature = subnode.FindNode('signature')
+ self.assertIsNotNone(signature)
+ self.assertIsNotNone(signature.props.get('value'))
+
+ def testFitSignKeyNotFound(self):
+ """Test that missing keys raise an error"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb(
+ '340_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])[0]
+ self.assertIn(
+ 'Filename \'rsa2048.key\' not found in input path',
+ str(e.exception))
+
+ def testFitSignMultipleKeyPaths(self):
+ """Test that keys found in multiple paths raise an error"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys1/rsa2048.key", data)
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys2/conf-rsa2048.key", data)
+
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ keys_subdir1 = os.path.join(self._indir, "keys1")
+ keys_subdir2 = os.path.join(self._indir, "keys2")
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb(
+ '341_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir, keys_subdir1, keys_subdir2])[0]
+ self.assertIn(
+ 'Node \'/binman/fit\': multiple key paths found',
+ str(e.exception))
+
+ def testFitSignNoSingatureNodes(self):
+ """Test that fit,sign doens't raise error if no signature nodes found"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ self._DoReadFileDtb(
+ '342_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])[0]
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/main.py b/tools/binman/main.py
index dc817dd..619840e 100755
--- a/tools/binman/main.py
+++ b/tools/binman/main.py
@@ -85,7 +85,7 @@
return (0 if result.wasSuccessful() else 1)
-def RunTestCoverage(toolpath, build_dir):
+def RunTestCoverage(toolpath, build_dir, args):
"""Run the tests and check that we get 100% coverage"""
glob_list = control.GetEntryModules(False)
all_set = set([os.path.splitext(os.path.basename(item))[0]
@@ -97,7 +97,7 @@
test_util.run_test_coverage('tools/binman/binman', None,
['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*',
'tools/u_boot_pylib/*'],
- build_dir, all_set, extra_args or None)
+ build_dir, all_set, extra_args or None, args=args)
def RunBinman(args):
"""Main entry point to binman once arguments are parsed
@@ -117,7 +117,7 @@
if args.cmd == 'test':
if args.test_coverage:
- RunTestCoverage(args.toolpath, args.build_dir)
+ RunTestCoverage(args.toolpath, args.build_dir, args.tests)
else:
ret_code = RunTests(args.debug, args.verbosity, args.processes,
args.test_preserve_dirs, args.tests,
diff --git a/tools/binman/test/340_fit_signature.dts b/tools/binman/test/340_fit_signature.dts
new file mode 100644
index 0000000..9dce62e
--- /dev/null
+++ b/tools/binman/test/340_fit_signature.dts
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ sign-images = "firmware", "loadables", "fdt";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/340_rsa2048.key b/tools/binman/test/340_rsa2048.key
new file mode 100644
index 0000000..e74b20c
--- /dev/null
+++ b/tools/binman/test/340_rsa2048.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDVUiT2JAF8Ajcx
+3XTB5qdGxuPMVFcXKJH+4L66oSt4YUBGi1bClo80U2azu08BTzk2Jzv6hez/mvzL
+hBvL3WnPwMl5vdOxb1kvUQyKLSw2bkM8VB0X1jGsKsKjzArg/aI8RknfiaSc5jua
+2lqwUFwv2RMF8jvIMN/1GnTLdECeMFVgVFSFkzIocISAHGPoGUOxTf8xK7o0x4RX
+NzB+95RtIqTQ5Az/KPVCOcQR5ETrUBXHF1I0rYjJjHHO4dUxxfDqFabt60EzQ/R2
+oZu58C4y0TrRI98g4hVPBYapildWjaNQm1Exa4ZaSDVl01OXsFW9Dm80PqfW4tTH
+Cm4nuCq5AgMBAAECggEBAIoG5b2SHJfFwzrzpQmVmeTU6i6a3+MvMBAwEZkmkb8J
+hhJfNFsiGjTsRgbDiuI5BbbBejCmmWvmN+3jZCzr7fwsLPEl36TufFF+atO5WOM7
+Qyv07QIwaOGSpXBgpSVhV6kSfdgy8p1G54hSAt4UkSGwnnt5ei8VWMP6Q1oltW3k
+f9DQ/ar4UEVa4jlJU3xqchcUTiKBKSH6pMC/Fqlq8x5JTLmk1Yb6C2UNcgJYez1u
+sHkdCA0FG3rFPrpFoQ1LUjMj1uEYNAxM3jOxE7Uvmk4yo9WpQDY7cRb2+Th9YY8a
+IKQ2s81Yg2TmkGzr8f5nrZz3WbAmQhQgsKbwlo6snjUCgYEA7kBOt0JlU7bJTfOr
+9s51g2VUfIH9lDS2Eh8MY+Bt6Y0Kdw/UK4HR8ZlN/nn0bHuHkc12K8lXEsQpgIEW
+DaqHytZJHqFs2egzKu/IvQYZ2WXEMj47LZQxEDHO9gtjE+5qCW9yJGqxW9BJKPVD
+F4spus4NqC+yD5OHM+6ESUtL/wMCgYEA5TZj6OHmECeh3efrwHqjDcjrqQbOTozU
+KPCNCY3Pv4Cg4xas/L93TE2CY6HJTr6mwEMUM+M4Ujjj15VCmSDQ/YYcGau1jo+f
+XdphOEENrPwoe9ATWIyBpT/wDrEz3L6JbE9dWMYY8vKYESt3qhVqDlbpmnYl8Jm+
+O3r5Cy2NlJMCgYEAyqzsCZuy5QcesnByvm8dqpxdxdkzJYu9wyakfKZj+gUgfO57
+OFOkjFk07yFB27MuPctCFredmfpDr+ygHRoPkG7AHw2Fss2EEaeP5bU18ilPQMqN
+vxVMs5EblVVUgJUVoVcsC2yz2f4S7oPOAk5BPoehOIzydauznWrvIAas7I8CgYBr
+CFHxLoNq6cbZQ3JACERZrIf2/vmZjoOHtoR1gKYRK7R1NmKDB7lihRMtCSBix/4/
+61Lkw+bJ5kzmn4lgzgUpTdWTWy5FquVlQxOA3EfRjlItNsXB5KKpksi7Y53vJ34u
+eIUDbkW6NPQzmFOhtaw3k/gzq5Yd2v0M82iWAqiJRwKBgQCl2+e2cjISK31QhKTC
+puhwQ0/YuC3zlwMXQgB3nPw8b9RlaDTMrRBCIUFIrrX11tHswGWpyVsxW2AvZ3Zm
+jsWpwGkUdpRdXJBhSaisV/PA+x3kYhpibzEI8FrzhU69zNROCb8CTkN4WcdBdq6J
+PUh/jRtKoE79qrlnIlNvFoz2gQ==
+-----END PRIVATE KEY-----
diff --git a/tools/binman/test/341_fit_signature.dts b/tools/binman/test/341_fit_signature.dts
new file mode 100644
index 0000000..77bec8d
--- /dev/null
+++ b/tools/binman/test/341_fit_signature.dts
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "conf-rsa2048";
+ sign-images = "firmware", "loadables", "fdt";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/342_fit_signature.dts b/tools/binman/test/342_fit_signature.dts
new file mode 100644
index 0000000..267105d
--- /dev/null
+++ b/tools/binman/test/342_fit_signature.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+ };
+ };
+ };
+ };
+};
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 4090d32..cbf1345 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -34,7 +34,7 @@
# Error in reading or end of file.
# <<
# which indicates that BREAK_ME has an empty default
-RE_NO_DEFAULT = re.compile(b'\((\w+)\) \[] \(NEW\)')
+RE_NO_DEFAULT = re.compile(br'\((\w+)\) \[] \(NEW\)')
# Symbol types which appear in the bloat feature (-B). Others are silently
# dropped when reading in the 'nm' output
@@ -374,9 +374,9 @@
self._re_function = re.compile('(.*): In function.*')
self._re_files = re.compile('In file included from.*')
- self._re_warning = re.compile('(.*):(\d*):(\d*): warning: .*')
+ self._re_warning = re.compile(r'(.*):(\d*):(\d*): warning: .*')
self._re_dtb_warning = re.compile('(.*): Warning .*')
- self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*')
+ self._re_note = re.compile(r'(.*):(\d*):(\d*): note: this is the location of the previous.*')
self._re_migration_warning = re.compile(r'^={21} WARNING ={22}\n.*\n=+\n',
re.MULTILINE | re.DOTALL)
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index a7d7883..0c8a4fa 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -440,12 +440,12 @@
This converts ${blah} within the string to the value of blah.
This function works recursively.
+ Resolved string
+
Args:
var_dict: Dictionary containing variables and their values
args: String containing make arguments
Returns:
- Resolved string
-
>>> bsettings.setup(None)
>>> tcs = Toolchains()
>>> tcs.Add('fred', False)
@@ -456,7 +456,7 @@
>>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd')
'this=OBLIQUE_setfi2ndrstnd'
"""
- re_var = re.compile('(\$\{[-_a-z0-9A-Z]{1,}\})')
+ re_var = re.compile(r'(\$\{[-_a-z0-9A-Z]{1,}\})')
while True:
m = re_var.search(args)
@@ -495,7 +495,7 @@
self._make_flags['target'] = brd.target
arg_str = self.ResolveReferences(self._make_flags,
self._make_flags.get(brd.target, ''))
- args = re.findall("(?:\".*?\"|\S)+", arg_str)
+ args = re.findall(r"(?:\".*?\"|\S)+", arg_str)
i = 0
while i < len(args):
args[i] = args[i].replace('"', '')
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index c401170..967ac89 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -244,12 +244,15 @@
rm -rf /tmp/trace
# Build coreboot
-RUN wget -O - https://coreboot.org/releases/coreboot-4.22.01.tar.xz | tar -C /tmp -xJ && \
- cd /tmp/coreboot-4.22.01 && \
+RUN wget -O - https://coreboot.org/releases/coreboot-24.08.tar.xz | tar -C /tmp -xJ && \
+ cd /tmp/coreboot-24.08 && \
make crossgcc-i386 CPUS=$(nproc) && \
make -C payloads/coreinfo olddefconfig && \
make -C payloads/coreinfo && \
make olddefconfig && \
+ echo CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y | tee -a .config && \
+ echo CONFIG_USE_OPTION_TABLE=y | tee -a .config && \
+ make olddefconfig && \
make -j $(nproc) && \
sudo mkdir /opt/coreboot && \
sudo cp build/coreboot.rom build/cbfstool /opt/coreboot/
diff --git a/tools/expo.py b/tools/expo.py
index ea80c70..44995f2 100755
--- a/tools/expo.py
+++ b/tools/expo.py
@@ -20,17 +20,22 @@
# Parse:
# SCENE1 = 7,
+# or SCENE1 = EXPOID_BASE_ID,
# or SCENE2,
-RE_ENUM = re.compile(r'(\S*)(\s*= (\d))?,')
+RE_ENUM = re.compile(r'(\S*)(\s*= ([0-9A-Z_]+))?,')
# Parse #define <name> "string"
RE_DEF = re.compile(r'#define (\S*)\s*"(.*)"')
-def calc_ids(fname):
+# Parse EXPOID_BASE_ID = 5,
+RE_BASE_ID = re.compile(r'\s*EXPOID_BASE_ID\s*= (\d+),')
+
+def calc_ids(fname, base_id):
"""Figure out the value of the enums in a C file
Args:
fname (str): Filename to parse
+ base_id (int): Base ID (value of EXPOID_BASE_ID)
Returns:
OrderedDict():
@@ -55,8 +60,12 @@
if not line or line.startswith('/*'):
continue
m_enum = RE_ENUM.match(line)
- if m_enum.group(3):
- cur_id = int(m_enum.group(3))
+ enum_name = m_enum.group(3)
+ if enum_name:
+ if enum_name == 'EXPOID_BASE_ID':
+ cur_id = base_id
+ else:
+ cur_id = int(enum_name)
vals[m_enum.group(1)] = cur_id
cur_id += 1
else:
@@ -66,11 +75,25 @@
return vals
+
+def find_base_id():
+ fname = 'include/expo.h'
+ base_id = None
+ with open(fname, 'r', encoding='utf-8') as inf:
+ for line in inf.readlines():
+ m_base_id = RE_BASE_ID.match(line)
+ if m_base_id:
+ base_id = int(m_base_id.group(1))
+ if base_id is None:
+ raise ValueError('EXPOID_BASE_ID not found in expo.h')
+ #print(f'EXPOID_BASE_ID={base_id}')
+ return base_id
def run_expo(args):
"""Run the expo program"""
+ base_id = find_base_id()
fname = args.enum_fname or args.layout
- ids = calc_ids(fname)
+ ids = calc_ids(fname, base_id)
if not ids:
print(f"Warning: No enum ID values found in file '{fname}'")
diff --git a/tools/image-host.c b/tools/image-host.c
index 49ce743..5e01b85 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -1333,7 +1333,7 @@
if (ret) {
fprintf(stderr, "Can't add verification data for node '%s' (%s)\n",
fdt_get_name(fit, noffset, NULL),
- fdt_strerror(ret));
+ strerror(-ret));
return ret;
}
}
diff --git a/tools/u_boot_pylib/test_util.py b/tools/u_boot_pylib/test_util.py
index 857ce58..dd67196 100644
--- a/tools/u_boot_pylib/test_util.py
+++ b/tools/u_boot_pylib/test_util.py
@@ -23,8 +23,9 @@
use_concurrent = False
-def run_test_coverage(prog, filter_fname, exclude_list, build_dir, required=None,
- extra_args=None, single_thread='-P1'):
+def run_test_coverage(prog, filter_fname, exclude_list, build_dir,
+ required=None, extra_args=None, single_thread='-P1',
+ args=None):
"""Run tests and check that we get 100% coverage
Args:
@@ -42,6 +43,7 @@
single_thread (str): Argument string to make the tests run
single-threaded. This is necessary to get proper coverage results.
The default is '-P0'
+ args (list of str): List of tests to run, or None to run all
Raises:
ValueError if the code coverage is not 100%
@@ -66,9 +68,10 @@
'coverage')
cmd = ('%s%s run '
- '--omit "%s" %s %s %s %s' % (prefix, covtool, ','.join(glob_list),
- prog, extra_args or '', test_cmd,
- single_thread or '-P1'))
+ '--omit "%s" %s %s %s %s %s' % (prefix, covtool, ','.join(glob_list),
+ prog, extra_args or '', test_cmd,
+ single_thread or '-P1',
+ ' '.join(args) if args else ''))
os.system(cmd)
stdout = command.output(covtool, 'report')
lines = stdout.splitlines()