aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sandbox/config.mk5
-rw-r--r--arch/sandbox/cpu/spl.c3
-rw-r--r--arch/sandbox/cpu/state.c1
-rw-r--r--arch/sandbox/dts/sandbox.dts336
-rw-r--r--arch/sandbox/dts/sandbox.dtsi364
-rw-r--r--arch/sandbox/dts/sandbox64.dts275
-rw-r--r--arch/sandbox/dts/test.dts8
-rw-r--r--arch/sandbox/include/asm/test.h13
-rw-r--r--arch/x86/include/asm/coreboot_tables.h2
-rw-r--r--board/sandbox/README.sandbox21
-rw-r--r--cmd/trace.c10
-rw-r--r--common/Kconfig7
-rw-r--r--common/board_f.c6
-rw-r--r--doc/README.SPL16
-rw-r--r--doc/README.TPL4
-rw-r--r--doc/driver-model/README.txt4
-rw-r--r--drivers/block/Kconfig7
-rw-r--r--drivers/core/util.c2
-rw-r--r--drivers/misc/swap_case.c102
-rw-r--r--drivers/pci/pci-uclass.c70
-rw-r--r--drivers/serial/serial_lpuart.c4
-rw-r--r--drivers/spi/Kconfig2
-rw-r--r--drivers/spi/spi-mem.c15
-rw-r--r--drivers/sysreset/sysreset_sandbox.c1
-rw-r--r--drivers/video/video-uclass.c4
-rw-r--r--include/configs/sandbox.h4
-rw-r--r--include/dm/ofnode.h6
-rw-r--r--include/dm/util.h6
-rw-r--r--include/pci.h35
-rw-r--r--include/trace.h6
-rw-r--r--lib/Kconfig15
-rw-r--r--lib/fdtdec_test.c2
-rw-r--r--lib/hang.c3
-rw-r--r--lib/trace.c67
-rw-r--r--test/dm/pci.c49
-rw-r--r--test/py/tests/test_ofplatdata.py28
-rw-r--r--tools/binman/README14
-rw-r--r--tools/binman/README.entries15
-rwxr-xr-xtools/binman/binman.py26
-rw-r--r--tools/binman/bsection.py7
-rw-r--r--tools/binman/control.py15
-rw-r--r--tools/binman/elf.py4
-rw-r--r--tools/binman/elf_test.py5
-rw-r--r--tools/binman/entry.py5
-rw-r--r--tools/binman/entry_test.py6
-rw-r--r--tools/binman/etype/_testing.py2
-rw-r--r--tools/binman/etype/blob.py2
-rw-r--r--tools/binman/etype/fill.py4
-rw-r--r--tools/binman/etype/fmap.py3
-rw-r--r--tools/binman/etype/gbb.py2
-rw-r--r--tools/binman/etype/text.py9
-rw-r--r--tools/binman/etype/u_boot_dtb_with_ucode.py4
-rw-r--r--tools/binman/etype/u_boot_spl_bss_pad.py2
-rw-r--r--tools/binman/etype/u_boot_ucode.py4
-rw-r--r--tools/binman/etype/vblock.py2
-rw-r--r--tools/binman/fmap_util.py12
-rw-r--r--tools/binman/ftest.py213
-rw-r--r--tools/binman/state.py7
-rw-r--r--tools/dtoc/dtb_platdata.py10
-rwxr-xr-xtools/dtoc/dtoc.py8
-rw-r--r--tools/dtoc/fdt.py148
-rw-r--r--tools/dtoc/fdt_util.py15
-rw-r--r--tools/dtoc/test_dtoc.py16
-rwxr-xr-xtools/dtoc/test_fdt.py52
-rw-r--r--tools/patman/cros_subprocess.py50
-rw-r--r--tools/patman/func_test.py41
-rw-r--r--tools/patman/gitutil.py16
-rwxr-xr-xtools/patman/patman.py2
-rw-r--r--tools/patman/series.py20
-rw-r--r--tools/patman/settings.py34
-rw-r--r--tools/patman/test_util.py27
-rw-r--r--tools/patman/tools.py111
-rw-r--r--tools/proftool.c4
-rwxr-xr-xtools/rmboard.py150
74 files changed, 1580 insertions, 990 deletions
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 31a12db103d..05fbbd7bcc7 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -5,14 +5,15 @@ PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
PLATFORM_CPPFLAGS += -fPIC
PLATFORM_LIBS += -lrt
+SDL_CONFIG ?= sdl-config
# Define this to avoid linking with SDL, which requires SDL libraries
# This can solve 'sdl-config: Command not found' errors
ifneq ($(NO_SDL),)
PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL
else
-PLATFORM_LIBS += $(shell sdl-config --libs)
-PLATFORM_CPPFLAGS += $(shell sdl-config --cflags)
+PLATFORM_LIBS += $(shell $(SDL_CONFIG) --libs)
+PLATFORM_CPPFLAGS += $(shell $(SDL_CONFIG) --cflags)
endif
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 2ca4cd6e35e..4f415c71d63 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -12,6 +12,7 @@
DECLARE_GLOBAL_DATA_PTR;
+/* SPL / TPL init function */
void board_init_f(ulong flag)
{
struct sandbox_state *state = state_get_current();
@@ -44,7 +45,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
return 0;
}
-SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
+SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_image);
void spl_board_init(void)
{
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index d3b9c059859..2333240fda8 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -356,6 +356,7 @@ void state_reset_for_test(struct sandbox_state *state)
/* No reset yet, so mark it as such. Always allow power reset */
state->last_sysreset = SYSRESET_COUNT;
state->sysreset_allowed[SYSRESET_POWER] = true;
+ state->sysreset_allowed[SYSRESET_POWER_OFF] = true;
memset(&state->wdt, '\0', sizeof(state->wdt));
memset(state->spi, '\0', sizeof(state->spi));
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index a41b5f052d7..16a33db87d3 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-#define USB_CLASS_HUB 9
+#include <config.h>
/ {
#address-cells = <1>;
@@ -12,46 +12,17 @@
pci0 = &pci;
rtc0 = &rtc_0;
axi0 = &axi;
+ spi0 = &spi;
};
- chosen {
- stdout-path = "/serial";
- };
-
- audio: audio-codec {
- compatible = "sandbox,audio-codec";
- #sound-dai-cells = <1>;
+ memory {
+ reg = <0 CONFIG_SYS_SDRAM_SIZE>;
};
cros_ec: cros-ec {
reg = <0 0>;
u-boot,dm-pre-reloc;
compatible = "google,cros-ec-sandbox";
-
- /*
- * This describes the flash memory within the EC. Note
- * that the STM32L flash erases to 0, not 0xff.
- */
- flash {
- u-boot,dm-pre-reloc;
- image-pos = <0x08000000>;
- size = <0x20000>;
- erase-value = <0>;
-
- /* Information for sandbox */
- ro {
- image-pos = <0>;
- size = <0xf000>;
- };
- wp-ro {
- image-pos = <0xf000>;
- size = <0x1000>;
- };
- rw {
- image-pos = <0x10000>;
- size = <0x10000>;
- };
- };
};
ethrawbus {
@@ -65,30 +36,6 @@
fake-host-hwaddr = [00 00 66 44 22 00];
};
- gpio_a: gpios@0 {
- u-boot,dm-pre-reloc;
- gpio-controller;
- compatible = "sandbox,gpio";
- #gpio-cells = <1>;
- gpio-bank-name = "a";
- sandbox,gpio-count = <20>;
- };
-
- gpio_b: gpios@1 {
- u-boot,dm-pre-reloc;
- gpio-controller;
- compatible = "sandbox,gpio";
- #gpio-cells = <2>;
- gpio-bank-name = "b";
- sandbox,gpio-count = <10>;
- };
-
- hexagon {
- compatible = "demo-simple";
- colour = "white";
- sides = <6>;
- };
-
i2c_0: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -97,63 +44,6 @@
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
- eeprom@2c {
- reg = <0x2c>;
- compatible = "i2c-eeprom";
- sandbox,emul = <&emul_eeprom>;
- };
-
- rtc_0: rtc@43 {
- reg = <0x43>;
- compatible = "sandbox-rtc";
- sandbox,emul = <&emul0>;
- };
- sandbox_pmic: sandbox_pmic {
- reg = <0x40>;
- };
-
- mc34708: pmic@41 {
- reg = <0x41>;
- };
-
- i2c_emul: emul {
- reg = <0xff>;
- compatible = "sandbox,i2c-emul-parent";
- emul_eeprom: emul-eeprom {
- compatible = "sandbox,i2c-eeprom";
- sandbox,filename = "i2c.bin";
- sandbox,size = <256>;
- };
- emul0: emul0 {
- compatible = "sandbox,i2c-rtc";
- };
- };
- };
-
- i2s: i2s {
- compatible = "sandbox,i2s";
- #sound-dai-cells = <1>;
- };
-
- lcd {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,lcd-sdl";
- xres = <1366>;
- yres = <768>;
- };
-
- leds {
- compatible = "gpio-leds";
-
- iracibble {
- gpios = <&gpio_a 1 0>;
- label = "sandbox:red";
- };
-
- martinet {
- gpios = <&gpio_a 2 0>;
- label = "sandbox:green";
- };
};
pci: pci-controller {
@@ -163,233 +53,19 @@
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
0x01000000 0 0x20000000 0x20000000 0 0x2000>;
- pci@1f,0 {
- compatible = "pci-generic";
- reg = <0xf800 0 0 0 0>;
- emul@1f,0 {
- compatible = "sandbox,swap-case";
- };
- };
- };
-
- pinctrl {
- compatible = "sandbox,pinctrl";
- status = "okay";
-
- pinctrl_i2c0: i2c0 {
- groups = "i2c";
- function = "i2c";
- bias-pull-up;
- };
-
- pinctrl_serial0: uart0 {
- groups = "serial_a";
- function = "serial";
- };
-
- pinctrl_onewire0: onewire0 {
- groups = "w1";
- function = "w1";
- bias-pull-up;
- };
- };
-
- reset@1 {
- compatible = "sandbox,reset";
};
- sound {
- compatible = "sandbox,sound";
- cpu {
- sound-dai = <&i2s 0>;
- };
-
- codec {
- sound-dai = <&audio 0>;
- };
- };
-
- spi@0 {
+ spi: spi@0 {
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
- firmware_storage_spi: flash@0 {
- u-boot,dm-pre-reloc;
- reg = <0>;
- compatible = "spansion,m25p16", "sandbox,spi-flash";
- spi-max-frequency = <40000000>;
- sandbox,filename = "spi.bin";
- };
- };
-
- spl-test {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- boolval;
- intval = <1>;
- intarray = <2 3 4>;
- byteval = [05];
- bytearray = [06];
- longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
- stringval = "message";
- stringarray = "multi-word", "message";
- };
-
- spl-test2 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- intval = <3>;
- intarray = <5>;
- byteval = [08];
- bytearray = [01 23 34];
- longbytearray = [09 0a 0b 0c];
- stringval = "message2";
- stringarray = "another", "multi-word", "message";
};
- spl-test3 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- stringarray = "one";
- };
-
- spl-test4 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test.2";
- };
-
- square {
- compatible = "demo-shape";
- colour = "blue";
- sides = <4>;
- };
-
- timer {
- compatible = "sandbox,timer";
- clock-frequency = <1000000>;
- };
-
- tpm {
- u-boot,dm-pre-reloc;
- compatible = "google,sandbox-tpm";
- };
-
- tpm2 {
- compatible = "sandbox,tpm2";
- };
-
- triangle {
- compatible = "demo-shape";
- colour = "cyan";
- sides = <3>;
- character = <83>;
- light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
- };
-
- /* Needs to be available prior to relocation */
- uart0: serial {
- u-boot,dm-spl;
- compatible = "sandbox,serial";
- sandbox,text-colour = "cyan";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_serial0>;
- };
-
- usb@0 {
- compatible = "sandbox,usb";
- status = "disabled";
- hub {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- };
- };
- };
-
- usb@1 {
- compatible = "sandbox,usb";
- hub {
- compatible = "usb-hub";
- usb,device-class = <USB_CLASS_HUB>;
- hub-emul {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- sandbox,filepath = "flash.bin";
- };
- };
- };
- };
-
- usb@2 {
- compatible = "sandbox,usb";
- status = "disabled";
- };
-
- spmi: spmi@0 {
- compatible = "sandbox,spmi";
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- pm8916@0 {
- compatible = "qcom,spmi-pmic";
- reg = <0x0 0x1>;
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
- spmi_gpios: gpios@c000 {
- compatible = "qcom,pm8916-gpio";
- reg = <0xc000 0x400>;
- gpio-controller;
- gpio-count = <4>;
- #gpio-cells = <2>;
- gpio-bank-name="spmi";
- };
- };
- };
-
- axi: axi@0 {
- compatible = "sandbox,axi";
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- store@0 {
- compatible = "sandbox,sandbox_store";
- reg = <0x0 0x400>;
- };
- };
-
- onewire0: onewire {
- compatible = "w1-gpio";
- gpios = <&gpio_a 8>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_onewire0>;
- status = "okay";
-
- sandbox_eeprom0: sandbox_eeprom@0 {
- compatible = "sandbox,w1-eeprom";
- status = "okay";
- };
- };
-
- sandbox_tee {
- compatible = "sandbox,tee";
- };
};
+#include "sandbox.dtsi"
#include "cros-ec-keyboard.dtsi"
#include "sandbox_pmic.dtsi"
-
-&cros_ec {
- u-boot,dm-pre-reloc;
- keyboard-controller {
- u-boot,dm-pre-reloc;
- };
-};
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
new file mode 100644
index 00000000000..c6d5650c20b
--- /dev/null
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -0,0 +1,364 @@
+/*
+ * This is the common sandbox device-tree nodes. This is shared between sandbox
+ * and sandbox64 builds.
+ */
+
+#define USB_CLASS_HUB 9
+
+/ {
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ audio: audio-codec {
+ compatible = "sandbox,audio-codec";
+ #sound-dai-cells = <1>;
+ };
+
+ gpio_a: gpios@0 {
+ u-boot,dm-pre-reloc;
+ gpio-controller;
+ compatible = "sandbox,gpio";
+ #gpio-cells = <1>;
+ gpio-bank-name = "a";
+ sandbox,gpio-count = <20>;
+ };
+
+ gpio_b: gpios@1 {
+ u-boot,dm-pre-reloc;
+ gpio-controller;
+ compatible = "sandbox,gpio";
+ #gpio-cells = <2>;
+ gpio-bank-name = "b";
+ sandbox,gpio-count = <10>;
+ };
+
+ hexagon {
+ compatible = "demo-simple";
+ colour = "white";
+ sides = <6>;
+ };
+
+ i2c_0: i2c@0 {
+ eeprom@2c {
+ reg = <0x2c>;
+ compatible = "i2c-eeprom";
+ sandbox,emul = <&emul_eeprom>;
+ };
+
+ rtc_0: rtc@43 {
+ reg = <0x43>;
+ compatible = "sandbox-rtc";
+ sandbox,emul = <&emul0>;
+ };
+ sandbox_pmic: sandbox_pmic {
+ reg = <0x40>;
+ };
+
+ mc34708: pmic@41 {
+ reg = <0x41>;
+ };
+
+ i2c_emul: emul {
+ reg = <0xff>;
+ compatible = "sandbox,i2c-emul-parent";
+ emul_eeprom: emul-eeprom {
+ compatible = "sandbox,i2c-eeprom";
+ sandbox,filename = "i2c.bin";
+ sandbox,size = <256>;
+ };
+ emul0: emul0 {
+ compatible = "sandbox,i2c-rtc";
+ };
+ };
+ };
+
+ i2s: i2s {
+ compatible = "sandbox,i2s";
+ #sound-dai-cells = <1>;
+ };
+
+ lcd {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,lcd-sdl";
+ xres = <1366>;
+ yres = <768>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ iracibble {
+ gpios = <&gpio_a 1 0>;
+ label = "sandbox:red";
+ };
+
+ martinet {
+ gpios = <&gpio_a 2 0>;
+ label = "sandbox:green";
+ };
+ };
+
+ pci-controller {
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+ };
+
+ pinctrl {
+ compatible = "sandbox,pinctrl";
+ status = "okay";
+
+ pinctrl_i2c0: i2c0 {
+ groups = "i2c";
+ function = "i2c";
+ bias-pull-up;
+ };
+
+ pinctrl_serial0: uart0 {
+ groups = "serial_a";
+ function = "serial";
+ };
+
+ pinctrl_onewire0: onewire0 {
+ groups = "w1";
+ function = "w1";
+ bias-pull-up;
+ };
+ };
+
+ reset@1 {
+ compatible = "sandbox,reset";
+ };
+
+ sound {
+ compatible = "sandbox,sound";
+ cpu {
+ sound-dai = <&i2s 0>;
+ };
+
+ codec {
+ sound-dai = <&audio 0>;
+ };
+ };
+
+ spi@0 {
+ firmware_storage_spi: flash@0 {
+ u-boot,dm-pre-reloc;
+ reg = <0>;
+ compatible = "spansion,m25p16", "jedec,spi-nor";
+ spi-max-frequency = <40000000>;
+ sandbox,filename = "spi.bin";
+ };
+ };
+
+ spl-test {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ boolval;
+ intval = <1>;
+ intarray = <2 3 4>;
+ byteval = [05];
+ bytearray = [06];
+ longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+ stringval = "message";
+ stringarray = "multi-word", "message";
+ };
+
+ spl-test2 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ intval = <3>;
+ intarray = <5>;
+ byteval = [08];
+ bytearray = [01 23 34];
+ longbytearray = [09 0a 0b 0c];
+ stringval = "message2";
+ stringarray = "another", "multi-word", "message";
+ };
+
+ spl-test3 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test";
+ stringarray = "one";
+ };
+
+ spl-test4 {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,spl-test.2";
+ };
+
+ spl-test5 {
+ u-boot,dm-tpl;
+ compatible = "sandbox,spl-test";
+ stringarray = "tpl";
+ };
+
+ spl-test6 {
+ u-boot,dm-pre-proper;
+ compatible = "sandbox,spl-test";
+ stringarray = "pre-proper";
+ };
+
+ spl-test7 {
+ u-boot,dm-spl;
+ compatible = "sandbox,spl-test";
+ stringarray = "spl";
+ };
+
+ square {
+ compatible = "demo-shape";
+ colour = "blue";
+ sides = <4>;
+ };
+
+ timer {
+ compatible = "sandbox,timer";
+ clock-frequency = <1000000>;
+ };
+
+ tpm {
+ u-boot,dm-pre-reloc;
+ compatible = "google,sandbox-tpm";
+ };
+
+ tpm2 {
+ compatible = "sandbox,tpm2";
+ };
+
+ triangle {
+ compatible = "demo-shape";
+ colour = "cyan";
+ sides = <3>;
+ character = <83>;
+ light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
+ };
+
+ /* Needs to be available prior to relocation */
+ uart0: serial {
+ u-boot,dm-spl;
+ compatible = "sandbox,serial";
+ sandbox,text-colour = "cyan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial0>;
+ };
+
+ usb@0 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ hub {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ };
+ };
+ };
+
+ usb@1 {
+ compatible = "sandbox,usb";
+ hub {
+ compatible = "usb-hub";
+ usb,device-class = <USB_CLASS_HUB>;
+ hub-emul {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ sandbox,filepath = "flash.bin";
+ };
+ };
+ };
+ };
+
+ usb@2 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ };
+
+ spmi: spmi@0 {
+ compatible = "sandbox,spmi";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ pm8916@0 {
+ compatible = "qcom,spmi-pmic";
+ reg = <0x0 0x1>;
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+
+ spmi_gpios: gpios@c000 {
+ compatible = "qcom,pm8916-gpio";
+ reg = <0xc000 0x400>;
+ gpio-controller;
+ gpio-count = <4>;
+ #gpio-cells = <2>;
+ gpio-bank-name="spmi";
+ };
+ };
+ };
+
+ axi: axi@0 {
+ compatible = "sandbox,axi";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ store@0 {
+ compatible = "sandbox,sandbox_store";
+ reg = <0x0 0x400>;
+ };
+ };
+
+ onewire0: onewire {
+ compatible = "w1-gpio";
+ gpios = <&gpio_a 8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_onewire0>;
+ status = "okay";
+
+ sandbox_eeprom0: sandbox_eeprom@0 {
+ compatible = "sandbox,w1-eeprom";
+ status = "okay";
+ };
+ };
+
+ sandbox_tee {
+ compatible = "sandbox,tee";
+ };
+};
+
+&cros_ec {
+ /*
+ * This describes the flash memory within the EC. Note
+ * that the STM32L flash erases to 0, not 0xff.
+ */
+ flash {
+ image-pos = <0x08000000>;
+ size = <0x20000>;
+ erase-value = <0>;
+
+ /* Information for sandbox */
+ ro {
+ image-pos = <0>;
+ size = <0xf000>;
+ };
+ wp-ro {
+ image-pos = <0xf000>;
+ size = <0x1000>;
+ };
+ rw {
+ image-pos = <0x10000>;
+ size = <0x10000>;
+ };
+ };
+
+ keyboard-controller {
+ u-boot,dm-pre-reloc;
+ };
+};
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index a3c95f2cdb2..37a5539ff47 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-#define USB_CLASS_HUB 9
+#include <config.h>
/ {
#address-cells = <2>;
@@ -11,39 +11,18 @@
i2c0 = &i2c_0;
pci0 = &pci;
rtc0 = &rtc_0;
+ axi0 = &axi;
+ spi0 = &spi;
};
- chosen {
- stdout-path = "/serial";
+ memory {
+ reg = /bits/ 64 <0 CONFIG_SYS_SDRAM_SIZE>;
};
cros_ec: cros-ec {
reg = <0 0 0 0>;
+ u-boot,dm-pre-reloc;
compatible = "google,cros-ec-sandbox";
-
- /*
- * This describes the flash memory within the EC. Note
- * that the STM32L flash erases to 0, not 0xff.
- */
- flash {
- image-pos = <0x08000000>;
- size = <0x20000>;
- erase-value = <0>;
-
- /* Information for sandbox */
- ro {
- image-pos = <0>;
- size = <0xf000>;
- };
- wp-ro {
- image-pos = <0xf000>;
- size = <0x1000>;
- };
- rw {
- image-pos = <0x10000>;
- size = <0x10000>;
- };
- };
};
ethrawbus {
@@ -57,28 +36,6 @@
fake-host-hwaddr = [00 00 66 44 22 00];
};
- gpio_a: gpios@0 {
- gpio-controller;
- compatible = "sandbox,gpio";
- #gpio-cells = <1>;
- gpio-bank-name = "a";
- sandbox,gpio-count = <20>;
- };
-
- gpio_b: gpios@1 {
- gpio-controller;
- compatible = "sandbox,gpio";
- #gpio-cells = <2>;
- gpio-bank-name = "b";
- sandbox,gpio-count = <10>;
- };
-
- hexagon {
- compatible = "demo-simple";
- colour = "white";
- sides = <6>;
- };
-
i2c_0: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -87,58 +44,6 @@
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
- eeprom@2c {
- reg = <0x2c>;
- compatible = "i2c-eeprom";
- sandbox,emul = <&emul_eeprom>;
- };
-
- rtc_0: rtc@43 {
- reg = <0x43>;
- compatible = "sandbox-rtc";
- sandbox,emul = <&emul0>;
- };
- sandbox_pmic: sandbox_pmic {
- reg = <0x40>;
- };
-
- mc34708: pmic@41 {
- reg = <0x41>;
- };
-
- i2c_emul: emul {
- reg = <0xff>;
- compatible = "sandbox,i2c-emul-parent";
- emul_eeprom: emul-eeprom {
- compatible = "sandbox,i2c-eeprom";
- sandbox,filename = "i2c.bin";
- sandbox,size = <256>;
- };
- emul0: emul0 {
- compatible = "sandbox,i2c-rtc";
- };
- };
- };
-
- lcd {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,lcd-sdl";
- xres = <1366>;
- yres = <768>;
- };
-
- leds {
- compatible = "gpio-leds";
-
- iracibble {
- gpios = <&gpio_a 1 0>;
- label = "sandbox:red";
- };
-
- martinet {
- gpios = <&gpio_a 2 0>;
- label = "sandbox:green";
- };
};
pci: pci-controller {
@@ -148,181 +53,19 @@
#size-cells = <2>;
ranges = <0x02000000 0 0x10000000 0 0x10000000 0 0x2000
0x01000000 0 0x20000000 0 0x20000000 0 0x2000>;
- pci@1f,0 {
- compatible = "pci-generic";
- reg = <0xf800 0 0 0 0>;
- emul@1f,0 {
- compatible = "sandbox,swap-case";
- };
- };
- };
-
- pinctrl {
- compatible = "sandbox,pinctrl";
-
- pinctrl_i2c0: i2c0 {
- groups = "i2c";
- function = "i2c";
- bias-pull-up;
- };
-
- pinctrl_serial0: uart0 {
- groups = "serial_a";
- function = "serial";
- };
};
- reset@1 {
- compatible = "sandbox,reset";
- };
-
- spi@0 {
+ spi: spi@0 {
+ u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0 0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
- firmware_storage_spi: flash@0 {
- reg = <0>;
- compatible = "spansion,m25p16", "sandbox,spi-flash";
- spi-max-frequency = <40000000>;
- sandbox,filename = "spi.bin";
- };
};
- spl-test {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- boolval;
- intval = <1>;
- intarray = <2 3 4>;
- byteval = [05];
- bytearray = [06];
- longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
- stringval = "message";
- stringarray = "multi-word", "message";
- };
-
- spl-test2 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- intval = <3>;
- intarray = <5>;
- byteval = [08];
- bytearray = [01 23 34];
- longbytearray = [09 0a 0b 0c];
- stringval = "message2";
- stringarray = "another", "multi-word", "message";
- };
-
- spl-test3 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test";
- stringarray = "one";
- };
-
- spl-test4 {
- u-boot,dm-pre-reloc;
- compatible = "sandbox,spl-test.2";
- };
-
- square {
- compatible = "demo-shape";
- colour = "blue";
- sides = <4>;
- };
-
- timer {
- compatible = "sandbox,timer";
- clock-frequency = <1000000>;
- };
-
- tpm {
- compatible = "google,sandbox-tpm";
- };
-
- tpm2 {
- compatible = "sandbox,tpm2";
- };
-
- triangle {
- compatible = "demo-shape";
- colour = "cyan";
- sides = <3>;
- character = <83>;
- light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
- };
-
- /* Needs to be available prior to relocation */
- uart0: serial {
- compatible = "sandbox,serial";
- sandbox,text-colour = "cyan";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_serial0>;
- };
-
- usb@0 {
- compatible = "sandbox,usb";
- status = "disabled";
- hub {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- };
- };
- };
-
- usb@1 {
- compatible = "sandbox,usb";
- hub {
- compatible = "usb-hub";
- usb,device-class = <USB_CLASS_HUB>;
- hub-emul {
- compatible = "sandbox,usb-hub";
- #address-cells = <1>;
- #size-cells = <0>;
- flash-stick {
- reg = <0>;
- compatible = "sandbox,usb-flash";
- sandbox,filepath = "flash.bin";
- };
- };
- };
- };
-
- usb@2 {
- compatible = "sandbox,usb";
- status = "disabled";
- };
-
- spmi: spmi@0 {
- compatible = "sandbox,spmi";
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- pm8916@0 {
- compatible = "qcom,spmi-pmic";
- reg = <0x0 0x1>;
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
- spmi_gpios: gpios@c000 {
- compatible = "qcom,pm8916-gpio";
- reg = <0xc000 0x400>;
- gpio-controller;
- gpio-count = <4>;
- #gpio-cells = <2>;
- gpio-bank-name="spmi";
- };
- };
- };
-
- sandbox_tee {
- compatible = "sandbox,tee";
- };
};
+#include "sandbox.dtsi"
#include "cros-ec-keyboard.dtsi"
#include "sandbox_pmic.dtsi"
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index a7a566c0d8b..8147d9781ea 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -446,6 +446,14 @@
compatible = "sandbox,swap-case";
};
};
+ pci@1,0 {
+ compatible = "pci-generic";
+ reg = <0x0800 0 0 0 0>;
+ emul@0,0 {
+ compatible = "sandbox,swap-case";
+ use-ea;
+ };
+ };
pci@1f,0 {
compatible = "pci-generic";
reg = <0xf800 0 0 0 0>;
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 7ec9b610083..cbf209693da 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -19,6 +19,7 @@
#define PCI_CAP_ID_PM_OFFSET 0x50
#define PCI_CAP_ID_EXP_OFFSET 0x60
#define PCI_CAP_ID_MSIX_OFFSET 0x70
+#define PCI_CAP_ID_EA_OFFSET 0x80
#define PCI_EXT_CAP_ID_ERR_OFFSET 0x100
#define PCI_EXT_CAP_ID_VC_OFFSET 0x200
@@ -30,6 +31,18 @@
#define SANDBOX_CLK_RATE 32768
+/* Macros used to test PCI EA capability structure */
+#define PCI_CAP_EA_BASE_LO0 0x00100000
+#define PCI_CAP_EA_BASE_LO1 0x00110000
+#define PCI_CAP_EA_BASE_LO2 0x00120000
+#define PCI_CAP_EA_BASE_LO4 0x00140000
+#define PCI_CAP_EA_BASE_HI2 0x00020000ULL
+#define PCI_CAP_EA_BASE_HI4 0x00040000ULL
+#define PCI_CAP_EA_SIZE_LO 0x0000ffff
+#define PCI_CAP_EA_SIZE_HI 0x00000010ULL
+#define PCI_EA_BAR2_MAGIC 0x72727272
+#define PCI_EA_BAR4_MAGIC 0x74747474
+
/* System controller driver data */
enum {
SYSCON0 = 32,
diff --git a/arch/x86/include/asm/coreboot_tables.h b/arch/x86/include/asm/coreboot_tables.h
index c42175b94da..2c54e24e02f 100644
--- a/arch/x86/include/asm/coreboot_tables.h
+++ b/arch/x86/include/asm/coreboot_tables.h
@@ -8,6 +8,8 @@
#ifndef _COREBOOT_TABLES_H
#define _COREBOOT_TABLES_H
+struct memory_area;
+
struct cbuint64 {
u32 lo;
u32 hi;
diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox
index 48c1e2b9e7b..c10dd444df0 100644
--- a/board/sandbox/README.sandbox
+++ b/board/sandbox/README.sandbox
@@ -435,6 +435,27 @@ board_init_f() and board_init_r().
This approach can be used on normal boards as well as sandbox.
+SDL_CONFIG
+----------
+
+If sdl-config is on a different path from the default, set the SDL_CONFIG
+environment variable to the correct pathname before building U-Boot.
+
+
+Using valgrind / memcheck
+-------------------------
+
+It is possible to run U-Boot under valgrind to check memory allocations:
+
+ valgrind u-boot
+
+If you are running sandbox SPL or TPL, then valgrind will not by default
+notice when U-Boot jumps from TPL to SPL, or from SPL to U-Boot proper. To
+fix this, use:
+
+ valgrind --trace-children=yes u-boot
+
+
Testing
-------
diff --git a/cmd/trace.c b/cmd/trace.c
index 26bf0960d49..7d328f88be5 100644
--- a/cmd/trace.c
+++ b/cmd/trace.c
@@ -30,8 +30,7 @@ static int get_args(int argc, char * const argv[], char **buff,
static int create_func_list(int argc, char * const argv[])
{
- size_t buff_size, avail, buff_ptr, used;
- unsigned int needed;
+ size_t buff_size, avail, buff_ptr, needed, used;
char *buff;
int err;
@@ -41,7 +40,7 @@ static int create_func_list(int argc, char * const argv[])
avail = buff_size - buff_ptr;
err = trace_list_functions(buff + buff_ptr, avail, &needed);
if (err)
- printf("Error: truncated (%#x bytes needed)\n", needed);
+ printf("Error: truncated (%#zx bytes needed)\n", needed);
used = min(avail, (size_t)needed);
printf("Function trace dumped to %08lx, size %#zx\n",
(ulong)map_to_sysmem(buff + buff_ptr), used);
@@ -54,8 +53,7 @@ static int create_func_list(int argc, char * const argv[])
static int create_call_list(int argc, char * const argv[])
{
- size_t buff_size, avail, buff_ptr, used;
- unsigned int needed;
+ size_t buff_size, avail, buff_ptr, needed, used;
char *buff;
int err;
@@ -65,7 +63,7 @@ static int create_call_list(int argc, char * const argv[])
avail = buff_size - buff_ptr;
err = trace_list_calls(buff + buff_ptr, avail, &needed);
if (err)
- printf("Error: truncated (%#x bytes needed)\n", needed);
+ printf("Error: truncated (%#zx bytes needed)\n", needed);
used = min(avail, (size_t)needed);
printf("Call list dumped to %08lx, size %#zx\n",
(ulong)map_to_sysmem(buff + buff_ptr), used);
diff --git a/common/Kconfig b/common/Kconfig
index af66496e752..4865a4dfc86 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -69,6 +69,13 @@ config SPL_BOOTSTAGE_RECORD_COUNT
This is the size of the bootstage record list and is the maximum
number of bootstage records that can be recorded.
+config TPL_BOOTSTAGE_RECORD_COUNT
+ int "Number of boot stage records to store for TPL"
+ default 5
+ help
+ This is the size of the bootstage record list and is the maximum
+ number of bootstage records that can be recorded.
+
config BOOTSTAGE_FDT
bool "Store boot timing information in the OS device tree"
depends on BOOTSTAGE
diff --git a/common/board_f.c b/common/board_f.c
index c25eb188fb2..4760d728f37 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -442,8 +442,8 @@ static int reserve_trace(void)
#ifdef CONFIG_TRACE
gd->relocaddr -= CONFIG_TRACE_BUFFER_SIZE;
gd->trace_buff = map_sysmem(gd->relocaddr, CONFIG_TRACE_BUFFER_SIZE);
- debug("Reserving %dk for trace data at: %08lx\n",
- CONFIG_TRACE_BUFFER_SIZE >> 10, gd->relocaddr);
+ debug("Reserving %luk for trace data at: %08lx\n",
+ (unsigned long)CONFIG_TRACE_BUFFER_SIZE >> 10, gd->relocaddr);
#endif
return 0;
@@ -839,7 +839,7 @@ static const init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
#endif
-#ifdef CONFIG_TRACE
+#ifdef CONFIG_TRACE_EARLY
trace_early_init,
#endif
initf_malloc,
diff --git a/doc/README.SPL b/doc/README.SPL
index 7a30fefa963..6eed83f8c57 100644
--- a/doc/README.SPL
+++ b/doc/README.SPL
@@ -66,6 +66,22 @@ CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o)
CONFIG_SPL_RAM_DEVICE (common/spl/spl.c)
CONFIG_SPL_WATCHDOG_SUPPORT (drivers/watchdog/libwatchdog.o)
+Device tree
+-----------
+The U-Boot device tree is filtered by the fdtgrep tools during the build
+process to generate a much smaller device tree used in SPL (spl/u-boot-spl.dtb)
+with:
+- the mandatory nodes (/alias, /chosen, /config)
+- the nodes with one pre-relocation property:
+ 'u-boot,dm-pre-reloc' or 'u-boot,dm-spl'
+
+ftgrep is also used to remove:
+- the properties defined in CONFIG_OF_SPL_REMOVE_PROPS
+- all the pre-relocation properties
+ ('u-boot,dm-pre-reloc', 'u-boot,dm-spl' and 'u-boot,dm-tpl')
+
+All the nodes remaining in the SPL devicetree are bound
+(see driver-model/README.txt).
Debugging
---------
diff --git a/doc/README.TPL b/doc/README.TPL
index 980debe777f..c94129fdc98 100644
--- a/doc/README.TPL
+++ b/doc/README.TPL
@@ -34,6 +34,10 @@ determine which SPL options to choose based on whether CONFIG_TPL_BUILD
is set. Source files can be compiled for TPL with options choosed in the
board config file.
+TPL use a small device tree (u-boot-tpl.dtb), containing only the nodes with
+the pre-relocation properties: 'u-boot,dm-pre-reloc' and 'u-boot,dm-tpl'
+(see README.SPL for details).
+
For example:
spl/Makefile:
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index 07b120d5121..532a771f688 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -849,6 +849,10 @@ in the device tree node. For U-Boot proper you can use 'u-boot,dm-pre-proper'
which means that it will be processed (and a driver bound) in U-Boot proper
prior to relocation, but will not be available in SPL or TPL.
+To reduce the size of SPL and TPL, only the nodes with pre-relocation properties
+('u-boot,dm-pre-reloc', 'u-boot,dm-spl' or 'u-boot,dm-tpl') are keept in their
+device trees (see README.SPL for details); the remaining nodes are always bound.
+
Then post relocation we throw that away and re-init driver model again.
For drivers which require some sort of continuity between pre- and
post-relocation devices, we can provide access to the pre-relocation
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 33f4aa24185..1e6dad86927 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -56,6 +56,13 @@ config SPL_BLOCK_CACHE
help
This option enables the disk-block cache in SPL
+config TPL_BLOCK_CACHE
+ bool "Use block device cache in TPL"
+ depends on TPL_BLK
+ default n
+ help
+ This option enables the disk-block cache in TPL
+
config IDE
bool "Support IDE controllers"
select HAVE_BLOCK_DEVICE
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 96e47dc7070..60b939a9240 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -42,6 +42,8 @@ bool dm_ofnode_pre_reloc(ofnode node)
#else
if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
return true;
+ if (ofnode_read_bool(node, "u-boot,dm-pre-proper"))
+ return true;
/*
* In regular builds individual spl and tpl handling both
diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c
index fa608cec1b9..6afc6d9466b 100644
--- a/drivers/misc/swap_case.c
+++ b/drivers/misc/swap_case.c
@@ -61,11 +61,63 @@ static int sandbox_swap_case_get_devfn(struct udevice *dev)
return plat->devfn;
}
+static int sandbox_swap_case_use_ea(struct udevice *dev)
+{
+ return !!ofnode_get_property(dev->node, "use-ea", NULL);
+}
+
+/* Please keep these macros in sync with ea_regs below */
+#define PCI_CAP_ID_EA_SIZE (sizeof(ea_regs) + 4)
+#define PCI_CAP_ID_EA_ENTRY_CNT 4
+/* Hardcoded EA structure, excluding 1st DW. */
+static const u32 ea_regs[] = {
+ /* BEI=0, ES=2, BAR0 32b Base + 32b MaxOffset, I/O space */
+ (2 << 8) | 2,
+ PCI_CAP_EA_BASE_LO0,
+ 0,
+ /* BEI=1, ES=2, BAR1 32b Base + 32b MaxOffset */
+ (1 << 4) | 2,
+ PCI_CAP_EA_BASE_LO1,
+ MEM_TEXT_SIZE - 1,
+ /* BEI=2, ES=3, BAR2 64b Base + 32b MaxOffset */
+ (2 << 4) | 3,
+ PCI_CAP_EA_BASE_LO2 | PCI_EA_IS_64,
+ PCI_CAP_EA_SIZE_LO,
+ PCI_CAP_EA_BASE_HI2,
+ /* BEI=4, ES=4, BAR4 64b Base + 64b MaxOffset */
+ (4 << 4) | 4,
+ PCI_CAP_EA_BASE_LO4 | PCI_EA_IS_64,
+ PCI_CAP_EA_SIZE_LO | PCI_EA_IS_64,
+ PCI_CAP_EA_BASE_HI4,
+ PCI_CAP_EA_SIZE_HI,
+};
+
+static int sandbox_swap_case_read_ea(struct udevice *emul, uint offset,
+ ulong *valuep, enum pci_size_t size)
+{
+ u32 reg;
+
+ offset = offset - PCI_CAP_ID_EA_OFFSET - 4;
+ reg = ea_regs[offset >> 2];
+ reg >>= (offset % 4) * 8;
+
+ *valuep = reg;
+ return 0;
+}
+
static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
ulong *valuep, enum pci_size_t size)
{
struct swap_case_platdata *plat = dev_get_platdata(emul);
+ /*
+ * The content of the EA capability structure is handled elsewhere to
+ * keep the switch/case below sane
+ */
+ if (offset > PCI_CAP_ID_EA_OFFSET + PCI_CAP_LIST_NEXT &&
+ offset < PCI_CAP_ID_EA_OFFSET + PCI_CAP_ID_EA_SIZE)
+ return sandbox_swap_case_read_ea(emul, offset, valuep, size);
+
switch (offset) {
case PCI_COMMAND:
*valuep = plat->command;
@@ -134,9 +186,21 @@ static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
*valuep = PCI_CAP_ID_MSIX_OFFSET;
break;
case PCI_CAP_ID_MSIX_OFFSET:
- *valuep = PCI_CAP_ID_MSIX;
+ if (sandbox_swap_case_use_ea(emul))
+ *valuep = (PCI_CAP_ID_EA_OFFSET << 8) | PCI_CAP_ID_MSIX;
+ else
+ *valuep = PCI_CAP_ID_MSIX;
break;
case PCI_CAP_ID_MSIX_OFFSET + PCI_CAP_LIST_NEXT:
+ if (sandbox_swap_case_use_ea(emul))
+ *valuep = PCI_CAP_ID_EA_OFFSET;
+ else
+ *valuep = 0;
+ break;
+ case PCI_CAP_ID_EA_OFFSET:
+ *valuep = (PCI_CAP_ID_EA_ENTRY_CNT << 16) | PCI_CAP_ID_EA;
+ break;
+ case PCI_CAP_ID_EA_OFFSET + PCI_CAP_LIST_NEXT:
*valuep = 0;
break;
case PCI_EXT_CAP_ID_ERR_OFFSET:
@@ -257,6 +321,9 @@ int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
return 0;
}
+static int pci_ea_bar2_magic = PCI_EA_BAR2_MAGIC;
+static int pci_ea_bar4_magic = PCI_EA_BAR4_MAGIC;
+
static int sandbox_swap_case_map_physmem(struct udevice *dev,
phys_addr_t addr, unsigned long *lenp, void **ptrp)
{
@@ -265,9 +332,42 @@ static int sandbox_swap_case_map_physmem(struct udevice *dev,
int barnum;
int ret;
+ if (sandbox_swap_case_use_ea(dev)) {
+ /*
+ * only support mapping base address in EA test for now, we
+ * don't handle mapping an offset inside a BAR. Seems good
+ * enough for the current test.
+ */
+ switch (addr) {
+ case (phys_addr_t)PCI_CAP_EA_BASE_LO0:
+ *ptrp = &priv->op;
+ *lenp = 4;
+ break;
+ case (phys_addr_t)PCI_CAP_EA_BASE_LO1:
+ *ptrp = priv->mem_text;
+ *lenp = barinfo[1].size - 1;
+ break;
+ case (phys_addr_t)((PCI_CAP_EA_BASE_HI2 << 32) |
+ PCI_CAP_EA_BASE_LO2):
+ *ptrp = &pci_ea_bar2_magic;
+ *lenp = PCI_CAP_EA_SIZE_LO;
+ break;
+ case (phys_addr_t)((PCI_CAP_EA_BASE_HI4 << 32) |
+ PCI_CAP_EA_BASE_LO4):
+ *ptrp = &pci_ea_bar4_magic;
+ *lenp = (PCI_CAP_EA_SIZE_HI << 32) |
+ PCI_CAP_EA_SIZE_LO;
+ break;
+ default:
+ return -ENOENT;
+ }
+ return 0;
+ }
+
ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
if (ret)
return ret;
+
if (barnum == 1) {
*ptrp = priv->mem_text + offset;
avail = barinfo[1].size - offset;
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index cf1e7617ae3..c74ebf6a763 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1341,10 +1341,56 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
return bus_addr;
}
+static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int flags,
+ int ea_off)
+{
+ int ea_cnt, i, entry_size;
+ int bar_id = (bar - PCI_BASE_ADDRESS_0) >> 2;
+ u32 ea_entry;
+ phys_addr_t addr;
+
+ /* EA capability structure header */
+ dm_pci_read_config32(dev, ea_off, &ea_entry);
+ ea_cnt = (ea_entry >> 16) & PCI_EA_NUM_ENT_MASK;
+ ea_off += PCI_EA_FIRST_ENT;
+
+ for (i = 0; i < ea_cnt; i++, ea_off += entry_size) {
+ /* Entry header */
+ dm_pci_read_config32(dev, ea_off, &ea_entry);
+ entry_size = ((ea_entry & PCI_EA_ES) + 1) << 2;
+
+ if (((ea_entry & PCI_EA_BEI) >> 4) != bar_id)
+ continue;
+
+ /* Base address, 1st DW */
+ dm_pci_read_config32(dev, ea_off + 4, &ea_entry);
+ addr = ea_entry & PCI_EA_FIELD_MASK;
+ if (ea_entry & PCI_EA_IS_64) {
+ /* Base address, 2nd DW, skip over 4B MaxOffset */
+ dm_pci_read_config32(dev, ea_off + 12, &ea_entry);
+ addr |= ((u64)ea_entry) << 32;
+ }
+
+ /* size ignored for now */
+ return map_physmem(addr, flags, 0);
+ }
+
+ return 0;
+}
+
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags)
{
pci_addr_t pci_bus_addr;
u32 bar_response;
+ int ea_off;
+
+ /*
+ * if the function supports Enhanced Allocation use that instead of
+ * BARs
+ */
+ ea_off = dm_pci_find_capability(dev, PCI_CAP_ID_EA);
+ if (ea_off)
+ return dm_pci_map_ea_bar(dev, bar, flags, ea_off);
/* read BAR address */
dm_pci_read_config32(dev, bar, &bar_response);
@@ -1448,6 +1494,30 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap)
return dm_pci_find_next_ext_capability(dev, 0, cap);
}
+int dm_pci_flr(struct udevice *dev)
+{
+ int pcie_off;
+ u32 cap;
+
+ /* look for PCI Express Capability */
+ pcie_off = dm_pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (!pcie_off)
+ return -ENOENT;
+
+ /* check FLR capability */
+ dm_pci_read_config32(dev, pcie_off + PCI_EXP_DEVCAP, &cap);
+ if (!(cap & PCI_EXP_DEVCAP_FLR))
+ return -ENOENT;
+
+ dm_pci_clrset_config16(dev, pcie_off + PCI_EXP_DEVCTL, 0,
+ PCI_EXP_DEVCTL_BCR_FLR);
+
+ /* wait 100ms, per PCI spec */
+ mdelay(100);
+
+ return 0;
+}
+
UCLASS_DRIVER(pci) = {
.id = UCLASS_PCI,
.name = "pci",
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index a357b00d287..57dd4a72c6d 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
+ * Copyright 2019 NXP
* Copyright 2013 Freescale Semiconductor, Inc.
*/
@@ -502,6 +503,9 @@ static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
plat->reg = (void *)addr;
plat->flags = dev_get_driver_data(dev);
+ if (fdtdec_get_bool(blob, node, "little-endian"))
+ plat->flags &= ~LPUART_FLAG_REGMAP_ENDIAN_BIG;
+
if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
plat->devtype = DEV_LS1021A;
else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 509dd0ec589..cc174dd0363 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -226,7 +226,7 @@ config SANDBOX_SPI
cs-gpios = <0>, <&gpio_a 0>;
flash@0 {
reg = <0>;
- compatible = "spansion,m25p16", "sandbox,spi-flash";
+ compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <40000000>;
sandbox,filename = "spi.bin";
};
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index b86eee75bcb..7aabebeff5f 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -201,7 +201,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
unsigned int pos = 0;
const u8 *tx_buf = NULL;
u8 *rx_buf = NULL;
- u8 *op_buf;
int op_len;
u32 flag;
int ret;
@@ -338,7 +337,17 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
}
op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
- op_buf = calloc(1, op_len);
+
+ /*
+ * Avoid using malloc() here so that we can use this code in SPL where
+ * simple malloc may be used. That implementation does not allow free()
+ * so repeated calls to this code can exhaust the space.
+ *
+ * The value of op_len is small, since it does not include the actual
+ * data being sent, only the op-code and address. In fact, it should be
+ * possible to just use a small fixed value here instead of op_len.
+ */
+ u8 op_buf[op_len];
op_buf[pos++] = op->cmd.opcode;
@@ -382,8 +391,6 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
debug("%02x ", tx_buf ? tx_buf[i] : rx_buf[i]);
debug("[ret %d]\n", ret);
- free(op_buf);
-
if (ret < 0)
return ret;
#endif /* __UBOOT__ */
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 38e2a7e241d..7dfd89460f0 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -66,6 +66,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
case SYSRESET_POWER_OFF:
if (!state->sysreset_allowed[type])
return -EACCES;
+ sandbox_exit();
default:
return -ENOSYS;
}
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index b19bfb4f2ff..d4071c06615 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -291,7 +291,9 @@ static int video_post_bind(struct udevice *dev)
return 0;
size = alloc_fb(dev, &addr);
if (addr < gd->video_bottom) {
- /* Device tree node may need the 'u-boot,dm-pre-reloc' tag */
+ /* Device tree node may need the 'u-boot,dm-pre-reloc' or
+ * 'u-boot,dm-pre-proper' tag
+ */
printf("Video device '%s' cannot allocate frame buffer memory -ensure the device is set up before relocation\n",
dev->name);
return -ENOSPC;
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 50affaf1a82..5d75021ed6b 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -63,7 +63,11 @@
func(HOST, host, 1) \
func(HOST, host, 0)
+#ifdef __ASSEMBLY__
+#define BOOTENV
+#else
#include <config_distro_bootcmd.h>
+#endif
#define CONFIG_KEEP_SERVERADDR
#define CONFIG_UDP_CHECKSUM
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 4ab2ae1ba5c..704f91589a5 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -676,12 +676,14 @@ int ofnode_read_simple_size_cells(ofnode node);
* After relocation and jumping into the real U-Boot binary it is possible to
* determine if a node was bound in one of SPL/TPL stages.
*
- * There are 3 settings currently in use
- * -
+ * There are 4 settings currently in use
+ * - u-boot,dm-pre-proper: U-Boot proper pre-relocation only
* - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
* Existing platforms only use it to indicate nodes needed in
* SPL. Should probably be replaced by u-boot,dm-spl for
* new platforms.
+ * - u-boot,dm-spl: SPL and U-Boot pre-relocation
+ * - u-boot,dm-tpl: TPL and U-Boot pre-relocation
*
* @node: node to check
* @return true if node is needed in SPL/TL, false otherwise
diff --git a/include/dm/util.h b/include/dm/util.h
index 60d3b93decd..348c2ace3c3 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -52,12 +52,14 @@ static inline void dm_dump_devres(void)
* it is possible to determine if a node was bound in one of
* SPL/TPL stages.
*
- * There are 3 settings currently in use
- * -
+ * There are 4 settings currently in use
+ * - u-boot,dm-pre-proper: U-Boot proper pre-relocation only
* - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
* Existing platforms only use it to indicate nodes needed in
* SPL. Should probably be replaced by u-boot,dm-spl for
* existing platforms.
+ * - u-boot,dm-spl: SPL and U-Boot pre-relocation
+ * - u-boot,dm-tpl: TPL and U-Boot pre-relocation
* @node: of node
*
* Returns true if node is needed in SPL/TL, false otherwise.
diff --git a/include/pci.h b/include/pci.h
index 508f7bca81c..298d0d43559 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -455,6 +455,23 @@
#define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */
#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM
+/* Enhanced Allocation Registers */
+#define PCI_EA_NUM_ENT 2 /* Number of Capability Entries */
+#define PCI_EA_NUM_ENT_MASK 0x3f /* Num Entries Mask */
+#define PCI_EA_FIRST_ENT 4 /* First EA Entry in List */
+#define PCI_EA_ES 0x00000007 /* Entry Size */
+#define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */
+/* Base, MaxOffset registers */
+/* bit 0 is reserved */
+#define PCI_EA_IS_64 0x00000002 /* 64-bit field flag */
+#define PCI_EA_FIELD_MASK 0xfffffffc /* For Base & Max Offset */
+
+/* PCI Express capabilities */
+#define PCI_EXP_DEVCAP 4 /* Device capabilities */
+#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
+#define PCI_EXP_DEVCTL 8 /* Device Control */
+#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
+
/* Include the ID list */
#include <pci_ids.h>
@@ -1309,12 +1326,16 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
* dm_pci_map_bar() - get a virtual address associated with a BAR region
*
* Looks up a base address register and finds the physical memory address
- * that corresponds to it
+ * that corresponds to it.
+ * Can be used for 32b BARs 0-5 on type 0 functions and for 32b BARs 0-1 on
+ * type 1 functions.
+ * Can also be used on type 0 functions that support Enhanced Allocation for
+ * 32b/64b BARs. Note that duplicate BEI entries are not supported.
*
* @dev: Device to check
- * @bar: Bar number to read (numbered from 0)
+ * @bar: Bar register offset (PCI_BASE_ADDRESS_...)
* @flags: Flags for the region type (PCI_REGION_...)
- * @return: pointer to the virtual address to use
+ * @return: pointer to the virtual address to use or 0 on error
*/
void *dm_pci_map_bar(struct udevice *dev, int bar, int flags);
@@ -1411,6 +1432,14 @@ int dm_pci_find_next_ext_capability(struct udevice *dev, int start, int cap);
*/
int dm_pci_find_ext_capability(struct udevice *dev, int cap);
+/**
+ * dm_pci_flr() - Perform FLR if the device suppoorts it
+ *
+ * @dev: PCI device to reset
+ * @return: 0 if OK, -ENOENT if FLR is not supported by dev
+ */
+int dm_pci_flr(struct udevice *dev);
+
#define dm_pci_virt_to_bus(dev, addr, flags) \
dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
diff --git a/include/trace.h b/include/trace.h
index 99f34f72bcc..606dba97689 100644
--- a/include/trace.h
+++ b/include/trace.h
@@ -39,7 +39,7 @@ struct trace_output_func {
/* A header at the start of the trace output buffer */
struct trace_output_hdr {
enum trace_chunk_type type; /* Record type */
- uint32_t rec_count; /* Number of records */
+ size_t rec_count; /* Number of records */
};
/* Print statistics about traced function calls */
@@ -57,7 +57,7 @@ void trace_print_stats(void);
* @param needed Returns number of bytes used / needed
* @return 0 if ok, -1 on error (buffer exhausted)
*/
-int trace_list_functions(void *buff, int buff_size, unsigned *needed);
+int trace_list_functions(void *buff, size_t buff_size, size_t *needed);
/* Flags for ftrace_record */
enum ftrace_flags {
@@ -77,7 +77,7 @@ struct trace_call {
uint32_t flags; /* Flags and timestamp */
};
-int trace_list_calls(void *buff, int buff_size, unsigned int *needed);
+int trace_list_calls(void *buff, size_t buff_size, size_t *needed);
/**
* Turn function tracing on and off
diff --git a/lib/Kconfig b/lib/Kconfig
index 416e63c1c73..e717eb3de50 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -192,6 +192,13 @@ config TRACE_BUFFER_SIZE
the size is too small then 'trace stats' will show a message saying
how many records were dropped due to buffer overflow.
+config TRACE_CALL_DEPTH_LIMIT
+ int "Trace call depth limit"
+ depends on TRACE
+ default 15
+ help
+ Sets the maximum call depth up to which function calls are recorded.
+
config TRACE_EARLY
bool "Enable tracing before relocation"
depends on TRACE
@@ -209,6 +216,14 @@ config TRACE_EARLY_SIZE
Sets the size of the early trace buffer in bytes. This is used to hold
tracing information before relocation.
+config TRACE_EARLY_CALL_DEPTH_LIMIT
+ int "Early trace call depth limit"
+ depends on TRACE_EARLY
+ default 200
+ help
+ Sets the maximum call depth up to which function calls are recorded
+ during early tracing.
+
config TRACE_EARLY_ADDR
hex "Address of early trace buffer in U-Boot"
depends on TRACE_EARLY
diff --git a/lib/fdtdec_test.c b/lib/fdtdec_test.c
index 1f4f2705405..e8bfd1fb1ec 100644
--- a/lib/fdtdec_test.c
+++ b/lib/fdtdec_test.c
@@ -138,6 +138,7 @@ static int run_test(const char *aliases, const char *nodes, const char *expect)
}
printf("pass\n");
+ free(blob);
return 0;
}
@@ -292,6 +293,7 @@ static int check_carveout(void)
CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 2), 0);
CHECKOK(check_fdt_carveout(fdt, 2, 2));
+ free(fdt);
return 0;
}
diff --git a/lib/hang.c b/lib/hang.c
index c5a78694be6..4d026a3e64c 100644
--- a/lib/hang.c
+++ b/lib/hang.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <bootstage.h>
+#include <os.h>
/**
* hang - stop processing by staying in an endless loop
@@ -26,6 +27,8 @@ void hang(void)
puts("### ERROR ### Please RESET the board ###\n");
#endif
bootstage_error(BOOTSTAGE_ID_NEED_RESET);
+ if (IS_ENABLED(CONFIG_SANDBOX))
+ os_exit(1);
for (;;)
;
}
diff --git a/lib/trace.c b/lib/trace.c
index 9956442fefe..f2402b93593 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -56,6 +56,49 @@ static inline uintptr_t __attribute__((no_instrument_function))
return offset / FUNC_SITE_SIZE;
}
+#ifdef CONFIG_EFI_LOADER
+
+/**
+ * trace_gd - the value of the gd register
+ */
+static volatile void *trace_gd;
+
+/**
+ * trace_save_gd() - save the value of the gd register
+ */
+static void __attribute__((no_instrument_function)) trace_save_gd(void)
+{
+ trace_gd = gd;
+}
+
+/**
+ * trace_swap_gd() - swap between U-Boot and application gd register value
+ *
+ * An UEFI application may change the value of the register that gd lives in.
+ * But some of our functions like get_ticks() access this register. So we
+ * have to set the gd register to the U-Boot value when entering a trace
+ * point and set it back to the application value when exiting the trace point.
+ */
+static void __attribute__((no_instrument_function)) trace_swap_gd(void)
+{
+ volatile void *temp_gd = trace_gd;
+
+ trace_gd = gd;
+ gd = temp_gd;
+}
+
+#else
+
+static void __attribute__((no_instrument_function)) trace_save_gd(void)
+{
+}
+
+static void __attribute__((no_instrument_function)) trace_swap_gd(void)
+{
+}
+
+#endif
+
static void __attribute__((no_instrument_function)) add_ftrace(void *func_ptr,
void *caller, ulong flags)
{
@@ -100,6 +143,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter(
if (trace_enabled) {
int func;
+ trace_swap_gd();
add_ftrace(func_ptr, caller, FUNCF_ENTRY);
func = func_ptr_to_num(func_ptr);
if (func < hdr->func_count) {
@@ -111,6 +155,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter(
hdr->depth++;
if (hdr->depth > hdr->depth_limit)
hdr->max_depth = hdr->depth;
+ trace_swap_gd();
}
}
@@ -126,8 +171,10 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit(
void *func_ptr, void *caller)
{
if (trace_enabled) {
+ trace_swap_gd();
add_ftrace(func_ptr, caller, FUNCF_EXIT);
hdr->depth--;
+ trace_swap_gd();
}
}
@@ -143,12 +190,12 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit(
* greater than buff_size if we ran out of space.
* @return 0 if ok, -1 if space was exhausted
*/
-int trace_list_functions(void *buff, int buff_size, unsigned int *needed)
+int trace_list_functions(void *buff, size_t buff_size, size_t *needed)
{
struct trace_output_hdr *output_hdr = NULL;
void *end, *ptr = buff;
- int func;
- int upto;
+ size_t func;
+ size_t upto;
end = buff ? buff + buff_size : NULL;
@@ -159,7 +206,7 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed)
/* Add information about each function */
for (func = upto = 0; func < hdr->func_count; func++) {
- int calls = hdr->call_accum[func];
+ size_t calls = hdr->call_accum[func];
if (!calls)
continue;
@@ -188,12 +235,12 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed)
return 0;
}
-int trace_list_calls(void *buff, int buff_size, unsigned *needed)
+int trace_list_calls(void *buff, size_t buff_size, size_t *needed)
{
struct trace_output_hdr *output_hdr = NULL;
void *end, *ptr = buff;
- int rec, upto;
- int count;
+ size_t rec, upto;
+ size_t count;
end = buff ? buff + buff_size : NULL;
@@ -284,6 +331,8 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
size_t needed;
int was_disabled = !trace_enabled;
+ trace_save_gd();
+
if (!was_disabled) {
#ifdef CONFIG_TRACE_EARLY
char *end;
@@ -327,7 +376,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
add_textbase();
puts("trace: enabled\n");
- hdr->depth_limit = 15;
+ hdr->depth_limit = CONFIG_TRACE_CALL_DEPTH_LIMIT;
trace_enabled = 1;
trace_inited = 1;
@@ -361,7 +410,7 @@ int __attribute__((no_instrument_function)) trace_early_init(void)
hdr->ftrace = (struct trace_call *)((char *)hdr + needed);
hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace);
add_textbase();
- hdr->depth_limit = 200;
+ hdr->depth_limit = CONFIG_TRACE_EARLY_CALL_DEPTH_LIMIT;
printf("trace: early enable at %08x\n", CONFIG_TRACE_EARLY_ADDR);
trace_enabled = 1;
diff --git a/test/dm/pci.c b/test/dm/pci.c
index a1febd54b7f..c325f6600e7 100644
--- a/test/dm/pci.c
+++ b/test/dm/pci.c
@@ -245,3 +245,52 @@ static int dm_test_pci_cap(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_pci_cap, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test looking up BARs in EA capability structure */
+static int dm_test_pci_ea(struct unit_test_state *uts)
+{
+ struct udevice *bus, *swap;
+ void *bar;
+ int cap;
+
+ /*
+ * use emulated device mapping function, we're not using real physical
+ * addresses in this test
+ */
+ sandbox_set_enable_pci_map(true);
+
+ ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &bus));
+ ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x01, 0), &swap));
+
+ /* look up PCI_CAP_ID_EA */
+ cap = dm_pci_find_capability(swap, PCI_CAP_ID_EA);
+ ut_asserteq(PCI_CAP_ID_EA_OFFSET, cap);
+
+ /* test swap case in BAR 1 */
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_0, 0);
+ ut_assertnonnull(bar);
+ *(int *)bar = 2; /* swap upper/lower */
+
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0);
+ ut_assertnonnull(bar);
+ strcpy(bar, "ea TEST");
+ unmap_sysmem(bar);
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0);
+ ut_assertnonnull(bar);
+ ut_asserteq_str("EA test", bar);
+
+ /* test magic values in BARs2, 4; BAR 3 is n/a */
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_2, 0);
+ ut_assertnonnull(bar);
+ ut_asserteq(PCI_EA_BAR2_MAGIC, *(u32 *)bar);
+
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_3, 0);
+ ut_assertnull(bar);
+
+ bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_4, 0);
+ ut_assertnonnull(bar);
+ ut_asserteq(PCI_EA_BAR4_MAGIC, *(u32 *)bar);
+
+ return 0;
+}
+DM_TEST(dm_test_pci_ea, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 98103ee71a9..263334b0743 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -2,6 +2,7 @@
# Copyright (c) 2016 Google, Inc
import pytest
+import u_boot_utils as util
OF_PLATDATA_OUTPUT = '''
of-platdata probe:
@@ -31,6 +32,15 @@ intarray 0 0 0 0
longbytearray 00 00 00 00 00 00 00 00 00
string <NULL>
stringarray "one" "" ""
+of-platdata probe:
+bool 0
+byte 00
+bytearray 00 00 00
+int 0
+intarray 0 0 0 0
+longbytearray 00 00 00 00 00 00 00 00 00
+string <NULL>
+stringarray "spl" "" ""
'''
@pytest.mark.buildconfigspec('spl_of_platdata')
@@ -40,3 +50,21 @@ def test_ofplatdata(u_boot_console):
cons.restart_uboot_with_flags(['--show_of_platdata'])
output = cons.get_spawn_output().replace('\r', '')
assert OF_PLATDATA_OUTPUT in output
+
+@pytest.mark.buildconfigspec('spl_of_platdata')
+def test_spl_devicetree(u_boot_console):
+ """Test content of spl device-tree"""
+ cons = u_boot_console
+ dtb = cons.config.build_dir + '/spl/u-boot-spl.dtb'
+ fdtgrep = cons.config.build_dir + '/tools/fdtgrep'
+ output = util.run_and_log(cons, [fdtgrep, '-l', dtb])
+
+ assert "u-boot,dm-pre-reloc" not in output
+ assert "u-boot,dm-pre-proper" not in output
+ assert "u-boot,dm-spl" not in output
+ assert "u-boot,dm-tpl" not in output
+
+ assert "spl-test4" in output
+ assert "spl-test5" not in output
+ assert "spl-test6" not in output
+ assert "spl-test7" in output
diff --git a/tools/binman/README b/tools/binman/README
index 927fa856acf..ac193f16cf7 100644
--- a/tools/binman/README
+++ b/tools/binman/README
@@ -702,6 +702,20 @@ To enable Python test coverage on Debian-type distributions (e.g. Ubuntu):
$ sudo apt-get install python-coverage python-pytest
+Concurrent tests
+----------------
+
+Binman tries to run tests concurrently. This means that the tests make use of
+all available CPUs to run.
+
+ To enable this:
+
+ $ sudo apt-get install python-subunit python3-subunit
+
+Use '-P 1' to disable this. It is automatically disabled when code coverage is
+being used (-T) since they are incompatible.
+
+
Advanced Features / Technical docs
----------------------------------
diff --git a/tools/binman/README.entries b/tools/binman/README.entries
index 9fc2f83280e..357946d6305 100644
--- a/tools/binman/README.entries
+++ b/tools/binman/README.entries
@@ -224,6 +224,20 @@ See README.x86 for information about x86 binary blobs.
+Entry: intel-refcode: Entry containing an Intel Reference Code file
+-------------------------------------------------------------------
+
+Properties / Entry arguments:
+ - filename: Filename of file to read into entry
+
+This file contains code for setting up the platform on some Intel systems.
+This is executed by U-Boot when needed early during startup. A typical
+filename is 'refcode.bin'.
+
+See README.x86 for information about x86 binary blobs.
+
+
+
Entry: intel-vbt: Entry containing an Intel Video BIOS Table (VBT) file
-----------------------------------------------------------------------
@@ -627,6 +641,7 @@ Entry: vblock: An entry which contains a Chromium OS verified boot block
------------------------------------------------------------------------
Properties / Entry arguments:
+ - content: List of phandles to entries to sign
- keydir: Directory containing the public keys to use
- keyblock: Name of the key file to use (inside keydir)
- signprivate: Name of provide key file to use (inside keydir)
diff --git a/tools/binman/binman.py b/tools/binman/binman.py
index 439908e6650..aad2e9c8bc4 100755
--- a/tools/binman/binman.py
+++ b/tools/binman/binman.py
@@ -9,6 +9,8 @@
"""See README for more information"""
+from __future__ import print_function
+
import glob
import multiprocessing
import os
@@ -85,13 +87,25 @@ def RunTests(debug, processes, args):
else:
suite.run(result)
- print result
+ # Remove errors which just indicate a missing test. Since Python v3.5 If an
+ # ImportError or AttributeError occurs while traversing name then a
+ # synthetic test that raises that error when run will be returned. These
+ # errors are included in the errors accumulated by result.errors.
+ if test_name:
+ errors = []
+ for test, err in result.errors:
+ if ("has no attribute '%s'" % test_name) not in err:
+ errors.append((test, err))
+ result.testsRun -= 1
+ result.errors = errors
+
+ print(result)
for test, err in result.errors:
- print test.id(), err
+ print(test.id(), err)
for test, err in result.failures:
- print err, result.failures
+ print(err, result.failures)
if result.errors or result.failures:
- print 'binman tests FAILED'
+ print('binman tests FAILED')
return 1
return 0
@@ -143,9 +157,9 @@ def RunBinman(options, args):
try:
ret_code = control.Binman(options, args)
except Exception as e:
- print 'binman: %s' % e
+ print('binman: %s' % e)
if options.debug:
- print
+ print()
traceback.print_exc()
ret_code = 1
return ret_code
diff --git a/tools/binman/bsection.py b/tools/binman/bsection.py
index 0ba542ee987..03dfa2f805c 100644
--- a/tools/binman/bsection.py
+++ b/tools/binman/bsection.py
@@ -8,7 +8,6 @@
from __future__ import print_function
from collections import OrderedDict
-from sets import Set
import sys
import fdt_util
@@ -109,7 +108,7 @@ class Section(object):
def GetFdtSet(self):
"""Get the set of device tree files used by this image"""
- fdt_set = Set()
+ fdt_set = set()
for entry in self._entries.values():
fdt_set.update(entry.GetFdtSet())
return fdt_set
@@ -254,7 +253,7 @@ class Section(object):
"""
for entry in self._entries.values():
offset_dict = entry.GetOffsets()
- for name, info in offset_dict.iteritems():
+ for name, info in offset_dict.items():
self._SetEntryOffsetSize(name, *info)
def PackEntries(self):
@@ -333,7 +332,7 @@ class Section(object):
def GetData(self):
"""Get the contents of the section"""
- section_data = chr(self._pad_byte) * self._size
+ section_data = tools.GetBytes(self._pad_byte, self._size)
for entry in self._entries.values():
data = entry.GetData()
diff --git a/tools/binman/control.py b/tools/binman/control.py
index b32e4e1996f..20186ee1980 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -5,6 +5,8 @@
# Creates binary images from input files controlled by a description
#
+from __future__ import print_function
+
from collections import OrderedDict
import os
import sys
@@ -129,12 +131,15 @@ def Binman(options, args):
if options.image:
skip = []
- for name, image in images.iteritems():
- if name not in options.image:
- del images[name]
+ new_images = OrderedDict()
+ for name, image in images.items():
+ if name in options.image:
+ new_images[name] = image
+ else:
skip.append(name)
+ images = new_images
if skip and options.verbosity >= 2:
- print 'Skipping images: %s' % ', '.join(skip)
+ print('Skipping images: %s' % ', '.join(skip))
state.Prepare(images, dtb)
@@ -170,7 +175,7 @@ def Binman(options, args):
except Exception as e:
if options.map:
fname = image.WriteMap()
- print "Wrote map file '%s' to show errors" % fname
+ print("Wrote map file '%s' to show errors" % fname)
raise
image.SetImagePos()
if options.update_fdt:
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index 97df8e32c5d..828681d76d0 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -59,7 +59,7 @@ def GetSymbols(fname, patterns):
flags[1] == 'w')
# Sort dict by address
- return OrderedDict(sorted(syms.iteritems(), key=lambda x: x[1].address))
+ return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
def GetSymbolAddress(fname, sym_name):
"""Get a value of a symbol from an ELF file
@@ -98,7 +98,7 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
base = syms.get('__image_copy_start')
if not base:
return
- for name, sym in syms.iteritems():
+ for name, sym in syms.items():
if name.startswith('_binman'):
msg = ("Section '%s': Symbol '%s'\n in entry '%s'" %
(section.GetPath(), name, entry.GetPath()))
diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py
index b68530c19ba..42d94cbbbe2 100644
--- a/tools/binman/elf_test.py
+++ b/tools/binman/elf_test.py
@@ -22,7 +22,7 @@ class FakeEntry:
"""
def __init__(self, contents_size):
self.contents_size = contents_size
- self.data = 'a' * contents_size
+ self.data = tools.GetBytes(ord('a'), contents_size)
def GetPath(self):
return 'entry_path'
@@ -122,7 +122,8 @@ class TestElf(unittest.TestCase):
section = FakeSection(sym_value=None)
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
- self.assertEqual(chr(255) * 16 + 'a' * 4, entry.data)
+ self.assertEqual(tools.GetBytes(255, 16) + tools.GetBytes(ord('a'), 4),
+ entry.data)
def testDebug(self):
"""Check that enabling debug in the elf module produced debug output"""
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 648cfd241f1..d842d89dd66 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -18,7 +18,6 @@ except:
have_importlib = False
import os
-from sets import Set
import sys
import fdt_util
@@ -178,8 +177,8 @@ class Entry(object):
# It would be better to use isinstance(self, Entry_blob_dtb) here but
# we cannot access Entry_blob_dtb
if fname and fname.endswith('.dtb'):
- return Set([fname])
- return Set()
+ return set([fname])
+ return set()
def ExpandEntries(self):
pass
diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py
index 1f7ff5b4e41..b30a7beecc8 100644
--- a/tools/binman/entry_test.py
+++ b/tools/binman/entry_test.py
@@ -41,7 +41,11 @@ class TestEntry(unittest.TestCase):
del sys.modules['importlib']
global entry
if entry:
- reload(entry)
+ if sys.version_info[0] >= 3:
+ import importlib
+ importlib.reload(entry)
+ else:
+ reload(entry)
else:
import entry
entry.Entry.Create(None, self.GetNode(), 'u-boot-spl')
diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py
index 3e345bd9526..ac62d2e2005 100644
--- a/tools/binman/etype/_testing.py
+++ b/tools/binman/etype/_testing.py
@@ -75,7 +75,7 @@ class Entry__testing(Entry):
def ObtainContents(self):
if self.return_unknown_contents or not self.return_contents:
return False
- self.data = 'a'
+ self.data = b'a'
self.contents_size = len(self.data)
if self.return_contents_once:
self.return_contents = False
diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py
index ae80bbee530..f56a1f87688 100644
--- a/tools/binman/etype/blob.py
+++ b/tools/binman/etype/blob.py
@@ -60,7 +60,7 @@ class Entry_blob(Entry):
except AttributeError:
data = lz4.compress(data)
'''
- data = tools.Run('lz4', '-c', self._pathname)
+ data = tools.Run('lz4', '-c', self._pathname, binary=True)
self.SetContents(data)
return True
diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py
index dcfe978a5bf..68efe42ec0b 100644
--- a/tools/binman/etype/fill.py
+++ b/tools/binman/etype/fill.py
@@ -5,7 +5,7 @@
from entry import Entry
import fdt_util
-
+import tools
class Entry_fill(Entry):
"""An entry which is filled to a particular byte value
@@ -28,5 +28,5 @@ class Entry_fill(Entry):
self.fill_value = fdt_util.GetByte(self._node, 'fill-byte', 0)
def ObtainContents(self):
- self.SetContents(chr(self.fill_value) * self.size)
+ self.SetContents(tools.GetBytes(self.fill_value, self.size))
return True
diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py
index bf35a5bbf4e..e6b5c5c74c0 100644
--- a/tools/binman/etype/fmap.py
+++ b/tools/binman/etype/fmap.py
@@ -7,6 +7,7 @@
from entry import Entry
import fmap_util
+import tools
class Entry_fmap(Entry):
@@ -46,7 +47,7 @@ class Entry_fmap(Entry):
if pos is not None:
pos -= entry.section.GetRootSkipAtStart()
areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0,
- entry.name, 0))
+ tools.FromUnicode(entry.name), 0))
entries = self.section._image.GetEntries()
areas = []
diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py
index 8fe10f47135..a94c0fca9d5 100644
--- a/tools/binman/etype/gbb.py
+++ b/tools/binman/etype/gbb.py
@@ -64,7 +64,7 @@ class Entry_gbb(Entry):
self.gbb_flags = 0
flags_node = node.FindNode('flags')
if flags_node:
- for flag, value in gbb_flag_properties.iteritems():
+ for flag, value in gbb_flag_properties.items():
if fdt_util.GetBool(flags_node, flag):
self.gbb_flags |= value
diff --git a/tools/binman/etype/text.py b/tools/binman/etype/text.py
index c4aa510a87b..9ee04d7c9d8 100644
--- a/tools/binman/etype/text.py
+++ b/tools/binman/etype/text.py
@@ -7,6 +7,7 @@ from collections import OrderedDict
from entry import Entry, EntryArg
import fdt_util
+import tools
class Entry_text(Entry):
@@ -48,9 +49,11 @@ class Entry_text(Entry):
"""
def __init__(self, section, etype, node):
Entry.__init__(self, section, etype, node)
- self.text_label, = self.GetEntryArgsOrProps(
- [EntryArg('text-label', str)])
- self.value, = self.GetEntryArgsOrProps([EntryArg(self.text_label, str)])
+ label, = self.GetEntryArgsOrProps([EntryArg('text-label', str)])
+ self.text_label = tools.ToStr(label) if type(label) != str else label
+ value, = self.GetEntryArgsOrProps([EntryArg(self.text_label, str)])
+ value = tools.ToBytes(value) if value is not None else value
+ self.value = value
def ObtainContents(self):
if not self.value:
diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py
index 444c51b8b72..188888e022b 100644
--- a/tools/binman/etype/u_boot_dtb_with_ucode.py
+++ b/tools/binman/etype/u_boot_dtb_with_ucode.py
@@ -26,7 +26,7 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
"""
def __init__(self, section, etype, node):
Entry_blob_dtb.__init__(self, section, etype, node)
- self.ucode_data = ''
+ self.ucode_data = b''
self.collate = False
self.ucode_offset = None
self.ucode_size = None
@@ -65,7 +65,7 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
for node in self.ucode.subnodes:
data_prop = node.props.get('data')
if data_prop:
- self.ucode_data += ''.join(data_prop.bytes)
+ self.ucode_data += data_prop.bytes
if self.collate:
node.DeleteProp('data')
return True
diff --git a/tools/binman/etype/u_boot_spl_bss_pad.py b/tools/binman/etype/u_boot_spl_bss_pad.py
index 00b7ac50040..66a296a6f85 100644
--- a/tools/binman/etype/u_boot_spl_bss_pad.py
+++ b/tools/binman/etype/u_boot_spl_bss_pad.py
@@ -38,5 +38,5 @@ class Entry_u_boot_spl_bss_pad(Entry_blob):
bss_size = elf.GetSymbolAddress(fname, '__bss_size')
if not bss_size:
self.Raise('Expected __bss_size symbol in spl/u-boot-spl')
- self.SetContents(chr(0) * bss_size)
+ self.SetContents(tools.GetBytes(0, bss_size))
return True
diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py
index a00e530295b..dee8848db7a 100644
--- a/tools/binman/etype/u_boot_ucode.py
+++ b/tools/binman/etype/u_boot_ucode.py
@@ -69,7 +69,7 @@ class Entry_u_boot_ucode(Entry_blob):
if entry and entry.target_offset:
found = True
if not found:
- self.data = ''
+ self.data = b''
return True
# Get the microcode from the device tree entry. If it is not available
# yet, return False so we will be called later. If the section simply
@@ -87,7 +87,7 @@ class Entry_u_boot_ucode(Entry_blob):
if not fdt_entry.collate:
# This binary can be empty
- self.data = ''
+ self.data = b''
return True
# Write it out to a file
diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py
index 334ff9f966a..91fa2f7808f 100644
--- a/tools/binman/etype/vblock.py
+++ b/tools/binman/etype/vblock.py
@@ -51,7 +51,7 @@ class Entry_vblock(Entry):
def ObtainContents(self):
# Join up the data files to be signed
- input_data = ''
+ input_data = b''
for entry_phandle in self.content:
data = self.section.GetContentsByPhandle(entry_phandle, self)
if data is None:
diff --git a/tools/binman/fmap_util.py b/tools/binman/fmap_util.py
index be3cbee87bd..d0f956b6221 100644
--- a/tools/binman/fmap_util.py
+++ b/tools/binman/fmap_util.py
@@ -8,9 +8,12 @@
import collections
import struct
+import sys
+
+import tools
# constants imported from lib/fmap.h
-FMAP_SIGNATURE = '__FMAP__'
+FMAP_SIGNATURE = b'__FMAP__'
FMAP_VER_MAJOR = 1
FMAP_VER_MINOR = 0
FMAP_STRLEN = 32
@@ -50,6 +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)
return name.replace('\0', '').replace('-', '_').upper()
def ConvertName(field_names, fields):
@@ -65,7 +70,7 @@ def ConvertName(field_names, fields):
value: value of that field (string for the ones we support)
"""
name_index = field_names.index('name')
- fields[name_index] = NameToFmap(fields[name_index])
+ fields[name_index] = tools.ToBytes(NameToFmap(fields[name_index]))
def DecodeFmap(data):
"""Decode a flashmap into a header and list of areas
@@ -106,7 +111,8 @@ def EncodeFmap(image_size, name, areas):
ConvertName(names, params)
return struct.pack(fmt, *params)
- values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size, name, len(areas))
+ values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size,
+ tools.FromUnicode(name), len(areas))
blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, values)
for area in areas:
blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, area)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index daea1ea1382..cc57ef3e04a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -29,38 +29,38 @@ import tools
import tout
# Contents of test files, corresponding to different entry types
-U_BOOT_DATA = '1234'
-U_BOOT_IMG_DATA = 'img'
-U_BOOT_SPL_DATA = '56780123456789abcde'
-U_BOOT_TPL_DATA = 'tpl'
-BLOB_DATA = '89'
-ME_DATA = '0abcd'
-VGA_DATA = 'vga'
-U_BOOT_DTB_DATA = 'udtb'
-U_BOOT_SPL_DTB_DATA = 'spldtb'
-U_BOOT_TPL_DTB_DATA = 'tpldtb'
-X86_START16_DATA = 'start16'
-X86_START16_SPL_DATA = 'start16spl'
-X86_START16_TPL_DATA = 'start16tpl'
-PPC_MPC85XX_BR_DATA = 'ppcmpc85xxbr'
-U_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here'
-U_BOOT_SPL_NODTB_DATA = 'splnodtb with microcode pointer somewhere in here'
-U_BOOT_TPL_NODTB_DATA = 'tplnodtb with microcode pointer somewhere in here'
-FSP_DATA = 'fsp'
-CMC_DATA = 'cmc'
-VBT_DATA = 'vbt'
-MRC_DATA = 'mrc'
+U_BOOT_DATA = b'1234'
+U_BOOT_IMG_DATA = b'img'
+U_BOOT_SPL_DATA = b'56780123456789abcde'
+U_BOOT_TPL_DATA = b'tpl'
+BLOB_DATA = b'89'
+ME_DATA = b'0abcd'
+VGA_DATA = b'vga'
+U_BOOT_DTB_DATA = b'udtb'
+U_BOOT_SPL_DTB_DATA = b'spldtb'
+U_BOOT_TPL_DTB_DATA = b'tpldtb'
+X86_START16_DATA = b'start16'
+X86_START16_SPL_DATA = b'start16spl'
+X86_START16_TPL_DATA = b'start16tpl'
+PPC_MPC85XX_BR_DATA = b'ppcmpc85xxbr'
+U_BOOT_NODTB_DATA = b'nodtb with microcode pointer somewhere in here'
+U_BOOT_SPL_NODTB_DATA = b'splnodtb with microcode pointer somewhere in here'
+U_BOOT_TPL_NODTB_DATA = b'tplnodtb with microcode pointer somewhere in here'
+FSP_DATA = b'fsp'
+CMC_DATA = b'cmc'
+VBT_DATA = b'vbt'
+MRC_DATA = b'mrc'
TEXT_DATA = 'text'
TEXT_DATA2 = 'text2'
TEXT_DATA3 = 'text3'
-CROS_EC_RW_DATA = 'ecrw'
-GBB_DATA = 'gbbd'
-BMPBLK_DATA = 'bmp'
-VBLOCK_DATA = 'vblk'
-FILES_DATA = ("sorry I'm late\nOh, don't bother apologising, I'm " +
- "sorry you're alive\n")
-COMPRESS_DATA = 'data to compress'
-REFCODE_DATA = 'refcode'
+CROS_EC_RW_DATA = b'ecrw'
+GBB_DATA = b'gbbd'
+BMPBLK_DATA = b'bmp'
+VBLOCK_DATA = b'vblk'
+FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " +
+ b"sorry you're alive\n")
+COMPRESS_DATA = b'data to compress'
+REFCODE_DATA = b'refcode'
class TestFunctional(unittest.TestCase):
@@ -119,11 +119,11 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA)
# ELF file with a '_dt_ucode_base_size' symbol
- with open(self.TestFile('u_boot_ucode_ptr')) as fd:
+ with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
TestFunctional._MakeInputFile('u-boot', fd.read())
# Intel flash descriptor file
- with open(self.TestFile('descriptor.bin')) as fd:
+ with open(self.TestFile('descriptor.bin'), 'rb') as fd:
TestFunctional._MakeInputFile('descriptor.bin', fd.read())
shutil.copytree(self.TestFile('files'),
@@ -214,7 +214,7 @@ class TestFunctional(unittest.TestCase):
if verbosity is not None:
args.append('-v%d' % verbosity)
if entry_args:
- for arg, value in entry_args.iteritems():
+ for arg, value in entry_args.items():
args.append('-a%s=%s' % (arg, value))
if images:
for image in images:
@@ -236,7 +236,7 @@ class TestFunctional(unittest.TestCase):
"""
tools.PrepareOutputDir(None)
dtb = fdt_util.EnsureCompiled(self.TestFile(fname))
- with open(dtb) as fd:
+ with open(dtb, 'rb') as fd:
data = fd.read()
TestFunctional._MakeInputFile(outfile, data)
tools.FinaliseOutputDir()
@@ -291,7 +291,6 @@ class TestFunctional(unittest.TestCase):
# Use the compiled test file as the u-boot-dtb input
if use_real_dtb:
dtb_data = self._SetupDtb(fname)
- infile = os.path.join(self._indir, 'u-boot.dtb')
# For testing purposes, make a copy of the DT for SPL and TPL. Add
# a node indicating which it is, so aid verification.
@@ -317,7 +316,7 @@ class TestFunctional(unittest.TestCase):
map_data = fd.read()
else:
map_data = None
- with open(image_fname) as fd:
+ with open(image_fname, 'rb') as fd:
return fd.read(), dtb_data, map_data, out_dtb_fname
finally:
# Put the test file back
@@ -379,7 +378,7 @@ class TestFunctional(unittest.TestCase):
Args:
Filename of ELF file to use as SPL
"""
- with open(self.TestFile(src_fname)) as fd:
+ with open(self.TestFile(src_fname), 'rb') as fd:
TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
@classmethod
@@ -396,7 +395,7 @@ class TestFunctional(unittest.TestCase):
for grep in grep_list:
if grep in target:
return
- self.fail("Error: '%' not found in '%s'" % (grep_list, target))
+ self.fail("Error: '%s' not found in '%s'" % (grep_list, target))
def CheckNoGaps(self, entries):
"""Check that all entries fit together without gaps
@@ -541,7 +540,7 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(len(U_BOOT_DATA), image._size)
fname = tools.GetOutputFilename('image1.bin')
self.assertTrue(os.path.exists(fname))
- with open(fname) as fd:
+ with open(fname, 'rb') as fd:
data = fd.read()
self.assertEqual(U_BOOT_DATA, data)
@@ -549,11 +548,11 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(3 + len(U_BOOT_DATA) + 5, image._size)
fname = tools.GetOutputFilename('image2.bin')
self.assertTrue(os.path.exists(fname))
- with open(fname) as fd:
+ with open(fname, 'rb') as fd:
data = fd.read()
self.assertEqual(U_BOOT_DATA, data[3:7])
- self.assertEqual(chr(0) * 3, data[:3])
- self.assertEqual(chr(0) * 5, data[7:])
+ self.assertEqual(tools.GetBytes(0, 3), data[:3])
+ self.assertEqual(tools.GetBytes(0, 5), data[7:])
def testBadAlign(self):
"""Test that an invalid alignment value is detected"""
@@ -732,7 +731,8 @@ class TestFunctional(unittest.TestCase):
"""Test that the image pad byte can be specified"""
self._SetupSplElf()
data = self._DoReadFile('021_image_pad.dts')
- self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 1) + U_BOOT_DATA, data)
+ self.assertEqual(U_BOOT_SPL_DATA + tools.GetBytes(0xff, 1) +
+ U_BOOT_DATA, data)
def testImageName(self):
"""Test that image files can be named"""
@@ -755,8 +755,8 @@ class TestFunctional(unittest.TestCase):
"""Test that entries can be sorted"""
self._SetupSplElf()
data = self._DoReadFile('024_sorted.dts')
- self.assertEqual(chr(0) * 1 + U_BOOT_SPL_DATA + chr(0) * 2 +
- U_BOOT_DATA, data)
+ self.assertEqual(tools.GetBytes(0, 1) + U_BOOT_SPL_DATA +
+ tools.GetBytes(0, 2) + U_BOOT_DATA, data)
def testPackZeroOffset(self):
"""Test that an entry at offset 0 is not given a new offset"""
@@ -798,12 +798,12 @@ class TestFunctional(unittest.TestCase):
"""Test that a basic x86 ROM can be created"""
self._SetupSplElf()
data = self._DoReadFile('029_x86-rom.dts')
- self.assertEqual(U_BOOT_DATA + chr(0) * 7 + U_BOOT_SPL_DATA +
- chr(0) * 2, data)
+ self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA +
+ tools.GetBytes(0, 2), data)
def testPackX86RomMeNoDesc(self):
"""Test that an invalid Intel descriptor entry is detected"""
- TestFunctional._MakeInputFile('descriptor.bin', '')
+ TestFunctional._MakeInputFile('descriptor.bin', b'')
with self.assertRaises(ValueError) as e:
self._DoTestFile('031_x86-rom-me.dts')
self.assertIn("Node '/binman/intel-descriptor': Cannot find FD "
@@ -900,8 +900,8 @@ class TestFunctional(unittest.TestCase):
"""
first, pos_and_size = self._RunMicrocodeTest('034_x86_ucode.dts',
U_BOOT_NODTB_DATA)
- self.assertEqual('nodtb with microcode' + pos_and_size +
- ' somewhere in here', first)
+ self.assertEqual(b'nodtb with microcode' + pos_and_size +
+ b' somewhere in here', first)
def _RunPackUbootSingleMicrocode(self):
"""Test that x86 microcode can be handled correctly
@@ -932,8 +932,8 @@ class TestFunctional(unittest.TestCase):
pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos,
len(ucode_data))
first = data[:len(U_BOOT_NODTB_DATA)]
- self.assertEqual('nodtb with microcode' + pos_and_size +
- ' somewhere in here', first)
+ self.assertEqual(b'nodtb with microcode' + pos_and_size +
+ b' somewhere in here', first)
def testPackUbootSingleMicrocode(self):
"""Test that x86 microcode can be handled correctly with fdt_normal.
@@ -970,7 +970,7 @@ class TestFunctional(unittest.TestCase):
"""Test that a U-Boot binary without the microcode symbol is detected"""
# ELF file without a '_dt_ucode_base_size' symbol
try:
- with open(self.TestFile('u_boot_no_ucode_ptr')) as fd:
+ with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
TestFunctional._MakeInputFile('u-boot', fd.read())
with self.assertRaises(ValueError) as e:
@@ -980,7 +980,7 @@ class TestFunctional(unittest.TestCase):
finally:
# Put the original file back
- with open(self.TestFile('u_boot_ucode_ptr')) as fd:
+ with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
TestFunctional._MakeInputFile('u-boot', fd.read())
def testMicrocodeNotInImage(self):
@@ -993,7 +993,7 @@ class TestFunctional(unittest.TestCase):
def testWithoutMicrocode(self):
"""Test that we can cope with an image without microcode (e.g. qemu)"""
- with open(self.TestFile('u_boot_no_ucode_ptr')) as fd:
+ with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
TestFunctional._MakeInputFile('u-boot', fd.read())
data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True)
@@ -1006,7 +1006,7 @@ class TestFunctional(unittest.TestCase):
used_len = len(U_BOOT_NODTB_DATA) + fdt_len
third = data[used_len:]
- self.assertEqual(chr(0) * (0x200 - used_len), third)
+ self.assertEqual(tools.GetBytes(0, 0x200 - used_len), third)
def testUnknownPosSize(self):
"""Test that microcode must be placed within the image"""
@@ -1035,7 +1035,8 @@ class TestFunctional(unittest.TestCase):
# ELF file with a '__bss_size' symbol
self._SetupSplElf()
data = self._DoReadFile('047_spl_bss_pad.dts')
- self.assertEqual(U_BOOT_SPL_DATA + (chr(0) * 10) + U_BOOT_DATA, data)
+ self.assertEqual(U_BOOT_SPL_DATA + tools.GetBytes(0, 10) + U_BOOT_DATA,
+ data)
def testSplBssPadMissing(self):
"""Test that a missing symbol is detected"""
@@ -1067,8 +1068,8 @@ class TestFunctional(unittest.TestCase):
self._SetupSplElf('u_boot_ucode_ptr')
first, pos_and_size = self._RunMicrocodeTest(dts, U_BOOT_SPL_NODTB_DATA,
ucode_second=ucode_second)
- self.assertEqual('splnodtb with microc' + pos_and_size +
- 'ter somewhere in here', first)
+ self.assertEqual(b'splnodtb with microc' + pos_and_size +
+ b'ter somewhere in here', first)
def testPackUbootSplMicrocode(self):
"""Test that x86 microcode can be handled correctly in SPL"""
@@ -1109,9 +1110,9 @@ class TestFunctional(unittest.TestCase):
self._SetupSplElf('u_boot_binman_syms')
data = self._DoReadFile('053_symbols.dts')
sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20)
- expected = (sym_values + U_BOOT_SPL_DATA[16:] + chr(0xff) +
- U_BOOT_DATA +
- sym_values + U_BOOT_SPL_DATA[16:])
+ expected = (sym_values + U_BOOT_SPL_DATA[16:] +
+ tools.GetBytes(0xff, 1) + U_BOOT_DATA + sym_values +
+ U_BOOT_SPL_DATA[16:])
self.assertEqual(expected, data)
def testPackUnitAddress(self):
@@ -1122,8 +1123,9 @@ class TestFunctional(unittest.TestCase):
def testSections(self):
"""Basic test of sections"""
data = self._DoReadFile('055_sections.dts')
- expected = (U_BOOT_DATA + '!' * 12 + U_BOOT_DATA + 'a' * 12 +
- U_BOOT_DATA + '&' * 4)
+ expected = (U_BOOT_DATA + tools.GetBytes(ord('!'), 12) +
+ U_BOOT_DATA + tools.GetBytes(ord('a'), 12) +
+ U_BOOT_DATA + tools.GetBytes(ord('&'), 4))
self.assertEqual(expected, data)
def testMap(self):
@@ -1281,8 +1283,10 @@ class TestFunctional(unittest.TestCase):
}
data, _, _, _ = self._DoReadFileDtb('066_text.dts',
entry_args=entry_args)
- expected = (TEXT_DATA + chr(0) * (8 - len(TEXT_DATA)) + TEXT_DATA2 +
- TEXT_DATA3 + 'some text')
+ expected = (tools.ToBytes(TEXT_DATA) +
+ tools.GetBytes(0, 8 - len(TEXT_DATA)) +
+ tools.ToBytes(TEXT_DATA2) + tools.ToBytes(TEXT_DATA3) +
+ b'some text')
self.assertEqual(expected, data)
def testEntryDocs(self):
@@ -1303,32 +1307,33 @@ class TestFunctional(unittest.TestCase):
"""Basic test of generation of a flashrom fmap"""
data = self._DoReadFile('067_fmap.dts')
fhdr, fentries = fmap_util.DecodeFmap(data[32:])
- expected = U_BOOT_DATA + '!' * 12 + U_BOOT_DATA + 'a' * 12
+ expected = (U_BOOT_DATA + tools.GetBytes(ord('!'), 12) +
+ U_BOOT_DATA + tools.GetBytes(ord('a'), 12))
self.assertEqual(expected, data[:32])
- self.assertEqual('__FMAP__', fhdr.signature)
+ self.assertEqual(b'__FMAP__', fhdr.signature)
self.assertEqual(1, fhdr.ver_major)
self.assertEqual(0, fhdr.ver_minor)
self.assertEqual(0, fhdr.base)
self.assertEqual(16 + 16 +
fmap_util.FMAP_HEADER_LEN +
fmap_util.FMAP_AREA_LEN * 3, fhdr.image_size)
- self.assertEqual('FMAP', fhdr.name)
+ self.assertEqual(b'FMAP', fhdr.name)
self.assertEqual(3, fhdr.nareas)
for fentry in fentries:
self.assertEqual(0, fentry.flags)
self.assertEqual(0, fentries[0].offset)
self.assertEqual(4, fentries[0].size)
- self.assertEqual('RO_U_BOOT', fentries[0].name)
+ self.assertEqual(b'RO_U_BOOT', fentries[0].name)
self.assertEqual(16, fentries[1].offset)
self.assertEqual(4, fentries[1].size)
- self.assertEqual('RW_U_BOOT', fentries[1].name)
+ self.assertEqual(b'RW_U_BOOT', fentries[1].name)
self.assertEqual(32, fentries[2].offset)
self.assertEqual(fmap_util.FMAP_HEADER_LEN +
fmap_util.FMAP_AREA_LEN * 3, fentries[2].size)
- self.assertEqual('FMAP', fentries[2].name)
+ self.assertEqual(b'FMAP', fentries[2].name)
def testBlobNamedByArg(self):
"""Test we can add a blob with the filename coming from an entry arg"""
@@ -1341,7 +1346,7 @@ class TestFunctional(unittest.TestCase):
def testFill(self):
"""Test for an fill entry type"""
data = self._DoReadFile('069_fill.dts')
- expected = 8 * chr(0xff) + 8 * chr(0)
+ expected = tools.GetBytes(0xff, 8) + tools.GetBytes(0, 8)
self.assertEqual(expected, data)
def testFillNoSize(self):
@@ -1357,7 +1362,7 @@ class TestFunctional(unittest.TestCase):
fname = pipe_list[0][-1]
# Append our GBB data to the file, which will happen every time the
# futility command is called.
- with open(fname, 'a') as fd:
+ with open(fname, 'ab') as fd:
fd.write(GBB_DATA)
return command.CommandResult()
@@ -1371,7 +1376,8 @@ class TestFunctional(unittest.TestCase):
data, _, _, _ = self._DoReadFileDtb('071_gbb.dts', entry_args=entry_args)
# Since futility
- expected = GBB_DATA + GBB_DATA + 8 * chr(0) + (0x2180 - 16) * chr(0)
+ expected = (GBB_DATA + GBB_DATA + tools.GetBytes(0, 8) +
+ tools.GetBytes(0, 0x2180 - 16))
self.assertEqual(expected, data)
def testGbbTooSmall(self):
@@ -1431,7 +1437,7 @@ class TestFunctional(unittest.TestCase):
def testTpl(self):
"""Test that an image with TPL and ots device tree can be created"""
# ELF file with a '__bss_size' symbol
- with open(self.TestFile('bss_data')) as fd:
+ with open(self.TestFile('bss_data'), 'rb') as fd:
TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
data = self._DoReadFile('078_u_boot_tpl.dts')
self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data)
@@ -1446,7 +1452,7 @@ class TestFunctional(unittest.TestCase):
def testFillZero(self):
"""Test for an fill entry type with a size of 0"""
data = self._DoReadFile('080_fill_empty.dts')
- self.assertEqual(chr(0) * 16, data)
+ self.assertEqual(tools.GetBytes(0, 16), data)
def testTextMissing(self):
"""Test for a text entry type where there is no text"""
@@ -1557,7 +1563,7 @@ class TestFunctional(unittest.TestCase):
out = os.path.join(self._indir, 'lz4.tmp')
with open(out, 'wb') as fd:
fd.write(data)
- return tools.Run('lz4', '-dc', out)
+ return tools.Run('lz4', '-dc', out, binary=True)
'''
try:
orig = lz4.frame.decompress(data)
@@ -1595,7 +1601,7 @@ class TestFunctional(unittest.TestCase):
files = entries['files']
entries = files._section._entries
- orig = ''
+ orig = b''
for i in range(1, 3):
key = '%d.dat' % i
start = entries[key].image_pos
@@ -1623,10 +1629,10 @@ class TestFunctional(unittest.TestCase):
"""Test an expanding entry"""
data, _, map_data, _ = self._DoReadFileDtb('088_expand_size.dts',
map=True)
- expect = ('a' * 8 + U_BOOT_DATA +
- MRC_DATA + 'b' * 1 + U_BOOT_DATA +
- 'c' * 8 + U_BOOT_DATA +
- 'd' * 8)
+ expect = (tools.GetBytes(ord('a'), 8) + U_BOOT_DATA +
+ MRC_DATA + tools.GetBytes(ord('b'), 1) + U_BOOT_DATA +
+ tools.GetBytes(ord('c'), 8) + U_BOOT_DATA +
+ tools.GetBytes(ord('d'), 8))
self.assertEqual(expect, data)
self.assertEqual('''ImagePos Offset Size Name
00000000 00000000 00000028 main-section
@@ -1658,7 +1664,7 @@ class TestFunctional(unittest.TestCase):
hash_node = dtb.GetNode('/binman/u-boot/hash').props['value']
m = hashlib.sha256()
m.update(U_BOOT_DATA)
- self.assertEqual(m.digest(), ''.join(hash_node.value))
+ self.assertEqual(m.digest(), b''.join(hash_node.value))
def testHashNoAlgo(self):
with self.assertRaises(ValueError) as e:
@@ -1681,8 +1687,8 @@ class TestFunctional(unittest.TestCase):
hash_node = dtb.GetNode('/binman/section/hash').props['value']
m = hashlib.sha256()
m.update(U_BOOT_DATA)
- m.update(16 * 'a')
- self.assertEqual(m.digest(), ''.join(hash_node.value))
+ m.update(tools.GetBytes(ord('a'), 16))
+ self.assertEqual(m.digest(), b''.join(hash_node.value))
def testPackUBootTplMicrocode(self):
"""Test that x86 microcode can be handled correctly in TPL
@@ -1693,18 +1699,18 @@ class TestFunctional(unittest.TestCase):
u-boot-tpl.dtb with the microcode removed
the microcode
"""
- with open(self.TestFile('u_boot_ucode_ptr')) as fd:
+ with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts',
U_BOOT_TPL_NODTB_DATA)
- self.assertEqual('tplnodtb with microc' + pos_and_size +
- 'ter somewhere in here', first)
+ self.assertEqual(b'tplnodtb with microc' + pos_and_size +
+ b'ter somewhere in here', first)
def testFmapX86(self):
"""Basic test of generation of a flashrom fmap"""
data = self._DoReadFile('094_fmap_x86.dts')
fhdr, fentries = fmap_util.DecodeFmap(data[32:])
- expected = U_BOOT_DATA + MRC_DATA + 'a' * (32 - 7)
+ expected = U_BOOT_DATA + MRC_DATA + tools.GetBytes(ord('a'), 32 - 7)
self.assertEqual(expected, data[:32])
fhdr, fentries = fmap_util.DecodeFmap(data[32:])
@@ -1712,21 +1718,21 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(0, fentries[0].offset)
self.assertEqual(4, fentries[0].size)
- self.assertEqual('U_BOOT', fentries[0].name)
+ self.assertEqual(b'U_BOOT', fentries[0].name)
self.assertEqual(4, fentries[1].offset)
self.assertEqual(3, fentries[1].size)
- self.assertEqual('INTEL_MRC', fentries[1].name)
+ self.assertEqual(b'INTEL_MRC', fentries[1].name)
self.assertEqual(32, fentries[2].offset)
self.assertEqual(fmap_util.FMAP_HEADER_LEN +
fmap_util.FMAP_AREA_LEN * 3, fentries[2].size)
- self.assertEqual('FMAP', fentries[2].name)
+ self.assertEqual(b'FMAP', fentries[2].name)
def testFmapX86Section(self):
"""Basic test of generation of a flashrom fmap"""
data = self._DoReadFile('095_fmap_x86_section.dts')
- expected = U_BOOT_DATA + MRC_DATA + 'b' * (32 - 7)
+ expected = U_BOOT_DATA + MRC_DATA + tools.GetBytes(ord('b'), 32 - 7)
self.assertEqual(expected, data[:32])
fhdr, fentries = fmap_util.DecodeFmap(data[36:])
@@ -1734,28 +1740,28 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(0, fentries[0].offset)
self.assertEqual(4, fentries[0].size)
- self.assertEqual('U_BOOT', fentries[0].name)
+ self.assertEqual(b'U_BOOT', fentries[0].name)
self.assertEqual(4, fentries[1].offset)
self.assertEqual(3, fentries[1].size)
- self.assertEqual('INTEL_MRC', fentries[1].name)
+ self.assertEqual(b'INTEL_MRC', fentries[1].name)
self.assertEqual(36, fentries[2].offset)
self.assertEqual(fmap_util.FMAP_HEADER_LEN +
fmap_util.FMAP_AREA_LEN * 3, fentries[2].size)
- self.assertEqual('FMAP', fentries[2].name)
+ self.assertEqual(b'FMAP', fentries[2].name)
def testElf(self):
"""Basic test of ELF entries"""
self._SetupSplElf()
- with open(self.TestFile('bss_data')) as fd:
+ with open(self.TestFile('bss_data'), 'rb') as fd:
TestFunctional._MakeInputFile('-boot', fd.read())
data = self._DoReadFile('096_elf.dts')
def testElfStripg(self):
"""Basic test of ELF entries"""
self._SetupSplElf()
- with open(self.TestFile('bss_data')) as fd:
+ with open(self.TestFile('bss_data'), 'rb') as fd:
TestFunctional._MakeInputFile('-boot', fd.read())
data = self._DoReadFile('097_elf_strip.dts')
@@ -1771,7 +1777,7 @@ class TestFunctional(unittest.TestCase):
# We should not get an inmage, but there should be a map file
self.assertFalse(os.path.exists(tools.GetOutputFilename('image.bin')))
self.assertTrue(os.path.exists(map_fname))
- map_data = tools.ReadFile(map_fname)
+ map_data = tools.ReadFile(map_fname, binary=False)
self.assertEqual('''ImagePos Offset Size Name
<none> 00000000 00000007 main-section
<none> 00000000 00000004 u-boot
@@ -1797,9 +1803,12 @@ class TestFunctional(unittest.TestCase):
0000002c 00000000 00000004 u-boot
''', map_data)
self.assertEqual(data,
- 4 * chr(0x26) + U_BOOT_DATA + 12 * chr(0x21) +
- 4 * chr(0x26) + U_BOOT_DATA + 12 * chr(0x61) +
- 4 * chr(0x26) + U_BOOT_DATA + 8 * chr(0x26))
+ tools.GetBytes(0x26, 4) + U_BOOT_DATA +
+ tools.GetBytes(0x21, 12) +
+ tools.GetBytes(0x26, 4) + U_BOOT_DATA +
+ tools.GetBytes(0x61, 12) +
+ tools.GetBytes(0x26, 4) + U_BOOT_DATA +
+ tools.GetBytes(0x26, 8))
if __name__ == "__main__":
diff --git a/tools/binman/state.py b/tools/binman/state.py
index d945e4bf657..af9678649cd 100644
--- a/tools/binman/state.py
+++ b/tools/binman/state.py
@@ -7,7 +7,6 @@
import hashlib
import re
-from sets import Set
import os
import tools
@@ -24,10 +23,10 @@ entry_args = {}
use_fake_dtb = False
# Set of all device tree files references by images
-fdt_set = Set()
+fdt_set = set()
# Same as above, but excluding the main one
-fdt_subset = Set()
+fdt_subset = set()
# The DTB which contains the full image information
main_dtb = None
@@ -136,7 +135,7 @@ def Prepare(images, dtb):
main_dtb = dtb
fdt_files.clear()
fdt_files['u-boot.dtb'] = dtb
- fdt_subset = Set()
+ fdt_subset = set()
if not use_fake_dtb:
for image in images.values():
fdt_subset.update(image.GetFdtSet())
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 17a3dccb116..037e82c8bbd 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -17,6 +17,7 @@ import sys
import fdt
import fdt_util
+import tools
# When we see these properties we ignore them - i.e. do not create a structure member
PROP_IGNORE_LIST = [
@@ -99,7 +100,7 @@ def get_value(ftype, value):
if ftype == fdt.TYPE_INT:
return '%#x' % fdt_util.fdt32_to_cpu(value)
elif ftype == fdt.TYPE_BYTE:
- return '%#x' % ord(value[0])
+ return '%#x' % tools.ToByte(value[0])
elif ftype == fdt.TYPE_STRING:
return '"%s"' % value
elif ftype == fdt.TYPE_BOOL:
@@ -449,7 +450,7 @@ class DtbPlatdata(object):
self.out(';\n')
self.out('};\n')
- for alias, struct_name in self._aliases.iteritems():
+ for alias, struct_name in self._aliases.items():
if alias not in sorted(structs):
self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
STRUCT_PREFIX, struct_name))
@@ -464,7 +465,8 @@ class DtbPlatdata(object):
var_name = conv_name_to_c(node.name)
self.buf('static const struct %s%s %s%s = {\n' %
(STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
- for pname, prop in node.props.items():
+ for pname in sorted(node.props):
+ prop = node.props[pname]
if pname in PROP_IGNORE_LIST or pname[0] == '#':
continue
member_name = conv_name_to_c(prop.name)
@@ -498,7 +500,7 @@ class DtbPlatdata(object):
vals.append(get_value(prop.type, val))
# Put 8 values per line to avoid very long lines.
- for i in xrange(0, len(vals), 8):
+ for i in range(0, len(vals), 8):
if i:
self.buf(',\n\t\t')
self.buf(', '.join(vals[i:i + 8]))
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 2277af9bf78..c1a1d3534d4 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -25,6 +25,8 @@ options. For more information about the use of this options and tool please
see doc/driver-model/of-plat.txt
"""
+from __future__ import print_function
+
from optparse import OptionParser
import os
import sys
@@ -64,11 +66,11 @@ def run_tests(args):
suite = unittest.TestLoader().loadTestsFromTestCase(module)
suite.run(result)
- print result
+ print(result)
for _, err in result.errors:
- print err
+ print(err)
for _, err in result.failures:
- print err
+ print(err)
def RunTestCoverage():
"""Run the tests and check that we get 100% coverage"""
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 9ad72f89ec7..d9471c43819 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -11,6 +11,7 @@ import sys
import fdt_util
import libfdt
from libfdt import QUIET_NOTFOUND
+import tools
# This deals with a device tree, presenting it as an assortment of Node and
# Prop objects, representing nodes and properties, respectively. This file
@@ -28,6 +29,66 @@ def CheckErr(errnum, msg):
raise ValueError('Error %d: %s: %s' %
(errnum, libfdt.fdt_strerror(errnum), msg))
+
+def BytesToValue(data):
+ """Converts a string of bytes into a type and value
+
+ Args:
+ A bytes value (which on Python 2 is an alias for str)
+
+ Return:
+ A tuple:
+ Type of data
+ Data, either a single element or a list of elements. Each element
+ is one of:
+ TYPE_STRING: str/bytes value from the property
+ TYPE_INT: a byte-swapped integer stored as a 4-byte str/bytes
+ TYPE_BYTE: a byte stored as a single-byte str/bytes
+ """
+ data = bytes(data)
+ size = len(data)
+ strings = data.split(b'\0')
+ is_string = True
+ count = len(strings) - 1
+ if count > 0 and not len(strings[-1]):
+ for string in strings[:-1]:
+ if not string:
+ is_string = False
+ break
+ for ch in string:
+ # Handle Python 2 treating bytes as str
+ if type(ch) == str:
+ ch = ord(ch)
+ if ch < 32 or ch > 127:
+ is_string = False
+ break
+ else:
+ is_string = False
+ if is_string:
+ if count == 1:
+ if sys.version_info[0] >= 3: # pragma: no cover
+ return TYPE_STRING, strings[0].decode()
+ else:
+ return TYPE_STRING, strings[0]
+ else:
+ if sys.version_info[0] >= 3: # pragma: no cover
+ return TYPE_STRING, [s.decode() for s in strings[:-1]]
+ else:
+ return TYPE_STRING, strings[:-1]
+ if size % 4:
+ if size == 1:
+ return TYPE_BYTE, tools.ToChar(data[0])
+ else:
+ return TYPE_BYTE, [tools.ToChar(ch) for ch in list(data)]
+ val = []
+ for i in range(0, size, 4):
+ val.append(data[i:i + 4])
+ if size == 4:
+ return TYPE_INT, val[0]
+ else:
+ return TYPE_INT, val
+
+
class Prop:
"""A device tree property
@@ -37,18 +98,18 @@ class Prop:
bytes
type: Value type
"""
- def __init__(self, node, offset, name, bytes):
+ def __init__(self, node, offset, name, data):
self._node = node
self._offset = offset
self.name = name
self.value = None
- self.bytes = str(bytes)
+ self.bytes = bytes(data)
self.dirty = False
- if not bytes:
+ if not data:
self.type = TYPE_BOOL
self.value = True
return
- self.type, self.value = self.BytesToValue(bytes)
+ self.type, self.value = BytesToValue(bytes(data))
def RefreshOffset(self, poffset):
self._offset = poffset
@@ -87,55 +148,6 @@ class Prop:
while len(self.value) < len(newprop.value):
self.value.append(val)
- def BytesToValue(self, bytes):
- """Converts a string of bytes into a type and value
-
- Args:
- A string containing bytes
-
- Return:
- A tuple:
- Type of data
- Data, either a single element or a list of elements. Each element
- is one of:
- TYPE_STRING: string value from the property
- TYPE_INT: a byte-swapped integer stored as a 4-byte string
- TYPE_BYTE: a byte stored as a single-byte string
- """
- bytes = str(bytes)
- size = len(bytes)
- strings = bytes.split('\0')
- is_string = True
- count = len(strings) - 1
- if count > 0 and not strings[-1]:
- for string in strings[:-1]:
- if not string:
- is_string = False
- break
- for ch in string:
- if ch < ' ' or ch > '~':
- is_string = False
- break
- else:
- is_string = False
- if is_string:
- if count == 1:
- return TYPE_STRING, strings[0]
- else:
- return TYPE_STRING, strings[:-1]
- if size % 4:
- if size == 1:
- return TYPE_BYTE, bytes[0]
- else:
- return TYPE_BYTE, list(bytes)
- val = []
- for i in range(0, size, 4):
- val.append(bytes[i:i + 4])
- if size == 4:
- return TYPE_INT, val[0]
- else:
- return TYPE_INT, val
-
@classmethod
def GetEmpty(self, type):
"""Get an empty / zero value of the given type
@@ -181,8 +193,8 @@ class Prop:
Args:
bytes: New property value to set
"""
- self.bytes = str(bytes)
- self.type, self.value = self.BytesToValue(bytes)
+ self.bytes = bytes
+ self.type, self.value = BytesToValue(bytes)
self.dirty = True
def Sync(self, auto_resize=False):
@@ -334,7 +346,8 @@ class Node:
Args:
prop_name: Name of property
"""
- self.props[prop_name] = Prop(self, None, prop_name, '\0' * 4)
+ self.props[prop_name] = Prop(self, None, prop_name,
+ tools.GetBytes(0, 4))
def AddEmptyProp(self, prop_name, len):
"""Add a property with a fixed data size, for filling in later
@@ -346,7 +359,7 @@ class Node:
prop_name: Name of property
len: Length of data in property
"""
- value = chr(0) * len
+ value = tools.GetBytes(0, len)
self.props[prop_name] = Prop(self, None, prop_name, value)
def SetInt(self, prop_name, val):
@@ -385,7 +398,9 @@ class Node:
prop_name: Name of property to set
val: String value to set (will be \0-terminated in DT)
"""
- self.props[prop_name].SetData(val + chr(0))
+ if sys.version_info[0] >= 3: # pragma: no cover
+ val = bytes(val, 'utf-8')
+ self.props[prop_name].SetData(val + b'\0')
def AddString(self, prop_name, val):
"""Add a new string property to a node
@@ -397,7 +412,9 @@ class Node:
prop_name: Name of property to add
val: String value of property
"""
- self.props[prop_name] = Prop(self, None, prop_name, val + chr(0))
+ if sys.version_info[0] >= 3: # pragma: no cover
+ val = bytes(val, 'utf-8')
+ self.props[prop_name] = Prop(self, None, prop_name, val + b'\0')
def AddSubnode(self, name):
"""Add a new subnode to the node
@@ -448,8 +465,11 @@ class Node:
# Sync properties now, whose offsets should not have been disturbed.
# We do this after subnodes, since this disturbs the offsets of these
- # properties.
- prop_list = sorted(self.props.values(), key=lambda prop: prop._offset,
+ # properties. Note that new properties will have an offset of None here,
+ # which Python 3 cannot sort against int. So use a large value instead
+ # to ensure that the new properties are added first.
+ prop_list = sorted(self.props.values(),
+ key=lambda prop: prop._offset or 1 << 31,
reverse=True)
for prop in prop_list:
prop.Sync(auto_resize)
@@ -469,7 +489,7 @@ class Fdt:
if self._fname:
self._fname = fdt_util.EnsureCompiled(self._fname)
- with open(self._fname) as fd:
+ with open(self._fname, 'rb') as fd:
self._fdt_obj = libfdt.Fdt(fd.read())
@staticmethod
@@ -483,7 +503,7 @@ class Fdt:
Fdt object containing the data
"""
fdt = Fdt(None)
- fdt._fdt_obj = libfdt.Fdt(bytearray(data))
+ fdt._fdt_obj = libfdt.Fdt(bytes(data))
return fdt
def LookupPhandle(self, phandle):
@@ -573,7 +593,7 @@ class Fdt:
Returns:
The FDT contents as a string of bytes
"""
- return self._fdt_obj.as_bytearray()
+ return bytes(self._fdt_obj.as_bytearray())
def GetFdtObj(self):
"""Get the contents of the FDT
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
index 5fbfc8877bd..f47879ac006 100644
--- a/tools/dtoc/fdt_util.py
+++ b/tools/dtoc/fdt_util.py
@@ -16,14 +16,6 @@ import tempfile
import command
import tools
-VERSION3 = sys.version_info > (3, 0)
-
-def get_plain_bytes(val):
- """Handle Python 3 strings"""
- if isinstance(val, bytes):
- val = val.decode('utf-8')
- return val.encode('raw_unicode_escape')
-
def fdt32_to_cpu(val):
"""Convert a device tree cell to an integer
@@ -33,9 +25,6 @@ def fdt32_to_cpu(val):
Return:
A native-endian integer value
"""
- if VERSION3:
- # This code is not reached in Python 2
- val = get_plain_bytes(val) # pragma: no cover
return struct.unpack('>I', val)[0]
def fdt_cells_to_cpu(val, cells):
@@ -45,11 +34,11 @@ def fdt_cells_to_cpu(val, cells):
Value to convert (array of one or more 4-character strings)
Return:
- A native-endian long value
+ A native-endian integer value
"""
if not cells:
return 0
- out = long(fdt32_to_cpu(val[0]))
+ out = int(fdt32_to_cpu(val[0]))
if cells == 2:
out = out << 32 | fdt32_to_cpu(val[1])
return out
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index cb6d6e7baf9..b915b278560 100644
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -8,6 +8,8 @@ This includes unit tests for some functions and functional tests for the dtoc
tool.
"""
+from __future__ import print_function
+
import collections
import os
import struct
@@ -97,7 +99,7 @@ class TestDtoc(unittest.TestCase):
if expected != actual:
self._WritePythonString('/tmp/binman.expected', expected)
self._WritePythonString('/tmp/binman.actual', actual)
- print 'Failures written to /tmp/binman.{expected,actual}'
+ print('Failures written to /tmp/binman.{expected,actual}')
self.assertEquals(expected, actual)
def test_name(self):
@@ -197,16 +199,16 @@ struct dtd_sandbox_spl_test_2 {
data = infile.read()
self._CheckStrings(C_HEADER + '''
static const struct dtd_sandbox_spl_test dtv_spl_test = {
+\t.boolval\t\t= true,
\t.bytearray\t\t= {0x6, 0x0, 0x0},
\t.byteval\t\t= 0x5,
+\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
\t.intval\t\t\t= 0x1,
-\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
\t\t0x11},
-\t.stringval\t\t= "message",
-\t.boolval\t\t= true,
-\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
+\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
\t.stringarray\t\t= {"multi-word", "message", ""},
+\t.stringval\t\t= "message",
};
U_BOOT_DEVICE(spl_test) = {
\t.name\t\t= "sandbox_spl_test",
@@ -217,12 +219,12 @@ U_BOOT_DEVICE(spl_test) = {
static const struct dtd_sandbox_spl_test dtv_spl_test2 = {
\t.bytearray\t\t= {0x1, 0x23, 0x34},
\t.byteval\t\t= 0x8,
+\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
\t.intval\t\t\t= 0x3,
\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
\t\t0x0},
-\t.stringval\t\t= "message2",
-\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
\t.stringarray\t\t= {"another", "multi-word", "message"},
+\t.stringval\t\t= "message2",
};
U_BOOT_DEVICE(spl_test2) = {
\t.name\t\t= "sandbox_spl_test",
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index 8d70dd2a294..bf469dbd54c 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -4,6 +4,8 @@
# Written by Simon Glass <sjg@chromium.org>
#
+from __future__ import print_function
+
from optparse import OptionParser
import glob
import os
@@ -17,7 +19,7 @@ for dirname in ['../patman', '..']:
import command
import fdt
-from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL
+from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, BytesToValue
import fdt_util
from fdt_util import fdt32_to_cpu
import libfdt
@@ -45,7 +47,7 @@ def _GetPropertyValue(dtb, node, prop_name):
# Add 12, which is sizeof(struct fdt_property), to get to start of data
offset = prop.GetOffset() + 12
data = dtb.GetContents()[offset:offset + len(prop.value)]
- return prop, [chr(x) for x in data]
+ return prop, [tools.ToChar(x) for x in data]
class TestFdt(unittest.TestCase):
@@ -83,13 +85,13 @@ class TestFdt(unittest.TestCase):
def testFlush(self):
"""Check that we can flush the device tree out to its file"""
fname = self.dtb._fname
- with open(fname) as fd:
+ with open(fname, 'rb') as fd:
data = fd.read()
os.remove(fname)
with self.assertRaises(IOError):
- open(fname)
+ open(fname, 'rb')
self.dtb.Flush()
- with open(fname) as fd:
+ with open(fname, 'rb') as fd:
data = fd.read()
def testPack(self):
@@ -119,6 +121,10 @@ class TestFdt(unittest.TestCase):
node = self.dtb.GetNode('/spl-test')
self.assertEqual(self.dtb, node.GetFdt())
+ def testBytesToValue(self):
+ self.assertEqual(BytesToValue(b'this\0is\0'),
+ (TYPE_STRING, ['this', 'is']))
+
class TestNode(unittest.TestCase):
"""Test operation of the Node class"""
@@ -277,7 +283,7 @@ class TestProp(unittest.TestCase):
"""Tests the GetEmpty() function for the various supported types"""
self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL))
self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE))
- self.assertEqual(chr(0) * 4, fdt.Prop.GetEmpty(fdt.TYPE_INT))
+ self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(fdt.TYPE_INT))
self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING))
def testGetOffset(self):
@@ -381,7 +387,7 @@ class TestProp(unittest.TestCase):
self.node.AddString('string', val)
self.dtb.Sync(auto_resize=True)
data = self.fdt.getprop(self.node.Offset(), 'string')
- self.assertEqual(val + '\0', data)
+ self.assertEqual(tools.ToBytes(val) + b'\0', data)
self.fdt.pack()
self.node.SetString('string', val + 'x')
@@ -391,21 +397,21 @@ class TestProp(unittest.TestCase):
self.node.SetString('string', val[:-1])
prop = self.node.props['string']
- prop.SetData(val)
+ prop.SetData(tools.ToBytes(val))
self.dtb.Sync(auto_resize=False)
data = self.fdt.getprop(self.node.Offset(), 'string')
- self.assertEqual(val, data)
+ self.assertEqual(tools.ToBytes(val), data)
self.node.AddEmptyProp('empty', 5)
self.dtb.Sync(auto_resize=True)
prop = self.node.props['empty']
- prop.SetData(val)
+ prop.SetData(tools.ToBytes(val))
self.dtb.Sync(auto_resize=False)
data = self.fdt.getprop(self.node.Offset(), 'empty')
- self.assertEqual(val, data)
+ self.assertEqual(tools.ToBytes(val), data)
- self.node.SetData('empty', '123')
- self.assertEqual('123', prop.bytes)
+ self.node.SetData('empty', b'123')
+ self.assertEqual(b'123', prop.bytes)
def testFromData(self):
dtb2 = fdt.Fdt.FromData(self.dtb.GetContents())
@@ -496,18 +502,22 @@ class TestFdtUtil(unittest.TestCase):
self.assertEqual(2, fdt_util.fdt_cells_to_cpu(val, 1))
dtb2 = fdt.FdtScan('tools/dtoc/dtoc_test_addr64.dts')
- node2 = dtb2.GetNode('/test1')
- val = node2.props['reg'].value
+ node1 = dtb2.GetNode('/test1')
+ val = node1.props['reg'].value
self.assertEqual(0x1234, fdt_util.fdt_cells_to_cpu(val, 2))
+ node2 = dtb2.GetNode('/test2')
+ val = node2.props['reg'].value
+ self.assertEqual(0x1234567890123456, fdt_util.fdt_cells_to_cpu(val, 2))
+ self.assertEqual(0x9876543210987654, fdt_util.fdt_cells_to_cpu(val[2:],
+ 2))
+ self.assertEqual(0x12345678, fdt_util.fdt_cells_to_cpu(val, 1))
+
def testEnsureCompiled(self):
"""Test a degenerate case of this function"""
dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
- def testGetPlainBytes(self):
- self.assertEqual('fred', fdt_util.get_plain_bytes('fred'))
-
def RunTestCoverage():
"""Run the tests and check that we get 100% coverage"""
@@ -535,11 +545,11 @@ def RunTests(args):
suite = unittest.TestLoader().loadTestsFromTestCase(module)
suite.run(result)
- print result
+ print(result)
for _, err in result.errors:
- print err
+ print(err)
for _, err in result.failures:
- print err
+ print(err)
if __name__ != '__main__':
sys.exit(1)
diff --git a/tools/patman/cros_subprocess.py b/tools/patman/cros_subprocess.py
index ebd4300dfd5..06be64cc2cb 100644
--- a/tools/patman/cros_subprocess.py
+++ b/tools/patman/cros_subprocess.py
@@ -54,7 +54,7 @@ class Popen(subprocess.Popen):
"""
def __init__(self, args, stdin=None, stdout=PIPE_PTY, stderr=PIPE_PTY,
- shell=False, cwd=None, env=None, **kwargs):
+ shell=False, cwd=None, env=None, binary=False, **kwargs):
"""Cut-down constructor
Args:
@@ -72,6 +72,7 @@ class Popen(subprocess.Popen):
"""
stdout_pty = None
stderr_pty = None
+ self.binary = binary
if stdout == PIPE_PTY:
stdout_pty = pty.openpty()
@@ -100,6 +101,19 @@ class Popen(subprocess.Popen):
if kwargs:
raise ValueError("Unit tests do not test extra args - please add tests")
+ def ConvertData(self, data):
+ """Convert stdout/stderr data to the correct format for output
+
+ Args:
+ data: Data to convert, or None for ''
+
+ Returns:
+ Converted data, as bytes
+ """
+ if data is None:
+ return b''
+ return data
+
def CommunicateFilter(self, output):
"""Interact with process: Read data from stdout and stderr.
@@ -156,11 +170,11 @@ class Popen(subprocess.Popen):
self.stdin.close()
if self.stdout:
read_set.append(self.stdout)
- stdout = []
+ stdout = b''
if self.stderr and self.stderr != self.stdout:
read_set.append(self.stderr)
- stderr = []
- combined = []
+ stderr = b''
+ combined = b''
input_offset = 0
while read_set or write_set:
@@ -186,46 +200,40 @@ class Popen(subprocess.Popen):
write_set.remove(self.stdin)
if self.stdout in rlist:
- data = ""
+ data = b''
# We will get an error on read if the pty is closed
try:
data = os.read(self.stdout.fileno(), 1024)
except OSError:
pass
- if data == "":
+ if not len(data):
self.stdout.close()
read_set.remove(self.stdout)
else:
- stdout.append(data)
- combined.append(data)
+ stdout += data
+ combined += data
if output:
output(sys.stdout, data)
if self.stderr in rlist:
- data = ""
+ data = b''
# We will get an error on read if the pty is closed
try:
data = os.read(self.stderr.fileno(), 1024)
except OSError:
pass
- if data == "":
+ if not len(data):
self.stderr.close()
read_set.remove(self.stderr)
else:
- stderr.append(data)
- combined.append(data)
+ stderr += data
+ combined += data
if output:
output(sys.stderr, data)
# All data exchanged. Translate lists into strings.
- if stdout is not None:
- stdout = ''.join(stdout)
- else:
- stdout = ''
- if stderr is not None:
- stderr = ''.join(stderr)
- else:
- stderr = ''
- combined = ''.join(combined)
+ stdout = self.ConvertData(stdout)
+ stderr = self.ConvertData(stderr)
+ combined = self.ConvertData(combined)
# Translate newlines, if requested. We cannot let the file
# object do the translation: It is based on stdio, which is
diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py
index d79e716074b..50a2741439e 100644
--- a/tools/patman/func_test.py
+++ b/tools/patman/func_test.py
@@ -12,15 +12,20 @@ import sys
import tempfile
import unittest
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
import gitutil
import patchstream
import settings
+import tools
@contextlib.contextmanager
def capture():
import sys
- from cStringIO import StringIO
oldout,olderr = sys.stdout, sys.stderr
try:
out=[StringIO(), StringIO()]
@@ -124,10 +129,10 @@ class TestFunctional(unittest.TestCase):
"""
process_tags = True
ignore_bad_tags = True
- stefan = u'Stefan Brüns <stefan.bruens@rwth-aachen.de>'
+ stefan = b'Stefan Br\xc3\xbcns <stefan.bruens@rwth-aachen.de>'.decode('utf-8')
rick = 'Richard III <richard@palace.gov>'
- mel = u'Lord Mëlchett <clergy@palace.gov>'
- ed = u'Lond Edmund Blackaddër <weasel@blackadder.org'
+ mel = b'Lord M\xc3\xablchett <clergy@palace.gov>'.decode('utf-8')
+ ed = b'Lond Edmund Blackadd\xc3\xabr <weasel@blackadder.org'.decode('utf-8')
fred = 'Fred Bloggs <f.bloggs@napier.net>'
add_maintainers = [stefan, rick]
dry_run = True
@@ -159,7 +164,6 @@ class TestFunctional(unittest.TestCase):
os.remove(cc_file)
lines = out[0].splitlines()
- #print '\n'.join(lines)
self.assertEqual('Cleaned %s patches' % len(series.commits), lines[0])
self.assertEqual('Change log missing for v2', lines[1])
self.assertEqual('Change log missing for v3', lines[2])
@@ -174,27 +178,30 @@ class TestFunctional(unittest.TestCase):
while 'Cc:' in lines[line]:
line += 1
self.assertEqual('To: u-boot@lists.denx.de', lines[line])
- self.assertEqual('Cc: %s' % stefan.encode('utf-8'), lines[line + 1])
+ self.assertEqual('Cc: %s' % tools.FromUnicode(stefan),
+ lines[line + 1])
self.assertEqual('Version: 3', lines[line + 2])
self.assertEqual('Prefix:\t RFC', lines[line + 3])
self.assertEqual('Cover: 4 lines', lines[line + 4])
line += 5
- self.assertEqual(' Cc: %s' % mel.encode('utf-8'), lines[line + 0])
- self.assertEqual(' Cc: %s' % rick, lines[line + 1])
- self.assertEqual(' Cc: %s' % fred, lines[line + 2])
- self.assertEqual(' Cc: %s' % ed.encode('utf-8'), lines[line + 3])
+ self.assertEqual(' Cc: %s' % fred, lines[line + 0])
+ self.assertEqual(' Cc: %s' % tools.FromUnicode(ed),
+ lines[line + 1])
+ self.assertEqual(' Cc: %s' % tools.FromUnicode(mel),
+ lines[line + 2])
+ self.assertEqual(' Cc: %s' % rick, lines[line + 3])
expected = ('Git command: git send-email --annotate '
'--in-reply-to="%s" --to "u-boot@lists.denx.de" '
'--cc "%s" --cc-cmd "%s --cc-cmd %s" %s %s'
% (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname,
- ' '.join(args))).encode('utf-8')
+ ' '.join(args)))
line += 4
- self.assertEqual(expected, lines[line])
+ self.assertEqual(expected, tools.ToUnicode(lines[line]))
- self.assertEqual(('%s %s, %s' % (args[0], rick, stefan))
- .encode('utf-8'), cc_lines[0])
- self.assertEqual(('%s %s, %s, %s, %s' % (args[1], fred, rick, stefan,
- ed)).encode('utf-8'), cc_lines[1])
+ self.assertEqual(('%s %s, %s' % (args[0], rick, stefan)),
+ tools.ToUnicode(cc_lines[0]))
+ self.assertEqual(('%s %s, %s, %s, %s' % (args[1], fred, ed, rick,
+ stefan)), tools.ToUnicode(cc_lines[1]))
expected = '''
This is a test of how the cover
@@ -223,7 +230,6 @@ Simon Glass (2):
'''
lines = open(cover_fname).read().splitlines()
- #print '\n'.join(lines)
self.assertEqual(
'Subject: [RFC PATCH v3 0/2] test: A test patch series',
lines[3])
@@ -231,7 +237,6 @@ Simon Glass (2):
for i, fname in enumerate(args):
lines = open(fname).read().splitlines()
- #print '\n'.join(lines)
subject = [line for line in lines if line.startswith('Subject')]
self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
subject[0][:18])
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index 9905bb0bbd8..dce7fa25b64 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -12,6 +12,7 @@ import terminal
import checkpatch
import settings
+import tools
# True to use --no-decorate - we check this in Setup()
use_no_decorate = True
@@ -325,6 +326,7 @@ def BuildEmailList(in_list, tag=None, alias=None, raise_on_error=True):
raw += LookupEmail(item, alias, raise_on_error=raise_on_error)
result = []
for item in raw:
+ item = tools.FromUnicode(item)
if not item in result:
result.append(item)
if tag:
@@ -395,11 +397,11 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname,
git_config_to = command.Output('git', 'config', 'sendemail.to',
raise_on_error=False)
if not git_config_to:
- print ("No recipient.\n"
- "Please add something like this to a commit\n"
- "Series-to: Fred Bloggs <f.blogs@napier.co.nz>\n"
- "Or do something like this\n"
- "git config sendemail.to u-boot@lists.denx.de")
+ print("No recipient.\n"
+ "Please add something like this to a commit\n"
+ "Series-to: Fred Bloggs <f.blogs@napier.co.nz>\n"
+ "Or do something like this\n"
+ "git config sendemail.to u-boot@lists.denx.de")
return
cc = BuildEmailList(list(set(series.get('cc')) - set(series.get('to'))),
'--cc', alias, raise_on_error)
@@ -410,9 +412,7 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname,
if smtp_server:
cmd.append('--smtp-server=%s' % smtp_server)
if in_reply_to:
- if type(in_reply_to) != str:
- in_reply_to = in_reply_to.encode('utf-8')
- cmd.append('--in-reply-to="%s"' % in_reply_to)
+ cmd.append('--in-reply-to="%s"' % tools.FromUnicode(in_reply_to))
if thread:
cmd.append('--thread')
diff --git a/tools/patman/patman.py b/tools/patman/patman.py
index 27a2febf704..9605a36eff2 100755
--- a/tools/patman/patman.py
+++ b/tools/patman/patman.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2011 The Chromium OS Authors.
diff --git a/tools/patman/series.py b/tools/patman/series.py
index 2735afaf88f..67103f03e69 100644
--- a/tools/patman/series.py
+++ b/tools/patman/series.py
@@ -11,6 +11,7 @@ import get_maintainer
import gitutil
import settings
import terminal
+import tools
# Series-xxx tags that we understand
valid_series = ['to', 'cc', 'version', 'changes', 'prefix', 'notes', 'name',
@@ -114,16 +115,16 @@ class Series(dict):
commit = self.commits[upto]
print(col.Color(col.GREEN, ' %s' % args[upto]))
cc_list = list(self._generated_cc[commit.patch])
- for email in set(cc_list) - to_set - cc_set:
+ for email in sorted(set(cc_list) - to_set - cc_set):
if email == None:
email = col.Color(col.YELLOW, "<alias '%s' not found>"
% tag)
if email:
print(' Cc: ', email)
print
- for item in to_set:
+ for item in sorted(to_set):
print('To:\t ', item)
- for item in cc_set - to_set:
+ for item in sorted(cc_set - to_set):
print('Cc:\t ', item)
print('Version: ', self.get('version'))
print('Prefix:\t ', self.get('prefix'))
@@ -131,7 +132,7 @@ class Series(dict):
print('Cover: %d lines' % len(self.cover))
cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
all_ccs = itertools.chain(cover_cc, *self._generated_cc.values())
- for email in set(all_ccs) - to_set - cc_set:
+ for email in sorted(set(all_ccs) - to_set - cc_set):
print(' Cc: ', email)
if cmd:
print('Git command: %s' % cmd)
@@ -238,19 +239,18 @@ class Series(dict):
for x in set(cc) & set(settings.bounces):
print(col.Color(col.YELLOW, 'Skipping "%s"' % x))
cc = set(cc) - set(settings.bounces)
- cc = [m.encode('utf-8') if type(m) != str else m for m in cc]
+ cc = [tools.FromUnicode(m) for m in cc]
if limit is not None:
cc = cc[:limit]
all_ccs += cc
- print(commit.patch, ', '.join(set(cc)), file=fd)
+ print(commit.patch, ', '.join(sorted(set(cc))), file=fd)
self._generated_cc[commit.patch] = cc
if cover_fname:
cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
- cover_cc = [m.encode('utf-8') if type(m) != str else m
- for m in cover_cc]
- cc_list = ', '.join([x.decode('utf-8')
- for x in set(cover_cc + all_ccs)])
+ cover_cc = [tools.FromUnicode(m) for m in cover_cc]
+ cc_list = ', '.join([tools.ToUnicode(x)
+ for x in sorted(set(cover_cc + all_ccs))])
print(cover_fname, cc_list.encode('utf-8'), file=fd)
fd.close()
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index ea2bc74f759..c98911d522b 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -14,6 +14,7 @@ import re
import command
import gitutil
+import tools
"""Default settings per-project.
@@ -57,26 +58,26 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
# Check to make sure that bogus project gets general alias.
>>> config = _ProjectConfigParser("zzz")
>>> config.readfp(StringIO(sample_config))
- >>> config.get("alias", "enemies")
- u'Evil <evil@example.com>'
+ >>> str(config.get("alias", "enemies"))
+ 'Evil <evil@example.com>'
# Check to make sure that alias gets overridden by project.
>>> config = _ProjectConfigParser("sm")
>>> config.readfp(StringIO(sample_config))
- >>> config.get("alias", "enemies")
- u'Green G. <ugly@example.com>'
+ >>> str(config.get("alias", "enemies"))
+ 'Green G. <ugly@example.com>'
# Check to make sure that settings get merged with project.
>>> config = _ProjectConfigParser("linux")
>>> config.readfp(StringIO(sample_config))
- >>> sorted(config.items("settings"))
- [(u'am_hero', u'True'), (u'process_tags', u'False')]
+ >>> sorted((str(a), str(b)) for (a, b) in config.items("settings"))
+ [('am_hero', 'True'), ('process_tags', 'False')]
# Check to make sure that settings works with unknown project.
>>> config = _ProjectConfigParser("unknown")
>>> config.readfp(StringIO(sample_config))
- >>> sorted(config.items("settings"))
- [(u'am_hero', u'True')]
+ >>> sorted((str(a), str(b)) for (a, b) in config.items("settings"))
+ [('am_hero', 'True')]
"""
def __init__(self, project_name):
"""Construct _ProjectConfigParser.
@@ -99,17 +100,6 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
for setting_name, setting_value in project_defaults.items():
self.set(project_settings, setting_name, setting_value)
- def _to_unicode(self, val):
- """Make sure a value is of type 'unicode'
-
- Args:
- val: string or unicode object
-
- Returns:
- unicode version of val
- """
- return val if isinstance(val, unicode) else val.decode('utf-8')
-
def get(self, section, option, *args, **kwargs):
"""Extend SafeConfigParser to try project_section before section.
@@ -127,7 +117,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
val = ConfigParser.SafeConfigParser.get(
self, section, option, *args, **kwargs
)
- return self._to_unicode(val)
+ return tools.ToUnicode(val)
def items(self, section, *args, **kwargs):
"""Extend SafeConfigParser to add project_section to section.
@@ -162,8 +152,8 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
item_dict = dict(top_items)
item_dict.update(project_items)
- return {(self._to_unicode(item), self._to_unicode(val))
- for item, val in item_dict.iteritems()}
+ return {(tools.ToUnicode(item), tools.ToUnicode(val))
+ for item, val in item_dict.items()}
def ReadGitAliases(fname):
"""Read a git alias file. This is in the form used by git:
diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py
index 687d40704ab..ea36cd16339 100644
--- a/tools/patman/test_util.py
+++ b/tools/patman/test_util.py
@@ -3,6 +3,8 @@
# Copyright (c) 2016 Google, Inc
#
+from __future__ import print_function
+
from contextlib import contextmanager
import glob
import os
@@ -15,6 +17,8 @@ try:
except ImportError:
from io import StringIO
+PYTHON = 'python%d' % sys.version_info[0]
+
def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None):
"""Run tests and check that we get 100% coverage
@@ -41,11 +45,12 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None):
else:
glob_list = []
glob_list += exclude_list
- glob_list += ['*libfdt.py', '*site-packages*']
- cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools python-coverage run '
- '--omit "%s" %s -P1 -t' % (build_dir, ','.join(glob_list), prog))
+ glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*']
+ cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools %s-coverage run '
+ '--omit "%s" %s -P1 -t' % (build_dir, PYTHON, ','.join(glob_list),
+ prog))
os.system(cmd)
- stdout = command.Output('python-coverage', 'report')
+ stdout = command.Output('%s-coverage' % PYTHON, 'report')
lines = stdout.splitlines()
if required:
# Convert '/path/to/name.py' just the module name 'name'
@@ -54,18 +59,18 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None):
missing_list = required
missing_list.difference_update(test_set)
if missing_list:
- print 'Missing tests for %s' % (', '.join(missing_list))
- print stdout
+ print('Missing tests for %s' % (', '.join(missing_list)))
+ print(stdout)
ok = False
coverage = lines[-1].split(' ')[-1]
ok = True
- print coverage
+ print(coverage)
if coverage != '100%':
- print stdout
- print ("Type 'python-coverage html' to get a report in "
- 'htmlcov/index.html')
- print 'Coverage error: %s, but should be 100%%' % coverage
+ print(stdout)
+ print("Type '%s-coverage html' to get a report in "
+ 'htmlcov/index.html' % PYTHON)
+ print('Coverage error: %s, but should be 100%%' % coverage)
ok = False
if not ok:
raise ValueError('Test coverage failure')
diff --git a/tools/patman/tools.py b/tools/patman/tools.py
index bf099798e65..8e9f22afe8a 100644
--- a/tools/patman/tools.py
+++ b/tools/patman/tools.py
@@ -7,6 +7,7 @@ import command
import glob
import os
import shutil
+import sys
import tempfile
import tout
@@ -167,9 +168,9 @@ def PathHasFile(fname):
return True
return False
-def Run(name, *args):
+def Run(name, *args, **kwargs):
try:
- return command.Run(name, *args, cwd=outdir, capture=True)
+ return command.Run(name, *args, cwd=outdir, capture=True, **kwargs)
except:
if not PathHasFile(name):
msg = "Plesae install tool '%s'" % name
@@ -213,7 +214,7 @@ def Filename(fname):
# If not found, just return the standard, unchanged path
return fname
-def ReadFile(fname):
+def ReadFile(fname, binary=True):
"""Read and return the contents of a file.
Args:
@@ -222,7 +223,7 @@ def ReadFile(fname):
Returns:
data read from file, as a string.
"""
- with open(Filename(fname), 'rb') as fd:
+ with open(Filename(fname), binary and 'rb' or 'r') as fd:
data = fd.read()
#self._out.Info("Read file '%s' size %d (%#0x)" %
#(fname, len(data), len(data)))
@@ -239,3 +240,105 @@ def WriteFile(fname, data):
#(fname, len(data), len(data)))
with open(Filename(fname), 'wb') as fd:
fd.write(data)
+
+def GetBytes(byte, size):
+ """Get a string of bytes of a given size
+
+ This handles the unfortunate different between Python 2 and Python 2.
+
+ Args:
+ byte: Numeric byte value to use
+ size: Size of bytes/string to return
+
+ Returns:
+ A bytes type with 'byte' repeated 'size' times
+ """
+ if sys.version_info[0] >= 3:
+ data = bytes([byte]) * size
+ else:
+ data = chr(byte) * size
+ return data
+
+def ToUnicode(val):
+ """Make sure a value is a unicode string
+
+ This allows some amount of compatibility between Python 2 and Python3. For
+ the former, it returns a unicode object.
+
+ Args:
+ val: string or unicode object
+
+ Returns:
+ unicode version of val
+ """
+ if sys.version_info[0] >= 3:
+ return val
+ return val if isinstance(val, unicode) else val.decode('utf-8')
+
+def FromUnicode(val):
+ """Make sure a value is a non-unicode string
+
+ This allows some amount of compatibility between Python 2 and Python3. For
+ the former, it converts a unicode object to a string.
+
+ Args:
+ val: string or unicode object
+
+ Returns:
+ non-unicode version of val
+ """
+ if sys.version_info[0] >= 3:
+ return val
+ return val if isinstance(val, str) else val.encode('utf-8')
+
+def ToByte(ch):
+ """Convert a character to an ASCII value
+
+ This is useful because in Python 2 bytes is an alias for str, but in
+ Python 3 they are separate types. This function converts the argument to
+ an ASCII value in either case.
+
+ Args:
+ ch: A string (Python 2) or byte (Python 3) value
+
+ Returns:
+ integer ASCII value for ch
+ """
+ return ord(ch) if type(ch) == str else ch
+
+def ToChar(byte):
+ """Convert a byte to a character
+
+ This is useful because in Python 2 bytes is an alias for str, but in
+ Python 3 they are separate types. This function converts an ASCII value to
+ a value with the appropriate type in either case.
+
+ Args:
+ byte: A byte or str value
+ """
+ return chr(byte) if type(byte) != str else byte
+
+def ToChars(byte_list):
+ """Convert a list of bytes to a str/bytes type
+
+ Args:
+ byte_list: List of ASCII values representing the string
+
+ Returns:
+ string made by concatenating all the ASCII values
+ """
+ return ''.join([chr(byte) for byte in byte_list])
+
+def ToBytes(string):
+ """Convert a str type into a bytes type
+
+ Args:
+ string: string to convert value
+
+ Returns:
+ Python 3: A bytes type
+ Python 2: A string type
+ """
+ if sys.version_info[0] >= 3:
+ return string.encode('utf-8')
+ return string
diff --git a/tools/proftool.c b/tools/proftool.c
index c1803fa78a7..fecb9d6e99c 100644
--- a/tools/proftool.c
+++ b/tools/proftool.c
@@ -205,12 +205,12 @@ static struct func_info *find_caller_by_offset(uint32_t offset)
return low >= 0 ? &func_list[low] : NULL;
}
-static int read_calls(FILE *fin, int count)
+static int read_calls(FILE *fin, size_t count)
{
struct trace_call *call_data;
int i;
- notice("call count: %d\n", count);
+ notice("call count: %zu\n", count);
call_list = (struct trace_call *)calloc(count, sizeof(*call_data));
if (!call_list) {
error("Cannot allocate call_list\n");
diff --git a/tools/rmboard.py b/tools/rmboard.py
new file mode 100755
index 00000000000..df4f04b01c5
--- /dev/null
+++ b/tools/rmboard.py
@@ -0,0 +1,150 @@
+#! /usr/bin/python
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2019 Google LLC
+#
+
+"""
+Script to remove boards
+
+Usage:
+ rmboard.py <board_name>...
+
+A single commit is created for each board removed.
+
+Some boards may depend on files provided by another and this will cause
+problems, generally the removal of files which should not be removed.
+
+This script works by:
+ - Looking through the MAINTAINERS files which mention a board to find out
+ what files the board uses
+ - Looking through the Kconfig files which mention a board to find one that
+ needs to have material removed
+
+Search for ## to update the commit message manually.
+"""
+
+from __future__ import print_function
+
+import glob
+import os
+import re
+import sys
+
+# Bring in the patman libraries
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../tools/patman'))
+
+import command
+
+def rm_kconfig_include(path):
+ """Remove a path from Kconfig files
+
+ This function finds the given path in a 'source' statement in a Kconfig
+ file and removes that line from the file. This is needed because the path
+ is going to be removed, so any reference to it will cause a problem with
+ Kconfig parsing.
+
+ The changes are made locally and then added to the git staging area.
+
+ Args:
+ path: Path to search for and remove
+ """
+ cmd = ['git', 'grep', path]
+ stdout = command.RunPipe([cmd], capture=True, raise_on_error=False).stdout
+ if not stdout:
+ return
+ fname = stdout.split(':')[0]
+
+ print("Fixing up '%s' to remove reference to '%s'" % (fname, path))
+ cmd = ['sed', '-i', '\|%s|d' % path, fname]
+ stdout = command.RunPipe([cmd], capture=True).stdout
+
+ cmd = ['git', 'add', fname]
+ stdout = command.RunPipe([cmd], capture=True).stdout
+
+def rm_board(board):
+ """Create a commit which removes a single board
+
+ This looks up the MAINTAINERS file to file files that need to be removed,
+ then removes pieces from the Kconfig files that mention the board.
+
+
+ Args:
+ board: Board name to remove
+ """
+
+ # Find all MAINTAINERS and Kconfig files which mention the board
+ cmd = ['git', 'grep', '-l', board]
+ stdout = command.RunPipe([cmd], capture=True).stdout
+ maintain = []
+ kconfig = []
+ for line in stdout.splitlines():
+ line = line.strip()
+ if 'MAINTAINERS' in line:
+ if line not in maintain:
+ maintain.append(line)
+ elif 'Kconfig' in line:
+ kconfig.append(line)
+ paths = []
+ cc = []
+
+ # Look through the MAINTAINERS file to find things to remove
+ for fname in maintain:
+ with open(fname) as fd:
+ for line in fd:
+ line = line.strip()
+ fields = re.split('[ \t]', line, 1)
+ if len(fields) == 2:
+ if fields[0] == 'M:':
+ cc.append(fields[1])
+ elif fields[0] == 'F:':
+ paths.append(fields[1].strip())
+
+ # Expand any wildcards in the MAINTAINERS file
+ real = []
+ for path in paths:
+ if path[-1] == '/':
+ path = path[:-1]
+ if '*' in path:
+ globbed = glob.glob(path)
+ print("Expanded '%s' to '%s'" % (path, globbed))
+ real += globbed
+ else:
+ real.append(path)
+
+ # Search for Kconfig files in the resulting list. Remove any 'source' lines
+ # which reference Kconfig files we want to remove
+ for path in real:
+ cmd = ['find', path]
+ stdout = (command.RunPipe([cmd], capture=True, raise_on_error=False).
+ stdout)
+ for fname in stdout.splitlines():
+ if fname.endswith('Kconfig'):
+ rm_kconfig_include(fname)
+
+ # Remove unwanted files
+ cmd = ['git', 'rm', '-r'] + real
+ stdout = command.RunPipe([cmd], capture=True).stdout
+
+ ## Change the messages as needed
+ msg = '''arm: Remove %s board
+
+This board has not been converted to CONFIG_DM_MMC by the deadline.
+Remove it.
+
+''' % board
+ for name in cc:
+ msg += 'Patch-cc: %s\n' % name
+
+ # Create the commit
+ cmd = ['git', 'commit', '-s', '-m', msg]
+ stdout = command.RunPipe([cmd], capture=True).stdout
+
+ # Check if the board is mentioned anywhere else. The user will need to deal
+ # with this
+ cmd = ['git', 'grep', '-il', board]
+ print(command.RunPipe([cmd], capture=True, raise_on_error=False).stdout)
+ print(' '.join(cmd))
+
+for board in sys.argv[1:]:
+ rm_board(board)