Merge https://gitlab.denx.de/u-boot/custodians/u-boot-usb
authorTom Rini <trini@konsulko.com>
Sun, 31 Jan 2021 19:24:35 +0000 (14:24 -0500)
committerTom Rini <trini@konsulko.com>
Sun, 31 Jan 2021 19:24:35 +0000 (14:24 -0500)
- Assorted gadget changes including:
  - dfu: Fix handling of UBI partitions in MTD backend
  - gadget: f_thor: fix wrong file size cast
  - Extend cmd: bcb
  - Fixes for fastboot and rockchip gadgets
  - dfu: Add SCRIPT and SKIP entities
  - dfu/thor: Add `dfu_alt_info` reinitialization from flashed script
  - u-boot: Reduce size of u-boot as usbd_device_* arrays are not exported

80 files changed:
Kconfig
arch/arm/dts/hihope-common.dtsi [new file with mode: 0644]
arch/arm/dts/hihope-rev4.dtsi [new file with mode: 0644]
arch/arm/dts/hihope-rzg2-ex.dtsi [new file with mode: 0644]
arch/arm/dts/r8a774a1-hihope-rzg2m-ex.dts [new file with mode: 0644]
arch/arm/dts/r8a774a1-hihope-rzg2m-u-boot.dts [new file with mode: 0644]
arch/arm/dts/r8a774a1-hihope-rzg2m.dts [new file with mode: 0644]
arch/arm/dts/r8a774a1-u-boot.dtsi [new file with mode: 0644]
arch/arm/lib/crt0_aarch64_efi.S
arch/sandbox/cpu/os.c
arch/sandbox/cpu/start.c
arch/sandbox/dts/sandbox.dtsi
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/test.h
arch/x86/cpu/i386/cpu.c
arch/x86/cpu/start.S
arch/x86/dts/chromebook_coral.dts
arch/x86/include/asm/arch-apollolake/iomap.h
cmd/bootefi.c
cmd/cros_ec.c
configs/chromebook_coral_defconfig
configs/sandbox_spl_defconfig
disk/part.c
disk/part_efi.c
doc/arch/sandbox.rst
drivers/block/sandbox.c
drivers/clk/clk-uclass.c
drivers/clk/intel/clk_intel.c
drivers/core/device.c
drivers/core/of_extra.c
drivers/i2c/Makefile
drivers/i2c/designware_i2c_pci.c
drivers/misc/cros_ec.c
drivers/misc/cros_ec_lpc.c
drivers/misc/cros_ec_sandbox.c
drivers/mmc/renesas-sdhi.c
drivers/mmc/tmio-common.c
drivers/mmc/tmio-common.h
drivers/rtc/i2c_rtc_emul.c
drivers/tpm/cr50_i2c.c
include/asm-generic/pe.h
include/cros_ec.h
include/ctype.h [new symlink]
include/dm/device.h
include/dm/read.h
include/ec_commands.h
include/os.h
lib/binman.c
lib/efi_loader/efi_disk.c
lib/efi_loader/efi_setup.c
lib/efi_selftest/efi_selftest_block_device.c
test/dm/Makefile
test/dm/cros_ec.c [new file with mode: 0644]
test/dm/of_extra.c [new file with mode: 0644]
test/dm/of_platdata.c
tools/.gitignore
tools/binman/README
tools/binman/control.py
tools/binman/elf.py
tools/binman/elf_test.py
tools/binman/entry.py
tools/binman/etype/blob.py
tools/binman/etype/files.py
tools/binman/etype/section.py
tools/binman/etype/u_boot_spl_bss_pad.py
tools/binman/etype/u_boot_spl_nodtb.py
tools/binman/etype/vblock.py
tools/binman/fmap_util.py
tools/binman/ftest.py
tools/binman/image.py
tools/binman/state.py
tools/binman/test/084_files.dts
tools/binman/test/187_symbols_sub.dts [new file with mode: 0644]
tools/binman/test/188_image_entryarg.dts [new file with mode: 0644]
tools/binman/test/189_vblock_content.dts [new file with mode: 0644]
tools/binman/test/190_files_align.dts [new file with mode: 0644]
tools/binman/test/191_read_image_skip.dts [new file with mode: 0644]
tools/dtoc/fdt.py
tools/dtoc/test_fdt.py
tools/patman/tools.py

diff --git a/Kconfig b/Kconfig
index 6dc20ed..86f0a39 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -217,22 +217,25 @@ config SYS_MALLOC_LEN
          TODO: Use for other architectures
 
 config SPL_SYS_MALLOC_F_LEN
-       hex "Size of malloc() pool in SPL before relocation"
+       hex "Size of malloc() pool in SPL"
        depends on SYS_MALLOC_F && SPL
        default 0x2800 if RCAR_GEN3
        default SYS_MALLOC_F_LEN
        help
-         Before relocation, memory is very limited on many platforms. Still,
+         In SPL memory is very limited on many platforms. Still,
          we can provide a small malloc() pool if needed. Driver model in
          particular needs this to operate, so that it can allocate the
          initial serial device and any others that are needed.
 
+         It is possible to enable CONFIG_SYS_SPL_MALLOC_START to start a new
+         malloc() region in SDRAM once it is inited.
+
 config TPL_SYS_MALLOC_F_LEN
-       hex "Size of malloc() pool in TPL before relocation"
+       hex "Size of malloc() pool in TPL"
        depends on SYS_MALLOC_F && TPL
-       default SYS_MALLOC_F_LEN
+       default SPL_SYS_MALLOC_F_LEN
        help
-         Before relocation, memory is very limited on many platforms. Still,
+         In TPL memory is very limited on many platforms. Still,
          we can provide a small malloc() pool if needed. Driver model in
          particular needs this to operate, so that it can allocate the
          initial serial device and any others that are needed.
diff --git a/arch/arm/dts/hihope-common.dtsi b/arch/arm/dts/hihope-common.dtsi
new file mode 100644 (file)
index 0000000..b1eb6a0
--- /dev/null
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2H Rev.4.0 and
+ * HiHope RZ/G2[MN] Rev.[2.0/3.0/4.0] main board common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       aliases {
+               serial0 = &scif2;
+               serial1 = &hscif0;
+       };
+
+       chosen {
+               bootargs = "ignore_loglevel";
+               stdout-path = "serial0:115200n8";
+       };
+
+       hdmi0-out {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi0_con: endpoint {
+                               remote-endpoint = <&rcar_dw_hdmi0_out>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led1 {
+                       gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+               };
+
+               led2 {
+                       gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
+               };
+
+               led3 {
+                       gpios = <&gpio0  0 GPIO_ACTIVE_HIGH>;
+               };
+
+               led4 {
+                       gpios = <&gpio6 11 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       reg_1p8v: regulator0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       reg_3p3v: regulator1 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       sound_card: sound {
+               compatible = "audio-graph-card";
+
+               label = "rcar-sound";
+
+               dais = <&rsnd_port>;
+       };
+
+       vbus0_usb2: regulator-vbus0-usb2 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "USB20_VBUS0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator-vccq-sdhi0 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio6 30 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1>, <1800000 0>;
+       };
+
+       x302_clk: x302-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <33000000>;
+       };
+
+       x304_clk: x304-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <25000000>;
+       };
+};
+
+&audio_clk_a {
+       clock-frequency = <22579200>;
+};
+
+&du {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&extal_clk {
+       clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+       clock-frequency = <32768>;
+};
+
+&gpio6 {
+       usb1-reset {
+               gpio-hog;
+               gpios = <10 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "usb1-reset";
+       };
+};
+
+&hdmi0 {
+       status = "okay";
+
+       ports {
+               port@1 {
+                       reg = <1>;
+                       rcar_dw_hdmi0_out: endpoint {
+                               remote-endpoint = <&hdmi0_con>;
+                       };
+               };
+               port@2 {
+                       reg = <2>;
+                       dw_hdmi0_snd_in: endpoint {
+                               remote-endpoint = <&rsnd_endpoint>;
+                       };
+               };
+       };
+};
+
+&hscif0 {
+       pinctrl-0 = <&hscif0_pins>;
+       pinctrl-names = "default";
+
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&hsusb {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&i2c4 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       versaclock5: clock-generator@6a {
+               compatible = "idt,5p49v5923";
+               reg = <0x6a>;
+               #clock-cells = <1>;
+               clocks = <&x304_clk>;
+               clock-names = "xin";
+       };
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&pcie_bus_clk {
+       clock-frequency = <100000000>;
+};
+
+&pfc {
+       pinctrl-0 = <&scif_clk_pins>;
+       pinctrl-names = "default";
+
+       hscif0_pins: hscif0 {
+               groups = "hscif0_data", "hscif0_ctrl";
+               function = "hscif0";
+       };
+
+       scif2_pins: scif2 {
+               groups = "scif2_data_a";
+               function = "scif2";
+       };
+
+       scif_clk_pins: scif_clk {
+               groups = "scif_clk_a";
+               function = "scif_clk";
+       };
+
+       sdhi0_pins: sd0 {
+               groups = "sdhi0_data4", "sdhi0_ctrl";
+               function = "sdhi0";
+               power-source = <3300>;
+       };
+
+       sdhi0_pins_uhs: sd0_uhs {
+               groups = "sdhi0_data4", "sdhi0_ctrl";
+               function = "sdhi0";
+               power-source = <1800>;
+       };
+
+       sdhi2_pins: sd2 {
+               groups = "sdhi2_data4", "sdhi2_ctrl";
+               function = "sdhi2";
+               power-source = <1800>;
+       };
+
+       sdhi3_pins: sd3 {
+               groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
+               function = "sdhi3";
+               power-source = <1800>;
+       };
+
+       usb0_pins: usb0 {
+               groups = "usb0";
+               function = "usb0";
+       };
+
+       usb1_pins: usb1 {
+               mux {
+                       groups = "usb1";
+                       function = "usb1";
+               };
+
+               ovc {
+                       pins = "GP_6_27";
+                       bias-pull-up;
+               };
+       };
+
+       usb30_pins: usb30 {
+               groups = "usb30";
+               function = "usb30";
+       };
+};
+
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
+};
+
+&scif2 {
+       pinctrl-0 = <&scif2_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&scif_clk {
+       clock-frequency = <14745600>;
+};
+
+&sdhi0 {
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-1 = <&sdhi0_pins_uhs>;
+       pinctrl-names = "default", "state_uhs";
+
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&sdhi2 {
+       status = "okay";
+       pinctrl-0 = <&sdhi2_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&wlan_en_reg>;
+       bus-width = <4>;
+       non-removable;
+       cap-power-off-card;
+       keep-power-in-suspend;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1837";
+               reg = <2>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+       };
+};
+
+&sdhi3 {
+       pinctrl-0 = <&sdhi3_pins>;
+       pinctrl-1 = <&sdhi3_pins>;
+       pinctrl-names = "default", "state_uhs";
+
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       bus-width = <8>;
+       mmc-hs200-1_8v;
+       non-removable;
+       fixed-emmc-driver-type = <1>;
+       status = "okay";
+};
+
+&usb_extal_clk {
+       clock-frequency = <50000000>;
+};
+
+&usb2_phy0 {
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+
+       vbus-supply = <&vbus0_usb2>;
+       status = "okay";
+};
+
+&usb2_phy1 {
+       pinctrl-0 = <&usb1_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&usb3_peri0 {
+       phys = <&usb3_phy0>;
+       phy-names = "usb";
+
+       companion = <&xhci0>;
+
+       status = "okay";
+};
+
+&usb3_phy0 {
+       status = "okay";
+};
+
+&usb3s0_clk {
+       clock-frequency = <100000000>;
+};
+
+&xhci0 {
+       pinctrl-0 = <&usb30_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
diff --git a/arch/arm/dts/hihope-rev4.dtsi b/arch/arm/dts/hihope-rev4.dtsi
new file mode 100644 (file)
index 0000000..30e9299
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2H Rev.4.0 and
+ * HiHope RZ/G2[MN] Rev.3.0/4.0 main board common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include "hihope-common.dtsi"
+
+/ {
+       audio_clkout: audio-clkout {
+               /*
+                * This is same as <&rcar_sound 0>
+                * but needed to avoid cs2000/rcar_sound probe dead-lock
+                */
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <12288000>;
+       };
+
+       wlan_en_reg: regulator-wlan_en {
+               compatible = "regulator-fixed";
+               regulator-name = "wlan-en-regulator";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               startup-delay-us = <70000>;
+
+               gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       x1801_clk: x1801-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24576000>;
+       };
+};
+
+&hscif0 {
+       bluetooth {
+               compatible = "ti,wl1837-st";
+               enable-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&i2c2 {
+       pinctrl-0 = <&i2c2_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       cs2000: clk_multiplier@4f {
+               #clock-cells = <0>;
+               compatible = "cirrus,cs2000-cp";
+               reg = <0x4f>;
+               clocks = <&audio_clkout>, <&x1801_clk>;
+               clock-names = "clk_in", "ref_clk";
+
+               assigned-clocks = <&cs2000>;
+               assigned-clock-rates = <24576000>; /* 1/1 divide */
+       };
+};
+
+&pfc {
+       i2c2_pins: i2c2 {
+               groups = "i2c2_a";
+               function = "i2c2";
+       };
+
+       sound_clk_pins: sound_clk {
+               groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clkout_a";
+               function = "audio_clk";
+       };
+
+       sound_pins: sound {
+               groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
+               function = "ssi";
+       };
+};
+
+&rcar_sound {
+       pinctrl-0 = <&sound_pins &sound_clk_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       /* Single DAI */
+       #sound-dai-cells = <0>;
+
+       /* audio_clkout0/1/2/3 */
+       #clock-cells = <1>;
+       clock-frequency = <12288000 11289600>;
+
+       /* update <audio_clk_b> to <cs2000> */
+       clocks = <&cpg CPG_MOD 1005>,
+                <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
+                <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
+                <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
+                <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
+                <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
+                <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
+                <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
+                <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
+                <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
+                <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
+                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
+                <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
+                <&audio_clk_a>, <&cs2000>,
+                <&audio_clk_c>,
+                <&cpg CPG_CORE CPG_AUDIO_CLK_I>;
+
+       rsnd_port: port {
+               rsnd_endpoint: endpoint {
+                       remote-endpoint = <&dw_hdmi0_snd_in>;
+
+                       dai-format = "i2s";
+                       bitclock-master = <&rsnd_endpoint>;
+                       frame-master = <&rsnd_endpoint>;
+
+                       playback = <&ssi2>;
+               };
+       };
+};
diff --git a/arch/arm/dts/hihope-rzg2-ex.dtsi b/arch/arm/dts/hihope-rzg2-ex.dtsi
new file mode 100644 (file)
index 0000000..7745012
--- /dev/null
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the RZ/G2[HMN] HiHope sub board common parts
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/ {
+       aliases {
+               ethernet0 = &avb;
+       };
+
+       chosen {
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+       };
+};
+
+&avb {
+       pinctrl-0 = <&avb_pins>;
+       pinctrl-names = "default";
+       phy-handle = <&phy0>;
+       phy-mode = "rgmii-txid";
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               reg = <0>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+               reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&can0 {
+       pinctrl-0 = <&can0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-0 = <&can1_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&pciec0 {
+       status = "okay";
+};
+
+&pfc {
+       pinctrl-0 = <&scif_clk_pins>;
+       pinctrl-names = "default";
+
+       avb_pins: avb {
+               mux {
+                       groups = "avb_link", "avb_mdio", "avb_mii";
+                       function = "avb";
+               };
+
+               pins_mdio {
+                       groups = "avb_mdio";
+                       drive-strength = <24>;
+               };
+
+               pins_mii_tx {
+                       pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0",
+                              "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3";
+                       drive-strength = <12>;
+               };
+       };
+
+       can0_pins: can0 {
+               groups = "can0_data_a";
+               function = "can0";
+       };
+
+       can1_pins: can1 {
+               groups = "can1_data";
+               function = "can1";
+       };
+
+       pwm0_pins: pwm0 {
+               groups = "pwm0";
+               function = "pwm0";
+       };
+};
+
+&pwm0 {
+       pinctrl-0 = <&pwm0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
diff --git a/arch/arm/dts/r8a774a1-hihope-rzg2m-ex.dts b/arch/arm/dts/r8a774a1-hihope-rzg2m-ex.dts
new file mode 100644 (file)
index 0000000..f0e4a1f
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2M Rev.3.0/4.0 connected to
+ * sub board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+#include "r8a774a1-hihope-rzg2m.dts"
+#include "hihope-rzg2-ex.dtsi"
+
+/ {
+       model = "HopeRun HiHope RZ/G2M with sub board";
+       compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2m",
+                    "renesas,r8a774a1";
+};
+
+/* SW43 should be OFF, if in ON state SATA port will be activated */
+&pciec1 {
+       status = "okay";
+};
diff --git a/arch/arm/dts/r8a774a1-hihope-rzg2m-u-boot.dts b/arch/arm/dts/r8a774a1-hihope-rzg2m-u-boot.dts
new file mode 100644 (file)
index 0000000..b735e97
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot for the Hihope RZ/G2M board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corporation
+ */
+
+#include "r8a774a1-hihope-rzg2m-ex.dts"
+#include "r8a774a1-u-boot.dtsi"
+
+&gpio3 {
+       bt_reg_on{
+               gpio-hog;
+               gpios = <13 GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "bt-reg-on";
+       };
+};
+
+&gpio4 {
+       wlan_reg_on{
+               gpio-hog;
+               gpios = <6 GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "wlan-reg-on";
+       };
+};
diff --git a/arch/arm/dts/r8a774a1-hihope-rzg2m.dts b/arch/arm/dts/r8a774a1-hihope-rzg2m.dts
new file mode 100644 (file)
index 0000000..a574c85
--- /dev/null
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the HiHope RZ/G2M Rev.3.0/4.0 main board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a774a1.dtsi"
+#include "hihope-rev4.dtsi"
+
+/ {
+       model = "HopeRun HiHope RZ/G2M main board based on r8a774a1";
+       compatible = "hoperun,hihope-rzg2m", "renesas,r8a774a1";
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x78000000>;
+       };
+
+       memory@600000000 {
+               device_type = "memory";
+               reg = <0x6 0x00000000 0x0 0x80000000>;
+       };
+};
+
+&du {
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&cpg CPG_MOD 722>,
+                <&versaclock5 1>,
+                <&x302_clk>,
+                <&versaclock5 2>;
+       clock-names = "du.0", "du.1", "du.2",
+                     "dclkin.0", "dclkin.1", "dclkin.2";
+};
diff --git a/arch/arm/dts/r8a774a1-u-boot.dtsi b/arch/arm/dts/r8a774a1-u-boot.dtsi
new file mode 100644 (file)
index 0000000..f826c41
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source extras for U-Boot on RZ/G2 R8A774A1 SoC
+ *
+ * Copyright (C) 2021 Renesas Electronics Corporation
+ */
+
+#include "r8a779x-u-boot.dtsi"
+
+&extalr_clk {
+       u-boot,dm-pre-reloc;
+};
+
+/delete-node/ &audma0;
+/delete-node/ &audma1;
+/delete-node/ &can0;
+/delete-node/ &can1;
+/delete-node/ &canfd;
+/delete-node/ &csi20;
+/delete-node/ &csi40;
+/delete-node/ &du;
+/delete-node/ &fcpf0;
+/delete-node/ &fcpvb0;
+/delete-node/ &fcpvd0;
+/delete-node/ &fcpvd1;
+/delete-node/ &fcpvd2;
+/delete-node/ &fcpvi0;
+/delete-node/ &hdmi0;
+/delete-node/ &lvds0;
+/delete-node/ &rcar_sound;
+/delete-node/ &sdhi2;
+/delete-node/ &sound_card;
+/delete-node/ &vin0;
+/delete-node/ &vin1;
+/delete-node/ &vin2;
+/delete-node/ &vin3;
+/delete-node/ &vin4;
+/delete-node/ &vin5;
+/delete-node/ &vin6;
+/delete-node/ &vin7;
+/delete-node/ &vspb;
+/delete-node/ &vspd0;
+/delete-node/ &vspd1;
+/delete-node/ &vspd2;
+/delete-node/ &vspi0;
+
+/ {
+       /delete-node/ hdmi0-out;
+};
+
+/ {
+       soc {
+               /delete-node/ fdp1@fe940000;
+       };
+};
index 368933e..492195f 100644 (file)
@@ -18,7 +18,8 @@
        .globl  ImageBase
 ImageBase:
        .short  IMAGE_DOS_SIGNATURE             /* 'MZ' */
-       .skip   58                              /* 'MZ' + pad + offset == 64 */
+       .skip   54                              /* 'MZ' + pad + offset == 64 */
+       .long   LINUX_ARM64_MAGIC               /* For GRUB's linux command */
        .long   pe_header - ImageBase           /* Offset to the PE header */
 pe_header:
        .long   IMAGE_NT_SIGNATURE              /* 'PE' */
index 80996a9..3d8af0a 100644 (file)
@@ -32,6 +32,9 @@
 #include <os.h>
 #include <rtc_def.h>
 
+/* Environment variable for time offset */
+#define ENV_TIME_OFFSET "UBOOT_SB_TIME_OFFSET"
+
 /* Operating System Interface */
 
 struct os_mem_hdr {
@@ -798,6 +801,28 @@ int os_spl_to_uboot(const char *fname)
        return os_jump_to_file(fname);
 }
 
+long os_get_time_offset(void)
+{
+       const char *offset;
+
+       offset = getenv(ENV_TIME_OFFSET);
+       if (offset)
+               return strtol(offset, NULL, 0);
+       return 0;
+}
+
+void os_set_time_offset(long offset)
+{
+       char buf[21];
+       int ret;
+
+       snprintf(buf, sizeof(buf), "%ld", offset);
+       ret = setenv(ENV_TIME_OFFSET, buf, true);
+       if (ret)
+               printf("Could not set environment variable %s\n",
+                      ENV_TIME_OFFSET);
+}
+
 void os_localtime(struct rtc_time *rt)
 {
        time_t t = time(NULL);
index 2d18d9d..2542580 100644 (file)
@@ -215,7 +215,7 @@ static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state,
        if (!p)
                p = fname + strlen(fname);
        len -= p - fname;
-       snprintf(p, len, fmt, p);
+       snprintf(p, len, fmt);
        state->fdt_fname = fname;
 
        return 0;
index d842f02..dc933f3 100644 (file)
                stringarray = "pre-proper";
        };
 
-       spl-test7 {
+       test-bus {
+               compatible = "simple-bus";
                u-boot,dm-spl;
-               compatible = "sandbox,spl-test";
-               stringarray = "spl";
+               spl-test7 {
+                       u-boot,dm-spl;
+                       compatible = "sandbox,spl-test";
+                       stringarray = "spl";
+               };
        };
 
        square {
index f86cd0d..e95f463 100644 (file)
                        wp-ro {
                                image-pos = <0xf000>;
                                size = <0x1000>;
+                               used = <0x884>;
+                               compress = "lz4";
+                               uncomp-size = <0xcf8>;
+                               hash {
+                                       algo = "sha256";
+                                       value = [00 01 02 03 04 05 06 07
+                                               08 09 0a 0b 0c 0d 0e 0f
+                                               10 11 12 13 14 15 16 17
+                                               18 19 1a 1b 1c 1d 1e 1f];
+                               };
                        };
                        rw {
                                image-pos = <0x10000>;
index 05f66f7..1cb960a 100644 (file)
@@ -58,6 +58,13 @@ enum {
 };
 
 /**
+ */
+enum cros_ec_test_t {
+       CROSECT_BREAK_HELLO     = BIT(1),
+       CROSECT_LID_OPEN        = BIT(2),
+};
+
+/**
  * sandbox_i2c_set_test_mode() - set test mode for running unit tests
  *
  * See sandbox_i2c_xfer() for the behaviour changes.
@@ -260,4 +267,12 @@ uint sandbox_pci_read_bar(u32 barval, int type, uint size);
  */
 void sandbox_set_enable_memio(bool enable);
 
+/**
+ * sandbox_cros_ec_set_test_flags() - Set behaviour for testing purposes
+ *
+ * @dev: Device to check
+ * @flags: Flags to control behaviour (CROSECT_...)
+ */
+void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags);
+
 #endif
index 7517b75..6fa0f4d 100644 (file)
@@ -175,7 +175,7 @@ void arch_setup_gd(gd_t *new_gd)
  * Per Intel FSP external architecture specification, before calling any FSP
  * APIs, we need make sure the system is in flat 32-bit mode and both the code
  * and data selectors should have full 4GB access range. Here we reuse the one
- * we used in arch/x86/cpu/start16.S, and reload the segement registers.
+ * we used in arch/x86/cpu/start16.S, and reload the segment registers.
  */
 void setup_fsp_gdt(void)
 {
index 3b6ed37..3d0d952 100644 (file)
@@ -77,7 +77,7 @@ _start:
        lgdt    gdt_ptr2
 #endif
 
-       /* Load the segement registers to match the GDT loaded in start16.S */
+       /* Load the segment registers to match the GDT loaded in start16.S */
        movl    $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
        movw    %ax, %fs
        movw    %ax, %ds
index a846022..9319123 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/x86-gpio.h>
 
 /include/ "skeleton.dtsi"
        clk: clock {
                compatible = "intel,apl-clk";
                #clock-cells = <1>;
+               u-boot,dm-pre-reloc;
        };
 
        cpus {
        };
 
        acpi_gpe: general-purpose-events {
+               u-boot,dm-pre-reloc;
                reg = <IOMAP_ACPI_BASE IOMAP_ACPI_SIZE>;
                compatible = "intel,acpi-gpe";
                interrupt-controller;
                };
 
                i2c_2: i2c2@16,2 {
-                       compatible = "intel,apl-i2c";
+                       compatible = "intel,apl-i2c", "snps,designware-i2c-pci";
                        reg = <0x0200b210 0 0 0 0>;
+                       early-regs = <IOMAP_I2C2_BASE 0x1000>;
+                       u-boot,dm-pre-reloc;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        clock-frequency = <400000>;
                        tpm: tpm@50 {
                                reg = <0x50>;
                                compatible = "google,cr50";
+                               u-boot,dm-pre-reloc;
                                u-boot,i2c-offset-len = <0>;
                                ready-gpios = <&gpio_n 28 GPIO_ACTIVE_LOW>;
                                interrupts-extended = <&acpi_gpe GPIO_28_IRQ
                                u-boot,dm-pre-reloc;
                                cros_ec: cros-ec {
                                        u-boot,dm-pre-proper;
+                                       u-boot,dm-vpl;
                                        compatible = "google,cros-ec-lpc";
                                        reg = <0x204 1 0x200 1 0x880 0x80>;
 
                                PAD_CFG0_TX_DISABLE | PAD_CFG0_ROUTE_IOAPIC |
                                PAD_CFG0_TRIG_LEVEL | PAD_CFG0_RX_POL_INVERT)
                        (PAD_CFG1_PULL_NONE | PAD_CFG1_IOSSTATE_TXD_RXE)
+               PAD_CFG_GPI(GPIO_25, UP_20K, DEEP)       /* unused */
 
                /*
                 * WLAN_PE_RST - default to deasserted just in case FSP
                PAD_CFG_NF(LPC_AD3, UP_20K, DEEP, NF1)   /* LPC_AD3 */
                PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */
                PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */
+
+               PAD_CFG_GPI(GPIO_101, NONE, DEEP) /* FST_IO2 -- MEM_CONFIG0 */
+               PAD_CFG_GPI(GPIO_102, NONE, DEEP) /* FST_IO3 -- MEM_CONFIG1 */
+               PAD_CFG_GPI(GPIO_38, NONE, DEEP) /* LPSS_UART0_RXD - MEM_CONFIG2*/
+               PAD_CFG_GPI(GPIO_45, NONE, DEEP) /* LPSS_UART1_CTS - MEM_CONFIG3 */
                >;
 };
 
                PAD_CFG_GPI(GPIO_73, UP_20K, DEEP)       /* GP_CAMERASB11 */
        >;
 };
+
+&rtc {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       u-boot,dm-pre-reloc;
+};
index 21c5f33..a4ea150 100644 (file)
@@ -33,6 +33,9 @@
 #define SRAM_SIZE_2            (4 * KiB)
 #endif
 
+/* Early address for I2C port 2 */
+#define IOMAP_I2C2_BASE                (0xfe020000 + 2 * 0x1000)
+
 /*
  * Use UART2. To use UART1 you need to set '2' to '1', change device tree serial
  * node name and 'reg' property, and update CONFIG_DEBUG_UART_BASE.
index c8eb5c3..81dd8e0 100644 (file)
@@ -8,6 +8,7 @@
 #define LOG_CATEGORY LOGC_EFI
 
 #include <common.h>
+#include <bootm.h>
 #include <charset.h>
 #include <command.h>
 #include <dm.h>
@@ -338,6 +339,9 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
        efi_uintn_t exit_data_size = 0;
        u16 *exit_data = NULL;
 
+       /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
+       switch_to_non_secure_mode();
+
        /* Call our payload! */
        ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data));
        if (ret != EFI_SUCCESS) {
index ce1f59a..eb5053d 100644 (file)
@@ -94,6 +94,169 @@ static int do_read_write(struct udevice *dev, int is_write, int argc,
        return 0;
 }
 
+static const char *const feat_name[64] = {
+       "limited",
+       "flash",
+       "pwm_fan",
+       "pwm_keyb",
+       "lightbar",
+       "led",
+       "motion_sense",
+       "keyb",
+       "pstore",
+       "port80",
+       "thermal",
+       "bklight_switch",
+       "wifi_switch",
+       "host_events",
+       "gpio",
+       "i2c",
+       "charger",
+       "battery",
+       "smart_battery",
+       "hang_detect",
+       "pmu",
+       "sub_mcu",
+       "usb_pd",
+       "usb_mux",
+       "motion_sense_fifo",
+       "vstore",
+       "usbc_ss_mux_virtual",
+       "rtc",
+       "fingerprint",
+       "touchpad",
+       "rwsig",
+       "device_event",
+       "unified_wake_masks",
+       "host_event64",
+       "exec_in_ram",
+       "cec",
+       "motion_sense_tight_timestamps",
+       "refined_tablet_mode_hysteresis",
+       "efs2",
+       "scp",
+       "ish",
+       "typec_cmd",
+       "typec_require_ap_mode_entry",
+       "typec_mux_require_ap_ack",
+};
+
+static int do_show_features(struct udevice *dev)
+{
+       u64 feat;
+       int ret;
+       uint i;
+
+       ret = cros_ec_get_features(dev, &feat);
+       if (ret)
+               return ret;
+       for (i = 0; i < ARRAY_SIZE(feat_name); i++) {
+               if (feat & (1ULL << i)) {
+                       if (feat_name[i])
+                               printf("%s\n", feat_name[i]);
+                       else
+                               printf("unknown %d\n", i);
+               }
+       }
+
+       return 0;
+}
+
+static const char *const switch_name[8] = {
+       "lid open",
+       "power button pressed",
+       "write-protect disabled",
+       NULL,
+       "dedicated recovery",
+       NULL,
+       NULL,
+       NULL,
+};
+
+static int do_show_switches(struct udevice *dev)
+{
+       uint switches;
+       int ret;
+       uint i;
+
+       ret = cros_ec_get_switches(dev);
+       if (ret < 0)
+               return log_msg_ret("get", ret);
+       switches = ret;
+       for (i = 0; i < ARRAY_SIZE(switch_name); i++) {
+               uint mask = 1 << i;
+
+               if (switches & mask) {
+                       if (switch_name[i])
+                               printf("%s\n", switch_name[i]);
+                       else
+                               printf("unknown %02x\n", mask);
+               }
+       }
+
+       return 0;
+}
+
+static const char *const event_name[] = {
+       "lid_closed",
+       "lid_open",
+       "power_button",
+       "ac_connected",
+       "ac_disconnected",
+       "battery_low",
+       "battery_critical",
+       "battery",
+       "thermal_threshold",
+       "device",
+       "thermal",
+       "usb_charger",
+       "key_pressed",
+       "interface_ready",
+       "keyboard_recovery",
+       "thermal_shutdown",
+       "battery_shutdown",
+       "throttle_start",
+       "throttle_stop",
+       "hang_detect",
+       "hang_reboot",
+       "pd_mcu",
+       "battery_status",
+       "panic",
+       "keyboard_fastboot",
+       "rtc",
+       "mkbp",
+       "usb_mux",
+       "mode_change",
+       "keyboard_recovery_hw_reinit",
+       "extended",
+       "invalid",
+};
+
+static int do_show_events(struct udevice *dev)
+{
+       u32 events;
+       int ret;
+       uint i;
+
+       ret = cros_ec_get_host_events(dev, &events);
+       if (ret)
+               return ret;
+       printf("%08x\n", events);
+       for (i = 0; i < ARRAY_SIZE(event_name); i++) {
+               enum host_event_code code = i + 1;
+               u64 mask = EC_HOST_EVENT_MASK(code);
+
+               if (events & mask) {
+                       if (event_name[i])
+                               printf("%s\n", event_name[i]);
+                       else
+                               printf("unknown code %#x\n", code);
+               }
+       }
+
+       return 0;
+}
+
 static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
                      char *const argv[])
 {
@@ -140,6 +303,16 @@ static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
                }
                printf("rows     = %u\n", info.rows);
                printf("cols     = %u\n", info.cols);
+       } else if (!strcmp("features", cmd)) {
+               ret = do_show_features(dev);
+
+               if (ret)
+                       printf("Error: %d\n", ret);
+       } else if (!strcmp("switches", cmd)) {
+               ret = do_show_switches(dev);
+
+               if (ret)
+                       printf("Error: %d\n", ret);
        } else if (0 == strcmp("curimage", cmd)) {
                enum ec_current_image image;
 
@@ -190,13 +363,10 @@ static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
                        return 1;
                }
        } else if (0 == strcmp("events", cmd)) {
-               uint32_t events;
+               ret = do_show_events(dev);
 
-               if (cros_ec_get_host_events(dev, &events)) {
-                       debug("%s: Could not read host events\n", __func__);
-                       return 1;
-               }
-               printf("0x%08x\n", events);
+               if (ret)
+                       printf("Error: %d\n", ret);
        } else if (0 == strcmp("clrevents", cmd)) {
                uint32_t events = 0x7fffffff;
 
@@ -352,6 +522,15 @@ static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
                        debug("%s: Could not access LDO%d\n", __func__, index);
                        return ret;
                }
+       } else if (!strcmp("sku", cmd)) {
+               ret = cros_ec_get_sku_id(dev);
+
+               if (ret >= 0) {
+                       printf("%d\n", ret);
+                       ret = 0;
+               } else {
+                       printf("Error: %d\n", ret);
+               }
        } else {
                return CMD_RET_USAGE;
        }
@@ -370,10 +549,13 @@ U_BOOT_CMD(
        "init                Re-init CROS-EC (done on startup automatically)\n"
        "crosec id                  Read CROS-EC ID\n"
        "crosec info                Read CROS-EC info\n"
+       "crosec features            Read CROS-EC features\n"
+       "crosec switches            Read CROS-EC switches\n"
        "crosec curimage            Read CROS-EC current image\n"
        "crosec hash                Read CROS-EC hash\n"
        "crosec reboot [rw | ro | cold]  Reboot CROS-EC\n"
        "crosec events              Read CROS-EC host events\n"
+       "crosec eventsb             Read CROS-EC host events_b\n"
        "crosec clrevents [mask]    Clear CROS-EC host events\n"
        "crosec regioninfo <ro|rw>  Read image info\n"
        "crosec flashinfo           Read flash info\n"
@@ -382,6 +564,7 @@ U_BOOT_CMD(
        "crosec write <ro|rw> <addr> [<size>]  Write EC image\n"
        "crosec vbnvcontext [hexstring]        Read [write] VbNvContext from EC\n"
        "crosec ldo <idx> [<state>] Switch/Read LDO state\n"
+       "crosec sku                 Read board SKU ID\n"
        "crosec test                run tests on cros_ec\n"
        "crosec version             Read CROS-EC version"
 );
index 05e6ce6..ab73a0a 100644 (file)
@@ -29,6 +29,7 @@ CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_SPL_BOOTSTAGE_RECORD_COUNT=10
 CONFIG_BOOTSTAGE_STASH=y
 CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS_SUBST=y
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_LOGF_FUNC=y
 CONFIG_SPL_LOG=y
index d193b18..61dae34 100644 (file)
@@ -101,7 +101,6 @@ CONFIG_SYSCON=y
 CONFIG_SPL_SYSCON=y
 CONFIG_DEVRES=y
 CONFIG_DEBUG_DEVRES=y
-# CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_ADC=y
 CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
index b69fd34..85b1af5 100644 (file)
@@ -150,6 +150,7 @@ void dev_print (struct blk_desc *dev_desc)
        case IF_TYPE_USB:
        case IF_TYPE_NVME:
        case IF_TYPE_PVBLOCK:
+       case IF_TYPE_HOST:
                printf ("Vendor: %s Rev: %s Prod: %s\n",
                        dev_desc->vendor,
                        dev_desc->revision,
index 2f92266..7a24e33 100644 (file)
@@ -867,6 +867,9 @@ int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
                return 1;
        }
 
+       /* Update the partition table entries*/
+       part_init(dev_desc);
+
        return 0;
 }
 #endif
index 4674c42..60ee1e0 100644 (file)
@@ -99,37 +99,44 @@ Command-line Options
 Various options are available, mostly for test purposes. Use -h to see
 available options. Some of these are described below:
 
--t, --terminal <arg>
-  The terminal is normally in what is called 'raw-with-sigs' mode. This means
+-t, --terminal <arg>
+  The terminal is normally in what is called 'raw-with-sigs' mode. This means
   that you can use arrow keys for command editing and history, but if you
   press Ctrl-C, U-Boot will exit instead of handling this as a keypress.
   Other options are 'raw' (so Ctrl-C is handled within U-Boot) and 'cooked'
   (where the terminal is in cooked mode and cursor keys will not work, Ctrl-C
   will exit).
 
--l
-  Show the LCD emulation window.
+-l
+  Show the LCD emulation window.
 
--d <device_tree>
-  A device tree binary file can be provided with -d. If you edit the source
+-d <device_tree>
+  A device tree binary file can be provided with -d. If you edit the source
   (it is stored at arch/sandbox/dts/sandbox.dts) you must rebuild U-Boot to
   recreate the binary file.
 
--D
-  To use the default device tree, use -D.
+-D
+  To use the default device tree, use -D.
 
--T
-  To use the test device tree, use -T.
+-T
+  To use the test device tree, use -T.
 
--c [<cmd>;]<cmd>
-  To execute commands directly, use the -c option. You can specify a single
+-c [<cmd>;]<cmd>
+  To execute commands directly, use the -c option. You can specify a single
   command, or multiple commands separated by a semicolon, as is normal in
   U-Boot. Be careful with quoting as the shell will normally process and
   swallow quotes. When -c is used, U-Boot exits after the command is complete,
   but you can force it to go to interactive mode instead with -i.
 
-* -i
-  - Go to interactive mode after executing the commands specified by -c.
+-i
+  Go to interactive mode after executing the commands specified by -c.
+
+Environment Variables
+---------------------
+
+UBOOT_SB_TIME_OFFSET
+    This environment variable stores the offset of the emulated real time clock
+    to the host's real time clock in seconds. The offset defaults to zero.
 
 Memory Emulation
 ----------------
index 34c26cd..f57f690 100644 (file)
@@ -92,6 +92,7 @@ int host_dev_bind(int devnum, char *filename)
 {
        struct host_block_dev *host_dev;
        struct udevice *dev;
+       struct blk_desc *desc;
        char dev_name[20], *str, *fname;
        int ret, fd;
 
@@ -143,6 +144,12 @@ int host_dev_bind(int devnum, char *filename)
                goto err_file;
        }
 
+       desc = blk_get_devnum_by_type(IF_TYPE_HOST, devnum);
+       desc->removable = 1;
+       snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
+       snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
+       snprintf(desc->revision, BLK_REV_SIZE, "1.0");
+
        return 0;
 err_file:
        os_close(fd);
@@ -187,6 +194,10 @@ int host_dev_bind(int dev, char *filename)
        blk_dev->block_write = host_block_write;
        blk_dev->devnum = dev;
        blk_dev->part_type = PART_TYPE_UNKNOWN;
+       blk_dev->removable = 1;
+       snprintf(blk_dev->vendor, BLK_VEN_SIZE, "U-Boot");
+       snprintf(blk_dev->product, BLK_PRD_SIZE, "hostfile");
+       snprintf(blk_dev->revision, BLK_REV_SIZE, "1.0");
        part_init(blk_dev);
 
        return 0;
index b750567..d5c4e3c 100644 (file)
@@ -83,7 +83,7 @@ static int clk_get_by_index_tail(int ret, ofnode node,
        if (ret) {
                debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
                      __func__, ret);
-               return ret;
+               return log_msg_ret("get", ret);
        }
 
        clk->dev = dev_clk;
@@ -96,14 +96,15 @@ static int clk_get_by_index_tail(int ret, ofnode node,
                ret = clk_of_xlate_default(clk, args);
        if (ret) {
                debug("of_xlate() failed: %d\n", ret);
-               return ret;
+               return log_msg_ret("xlate", ret);
        }
 
        return clk_request(dev_clk, clk);
 err:
        debug("%s: Node '%s', property '%s', failed to request CLK index %d: %d\n",
              __func__, ofnode_get_name(node), list_name, index, ret);
-       return ret;
+
+       return log_msg_ret("prop", ret);
 }
 
 static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
@@ -122,7 +123,7 @@ static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
        if (ret) {
                debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
                      __func__, ret);
-               return ret;
+               return log_ret(ret);
        }
 
 
@@ -470,6 +471,7 @@ int clk_free(struct clk *clk)
 ulong clk_get_rate(struct clk *clk)
 {
        const struct clk_ops *ops;
+       int ret;
 
        debug("%s(clk=%p)\n", __func__, clk);
        if (!clk_valid(clk))
@@ -479,7 +481,11 @@ ulong clk_get_rate(struct clk *clk)
        if (!ops->get_rate)
                return -ENOSYS;
 
-       return ops->get_rate(clk);
+       ret = ops->get_rate(clk);
+       if (ret)
+               return log_ret(ret);
+
+       return 0;
 }
 
 struct clk *clk_get_parent(struct clk *clk)
index b633934..46ccbb1 100644 (file)
@@ -29,8 +29,8 @@ static const struct udevice_id intel_clk_ids[] = {
        { }
 };
 
-U_BOOT_DRIVER(clk_intel) = {
-       .name           = "clk_intel",
+U_BOOT_DRIVER(intel_apl_clk) = {
+       .name           = "intel_apl_clk",
        .id             = UCLASS_CLK,
        .of_match       = intel_clk_ids,
        .ops            = &intel_clk_ops,
index aeab383..8629df8 100644 (file)
@@ -462,6 +462,15 @@ int device_probe(struct udevice *dev)
         * continue regardless of the result of pinctrl. Don't process pinctrl
         * settings for pinctrl devices since the device may not yet be
         * probed.
+        *
+        * This call can produce some non-intuitive results. For example, on an
+        * x86 device where dev is the main PCI bus, the pinctrl device may be
+        * child or grandchild of that bus, meaning that the child will be
+        * probed here. If the child happens to be the P2SB and the pinctrl
+        * device is a child of that, then both the pinctrl and P2SB will be
+        * probed by this call. This works because the DM_FLAG_ACTIVATED flag
+        * is set just above. However, the PCI bus' probe() method and
+        * associated uclass methods have not yet been called.
         */
        if (dev->parent && device_get_uclass_id(dev) != UCLASS_PINCTRL)
                pinctrl_select_state(dev, "default");
index 6420e6e..6533445 100644 (file)
 int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry)
 {
        const char *prop;
+       ofnode subnode;
 
        if (ofnode_read_u32(node, "image-pos", &entry->offset)) {
                debug("Node '%s' has bad/missing 'image-pos' property\n",
                      ofnode_get_name(node));
-               return log_ret(-ENOENT);
+               return log_msg_ret("image-pos", -ENOENT);
        }
        if (ofnode_read_u32(node, "size", &entry->length)) {
                debug("Node '%s' has bad/missing 'size' property\n",
                      ofnode_get_name(node));
-               return log_ret(-ENOENT);
+               return log_msg_ret("size", -ENOENT);
        }
        entry->used = ofnode_read_s32_default(node, "used", entry->length);
        prop = ofnode_read_string(node, "compress");
@@ -31,18 +32,20 @@ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry)
                if (!strcmp(prop, "lz4"))
                        entry->compress_algo = FMAP_COMPRESS_LZ4;
                else
-                       return log_msg_ret("Unknown compression algo",
-                                          -EINVAL);
+                       return log_msg_ret("compression algo", -EINVAL);
        } else {
                entry->compress_algo = FMAP_COMPRESS_NONE;
        }
        entry->unc_length = ofnode_read_s32_default(node, "uncomp-size",
                                                    entry->length);
-       prop = ofnode_read_string(node, "hash");
-       if (prop)
-               entry->hash_size = strlen(prop);
-       entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
-       entry->hash = (uint8_t *)prop;
+       subnode = ofnode_find_subnode(node, "hash");
+       if (ofnode_valid(subnode)) {
+               prop = ofnode_read_prop(subnode, "value", &entry->hash_size);
+
+               /* Assume it is sha256 */
+               entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
+               entry->hash = (uint8_t *)prop;
+       }
 
        return 0;
 }
index 1aac5c4..29aab0f 100644 (file)
@@ -39,7 +39,9 @@ obj-$(CONFIG_SYS_I2C_RCAR_I2C) += rcar_i2c.o
 obj-$(CONFIG_SYS_I2C_RCAR_IIC) += rcar_iic.o
 obj-$(CONFIG_SYS_I2C_ROCKCHIP) += rk_i2c.o
 obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
+endif
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
index ec0cdf6..9e38773 100644 (file)
@@ -192,6 +192,8 @@ static const struct udevice_id designware_i2c_pci_ids[] = {
        { }
 };
 
+DM_DRIVER_ALIAS(i2c_designware_pci, intel_apl_i2c)
+
 U_BOOT_DRIVER(i2c_designware_pci) = {
        .name   = "i2c_designware_pci",
        .id     = UCLASS_I2C,
index f03b7d5..ebfa7c4 100644 (file)
@@ -44,6 +44,10 @@ enum {
        CROS_EC_CMD_TIMEOUT_MS  = 5000,
        /* Timeout waiting for a synchronous hash to be recomputed */
        CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,
+
+       /* Wait 10 ms between attempts to check if EC's hash is ready */
+       CROS_EC_HASH_CHECK_DELAY_MS = 10,
+
 };
 
 #define INVALID_HCMD 0xFF
@@ -400,6 +404,8 @@ static int ec_command(struct udevice *dev, uint cmd, int cmd_version,
                 */
                if (din && in_buffer) {
                        assert(len <= din_len);
+                       if (len > din_len)
+                               return -ENOSPC;
                        memmove(din, in_buffer, len);
                }
        }
@@ -502,9 +508,10 @@ static int cros_ec_wait_on_hash_done(struct udevice *dev,
 
        start = get_timer(0);
        while (hash->status == EC_VBOOT_HASH_STATUS_BUSY) {
-               mdelay(50);     /* Insert some reasonable delay */
+               mdelay(CROS_EC_HASH_CHECK_DELAY_MS);
 
                p->cmd = EC_VBOOT_HASH_GET;
+
                if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, p, sizeof(*p), hash,
                               sizeof(*hash)) < 0)
                        return -1;
@@ -591,6 +598,25 @@ static int cros_ec_invalidate_hash(struct udevice *dev)
        return 0;
 }
 
+int cros_ec_hello(struct udevice *dev, uint *handshakep)
+{
+       struct ec_params_hello req;
+       struct ec_response_hello *resp;
+
+       req.in_data = 0x12345678;
+       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
+                            (uint8_t **)&resp, sizeof(*resp)) < 0)
+               return -EIO;
+       if (resp->out_data != req.in_data + 0x01020304) {
+               printf("Received invalid handshake %x\n", resp->out_data);
+               if (handshakep)
+                       *handshakep = req.in_data;
+               return -ENOTSYNC;
+       }
+
+       return 0;
+}
+
 int cros_ec_reboot(struct udevice *dev, enum ec_reboot_cmd cmd, uint8_t flags)
 {
        struct ec_params_reboot_ec p;
@@ -603,18 +629,23 @@ int cros_ec_reboot(struct udevice *dev, enum ec_reboot_cmd cmd, uint8_t flags)
                return -1;
 
        if (!(flags & EC_REBOOT_FLAG_ON_AP_SHUTDOWN)) {
+               ulong start;
+
                /*
                 * EC reboot will take place immediately so delay to allow it
                 * to complete.  Note that some reboot types (EC_REBOOT_COLD)
                 * will reboot the AP as well, in which case we won't actually
                 * get to this point.
                 */
-               /*
-                * TODO(rspangler@chromium.org): Would be nice if we had a
-                * better way to determine when the reboot is complete.  Could
-                * we poll a memory-mapped LPC value?
-                */
-               udelay(50000);
+               mdelay(50);
+               start = get_timer(0);
+               while (cros_ec_hello(dev, NULL)) {
+                       if (get_timer(start) > 3000) {
+                               log_err("EC did not return from reboot\n");
+                               return -ETIMEDOUT;
+                       }
+                       mdelay(5);
+               }
        }
 
        return 0;
@@ -738,7 +769,6 @@ static int cros_ec_check_version(struct udevice *dev)
 {
        struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
        struct ec_params_hello req;
-       struct ec_response_hello *resp;
 
        struct dm_cros_ec_ops *ops;
        int ret;
@@ -767,14 +797,14 @@ static int cros_ec_check_version(struct udevice *dev)
        /* Try sending a version 3 packet */
        cdev->protocol_version = 3;
        req.in_data = 0;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                            (uint8_t **)&resp, sizeof(*resp)) > 0)
+       ret = cros_ec_hello(dev, NULL);
+       if (!ret || ret == -ENOTSYNC)
                return 0;
 
        /* Try sending a version 2 packet */
        cdev->protocol_version = 2;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                            (uint8_t **)&resp, sizeof(*resp)) > 0)
+       ret = cros_ec_hello(dev, NULL);
+       if (!ret || ret == -ENOTSYNC)
                return 0;
 
        /*
@@ -790,18 +820,16 @@ static int cros_ec_check_version(struct udevice *dev)
 
 int cros_ec_test(struct udevice *dev)
 {
-       struct ec_params_hello req;
-       struct ec_response_hello *resp;
+       uint out_data;
+       int ret;
 
-       req.in_data = 0x12345678;
-       if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req),
-                      (uint8_t **)&resp, sizeof(*resp)) < sizeof(*resp)) {
+       ret = cros_ec_hello(dev, &out_data);
+       if (ret == -ENOTSYNC) {
+               printf("Received invalid handshake %x\n", out_data);
+               return ret;
+       } else if (ret) {
                printf("ec_command_inptr() returned error\n");
-               return -1;
-       }
-       if (resp->out_data != req.in_data + 0x01020304) {
-               printf("Received invalid handshake %x\n", resp->out_data);
-               return -1;
+               return ret;
        }
 
        return 0;
@@ -1077,6 +1105,19 @@ int cros_ec_flash_update_rw(struct udevice *dev, const uint8_t *image,
        return 0;
 }
 
+int cros_ec_get_sku_id(struct udevice *dev)
+{
+       struct ec_sku_id_info *r;
+       int ret;
+
+       ret = ec_command_inptr(dev, EC_CMD_GET_SKU_ID, 0, NULL, 0,
+                              (uint8_t **)&r, sizeof(*r));
+       if (ret != sizeof(*r))
+               return -ret;
+
+       return r->sku_id;
+}
+
 int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size)
 {
        struct ec_params_vbnvcontext p;
@@ -1303,19 +1344,33 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,
        return 0;
 }
 
-int cros_ec_check_feature(struct udevice *dev, int feature)
+int cros_ec_get_features(struct udevice *dev, u64 *featuresp)
 {
        struct ec_response_get_features r;
        int rv;
 
-       rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0);
-       if (rv)
-               return rv;
+       rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
+       if (rv != sizeof(r))
+               return -EIO;
+       *featuresp = r.flags[0] | (u64)r.flags[1] << 32;
+
+       return 0;
+}
+
+int cros_ec_check_feature(struct udevice *dev, uint feature)
+{
+       struct ec_response_get_features r;
+       int rv;
+
+       rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
+       if (rv != sizeof(r))
+               return -EIO;
 
        if (feature >= 8 * sizeof(r.flags))
-               return -1;
+               return -EINVAL;
 
-       return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature);
+       return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature) ? true :
+                false;
 }
 
 /*
@@ -1502,10 +1557,99 @@ int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable)
        return 0;
 }
 
+int cros_ec_vstore_supported(struct udevice *dev)
+{
+       return cros_ec_check_feature(dev, EC_FEATURE_VSTORE);
+}
+
+int cros_ec_vstore_info(struct udevice *dev, u32 *lockedp)
+{
+       struct ec_response_vstore_info *resp;
+
+       if (ec_command_inptr(dev, EC_CMD_VSTORE_INFO, 0, NULL, 0,
+                            (uint8_t **)&resp, sizeof(*resp)) != sizeof(*resp))
+               return -EIO;
+
+       if (lockedp)
+               *lockedp = resp->slot_locked;
+
+       return resp->slot_count;
+}
+
+/*
+ * cros_ec_vstore_read - Read data from EC vstore slot
+ *
+ * @slot: vstore slot to read from
+ * @data: buffer to store read data, must be EC_VSTORE_SLOT_SIZE bytes
+ */
+int cros_ec_vstore_read(struct udevice *dev, int slot, uint8_t *data)
+{
+       struct ec_params_vstore_read req;
+       struct ec_response_vstore_read *resp;
+
+       req.slot = slot;
+       if (ec_command_inptr(dev, EC_CMD_VSTORE_READ, 0, &req, sizeof(req),
+                            (uint8_t **)&resp, sizeof(*resp)) != sizeof(*resp))
+               return -EIO;
+
+       if (!data || req.slot >= EC_VSTORE_SLOT_MAX)
+               return -EINVAL;
+
+       memcpy(data, resp->data, sizeof(resp->data));
+
+       return 0;
+}
+
+/*
+ * cros_ec_vstore_write - Save data into EC vstore slot
+ *
+ * @slot: vstore slot to write into
+ * @data: data to write
+ * @size: size of data in bytes
+ *
+ * Maximum size of data is EC_VSTORE_SLOT_SIZE.  It is the callers
+ * responsibility to check the number of implemented slots by
+ * querying the vstore info.
+ */
+int cros_ec_vstore_write(struct udevice *dev, int slot, const uint8_t *data,
+                        size_t size)
+{
+       struct ec_params_vstore_write req;
+
+       if (slot >= EC_VSTORE_SLOT_MAX || size > EC_VSTORE_SLOT_SIZE)
+               return -EINVAL;
+
+       req.slot = slot;
+       memcpy(req.data, data, size);
+
+       if (ec_command(dev, EC_CMD_VSTORE_WRITE, 0, &req, sizeof(req), NULL, 0))
+               return -EIO;
+
+       return 0;
+}
+
+int cros_ec_get_switches(struct udevice *dev)
+{
+       struct dm_cros_ec_ops *ops;
+       int ret;
+
+       ops = dm_cros_ec_get_ops(dev);
+       if (!ops->get_switches)
+               return -ENOSYS;
+
+       ret = ops->get_switches(dev);
+       if (ret < 0)
+               return log_msg_ret("get", ret);
+
+       return ret;
+}
+
 UCLASS_DRIVER(cros_ec) = {
        .id             = UCLASS_CROS_EC,
        .name           = "cros-ec",
        .per_device_auto        = sizeof(struct cros_ec_dev),
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
        .post_bind      = dm_scan_fdt_dev,
+#endif
        .flags          = DM_UC_FLAG_ALLOC_PRIV_DMA,
 };
index e0002b9..f403759 100644 (file)
@@ -207,6 +207,12 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob)
        return 0;
 }
 
+/* Return the byte of EC switch states */
+static int cros_ec_lpc_get_switches(struct udevice *dev)
+{
+       return inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES);
+}
+
 /*
  * Test if LPC command args are supported.
  *
@@ -239,6 +245,7 @@ static struct dm_cros_ec_ops cros_ec_ops = {
        .packet = cros_ec_lpc_packet,
        .command = cros_ec_lpc_command,
        .check_version = cros_ec_lpc_check_version,
+       .get_switches = cros_ec_lpc_get_switches,
 };
 
 static const struct udevice_id cros_ec_ids[] = {
index 9fd6cc2..cb8adc4 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/malloc.h>
 #include <asm/state.h>
 #include <asm/sdl.h>
+#include <asm/test.h>
 #include <linux/input.h>
 
 /*
@@ -61,6 +62,15 @@ struct ec_keymatrix_entry {
        int keycode;    /* corresponding linux key code */
 };
 
+enum {
+       VSTORE_SLOT_COUNT       = 4,
+};
+
+struct vstore_slot {
+       bool locked;
+       u8 data[EC_VSTORE_SLOT_SIZE];
+};
+
 /**
  * struct ec_state - Information about the EC state
  *
@@ -73,6 +83,8 @@ struct ec_keymatrix_entry {
  * @matrix: Information about keyboard matrix
  * @keyscan: Current keyscan information (bit set for each row/column pressed)
  * @recovery_req: Keyboard recovery requested
+ * @test_flags: Flags that control behaviour for tests
+ * @slot_locked: Locked vstore slots (mask)
  */
 struct ec_state {
        u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2];
@@ -84,6 +96,8 @@ struct ec_state {
        struct ec_keymatrix_entry *matrix;      /* the key matrix info */
        uint8_t keyscan[KEYBOARD_COLS];
        bool recovery_req;
+       uint test_flags;
+       struct vstore_slot slot[VSTORE_SLOT_COUNT];
 } s_state, *g_state;
 
 /**
@@ -295,6 +309,8 @@ static int process_cmd(struct ec_state *ec,
                struct ec_response_hello *resp = resp_data;
 
                resp->out_data = req->in_data + 0x01020304;
+               if (ec->test_flags & CROSECT_BREAK_HELLO)
+                       resp->out_data++;
                len = sizeof(*resp);
                break;
        }
@@ -358,10 +374,20 @@ static int process_cmd(struct ec_state *ec,
                        resp->mask |= EC_HOST_EVENT_MASK(
                                        EC_HOST_EVENT_KEYBOARD_RECOVERY);
                }
-
+               if (ec->test_flags & CROSECT_LID_OPEN)
+                       resp->mask |=
+                               EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN);
                len = sizeof(*resp);
                break;
        }
+       case EC_CMD_HOST_EVENT_CLEAR_B: {
+               const struct ec_params_host_event_mask *req = req_data;
+
+               if (req->mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN))
+                       ec->test_flags &= ~CROSECT_LID_OPEN;
+               len = 0;
+               break;
+               }
        case EC_CMD_VBOOT_HASH: {
                const struct ec_params_vboot_hash *req = req_data;
                struct ec_response_vboot_hash *resp = resp_data;
@@ -468,6 +494,62 @@ static int process_cmd(struct ec_state *ec,
                len = sizeof(*resp);
                break;
        }
+       case EC_CMD_GET_SKU_ID: {
+               struct ec_sku_id_info *resp = resp_data;
+
+               resp->sku_id = 1234;
+               len = sizeof(*resp);
+               break;
+       }
+       case EC_CMD_GET_FEATURES: {
+               struct ec_response_get_features *resp = resp_data;
+
+               resp->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FLASH) |
+                       EC_FEATURE_MASK_0(EC_FEATURE_I2C) |
+                       EC_FEATURE_MASK_0(EC_FEATURE_VSTORE);
+               resp->flags[1] =
+                       EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS) |
+                       EC_FEATURE_MASK_1(EC_FEATURE_ISH);
+               len = sizeof(*resp);
+               break;
+       }
+       case EC_CMD_VSTORE_INFO: {
+               struct ec_response_vstore_info *resp = resp_data;
+               int i;
+
+               resp->slot_count = VSTORE_SLOT_COUNT;
+               resp->slot_locked = 0;
+               for (i = 0; i < VSTORE_SLOT_COUNT; i++) {
+                       if (ec->slot[i].locked)
+                               resp->slot_locked |= 1 << i;
+               }
+               len = sizeof(*resp);
+               break;
+       };
+       case EC_CMD_VSTORE_WRITE: {
+               const struct ec_params_vstore_write *req = req_data;
+               struct vstore_slot *slot;
+
+               if (req->slot >= EC_VSTORE_SLOT_MAX)
+                       return -EINVAL;
+               slot = &ec->slot[req->slot];
+               slot->locked = true;
+               memcpy(slot->data, req->data, EC_VSTORE_SLOT_SIZE);
+               len = 0;
+               break;
+       }
+       case EC_CMD_VSTORE_READ: {
+               const struct ec_params_vstore_read *req = req_data;
+               struct ec_response_vstore_read *resp = resp_data;
+               struct vstore_slot *slot;
+
+               if (req->slot >= EC_VSTORE_SLOT_MAX)
+                       return -EINVAL;
+               slot = &ec->slot[req->slot];
+               memcpy(resp->data, slot->data, EC_VSTORE_SLOT_SIZE);
+               len = sizeof(*resp);
+               break;
+       }
        default:
                printf("   ** Unknown EC command %#02x\n", req_hdr->command);
                return -1;
@@ -518,6 +600,21 @@ void cros_ec_check_keyboard(struct udevice *dev)
        }
 }
 
+/* Return the byte of EC switch states */
+static int cros_ec_sandbox_get_switches(struct udevice *dev)
+{
+       struct ec_state *ec = dev_get_priv(dev);
+
+       return ec->test_flags & CROSECT_LID_OPEN ? EC_SWITCH_LID_OPEN : 0;
+}
+
+void sandbox_cros_ec_set_test_flags(struct udevice *dev, uint flags)
+{
+       struct ec_state *ec = dev_get_priv(dev);
+
+       ec->test_flags = flags;
+}
+
 int cros_ec_probe(struct udevice *dev)
 {
        struct ec_state *ec = dev_get_priv(dev);
@@ -573,6 +670,7 @@ int cros_ec_probe(struct udevice *dev)
 
 struct dm_cros_ec_ops cros_ec_ops = {
        .packet = cros_ec_sandbox_packet,
+       .get_switches = cros_ec_sandbox_get_switches,
 };
 
 static const struct udevice_id cros_ec_ids[] = {
index 24130e6..2acb8c6 100644 (file)
@@ -862,6 +862,9 @@ static void renesas_sdhi_filter_caps(struct udevice *dev)
        if (!(priv->caps & TMIO_SD_CAP_RCAR_GEN3))
                return;
 
+       if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL)
+               priv->idma_bus_width = TMIO_SD_DMA_MODE_BUS_WIDTH;
+
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
     CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
index 2c52868..6c0c840 100644 (file)
@@ -324,6 +324,8 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
 
        tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE);
 
+       tmp |= priv->idma_bus_width;
+
        if (data->flags & MMC_DATA_READ) {
                buf = data->dest;
                dir = DMA_FROM_DEVICE;
@@ -702,6 +704,7 @@ static void tmio_sd_host_init(struct tmio_sd_priv *priv)
        if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL) {
                tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE);
                tmp |= TMIO_SD_DMA_MODE_ADDR_INC;
+               tmp |= priv->idma_bus_width;
                tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE);
        }
 }
index 9062300..59d5a0e 100644 (file)
@@ -90,6 +90,7 @@
 #define   TMIO_SD_VOLT_180             (2 << 0)/* 1.8V signal */
 #define TMIO_SD_DMA_MODE               0x410
 #define   TMIO_SD_DMA_MODE_DIR_RD      BIT(16) /* 1: from device, 0: to dev */
+#define   TMIO_SD_DMA_MODE_BUS_WIDTH   (BIT(5) | BIT(4)) /* RCar, 64bit */
 #define   TMIO_SD_DMA_MODE_ADDR_INC    BIT(0)  /* 1: address inc, 0: fixed */
 #define TMIO_SD_DMA_CTL                0x414
 #define   TMIO_SD_DMA_CTL_START        BIT(0)  /* start DMA (auto cleared) */
@@ -121,6 +122,7 @@ struct tmio_sd_priv {
        unsigned int                    version;
        u32                             caps;
        u32                             read_poll_flag;
+       u32                             idma_bus_width;
 #define TMIO_SD_CAP_NONREMOVABLE       BIT(0)  /* Nonremovable e.g. eMMC */
 #define TMIO_SD_CAP_DMA_INTERNAL       BIT(1)  /* have internal DMA engine */
 #define TMIO_SD_CAP_DIV1024            BIT(2)  /* divisor 1024 is available */
index 5a2a154..f25b976 100644 (file)
@@ -57,6 +57,7 @@ long sandbox_i2c_rtc_set_offset(struct udevice *dev, bool use_system_time,
        plat->use_system_time = use_system_time;
        if (offset != -1)
                plat->offset = offset;
+       os_set_time_offset(plat->offset);
 
        return old_offset;
 }
@@ -80,7 +81,7 @@ static void reset_time(struct udevice *dev)
 
        os_localtime(&now);
        plat->base_time = rtc_mktime(&now);
-       plat->offset = 0;
+       plat->offset = os_get_time_offset();
        plat->use_system_time = true;
 }
 
@@ -115,6 +116,7 @@ static int sandbox_i2c_rtc_set(struct udevice *dev, const struct rtc_time *time)
                now = plat->base_time;
        }
        plat->offset = rtc_mktime(time) - now;
+       os_set_time_offset(plat->offset);
 
        return 0;
 }
index ce61b72..b103a6f 100644 (file)
@@ -183,23 +183,31 @@ static int cr50_i2c_write(struct udevice *dev, u8 addr, const u8 *buffer,
        return cr50_i2c_wait_tpm_ready(dev);
 }
 
-static inline u8 tpm_access(u8 locality)
+static inline u8 tpm_access(int locality)
 {
+       if (locality == -1)
+               locality = 0;
        return 0x0 | (locality << 4);
 }
 
-static inline u8 tpm_sts(u8 locality)
+static inline u8 tpm_sts(int locality)
 {
+       if (locality == -1)
+               locality = 0;
        return 0x1 | (locality << 4);
 }
 
-static inline u8 tpm_data_fifo(u8 locality)
+static inline u8 tpm_data_fifo(int locality)
 {
+       if (locality == -1)
+               locality = 0;
        return 0x5 | (locality << 4);
 }
 
-static inline u8 tpm_did_vid(u8 locality)
+static inline u8 tpm_did_vid(int locality)
 {
+       if (locality == -1)
+               locality = 0;
        return 0x6 | (locality << 4);
 }
 
@@ -372,7 +380,6 @@ out_err:
 static int cr50_i2c_send(struct udevice *dev, const u8 *buf, size_t len)
 {
        struct cr50_priv *priv = dev_get_priv(dev);
-
        int status;
        size_t burstcnt, limit, sent = 0;
        u8 tpm_go[4] = { TPM_STS_GO };
@@ -549,9 +556,23 @@ static int cr50_i2c_get_desc(struct udevice *dev, char *buf, int size)
 {
        struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
        struct cr50_priv *priv = dev_get_priv(dev);
+       int len;
+
+       len = snprintf(buf, size, "cr50 TPM 2.0 (i2c %02x id %x), ",
+                      chip->chip_addr, priv->vendor >> 16);
+       if (priv->use_irq) {
+               len += snprintf(buf + len, size - len, "irq=%s/%ld",
+                               priv->irq.dev->name, priv->irq.id);
+       } else if (dm_gpio_is_valid(&priv->ready_gpio)) {
+               len += snprintf(buf + len, size - len, "gpio=%s/%u",
+                               priv->ready_gpio.dev->name,
+                               priv->ready_gpio.offset);
+       } else {
+               len += snprintf(buf + len, size - len, "delay=%d",
+                               TIMEOUT_NO_IRQ_US);
+       }
 
-       return snprintf(buf, size, "cr50 TPM 2.0 (i2c %02x id %x) irq=%d",
-                       chip->chip_addr, priv->vendor >> 16, priv->use_irq);
+       return len;
 }
 
 static int cr50_i2c_open(struct udevice *dev)
@@ -694,11 +715,12 @@ static int cr50_i2c_probe(struct udevice *dev)
                mdelay(10);
        }
        if (vendor != CR50_DID_VID) {
-               log_debug("DID_VID %08x not recognised\n", vendor);
+               log_warning("DID_VID %08x not recognised\n", vendor);
                return log_msg_ret("vendor-id", -EXDEV);
        }
        priv->vendor = vendor;
        priv->locality = -1;
+       log_debug("Cr50 ready\n");
 
        return 0;
 }
@@ -720,8 +742,8 @@ static const struct udevice_id cr50_i2c_ids[] = {
        { }
 };
 
-U_BOOT_DRIVER(cr50_i2c) = {
-       .name   = "cr50_i2c",
+U_BOOT_DRIVER(google_cr50) = {
+       .name   = "google_cr50",
        .id     = UCLASS_TPM,
        .of_match = cr50_i2c_ids,
        .ops    = &cr50_i2c_ops,
index b247519..a1df747 100644 (file)
@@ -51,4 +51,6 @@
 #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER     12
 #define IMAGE_SUBSYSTEM_EFI_ROM                        13
 
+#define LINUX_ARM64_MAGIC                      0x644d5241
+
 #endif /* _ASM_PE_H */
index f187bd0..eddc23d 100644 (file)
@@ -234,11 +234,61 @@ int cros_ec_flash_update_rw(struct udevice *dev, const uint8_t  *image,
 struct udevice *board_get_cros_ec_dev(void);
 
 struct dm_cros_ec_ops {
+       /**
+        * check_version() - Check the protocol version being used (optional)
+        *
+        * If provided, this function should check that the EC can be supported
+        * by the driver. If not provided, HELLO messages will be sent to try
+        * to determine the protocol version.
+        *
+        * @dev: Device to check
+        * @return 0 if the protocol is valid, -ve if not supported
+        */
        int (*check_version)(struct udevice *dev);
+
+       /**
+        * command() - Old-style command interface
+        *
+        * This sends a command and receives a response (deprecated, use
+        * packet())
+        *
+        * @dev: Device to use
+        * @cmd: Command to send (only supports 0-0xff)
+        * @cmd_version: Version of command to send (often 0)
+        * @dout: Output data (may be NULL If dout_len=0)
+        * @dout_len: Length of output data excluding 4-byte header
+        * @dinp: On input, set to point to input data, often struct
+        *      cros_ec_dev->din - typically this is left alone but may be
+        *      updated by the driver
+        * @din_len: Maximum length of response
+        * @return number of bytes in response, or -ve on error
+        */
        int (*command)(struct udevice *dev, uint8_t cmd, int cmd_version,
                       const uint8_t *dout, int dout_len,
                       uint8_t **dinp, int din_len);
+
+       /**
+        * packet() - New-style command interface
+        *
+        * This interface is preferred over command(), since it is typically
+        * easier to implement.
+        *
+        * @dev: Device to use
+        * @out_bytes: Number of bytes to send (from struct cros_ec_dev->dout)
+        * @in_bytes: Maximum number of bytes to expect in response
+        * @return number of bytes in response, or -ve on error
+        */
        int (*packet)(struct udevice *dev, int out_bytes, int in_bytes);
+
+       /**
+        * get_switches() - Get value of EC switches
+        *
+        * This is currently supported on the LPC EC.
+        *
+        * @dev: Device to use
+        * @return current switches value, or -ENOSYS if not supported
+        */
+       int (*get_switches)(struct udevice *dev);
 };
 
 #define dm_cros_ec_get_ops(dev) \
@@ -330,6 +380,14 @@ int cros_ec_flash_offset(struct udevice *dev, enum ec_flash_region region,
                         uint32_t *offset, uint32_t *size);
 
 /**
+ * cros_ec_get_sku_id() - Read the SKU ID
+ *
+ * @dev: CROS-EC device
+ * return SKU ID, or -ve on error
+ */
+int cros_ec_get_sku_id(struct udevice *dev);
+
+/**
  * Read/write non-volatile data from/to a CROS-EC device.
  *
  * @param dev          CROS-EC device
@@ -497,4 +555,88 @@ int cros_ec_get_lid_shutdown_mask(struct udevice *dev);
  */
 int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable);
 
+/**
+ * cros_ec_hello() - Send a hello message
+ *
+ * Sends a message with a fixed input value and checks that the expected output
+ * value is received
+ *
+ * @dev: CROS-EC device
+ * @handshakep: If non-NULL, returns received handshake value on error
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_hello(struct udevice *dev, uint *handshakep);
+
+/**
+ * cros_ec_get_features() - Get the set of features provided by the EC
+ *
+ * See enum ec_feature_code for the list of available features
+ *
+ * @dev: CROS-EC device
+ * @featuresp: Returns a bitmask of supported features
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_get_features(struct udevice *dev, u64 *featuresp);
+
+/**
+ * cros_ec_check_feature() - Check if a feature is supported
+ *
+ * @dev: CROS-EC device
+ * @feature: Feature number to check (enum ec_feature_code)
+ * @return true if supported, false if not, -ve on error
+ */
+int cros_ec_check_feature(struct udevice *dev, uint feature);
+
+/**
+ * cros_ec_get_switches() - Get switches value
+ *
+ * @dev: CROS-EC device
+ * @return switches value, or -ENOSYS if not supported, or other -ve value on
+ *     other error
+ */
+int cros_ec_get_switches(struct udevice *dev);
+
+/**
+ * cros_ec_vstore_supported() - Check if vstore is supported
+ *
+ * @dev: CROS-EC device
+ * @return false if not supported, true if supported, -ve on error
+ */
+int cros_ec_vstore_supported(struct udevice *dev);
+
+/**
+ * cros_ec_vstore_info() - Get vstore information
+ *
+ * @dev: CROS-EC device
+ * @lockedp: mask of locked slots
+ * @return number of vstore slots supported by the EC,, -ve on error
+ */
+int cros_ec_vstore_info(struct udevice *dev, u32 *lockedp);
+
+/**
+ * cros_ec_vstore_read() - Read data from EC vstore slot
+ *
+ * @dev: CROS-EC device
+ * @slot: vstore slot to read from
+ * @data: buffer to store read data, must be EC_VSTORE_SLOT_SIZE bytes
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_vstore_read(struct udevice *dev, int slot, uint8_t *data);
+
+/**
+ * cros_ec_vstore_write() - Save data into EC vstore slot
+ *
+ * The maximum size of data is EC_VSTORE_SLOT_SIZE.  It is the caller's
+ * responsibility to check the number of implemented slots by querying the
+ * vstore info.
+ *
+ * @dev: CROS-EC device
+ * @slot: vstore slot to write into
+ * @data: data to write
+ * @size: size of data in bytes
+ * @return 0 if OK, -ve on error
+ */
+int cros_ec_vstore_write(struct udevice *dev, int slot, const uint8_t *data,
+                        size_t size);
+
 #endif
diff --git a/include/ctype.h b/include/ctype.h
new file mode 120000 (symlink)
index 0000000..9e43f9c
--- /dev/null
@@ -0,0 +1 @@
+linux/ctype.h
\ No newline at end of file
index f5b4cd6..e665558 100644 (file)
@@ -111,7 +111,7 @@ enum {
  * probe method if the device has a device tree node.
  *
  * All three of plat, priv and uclass_priv can be allocated by the
- * driver, or you can use the auto_alloc_size members of struct driver and
+ * driver, or you can use the auto members of struct driver and
  * struct uclass_driver to have driver model do this automatically.
  *
  * @driver: The driver used by this device
index c875e11..03ba982 100644 (file)
@@ -30,8 +30,7 @@ static inline const struct device_node *dev_np(const struct udevice *dev)
 }
 #endif
 
-#ifndef CONFIG_DM_DEV_READ_INLINE
-
+#if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA)
 /**
  * dev_read_u32() - read a 32-bit integer from a device's DT property
  *
@@ -1007,7 +1006,7 @@ static inline u64 dev_translate_dma_address(const struct udevice *dev,
 
 static inline int dev_read_alias_highest_id(const char *stem)
 {
-       if (!CONFIG_IS_ENABLED(OF_LIBFDT))
+       if (!CONFIG_IS_ENABLED(OF_LIBFDT) || !gd->fdt_blob)
                return -1;
        return fdtdec_get_alias_highest_id(gd->fdt_blob, stem);
 }
index 444ba61..36f4a02 100644 (file)
@@ -1101,13 +1101,50 @@ enum ec_feature_code {
        EC_FEATURE_DEVICE_EVENT = 31,
        /* EC supports the unified wake masks for LPC/eSPI systems */
        EC_FEATURE_UNIFIED_WAKE_MASKS = 32,
+       /* EC supports 64-bit host events */
+       EC_FEATURE_HOST_EVENT64 = 33,
+       /* EC runs code in RAM (not in place, a.k.a. XIP) */
+       EC_FEATURE_EXEC_IN_RAM = 34,
+       /* EC supports CEC commands */
+       EC_FEATURE_CEC = 35,
+       /* EC supports tight sensor timestamping. */
+       EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS = 36,
+       /*
+        * EC supports tablet mode detection aligned to Chrome and allows
+        * setting of threshold by host command using
+        * MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE.
+        */
+       EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37,
+       /*
+        * Early Firmware Selection ver.2. Enabled by CONFIG_VBOOT_EFS2.
+        * Note this is a RO feature. So, a query (EC_CMD_GET_FEATURES) should
+        * be sent to RO to be precise.
+        */
+       EC_FEATURE_EFS2 = 38,
+       /* The MCU is a System Companion Processor (SCP). */
+       EC_FEATURE_SCP = 39,
+       /* The MCU is an Integrated Sensor Hub */
+       EC_FEATURE_ISH = 40,
+       /* New TCPMv2 TYPEC_ prefaced commands supported */
+       EC_FEATURE_TYPEC_CMD = 41,
+       /*
+        * The EC will wait for direction from the AP to enter Type-C alternate
+        * modes or USB4.
+        */
+       EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY = 42,
+       /*
+        * The EC will wait for an acknowledge from the AP after setting the
+        * mux.
+        */
+       EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43,
 };
 
-#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
-#define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32))
-struct __ec_align4 ec_response_get_features {
+#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
+#define EC_FEATURE_MASK_1(event_code) BIT(event_code - 32)
+
+struct ec_response_get_features {
        uint32_t flags[2];
-};
+} __ec_align4;
 
 /*****************************************************************************/
 /* Get the board's SKU ID from EC */
index 0913b47..e192e32 100644 (file)
@@ -424,4 +424,22 @@ int os_setup_signal_handlers(void);
  */
 void os_signal_action(int sig, unsigned long pc);
 
+/**
+ * os_get_time_offset() - get time offset
+ *
+ * Get the time offset from environment variable UBOOT_SB_TIME_OFFSET.
+ *
+ * Return:     offset in seconds
+ */
+long os_get_time_offset(void);
+
+/**
+ * os_set_time_offset() - set time offset
+ *
+ * Save the time offset in environment variable UBOOT_SB_TIME_OFFSET.
+ *
+ * @offset:    offset in seconds
+ */
+void os_set_time_offset(long offset);
+
 #endif
index f415df3..6040ec8 100644 (file)
@@ -145,6 +145,8 @@ int binman_init(void)
        if (ret)
                return log_msg_ret("node", -ENOENT);
        binman_set_rom_offset(ROM_OFFSET_NONE);
+       log_debug("binman: Selected image node '%s'\n",
+                 ofnode_get_name(binman->image));
 
        return 0;
 }
index c0804ef..d0aad02 100644 (file)
@@ -142,8 +142,9 @@ static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this,
                return EFI_MEDIA_CHANGED;
        if (!this->media->media_present)
                return EFI_NO_MEDIA;
-       /* media->io_align is a power of 2 */
-       if ((uintptr_t)buffer & (this->media->io_align - 1))
+       /* media->io_align is a power of 2 or 0 */
+       if (this->media->io_align &&
+           (uintptr_t)buffer & (this->media->io_align - 1))
                return EFI_INVALID_PARAMETER;
        if (lba * this->media->block_size + buffer_size >
            this->media->last_block * this->media->block_size)
@@ -209,8 +210,9 @@ static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this,
                return EFI_MEDIA_CHANGED;
        if (!this->media->media_present)
                return EFI_NO_MEDIA;
-       /* media->io_align is a power of 2 */
-       if ((uintptr_t)buffer & (this->media->io_align - 1))
+       /* media->io_align is a power of 2 or 0 */
+       if (this->media->io_align &&
+           (uintptr_t)buffer & (this->media->io_align - 1))
                return EFI_INVALID_PARAMETER;
        if (lba * this->media->block_size + buffer_size >
            this->media->last_block * this->media->block_size)
index 5800cbf..b1c5125 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include <common.h>
-#include <bootm.h>
 #include <efi_loader.h>
 #include <efi_variable.h>
 
@@ -188,9 +187,6 @@ efi_status_t efi_init_obj_list(void)
        /* Allow unaligned memory access */
        allow_unaligned();
 
-       /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
-       switch_to_non_secure_mode();
-
        /* Initialize root node */
        ret = efi_root_node_register();
        if (ret != EFI_SUCCESS)
index 5eb297d..15f0375 100644 (file)
@@ -194,7 +194,7 @@ static int setup(const efi_handle_t handle,
        decompress(&image);
 
        block_io.media->block_size = 1 << LB_BLOCK_SIZE;
-       block_io.media->last_block = img.length >> LB_BLOCK_SIZE;
+       block_io.media->last_block = (img.length >> LB_BLOCK_SIZE) - 1;
 
        ret = boottime->install_protocol_interface(
                                &disk_handle, &block_io_protocol_guid,
@@ -301,6 +301,7 @@ static int execute(void)
        efi_handle_t *handles;
        efi_handle_t handle_partition = NULL;
        struct efi_device_path *dp_partition;
+       struct efi_block_io *block_io_protocol;
        struct efi_simple_file_system_protocol *file_system;
        struct efi_file_handle *root, *file;
        struct {
@@ -309,6 +310,7 @@ static int execute(void)
        } system_info;
        efi_uintn_t buf_size;
        char buf[16] __aligned(ARCH_DMA_MINALIGN);
+       u32 part1_size;
        u64 pos;
 
        /* Connect controller to virtual disk */
@@ -353,6 +355,23 @@ static int execute(void)
                return EFI_ST_FAILURE;
        }
 
+       /* Open the block_io_protocol */
+       ret = boottime->open_protocol(handle_partition,
+                                     &block_io_protocol_guid,
+                                     (void **)&block_io_protocol, NULL, NULL,
+                                     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("Failed to open block IO protocol\n");
+               return EFI_ST_FAILURE;
+       }
+       /* Get size of first MBR partition */
+       memcpy(&part1_size, image + 0x1ca, sizeof(u32));
+       if (block_io_protocol->media->last_block != part1_size - 1) {
+               efi_st_error("Last LBA of partition %x, expected %x\n",
+                            (unsigned int)block_io_protocol->media->last_block,
+                            part1_size - 1);
+               return EFI_ST_FAILURE;
+       }
        /* Open the simple file system protocol */
        ret = boottime->open_protocol(handle_partition,
                                      &guid_simple_file_system_protocol,
index 46e076e..e70e50f 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_BLK) += blk.o
 obj-$(CONFIG_BUTTON) += button.o
 obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
 obj-$(CONFIG_CLK) += clk.o clk_ccf.o
+obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-$(CONFIG_DEVRES) += devres.o
 obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
 obj-$(CONFIG_DM_ETH) += eth.o
@@ -41,6 +42,7 @@ obj-y += fdtdec.o
 obj-$(CONFIG_UT_DM) += nop.o
 obj-y += ofnode.o
 obj-y += ofread.o
+obj-y += of_extra.o
 obj-$(CONFIG_OSD) += osd.o
 obj-$(CONFIG_DM_VIDEO) += panel.o
 obj-$(CONFIG_DM_PCI) += pci.o
diff --git a/test/dm/cros_ec.c b/test/dm/cros_ec.c
new file mode 100644 (file)
index 0000000..30cb70e
--- /dev/null
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <cros_ec.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_cros_ec_hello(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       uint val;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+
+       ut_assertok(cros_ec_hello(dev, NULL));
+
+       val = 0xdead1357;
+       ut_assertok(cros_ec_hello(dev, &val));
+       ut_asserteq(0xdead1357, val);
+
+       sandbox_cros_ec_set_test_flags(dev, CROSECT_BREAK_HELLO);
+       ut_asserteq(-ENOTSYNC, cros_ec_hello(dev, &val));
+       ut_asserteq(0x12345678, val);
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_hello, UT_TESTF_SCAN_FDT);
+
+static int dm_test_cros_ec_sku_id(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+       ut_asserteq(1234, cros_ec_get_sku_id(dev));
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec sku", 0));
+       ut_assert_nextline("1234");
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_sku_id, UT_TESTF_SCAN_FDT);
+
+static int dm_test_cros_ec_features(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       u64 feat;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+       ut_assertok(cros_ec_get_features(dev, &feat));
+       ut_asserteq_64(1U << EC_FEATURE_FLASH | 1U << EC_FEATURE_I2C |
+               1u << EC_FEATURE_VSTORE |
+               1ULL << EC_FEATURE_UNIFIED_WAKE_MASKS | 1ULL << EC_FEATURE_ISH,
+               feat);
+
+       ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_I2C));
+       ut_asserteq(false, cros_ec_check_feature(dev, EC_FEATURE_MOTION_SENSE));
+       ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_ISH));
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec features", 0));
+       ut_assert_nextline("flash");
+       ut_assert_nextline("i2c");
+       ut_assert_nextline("vstore");
+       ut_assert_nextline("unified_wake_masks");
+       ut_assert_nextline("ish");
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_features, UT_TESTF_SCAN_FDT);
+
+static int dm_test_cros_ec_switches(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+       ut_asserteq(0, cros_ec_get_switches(dev));
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec switches", 0));
+       ut_assert_console_end();
+
+       /* Open the lid and check the switch changes */
+       sandbox_cros_ec_set_test_flags(dev, CROSECT_LID_OPEN);
+       ut_asserteq(EC_SWITCH_LID_OPEN, cros_ec_get_switches(dev));
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec switches", 0));
+       ut_assert_nextline("lid open");
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_switches, UT_TESTF_SCAN_FDT);
+
+static int dm_test_cros_ec_events(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       u32 events;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+       ut_assertok(cros_ec_get_host_events(dev, &events));
+       ut_asserteq(0, events);
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec events", 0));
+       ut_assert_nextline("00000000");
+       ut_assert_console_end();
+
+       /* Open the lid and check the event appears */
+       sandbox_cros_ec_set_test_flags(dev, CROSECT_LID_OPEN);
+       ut_assertok(cros_ec_get_host_events(dev, &events));
+       ut_asserteq(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN), events);
+
+       /* try the command */
+       console_record_reset();
+       ut_assertok(run_command("crosec events", 0));
+       ut_assert_nextline("00000002");
+       ut_assert_nextline("lid_open");
+       ut_assert_console_end();
+
+       /* Clear the event */
+       ut_assertok(cros_ec_clear_host_events(dev,
+               EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)));
+       ut_assertok(cros_ec_get_host_events(dev, &events));
+       ut_asserteq(0, events);
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_events, UT_TESTF_SCAN_FDT);
+
+static int dm_test_cros_ec_vstore(struct unit_test_state *uts)
+{
+       const int size = EC_VSTORE_SLOT_SIZE;
+       u8 test_data[size], data[size];
+       struct udevice *dev;
+       u32 locked;
+       int i;
+
+       ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
+       ut_asserteq(true, cros_ec_vstore_supported(dev));
+
+       ut_asserteq(4, cros_ec_vstore_info(dev, &locked));
+       ut_asserteq(0, locked);
+
+       /* Write some data */
+       for (i = 0; i < size; i++)
+               test_data[i] = ' ' + i;
+       ut_assertok(cros_ec_vstore_write(dev, 2, test_data, size));
+
+       /* Check it is locked */
+       ut_asserteq(4, cros_ec_vstore_info(dev, &locked));
+       ut_asserteq(1 << 2, locked);
+
+       /* Read it back and compare */
+       ut_assertok(cros_ec_vstore_read(dev, 2, data));
+       ut_asserteq_mem(test_data, data, size);
+
+       /* Try another slot to make sure it is empty */
+       ut_assertok(cros_ec_vstore_read(dev, 0, data));
+       for (i = 0; i < size; i++)
+               ut_asserteq(0, data[i]);
+
+       return 0;
+}
+DM_TEST(dm_test_cros_ec_vstore, UT_TESTF_SCAN_FDT);
diff --git a/test/dm/of_extra.c b/test/dm/of_extra.c
new file mode 100644 (file)
index 0000000..b19cd37
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_extra.h>
+#include <dm/test.h>
+#include <test/ut.h>
+#include <u-boot/sha256.h>
+
+static int dm_test_ofnode_read_fmap_entry(struct unit_test_state *uts)
+{
+       const char hash_expect[] = {
+               0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+               0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+               0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+       };
+       struct fmap_entry entry;
+       ofnode node;
+
+       node = ofnode_path("/cros-ec/flash/wp-ro");
+       ut_assertok(ofnode_read_fmap_entry(node, &entry));
+       ut_asserteq(0xf000, entry.offset);
+       ut_asserteq(0x1000, entry.length);
+       ut_asserteq(0x884, entry.used);
+       ut_asserteq(FMAP_COMPRESS_LZ4, entry.compress_algo);
+       ut_asserteq(0xcf8, entry.unc_length);
+       ut_asserteq(FMAP_HASH_SHA256, entry.hash_algo);
+       ut_asserteq(SHA256_SUM_LEN, entry.hash_size);
+       ut_asserteq_mem(hash_expect, entry.hash, SHA256_SUM_LEN);
+
+       return 0;
+}
+DM_TEST(dm_test_ofnode_read_fmap_entry, 0);
index cfc43a5..26c5092 100644 (file)
@@ -210,11 +210,11 @@ DM_TEST(dm_test_of_plat_phandle, UT_TESTF_SCAN_PDATA);
 /* Test that device parents are correctly set up */
 static int dm_test_of_plat_parent(struct unit_test_state *uts)
 {
-       struct udevice *rtc, *i2c;
+       struct udevice *dev, *bus;
 
-       ut_assertok(uclass_first_device_err(UCLASS_RTC, &rtc));
-       ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
-       ut_asserteq_ptr(i2c, dev_get_parent(rtc));
+       ut_assertok(uclass_first_device_err(UCLASS_SIMPLE_BUS, &bus));
+       ut_assertok(device_first_child_err(bus, &dev));
+       ut_asserteq_ptr(bus, dev_get_parent(dev));
 
        return 0;
 }
index a021ea9..a88453f 100644 (file)
@@ -20,6 +20,7 @@
 /kwboot
 /lib/
 /mips-relocs
+/mkeficapsule
 /mkenvimage
 /mkexynosspl
 /mkimage
index de1eedf..a00c902 100644 (file)
@@ -1050,10 +1050,9 @@ Some ideas:
 - Allow easy building of images by specifying just the board name
 - Support building an image for a board (-b) more completely, with a
   configurable build directory
-- Support adding FITs to an image
-- Support for ARM Trusted Firmware (ATF)
 - Detect invalid properties in nodes
 - Sort the fdtmap by offset
+- Output temporary files to a different directory
 
 --
 Simon Glass <sjg@chromium.org>
index 072417f..1952b2a 100644 (file)
@@ -244,7 +244,8 @@ def ExtractEntries(image_fname, output_fname, outdir, entry_paths,
             if not os.path.exists(fname):
                 os.makedirs(fname)
             fname = os.path.join(fname, 'root')
-        tout.Notice("Write entry '%s' to '%s'" % (entry.GetPath(), fname))
+        tout.Notice("Write entry '%s' size %x to '%s'" %
+                    (entry.GetPath(), len(data), fname))
         tools.WriteFile(fname, data)
     return einfos
 
index 249074a..03b49d7 100644 (file)
@@ -132,7 +132,8 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
                                  (msg, sym.size))
 
             # Look up the symbol in our entry tables.
-            value = section.LookupSymbol(name, sym.weak, msg, base.address)
+            value = section.GetImage().LookupImageSymbol(name, sym.weak, msg,
+                                                         base.address)
             if value is None:
                 value = -1
                 pack_string = pack_string.lower()
index e3d218a..7a12801 100644 (file)
@@ -45,10 +45,12 @@ class FakeSection:
     def GetPath(self):
         return 'section_path'
 
-    def LookupSymbol(self, name, weak, msg, base_addr):
+    def LookupImageSymbol(self, name, weak, msg, base_addr):
         """Fake implementation which returns the same value for all symbols"""
         return self.sym_value
 
+    def GetImage(self):
+        return self
 
 def BuildElfTestFiles(target_dir):
     """Build ELF files used for testing in binman
index 2be0d8e..d58a730 100644 (file)
@@ -434,8 +434,7 @@ class Entry(object):
                 missing.append(prop.name)
             values.append(value)
         if missing:
-            self.Raise('Missing required properties/entry args: %s' %
-                       (', '.join(missing)))
+            self.GetImage().MissingArgs(self, missing)
         return values
 
     def GetPath(self):
index 301ac55..81756c3 100644 (file)
@@ -66,3 +66,7 @@ class Entry_blob(Entry):
 
     def GetDefaultFilename(self):
         return self._filename
+
+    def ProcessContents(self):
+        # The blob may have changed due to WriteSymbols()
+        return self.ProcessContentsUpdate(self.data)
index ce3832e..1feebd0 100644 (file)
@@ -22,6 +22,7 @@ class Entry_files(Entry_section):
         - files-compress: Compression algorithm to use:
             none: No compression
             lz4: Use lz4 compression (via 'lz4' command-line utility)
+        - files-align: Align each file to the given alignment
 
     This entry reads a number of files and places each in a separate sub-entry
     within this entry. To access these you need to enable device-tree updates
@@ -38,6 +39,7 @@ class Entry_files(Entry_section):
             self.Raise("Missing 'pattern' property")
         self._files_compress = fdt_util.GetString(self._node, 'files-compress',
                                                   'none')
+        self._files_align = fdt_util.GetInt(self._node, 'files-align');
         self._require_matches = fdt_util.GetBool(self._node,
                                                 'require-matches')
 
@@ -55,6 +57,8 @@ class Entry_files(Entry_section):
             state.AddString(subnode, 'type', 'blob')
             state.AddString(subnode, 'filename', fname)
             state.AddString(subnode, 'compress', self._files_compress)
+            if self._files_align:
+                state.AddInt(subnode, 'align', self._files_align)
 
         # Read entries again, now that we have some
         self._ReadEntries()
index 3dd5f58..1ceadef 100644 (file)
@@ -385,7 +385,7 @@ class Entry_section(Entry):
                 return entry.GetData()
         source_entry.Raise("Cannot find entry for node '%s'" % node.name)
 
-    def LookupSymbol(self, sym_name, optional, msg, base_addr):
+    def LookupSymbol(self, sym_name, optional, msg, base_addr, entries=None):
         """Look up a symbol in an ELF file
 
         Looks up a symbol in an ELF file. Only entry types which come from an
@@ -428,18 +428,20 @@ class Entry_section(Entry):
                              (msg, sym_name))
         entry_name, prop_name = m.groups()
         entry_name = entry_name.replace('_', '-')
-        entry = self._entries.get(entry_name)
+        if not entries:
+            entries = self._entries
+        entry = entries.get(entry_name)
         if not entry:
             if entry_name.endswith('-any'):
                 root = entry_name[:-4]
-                for name in self._entries:
+                for name in entries:
                     if name.startswith(root):
                         rest = name[len(root):]
                         if rest in ['', '-img', '-nodtb']:
-                            entry = self._entries[name]
+                            entry = entries[name]
         if not entry:
             err = ("%s: Entry '%s' not found in list (%s)" %
-                   (msg, entry_name, ','.join(self._entries.keys())))
+                   (msg, entry_name, ','.join(entries.keys())))
             if optional:
                 print('Warning: %s' % err, file=sys.stderr)
                 return None
@@ -603,10 +605,12 @@ class Entry_section(Entry):
     def ReadData(self, decomp=True):
         tout.Info("ReadData path='%s'" % self.GetPath())
         parent_data = self.section.ReadData(True)
-        tout.Info('%s: Reading data from offset %#x-%#x, size %#x' %
-                  (self.GetPath(), self.offset, self.offset + self.size,
-                   self.size))
-        data = parent_data[self.offset:self.offset + self.size]
+        offset = self.offset - self.section._skip_at_start
+        data = parent_data[offset:offset + self.size]
+        tout.Info(
+            '%s: Reading data from offset %#x-%#x (real %#x), size %#x, got %#x' %
+                  (self.GetPath(), self.offset, self.offset + self.size, offset,
+                   self.size, len(data)))
         return data
 
     def ReadChildData(self, child, decomp=True):
@@ -648,3 +652,47 @@ class Entry_section(Entry):
         """
         for entry in self._entries.values():
             entry.CheckMissing(missing_list)
+
+    def _CollectEntries(self, entries, entries_by_name, add_entry):
+        """Collect all the entries in an section
+
+        This builds up a dict of entries in this section and all subsections.
+        Entries are indexed by path and by name.
+
+        Since all paths are unique, entries will not have any conflicts. However
+        entries_by_name make have conflicts if two entries have the same name
+        (e.g. with different parent sections). In this case, an entry at a
+        higher level in the hierarchy will win over a lower-level entry.
+
+        Args:
+            entries: dict to put entries:
+                key: entry path
+                value: Entry object
+            entries_by_name: dict to put entries
+                key: entry name
+                value: Entry object
+            add_entry: Entry to add
+        """
+        entries[add_entry.GetPath()] = add_entry
+        to_add = add_entry.GetEntries()
+        if to_add:
+            for entry in to_add.values():
+                entries[entry.GetPath()] = entry
+            for entry in to_add.values():
+                self._CollectEntries(entries, entries_by_name, entry)
+        entries_by_name[add_entry.name] = add_entry
+
+    def MissingArgs(self, entry, missing):
+        """Report a missing argument, if enabled
+
+        For entries which require arguments, this reports an error if some are
+        missing. If missing entries are being ignored (e.g. because we read the
+        entry from an image rather than creating it), this function does
+        nothing.
+
+        Args:
+            missing: List of missing properties / entry args, each a string
+        """
+        if not self._ignore_missing:
+            entry.Raise('Missing required properties/entry args: %s' %
+                       (', '.join(missing)))
index 596b2be..df15cd2 100644 (file)
@@ -9,7 +9,6 @@
 
 from binman import elf
 from binman.entry import Entry
-from patman import command
 from binman.etype.blob import Entry_blob
 from patman import tools
 
index 6f45293..c154cfd 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright (c) 2016 Google, Inc
 # Written by Simon Glass <sjg@chromium.org>
 #
-# Entry-type module for 'u-boot-nodtb.bin'
+# Entry-type module for 'u-boot-spl-nodtb.bin'
 #
 
 from binman.entry import Entry
index f734fba..eba5351 100644 (file)
@@ -49,7 +49,7 @@ class Entry_vblock(Entry):
             EntryArg('kernelkey', str),
             EntryArg('preamble-flags', int)])
 
-    def ObtainContents(self):
+    def GetVblock(self):
         # Join up the data files to be signed
         input_data = b''
         for entry_phandle in self.content:
@@ -76,5 +76,16 @@ class Entry_vblock(Entry):
         ]
         #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
         stdout = tools.Run('futility', *args)
-        self.SetContents(tools.ReadFile(output_fname))
+        return tools.ReadFile(output_fname)
+
+    def ObtainContents(self):
+        data = self.GetVblock()
+        if data is False:
+            return False
+        self.SetContents(data)
         return True
+
+    def ProcessContents(self):
+        # The blob may have changed due to WriteSymbols()
+        data = self.GetVblock()
+        return self.ProcessContentsUpdate(data)
index b03fc28..8277619 100644 (file)
@@ -53,8 +53,8 @@ FmapArea = collections.namedtuple('FmapArea', FMAP_AREA_NAMES)
 
 
 def NameToFmap(name):
-    if type(name) == bytes and sys.version_info[0] >= 3:
-        name = name.decode('utf-8')  # pragma: no cover (for Python 2)
+    if type(name) == bytes:
+        name = name.decode('utf-8')
     return name.replace('\0', '').replace('-', '_').upper()
 
 def ConvertName(field_names, fields):
index e753a34..814e91d 100644 (file)
@@ -1638,15 +1638,37 @@ class TestFunctional(unittest.TestCase):
                       str(e.exception))
 
     def _HandleVblockCommand(self, pipe_list):
-        """Fake calls to the futility utility"""
+        """Fake calls to the futility utility
+
+        The expected pipe is:
+
+           [('futility', 'vbutil_firmware', '--vblock',
+             'vblock.vblock', '--keyblock', 'devkeys/firmware.keyblock',
+             '--signprivate', 'devkeys/firmware_data_key.vbprivk',
+             '--version', '1', '--fv', 'input.vblock', '--kernelkey',
+             'devkeys/kernel_subkey.vbpubk', '--flags', '1')]
+
+        This writes to the output file (here, 'vblock.vblock'). If
+        self._hash_data is False, it writes VBLOCK_DATA, else it writes a hash
+        of the input data (here, 'input.vblock').
+        """
         if pipe_list[0][0] == 'futility':
             fname = pipe_list[0][3]
             with open(fname, 'wb') as fd:
-                fd.write(VBLOCK_DATA)
+                if self._hash_data:
+                    infile = pipe_list[0][11]
+                    m = hashlib.sha256()
+                    data = tools.ReadFile(infile)
+                    m.update(data)
+                    fd.write(m.digest())
+                else:
+                    fd.write(VBLOCK_DATA)
+
             return command.CommandResult()
 
     def testVblock(self):
         """Test for the Chromium OS Verified Boot Block"""
+        self._hash_data = False
         command.test_result = self._HandleVblockCommand
         entry_args = {
             'keydir': 'devkeys',
@@ -1677,6 +1699,29 @@ class TestFunctional(unittest.TestCase):
         self.assertIn("Node '/binman/vblock': Cannot find entry for node "
                       "'other'", str(e.exception))
 
+    def testVblockContent(self):
+        """Test that the vblock signs the right data"""
+        self._hash_data = True
+        command.test_result = self._HandleVblockCommand
+        entry_args = {
+            'keydir': 'devkeys',
+        }
+        data = self._DoReadFileDtb(
+            '189_vblock_content.dts', use_real_dtb=True, update_dtb=True,
+            entry_args=entry_args)[0]
+        hashlen = 32  # SHA256 hash is 32 bytes
+        self.assertEqual(U_BOOT_DATA, data[:len(U_BOOT_DATA)])
+        hashval = data[-hashlen:]
+        dtb = data[len(U_BOOT_DATA):-hashlen]
+
+        expected_data = U_BOOT_DATA + dtb
+
+        # The hashval should be a hash of the dtb
+        m = hashlib.sha256()
+        m.update(expected_data)
+        expected_hashval = m.digest()
+        self.assertEqual(expected_hashval, hashval)
+
     def testTpl(self):
         """Test that an image with TPL and its device tree can be created"""
         # ELF file with a '__bss_size' symbol
@@ -4139,6 +4184,67 @@ class TestFunctional(unittest.TestCase):
             }
         self.assertEqual(expected, props)
 
+    def testSymbolsSubsection(self):
+        """Test binman can assign symbols from a subsection"""
+        elf_fname = self.ElfTestFile('u_boot_binman_syms')
+        syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
+        addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start')
+        self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr)
+
+        self._SetupSplElf('u_boot_binman_syms')
+        data = self._DoReadFile('187_symbols_sub.dts')
+        sym_values = struct.pack('<LQLL', 0x00, 0x1c, 0x28, 0x04)
+        expected = (sym_values + U_BOOT_SPL_DATA[20:] +
+                    tools.GetBytes(0xff, 1) + U_BOOT_DATA + sym_values +
+                    U_BOOT_SPL_DATA[20:])
+        self.assertEqual(expected, data)
+
+    def testReadImageEntryArg(self):
+        """Test reading an image that would need an entry arg to generate"""
+        entry_args = {
+            'cros-ec-rw-path': 'ecrw.bin',
+        }
+        data = self.data = self._DoReadFileDtb(
+            '188_image_entryarg.dts',use_real_dtb=True, update_dtb=True,
+            entry_args=entry_args)
+
+        image_fname = tools.GetOutputFilename('image.bin')
+        orig_image = control.images['image']
+
+        # This should not generate an error about the missing 'cros-ec-rw-path'
+        # since we are reading the image from a file. Compare with
+        # testEntryArgsRequired()
+        image = Image.FromFile(image_fname)
+        self.assertEqual(orig_image.GetEntries().keys(),
+                         image.GetEntries().keys())
+
+    def testFilesAlign(self):
+        """Test alignment with files"""
+        data = self._DoReadFile('190_files_align.dts')
+
+        # The first string is 15 bytes so will align to 16
+        expect = FILES_DATA[:15] + b'\0' + FILES_DATA[15:]
+        self.assertEqual(expect, data)
+
+    def testReadImageSkip(self):
+        """Test reading an image and accessing its FDT map"""
+        data = self.data = self._DoReadFileRealDtb('191_read_image_skip.dts')
+        image_fname = tools.GetOutputFilename('image.bin')
+        orig_image = control.images['image']
+        image = Image.FromFile(image_fname)
+        self.assertEqual(orig_image.GetEntries().keys(),
+                         image.GetEntries().keys())
+
+        orig_entry = orig_image.GetEntries()['fdtmap']
+        entry = image.GetEntries()['fdtmap']
+        self.assertEqual(orig_entry.offset, entry.offset)
+        self.assertEqual(orig_entry.size, entry.size)
+        self.assertEqual(16, entry.image_pos)
+
+        u_boot = image.GetEntries()['section'].GetEntries()['u-boot']
+
+        self.assertEquals(U_BOOT_DATA, u_boot.ReadData())
+
 
 if __name__ == "__main__":
     unittest.main()
index d65ab88..e949435 100644 (file)
@@ -43,8 +43,13 @@ class Image(section.Entry_section):
         test: True if this is being called from a test of Images. This this case
             there is no device tree defining the structure of the section, so
             we create a section manually.
+        ignore_missing: Ignore any missing entry arguments (i.e. don't raise an
+            exception). This should be used if the Image is being loaded from
+            a file rather than generated. In that case we obviously don't need
+            the entry arguments since the contents already exists.
     """
-    def __init__(self, name, node, copy_to_orig=True, test=False):
+    def __init__(self, name, node, copy_to_orig=True, test=False,
+                 ignore_missing=False):
         super().__init__(None, 'section', node, test=test)
         self.copy_to_orig = copy_to_orig
         self.name = 'main-section'
@@ -53,6 +58,7 @@ class Image(section.Entry_section):
         self.fdtmap_dtb = None
         self.fdtmap_data = None
         self.allow_repack = False
+        self._ignore_missing = ignore_missing
         if not test:
             self.ReadNode()
 
@@ -100,7 +106,7 @@ class Image(section.Entry_section):
 
         # Return an Image with the associated nodes
         root = dtb.GetRoot()
-        image = Image('image', root, copy_to_orig=False)
+        image = Image('image', root, copy_to_orig=False, ignore_missing=True)
 
         image.image_node = fdt_util.GetString(root, 'image-node', 'image')
         image.fdtmap_dtb = dtb
@@ -130,12 +136,7 @@ class Image(section.Entry_section):
         Returns:
             True if the new data size is OK, False if expansion is needed
         """
-        sizes_ok = True
-        for entry in self._entries.values():
-            if not entry.ProcessContents():
-                sizes_ok = False
-                tout.Debug("Entry '%s' size change" % self._node.path)
-        return sizes_ok
+        return super().ProcessContents()
 
     def WriteSymbols(self):
         """Write symbol values into binary files for access at run time"""
@@ -324,3 +325,48 @@ class Image(section.Entry_section):
             _DoLine(lines, _EntryToStrings(entry))
             selected_entries.append(entry)
         return selected_entries, lines, widths
+
+    def LookupImageSymbol(self, sym_name, optional, msg, base_addr):
+        """Look up a symbol in an ELF file
+
+        Looks up a symbol in an ELF file. Only entry types which come from an
+        ELF image can be used by this function.
+
+        This searches through this image including all of its subsections.
+
+        At present the only entry properties supported are:
+            offset
+            image_pos - 'base_addr' is added if this is not an end-at-4gb image
+            size
+
+        Args:
+            sym_name: Symbol name in the ELF file to look up in the format
+                _binman_<entry>_prop_<property> where <entry> is the name of
+                the entry and <property> is the property to find (e.g.
+                _binman_u_boot_prop_offset). As a special case, you can append
+                _any to <entry> to have it search for any matching entry. E.g.
+                _binman_u_boot_any_prop_offset will match entries called u-boot,
+                u-boot-img and u-boot-nodtb)
+            optional: True if the symbol is optional. If False this function
+                will raise if the symbol is not found
+            msg: Message to display if an error occurs
+            base_addr: Base address of image. This is added to the returned
+                image_pos in most cases so that the returned position indicates
+                where the targeted entry/binary has actually been loaded. But
+                if end-at-4gb is used, this is not done, since the binary is
+                already assumed to be linked to the ROM position and using
+                execute-in-place (XIP).
+
+        Returns:
+            Value that should be assigned to that symbol, or None if it was
+                optional and not found
+
+        Raises:
+            ValueError if the symbol is invalid or not found, or references a
+                property which is not supported
+        """
+        entries = OrderedDict()
+        entries_by_name = {}
+        self._CollectEntries(entries, entries_by_name, self)
+        return self.LookupSymbol(sym_name, optional, msg, base_addr,
+                                 entries_by_name)
index 36bc513..bb3e36e 100644 (file)
@@ -314,6 +314,16 @@ def AddString(node, prop, value):
     for n in GetUpdateNodes(node):
         n.AddString(prop, value)
 
+def AddInt(node, prop, value):
+    """Add a new string property to affected device trees
+
+    Args:
+        prop_name: Name of property
+        val: Integer value of property
+    """
+    for n in GetUpdateNodes(node):
+        n.AddInt(prop, value)
+
 def SetInt(node, prop, value, for_repack=False):
     """Update an integer property in affected device trees with an integer value
 
index 83ddb78..8f09afd 100644 (file)
@@ -5,7 +5,7 @@
        binman {
                files {
                        pattern = "files/*.dat";
-                       compress = "none";
+                       files-compress = "none";
                };
        };
 };
diff --git a/tools/binman/test/187_symbols_sub.dts b/tools/binman/test/187_symbols_sub.dts
new file mode 100644 (file)
index 0000000..54511a7
--- /dev/null
@@ -0,0 +1,22 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               section {
+                       pad-byte = <0xff>;
+                       u-boot-spl {
+                       };
+
+                       u-boot {
+                               offset = <24>;
+                       };
+               };
+
+               u-boot-spl2 {
+                       type = "u-boot-spl";
+               };
+       };
+};
diff --git a/tools/binman/test/188_image_entryarg.dts b/tools/binman/test/188_image_entryarg.dts
new file mode 100644 (file)
index 0000000..29d8149
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               size = <0xc00>;
+               u-boot {
+               };
+               cros-ec-rw {
+               };
+               fdtmap {
+               };
+               image-header {
+                       location = "end";
+               };
+       };
+};
diff --git a/tools/binman/test/189_vblock_content.dts b/tools/binman/test/189_vblock_content.dts
new file mode 100644 (file)
index 0000000..dcc7444
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u_boot: u-boot {
+               };
+
+               dtb: u-boot-dtb {
+               };
+
+               /*
+                * Put the vblock after the dtb so that the dtb is updated
+                * before the vblock reads its data. At present binman does not
+                * understand dependencies between entries, but simply
+                * iterates again when it thinks something needs to be
+                * recalculated.
+                */
+               vblock {
+                       content = <&u_boot &dtb>;
+                       keyblock = "firmware.keyblock";
+                       signprivate = "firmware_data_key.vbprivk";
+                       version = <1>;
+                       kernelkey = "kernel_subkey.vbpubk";
+                       preamble-flags = <1>;
+               };
+       };
+};
diff --git a/tools/binman/test/190_files_align.dts b/tools/binman/test/190_files_align.dts
new file mode 100644 (file)
index 0000000..213ba96
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+       binman {
+               files {
+                       pattern = "files/*.dat";
+                       files-compress = "none";
+                       files-align = <4>;
+               };
+       };
+};
diff --git a/tools/binman/test/191_read_image_skip.dts b/tools/binman/test/191_read_image_skip.dts
new file mode 100644 (file)
index 0000000..31df518
--- /dev/null
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               end-at-4gb;
+               size = <0x400>;
+               section {
+                       size = <0x10>;
+                       u-boot {
+                       };
+               };
+               fdtmap {
+               };
+               image-header {
+                       location = "end";
+               };
+       };
+};
index 4a78c73..25ce513 100644 (file)
@@ -460,10 +460,21 @@ class Node:
             prop_name: Name of property to add
             val: String value of property
         """
-        if sys.version_info[0] >= 3:  # pragma: no cover
-            val = bytes(val, 'utf-8')
+        val = bytes(val, 'utf-8')
         self.AddData(prop_name, val + b'\0')
 
+    def AddInt(self, prop_name, val):
+        """Add a new integer property to a node
+
+        The device tree is marked dirty so that the value will be written to
+        the blob on the next sync.
+
+        Args:
+            prop_name: Name of property to add
+            val: Integer value of property
+        """
+        self.AddData(prop_name, struct.pack('>I', val))
+
     def AddSubnode(self, name):
         """Add a new subnode to the node
 
index dc6943f..e8fbbd5 100755 (executable)
@@ -397,6 +397,12 @@ class TestProp(unittest.TestCase):
         data = self.fdt.getprop(self.node.Offset(), 'one')
         self.assertEqual(1, fdt32_to_cpu(data))
 
+        val = 1234
+        self.node.AddInt('integer', val)
+        self.dtb.Sync(auto_resize=True)
+        data = self.fdt.getprop(self.node.Offset(), 'integer')
+        self.assertEqual(val, fdt32_to_cpu(data))
+
         val = '123' + chr(0) + '456'
         self.node.AddString('string', val)
         self.dtb.Sync(auto_resize=True)
index d8e01a3..10997e4 100644 (file)
@@ -476,7 +476,8 @@ def Compress(indata, algo, with_header=True):
     fname = GetOutputFilename('%s.comp.tmp' % algo)
     WriteFile(fname, indata)
     if algo == 'lz4':
-        data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True)
+        data = Run('lz4', '--no-frame-crc', '-B4', '-5', '-c', fname,
+                   binary=True)
     # cbfstool uses a very old version of lzma
     elif algo == 'lzma':
         outfname = GetOutputFilename('%s.comp.otmp' % algo)