diff --git a/bcm283x-device-tree-sources-to-Linux-4.14-state.patch b/bcm283x-device-tree-sources-to-Linux-4.14-state.patch deleted file mode 100644 index 304b61a..0000000 --- a/bcm283x-device-tree-sources-to-Linux-4.14-state.patch +++ /dev/null @@ -1,1242 +0,0 @@ -From patchwork Wed Oct 4 12:39:16 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, - v2] fdt: update bcm283x device tree sources to Linux 4.14 state -X-Patchwork-Submitter: Alexander Graf -X-Patchwork-Id: 821297 -Message-Id: <20171004123916.13789-1-agraf@suse.de> -To: u-boot@lists.denx.de -Cc: Stefan Wahren , Fabian Vogt -Date: Wed, 4 Oct 2017 14:39:16 +0200 -From: Alexander Graf -List-Id: U-Boot discussion - -Upstream Linux has received a few device tree updates to the RPi -which we should propagate into the builtin U-Boot one as well to -gain hardware support. - -This patch bumps the dts files to their 4.14 Linux counterparts -with the exception of sdhost on 32bit RPi versions. There we stay -with iproc as the sdhost driver is missing in U-Boot. - -Signed-off-by: Alexander Graf ---- - -v1 -> v2: - - - use sdhost on 32bit RPis ---- - arch/arm/dts/bcm2835-rpi-a-plus.dts | 74 +++++++- - arch/arm/dts/bcm2835-rpi-a.dts | 76 +++++++- - arch/arm/dts/bcm2835-rpi-b-plus.dts | 75 +++++++- - arch/arm/dts/bcm2835-rpi-b-rev2.dts | 75 +++++++- - arch/arm/dts/bcm2835-rpi-b.dts | 76 +++++++- - arch/arm/dts/bcm2835-rpi.dtsi | 34 +++- - arch/arm/dts/bcm2835.dtsi | 10 + - arch/arm/dts/bcm2836-rpi-2-b.dts | 9 +- - arch/arm/dts/bcm2836.dtsi | 11 ++ - arch/arm/dts/bcm2837-rpi-3-b.dts | 35 +++- - arch/arm/dts/bcm2837.dtsi | 13 +- - arch/arm/dts/bcm283x-rpi-smsc9512.dtsi | 2 +- - arch/arm/dts/bcm283x-rpi-smsc9514.dtsi | 2 +- - arch/arm/dts/bcm283x-rpi-usb-host.dtsi | 3 + - arch/arm/dts/bcm283x.dtsi | 325 ++++++++++++++++++++++++++++++++- - include/dt-bindings/clock/bcm2835.h | 2 + - include/dt-bindings/pinctrl/bcm2835.h | 5 + - 17 files changed, 801 insertions(+), 26 deletions(-) - create mode 100644 arch/arm/dts/bcm283x-rpi-usb-host.dtsi - -diff --git a/arch/arm/dts/bcm2835-rpi-a-plus.dts b/arch/arm/dts/bcm2835-rpi-a-plus.dts -index 35ff4e7a4a..9f866491ef 100644 ---- a/arch/arm/dts/bcm2835-rpi-a-plus.dts -+++ b/arch/arm/dts/bcm2835-rpi-a-plus.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,model-a-plus", "brcm,bcm2835"; -@@ -21,7 +22,72 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+ /* -+ * This is based on the unreleased schematic for the Model A+. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "NC", /* GPIO31 */ -+ "CAM_GPIO1", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "PWR_LOW_N", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "USB_LIMIT", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", /* GPIO40 */ -+ "CAM_GPIO0", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", /* GPIO45 */ -+ "HDMI_HPD_N", -+ "STATUS_LED", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ -+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>; - - /* I2S interface */ - i2s_alt0: i2s_alt0 { -@@ -33,3 +99,9 @@ - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2835-rpi-a.dts b/arch/arm/dts/bcm2835-rpi-a.dts -index 306a84ee98..4b1af06c8d 100644 ---- a/arch/arm/dts/bcm2835-rpi-a.dts -+++ b/arch/arm/dts/bcm2835-rpi-a.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,model-a", "brcm,bcm2835"; -@@ -14,7 +15,74 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -+ /* -+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf -+ * RPI00021 sheet 02 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "CAM_GPIO1", -+ "LAN_RUN", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "NC", /* GPIO12 */ -+ "NC", /* GPIO13 */ -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "STATUS_LED_N", -+ "GPIO17", -+ "GPIO18", -+ "NC", /* GPIO19 */ -+ "NC", /* GPIO20 */ -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "NC", /* GPIO26 */ -+ "CAM_GPIO0", -+ /* Binary number representing build/revision */ -+ "CONFIG0", -+ "CONFIG1", -+ "CONFIG2", -+ "CONFIG3", -+ "NC", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "NC", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", -+ "HDMI_HPD_P", -+ "SD_CARD_DET", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ -+ pinctrl-0 = <&gpioout &alt0 &i2s_alt2>; - - /* I2S interface */ - i2s_alt2: i2s_alt2 { -@@ -26,3 +94,9 @@ - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2835-rpi-b-plus.dts b/arch/arm/dts/bcm2835-rpi-b-plus.dts -index d5fdb8e761..a846f1e781 100644 ---- a/arch/arm/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/dts/bcm2835-rpi-b-plus.dts -@@ -2,6 +2,7 @@ - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; -@@ -22,7 +23,73 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+ /* -+ * Taken from Raspberry-Pi-B-Plus-V1.2-Schematics.pdf -+ * RPI-BPLUS sheet 1 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "LAN_RUN", /* GPIO31 */ -+ "CAM_GPIO1", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "PWR_LOW_N", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "USB_LIMIT", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", /* GPIO40 */ -+ "CAM_GPIO0", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "ETHCLK", /* GPIO44 */ -+ "PWM1_OUT", /* GPIO45 */ -+ "HDMI_HPD_N", -+ "STATUS_LED", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ -+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>; - - /* I2S interface */ - i2s_alt0: i2s_alt0 { -@@ -34,3 +101,9 @@ - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/dts/bcm2835-rpi-b-rev2.dts -index bfc4bd9b77..e860964e39 100644 ---- a/arch/arm/dts/bcm2835-rpi-b-rev2.dts -+++ b/arch/arm/dts/bcm2835-rpi-b-rev2.dts -@@ -2,6 +2,7 @@ - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" - #include "bcm283x-rpi-smsc9512.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835"; -@@ -15,7 +16,73 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -+ /* -+ * Taken from Raspberry-Pi-Rev-2.0-Model-AB-Schematics.pdf -+ * RPI00022 sheet 02 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "CAM_CLK", -+ "LAN_RUN", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "NC", /* GPIO12 */ -+ "NC", /* GPIO13 */ -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "STATUS_LED_N", -+ "GPIO17", -+ "GPIO18", -+ "NC", /* GPIO19 */ -+ "NC", /* GPIO20 */ -+ "CAM_GPIO", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "NC", /* GPIO26 */ -+ "GPIO27", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "NC", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "NC", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", -+ "HDMI_HPD_P", -+ "SD_CARD_DET", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ -+ pinctrl-0 = <&gpioout &alt0 &i2s_alt2>; - - /* I2S interface */ - i2s_alt2: i2s_alt2 { -@@ -27,3 +94,9 @@ - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2835-rpi-b.dts b/arch/arm/dts/bcm2835-rpi-b.dts -index 0371bb7374..5d77f3f8c4 100644 ---- a/arch/arm/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/dts/bcm2835-rpi-b.dts -@@ -2,6 +2,7 @@ - #include "bcm2835.dtsi" - #include "bcm2835-rpi.dtsi" - #include "bcm283x-rpi-smsc9512.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; -@@ -15,9 +16,82 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &alt3>; -+ /* -+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf -+ * RPI00021 sheet 02 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "CAM_GPIO1", -+ "LAN_RUN", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "NC", /* GPIO12 */ -+ "NC", /* GPIO13 */ -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "STATUS_LED_N", -+ "GPIO17", -+ "GPIO18", -+ "NC", /* GPIO19 */ -+ "NC", /* GPIO20 */ -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "NC", /* GPIO26 */ -+ "CAM_GPIO0", -+ /* Binary number representing build/revision */ -+ "CONFIG0", -+ "CONFIG1", -+ "CONFIG2", -+ "CONFIG3", -+ "NC", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "NC", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", -+ "HDMI_HPD_P", -+ "SD_CARD_DET", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ -+ pinctrl-0 = <&gpioout &alt0>; - }; - - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2835-rpi.dtsi b/arch/arm/dts/bcm2835-rpi.dtsi -index e9b47b2bbc..8b95832dd0 100644 ---- a/arch/arm/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/dts/bcm2835-rpi.dtsi -@@ -39,22 +39,21 @@ - }; - - alt0: alt0 { -- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; -+ brcm,pins = <4 5 7 8 9 10 11>; - brcm,function = ; - }; -- -- alt3: alt3 { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = ; -- }; - }; - - &i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_gpio0>; - status = "okay"; - clock-frequency = <100000>; - }; - - &i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_gpio2>; - status = "okay"; - clock-frequency = <100000>; - }; -@@ -64,11 +63,21 @@ - }; - - &sdhci { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_gpio48>; - status = "okay"; - bus-width = <4>; - }; - -+&sdhost { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_gpio48>; -+ bus-width = <4>; -+}; -+ - &pwm { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>; - status = "okay"; - }; - -@@ -84,3 +93,16 @@ - power-domains = <&power RPI_POWER_DOMAIN_HDMI>; - status = "okay"; - }; -+ -+&vec { -+ power-domains = <&power RPI_POWER_DOMAIN_VEC>; -+ status = "okay"; -+}; -+ -+&dsi0 { -+ power-domains = <&power RPI_POWER_DOMAIN_DSI0>; -+}; -+ -+&dsi1 { -+ power-domains = <&power RPI_POWER_DOMAIN_DSI1>; -+}; -diff --git a/arch/arm/dts/bcm2835.dtsi b/arch/arm/dts/bcm2835.dtsi -index a78759e737..659b6e9513 100644 ---- a/arch/arm/dts/bcm2835.dtsi -+++ b/arch/arm/dts/bcm2835.dtsi -@@ -23,3 +23,13 @@ - }; - }; - }; -+ -+&cpu_thermal { -+ coefficients = <(-538) 407000>; -+}; -+ -+/* enable thermal sensor with the correct compatible property set */ -+&thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2836-rpi-2-b.dts b/arch/arm/dts/bcm2836-rpi-2-b.dts -index 29e1cfe8eb..e8de41444b 100644 ---- a/arch/arm/dts/bcm2836-rpi-2-b.dts -+++ b/arch/arm/dts/bcm2836-rpi-2-b.dts -@@ -2,6 +2,7 @@ - #include "bcm2836.dtsi" - #include "bcm2835-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; -@@ -26,7 +27,7 @@ - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+ pinctrl-0 = <&gpioout &alt0 &i2s_alt0>; - - /* I2S interface */ - i2s_alt0: i2s_alt0 { -@@ -38,3 +39,9 @@ - &hdmi { - hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; - }; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio14>; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2836.dtsi b/arch/arm/dts/bcm2836.dtsi -index 9d0651d8f3..2c26d0be8b 100644 ---- a/arch/arm/dts/bcm2836.dtsi -+++ b/arch/arm/dts/bcm2836.dtsi -@@ -36,6 +36,7 @@ - cpus: cpus { - #address-cells = <1>; - #size-cells = <0>; -+ enable-method = "brcm,bcm2836-smp"; - - v7_cpu0: cpu@0 { - device_type = "cpu"; -@@ -76,3 +77,13 @@ - interrupt-parent = <&local_intc>; - interrupts = <8>; - }; -+ -+&cpu_thermal { -+ coefficients = <(-538) 407000>; -+}; -+ -+/* enable thermal sensor with the correct compatible property set */ -+&thermal { -+ compatible = "brcm,bcm2836-thermal"; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm2837-rpi-3-b.dts b/arch/arm/dts/bcm2837-rpi-3-b.dts -index 7841b724e3..20725ca487 100644 ---- a/arch/arm/dts/bcm2837-rpi-3-b.dts -+++ b/arch/arm/dts/bcm2837-rpi-3-b.dts -@@ -2,6 +2,7 @@ - #include "bcm2837.dtsi" - #include "bcm2835-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" -+#include "bcm283x-rpi-usb-host.dtsi" - - / { - compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; -@@ -15,16 +16,36 @@ - act { - gpios = <&gpio 47 0>; - }; -- -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; - }; - }; - -+/* uart0 communicates with the BT module */ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>; -+ status = "okay"; -+}; -+ -+/* uart1 is mapped to the pin header */ - &uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_gpio14>; -+ status = "okay"; -+}; -+ -+/* SDHCI is used to control the SDIO for wireless */ -+&sdhci { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_gpio34>; -+ status = "okay"; -+ bus-width = <4>; -+ non-removable; -+}; -+ -+/* SDHOST is used to drive the SD card */ -+&sdhost { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_gpio48>; - status = "okay"; -+ bus-width = <4>; - }; -diff --git a/arch/arm/dts/bcm2837.dtsi b/arch/arm/dts/bcm2837.dtsi -index 8216bbb29f..bc1cca5cf4 100644 ---- a/arch/arm/dts/bcm2837.dtsi -+++ b/arch/arm/dts/bcm2837.dtsi -@@ -1,7 +1,7 @@ - #include "bcm283x.dtsi" - - / { -- compatible = "brcm,bcm2836"; -+ compatible = "brcm,bcm2837"; - - soc { - ranges = <0x7e000000 0x3f000000 0x1000000>, -@@ -30,6 +30,7 @@ - cpus: cpus { - #address-cells = <1>; - #size-cells = <0>; -+ enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit - - cpu0: cpu@0 { - device_type = "cpu"; -@@ -74,3 +75,13 @@ - interrupt-parent = <&local_intc>; - interrupts = <8>; - }; -+ -+&cpu_thermal { -+ coefficients = <(-538) 412000>; -+}; -+ -+/* enable thermal sensor with the correct compatible property set */ -+&thermal { -+ compatible = "brcm,bcm2837-thermal"; -+ status = "okay"; -+}; -diff --git a/arch/arm/dts/bcm283x-rpi-smsc9512.dtsi b/arch/arm/dts/bcm283x-rpi-smsc9512.dtsi -index 12c981e511..9a0599f711 100644 ---- a/arch/arm/dts/bcm283x-rpi-smsc9512.dtsi -+++ b/arch/arm/dts/bcm283x-rpi-smsc9512.dtsi -@@ -1,6 +1,6 @@ - / { - aliases { -- ethernet = ðernet; -+ ethernet0 = ðernet; - }; - }; - -diff --git a/arch/arm/dts/bcm283x-rpi-smsc9514.dtsi b/arch/arm/dts/bcm283x-rpi-smsc9514.dtsi -index 3f0a56ebcf..dc7ae776db 100644 ---- a/arch/arm/dts/bcm283x-rpi-smsc9514.dtsi -+++ b/arch/arm/dts/bcm283x-rpi-smsc9514.dtsi -@@ -1,6 +1,6 @@ - / { - aliases { -- ethernet = ðernet; -+ ethernet0 = ðernet; - }; - }; - -diff --git a/arch/arm/dts/bcm283x-rpi-usb-host.dtsi b/arch/arm/dts/bcm283x-rpi-usb-host.dtsi -new file mode 100644 -index 0000000000..73f4ece8dc ---- /dev/null -+++ b/arch/arm/dts/bcm283x-rpi-usb-host.dtsi -@@ -0,0 +1,3 @@ -+&usb { -+ dr_mode = "host"; -+}; -diff --git a/arch/arm/dts/bcm283x.dtsi b/arch/arm/dts/bcm283x.dtsi -index e5b4f20c2a..05a6f489af 100644 ---- a/arch/arm/dts/bcm283x.dtsi -+++ b/arch/arm/dts/bcm283x.dtsi -@@ -3,6 +3,11 @@ - #include - #include - -+/* firmware-provided startup stubs live here, where the secondary CPUs are -+ * spinning. -+ */ -+/memreserve/ 0x00000000 0x00001000; -+ - /* This include file covers the common peripherals and configuration between - * bcm2835 and bcm2836 implementations, leaving the CPU configuration to - * bcm2835.dtsi and bcm2836.dtsi. -@@ -19,6 +24,26 @@ - bootargs = "earlyprintk console=ttyAMA0"; - }; - -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <0>; -+ polling-delay = <1000>; -+ -+ thermal-sensors = <&thermal>; -+ -+ trips { -+ cpu-crit { -+ temperature = <80000>; -+ hysteresis = <0>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ }; -+ }; -+ }; -+ - soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; -@@ -93,10 +118,13 @@ - #clock-cells = <1>; - reg = <0x7e101000 0x2000>; - -- /* CPRMAN derives everything from the platform's -- * oscillator. -+ /* CPRMAN derives almost everything from the -+ * platform's oscillator. However, the DSI -+ * pixel clocks come from the DSI analog PHY. - */ -- clocks = <&clk_osc>; -+ clocks = <&clk_osc>, -+ <&dsi0 0>, <&dsi0 1>, <&dsi0 2>, -+ <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; - }; - - rng@7e104000 { -@@ -104,7 +132,7 @@ - reg = <0x7e104000 0x10>; - }; - -- mailbox: mailbox@7e00b800 { -+ mailbox: mailbox@7e00b880 { - compatible = "brcm,bcm2835-mbox"; - reg = <0x7e00b880 0x40>; - interrupts = <0 1>; -@@ -132,6 +160,213 @@ - - interrupt-controller; - #interrupt-cells = <2>; -+ -+ /* Defines pin muxing groups according to -+ * BCM2835-ARM-Peripherals.pdf page 102. -+ * -+ * While each pin can have its mux selected -+ * for various functions individually, some -+ * groups only make sense to switch to a -+ * particular function together. -+ */ -+ dpi_gpio0: dpi_gpio0 { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15 16 17 18 19 -+ 20 21 22 23 24 25 26 27>; -+ brcm,function = ; -+ }; -+ emmc_gpio22: emmc_gpio22 { -+ brcm,pins = <22 23 24 25 26 27>; -+ brcm,function = ; -+ }; -+ emmc_gpio34: emmc_gpio34 { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ emmc_gpio48: emmc_gpio48 { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = ; -+ }; -+ -+ gpclk0_gpio4: gpclk0_gpio4 { -+ brcm,pins = <4>; -+ brcm,function = ; -+ }; -+ gpclk1_gpio5: gpclk1_gpio5 { -+ brcm,pins = <5>; -+ brcm,function = ; -+ }; -+ gpclk1_gpio42: gpclk1_gpio42 { -+ brcm,pins = <42>; -+ brcm,function = ; -+ }; -+ gpclk1_gpio44: gpclk1_gpio44 { -+ brcm,pins = <44>; -+ brcm,function = ; -+ }; -+ gpclk2_gpio6: gpclk2_gpio6 { -+ brcm,pins = <6>; -+ brcm,function = ; -+ }; -+ gpclk2_gpio43: gpclk2_gpio43 { -+ brcm,pins = <43>; -+ brcm,function = ; -+ }; -+ -+ i2c0_gpio0: i2c0_gpio0 { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ }; -+ i2c0_gpio28: i2c0_gpio28 { -+ brcm,pins = <28 29>; -+ brcm,function = ; -+ }; -+ i2c0_gpio44: i2c0_gpio44 { -+ brcm,pins = <44 45>; -+ brcm,function = ; -+ }; -+ i2c1_gpio2: i2c1_gpio2 { -+ brcm,pins = <2 3>; -+ brcm,function = ; -+ }; -+ i2c1_gpio44: i2c1_gpio44 { -+ brcm,pins = <44 45>; -+ brcm,function = ; -+ }; -+ i2c_slave_gpio18: i2c_slave_gpio18 { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ -+ jtag_gpio4: jtag_gpio4 { -+ brcm,pins = <4 5 6 12 13>; -+ brcm,function = ; -+ }; -+ jtag_gpio22: jtag_gpio22 { -+ brcm,pins = <22 23 24 25 26 27>; -+ brcm,function = ; -+ }; -+ -+ pcm_gpio18: pcm_gpio18 { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ pcm_gpio28: pcm_gpio28 { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = ; -+ }; -+ -+ pwm0_gpio12: pwm0_gpio12 { -+ brcm,pins = <12>; -+ brcm,function = ; -+ }; -+ pwm0_gpio18: pwm0_gpio18 { -+ brcm,pins = <18>; -+ brcm,function = ; -+ }; -+ pwm0_gpio40: pwm0_gpio40 { -+ brcm,pins = <40>; -+ brcm,function = ; -+ }; -+ pwm1_gpio13: pwm1_gpio13 { -+ brcm,pins = <13>; -+ brcm,function = ; -+ }; -+ pwm1_gpio19: pwm1_gpio19 { -+ brcm,pins = <19>; -+ brcm,function = ; -+ }; -+ pwm1_gpio41: pwm1_gpio41 { -+ brcm,pins = <41>; -+ brcm,function = ; -+ }; -+ pwm1_gpio45: pwm1_gpio45 { -+ brcm,pins = <45>; -+ brcm,function = ; -+ }; -+ -+ sdhost_gpio48: sdhost_gpio48 { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = ; -+ }; -+ -+ spi0_gpio7: spi0_gpio7 { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = ; -+ }; -+ spi0_gpio35: spi0_gpio35 { -+ brcm,pins = <35 36 37 38 39>; -+ brcm,function = ; -+ }; -+ spi1_gpio16: spi1_gpio16 { -+ brcm,pins = <16 17 18 19 20 21>; -+ brcm,function = ; -+ }; -+ spi2_gpio40: spi2_gpio40 { -+ brcm,pins = <40 41 42 43 44 45>; -+ brcm,function = ; -+ }; -+ -+ uart0_gpio14: uart0_gpio14 { -+ brcm,pins = <14 15>; -+ brcm,function = ; -+ }; -+ /* Separate from the uart0_gpio14 group -+ * because it conflicts with spi1_gpio16, and -+ * people often run uart0 on the two pins -+ * without flow control. -+ */ -+ uart0_ctsrts_gpio16: uart0_ctsrts_gpio16 { -+ brcm,pins = <16 17>; -+ brcm,function = ; -+ }; -+ uart0_ctsrts_gpio30: uart0_ctsrts_gpio30 { -+ brcm,pins = <30 31>; -+ brcm,function = ; -+ }; -+ uart0_gpio32: uart0_gpio32 { -+ brcm,pins = <32 33>; -+ brcm,function = ; -+ }; -+ uart0_gpio36: uart0_gpio36 { -+ brcm,pins = <36 37>; -+ brcm,function = ; -+ }; -+ uart0_ctsrts_gpio38: uart0_ctsrts_gpio38 { -+ brcm,pins = <38 39>; -+ brcm,function = ; -+ }; -+ -+ uart1_gpio14: uart1_gpio14 { -+ brcm,pins = <14 15>; -+ brcm,function = ; -+ }; -+ uart1_ctsrts_gpio16: uart1_ctsrts_gpio16 { -+ brcm,pins = <16 17>; -+ brcm,function = ; -+ }; -+ uart1_gpio32: uart1_gpio32 { -+ brcm,pins = <32 33>; -+ brcm,function = ; -+ }; -+ uart1_ctsrts_gpio30: uart1_ctsrts_gpio30 { -+ brcm,pins = <30 31>; -+ brcm,function = ; -+ }; -+ uart1_gpio40: uart1_gpio40 { -+ brcm,pins = <40 41>; -+ brcm,function = ; -+ }; -+ uart1_ctsrts_gpio42: uart1_ctsrts_gpio42 { -+ brcm,pins = <42 43>; -+ brcm,function = ; -+ }; - }; - - uart0: serial@7e201000 { -@@ -144,6 +379,16 @@ - arm,primecell-periphid = <0x00241011>; - }; - -+ sdhost: mmc@7e202000 { -+ compatible = "brcm,bcm2835-sdhost"; -+ reg = <0x7e202000 0x100>; -+ interrupts = <2 24>; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ dmas = <&dma 13>; -+ dma-names = "rx-tx"; -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2835-i2s"; - reg = <0x7e203000 0x20>, -@@ -187,6 +432,33 @@ - interrupts = <2 14>; /* pwa1 */ - }; - -+ dsi0: dsi@7e209000 { -+ compatible = "brcm,bcm2835-dsi0"; -+ reg = <0x7e209000 0x78>; -+ interrupts = <2 4>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #clock-cells = <1>; -+ -+ clocks = <&clocks BCM2835_PLLA_DSI0>, -+ <&clocks BCM2835_CLOCK_DSI0E>, -+ <&clocks BCM2835_CLOCK_DSI0P>; -+ clock-names = "phy", "escape", "pixel"; -+ -+ clock-output-names = "dsi0_byte", -+ "dsi0_ddr2", -+ "dsi0_ddr"; -+ -+ }; -+ -+ thermal: thermal@7e212000 { -+ compatible = "brcm,bcm2835-thermal"; -+ reg = <0x7e212000 0x8>; -+ clocks = <&clocks BCM2835_CLOCK_TSENS>; -+ #thermal-sensor-cells = <0>; -+ status = "disabled"; -+ }; -+ - aux: aux@0x7e215000 { - compatible = "brcm,bcm2835-aux"; - #clock-cells = <1>; -@@ -246,6 +518,26 @@ - interrupts = <2 1>; - }; - -+ dsi1: dsi@7e700000 { -+ compatible = "brcm,bcm2835-dsi1"; -+ reg = <0x7e700000 0x8c>; -+ interrupts = <2 12>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #clock-cells = <1>; -+ -+ clocks = <&clocks BCM2835_PLLD_DSI1>, -+ <&clocks BCM2835_CLOCK_DSI1E>, -+ <&clocks BCM2835_CLOCK_DSI1P>; -+ clock-names = "phy", "escape", "pixel"; -+ -+ clock-output-names = "dsi1_byte", -+ "dsi1_ddr2", -+ "dsi1_ddr"; -+ -+ status = "disabled"; -+ }; -+ - i2c1: i2c@7e804000 { - compatible = "brcm,bcm2835-i2c"; - reg = <0x7e804000 0x1000>; -@@ -266,6 +558,14 @@ - status = "disabled"; - }; - -+ vec: vec@7e806000 { -+ compatible = "brcm,bcm2835-vec"; -+ reg = <0x7e806000 0x1000>; -+ clocks = <&clocks BCM2835_CLOCK_VEC>; -+ interrupts = <2 27>; -+ status = "disabled"; -+ }; -+ - pixelvalve@7e807000 { - compatible = "brcm,bcm2835-pixelvalve2"; - reg = <0x7e807000 0x100>; -@@ -281,6 +581,8 @@ - clocks = <&clocks BCM2835_PLLH_PIX>, - <&clocks BCM2835_CLOCK_HSM>; - clock-names = "pixel", "hdmi"; -+ dmas = <&dma 17>; -+ dma-names = "audio-rx"; - status = "disabled"; - }; - -@@ -290,6 +592,10 @@ - interrupts = <1 9>; - #address-cells = <1>; - #size-cells = <0>; -+ clocks = <&clk_usb>; -+ clock-names = "otg"; -+ phys = <&usbphy>; -+ phy-names = "usb2-phy"; - }; - - v3d: v3d@7ec00000 { -@@ -317,6 +623,17 @@ - clock-frequency = <19200000>; - }; - -+ clk_usb: clock@4 { -+ compatible = "fixed-clock"; -+ reg = <4>; -+ #clock-cells = <0>; -+ clock-output-names = "otg"; -+ clock-frequency = <480000000>; -+ }; -+ }; -+ -+ usbphy: phy { -+ compatible = "usb-nop-xceiv"; - }; - }; - -diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h -index 360e00cefd..a0c812b0fa 100644 ---- a/include/dt-bindings/clock/bcm2835.h -+++ b/include/dt-bindings/clock/bcm2835.h -@@ -64,3 +64,5 @@ - #define BCM2835_CLOCK_CAM1 46 - #define BCM2835_CLOCK_DSI0E 47 - #define BCM2835_CLOCK_DSI1E 48 -+#define BCM2835_CLOCK_DSI0P 49 -+#define BCM2835_CLOCK_DSI1P 50 -diff --git a/include/dt-bindings/pinctrl/bcm2835.h b/include/dt-bindings/pinctrl/bcm2835.h -index 6f0bc37af3..e4e4fdf5d3 100644 ---- a/include/dt-bindings/pinctrl/bcm2835.h -+++ b/include/dt-bindings/pinctrl/bcm2835.h -@@ -24,4 +24,9 @@ - #define BCM2835_FSEL_ALT2 6 - #define BCM2835_FSEL_ALT3 7 - -+/* brcm,pull property */ -+#define BCM2835_PUD_OFF 0 -+#define BCM2835_PUD_DOWN 1 -+#define BCM2835_PUD_UP 2 -+ - #endif /* __DT_BINDINGS_PINCTRL_BCM2835_H__ */ diff --git a/disk-part_dos-Use-the-original-allocation-scheme-for-the-SPL-case.patch b/disk-part_dos-Use-the-original-allocation-scheme-for-the-SPL-case.patch deleted file mode 100644 index aa9f81e..0000000 --- a/disk-part_dos-Use-the-original-allocation-scheme-for-the-SPL-case.patch +++ /dev/null @@ -1,70 +0,0 @@ -From patchwork Wed Oct 4 16:29:57 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot] disk: part_dos: Use the original allocation scheme for the - SPL case -X-Patchwork-Submitter: Fabio Estevam -X-Patchwork-Id: 821393 -Message-Id: <1507134597-6831-1-git-send-email-fabio.estevam@nxp.com> -To: -Cc: u-boot@lists.denx.de, pjones@redhat.com, - Fabio Estevam -Date: Wed, 4 Oct 2017 13:29:57 -0300 -From: Fabio Estevam -List-Id: U-Boot discussion - -Since commit ff98cb90514d ("part: extract MBR signature from partitions") -SPL boot on i.MX6 starts to fail: - -U-Boot SPL 2017.09-00221-g0d6ab32 (Oct 02 2017 - 15:13:19) -Trying to boot from MMC1 -(keep in loop) - -Use the original allocation scheme for the SPL case, so that MX6 boards -can boot again. - -This is a temporary solution to avoid the boot regression. - -Signed-off-by: Fabio Estevam -Acked-by: Rob Clark ---- -Hi Tom, - -I do not have time this week to further investigate and narrow down -this problem. - -Using the old allocation scheme fixes the mx6 SPL boot problem. - - - disk/part_dos.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/disk/part_dos.c b/disk/part_dos.c -index 1a36be0..6dd2c2d 100644 ---- a/disk/part_dos.c -+++ b/disk/part_dos.c -@@ -89,6 +89,7 @@ static int test_block_type(unsigned char *buffer) - - static int part_test_dos(struct blk_desc *dev_desc) - { -+#ifndef CONFIG_SPL_BUILD - ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz); - - if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) -@@ -102,6 +103,15 @@ static int part_test_dos(struct blk_desc *dev_desc) - dev_desc->sig_type = SIG_TYPE_MBR; - dev_desc->mbr_sig = mbr->unique_mbr_signature; - } -+#else -+ ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); -+ -+ if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1) -+ return -1; -+ -+ if (test_block_type(buffer) != DOS_MBR) -+ return -1; -+#endif - - return 0; - } diff --git a/dm-video-enhancements-for-Shell.efi.patch b/dm-video-enhancements-for-Shell.efi.patch deleted file mode 100644 index c335089..0000000 --- a/dm-video-enhancements-for-Shell.efi.patch +++ /dev/null @@ -1,434 +0,0 @@ -From patchwork Wed Sep 13 22:12:20 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,1/3] dm: video: Fix cache flushes -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813662 -X-Patchwork-Delegate: sjg@chromium.org -Message-Id: <20170913221227.21091-2-robdclark@gmail.com> -To: U-Boot Mailing List -Date: Wed, 13 Sep 2017 18:12:20 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Content can come to screen via putc() and we cannot always rely on -updates ending with a puts(). This is the case with efi_console output -to vidconsole. Fixes corruption with Shell.efi. - -Signed-off-by: Rob Clark ---- - drivers/video/vidconsole-uclass.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c -index b5afd72227..e081d5a0ee 100644 ---- a/drivers/video/vidconsole-uclass.c -+++ b/drivers/video/vidconsole-uclass.c -@@ -163,6 +163,7 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch) - struct udevice *dev = sdev->priv; - - vidconsole_put_char(dev, ch); -+ video_sync(dev->parent); - } - - static void vidconsole_puts(struct stdio_dev *sdev, const char *s) -@@ -260,6 +261,8 @@ static int do_video_puts(cmd_tbl_t *cmdtp, int flag, int argc, - for (s = argv[1]; *s; s++) - vidconsole_put_char(dev, *s); - -+ video_sync(dev->parent); -+ - return 0; - } - - -From patchwork Wed Sep 13 22:12:21 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,2/3] dm: video: Add basic ANSI escape sequence support -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813649 -X-Patchwork-Delegate: sjg@chromium.org -Message-Id: <20170913221227.21091-3-robdclark@gmail.com> -To: U-Boot Mailing List -Date: Wed, 13 Sep 2017 18:12:21 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Really just the subset that is needed by efi_console. Perhaps more will -be added later, for example color support would be useful to implement -efi_cout_set_attribute(). - -Signed-off-by: Rob Clark -Reviewed-by: Simon Glass ---- - drivers/video/Kconfig | 8 +++ - drivers/video/vidconsole-uclass.c | 109 ++++++++++++++++++++++++++++++++++++++ - drivers/video/video-uclass.c | 4 +- - include/video.h | 7 +++ - include/video_console.h | 11 ++++ - 5 files changed, 136 insertions(+), 3 deletions(-) - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 082cc4a528..add156cb70 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -44,6 +44,14 @@ config VIDEO_BPP32 - this option, such displays will not be supported and console output - will be empty. - -+config VIDEO_ANSI -+ bool "Support ANSI escape sequences in video console" -+ depends on DM_VIDEO -+ default y if DM_VIDEO -+ help -+ Enable ANSI escape sequence decoding for a more fully functional -+ console. -+ - config CONSOLE_NORMAL - bool "Support a simple text console" - depends on DM_VIDEO -diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c -index e081d5a0ee..0a88cc0a42 100644 ---- a/drivers/video/vidconsole-uclass.c -+++ b/drivers/video/vidconsole-uclass.c -@@ -9,6 +9,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -107,12 +108,120 @@ static void vidconsole_newline(struct udevice *dev) - video_sync(dev->parent); - } - -+static char *parsenum(char *s, int *num) -+{ -+ char *end; -+ *num = simple_strtol(s, &end, 10); -+ return end; -+} -+ -+/* -+ * Process a character while accumulating an escape string. Chars are -+ * accumulated into escape_buf until the end of escape sequence is -+ * found, at which point the sequence is parsed and processed. -+ */ -+static void vidconsole_escape_char(struct udevice *dev, char ch) -+{ -+ struct vidconsole_priv *priv = dev_get_uclass_priv(dev); -+ -+ if (!IS_ENABLED(CONFIG_VIDEO_ANSI)) -+ goto error; -+ -+ /* Sanity checking for bogus ESC sequences: */ -+ if (priv->escape_len >= sizeof(priv->escape_buf)) -+ goto error; -+ if (priv->escape_len == 0 && ch != '[') -+ goto error; -+ -+ priv->escape_buf[priv->escape_len++] = ch; -+ -+ /* -+ * Escape sequences are terminated by a letter, so keep -+ * accumulating until we get one: -+ */ -+ if (!isalpha(ch)) -+ return; -+ -+ /* -+ * clear escape mode first, otherwise things will get highly -+ * surprising if you hit any debug prints that come back to -+ * this console. -+ */ -+ priv->escape = 0; -+ -+ switch (ch) { -+ case 'H': -+ case 'f': { -+ int row, col; -+ char *s = priv->escape_buf; -+ -+ /* -+ * Set cursor position: [%d;%df or [%d;%dH -+ */ -+ s++; /* [ */ -+ s = parsenum(s, &row); -+ s++; /* ; */ -+ s = parsenum(s, &col); -+ -+ priv->ycur = row * priv->y_charsize; -+ priv->xcur_frac = priv->xstart_frac + -+ VID_TO_POS(col * priv->x_charsize); -+ -+ break; -+ } -+ case 'J': { -+ int mode; -+ -+ /* -+ * Clear part/all screen: -+ * [J or [0J - clear screen from cursor down -+ * [1J - clear screen from cursor up -+ * [2J - clear entire screen -+ * -+ * TODO we really only handle entire-screen case, others -+ * probably require some additions to video-uclass (and -+ * are not really needed yet by efi_console) -+ */ -+ parsenum(priv->escape_buf + 1, &mode); -+ -+ if (mode == 2) { -+ video_clear(dev->parent); -+ video_sync(dev->parent); -+ priv->ycur = 0; -+ priv->xcur_frac = priv->xstart_frac; -+ } else { -+ debug("unsupported clear mode: %d\n", mode); -+ } -+ break; -+ } -+ default: -+ debug("unrecognized escape sequence: %*s\n", -+ priv->escape_len, priv->escape_buf); -+ } -+ -+ return; -+ -+error: -+ /* something went wrong, just revert to normal mode: */ -+ priv->escape = 0; -+ return; -+} -+ - int vidconsole_put_char(struct udevice *dev, char ch) - { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - int ret; - -+ if (priv->escape) { -+ vidconsole_escape_char(dev, ch); -+ return 0; -+ } -+ - switch (ch) { -+ case '\x1b': -+ priv->escape_len = 0; -+ priv->escape = 1; -+ break; - case '\a': - /* beep */ - break; -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 3036e3a1f2..0163039821 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -87,7 +87,7 @@ int video_reserve(ulong *addrp) - return 0; - } - --static int video_clear(struct udevice *dev) -+void video_clear(struct udevice *dev) - { - struct video_priv *priv = dev_get_uclass_priv(dev); - -@@ -100,8 +100,6 @@ static int video_clear(struct udevice *dev) - } else { - memset(priv->fb, priv->colour_bg, priv->fb_size); - } -- -- return 0; - } - - /* Flush video activity to the caches */ -diff --git a/include/video.h b/include/video.h -index 5b4e78b182..61ff653121 100644 ---- a/include/video.h -+++ b/include/video.h -@@ -115,6 +115,13 @@ struct video_ops { - int video_reserve(ulong *addrp); - - /** -+ * video_clear() - Clear a device's frame buffer to background color. -+ * -+ * @dev: Device to clear -+ */ -+void video_clear(struct udevice *dev); -+ -+/** - * video_sync() - Sync a device's frame buffer with its hardware - * - * Some frame buffers are cached or have a secondary frame buffer. This -diff --git a/include/video_console.h b/include/video_console.h -index 26047934da..9dce234bd9 100644 ---- a/include/video_console.h -+++ b/include/video_console.h -@@ -29,6 +29,9 @@ - * @xsize_frac: Width of the display in fractional units - * @xstart_frac: Left margin for the text console in fractional units - * @last_ch: Last character written to the text console on this line -+ * @escape: TRUE if currently accumulating an ANSI escape sequence -+ * @escape_len: Length of accumulated escape sequence so far -+ * @escape_buf: Buffer to accumulate escape sequence - */ - struct vidconsole_priv { - struct stdio_dev sdev; -@@ -42,6 +45,14 @@ struct vidconsole_priv { - int xsize_frac; - int xstart_frac; - int last_ch; -+ /* -+ * ANSI escape sequences are accumulated character by character, -+ * starting after the ESC char (0x1b) until the entire sequence -+ * is consumed at which point it is acted upon. -+ */ -+ int escape; -+ int escape_len; -+ char escape_buf[32]; - }; - - /** - -From patchwork Wed Sep 13 22:12:22 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,3/3] dm: video: Add color ANSI escape sequence support -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813661 -X-Patchwork-Delegate: sjg@chromium.org -Message-Id: <20170913221227.21091-4-robdclark@gmail.com> -To: U-Boot Mailing List -Date: Wed, 13 Sep 2017 18:12:22 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Note that this doesn't differentiate (due to lack of information in -video_priv) between different possible component orders for 32bpp. -But the main user at this point is efi_loader, and GOP expects xBGR -so any video drivers that this is incorrect for already have problems. -(Also, conveniently, this matches what simple-framebuffer bindings -expect for kernels that use the simple-framebuffer DT binding to -take over the bootloader display.) - -Signed-off-by: Rob Clark ---- - drivers/video/vidconsole-uclass.c | 94 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 94 insertions(+) - -diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c -index 0a88cc0a42..820540b1bf 100644 ---- a/drivers/video/vidconsole-uclass.c -+++ b/drivers/video/vidconsole-uclass.c -@@ -108,6 +108,41 @@ static void vidconsole_newline(struct udevice *dev) - video_sync(dev->parent); - } - -+static const struct { -+ unsigned r; -+ unsigned g; -+ unsigned b; -+} colors[] = { -+ { 0x00, 0x00, 0x00 }, /* black */ -+ { 0xff, 0x00, 0x00 }, /* red */ -+ { 0x00, 0xff, 0x00 }, /* green */ -+ { 0xff, 0xff, 0x00 }, /* yellow */ -+ { 0x00, 0x00, 0xff }, /* blue */ -+ { 0xff, 0x00, 0xff }, /* magenta */ -+ { 0x00, 0xff, 0xff }, /* cyan */ -+ { 0xff, 0xff, 0xff }, /* white */ -+}; -+ -+static void set_color(struct video_priv *priv, unsigned idx, unsigned *c) -+{ -+ switch (priv->bpix) { -+ case VIDEO_BPP16: -+ *c = ((colors[idx].r >> 3) << 0) | -+ ((colors[idx].g >> 2) << 5) | -+ ((colors[idx].b >> 3) << 11); -+ break; -+ case VIDEO_BPP32: -+ *c = 0xff000000 | -+ (colors[idx].r << 0) | -+ (colors[idx].g << 8) | -+ (colors[idx].b << 16); -+ break; -+ default: -+ /* unsupported, leave current color in place */ -+ break; -+ } -+} -+ - static char *parsenum(char *s, int *num) - { - char *end; -@@ -194,6 +229,65 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) - } - break; - } -+ case 'm': { -+ struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); -+ char *s = priv->escape_buf; -+ char *end = &priv->escape_buf[priv->escape_len]; -+ -+ /* -+ * Set graphics mode: [%d;...;%dm -+ * -+ * Currently only supports the color attributes: -+ * -+ * Foreground Colors: -+ * -+ * 30 Black -+ * 31 Red -+ * 32 Green -+ * 33 Yellow -+ * 34 Blue -+ * 35 Magenta -+ * 36 Cyan -+ * 37 White -+ * -+ * Background Colors: -+ * -+ * 40 Black -+ * 41 Red -+ * 42 Green -+ * 43 Yellow -+ * 44 Blue -+ * 45 Magenta -+ * 46 Cyan -+ * 47 White -+ */ -+ -+ s++; /* [ */ -+ while (s < end) { -+ int val; -+ -+ s = parsenum(s, &val); -+ s++; -+ -+ switch (val) { -+ case 30 ... 37: -+ /* fg color */ -+ set_color(vid_priv, val - 30, -+ (unsigned *)&vid_priv->colour_fg); -+ break; -+ case 40 ... 47: -+ /* bg color */ -+ set_color(vid_priv, val - 40, -+ (unsigned *)&vid_priv->colour_bg); -+ break; -+ default: -+ /* unknown/unsupported */ -+ break; -+ } -+ } -+ -+ break; -+ } - default: - debug("unrecognized escape sequence: %*s\n", - priv->escape_len, priv->escape_buf); diff --git a/dragonboard-fixes.patch b/dragonboard-fixes.patch index ad11779..2ffe3b3 100644 --- a/dragonboard-fixes.patch +++ b/dragonboard-fixes.patch @@ -103,361 +103,6 @@ index 7746622dda..0d3b7a35f4 100644 -- 2.13.3 -From 03569f3ef44fd1208a68030c1740d7347bcf3fa3 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Fri, 23 Jun 2017 15:36:33 -0400 -Subject: [PATCH 03/23] dm: core: also parse chosen node - -This is the node that would contain, for example, the framebuffer setup -by an earlier stage. - -Signed-off-by: Rob Clark ---- - drivers/core/root.c | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - -diff --git a/drivers/core/root.c b/drivers/core/root.c -index d691d6ff94..5e6b2da248 100644 ---- a/drivers/core/root.c -+++ b/drivers/core/root.c -@@ -266,6 +266,26 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, - for (offset = fdt_first_subnode(blob, offset); - offset > 0; - offset = fdt_next_subnode(blob, offset)) { -+ ofnode node = offset_to_ofnode(offset); -+ -+ /* "chosen" node isn't a device itself but may contain some: */ -+ if (strcmp(ofnode_get_name(node), "chosen") == 0) { -+ dm_dbg("parsing subnodes of \"chosen\"\n"); -+ -+ for (node = ofnode_first_subnode(node); -+ ofnode_valid(node); -+ node = ofnode_next_subnode(node)) { -+ dm_dbg("subnode: %s\n", ofnode_get_name(node)); -+ err = lists_bind_fdt(parent, node, NULL); -+ if (err && !ret) { -+ ret = err; -+ dm_dbg("%s: ret=%d\n", ofnode_get_name(node), ret); -+ } -+ } -+ -+ continue; -+ } -+ - if (pre_reloc_only && - !dm_fdt_pre_reloc(blob, offset)) - continue; -@@ -273,7 +293,7 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, - dm_dbg(" - ignoring disabled device\n"); - continue; - } -- err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL); -+ err = lists_bind_fdt(parent, node, NULL); - if (err && !ret) { - ret = err; - debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL), --- -2.13.3 - -From 9f99ca35c96d4b564062bb86ddc62f7421632906 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Thu, 22 Jun 2017 16:17:00 -0400 -Subject: [PATCH 04/23] video: simplefb - -Not really qcom specific, but for now qcom/lk is the one firmware that -is (afaiu) setting up the appropriate dt node for pre-configured -display. Uses the generic simple-framebuffer DT bindings so this should -be useful on other platforms. - -Signed-off-by: Rob Clark ---- - drivers/video/Kconfig | 10 +++++++ - drivers/video/Makefile | 2 +- - drivers/video/simplefb.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 82 insertions(+), 1 deletion(-) - create mode 100644 drivers/video/simplefb.c - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 61dfed8c06..8eb0359231 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -628,4 +628,14 @@ config VIDEO_DW_HDMI - rather requires a SoC-specific glue driver to call it), it - can not be enabled from the configuration menu. - -+config VIDEO_SIMPLE -+ bool "Simple display driver for preconfigured display" -+ help -+ Enables a simple generic display driver which utilizes the -+ simple-framebuffer devicetree bindings. -+ -+ This driver assumes that the display hardware has been initialized -+ before u-boot starts, and u-boot will simply render to the pre- -+ allocated frame buffer surface. -+ - endmenu -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index ac5371f2ae..52f50f647b 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -57,7 +57,7 @@ obj-$(CONFIG_FORMIKE) += formike.o - obj-$(CONFIG_LG4573) += lg4573.o - obj-$(CONFIG_AM335X_LCD) += am335x-fb.o - obj-$(CONFIG_VIDEO_DW_HDMI) += dw_hdmi.o -- -+obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o - obj-${CONFIG_VIDEO_TEGRA124} += tegra124/ - obj-${CONFIG_EXYNOS_FB} += exynos/ - obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/ -diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c -new file mode 100644 -index 0000000000..035a9761b9 ---- /dev/null -+++ b/drivers/video/simplefb.c -@@ -0,0 +1,71 @@ -+/* -+ * (C) Copyright 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int simple_video_probe(struct udevice *dev) -+{ -+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); -+ struct video_priv *uc_priv = dev_get_uclass_priv(dev); -+ const void *blob = gd->fdt_blob; -+ const int node = dev_of_offset(dev); -+ const char *format; -+ fdt_addr_t base; -+ fdt_size_t size; -+ -+ base = fdtdec_get_addr_size_auto_parent(blob, dev_of_offset(dev->parent), -+ node, "reg", 0, &size, false); -+ if (base == FDT_ADDR_T_NONE) { -+ debug("%s: Failed to decode memory region\n", __func__); -+ return -EINVAL; -+ } -+ -+ debug("%s: base=%llx, size=%llu\n", __func__, base, size); -+ -+ // TODO is there some way to reserve the framebuffer -+ // region so it isn't clobbered? -+ plat->base = base; -+ plat->size = size; -+ -+ video_set_flush_dcache(dev, true); -+ -+ debug("%s: Query resolution...\n", __func__); -+ -+ uc_priv->xsize = fdtdec_get_uint(blob, node, "width", 0); -+ uc_priv->ysize = fdtdec_get_uint(blob, node, "height", 0); -+ uc_priv->rot = 0; -+ -+ format = fdt_getprop(blob, node, "format", NULL); -+ debug("%s: %dx%d@%s\n", __func__, uc_priv->xsize, uc_priv->ysize, format); -+ -+ if (strcmp(format, "r5g6b5") == 0) { -+ uc_priv->bpix = VIDEO_BPP16; -+ } else if (strcmp(format, "a8b8g8r8") == 0) { -+ uc_priv->bpix = VIDEO_BPP32; -+ } else { -+ printf("%s: invalid format: %s\n", __func__, format); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct udevice_id simple_video_ids[] = { -+ { .compatible = "simple-framebuffer" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(simple_video) = { -+ .name = "simple_video", -+ .id = UCLASS_VIDEO, -+ .of_match = simple_video_ids, -+ .probe = simple_video_probe, -+ .flags = DM_FLAG_PRE_RELOC, -+}; --- -2.13.3 - -From 1d6f9273461ba5afa7f04cb8ea00fd87272642f8 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Tue, 4 Jul 2017 09:16:08 -0400 -Subject: [PATCH 05/23] video: add config option to skip framebuffer clear - -The use-case is that the thing that loaded u-boot already put a splash -image on screen. And we want to preserve that until grub boot menu -takes over. - -Signed-off-by: Rob Clark ---- - drivers/video/Kconfig | 8 ++++++++ - drivers/video/cfb_console.c | 3 ++- - drivers/video/video-uclass.c | 4 +++- - 3 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index 8eb0359231..7b56b20344 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -98,6 +98,14 @@ config SYS_WHITE_ON_BLACK - better in low-light situations or to reduce eye strain in some - cases. - -+config NO_FB_CLEAR -+ bool "Skip framebuffer clear" -+ help -+ If firmware (whatever loads u-boot) has already put a splash image -+ on screen, you might want to preserve it until whatever u-boots -+ loads takes over the screen. This, for example, can be used to -+ keep splash image on screen until grub graphical boot menu starts. -+ - source "drivers/video/fonts/Kconfig" - - config VIDCONSOLE_AS_LCD -diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c -index f54802052e..85fa5b0cae 100644 ---- a/drivers/video/cfb_console.c -+++ b/drivers/video/cfb_console.c -@@ -2091,7 +2091,8 @@ static int cfg_video_init(void) - } - eorx = fgx ^ bgx; - -- video_clear(); -+ if (!CONFIG_IS_ENABLED(NO_FB_CLEAR)) -+ video_clear(); - - #ifdef CONFIG_VIDEO_LOGO - /* Plot the logo and get start point of console */ -diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c -index 3036e3a1f2..dfa39b0d1b 100644 ---- a/drivers/video/video-uclass.c -+++ b/drivers/video/video-uclass.c -@@ -199,7 +199,9 @@ static int video_post_probe(struct udevice *dev) - #else - priv->colour_bg = 0xffffff; - #endif -- video_clear(dev); -+ -+ if (!CONFIG_IS_ENABLED(NO_FB_CLEAR)) -+ video_clear(dev); - - /* - * Create a text console device. For now we always do this, although --- -2.13.3 - -From d031c039a18b3a76a4ef16fb4ff8581a79f42fe3 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Thu, 3 Aug 2017 09:52:14 -0400 -Subject: [PATCH 06/23] fdtdec: allow board to provide fdt for - CONFIG_OF_SEPARATE - -Similar to CONFIG_OF_BOARD, but in this case the fdt is still built by -u-boot build. This allows the board to patch the fdt, etc. - -In the specific case of dragonboard 410c, we pass the u-boot generated -fdt to the previous stage of bootloader (by embedding it in the -u-boot.img that is loaded by lk/aboot), which patches the fdt and passes -it back to u-boot. - -Signed-off-by: Rob Clark ---- - include/fdtdec.h | 3 ++- - lib/fdtdec.c | 45 ++++++++++++++++++++++++++------------------- - 2 files changed, 28 insertions(+), 20 deletions(-) - -diff --git a/include/fdtdec.h b/include/fdtdec.h -index 4a0947c626..b9acec735a 100644 ---- a/include/fdtdec.h -+++ b/include/fdtdec.h -@@ -986,7 +986,8 @@ int fdtdec_setup(void); - - /** - * Board-specific FDT initialization. Returns the address to a device tree blob. -- * Called when CONFIG_OF_BOARD is defined. -+ * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined -+ * and the board implements it. - */ - void *board_fdt_blob_setup(void); - -diff --git a/lib/fdtdec.c b/lib/fdtdec.c -index d2dbd0f122..07c458673c 100644 ---- a/lib/fdtdec.c -+++ b/lib/fdtdec.c -@@ -1203,34 +1203,41 @@ int fdtdec_setup_memory_banksize(void) - } - #endif - --int fdtdec_setup(void) -+#ifdef CONFIG_OF_SEPARATE -+/* -+ * For CONFIG_OF_SEPARATE, the board may optionally implement this to -+ * provide and/or fixup the fdt. -+ */ -+__weak void *board_fdt_blob_setup(void) - { --#if CONFIG_IS_ENABLED(OF_CONTROL) --# ifdef CONFIG_OF_EMBED -- /* Get a pointer to the FDT */ -- gd->fdt_blob = __dtb_dt_begin; --# elif defined CONFIG_OF_SEPARATE --# ifdef CONFIG_SPL_BUILD -+ void *fdt_blob = NULL; -+#ifdef CONFIG_SPL_BUILD - /* FDT is at end of BSS unless it is in a different memory region */ - if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) -- gd->fdt_blob = (ulong *)&_image_binary_end; -+ fdt_blob = (ulong *)&_image_binary_end; - else -- gd->fdt_blob = (ulong *)&__bss_end; -+ fdt_blob = (ulong *)&__bss_end; - --# elif defined CONFIG_FIT_EMBED -- gd->fdt_blob = locate_dtb_in_fit(&_end); -+#elif defined CONFIG_FIT_EMBED -+ fdt_blob = locate_dtb_in_fit(&_end); - -- if (gd->fdt_blob == NULL || gd->fdt_blob <= ((void *)&_end)) { -+ if (fdt_blob == NULL || fdt_blob <= ((void *)&_end)) - puts("Failed to find proper dtb in embedded FIT Image\n"); -- return -1; -- } -- --# else -+#else - /* FDT is at end of image */ -- gd->fdt_blob = (ulong *)&_end; -+ fdt_blob = (ulong *)&_end; - # endif --# elif defined(CONFIG_OF_BOARD) -- /* Allow the board to override the fdt address. */ -+ return fdt_blob; -+} -+#endif -+ -+int fdtdec_setup(void) -+{ -+#if CONFIG_IS_ENABLED(OF_CONTROL) -+# ifdef CONFIG_OF_EMBED -+ /* Get a pointer to the FDT */ -+ gd->fdt_blob = __dtb_dt_begin; -+# elif defined(CONFIG_OF_SEPARATE) || defined(CONFIG_OF_BOARD) - gd->fdt_blob = board_fdt_blob_setup(); - # elif defined(CONFIG_OF_HOSTFILE) - if (sandbox_read_fdt_from_file()) { --- -2.13.3 - From 7f0491168cf31c9935dede6fb1f560ef33cfb739 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 23 Jun 2017 07:52:08 -0400 @@ -589,32 +234,6 @@ index 0d3b7a35f4..a47b95264c 100644 -- 2.13.3 -From 47f22a41df082c62411389ab5bf6e9ae26d93083 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Wed, 19 Jul 2017 10:39:12 -0400 -Subject: [PATCH 13/23] usb: kbd: add missing \n - -Signed-off-by: Rob Clark ---- - common/usb_kbd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/common/usb_kbd.c b/common/usb_kbd.c -index 703dd748f5..92d5e96d01 100644 ---- a/common/usb_kbd.c -+++ b/common/usb_kbd.c -@@ -655,7 +655,7 @@ static int usb_kbd_remove(struct udevice *dev) - - return 0; - err: -- printf("%s: warning, ret=%d", __func__, ret); -+ printf("%s: warning, ret=%d\n", __func__, ret); - return ret; - } - --- -2.13.3 - From 54997f67cc935704cab36025d98d27eaf5a4aa7c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 26 Jun 2017 10:29:40 -0400 @@ -656,34 +275,29 @@ diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconf index 2224b3850a..32efdfa46b 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig -@@ -10,6 +10,7 @@ CONFIG_BOOTARGS="console=ttyMSM0,115200n8" +@@ -9,6 +9,7 @@ CONFIG_BOOTARGS="console=ttyMSM0,115200n8" + # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_SYS_PROMPT="dragonboard410c => " # CONFIG_CMD_IMI is not set - # CONFIG_CMD_IMLS is not set +CONFIG_CMD_POWEROFF=y CONFIG_CMD_MD5SUM=y CONFIG_CMD_MEMINFO=y - CONFIG_CMD_UNZIP=y -@@ -22,11 +23,14 @@ CONFIG_CMD_TIMER=y + CONFIG_CMD_GPIO=y +@@ -20,6 +21,8 @@ CONFIG_CMD_TIMER=y CONFIG_CLK=y CONFIG_MSM_GPIO=y CONFIG_PM8916_GPIO=y +CONFIG_DM_KEYBOARD=y ++CONFIG_DM_ETH=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_DM_MMC=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_MSM=y -+CONFIG_DM_ETH=y -+# CONFIG_NETDEVICES is not set - CONFIG_DM_PMIC=y - CONFIG_PMIC_PM8916=y - CONFIG_MSM_SERIAL=y -@@ -39,9 +43,17 @@ CONFIG_USB_EHCI_MSM=y +@@ -36,10 +39,18 @@ CONFIG_USB_EHCI_HCD=y + CONFIG_USB_EHCI_MSM=y CONFIG_USB_ULPI_VIEWPORT=y CONFIG_USB_ULPI=y - CONFIG_USB_STORAGE=y +CONFIG_USB_KEYBOARD=y + CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_ASIX88179=y @@ -699,4 +313,3 @@ index 2224b3850a..32efdfa46b 100644 CONFIG_OF_LIBFDT_OVERLAY=y -- 2.13.5 - diff --git a/qemu-machine-virt-ARM.patch b/qemu-machine-virt-ARM.patch deleted file mode 100644 index 1d8dd04..0000000 --- a/qemu-machine-virt-ARM.patch +++ /dev/null @@ -1,895 +0,0 @@ -From patchwork Tue Sep 19 20:18:03 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v2, - 1/6] pci: Add helper for implementing memory-mapped config space - accesses -X-Patchwork-Submitter: Tuomas Tynkkynen -X-Patchwork-Id: 815808 -Message-Id: <20170919201808.11433-2-tuomas.tynkkynen@iki.fi> -To: u-boot@lists.denx.de -Cc: Tom Rini -Date: Tue, 19 Sep 2017 23:18:03 +0300 -From: Tuomas Tynkkynen -List-Id: U-Boot discussion - -This sort of pattern for implementing memory-mapped PCI config space -accesses appears in U-Boot twice already, and a third user is coming up. -So add helper functions to avoid code duplication, similar to how Linux -has pci_generic_config_write and pci_generic_config_read. - -Signed-off-by: Tuomas Tynkkynen -Reviewed-by: Bin Meng ---- - drivers/pci/pci-uclass.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ - include/pci.h | 51 ++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 109 insertions(+) - -diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c -index 86df141d60..5a24eb6428 100644 ---- a/drivers/pci/pci-uclass.c -+++ b/drivers/pci/pci-uclass.c -@@ -518,6 +518,64 @@ int pci_auto_config_devices(struct udevice *bus) - return sub_bus; - } - -+int pci_generic_mmap_write_config( -+ struct udevice *bus, -+ int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp), -+ pci_dev_t bdf, -+ uint offset, -+ ulong value, -+ enum pci_size_t size) -+{ -+ void *address; -+ -+ if (addr_f(bus, bdf, offset, &address) < 0) -+ return 0; -+ -+ switch (size) { -+ case PCI_SIZE_8: -+ writeb(value, address); -+ return 0; -+ case PCI_SIZE_16: -+ writew(value, address); -+ return 0; -+ case PCI_SIZE_32: -+ writel(value, address); -+ return 0; -+ default: -+ return -EINVAL; -+ } -+} -+ -+int pci_generic_mmap_read_config( -+ struct udevice *bus, -+ int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp), -+ pci_dev_t bdf, -+ uint offset, -+ ulong *valuep, -+ enum pci_size_t size) -+{ -+ void *address; -+ -+ if (addr_f(bus, bdf, offset, &address) < 0) { -+ *valuep = pci_get_ff(size); -+ return 0; -+ } -+ -+ switch (size) { -+ case PCI_SIZE_8: -+ *valuep = readb(address); -+ return 0; -+ case PCI_SIZE_16: -+ *valuep = readw(address); -+ return 0; -+ case PCI_SIZE_32: -+ *valuep = readl(address); -+ return 0; -+ default: -+ return -EINVAL; -+ } -+} -+ - int dm_pci_hose_probe_bus(struct udevice *bus) - { - int sub_bus; -diff --git a/include/pci.h b/include/pci.h -index c8ef997d0d..7adc04301c 100644 ---- a/include/pci.h -+++ b/include/pci.h -@@ -1086,6 +1086,57 @@ int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep); - int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep); - int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep); - -+/** -+ * pci_generic_mmap_write_config() - Generic helper for writing to -+ * memory-mapped PCI configuration space. -+ * @bus: Pointer to the PCI bus -+ * @addr_f: Callback for calculating the config space address -+ * @bdf: Identifies the PCI device to access -+ * @offset: The offset into the device's configuration space -+ * @value: The value to write -+ * @size: Indicates the size of access to perform -+ * -+ * Write the value @value of size @size from offset @offset within the -+ * configuration space of the device identified by the bus, device & function -+ * numbers in @bdf on the PCI bus @bus. The callback function @addr_f is -+ * responsible for calculating the CPU address of the respective configuration -+ * space offset. -+ * -+ * Return: 0 on success, else -EINVAL -+ */ -+int pci_generic_mmap_write_config( -+ struct udevice *bus, -+ int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp), -+ pci_dev_t bdf, -+ uint offset, -+ ulong value, -+ enum pci_size_t size); -+ -+/** -+ * pci_generic_mmap_read_config() - Generic helper for reading from -+ * memory-mapped PCI configuration space. -+ * @bus: Pointer to the PCI bus -+ * @addr_f: Callback for calculating the config space address -+ * @bdf: Identifies the PCI device to access -+ * @offset: The offset into the device's configuration space -+ * @valuep: A pointer at which to store the read value -+ * @size: Indicates the size of access to perform -+ * -+ * Read a value of size @size from offset @offset within the configuration -+ * space of the device identified by the bus, device & function numbers in @bdf -+ * on the PCI bus @bus. The callback function @addr_f is responsible for -+ * calculating the CPU address of the respective configuration space offset. -+ * -+ * Return: 0 on success, else -EINVAL -+ */ -+int pci_generic_mmap_read_config( -+ struct udevice *bus, -+ int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp), -+ pci_dev_t bdf, -+ uint offset, -+ ulong *valuep, -+ enum pci_size_t size); -+ - #ifdef CONFIG_DM_PCI_COMPAT - /* Compatibility with old naming */ - static inline int pci_write_config_dword(pci_dev_t pcidev, int offset, - -From patchwork Tue Sep 19 20:18:04 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v2, 2/6] pci: xilinx: Use pci_generic_mmap_{read, - write}_config() -X-Patchwork-Submitter: Tuomas Tynkkynen -X-Patchwork-Id: 815813 -Message-Id: <20170919201808.11433-3-tuomas.tynkkynen@iki.fi> -To: u-boot@lists.denx.de -Cc: Tom Rini -Date: Tue, 19 Sep 2017 23:18:04 +0300 -From: Tuomas Tynkkynen -List-Id: U-Boot discussion - -Use the new helper function to avoid boilerplate in the driver. - -Note that this changes __raw_writel et al. to writel. AFAICT this is -no problem because: - -- The Linux driver for the same hardware uses the non-__raw variants as - well (via pci_generic_config_write()). -- This driver seems to be used only on MIPS so far, where the __raw and - non-__raw accessors are the same. - -Signed-off-by: Tuomas Tynkkynen -Reviewed-by: Bin Meng ---- - drivers/pci/pcie_xilinx.c | 53 +++++++---------------------------------------- - 1 file changed, 7 insertions(+), 46 deletions(-) - -diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c -index 08e2e93445..d788552fed 100644 ---- a/drivers/pci/pcie_xilinx.c -+++ b/drivers/pci/pcie_xilinx.c -@@ -43,7 +43,7 @@ static bool pcie_xilinx_link_up(struct xilinx_pcie *pcie) - - /** - * pcie_xilinx_config_address() - Calculate the address of a config access -- * @pcie: Pointer to the PCI controller state -+ * @udev: Pointer to the PCI bus - * @bdf: Identifies the PCIe device to access - * @offset: The offset into the device's configuration space - * @paddress: Pointer to the pointer to write the calculates address to -@@ -57,9 +57,10 @@ static bool pcie_xilinx_link_up(struct xilinx_pcie *pcie) - * - * Return: 0 on success, else -ENODEV - */ --static int pcie_xilinx_config_address(struct xilinx_pcie *pcie, pci_dev_t bdf, -+static int pcie_xilinx_config_address(struct udevice *udev, pci_dev_t bdf, - uint offset, void **paddress) - { -+ struct xilinx_pcie *pcie = dev_get_priv(udev); - unsigned int bus = PCI_BUS(bdf); - unsigned int dev = PCI_DEV(bdf); - unsigned int func = PCI_FUNC(bdf); -@@ -103,29 +104,8 @@ static int pcie_xilinx_read_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong *valuep, - enum pci_size_t size) - { -- struct xilinx_pcie *pcie = dev_get_priv(bus); -- void *address; -- int err; -- -- err = pcie_xilinx_config_address(pcie, bdf, offset, &address); -- if (err < 0) { -- *valuep = pci_get_ff(size); -- return 0; -- } -- -- switch (size) { -- case PCI_SIZE_8: -- *valuep = __raw_readb(address); -- return 0; -- case PCI_SIZE_16: -- *valuep = __raw_readw(address); -- return 0; -- case PCI_SIZE_32: -- *valuep = __raw_readl(address); -- return 0; -- default: -- return -EINVAL; -- } -+ return pci_generic_mmap_read_config(bus, pcie_xilinx_config_address, -+ bdf, offset, valuep, size); - } - - /** -@@ -146,27 +126,8 @@ static int pcie_xilinx_write_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong value, - enum pci_size_t size) - { -- struct xilinx_pcie *pcie = dev_get_priv(bus); -- void *address; -- int err; -- -- err = pcie_xilinx_config_address(pcie, bdf, offset, &address); -- if (err < 0) -- return 0; -- -- switch (size) { -- case PCI_SIZE_8: -- __raw_writeb(value, address); -- return 0; -- case PCI_SIZE_16: -- __raw_writew(value, address); -- return 0; -- case PCI_SIZE_32: -- __raw_writel(value, address); -- return 0; -- default: -- return -EINVAL; -- } -+ return pci_generic_mmap_write_config(bus, pcie_xilinx_config_address, -+ bdf, offset, value, size); - } - - /** - -From patchwork Tue Sep 19 20:18:05 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v2, 3/6] pci: layerscape: Use pci_generic_mmap_{read, - write}_config -X-Patchwork-Submitter: Tuomas Tynkkynen -X-Patchwork-Id: 815814 -Message-Id: <20170919201808.11433-4-tuomas.tynkkynen@iki.fi> -To: u-boot@lists.denx.de -Cc: Tom Rini -Date: Tue, 19 Sep 2017 23:18:05 +0300 -From: Tuomas Tynkkynen -List-Id: U-Boot discussion - -Use the new helpers to avoid boilerplate in the driver. - -Signed-off-by: Tuomas Tynkkynen -Reviewed-by: Bin Meng ---- - drivers/pci/pcie_layerscape.c | 68 +++++++++++-------------------------------- - 1 file changed, 17 insertions(+), 51 deletions(-) - -diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c -index 610f85c4e8..0cb7f6d564 100644 ---- a/drivers/pci/pcie_layerscape.c -+++ b/drivers/pci/pcie_layerscape.c -@@ -241,14 +241,19 @@ static int ls_pcie_addr_valid(struct ls_pcie *pcie, pci_dev_t bdf) - return 0; - } - --void *ls_pcie_conf_address(struct ls_pcie *pcie, pci_dev_t bdf, -- int offset) -+int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf, -+ uint offset, void **paddress) - { -- struct udevice *bus = pcie->bus; -+ struct ls_pcie *pcie = dev_get_priv(bus); - u32 busdev; - -- if (PCI_BUS(bdf) == bus->seq) -- return pcie->dbi + offset; -+ if (ls_pcie_addr_valid(pcie, bdf)) -+ return -EINVAL; -+ -+ if (PCI_BUS(bdf) == bus->seq) { -+ *paddress = pcie->dbi + offset; -+ return 0; -+ } - - busdev = PCIE_ATU_BUS(PCI_BUS(bdf)) | - PCIE_ATU_DEV(PCI_DEV(bdf)) | -@@ -256,67 +261,28 @@ void *ls_pcie_conf_address(struct ls_pcie *pcie, pci_dev_t bdf, - - if (PCI_BUS(bdf) == bus->seq + 1) { - ls_pcie_cfg0_set_busdev(pcie, busdev); -- return pcie->cfg0 + offset; -+ *paddress = pcie->cfg0 + offset; - } else { - ls_pcie_cfg1_set_busdev(pcie, busdev); -- return pcie->cfg1 + offset; -+ *paddress = pcie->cfg1 + offset; - } -+ return 0; - } - - static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong *valuep, - enum pci_size_t size) - { -- struct ls_pcie *pcie = dev_get_priv(bus); -- void *address; -- -- if (ls_pcie_addr_valid(pcie, bdf)) { -- *valuep = pci_get_ff(size); -- return 0; -- } -- -- address = ls_pcie_conf_address(pcie, bdf, offset); -- -- switch (size) { -- case PCI_SIZE_8: -- *valuep = readb(address); -- return 0; -- case PCI_SIZE_16: -- *valuep = readw(address); -- return 0; -- case PCI_SIZE_32: -- *valuep = readl(address); -- return 0; -- default: -- return -EINVAL; -- } -+ return pci_generic_mmap_read_config(bus, ls_pcie_conf_address, -+ bdf, offset, valuep, size); - } - - static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf, - uint offset, ulong value, - enum pci_size_t size) - { -- struct ls_pcie *pcie = dev_get_priv(bus); -- void *address; -- -- if (ls_pcie_addr_valid(pcie, bdf)) -- return 0; -- -- address = ls_pcie_conf_address(pcie, bdf, offset); -- -- switch (size) { -- case PCI_SIZE_8: -- writeb(value, address); -- return 0; -- case PCI_SIZE_16: -- writew(value, address); -- return 0; -- case PCI_SIZE_32: -- writel(value, address); -- return 0; -- default: -- return -EINVAL; -- } -+ return pci_generic_mmap_write_config(bus, ls_pcie_conf_address, -+ bdf, offset, value, size); - } - - /* Clear multi-function bit */ - -From patchwork Tue Sep 19 20:18:06 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v2, - 4/6] PCI: Add driver for a 'pci-host-ecam-generic' host controller -X-Patchwork-Submitter: Tuomas Tynkkynen -X-Patchwork-Id: 815817 -Message-Id: <20170919201808.11433-5-tuomas.tynkkynen@iki.fi> -To: u-boot@lists.denx.de -Cc: Tom Rini -Date: Tue, 19 Sep 2017 23:18:06 +0300 -From: Tuomas Tynkkynen -List-Id: U-Boot discussion - -QEMU emulates such a device with '-machine virt,highmem=off' on ARM. -The 'highmem=off' part is required for things to work as the PCI code -in U-Boot doesn't seem to support 64-bit BARs. - -Signed-off-by: Tuomas Tynkkynen -Reviewed-by: Bin Meng ---- -v2: - - no 'default n' - - remove unnecessary non-DM struct field (inherited from the Xilinx driver) - - fix doc comment problems (inherited from the Xilinx driver) - - use the new generic memory mapped config space helpers ---- - drivers/pci/Kconfig | 8 +++ - drivers/pci/Makefile | 1 + - drivers/pci/pcie_ecam_generic.c | 143 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 152 insertions(+) - create mode 100644 drivers/pci/pcie_ecam_generic.c - -diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig -index e2a1c0a409..648dff7543 100644 ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -33,6 +33,14 @@ config PCI_PNP - help - Enable PCI memory and I/O space resource allocation and assignment. - -+config PCIE_ECAM_GENERIC -+ bool "Generic ECAM-based PCI host controller support" -+ default n -+ depends on DM_PCI -+ help -+ Say Y here if you want to enable support for generic ECAM-based -+ PCIe host controllers, such as the one emulated by QEMU. -+ - config PCIE_DW_MVEBU - bool "Enable Armada-8K PCIe driver (DesignWare core)" - default n -diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile -index ad44e83996..5eb12efbf5 100644 ---- a/drivers/pci/Makefile -+++ b/drivers/pci/Makefile -@@ -17,6 +17,7 @@ obj-$(CONFIG_PCI) += pci.o pci_auto_old.o - endif - obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o - -+obj-$(CONFIG_PCIE_ECAM_GENERIC) += pcie_ecam_generic.o - obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o - obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o - obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o -diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c -new file mode 100644 -index 0000000000..2758f90de1 ---- /dev/null -+++ b/drivers/pci/pcie_ecam_generic.c -@@ -0,0 +1,143 @@ -+/* -+ * Generic PCIE host provided by e.g. QEMU -+ * -+ * Heavily based on drivers/pci/pcie_xilinx.c -+ * -+ * Copyright (C) 2016 Imagination Technologies -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+/** -+ * struct generic_ecam_pcie - generic_ecam PCIe controller state -+ * @cfg_base: The base address of memory mapped configuration space -+ */ -+struct generic_ecam_pcie { -+ void *cfg_base; -+}; -+ -+/** -+ * pci_generic_ecam_conf_address() - Calculate the address of a config access -+ * @bus: Pointer to the PCI bus -+ * @bdf: Identifies the PCIe device to access -+ * @offset: The offset into the device's configuration space -+ * @paddress: Pointer to the pointer to write the calculates address to -+ * -+ * Calculates the address that should be accessed to perform a PCIe -+ * configuration space access for a given device identified by the PCIe -+ * controller device @pcie and the bus, device & function numbers in @bdf. If -+ * access to the device is not valid then the function will return an error -+ * code. Otherwise the address to access will be written to the pointer pointed -+ * to by @paddress. -+ */ -+static int pci_generic_ecam_conf_address(struct udevice *bus, pci_dev_t bdf, -+ uint offset, void **paddress) -+{ -+ struct generic_ecam_pcie *pcie = dev_get_priv(bus); -+ void *addr; -+ -+ addr = pcie->cfg_base; -+ addr += PCI_BUS(bdf) << 20; -+ addr += PCI_DEV(bdf) << 15; -+ addr += PCI_FUNC(bdf) << 12; -+ addr += offset; -+ *paddress = addr; -+ -+ return 0; -+} -+ -+/** -+ * pci_generic_ecam_read_config() - Read from configuration space -+ * @bus: Pointer to the PCI bus -+ * @bdf: Identifies the PCIe device to access -+ * @offset: The offset into the device's configuration space -+ * @valuep: A pointer at which to store the read value -+ * @size: Indicates the size of access to perform -+ * -+ * Read a value of size @size from offset @offset within the configuration -+ * space of the device identified by the bus, device & function numbers in @bdf -+ * on the PCI bus @bus. -+ */ -+static int pci_generic_ecam_read_config(struct udevice *bus, pci_dev_t bdf, -+ uint offset, ulong *valuep, -+ enum pci_size_t size) -+{ -+ return pci_generic_mmap_read_config(bus, pci_generic_ecam_conf_address, -+ bdf, offset, valuep, size); -+} -+ -+/** -+ * pci_generic_ecam_write_config() - Write to configuration space -+ * @bus: Pointer to the PCI bus -+ * @bdf: Identifies the PCIe device to access -+ * @offset: The offset into the device's configuration space -+ * @value: The value to write -+ * @size: Indicates the size of access to perform -+ * -+ * Write the value @value of size @size from offset @offset within the -+ * configuration space of the device identified by the bus, device & function -+ * numbers in @bdf on the PCI bus @bus. -+ */ -+static int pci_generic_ecam_write_config(struct udevice *bus, pci_dev_t bdf, -+ uint offset, ulong value, -+ enum pci_size_t size) -+{ -+ return pci_generic_mmap_write_config(bus, pci_generic_ecam_conf_address, -+ bdf, offset, value, size); -+} -+ -+/** -+ * pci_generic_ecam_ofdata_to_platdata() - Translate from DT to device state -+ * @dev: A pointer to the device being operated on -+ * -+ * Translate relevant data from the device tree pertaining to device @dev into -+ * state that the driver will later make use of. This state is stored in the -+ * device's private data structure. -+ * -+ * Return: 0 on success, else -EINVAL -+ */ -+static int pci_generic_ecam_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct generic_ecam_pcie *pcie = dev_get_priv(dev); -+ struct fdt_resource reg_res; -+ DECLARE_GLOBAL_DATA_PTR; -+ int err; -+ -+ err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg", -+ 0, ®_res); -+ if (err < 0) { -+ error("\"reg\" resource not found\n"); -+ return err; -+ } -+ -+ pcie->cfg_base = map_physmem(reg_res.start, -+ fdt_resource_size(®_res), -+ MAP_NOCACHE); -+ -+ return 0; -+} -+ -+static const struct dm_pci_ops pci_generic_ecam_ops = { -+ .read_config = pci_generic_ecam_read_config, -+ .write_config = pci_generic_ecam_write_config, -+}; -+ -+static const struct udevice_id pci_generic_ecam_ids[] = { -+ { .compatible = "pci-host-ecam-generic" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(pci_generic_ecam) = { -+ .name = "pci_generic_ecam", -+ .id = UCLASS_PCI, -+ .of_match = pci_generic_ecam_ids, -+ .ops = &pci_generic_ecam_ops, -+ .ofdata_to_platdata = pci_generic_ecam_ofdata_to_platdata, -+ .priv_auto_alloc_size = sizeof(struct generic_ecam_pcie), -+}; - -From patchwork Tue Sep 19 20:18:07 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v2, - 5/6] ARM: Add a new arch + board for QEMU's 'virt' machine -X-Patchwork-Submitter: Tuomas Tynkkynen -X-Patchwork-Id: 815816 -Message-Id: <20170919201808.11433-6-tuomas.tynkkynen@iki.fi> -To: u-boot@lists.denx.de -Cc: Tom Rini -Date: Tue, 19 Sep 2017 23:18:07 +0300 -From: Tuomas Tynkkynen -List-Id: U-Boot discussion - -This board builds an U-Boot binary that is bootable with QEMU's 'virt' -machine on ARM. The minimal QEMU command line is: - - qemu-system-arm -machine virt,highmem=off -bios u-boot.bin - -(Note that the 'highmem=off' parameter to the 'virt' machine is required for -PCI to work in U-Boot.) This command line enables the following: - - u-boot.bin loaded and executing in the emulated flash at address 0x0 - - A generated device tree blob placed at the start of RAM - - A freely configurable amount of RAM, described by the DTB - - A PL011 serial port, discoverable via the DTB - - An ARMv7 architected timer - - PSCI for rebooting the system - - A generic ECAM-based PCI host controller, discoverable via the DTB - -Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. -The following ones are supported by both U-Boot and Linux: - -- To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.: - -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 -- To add an Intel E1000 network adapter, pass e.g.: - -net nic,model=e1000 -net user -- To add an EHCI-compliant USB host controller, pass e.g.: - -device usb-ehci,id=ehci -- To add a NVMe disk, pass e.g.: - -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo - -Signed-off-by: Tuomas Tynkkynen ---- -v2: -- enable CONFIG_NVME -- alphasort correctly -- remove unnecessary gd declaration -- move board under board/emulation -- add MAINTAINERS ---- - arch/arm/Kconfig | 10 +++++++ - arch/arm/mach-qemu/Kconfig | 12 ++++++++ - board/emulation/qemu-arm/MAINTAINERS | 6 ++++ - board/emulation/qemu-arm/Makefile | 5 ++++ - board/emulation/qemu-arm/qemu-arm.c | 33 ++++++++++++++++++++ - configs/qemu_arm_defconfig | 28 +++++++++++++++++ - include/configs/qemu-arm.h | 58 ++++++++++++++++++++++++++++++++++++ - 7 files changed, 152 insertions(+) - create mode 100644 arch/arm/mach-qemu/Kconfig - create mode 100644 board/emulation/qemu-arm/MAINTAINERS - create mode 100644 board/emulation/qemu-arm/Makefile - create mode 100644 board/emulation/qemu-arm/qemu-arm.c - create mode 100644 configs/qemu_arm_defconfig - create mode 100644 include/configs/qemu-arm.h - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 53eae8953e..1de5be7a72 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -630,6 +630,14 @@ config ARCH_MX5 - select CPU_V7 - select BOARD_EARLY_INIT_F - -+config ARCH_QEMU -+ bool "QEMU Virtual Platform" -+ select CPU_V7 -+ select ARCH_SUPPORT_PSCI -+ select DM -+ select DM_SERIAL -+ select OF_CONTROL -+ - config ARCH_RMOBILE - bool "Renesas ARM SoCs" - select DM -@@ -1142,6 +1150,8 @@ source "arch/arm/mach-rmobile/Kconfig" - - source "arch/arm/mach-meson/Kconfig" - -+source "arch/arm/mach-qemu/Kconfig" -+ - source "arch/arm/mach-rockchip/Kconfig" - - source "arch/arm/mach-s5pc1xx/Kconfig" -diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig -new file mode 100644 -index 0000000000..3500b56cb0 ---- /dev/null -+++ b/arch/arm/mach-qemu/Kconfig -@@ -0,0 +1,12 @@ -+if ARCH_QEMU -+ -+config SYS_VENDOR -+ default "emulation" -+ -+config SYS_BOARD -+ default "qemu-arm" -+ -+config SYS_CONFIG_NAME -+ default "qemu-arm" -+ -+endif -diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS -new file mode 100644 -index 0000000000..a803061ff4 ---- /dev/null -+++ b/board/emulation/qemu-arm/MAINTAINERS -@@ -0,0 +1,6 @@ -+QEMU ARM 'VIRT' BOARD -+M: Tuomas Tynkkynen -+S: Maintained -+F: board/emulation/qemu-arm/ -+F: include/configs/qemu-arm.h -+F: configs/qemu_arm_defconfig -diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile -new file mode 100644 -index 0000000000..716a6e9c28 ---- /dev/null -+++ b/board/emulation/qemu-arm/Makefile -@@ -0,0 +1,5 @@ -+# -+# SPDX-License-Identifier: GPL-2.0+ -+# -+ -+obj-y += qemu-arm.o -diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c -new file mode 100644 -index 0000000000..e29ba4630f ---- /dev/null -+++ b/board/emulation/qemu-arm/qemu-arm.c -@@ -0,0 +1,33 @@ -+/* -+ * Copyright (c) 2017 Tuomas Tynkkynen -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+#include -+#include -+ -+int board_init(void) -+{ -+ return 0; -+} -+ -+int dram_init(void) -+{ -+ if (fdtdec_setup_memory_size() != 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+int dram_init_banksize(void) -+{ -+ fdtdec_setup_memory_banksize(); -+ -+ return 0; -+} -+ -+void *board_fdt_blob_setup(void) -+{ -+ /* QEMU loads a generated DTB for us at the start of RAM. */ -+ return (void *)CONFIG_SYS_SDRAM_BASE; -+} -diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig -new file mode 100644 -index 0000000000..2a8594d472 ---- /dev/null -+++ b/configs/qemu_arm_defconfig -@@ -0,0 +1,28 @@ -+CONFIG_ARM=y -+CONFIG_ARM_SMCCC=y -+CONFIG_ARCH_QEMU=y -+CONFIG_AHCI=y -+CONFIG_DISTRO_DEFAULTS=y -+# CONFIG_DISPLAY_CPUINFO is not set -+# CONFIG_DISPLAY_BOARDINFO is not set -+# CONFIG_CMD_IMLS is not set -+CONFIG_CMD_PCI=y -+CONFIG_CMD_USB=y -+CONFIG_OF_BOARD=y -+CONFIG_AHCI_PCI=y -+CONFIG_BLK=y -+# CONFIG_MMC is not set -+CONFIG_DM_ETH=y -+CONFIG_E1000=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_PCIE_ECAM_GENERIC=y -+CONFIG_SCSI=y -+CONFIG_DM_SCSI=y -+CONFIG_SYSRESET=y -+CONFIG_SYSRESET_PSCI=y -+CONFIG_USB=y -+CONFIG_DM_USB=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_PCI=y -diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h -new file mode 100644 -index 0000000000..4376a24787 ---- /dev/null -+++ b/include/configs/qemu-arm.h -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2017 Tuomas Tynkkynen -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef __CONFIG_H -+#define __CONFIG_H -+ -+#include -+ -+/* Physical memory map */ -+#define CONFIG_SYS_TEXT_BASE 0x00000000 -+ -+#define CONFIG_NR_DRAM_BANKS 1 -+#define CONFIG_SYS_SDRAM_BASE 0x40000000 -+ -+/* The DTB generated by QEMU is placed at start of RAM, stay away from there */ -+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) -+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) -+#define CONFIG_SYS_MALLOC_LEN SZ_16M -+ -+/* QEMU's PL011 serial port is detected via FDT using the device model */ -+#define CONFIG_PL01X_SERIAL -+ -+/* QEMU implements a 62.5MHz architected timer */ -+/* FIXME: can we rely on CNTFREQ instead of hardcoding this fact here? */ -+#define CONFIG_SYS_ARCH_TIMER -+#define CONFIG_SYS_HZ 1000 -+#define CONFIG_SYS_HZ_CLOCK 62500000 -+ -+/* For block devices, QEMU emulates an ICH9 AHCI controller over PCI */ -+#define CONFIG_SYS_SCSI_MAX_SCSI_ID 6 -+#define CONFIG_SCSI_AHCI -+#define CONFIG_LIBATA -+ -+/* Environment options */ -+#define CONFIG_ENV_SIZE SZ_64K -+ -+#include -+ -+#define BOOT_TARGET_DEVICES(func) \ -+ func(SCSI, scsi, 0) -+ -+#include -+ -+#define CONFIG_PREBOOT "pci enum" -+#define CONFIG_EXTRA_ENV_SETTINGS \ -+ "fdt_high=0xffffffff\0" \ -+ "initrd_high=0xffffffff\0" \ -+ "fdt_addr=0x40000000\0" \ -+ "scriptaddr=0x40200000\0" \ -+ "pxefile_addr_r=0x40300000\0" \ -+ "kernel_addr_r=0x40400000\0" \ -+ "ramdisk_addr_r=0x44000000\0" \ -+ BOOTENV -+ -+#endif /* __CONFIG_H */ - diff --git a/sources b/sources index d111dc5..e2451a9 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (u-boot-2017.09.tar.bz2) = dff6e793f135e7d6cb9d85d6ef8e4aa7ed5c1e20eece4f434e8c0a6039eb75c3f2cb7bc550121b1f5a5709e943c7cc5d6d8590e05a47a6b0d0d8f05185fe7ec6 +SHA512 (u-boot-2017.11-rc2.tar.bz2) = 881c53e2888a591046d033e06631a2011aef3afb9e809b3419653e2595ebc362b855c43efbb67813fb815673df1e7692f27ce11334353527cb0cb94bc2057672 diff --git a/sti-STiH410-B2260-support.patch b/sti-STiH410-B2260-support.patch deleted file mode 100644 index fdcf93f..0000000 --- a/sti-STiH410-B2260-support.patch +++ /dev/null @@ -1,1471 +0,0 @@ -From patchwork Tue Sep 5 09:04:18 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,01/10] mmc: sti_sdhci: Rework sti_mmc_core_config() -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810017 -Message-Id: <1504602267-31283-2-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:18 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Use struct udevice* as input parameter. Previous -parameters are retrieved through plat and priv data. - -This to prepare to use the reset framework. - -Signed-off-by: Patrice Chotard -Reviewed-by: Jaehoon Chung -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass -v5: _ none -v4: _ none -v3: _ none -v2: _ none - - drivers/mmc/sti_sdhci.c | 33 ++++++++++++++++++--------------- - 1 file changed, 18 insertions(+), 15 deletions(-) - -diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c -index f85f6b4..714afd9 100644 ---- a/drivers/mmc/sti_sdhci.c -+++ b/drivers/mmc/sti_sdhci.c -@@ -16,6 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; - struct sti_sdhci_plat { - struct mmc_config cfg; - struct mmc mmc; -+ int instance; - }; - - /* -@@ -26,8 +27,8 @@ struct sti_sdhci_plat { - - /** - * sti_mmc_core_config: configure the Arasan HC -- * @regbase: base address -- * @mmc_instance: mmc instance id -+ * @dev : udevice -+ * - * Description: this function is to configure the Arasan MMC HC. - * This should be called when the system starts in case of, on the SoC, - * it is needed to configure the host controller. -@@ -36,33 +37,35 @@ struct sti_sdhci_plat { - * W/o these settings the SDHCI could configure and use the embedded controller - * with limited features. - */ --static void sti_mmc_core_config(const u32 regbase, int mmc_instance) -+static void sti_mmc_core_config(struct udevice *dev) - { -+ struct sti_sdhci_plat *plat = dev_get_platdata(dev); -+ struct sdhci_host *host = dev_get_priv(dev); - unsigned long *sysconf; - - /* only MMC1 has a reset line */ -- if (mmc_instance) { -+ if (plat->instance) { - sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + - ST_MMC_CCONFIG_REG_5); - generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); - } - - writel(STI_FLASHSS_MMC_CORE_CONFIG_1, -- regbase + FLASHSS_MMC_CORE_CONFIG_1); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1); - -- if (mmc_instance) { -+ if (plat->instance) { - writel(STI_FLASHSS_MMC_CORE_CONFIG2, -- regbase + FLASHSS_MMC_CORE_CONFIG_2); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2); - writel(STI_FLASHSS_MMC_CORE_CONFIG3, -- regbase + FLASHSS_MMC_CORE_CONFIG_3); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3); - } else { - writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, -- regbase + FLASHSS_MMC_CORE_CONFIG_2); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2); - writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, -- regbase + FLASHSS_MMC_CORE_CONFIG_3); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3); - } - writel(STI_FLASHSS_MMC_CORE_CONFIG4, -- regbase + FLASHSS_MMC_CORE_CONFIG_4); -+ host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4); - } - - static int sti_sdhci_probe(struct udevice *dev) -@@ -70,7 +73,7 @@ static int sti_sdhci_probe(struct udevice *dev) - struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct sti_sdhci_plat *plat = dev_get_platdata(dev); - struct sdhci_host *host = dev_get_priv(dev); -- int ret, mmc_instance; -+ int ret; - - /* - * identify current mmc instance, mmc1 has a reset, not mmc0 -@@ -79,11 +82,11 @@ static int sti_sdhci_probe(struct udevice *dev) - */ - - if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) -- mmc_instance = 1; -+ plat->instance = 1; - else -- mmc_instance = 0; -+ plat->instance = 0; - -- sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); -+ sti_mmc_core_config(dev); - - host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | - SDHCI_QUIRK_32BIT_DMA_ADDR | - -From patchwork Tue Sep 5 09:04:19 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v10, - 02/10] ARM: dts: stih410-family: Add missing reset_names for mmc1 node -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810023 -Message-Id: <1504602267-31283-3-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:19 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -reset-names property is needed to use the reset -API for STi sdhci driver. - -Signed-off-by: Patrice Chotard -Reviewed-by: Jaehoon Chung -Reviewed-by: Simon Glass ---- - -v10: _ none -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass -v5: _ none -v4: _ none -v3: _ none -v2: _ none - arch/arm/dts/stih407-family.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/dts/stih407-family.dtsi b/arch/arm/dts/stih407-family.dtsi -index af66b53..452ac1c 100644 ---- a/arch/arm/dts/stih407-family.dtsi -+++ b/arch/arm/dts/stih407-family.dtsi -@@ -563,6 +563,7 @@ - clocks = <&clk_s_c0_flexgen CLK_MMC_1>, - <&clk_s_c0_flexgen CLK_RX_ICN_HVA>; - resets = <&softreset STIH407_MMC1_SOFTRESET>; -+ reset-names = "softreset"; - bus-width = <4>; - }; - - -From patchwork Tue Sep 5 09:04:20 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,03/10] mmc: sti_sdhci: Use reset framework -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810027 -Message-Id: <1504602267-31283-4-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:20 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Signed-off-by: Patrice Chotard -Reviewed-by: Jaehoon Chung -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass -v5: _ none -v4: _ none -v3: _ none -v2: _ none - drivers/mmc/sti_sdhci.c | 35 ++++++++++++++++++++--------------- - 1 file changed, 20 insertions(+), 15 deletions(-) - -diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c -index 714afd9..d8b5888 100644 ---- a/drivers/mmc/sti_sdhci.c -+++ b/drivers/mmc/sti_sdhci.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -16,15 +17,10 @@ DECLARE_GLOBAL_DATA_PTR; - struct sti_sdhci_plat { - struct mmc_config cfg; - struct mmc mmc; -+ struct reset_ctl reset; - int instance; - }; - --/* -- * used to get access to MMC1 reset, -- * will be removed when STi reset driver will be available -- */ --#define STIH410_SYSCONF5_BASE 0x092b0000 -- - /** - * sti_mmc_core_config: configure the Arasan HC - * @dev : udevice -@@ -37,17 +33,19 @@ struct sti_sdhci_plat { - * W/o these settings the SDHCI could configure and use the embedded controller - * with limited features. - */ --static void sti_mmc_core_config(struct udevice *dev) -+static int sti_mmc_core_config(struct udevice *dev) - { - struct sti_sdhci_plat *plat = dev_get_platdata(dev); - struct sdhci_host *host = dev_get_priv(dev); -- unsigned long *sysconf; -+ int ret; - - /* only MMC1 has a reset line */ - if (plat->instance) { -- sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + -- ST_MMC_CCONFIG_REG_5); -- generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); -+ ret = reset_deassert(&plat->reset); -+ if (ret < 0) { -+ error("MMC1 deassert failed: %d", ret); -+ return ret; -+ } - } - - writel(STI_FLASHSS_MMC_CORE_CONFIG_1, -@@ -66,6 +64,8 @@ static void sti_mmc_core_config(struct udevice *dev) - } - writel(STI_FLASHSS_MMC_CORE_CONFIG4, - host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4); -+ -+ return 0; - } - - static int sti_sdhci_probe(struct udevice *dev) -@@ -80,13 +80,18 @@ static int sti_sdhci_probe(struct udevice *dev) - * MMC0 is wired to the SD slot, - * MMC1 is wired on the high speed connector - */ -- -- if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) -+ ret = reset_get_by_index(dev, 0, &plat->reset); -+ if (!ret) - plat->instance = 1; - else -- plat->instance = 0; -+ if (ret == -ENOENT) -+ plat->instance = 0; -+ else -+ return ret; - -- sti_mmc_core_config(dev); -+ ret = sti_mmc_core_config(dev); -+ if (ret) -+ return ret; - - host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | - SDHCI_QUIRK_32BIT_DMA_ADDR | - -From patchwork Tue Sep 5 09:04:21 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,04/10] usb: phy: Add STi USB2 PHY -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810026 -Message-Id: <1504602267-31283-5-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:21 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -This is the generic phy driver for the picoPHY ports -used by USB2/1.1 controllers. It is found on STiH407 SoC -family from STMicroelectronics. - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ update doc/device-tree-bindings/phy/phy-stih407-usb.txt requested by - Marek Vasut -v8: _ add Reviewed-by Simon Glass -v7: _ replace fdtdec_parse_phandle_with_args() by dev_read_phandle_with_args() - _ replace uclass_get_device_by_of_offset() by uclass_get_device_by_ofnode() -v6: _ none -v5: _ add Reviewed-by: Marek Vasut -v4: _ update to use the new PHY uclass currently available on dm-next branch -v3: _ convert driver to USB PHY uclass -v2: _ replace bitfield_replace() by clrsetbits_le32() - - doc/device-tree-bindings/phy/phy-stih407-usb.txt | 24 +++ - drivers/phy/Kconfig | 8 + - drivers/phy/Makefile | 1 + - drivers/phy/sti_usb_phy.c | 181 +++++++++++++++++++++++ - 4 files changed, 214 insertions(+) - create mode 100644 doc/device-tree-bindings/phy/phy-stih407-usb.txt - create mode 100644 drivers/phy/sti_usb_phy.c - -diff --git a/doc/device-tree-bindings/phy/phy-stih407-usb.txt b/doc/device-tree-bindings/phy/phy-stih407-usb.txt -new file mode 100644 -index 0000000..371a7fe ---- /dev/null -+++ b/doc/device-tree-bindings/phy/phy-stih407-usb.txt -@@ -0,0 +1,24 @@ -+ST STiH407 USB PHY controller -+ -+This file documents the dt bindings for the usb picoPHY driver which is the PHY for both USB2 and USB3 -+host controllers (when controlling usb2/1.1 devices) available on STiH407 SoC family from STMicroelectronics. -+ -+Required properties: -+- compatible : should be "st,stih407-usb2-phy" -+- st,syscfg : phandle of sysconfig bank plus integer array containing phyparam and phyctrl register offsets -+- resets : list of phandle and reset specifier pairs. There should be two entries, one -+ for the whole phy and one for the port -+- reset-names : list of reset signal names. Should be "global" and "port" -+See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt -+See: Documentation/devicetree/bindings/reset/reset.txt -+ -+Example: -+ -+usb2_picophy0: usbpicophy { -+ compatible = "st,stih407-usb2-phy"; -+ #phy-cells = <0>; -+ st,syscfg = <&syscfg_core 0x100 0xf4>; -+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>, -+ <&picophyreset STIH407_PICOPHY0_RESET>; -+ reset-names = "global", "port"; -+}; -diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig -index 98f2a1b..3b9a09c 100644 ---- a/drivers/phy/Kconfig -+++ b/drivers/phy/Kconfig -@@ -77,4 +77,12 @@ config SPL_PIPE3_PHY - This PHY is found on omap devices supporting SATA such as dra7, am57x - and omap5 - -+config STI_USB_PHY -+ bool "STMicroelectronics USB2 picoPHY driver for STiH407 family" -+ depends on PHY && ARCH_STI -+ help -+ This is the generic phy driver for the picoPHY ports -+ used by USB2 and USB3 Host controllers available on -+ STiH407 SoC families. -+ - endmenu -diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile -index ab56c46..668040b 100644 ---- a/drivers/phy/Makefile -+++ b/drivers/phy/Makefile -@@ -9,3 +9,4 @@ obj-$(CONFIG_$(SPL_)PHY) += phy-uclass.o - obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o - obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o - obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o -+obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o -diff --git a/drivers/phy/sti_usb_phy.c b/drivers/phy/sti_usb_phy.c -new file mode 100644 -index 0000000..0e0b1c0 ---- /dev/null -+++ b/drivers/phy/sti_usb_phy.c -@@ -0,0 +1,181 @@ -+/* -+ * Copyright (c) 2017 -+ * Patrice Chotard -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+/* Default PHY_SEL and REFCLKSEL configuration */ -+#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6 -+ -+/* ports parameters overriding */ -+#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc -+ -+#define PHYPARAM_REG 1 -+#define PHYCTRL_REG 2 -+#define PHYPARAM_NB 3 -+ -+struct sti_usb_phy { -+ struct regmap *regmap; -+ struct reset_ctl global_ctl; -+ struct reset_ctl port_ctl; -+ int param; -+ int ctrl; -+}; -+ -+static int sti_usb_phy_deassert(struct sti_usb_phy *phy) -+{ -+ int ret; -+ -+ ret = reset_deassert(&phy->global_ctl); -+ if (ret < 0) { -+ error("PHY global deassert failed: %d", ret); -+ return ret; -+ } -+ -+ ret = reset_deassert(&phy->port_ctl); -+ if (ret < 0) -+ error("PHY port deassert failed: %d", ret); -+ -+ return ret; -+} -+ -+static int sti_usb_phy_init(struct phy *usb_phy) -+{ -+ struct udevice *dev = usb_phy->dev; -+ struct sti_usb_phy *phy = dev_get_priv(dev); -+ void __iomem *reg; -+ -+ /* set ctrl picophy value */ -+ reg = (void __iomem *)phy->regmap->base + phy->ctrl; -+ /* CTRL_PORT mask is 0x1f */ -+ clrsetbits_le32(reg, 0x1f, STIH407_USB_PICOPHY_CTRL_PORT_CONF); -+ -+ /* set ports parameters overriding */ -+ reg = (void __iomem *)phy->regmap->base + phy->param; -+ /* PARAM_DEF mask is 0xffffffff */ -+ clrsetbits_le32(reg, 0xffffffff, STIH407_USB_PICOPHY_PARAM_DEF); -+ -+ return sti_usb_phy_deassert(phy); -+} -+ -+static int sti_usb_phy_exit(struct phy *usb_phy) -+{ -+ struct udevice *dev = usb_phy->dev; -+ struct sti_usb_phy *phy = dev_get_priv(dev); -+ int ret; -+ -+ ret = reset_assert(&phy->port_ctl); -+ if (ret < 0) { -+ error("PHY port assert failed: %d", ret); -+ return ret; -+ } -+ -+ ret = reset_assert(&phy->global_ctl); -+ if (ret < 0) -+ error("PHY global assert failed: %d", ret); -+ -+ return ret; -+} -+ -+struct phy_ops sti_usb_phy_ops = { -+ .init = sti_usb_phy_init, -+ .exit = sti_usb_phy_exit, -+}; -+ -+int sti_usb_phy_probe(struct udevice *dev) -+{ -+ struct sti_usb_phy *priv = dev_get_priv(dev); -+ struct udevice *syscon; -+ struct ofnode_phandle_args syscfg_phandle; -+ u32 cells[PHYPARAM_NB]; -+ int ret, count; -+ -+ /* get corresponding syscon phandle */ -+ ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0, -+ &syscfg_phandle); -+ -+ if (ret < 0) { -+ error("Can't get syscfg phandle: %d\n", ret); -+ return ret; -+ } -+ -+ ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, syscfg_phandle.node, -+ &syscon); -+ if (ret) { -+ error("unable to find syscon device (%d)\n", ret); -+ return ret; -+ } -+ -+ priv->regmap = syscon_get_regmap(syscon); -+ if (!priv->regmap) { -+ error("unable to find regmap\n"); -+ return -ENODEV; -+ } -+ -+ /* get phy param offset */ -+ count = fdtdec_get_int_array_count(gd->fdt_blob, dev_of_offset(dev), -+ "st,syscfg", cells, -+ ARRAY_SIZE(cells)); -+ -+ if (count < 0) { -+ error("Bad PHY st,syscfg property %d\n", count); -+ return -EINVAL; -+ } -+ -+ if (count > PHYPARAM_NB) { -+ error("Unsupported PHY param count %d\n", count); -+ return -EINVAL; -+ } -+ -+ priv->param = cells[PHYPARAM_REG]; -+ priv->ctrl = cells[PHYCTRL_REG]; -+ -+ /* get global reset control */ -+ ret = reset_get_by_name(dev, "global", &priv->global_ctl); -+ if (ret) { -+ error("can't get global reset for %s (%d)", dev->name, ret); -+ return ret; -+ } -+ -+ /* get port reset control */ -+ ret = reset_get_by_name(dev, "port", &priv->port_ctl); -+ if (ret) { -+ error("can't get port reset for %s (%d)", dev->name, ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct udevice_id sti_usb_phy_ids[] = { -+ { .compatible = "st,stih407-usb2-phy" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(sti_usb_phy) = { -+ .name = "sti_usb_phy", -+ .id = UCLASS_PHY, -+ .of_match = sti_usb_phy_ids, -+ .probe = sti_usb_phy_probe, -+ .ops = &sti_usb_phy_ops, -+ .priv_auto_alloc_size = sizeof(struct sti_usb_phy), -+}; - -From patchwork Tue Sep 5 09:04:22 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,05/10] STiH410-B2260: enable USB Host Networking -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810018 -Message-Id: <1504602267-31283-6-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:22 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Enable USB Host Networking support by enabling Ethernet/USB -adaptors support and by enabling some BOOTP flags - -Signed-off-by: Patrice Chotard ---- - -v10: _ remove obsolete CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass - _ add missing comment in commit message -v5: _ none -v4: _ none -v3: _ none -v2: _ none - - include/configs/stih410-b2260.h | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h -index e07dd0e..372c083 100644 ---- a/include/configs/stih410-b2260.h -+++ b/include/configs/stih410-b2260.h -@@ -45,4 +45,19 @@ - - #define CONFIG_SKIP_LOWLEVEL_INIT - -+/* USB Configs */ -+#define CONFIG_USB_OHCI_NEW -+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 -+ -+#define CONFIG_USB_HOST_ETHER -+#define CONFIG_USB_ETHER_ASIX -+#define CONFIG_USB_ETHER_MCS7830 -+#define CONFIG_USB_ETHER_SMSC95XX -+ -+/* NET Configs */ -+#define CONFIG_BOOTP_SUBNETMASK -+#define CONFIG_BOOTP_GATEWAY -+#define CONFIG_BOOTP_HOSTNAME -+#define CONFIG_BOOTP_BOOTPATH -+ - #endif /* __CONFIG_H */ - -From patchwork Tue Sep 5 09:04:23 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v10, 06/10] STiH410-B2260: enable USB, fastboot, reset, - PHY related flags -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810024 -Message-Id: <1504602267-31283-7-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:23 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass -v5: _ remove CONFIG_USB_OHCI_STI and CONFIG_USB_EHCI_STI -: _ enable CONFIG_USB_EHCI_GENERIC and CONFIG_USB_OHCI_GENERIC -v4: _ enable CONFIG_PHY and CONFIG_STI_USB_PHY -v3: _ none -v2: _ none - - - configs/stih410-b2260_defconfig | 39 +++++++++++++++++++++++++++++++++++---- - 1 file changed, 35 insertions(+), 4 deletions(-) - -diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig -index 10e1a2d..8fd1ff2 100644 ---- a/configs/stih410-b2260_defconfig -+++ b/configs/stih410-b2260_defconfig -@@ -2,27 +2,58 @@ CONFIG_ARM=y - CONFIG_ARCH_STI=y - CONFIG_IDENT_STRING="STMicroelectronics STiH410-B2260" - CONFIG_DEFAULT_DEVICE_TREE="stih410-b2260" -+CONFIG_DISTRO_DEFAULTS=y - CONFIG_FIT=y - CONFIG_FIT_VERBOSE=y - CONFIG_USE_BOOTARGS=y - CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" - # CONFIG_DISPLAY_CPUINFO is not set - CONFIG_SYS_PROMPT="stih410-b2260 => " -+CONFIG_FASTBOOT=y -+CONFIG_USB_FUNCTION_FASTBOOT=y -+CONFIG_CMD_FASTBOOT=y -+CONFIG_ANDROID_BOOT_IMAGE=y -+CONFIG_FASTBOOT_BUF_ADDR=0x40000000 -+CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000 -+CONFIG_FASTBOOT_FLASH=y -+CONFIG_FASTBOOT_FLASH_MMC_DEV=0 - # CONFIG_CMD_IMLS is not set -+CONFIG_CMD_GPT=y - CONFIG_CMD_MMC=y -+CONFIG_CMD_USB=y - CONFIG_CMD_TIME=y - CONFIG_CMD_TIMER=y --CONFIG_CMD_EXT2=y --CONFIG_CMD_EXT4=y --CONFIG_CMD_FAT=y --CONFIG_CMD_FS_GENERIC=y -+CONFIG_CMD_EXT4_WRITE=y -+# CONFIG_ISO_PARTITION is not set - CONFIG_OF_CONTROL=y - CONFIG_REGMAP=y - CONFIG_SYSCON=y -+CONFIG_CLK=y -+CONFIG_MISC=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_STI=y -+CONFIG_PHY=y -+CONFIG_STI_USB_PHY=y - CONFIG_PINCTRL=y -+CONFIG_STI_RESET=y - CONFIG_STI_ASC_SERIAL=y - CONFIG_SYSRESET=y - CONFIG_TIMER=y -+CONFIG_USB=y -+CONFIG_DM_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_DWC3=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_GENERIC=y -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_GENERIC=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_DWC3_GADGET=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_GADGET_DOWNLOAD=y -+CONFIG_G_DNL_MANUFACTURER="STMicroelectronics" -+CONFIG_G_DNL_VENDOR_NUM=0x483 -+CONFIG_G_DNL_PRODUCT_NUM=0x7270 -+CONFIG_OF_LIBFDT_OVERLAY=y - CONFIG_SPL_OF_LIBFDT=y - -From patchwork Tue Sep 5 09:04:24 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,07/10] usb: dwc3: Add dwc3 glue driver support for STi -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810020 -Message-Id: <1504602267-31283-8-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:24 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -This patch adds the ST glue logic to manage the DWC3 HC -on STiH407 SoC family. It configures the internal glue -logic and syscfg registers. - -Part of this code been extracted from kernel.org driver -(drivers/usb/dwc3/dwc3-st.c) - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ move inclusion of linux/usb/otg.h from include/dwc3-sti-glue.h to - drivers/usb/host/dwc3-sti-glue.c requested by Marek Vasut -v8: _ update failpath label names in sti_dwc3_glue_probe() -v7: _ none -v6: _ add reviewed-by Simon Glass - _ put #define first -v5: _ none -v4: _ none -v3: _ rename dwc3-sti.c to dwc3-sti-glue.c - respect device tree hierarchy, this driver is now responsible -: for xhci-sti binding (done in sti_dwc3_glue_bind()) -v2: _ use setbits_le32() instead of read, modify, write sequence - add missing parenthesis - - - - arch/arm/include/asm/arch-stih410/sys_proto.h | 11 ++ - doc/device-tree-bindings/usb/dwc3-st.txt | 60 ++++++ - drivers/usb/host/Kconfig | 9 + - drivers/usb/host/Makefile | 1 + - drivers/usb/host/dwc3-sti-glue.c | 257 ++++++++++++++++++++++++++ - include/dwc3-sti-glue.h | 41 ++++ - 6 files changed, 379 insertions(+) - create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h - create mode 100644 doc/device-tree-bindings/usb/dwc3-st.txt - create mode 100644 drivers/usb/host/dwc3-sti-glue.c - create mode 100644 include/dwc3-sti-glue.h - -diff --git a/arch/arm/include/asm/arch-stih410/sys_proto.h b/arch/arm/include/asm/arch-stih410/sys_proto.h -new file mode 100644 -index 0000000..5c40d3b ---- /dev/null -+++ b/arch/arm/include/asm/arch-stih410/sys_proto.h -@@ -0,0 +1,11 @@ -+/* -+ * Copyright (c) 2017 -+ * Patrice Chotard -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef _ASM_ARCH_SYS_PROTO_H -+#define _ASM_ARCH_SYS_PROTO_H -+ -+#endif /* _ASM_ARCH_SYS_PROTO_H */ -diff --git a/doc/device-tree-bindings/usb/dwc3-st.txt b/doc/device-tree-bindings/usb/dwc3-st.txt -new file mode 100644 -index 0000000..a26a139 ---- /dev/null -+++ b/doc/device-tree-bindings/usb/dwc3-st.txt -@@ -0,0 +1,60 @@ -+ST DWC3 glue logic -+ -+This file documents the parameters for the dwc3-st driver. -+This driver controls the glue logic used to configure the dwc3 core on -+STiH407 based platforms. -+ -+Required properties: -+ - compatible : must be "st,stih407-dwc3" -+ - reg : glue logic base address and USB syscfg ctrl register offset -+ - reg-names : should be "reg-glue" and "syscfg-reg" -+ - st,syscon : should be phandle to system configuration node which -+ encompasses the glue registers -+ - resets : list of phandle and reset specifier pairs. There should be two entries, one -+ for the powerdown and softreset lines of the usb3 IP -+ - reset-names : list of reset signal names. Names should be "powerdown" and "softreset" -+ -+ - #address-cells, #size-cells : should be '1' if the device has sub-nodes -+ with 'reg' property -+ -+ - pinctl-names : A pinctrl state named "default" must be defined -+ -+ - pinctrl-0 : Pin control group -+ -+ - ranges : allows valid 1:1 translation between child's address space and -+ parent's address space -+ -+Sub-nodes: -+The dwc3 core should be added as subnode to ST DWC3 glue as shown in the -+example below. -+ -+NB: The dr_mode property is NOT optional for this driver, as the default value -+is "otg", which isn't supported by this SoC. Valid dr_mode values for dwc3-st are -+either "host" or "device". -+ -+Example: -+ -+st_dwc3: dwc3@8f94000 { -+ status = "disabled"; -+ compatible = "st,stih407-dwc3"; -+ reg = <0x08f94000 0x1000>, <0x110 0x4>; -+ reg-names = "reg-glue", "syscfg-reg"; -+ st,syscfg = <&syscfg_core>; -+ resets = <&powerdown STIH407_USB3_POWERDOWN>, -+ <&softreset STIH407_MIPHY2_SOFTRESET>; -+ reset-names = "powerdown", "softreset"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usb3>; -+ ranges; -+ -+ dwc3: dwc3@9900000 { -+ compatible = "snps,dwc3"; -+ reg = <0x09900000 0x100000>; -+ interrupts = ; -+ dr_mode = "host"; -+ phy-names = "usb2-phy", "usb3-phy"; -+ phys = <&usb2_picophy2>, <&phy_port2 PHY_TYPE_USB3>; -+ }; -+}; -diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index eb035a4..f797a25 100644 ---- a/drivers/usb/host/Kconfig -+++ b/drivers/usb/host/Kconfig -@@ -47,6 +47,15 @@ config USB_XHCI_ROCKCHIP - help - Enables support for the on-chip xHCI controller on Rockchip SoCs. - -+config USB_XHCI_STI -+ bool "Support for STMicroelectronics STiH407 family on-chip xHCI USB controller" -+ depends on ARCH_STI -+ default y -+ help -+ Enables support for the on-chip xHCI controller on STMicroelectronics -+ STiH407 family SoCs. This is a driver for the dwc3 to provide the glue logic -+ to configure the controller. -+ - config USB_XHCI_ZYNQMP - bool "Support for Xilinx ZynqMP on-chip xHCI USB controller" - depends on ARCH_ZYNQMP -diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index ab5a99f..29afb7c 100644 ---- a/drivers/usb/host/Makefile -+++ b/drivers/usb/host/Makefile -@@ -60,6 +60,7 @@ obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o - obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o - obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o - obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o -+obj-$(CONFIG_USB_XHCI_STI) += dwc3-sti-glue.o - - # designware - obj-$(CONFIG_USB_DWC2) += dwc2.o -diff --git a/drivers/usb/host/dwc3-sti-glue.c b/drivers/usb/host/dwc3-sti-glue.c -new file mode 100644 -index 0000000..02ad311 ---- /dev/null -+++ b/drivers/usb/host/dwc3-sti-glue.c -@@ -0,0 +1,257 @@ -+/* -+ * STiH407 family DWC3 specific Glue layer -+ * -+ * Copyright (c) 2017 -+ * Patrice Chotard -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+/* -+ * struct sti_dwc3_glue_platdata - dwc3 STi glue driver private structure -+ * @syscfg_base: addr for the glue syscfg -+ * @glue_base: addr for the glue registers -+ * @syscfg_offset: usb syscfg control offset -+ * @powerdown_ctl: rest controller for powerdown signal -+ * @softreset_ctl: reset controller for softreset signal -+ * @mode: drd static host/device config -+ */ -+struct sti_dwc3_glue_platdata { -+ phys_addr_t syscfg_base; -+ phys_addr_t glue_base; -+ phys_addr_t syscfg_offset; -+ struct reset_ctl powerdown_ctl; -+ struct reset_ctl softreset_ctl; -+ enum usb_dr_mode mode; -+}; -+ -+static int sti_dwc3_glue_drd_init(struct sti_dwc3_glue_platdata *plat) -+{ -+ unsigned long val; -+ -+ val = readl(plat->syscfg_base + plat->syscfg_offset); -+ -+ val &= USB3_CONTROL_MASK; -+ -+ switch (plat->mode) { -+ case USB_DR_MODE_PERIPHERAL: -+ val &= ~(USB3_DELAY_VBUSVALID -+ | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) -+ | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 -+ | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); -+ -+ val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID; -+ break; -+ -+ case USB_DR_MODE_HOST: -+ val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID -+ | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) -+ | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 -+ | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); -+ -+ val |= USB3_DELAY_VBUSVALID; -+ break; -+ -+ default: -+ error("Unsupported mode of operation %d\n", plat->mode); -+ return -EINVAL; -+ } -+ writel(val, plat->syscfg_base + plat->syscfg_offset); -+ -+ return 0; -+} -+ -+static void sti_dwc3_glue_init(struct sti_dwc3_glue_platdata *plat) -+{ -+ unsigned long reg; -+ -+ reg = readl(plat->glue_base + CLKRST_CTRL); -+ -+ reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION; -+ reg &= ~SW_PIPEW_RESET_N; -+ -+ writel(reg, plat->glue_base + CLKRST_CTRL); -+ -+ /* configure mux for vbus, powerpresent and bvalid signals */ -+ reg = readl(plat->glue_base + USB2_VBUS_MNGMNT_SEL1); -+ -+ reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) | -+ SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) | -+ SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG); -+ -+ writel(reg, plat->glue_base + USB2_VBUS_MNGMNT_SEL1); -+ -+ setbits_le32(plat->glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N); -+} -+ -+static int sti_dwc3_glue_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev); -+ struct udevice *syscon; -+ struct regmap *regmap; -+ int ret; -+ u32 reg[4]; -+ -+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), -+ "reg", reg, ARRAY_SIZE(reg)); -+ if (ret) { -+ error("unable to find st,stih407-dwc3 reg property(%d)\n", ret); -+ return ret; -+ } -+ -+ plat->glue_base = reg[0]; -+ plat->syscfg_offset = reg[2]; -+ -+ /* get corresponding syscon phandle */ -+ ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "st,syscfg", -+ &syscon); -+ if (ret) { -+ error("unable to find syscon device (%d)\n", ret); -+ return ret; -+ } -+ -+ /* get syscfg-reg base address */ -+ regmap = syscon_get_regmap(syscon); -+ if (!regmap) { -+ error("unable to find regmap\n"); -+ return -ENODEV; -+ } -+ plat->syscfg_base = regmap->base; -+ -+ /* get powerdown reset */ -+ ret = reset_get_by_name(dev, "powerdown", &plat->powerdown_ctl); -+ if (ret) { -+ error("can't get powerdown reset for %s (%d)", dev->name, ret); -+ return ret; -+ } -+ -+ /* get softreset reset */ -+ ret = reset_get_by_name(dev, "softreset", &plat->softreset_ctl); -+ if (ret) -+ error("can't get soft reset for %s (%d)", dev->name, ret); -+ -+ return ret; -+}; -+ -+static int sti_dwc3_glue_bind(struct udevice *dev) -+{ -+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev); -+ int dwc3_node; -+ -+ /* check if one subnode is present */ -+ dwc3_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev)); -+ if (dwc3_node <= 0) { -+ error("Can't find subnode for %s\n", dev->name); -+ return -ENODEV; -+ } -+ -+ /* check if the subnode compatible string is the dwc3 one*/ -+ if (fdt_node_check_compatible(gd->fdt_blob, dwc3_node, -+ "snps,dwc3") != 0) { -+ error("Can't find dwc3 subnode for %s\n", dev->name); -+ return -ENODEV; -+ } -+ -+ /* retrieve the DWC3 dual role mode */ -+ plat->mode = usb_get_dr_mode(dwc3_node); -+ if (plat->mode == USB_DR_MODE_UNKNOWN) -+ /* by default set dual role mode to HOST */ -+ plat->mode = USB_DR_MODE_HOST; -+ -+ return dm_scan_fdt_dev(dev); -+} -+ -+static int sti_dwc3_glue_probe(struct udevice *dev) -+{ -+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev); -+ int ret; -+ -+ /* deassert both powerdown and softreset */ -+ ret = reset_deassert(&plat->powerdown_ctl); -+ if (ret < 0) { -+ error("DWC3 powerdown reset deassert failed: %d", ret); -+ return ret; -+ } -+ -+ ret = reset_deassert(&plat->softreset_ctl); -+ if (ret < 0) { -+ error("DWC3 soft reset deassert failed: %d", ret); -+ goto softreset_err; -+ } -+ -+ ret = sti_dwc3_glue_drd_init(plat); -+ if (ret) -+ goto init_err; -+ -+ sti_dwc3_glue_init(plat); -+ -+ return 0; -+ -+init_err: -+ ret = reset_assert(&plat->softreset_ctl); -+ if (ret < 0) { -+ error("DWC3 soft reset deassert failed: %d", ret); -+ return ret; -+ } -+ -+softreset_err: -+ ret = reset_assert(&plat->powerdown_ctl); -+ if (ret < 0) -+ error("DWC3 powerdown reset deassert failed: %d", ret); -+ -+ return ret; -+} -+ -+static int sti_dwc3_glue_remove(struct udevice *dev) -+{ -+ struct sti_dwc3_glue_platdata *plat = dev_get_platdata(dev); -+ int ret; -+ -+ /* assert both powerdown and softreset */ -+ ret = reset_assert(&plat->powerdown_ctl); -+ if (ret < 0) { -+ error("DWC3 powerdown reset deassert failed: %d", ret); -+ return ret; -+ } -+ -+ ret = reset_assert(&plat->softreset_ctl); -+ if (ret < 0) -+ error("DWC3 soft reset deassert failed: %d", ret); -+ -+ return ret; -+} -+ -+static const struct udevice_id sti_dwc3_glue_ids[] = { -+ { .compatible = "st,stih407-dwc3" }, -+ { } -+}; -+ -+U_BOOT_DRIVER(dwc3_sti_glue) = { -+ .name = "dwc3_sti_glue", -+ .id = UCLASS_MISC, -+ .of_match = sti_dwc3_glue_ids, -+ .ofdata_to_platdata = sti_dwc3_glue_ofdata_to_platdata, -+ .probe = sti_dwc3_glue_probe, -+ .remove = sti_dwc3_glue_remove, -+ .bind = sti_dwc3_glue_bind, -+ .platdata_auto_alloc_size = sizeof(struct sti_dwc3_glue_platdata), -+ .flags = DM_FLAG_ALLOC_PRIV_DMA, -+}; -diff --git a/include/dwc3-sti-glue.h b/include/dwc3-sti-glue.h -new file mode 100644 -index 0000000..98e7696 ---- /dev/null -+++ b/include/dwc3-sti-glue.h -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (c) 2017 -+ * Patrice Chotard -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef __DWC3_STI_UBOOT_H_ -+#define __DWC3_STI_UBOOT_H_ -+ -+/* glue registers */ -+#define CLKRST_CTRL 0x00 -+#define AUX_CLK_EN BIT(0) -+#define SW_PIPEW_RESET_N BIT(4) -+#define EXT_CFG_RESET_N BIT(8) -+ -+#define XHCI_REVISION BIT(12) -+ -+#define USB2_VBUS_MNGMNT_SEL1 0x2C -+#define USB2_VBUS_UTMIOTG 0x1 -+ -+#define SEL_OVERRIDE_VBUSVALID(n) ((n) << 0) -+#define SEL_OVERRIDE_POWERPRESENT(n) ((n) << 4) -+#define SEL_OVERRIDE_BVALID(n) ((n) << 8) -+ -+/* Static DRD configuration */ -+#define USB3_CONTROL_MASK 0xf77 -+ -+#define USB3_DEVICE_NOT_HOST BIT(0) -+#define USB3_FORCE_VBUSVALID BIT(1) -+#define USB3_DELAY_VBUSVALID BIT(2) -+#define USB3_SEL_FORCE_OPMODE BIT(4) -+#define USB3_FORCE_OPMODE(n) ((n) << 5) -+#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) -+#define USB3_FORCE_DPPULLDOWN2 BIT(9) -+#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) -+#define USB3_FORCE_DMPULLDOWN2 BIT(11) -+ -+int sti_dwc3_init(enum usb_dr_mode mode); -+ -+#endif /* __DWC3_STI_UBOOT_H_ */ - -From patchwork Tue Sep 5 09:04:25 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v10, - 08/10] ARM: dts: STiH410: set DWC3 dual role mode to peripheral -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810021 -Message-Id: <1504602267-31283-9-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:25 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -On STi 96boards, configure by default the micro USB connector -(managed by DWC3 hardware block) in peripheral mode. -This will allow to use fastboot feature. - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- - -v10: _ none -v9: _ none -v8: _ add Reviewed-by: Simon Glass -v7: _ none - - arch/arm/dts/stih407-family.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/dts/stih407-family.dtsi b/arch/arm/dts/stih407-family.dtsi -index 452ac1c..6c6de58 100644 ---- a/arch/arm/dts/stih407-family.dtsi -+++ b/arch/arm/dts/stih407-family.dtsi -@@ -655,7 +655,7 @@ - compatible = "snps,dwc3"; - reg = <0x09900000 0x100000>; - interrupts = ; -- dr_mode = "host"; -+ dr_mode = "peripheral"; - phy-names = "usb2-phy", "usb3-phy"; - phys = <&usb2_picophy0>, - <&phy_port2 PHY_TYPE_USB3>; - -From patchwork Tue Sep 5 09:04:26 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v10, - 09/10] ARM: dts: STiH410: update ehci and ohci compatible -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810019 -Message-Id: <1504602267-31283-10-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:26 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Update ehci and ohci node's compatible string in order to -use ehci-generic and ohci-generic drivers. - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- - -v10: _ none -v9: _ none -v8: _ add Reviewed-by: Simon Glass -v7: _ none - - arch/arm/dts/stih410.dtsi | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/dts/stih410.dtsi b/arch/arm/dts/stih410.dtsi -index f118a9e..b59b110 100644 ---- a/arch/arm/dts/stih410.dtsi -+++ b/arch/arm/dts/stih410.dtsi -@@ -83,7 +83,7 @@ - }; - - ohci0: usb@9a03c00 { -- compatible = "st,st-ohci-300x"; -+ compatible = "generic-ohci"; - reg = <0x9a03c00 0x100>; - interrupts = ; - clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, -@@ -91,6 +91,7 @@ - resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>, - <&softreset STIH407_USB2_PORT0_SOFTRESET>; - reset-names = "power", "softreset"; -+ - phys = <&usb2_picophy1>; - phy-names = "usb"; - -@@ -98,7 +99,7 @@ - }; - - ehci0: usb@9a03e00 { -- compatible = "st,st-ehci-300x"; -+ compatible = "generic-ehci"; - reg = <0x9a03e00 0x100>; - interrupts = ; - pinctrl-names = "default"; -@@ -115,7 +116,7 @@ - }; - - ohci1: usb@9a83c00 { -- compatible = "st,st-ohci-300x"; -+ compatible = "generic-ohci"; - reg = <0x9a83c00 0x100>; - interrupts = ; - clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>, -@@ -123,6 +124,7 @@ - resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, - <&softreset STIH407_USB2_PORT1_SOFTRESET>; - reset-names = "power", "softreset"; -+ - phys = <&usb2_picophy2>; - phy-names = "usb"; - -@@ -130,7 +132,7 @@ - }; - - ehci1: usb@9a83e00 { -- compatible = "st,st-ehci-300x"; -+ compatible = "generic-ehci"; - reg = <0x9a83e00 0x100>; - interrupts = ; - pinctrl-names = "default"; -@@ -140,6 +142,7 @@ - resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>, - <&softreset STIH407_USB2_PORT1_SOFTRESET>; - reset-names = "power", "softreset"; -+ - phys = <&usb2_picophy2>; - phy-names = "usb"; - - -From patchwork Tue Sep 5 09:04:27 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v10,10/10] board: STiH410-B2260: add fastboot support -X-Patchwork-Submitter: Patrice CHOTARD -X-Patchwork-Id: 810022 -Message-Id: <1504602267-31283-11-git-send-email-patrice.chotard@st.com> -To: , , , - , -Date: Tue, 5 Sep 2017 11:04:27 +0200 -From: -List-Id: U-Boot discussion - -From: Patrice Chotard - -Add usb_gadget_handle_interrupts(), board_usb_init(), -board_usb_cleanup() and g_dnl_board_usb_cable_connected() -callbacks needed for FASTBOOT support - -Signed-off-by: Patrice Chotard -Reviewed-by: Simon Glass ---- -v10: _ none -v9: _ none -v8: _ none -v7: _ none -v6: _ add reviewed-by Simon Glass -v5: _ none -v4: _ none -v3: _ none -v2: _ none - - - - board/st/stih410-b2260/board.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - -diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c -index 92b0695..d6cbbb8 100644 ---- a/board/st/stih410-b2260/board.c -+++ b/board/st/stih410-b2260/board.c -@@ -7,6 +7,10 @@ - */ - - #include -+#include -+#include -+#include -+#include - - DECLARE_GLOBAL_DATA_PTR; - -@@ -36,3 +40,41 @@ int board_init(void) - { - return 0; - } -+ -+#ifdef CONFIG_USB_DWC3 -+static struct dwc3_device dwc3_device_data = { -+ .maximum_speed = USB_SPEED_HIGH, -+ .dr_mode = USB_DR_MODE_PERIPHERAL, -+ .index = 0, -+}; -+ -+int usb_gadget_handle_interrupts(int index) -+{ -+ dwc3_uboot_handle_interrupt(index); -+ return 0; -+} -+ -+int board_usb_init(int index, enum usb_init_type init) -+{ -+ int node; -+ const void *blob = gd->fdt_blob; -+ -+ /* find the snps,dwc3 node */ -+ node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3"); -+ -+ dwc3_device_data.base = fdtdec_get_addr(blob, node, "reg"); -+ -+ return dwc3_uboot_init(&dwc3_device_data); -+} -+ -+int board_usb_cleanup(int index, enum usb_init_type init) -+{ -+ dwc3_uboot_exit(index); -+ return 0; -+} -+ -+int g_dnl_board_usb_cable_connected(void) -+{ -+ return 1; -+} -+#endif diff --git a/sunxi-A83T-improvements.patch b/sunxi-A83T-improvements.patch deleted file mode 100644 index c658a8c..0000000 --- a/sunxi-A83T-improvements.patch +++ /dev/null @@ -1,541 +0,0 @@ -From patchwork Fri Sep 22 07:26:27 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,1/9] sunxi: rename Bananapi M3 dts file name -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817346 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-2-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:27 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The upstream (Linux) device tree file for the Bananapi M3 follows the -convention of using the well known brand name, instead of the vendor -name, for naming. The file was recently added to upstream in commit -359b5a1e1c2d ("ARM: sun8i: a83t: Add device tree for Sinovoip Bananapi -BPI-M3") - -Rename the device tree file in U-boot to match. - -Signed-off-by: Chen-Yu Tsai ---- - arch/arm/dts/Makefile | 4 ++-- - .../{sun8i-a83t-sinovoip-bpi-m3.dts => sun8i-a83t-bananapi-m3.dts} | 0 - configs/Sinovoip_BPI_M3_defconfig | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - rename arch/arm/dts/{sun8i-a83t-sinovoip-bpi-m3.dts => sun8i-a83t-bananapi-m3.dts} (100%) - -diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile -index 762429c463d1..b7550104c340 100644 ---- a/arch/arm/dts/Makefile -+++ b/arch/arm/dts/Makefile -@@ -307,8 +307,8 @@ dtb-$(CONFIG_MACH_SUN8I_A33) += \ - sun8i-r16-parrot.dtb - dtb-$(CONFIG_MACH_SUN8I_A83T) += \ - sun8i-a83t-allwinner-h8homlet-v2.dtb \ -- sun8i-a83t-cubietruck-plus.dtb \ -- sun8i-a83t-sinovoip-bpi-m3.dtb -+ sun8i-a83t-bananapi-m3.dtb \ -+ sun8i-a83t-cubietruck-plus.dtb - dtb-$(CONFIG_MACH_SUN8I_H3) += \ - sun8i-h2-plus-orangepi-zero.dtb \ - sun8i-h3-bananapi-m2-plus.dtb \ -diff --git a/arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts b/arch/arm/dts/sun8i-a83t-bananapi-m3.dts -similarity index 100% -rename from arch/arm/dts/sun8i-a83t-sinovoip-bpi-m3.dts -rename to arch/arm/dts/sun8i-a83t-bananapi-m3.dts -diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig -index 04d81693ebd8..f321d94e04eb 100644 ---- a/configs/Sinovoip_BPI_M3_defconfig -+++ b/configs/Sinovoip_BPI_M3_defconfig -@@ -13,7 +13,7 @@ CONFIG_USB0_ID_DET="PH11" - CONFIG_USB1_VBUS_PIN="PD24" - CONFIG_AXP_GPIO=y - CONFIG_SATAPWR="PD25" --CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-sinovoip-bpi-m3" -+CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-bananapi-m3" - # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set - CONFIG_CONSOLE_MUX=y - CONFIG_SPL=y - -From patchwork Fri Sep 22 07:26:28 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,2/9] sunxi: Enable eMMC on Cubietruck Plus -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817342 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-3-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:28 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -Set CONFIG_MMC_SUNXI_SLOT_EXTRA=2 to enable the eMMC controller to -access eMMC on the board. - -Signed-off-by: Chen-Yu Tsai ---- - configs/Cubietruck_plus_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configs/Cubietruck_plus_defconfig b/configs/Cubietruck_plus_defconfig -index 34444ec0bd09..3d999192cbc1 100644 ---- a/configs/Cubietruck_plus_defconfig -+++ b/configs/Cubietruck_plus_defconfig -@@ -4,6 +4,7 @@ CONFIG_MACH_SUN8I_A83T=y - CONFIG_DRAM_CLK=672 - CONFIG_DRAM_ZQ=15355 - CONFIG_DRAM_ODT_EN=y -+CONFIG_MMC_SUNXI_SLOT_EXTRA=2 - CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" - CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" - CONFIG_USB0_ID_DET="PH11" - -From patchwork Fri Sep 22 07:26:29 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,3/9] sunxi: Fix USB PHY control register offset for A83T -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817341 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-4-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:29 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -It was recently discovered that the USB PHY control register offset on -the A83T is 0x410 like on the A33, not 0x404. Fix it. - -Fixes: 0c935acb9e5d ("sunxi: usb_phy: Add support for A83T USB PHYs") -Signed-off-by: Chen-Yu Tsai ---- - arch/arm/mach-sunxi/usb_phy.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c -index 9bf0b5633d4a..3fbef0050e3f 100644 ---- a/arch/arm/mach-sunxi/usb_phy.c -+++ b/arch/arm/mach-sunxi/usb_phy.c -@@ -19,7 +19,7 @@ - #include - - #define SUNXI_USB_PMU_IRQ_ENABLE 0x800 --#ifdef CONFIG_MACH_SUN8I_A33 -+#if defined CONFIG_MACH_SUN8I_A33 || defined CONFIG_MACH_SUN8I_A83T - #define SUNXI_USB_CSR 0x410 - #else - #define SUNXI_USB_CSR 0x404 - -From patchwork Fri Sep 22 07:26:30 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,4/9] sunxi: Switch MUSB to gadget mode on the Bananapi M3 -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817348 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-5-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:30 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The Bananapi M3 has a micro-USB OTG port. It supports both host and -gadget mode. Having the OTG port operate in gadget mode is more useful, -as we can use it for fastboot or Ethernet over USB. - -The board has 2 other USB host ports that are supported. These can be -used for connecting peripherals. - -Signed-off-by: Chen-Yu Tsai ---- - configs/Sinovoip_BPI_M3_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig -index f321d94e04eb..e48983fc3310 100644 ---- a/configs/Sinovoip_BPI_M3_defconfig -+++ b/configs/Sinovoip_BPI_M3_defconfig -@@ -27,5 +27,5 @@ CONFIG_AXP_DCDC5_VOLT=1200 - CONFIG_AXP_DLDO3_VOLT=2500 - CONFIG_AXP_SW_ON=y - CONFIG_USB_EHCI_HCD=y --CONFIG_USB_MUSB_HOST=y -+CONFIG_USB_MUSB_GADGET=y - CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y - -From patchwork Fri Sep 22 07:26:31 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, 5/9] sunxi: Switch MUSB to gadget mode on the Cubietruck Plus -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817344 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-6-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:31 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The Cubietruck Plus has a micro-USB OTG port. It supports both host and -gadget mode. Having the OTG port operate in gadget mode is more useful, -as we can use it for fastboot or Ethernet over USB. - -The board has 2 other USB host ports that are supported. These can be -used for connecting peripherals. - -Signed-off-by: Chen-Yu Tsai ---- - configs/Cubietruck_plus_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configs/Cubietruck_plus_defconfig b/configs/Cubietruck_plus_defconfig -index 3d999192cbc1..3aefcc58413c 100644 ---- a/configs/Cubietruck_plus_defconfig -+++ b/configs/Cubietruck_plus_defconfig -@@ -26,5 +26,5 @@ CONFIG_AXP_DLDO3_VOLT=2500 - CONFIG_AXP_DLDO4_VOLT=3300 - CONFIG_AXP_FLDO1_VOLT=1200 - CONFIG_USB_EHCI_HCD=y --CONFIG_USB_MUSB_HOST=y -+CONFIG_USB_MUSB_GADGET=y - CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y - -From patchwork Fri Sep 22 07:26:32 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,6/9] net: sun8i_emac: Support RX/TX delay chains -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817350 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-7-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:32 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The EMAC syscon has configurable RX/TX delay chains for use with RGMII -PHYs. - -This adds support for configuring them via device tree properties. The -property names and format were defined in Linux's dwmac-sun8i binding -that was merged at one point. - -Signed-off-by: Chen-Yu Tsai -Acked-by: Maxime Ripard ---- - drivers/net/sun8i_emac.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c -index 09bbb2cdb5ca..5fa1b4c170d7 100644 ---- a/drivers/net/sun8i_emac.c -+++ b/drivers/net/sun8i_emac.c -@@ -56,6 +56,10 @@ - #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */ - - #define SC_RMII_EN BIT(13) -+#define SC_TXDC_SHIFT 10 -+#define SC_TXDC_MASK GENMASK(2, 0) -+#define SC_RXDC_SHIFT 5 -+#define SC_RXDC_MASK GENMASK(4, 0) - #define SC_EPIT BIT(2) /* 1: RGMII, 0: MII */ - #define SC_ETCS_MASK GENMASK(1, 0) - #define SC_ETCS_EXT_GMII 0x1 -@@ -125,6 +129,8 @@ struct emac_eth_dev { - u32 addr; - u32 tx_slot; - bool use_internal_phy; -+ u32 tx_delay; -+ u32 rx_delay; - - enum emac_variant variant; - void *mac_reg; -@@ -290,6 +296,12 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv) - if (priv->variant == H3_EMAC || priv->variant == A64_EMAC) - reg &= ~SC_RMII_EN; - -+ /* Configure RX/TX delay chains */ -+ reg &= ~(SC_RXDC_MASK << SC_RXDC_SHIFT); -+ reg &= ~(SC_TXDC_MASK << SC_TXDC_SHIFT); -+ reg |= (priv->rx_delay & SC_RXDC_MASK) << SC_RXDC_SHIFT; -+ reg |= (priv->tx_delay & SC_TXDC_MASK) << SC_TXDC_SHIFT; -+ - switch (priv->interface) { - case PHY_INTERFACE_MODE_MII: - /* default */ -@@ -836,6 +848,19 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) - } - #endif - -+ /* Get RX/TX delays for RGMII */ -+ priv->rx_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), -+ "allwinner,rx-delay-ps", 0); -+ if (priv->rx_delay % 100 || priv->rx_delay > 3100) -+ debug("%s: invalid rx delay value\n", __func__); -+ priv->rx_delay /= 100; -+ -+ priv->tx_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), -+ "allwinner,tx-delay-ps", 0); -+ if (priv->tx_delay % 100 || priv->tx_delay > 800) -+ debug("%s: invalid tx delay value\n", __func__); -+ priv->tx_delay /= 100; -+ - return 0; - } - - -From patchwork Fri Sep 22 07:26:33 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,7/9] net: sun8i_emac: Fix build for non-H3/H5 SoCs -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817349 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-8-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:33 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -Only the H3/H5 SoCs have an internal PHY and its related clock and -reset controls. - -Use an #ifdef to guard the internal PHY control code block so it -can be built for other SoCs, such as the A83T or A64. - -Signed-off-by: Chen-Yu Tsai -Acked-by: Maxime Ripard -Reviewed-by: Joe Hershberger ---- - drivers/net/sun8i_emac.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c -index 5fa1b4c170d7..0a98a04967da 100644 ---- a/drivers/net/sun8i_emac.c -+++ b/drivers/net/sun8i_emac.c -@@ -616,6 +616,8 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv) - { - struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - -+#ifdef CONFIG_MACH_SUNXI_H3_H5 -+ /* Only H3/H5 have clock controls for internal EPHY */ - if (priv->use_internal_phy) { - /* Set clock gating for ephy */ - setbits_le32(&ccm->bus_gate4, BIT(AHB_GATE_OFFSET_EPHY)); -@@ -623,6 +625,7 @@ static void sun8i_emac_board_setup(struct emac_eth_dev *priv) - /* Deassert EPHY */ - setbits_le32(&ccm->ahb_reset2_cfg, BIT(AHB_RESET_OFFSET_EPHY)); - } -+#endif - - /* Set clock gating for emac */ - setbits_le32(&ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_GMAC)); - -From patchwork Fri Sep 22 07:26:34 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,8/9] sunxi: Enable EMAC on the Cubietruck Plus -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817345 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-9-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:34 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The Cubietruck Plus has an RTL8211E PHY connected to the EMAC using -RGMII. The PHY is powered by DLDO4 @ 3.3V, while the I/O pins are -powered by DLDO3 @ 2.5V. - -This patch adds a U-boot specific dtsi file for the board adding -an enabled EMAC node, and enables the EMAC driver in the defconfig. -The binding used here is the old revision currently supported in -U-boot. There is no stable binding nor support in upstream Linux -at this time. - -Signed-off-by: Chen-Yu Tsai ---- - .../arm/dts/sun8i-a83t-cubietruck-plus-u-boot.dtsi | 39 ++++++++++++++++++++++ - configs/Cubietruck_plus_defconfig | 1 + - 2 files changed, 40 insertions(+) - create mode 100644 arch/arm/dts/sun8i-a83t-cubietruck-plus-u-boot.dtsi - -diff --git a/arch/arm/dts/sun8i-a83t-cubietruck-plus-u-boot.dtsi b/arch/arm/dts/sun8i-a83t-cubietruck-plus-u-boot.dtsi -new file mode 100644 -index 000000000000..b4e216c14264 ---- /dev/null -+++ b/arch/arm/dts/sun8i-a83t-cubietruck-plus-u-boot.dtsi -@@ -0,0 +1,39 @@ -+#include "sunxi-u-boot.dtsi" -+ -+/ { -+ aliases { -+ ethernet0 = &emac; -+ }; -+ -+ soc { -+ emac: ethernet@01c30000 { -+ compatible = "allwinner,sun8i-a83t-emac"; -+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; -+ reg-names = "emac", "syscon"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy = <&phy1>; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+}; -+ -+&pio { -+ rgmii_pins: rgmii_pins { -+ allwinner,pins = "PD8", "PD9", "PD10", "PD11", -+ "PD12", "PD13", "PD15", -+ "PD16", "PD17", "PD18", "PD19", -+ "PD20", "PD21", "PD22", "PD23"; -+ allwinner,function = "emac"; -+ allwinner,drive = <3>; -+ allwinner,pull = <0>; -+ }; -+}; -diff --git a/configs/Cubietruck_plus_defconfig b/configs/Cubietruck_plus_defconfig -index 3aefcc58413c..ee8b901d0d08 100644 ---- a/configs/Cubietruck_plus_defconfig -+++ b/configs/Cubietruck_plus_defconfig -@@ -22,6 +22,7 @@ CONFIG_SPL=y - # CONFIG_SPL_DOS_PARTITION is not set - # CONFIG_SPL_ISO_PARTITION is not set - # CONFIG_SPL_EFI_PARTITION is not set -+CONFIG_SUN8I_EMAC=y - CONFIG_AXP_DLDO3_VOLT=2500 - CONFIG_AXP_DLDO4_VOLT=3300 - CONFIG_AXP_FLDO1_VOLT=1200 - -From patchwork Fri Sep 22 07:26:35 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,9/9] sunxi: Enable EMAC on the Bananapi M3 -X-Patchwork-Submitter: Chen-Yu Tsai -X-Patchwork-Id: 817347 -X-Patchwork-Delegate: jagannadh.teki@gmail.com -Message-Id: <20170922072635.32105-10-wens@csie.org> -To: u-boot@lists.denx.de -Cc: Joe Hershberger , Jagan Teki , - Maxime Ripard -Date: Fri, 22 Sep 2017 15:26:35 +0800 -From: Chen-Yu Tsai -List-Id: U-Boot discussion - -The Bananapi M3 has an RTL8211E PHY connected to the EMAC using -RGMII. The PHY is powered by DCDC1 through SW @ 3.3V. - -This patch adds a U-boot specific dtsi file for the board adding -an enabled EMAC node, and enables the EMAC driver in the defconfig. -The binding used here is the old revision currently supported in -U-boot. There is no stable binding nor support in upstream Linux -at this time. - -Signed-off-by: Chen-Yu Tsai ---- - arch/arm/dts/sun8i-a83t-bananapi-m3-u-boot.dtsi | 41 +++++++++++++++++++++++++ - configs/Sinovoip_BPI_M3_defconfig | 1 + - 2 files changed, 42 insertions(+) - create mode 100644 arch/arm/dts/sun8i-a83t-bananapi-m3-u-boot.dtsi - -diff --git a/arch/arm/dts/sun8i-a83t-bananapi-m3-u-boot.dtsi b/arch/arm/dts/sun8i-a83t-bananapi-m3-u-boot.dtsi -new file mode 100644 -index 000000000000..9c7977e67b92 ---- /dev/null -+++ b/arch/arm/dts/sun8i-a83t-bananapi-m3-u-boot.dtsi -@@ -0,0 +1,41 @@ -+#include "sunxi-u-boot.dtsi" -+ -+/ { -+ aliases { -+ ethernet0 = &emac; -+ }; -+ -+ soc { -+ emac: ethernet@01c30000 { -+ compatible = "allwinner,sun8i-a83t-emac"; -+ reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; -+ reg-names = "emac", "syscon"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy = <&phy1>; -+ allwinner,rx-delay-ps = <700>; -+ allwinner,tx-delay-ps = <700>; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+}; -+ -+&pio { -+ rgmii_pins: rgmii_pins { -+ allwinner,pins = "PD8", "PD9", "PD10", "PD11", -+ "PD12", "PD13", "PD15", -+ "PD16", "PD17", "PD18", "PD19", -+ "PD20", "PD21", "PD22", "PD23"; -+ allwinner,function = "emac"; -+ allwinner,drive = <3>; -+ allwinner,pull = <0>; -+ }; -+}; -diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig -index e48983fc3310..efdf3c7396fd 100644 ---- a/configs/Sinovoip_BPI_M3_defconfig -+++ b/configs/Sinovoip_BPI_M3_defconfig -@@ -23,6 +23,7 @@ CONFIG_SPL=y - # CONFIG_SPL_DOS_PARTITION is not set - # CONFIG_SPL_ISO_PARTITION is not set - # CONFIG_SPL_EFI_PARTITION is not set -+CONFIG_SUN8I_EMAC=y - CONFIG_AXP_DCDC5_VOLT=1200 - CONFIG_AXP_DLDO3_VOLT=2500 - CONFIG_AXP_SW_ON=y diff --git a/uboot-tools.spec b/uboot-tools.spec index 764ebd9..d2bf07e 100644 --- a/uboot-tools.spec +++ b/uboot-tools.spec @@ -1,8 +1,8 @@ -#global candidate rc4 +%global candidate rc2 Name: uboot-tools -Version: 2017.09 -Release: 4%{?candidate:.%{candidate}}%{?dist} +Version: 2017.11 +Release: 0.1%{?candidate:.%{candidate}}%{?dist} Summary: U-Boot utilities License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+ URL: http://www.denx.de/wiki/U-Boot @@ -14,23 +14,17 @@ Source3: aarch64-boards Source4: aarch64-chromebooks Source5: 10-devicetree.install -# Fedoraisms patches, general fixes -Patch1: uefi-vsprintf.patch -Patch2: uefi-improve-fat.patch -Patch3: uefi-efi_loader-enough-UEFI-for-standard-distro-boot.patch -Patch4: uefi-use-Fedora-specific-path-name.patch -Patch5: dm-video-enhancements-for-Shell.efi.patch -Patch6: usb-kbd-fixes.patch -Patch7: disk-part_dos-Use-the-original-allocation-scheme-for-the-SPL-case.patch -Patch8: uefi-distro-load-FDT-from-any-partition-on-boot-device.patch -Patch9: uefi-efi_loader-Fix-disk-dp-s-for-pre-DM-legacy-devices.patch +# Fedoraisms patches +Patch1: uefi-use-Fedora-specific-path-name.patch + +# general fixes +Patch2: uefi-distro-load-FDT-from-any-partition-on-boot-device.patch +Patch3: usb-kbd-fixes.patch +# Patch4: fdt-fixes.patch # Board fixes and enablement Patch10: dragonboard-fixes.patch -Patch11: qemu-machine-virt-ARM.patch -Patch12: sti-STiH410-B2260-support.patch -Patch13: bcm283x-device-tree-sources-to-Linux-4.14-state.patch -Patch14: sunxi-A83T-improvements.patch +Patch15: rockchips-3399-atf.patch # Patch14: mvebu-enable-generic-distro-boot-config.patch # Patch15: mx6-Initial-Hummingboard-2-support.patch @@ -290,6 +284,9 @@ cp -p board/warp7/README builds/docs/README.warp7 %endif %changelog +* Tue Oct 17 2017 Peter Robinson 2017.11-0.1.rc2 +- 2017.11 RC2 + * Tue Oct 10 2017 Peter Robinson 2017.09-4 - Improve uEFI partition detection for some devices diff --git a/uefi-efi_loader-Fix-disk-dp-s-for-pre-DM-legacy-devices.patch b/uefi-efi_loader-Fix-disk-dp-s-for-pre-DM-legacy-devices.patch deleted file mode 100644 index 1dea559..0000000 --- a/uefi-efi_loader-Fix-disk-dp-s-for-pre-DM-legacy-devices.patch +++ /dev/null @@ -1,185 +0,0 @@ -From patchwork Sun Oct 8 15:33:08 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot] efi_loader: Fix disk dp's for pre-DM/legacy devices -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 823012 -Message-Id: <20171008153310.25350-1-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , =?utf-8?q?Andreas_F=C3=A4rbe?= - =?utf-8?q?r?= -Date: Sun, 8 Oct 2017 11:33:08 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -This fixes an issue with OpenBSD's bootloader, and I think should also -fix a similar issue with grub2 on legacy devices. In the legacy case -we were creating disk objects for the partitions, but not also the -parent device. - -Reported-by: Jonathan Gray -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_disk.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c -index eb9ce772d1..47b487aa30 100644 ---- a/lib/efi_loader/efi_disk.c -+++ b/lib/efi_loader/efi_disk.c -@@ -340,6 +340,8 @@ int efi_disk_register(void) - for (i = 0; i < 4; i++) { - struct blk_desc *desc; - char devname[32] = { 0 }; /* dp->str is u16[32] long */ -+ disk_partition_t info; -+ int part = 1; - - desc = blk_get_devnum_by_type(if_type, i); - if (!desc) -@@ -349,6 +351,15 @@ int efi_disk_register(void) - - snprintf(devname, sizeof(devname), "%s%d", - if_typename, i); -+ -+ /* add devices for each partition: */ -+ while (!part_get_info(desc, part, &info)) { -+ efi_disk_add_dev(devname, if_typename, desc, -+ i, 0, part); -+ part++; -+ } -+ -+ /* ... and add block device: */ - efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); - disks++; - -From patchwork Tue Oct 10 02:55:26 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot] efi_loader: search all possible disk partitions -X-Patchwork-Submitter: Jonathan Gray -X-Patchwork-Id: 823664 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20171010025526.85329-1-jsg@jsg.id.au> -To: u-boot@lists.denx.de -Date: Tue, 10 Oct 2017 13:55:26 +1100 -From: Jonathan Gray -List-Id: U-Boot discussion - -When searching for partitions don't stop if a partition is not present -for a given partition number as there may be valid partitions after. - -Search for up to MAX_SEARCH_PARTITIONS matching the other callers of -part_get_info(). - -This allows OpenBSD to boot via the efi_loader on rpi_3 again after -changes made after U-Boot 2017.09. With MBR partitioning OpenBSD will -by default use the fourth partition for the 0xA6 (OpenBSD) partition. - -Signed-off-by: Jonathan Gray ---- - lib/efi_loader/efi_disk.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c -index 47b487aa30..6b192701a8 100644 ---- a/lib/efi_loader/efi_disk.c -+++ b/lib/efi_loader/efi_disk.c -@@ -254,18 +254,19 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, - #if CONFIG_IS_ENABLED(ISO_PARTITION) - char devname[32] = { 0 }; /* dp->str is u16[32] long */ - disk_partition_t info; -- int part = 1; -+ int part; - - if (desc->part_type != PART_TYPE_ISO) - return 0; - - /* and devices for each partition: */ -- while (!part_get_info(desc, part, &info)) { -+ for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { -+ if (part_get_info(desc, part, &info)) -+ continue; - snprintf(devname, sizeof(devname), "%s:%d", pdevname, - part); - efi_disk_add_dev(devname, if_typename, desc, diskid, - info.start, part); -- part++; - disks++; - } - -@@ -299,15 +300,16 @@ int efi_disk_register(void) - struct blk_desc *desc = dev_get_uclass_platdata(dev); - const char *if_typename = dev->driver->name; - disk_partition_t info; -- int part = 1; -+ int part; - - printf("Scanning disk %s...\n", dev->name); - - /* add devices for each partition: */ -- while (!part_get_info(desc, part, &info)) { -+ for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { -+ if (part_get_info(desc, part, &info)) -+ continue; - efi_disk_add_dev(dev->name, if_typename, desc, - desc->devnum, 0, part); -- part++; - } - - /* ... and add block device: */ -@@ -341,7 +343,7 @@ int efi_disk_register(void) - struct blk_desc *desc; - char devname[32] = { 0 }; /* dp->str is u16[32] long */ - disk_partition_t info; -- int part = 1; -+ int part; - - desc = blk_get_devnum_by_type(if_type, i); - if (!desc) -@@ -353,7 +355,9 @@ int efi_disk_register(void) - if_typename, i); - - /* add devices for each partition: */ -- while (!part_get_info(desc, part, &info)) { -+ for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { -+ if (part_get_info(desc, part, &info)) -+ continue; - efi_disk_add_dev(devname, if_typename, desc, - i, 0, part); - part++; -From patchwork Tue Oct 10 10:32:29 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot] efi_loader: don't increment part twice per loop -X-Patchwork-Submitter: Jonathan Gray -X-Patchwork-Id: 823787 -Message-Id: <20171010103229.71768-1-jsg@jsg.id.au> -To: u-boot@lists.denx.de -Date: Tue, 10 Oct 2017 21:32:29 +1100 -From: Jonathan Gray -List-Id: U-Boot discussion - -Correct a mistake in the part number handling of -16a73b249d138fedeb188710533902ed7aac1ddc and only increment part once -per loop. - -Signed-off-by: Jonathan Gray ---- - lib/efi_loader/efi_disk.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c -index 6b192701a8..e61dbc8058 100644 ---- a/lib/efi_loader/efi_disk.c -+++ b/lib/efi_loader/efi_disk.c -@@ -360,7 +360,6 @@ int efi_disk_register(void) - continue; - efi_disk_add_dev(devname, if_typename, desc, - i, 0, part); -- part++; - } - - /* ... and add block device: */ diff --git a/uefi-efi_loader-enough-UEFI-for-standard-distro-boot.patch b/uefi-efi_loader-enough-UEFI-for-standard-distro-boot.patch deleted file mode 100644 index 4ab5dbc..0000000 --- a/uefi-efi_loader-enough-UEFI-for-standard-distro-boot.patch +++ /dev/null @@ -1,4423 +0,0 @@ -From patchwork Wed Sep 13 22:05:24 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,01/21] part: move efi_guid_t -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813637 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-2-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Petr Kulhavy , Heinrich Schuchardt , - Alison Chaiken , - Steve Rae , - Maxime Ripard -Date: Wed, 13 Sep 2017 18:05:24 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Prep work for next patch. - -Signed-off-by: Rob Clark -Reviewed-by: Heinrich Schuchardt ---- - include/efi.h | 4 ++++ - include/part.h | 3 ++- - include/part_efi.h | 4 ---- - 3 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/include/efi.h b/include/efi.h -index 02b78b31b1..87b0b43f20 100644 ---- a/include/efi.h -+++ b/include/efi.h -@@ -28,6 +28,10 @@ - - struct efi_device_path; - -+typedef struct { -+ u8 b[16]; -+} efi_guid_t; -+ - #define EFI_BITS_PER_LONG BITS_PER_LONG - - /* -diff --git a/include/part.h b/include/part.h -index 86117a7ce5..b2e820ef8a 100644 ---- a/include/part.h -+++ b/include/part.h -@@ -280,8 +280,9 @@ struct part_driver { - #define U_BOOT_PART_TYPE(__name) \ - ll_entry_declare(struct part_driver, __name, part_driver) - --#if CONFIG_IS_ENABLED(EFI_PARTITION) - #include -+ -+#if CONFIG_IS_ENABLED(EFI_PARTITION) - /* disk/part_efi.c */ - /** - * write_gpt_table() - Write the GUID Partition Table to disk -diff --git a/include/part_efi.h b/include/part_efi.h -index 317c044795..31e6bc6e14 100644 ---- a/include/part_efi.h -+++ b/include/part_efi.h -@@ -58,10 +58,6 @@ - /* linux/include/efi.h */ - typedef u16 efi_char16_t; - --typedef struct { -- u8 b[16]; --} efi_guid_t; -- - /* based on linux/include/genhd.h */ - struct partition { - u8 boot_ind; /* 0x80 - active */ - -From patchwork Wed Sep 13 22:05:25 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,02/21] part: extract MBR signature from partitions -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813639 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-3-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Petr Kulhavy , Heinrich Schuchardt , - Wenbin Song , - Alison Chaiken , Peter Jones , - Vincent Tinelli , - Steve Rae , - Maxime Ripard -Date: Wed, 13 Sep 2017 18:05:25 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -From: Peter Jones - -EFI client programs need the signature information from the partition -table to determine the disk a partition is on, so we need to fill that -in here. - -Signed-off-by: Peter Jones -[separated from efi_loader part, and fixed build-errors for non- - CONFIG_EFI_PARTITION case] -Signed-off-by: Rob Clark ---- - disk/part_dos.c | 12 +++++++++--- - disk/part_efi.c | 20 ++++++++++++++++++++ - include/blk.h | 18 ++++++++++++++++++ - 3 files changed, 47 insertions(+), 3 deletions(-) - -diff --git a/disk/part_dos.c b/disk/part_dos.c -index 7ede15ec26..850a538e83 100644 ---- a/disk/part_dos.c -+++ b/disk/part_dos.c -@@ -89,14 +89,20 @@ static int test_block_type(unsigned char *buffer) - - static int part_test_dos(struct blk_desc *dev_desc) - { -- ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); -+ ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz); - -- if (blk_dread(dev_desc, 0, 1, (ulong *)buffer) != 1) -+ if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) - return -1; - -- if (test_block_type(buffer) != DOS_MBR) -+ if (test_block_type((unsigned char *)mbr) != DOS_MBR) - return -1; - -+ if (dev_desc->sig_type == SIG_TYPE_NONE && -+ mbr->unique_mbr_signature != 0) { -+ dev_desc->sig_type = SIG_TYPE_MBR; -+ dev_desc->mbr_sig = mbr->unique_mbr_signature; -+ } -+ - return 0; - } - -diff --git a/disk/part_efi.c b/disk/part_efi.c -index 2973d52f6a..208bb14ee8 100644 ---- a/disk/part_efi.c -+++ b/disk/part_efi.c -@@ -923,11 +923,19 @@ static int is_pmbr_valid(legacy_mbr * mbr) - static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, - gpt_header *pgpt_head, gpt_entry **pgpt_pte) - { -+ ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz); -+ - if (!dev_desc || !pgpt_head) { - printf("%s: Invalid Argument(s)\n", __func__); - return 0; - } - -+ /* Read MBR Header from device */ -+ if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) { -+ printf("*** ERROR: Can't read MBR header ***\n"); -+ return 0; -+ } -+ - /* Read GPT Header from device */ - if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) { - printf("*** ERROR: Can't read GPT header ***\n"); -@@ -937,6 +945,18 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, - if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) - return 0; - -+ if (dev_desc->sig_type == SIG_TYPE_NONE) { -+ efi_guid_t empty = {}; -+ if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) { -+ dev_desc->sig_type = SIG_TYPE_GUID; -+ memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid, -+ sizeof(empty)); -+ } else if (mbr->unique_mbr_signature != 0) { -+ dev_desc->sig_type = SIG_TYPE_MBR; -+ dev_desc->mbr_sig = mbr->unique_mbr_signature; -+ } -+ } -+ - /* Read and allocate Partition Table Entries */ - *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); - if (*pgpt_pte == NULL) { -diff --git a/include/blk.h b/include/blk.h -index 1965812a9d..41b4d7efa8 100644 ---- a/include/blk.h -+++ b/include/blk.h -@@ -8,6 +8,8 @@ - #ifndef BLK_H - #define BLK_H - -+#include -+ - #ifdef CONFIG_SYS_64BIT_LBA - typedef uint64_t lbaint_t; - #define LBAFlength "ll" -@@ -41,6 +43,17 @@ enum if_type { - #define BLK_REV_SIZE 8 - - /* -+ * Identifies the partition table type (ie. MBR vs GPT GUID) signature -+ */ -+enum sig_type { -+ SIG_TYPE_NONE, -+ SIG_TYPE_MBR, -+ SIG_TYPE_GUID, -+ -+ SIG_TYPE_COUNT /* Number of signature types */ -+}; -+ -+/* - * With driver model (CONFIG_BLK) this is uclass platform data, accessible - * with dev_get_uclass_platdata(dev) - */ -@@ -67,6 +80,11 @@ struct blk_desc { - char vendor[BLK_VEN_SIZE + 1]; /* device vendor string */ - char product[BLK_PRD_SIZE + 1]; /* device product number */ - char revision[BLK_REV_SIZE + 1]; /* firmware revision */ -+ enum sig_type sig_type; /* Partition table signature type */ -+ union { -+ uint32_t mbr_sig; /* MBR integer signature */ -+ efi_guid_t guid_sig; /* GPT GUID Signature */ -+ }; - #if CONFIG_IS_ENABLED(BLK) - /* - * For now we have a few functions which take struct blk_desc as a - -From patchwork Wed Sep 13 22:05:26 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,03/21] efi: add some missing __packed -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813645 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-4-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:26 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -All of the device-path related structures should be packed. UEFI -defines the device-path as a byte-aligned data structure. - -Signed-off-by: Rob Clark ---- - include/efi_api.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/include/efi_api.h b/include/efi_api.h -index ec1b321e8e..175341348e 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -284,11 +284,11 @@ struct efi_device_path { - u8 type; - u8 sub_type; - u16 length; --}; -+} __packed; - - struct efi_mac_addr { - u8 addr[32]; --}; -+} __packed; - - #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 - # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b -@@ -297,7 +297,7 @@ struct efi_device_path_mac_addr { - struct efi_device_path dp; - struct efi_mac_addr mac; - u8 if_type; --}; -+} __packed; - - #define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04 - # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 -@@ -305,7 +305,7 @@ struct efi_device_path_mac_addr { - struct efi_device_path_file_path { - struct efi_device_path dp; - u16 str[32]; --}; -+} __packed; - - #define BLOCK_IO_GUID \ - EFI_GUID(0x964e5b21, 0x6459, 0x11d2, \ - -From patchwork Wed Sep 13 22:05:27 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,04/21] efi: add some more device path structures -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813638 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-5-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:27 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -From: Peter Jones - -Signed-off-by: Peter Jones -Signed-off-by: Rob Clark ---- - include/efi_api.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 54 insertions(+) - -diff --git a/include/efi_api.h b/include/efi_api.h -index 175341348e..b761cf4822 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -290,8 +290,38 @@ struct efi_mac_addr { - u8 addr[32]; - } __packed; - -+#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01 -+# define DEVICE_PATH_SUB_TYPE_VENDOR 0x04 -+ -+struct efi_device_path_vendor { -+ struct efi_device_path dp; -+ efi_guid_t guid; -+ u8 vendor_data[]; -+} __packed; -+ -+#define DEVICE_PATH_TYPE_ACPI_DEVICE 0x02 -+# define DEVICE_PATH_SUB_TYPE_ACPI_DEVICE 0x01 -+ -+#define EFI_PNP_ID(ID) (u32)(((ID) << 16) | 0x41D0) -+#define EISA_PNP_ID(ID) EFI_PNP_ID(ID) -+ -+struct efi_device_path_acpi_path { -+ struct efi_device_path dp; -+ u32 hid; -+ u32 uid; -+} __packed; -+ - #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 -+# define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05 - # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b -+# define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a -+# define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d -+ -+struct efi_device_path_usb { -+ struct efi_device_path dp; -+ u8 parent_port_number; -+ u8 usb_interface; -+} __packed; - - struct efi_device_path_mac_addr { - struct efi_device_path dp; -@@ -299,9 +329,33 @@ struct efi_device_path_mac_addr { - u8 if_type; - } __packed; - -+struct efi_device_path_sd_mmc_path { -+ struct efi_device_path dp; -+ u8 slot_number; -+} __packed; -+ - #define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04 -+# define DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH 0x01 -+# define DEVICE_PATH_SUB_TYPE_CDROM_PATH 0x02 - # define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04 - -+struct efi_device_path_hard_drive_path { -+ struct efi_device_path dp; -+ u32 partition_number; -+ u64 partition_start; -+ u64 partition_end; -+ u8 partition_signature[16]; -+ u8 partmap_type; -+ u8 signature_type; -+} __packed; -+ -+struct efi_device_path_cdrom_path { -+ struct efi_device_path dp; -+ u32 boot_entry; -+ u64 partition_start; -+ u64 partition_end; -+} __packed; -+ - struct efi_device_path_file_path { - struct efi_device_path dp; - u16 str[32]; - -From patchwork Wed Sep 13 22:05:28 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,05/21] efi_loader: add device-path utils -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813641 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-6-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:28 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Helpers to construct device-paths from devices, partitions, files, and -for parsing and manipulating device-paths. - -For non-legacy devices, this will use u-boot's device-model to construct -device-paths which include bus hierarchy to construct device-paths. For -legacy devices we still fake it, but slightly more convincingly. - -Signed-off-by: Rob Clark ---- - include/efi_api.h | 10 + - include/efi_loader.h | 26 ++ - lib/efi_loader/Makefile | 2 +- - lib/efi_loader/efi_boottime.c | 13 +- - lib/efi_loader/efi_device_path.c | 563 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 611 insertions(+), 3 deletions(-) - create mode 100644 lib/efi_loader/efi_device_path.c - -diff --git a/include/efi_api.h b/include/efi_api.h -index b761cf4822..4e27c82129 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -314,6 +314,7 @@ struct efi_device_path_acpi_path { - #define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 - # define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05 - # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b -+# define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f - # define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a - # define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d - -@@ -329,6 +330,15 @@ struct efi_device_path_mac_addr { - u8 if_type; - } __packed; - -+struct efi_device_path_usb_class { -+ struct efi_device_path dp; -+ u16 vendor_id; -+ u16 product_id; -+ u8 device_class; -+ u8 device_subclass; -+ u8 device_protocol; -+} __packed; -+ - struct efi_device_path_sd_mmc_path { - struct efi_device_path dp; - u8 slot_number; -diff --git a/include/efi_loader.h b/include/efi_loader.h -index 1179234f68..d052b03ab7 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -197,6 +197,32 @@ extern void *efi_bounce_buffer; - #define EFI_LOADER_BOUNCE_BUFFER_SIZE (64 * 1024 * 1024) - #endif - -+ -+struct efi_device_path *efi_dp_next(const struct efi_device_path *dp); -+int efi_dp_match(struct efi_device_path *a, struct efi_device_path *b); -+struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, -+ struct efi_device_path **rem); -+unsigned efi_dp_size(const struct efi_device_path *dp); -+struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp); -+struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1, -+ const struct efi_device_path *dp2); -+struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, -+ const struct efi_device_path *node); -+ -+ -+struct efi_device_path *efi_dp_from_dev(struct udevice *dev); -+struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); -+struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, -+ const char *path); -+struct efi_device_path *efi_dp_from_eth(void); -+void efi_dp_split_file_path(struct efi_device_path *full_path, -+ struct efi_device_path **device_path, -+ struct efi_device_path **file_path); -+ -+#define EFI_DP_TYPE(_dp, _type, _subtype) \ -+ (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \ -+ ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype)) -+ - /* Convert strings from normal C strings to uEFI strings */ - static inline void ascii2unicode(u16 *unicode, const char *ascii) - { -diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile -index 30bf343a36..f35e5ce8a8 100644 ---- a/lib/efi_loader/Makefile -+++ b/lib/efi_loader/Makefile -@@ -15,7 +15,7 @@ always := $(efiprogs-y) - - obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o - obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o --obj-y += efi_memory.o efi_device_path_to_text.o -+obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o - obj-$(CONFIG_LCD) += efi_gop.o - obj-$(CONFIG_DM_VIDEO) += efi_gop.o - obj-$(CONFIG_PARTITIONS) += efi_disk.o -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index 43f32385fa..b962b62a97 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -665,8 +665,17 @@ static efi_status_t EFIAPI efi_locate_device_path(efi_guid_t *protocol, - struct efi_device_path **device_path, - efi_handle_t *device) - { -- EFI_ENTRY("%p, %p, %p", protocol, device_path, device); -- return EFI_EXIT(EFI_NOT_FOUND); -+ struct efi_object *efiobj; -+ -+ EFI_ENTRY("%pUl, %p, %p", protocol, device_path, device); -+ -+ efiobj = efi_dp_find_obj(*device_path, device_path); -+ if (!efiobj) -+ return EFI_EXIT(EFI_NOT_FOUND); -+ -+ *device = efiobj->handle; -+ -+ return EFI_EXIT(EFI_SUCCESS); - } - - /* Collapses configuration table entries, removing index i */ -diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c -new file mode 100644 -index 0000000000..5d5c3b3464 ---- /dev/null -+++ b/lib/efi_loader/efi_device_path.c -@@ -0,0 +1,563 @@ -+/* -+ * EFI device path from u-boot device-model mapping -+ * -+ * (C) Copyright 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* template END node: */ -+static const struct efi_device_path END = { -+ .type = DEVICE_PATH_TYPE_END, -+ .sub_type = DEVICE_PATH_SUB_TYPE_END, -+ .length = sizeof(END), -+}; -+ -+#define U_BOOT_GUID \ -+ EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \ -+ 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b) -+ -+/* template ROOT node: */ -+static const struct efi_device_path_vendor ROOT = { -+ .dp = { -+ .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, -+ .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, -+ .length = sizeof(ROOT), -+ }, -+ .guid = U_BOOT_GUID, -+}; -+ -+static void *dp_alloc(size_t sz) -+{ -+ void *buf; -+ -+ if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) != EFI_SUCCESS) -+ return NULL; -+ -+ return buf; -+} -+ -+/* -+ * Iterate to next block in device-path, terminating (returning NULL) -+ * at /End* node. -+ */ -+struct efi_device_path *efi_dp_next(const struct efi_device_path *dp) -+{ -+ if (dp == NULL) -+ return NULL; -+ if (dp->type == DEVICE_PATH_TYPE_END) -+ return NULL; -+ dp = ((void *)dp) + dp->length; -+ if (dp->type == DEVICE_PATH_TYPE_END) -+ return NULL; -+ return (struct efi_device_path *)dp; -+} -+ -+/* -+ * Compare two device-paths, stopping when the shorter of the two hits -+ * an End* node. This is useful to, for example, compare a device-path -+ * representing a device with one representing a file on the device, or -+ * a device with a parent device. -+ */ -+int efi_dp_match(struct efi_device_path *a, struct efi_device_path *b) -+{ -+ while (1) { -+ int ret; -+ -+ ret = memcmp(&a->length, &b->length, sizeof(a->length)); -+ if (ret) -+ return ret; -+ -+ ret = memcmp(a, b, a->length); -+ if (ret) -+ return ret; -+ -+ a = efi_dp_next(a); -+ b = efi_dp_next(b); -+ -+ if (!a || !b) -+ return 0; -+ } -+} -+ -+ -+/* -+ * See UEFI spec (section 3.1.2, about short-form device-paths.. -+ * tl;dr: we can have a device-path that starts with a USB WWID -+ * or USB Class node, and a few other cases which don't encode -+ * the full device path with bus hierarchy: -+ * -+ * - MESSAGING:USB_WWID -+ * - MESSAGING:USB_CLASS -+ * - MEDIA:FILE_PATH -+ * - MEDIA:HARD_DRIVE -+ * - MESSAGING:URI -+ */ -+static struct efi_device_path *shorten_path(struct efi_device_path *dp) -+{ -+ while (dp) { -+ /* -+ * TODO: Add MESSAGING:USB_WWID and MESSAGING:URI.. -+ * in practice fallback.efi just uses MEDIA:HARD_DRIVE -+ * so not sure when we would see these other cases. -+ */ -+ if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) || -+ EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) || -+ EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH)) -+ return dp; -+ -+ dp = efi_dp_next(dp); -+ } -+ -+ return dp; -+} -+ -+static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path, -+ struct efi_device_path **rem) -+{ -+ struct efi_object *efiobj; -+ -+ list_for_each_entry(efiobj, &efi_obj_list, link) { -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { -+ struct efi_handler *handler = &efiobj->protocols[i]; -+ struct efi_device_path *obj_dp; -+ -+ if (!handler->guid) -+ break; -+ -+ if (guidcmp(handler->guid, &efi_guid_device_path)) -+ continue; -+ -+ obj_dp = handler->protocol_interface; -+ -+ do { -+ if (efi_dp_match(dp, obj_dp) == 0) { -+ if (rem) { -+ *rem = ((void *)dp) + -+ efi_dp_size(obj_dp); -+ } -+ return efiobj; -+ } -+ -+ obj_dp = shorten_path(efi_dp_next(obj_dp)); -+ } while (short_path && obj_dp); -+ } -+ } -+ -+ return NULL; -+} -+ -+ -+/* -+ * Find an efiobj from device-path, if 'rem' is not NULL, returns the -+ * remaining part of the device path after the matched object. -+ */ -+struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, -+ struct efi_device_path **rem) -+{ -+ struct efi_object *efiobj; -+ -+ efiobj = find_obj(dp, false, rem); -+ -+ if (!efiobj) -+ efiobj = find_obj(dp, true, rem); -+ -+ return efiobj; -+} -+ -+/* return size not including End node: */ -+unsigned efi_dp_size(const struct efi_device_path *dp) -+{ -+ unsigned sz = 0; -+ -+ while (dp) { -+ sz += dp->length; -+ dp = efi_dp_next(dp); -+ } -+ -+ return sz; -+} -+ -+struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) -+{ -+ struct efi_device_path *ndp; -+ unsigned sz = efi_dp_size(dp) + sizeof(END); -+ -+ if (!dp) -+ return NULL; -+ -+ ndp = dp_alloc(sz); -+ memcpy(ndp, dp, sz); -+ -+ return ndp; -+} -+ -+struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1, -+ const struct efi_device_path *dp2) -+{ -+ struct efi_device_path *ret; -+ -+ if (!dp1) { -+ ret = efi_dp_dup(dp2); -+ } else if (!dp2) { -+ ret = efi_dp_dup(dp1); -+ } else { -+ /* both dp1 and dp2 are non-null */ -+ unsigned sz1 = efi_dp_size(dp1); -+ unsigned sz2 = efi_dp_size(dp2); -+ void *p = dp_alloc(sz1 + sz2 + sizeof(END)); -+ memcpy(p, dp1, sz1); -+ memcpy(p + sz1, dp2, sz2); -+ memcpy(p + sz1 + sz2, &END, sizeof(END)); -+ ret = p; -+ } -+ -+ return ret; -+} -+ -+struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, -+ const struct efi_device_path *node) -+{ -+ struct efi_device_path *ret; -+ -+ if (!node && !dp) { -+ ret = efi_dp_dup(&END); -+ } else if (!node) { -+ ret = efi_dp_dup(dp); -+ } else if (!dp) { -+ unsigned sz = node->length; -+ void *p = dp_alloc(sz + sizeof(END)); -+ memcpy(p, node, sz); -+ memcpy(p + sz, &END, sizeof(END)); -+ ret = p; -+ } else { -+ /* both dp and node are non-null */ -+ unsigned sz = efi_dp_size(dp); -+ void *p = dp_alloc(sz + node->length + sizeof(END)); -+ memcpy(p, dp, sz); -+ memcpy(p + sz, node, node->length); -+ memcpy(p + sz + node->length, &END, sizeof(END)); -+ ret = p; -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_DM -+/* size of device-path not including END node for device and all parents -+ * up to the root device. -+ */ -+static unsigned dp_size(struct udevice *dev) -+{ -+ if (!dev || !dev->driver) -+ return sizeof(ROOT); -+ -+ switch (dev->driver->id) { -+ case UCLASS_ROOT: -+ case UCLASS_SIMPLE_BUS: -+ /* stop traversing parents at this point: */ -+ return sizeof(ROOT); -+ case UCLASS_MMC: -+ return dp_size(dev->parent) + -+ sizeof(struct efi_device_path_sd_mmc_path); -+ case UCLASS_MASS_STORAGE: -+ case UCLASS_USB_HUB: -+ return dp_size(dev->parent) + -+ sizeof(struct efi_device_path_usb_class); -+ default: -+ /* just skip over unknown classes: */ -+ return dp_size(dev->parent); -+ } -+} -+ -+static void *dp_fill(void *buf, struct udevice *dev) -+{ -+ if (!dev || !dev->driver) -+ return buf; -+ -+ switch (dev->driver->id) { -+ case UCLASS_ROOT: -+ case UCLASS_SIMPLE_BUS: { -+ /* stop traversing parents at this point: */ -+ struct efi_device_path_vendor *vdp = buf; -+ *vdp = ROOT; -+ return &vdp[1]; -+ } -+#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC) -+ case UCLASS_MMC: { -+ struct efi_device_path_sd_mmc_path *sddp = -+ dp_fill(buf, dev->parent); -+ struct mmc *mmc = mmc_get_mmc_dev(dev); -+ struct blk_desc *desc = mmc_get_blk_desc(mmc); -+ -+ sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; -+ sddp->dp.sub_type = (desc->if_type == IF_TYPE_MMC) ? -+ DEVICE_PATH_SUB_TYPE_MSG_MMC : -+ DEVICE_PATH_SUB_TYPE_MSG_SD; -+ sddp->dp.length = sizeof(*sddp); -+ sddp->slot_number = dev->seq; -+ -+ return &sddp[1]; -+ } -+#endif -+ case UCLASS_MASS_STORAGE: -+ case UCLASS_USB_HUB: { -+ struct efi_device_path_usb_class *udp = -+ dp_fill(buf, dev->parent); -+ struct usb_device *udev = dev_get_parent_priv(dev); -+ struct usb_device_descriptor *desc = &udev->descriptor; -+ -+ udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; -+ udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS; -+ udp->dp.length = sizeof(*udp); -+ udp->vendor_id = desc->idVendor; -+ udp->product_id = desc->idProduct; -+ udp->device_class = desc->bDeviceClass; -+ udp->device_subclass = desc->bDeviceSubClass; -+ udp->device_protocol = desc->bDeviceProtocol; -+ -+ return &udp[1]; -+ } -+ default: -+ debug("unhandled device class: %s (%u)\n", -+ dev->name, dev->driver->id); -+ return dp_fill(buf, dev->parent); -+ } -+} -+ -+/* Construct a device-path from a device: */ -+struct efi_device_path *efi_dp_from_dev(struct udevice *dev) -+{ -+ void *buf, *start; -+ -+ start = buf = dp_alloc(dp_size(dev) + sizeof(END)); -+ buf = dp_fill(buf, dev); -+ *((struct efi_device_path *)buf) = END; -+ -+ return start; -+} -+#endif -+ -+static unsigned dp_part_size(struct blk_desc *desc, int part) -+{ -+ unsigned dpsize; -+ -+#ifdef CONFIG_BLK -+ dpsize = dp_size(desc->bdev->parent); -+#else -+ dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb); -+#endif -+ -+ if (part == 0) /* the actual disk, not a partition */ -+ return dpsize; -+ -+ if (desc->part_type == PART_TYPE_ISO) -+ dpsize += sizeof(struct efi_device_path_cdrom_path); -+ else -+ dpsize += sizeof(struct efi_device_path_hard_drive_path); -+ -+ return dpsize; -+} -+ -+static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) -+{ -+ disk_partition_t info; -+ -+#ifdef CONFIG_BLK -+ buf = dp_fill(buf, desc->bdev->parent); -+#else -+ /* -+ * We *could* make a more accurate path, by looking at if_type -+ * and handling all the different cases like we do for non- -+ * legacy (ie CONFIG_BLK=y) case. But most important thing -+ * is just to have a unique device-path for if_type+devnum. -+ * So map things to a fictional USB device: -+ */ -+ struct efi_device_path_usb *udp; -+ -+ memcpy(buf, &ROOT, sizeof(ROOT)); -+ buf += sizeof(ROOT); -+ -+ udp = buf; -+ udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; -+ udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB; -+ udp->dp.length = sizeof(*udp); -+ udp->parent_port_number = desc->if_type; -+ udp->usb_interface = desc->devnum; -+ buf = &udp[1]; -+#endif -+ -+ if (part == 0) /* the actual disk, not a partition */ -+ return buf; -+ -+ part_get_info(desc, part, &info); -+ -+ if (desc->part_type == PART_TYPE_ISO) { -+ struct efi_device_path_cdrom_path *cddp = buf; -+ -+ cddp->boot_entry = part - 1; -+ cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; -+ cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH; -+ cddp->dp.length = sizeof(*cddp); -+ cddp->partition_start = info.start; -+ cddp->partition_end = info.size; -+ -+ buf = &cddp[1]; -+ } else { -+ struct efi_device_path_hard_drive_path *hddp = buf; -+ -+ hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; -+ hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH; -+ hddp->dp.length = sizeof(*hddp); -+ hddp->partition_number = part - 1; -+ hddp->partition_start = info.start; -+ hddp->partition_end = info.size; -+ if (desc->part_type == PART_TYPE_EFI) -+ hddp->partmap_type = 2; -+ else -+ hddp->partmap_type = 1; -+ hddp->signature_type = desc->sig_type; -+ if (hddp->signature_type != 0) -+ memcpy(hddp->partition_signature, &desc->guid_sig, -+ sizeof(hddp->partition_signature)); -+ -+ buf = &hddp[1]; -+ } -+ -+ return buf; -+} -+ -+ -+/* Construct a device-path from a partition on a blk device: */ -+struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part) -+{ -+ void *buf, *start; -+ -+ start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END)); -+ -+ buf = dp_part_fill(buf, desc, part); -+ -+ *((struct efi_device_path *)buf) = END; -+ -+ return start; -+} -+ -+/* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */ -+static void path_to_uefi(u16 *uefi, const char *path) -+{ -+ while (*path) { -+ char c = *(path++); -+ if (c == '/') -+ c = '\\'; -+ *(uefi++) = c; -+ } -+ *uefi = '\0'; -+} -+ -+/* -+ * If desc is NULL, this creates a path with only the file component, -+ * otherwise it creates a full path with both device and file components -+ */ -+struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, -+ const char *path) -+{ -+ struct efi_device_path_file_path *fp; -+ void *buf, *start; -+ unsigned dpsize = 0, fpsize; -+ -+ if (desc) -+ dpsize = dp_part_size(desc, part); -+ -+ fpsize = sizeof(struct efi_device_path) + 2 * (strlen(path) + 1); -+ dpsize += fpsize; -+ -+ start = buf = dp_alloc(dpsize + sizeof(END)); -+ -+ if (desc) -+ buf = dp_part_fill(buf, desc, part); -+ -+ /* add file-path: */ -+ fp = buf; -+ fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; -+ fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; -+ fp->dp.length = fpsize; -+ path_to_uefi(fp->str, path); -+ buf += fpsize; -+ -+ *((struct efi_device_path *)buf) = END; -+ -+ return start; -+} -+ -+#ifdef CONFIG_NET -+struct efi_device_path *efi_dp_from_eth(void) -+{ -+ struct efi_device_path_mac_addr *ndp; -+ void *buf, *start; -+ unsigned dpsize = 0; -+ -+ assert(eth_get_dev()); -+ -+#ifdef CONFIG_DM_ETH -+ dpsize += dp_size(eth_get_dev()); -+#else -+ dpsize += sizeof(ROOT); -+#endif -+ dpsize += sizeof(*ndp); -+ -+ start = buf = dp_alloc(dpsize + sizeof(END)); -+ -+#ifdef CONFIG_DM_ETH -+ buf = dp_fill(buf, eth_get_dev()); -+#else -+ memcpy(buf, &ROOT, sizeof(ROOT)); -+ buf += sizeof(ROOT); -+#endif -+ -+ ndp = buf; -+ ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; -+ ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR; -+ ndp->dp.length = sizeof(*ndp); -+ memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN); -+ buf = &ndp[1]; -+ -+ *((struct efi_device_path *)buf) = END; -+ -+ return start; -+} -+#endif -+ -+/* -+ * Helper to split a full device path (containing both device and file -+ * parts) into it's constituent parts. -+ */ -+void efi_dp_split_file_path(struct efi_device_path *full_path, -+ struct efi_device_path **device_path, -+ struct efi_device_path **file_path) -+{ -+ struct efi_device_path *p, *dp, *fp; -+ -+ dp = efi_dp_dup(full_path); -+ p = dp; -+ while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) -+ p = efi_dp_next(p); -+ fp = efi_dp_dup(p); -+ -+ p->type = DEVICE_PATH_TYPE_END; -+ p->sub_type = DEVICE_PATH_SUB_TYPE_END; -+ p->length = sizeof(*p); -+ -+ *device_path = dp; -+ *file_path = fp; -+} - -From patchwork Wed Sep 13 22:05:29 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v3, - 06/21] efi_loader: drop redundant efi_device_path_protocol -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813650 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-7-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:29 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -This is really the same thing as the efi_device_path struct. - -Signed-off-by: Rob Clark ---- - include/efi_api.h | 12 ++---------- - lib/efi_loader/efi_device_path_to_text.c | 13 ++++++++----- - 2 files changed, 10 insertions(+), 15 deletions(-) - -diff --git a/include/efi_api.h b/include/efi_api.h -index 4e27c82129..ac58fd58de 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -487,22 +487,14 @@ struct efi_console_control_protocol - EFI_GUID(0x8b843e20, 0x8132, 0x4852, \ - 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c) - --struct efi_device_path_protocol --{ -- uint8_t type; -- uint8_t sub_type; -- uint16_t length; -- uint8_t data[]; --}; -- - struct efi_device_path_to_text_protocol - { - uint16_t *(EFIAPI *convert_device_node_to_text)( -- struct efi_device_path_protocol *device_node, -+ struct efi_device_path *device_node, - bool display_only, - bool allow_shortcuts); - uint16_t *(EFIAPI *convert_device_path_to_text)( -- struct efi_device_path_protocol *device_path, -+ struct efi_device_path *device_path, - bool display_only, - bool allow_shortcuts); - }; -diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c -index 4b2f43f0c8..f9d071ac50 100644 ---- a/lib/efi_loader/efi_device_path_to_text.c -+++ b/lib/efi_loader/efi_device_path_to_text.c -@@ -16,7 +16,7 @@ const efi_guid_t efi_guid_device_path_to_text_protocol = - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; - - static uint16_t *efi_convert_device_node_to_text( -- struct efi_device_path_protocol *device_node, -+ struct efi_device_path *device_node, - bool display_only, - bool allow_shortcuts) - { -@@ -55,15 +55,18 @@ static uint16_t *efi_convert_device_node_to_text( - break; - case DEVICE_PATH_TYPE_MEDIA_DEVICE: - switch (device_node->sub_type) { -- case DEVICE_PATH_SUB_TYPE_FILE_PATH: -+ case DEVICE_PATH_SUB_TYPE_FILE_PATH: { -+ struct efi_device_path_file_path *fp = -+ (struct efi_device_path_file_path *)device_node; - buffer_size = device_node->length - 4; - r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, - buffer_size, (void **) &buffer); - if (r != EFI_SUCCESS) - return NULL; -- memcpy(buffer, device_node->data, buffer_size); -+ memcpy(buffer, fp->str, buffer_size); - break; - } -+ } - break; - } - -@@ -89,7 +92,7 @@ static uint16_t *efi_convert_device_node_to_text( - } - - static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( -- struct efi_device_path_protocol *device_node, -+ struct efi_device_path *device_node, - bool display_only, - bool allow_shortcuts) - { -@@ -105,7 +108,7 @@ static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( - } - - static uint16_t EFIAPI *efi_convert_device_path_to_text( -- struct efi_device_path_protocol *device_path, -+ struct efi_device_path *device_path, - bool display_only, - bool allow_shortcuts) - { - -From patchwork Wed Sep 13 22:05:30 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,07/21] efi_loader: flesh out device-path to text -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813658 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-8-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:30 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -It needs to handle more device-path node types, and also multiple levels -of path hierarchy. To simplify this, initially construct utf8 string to -a temporary buffer, and then allocate the real utf16 buffer that is -returned. This should be mostly for debugging or at least not critical- -path so an extra copy won't hurt, and is saner than the alternative. - -Signed-off-by: Rob Clark ---- - include/efi_api.h | 1 + - include/efi_loader.h | 2 + - lib/efi_loader/efi_device_path_to_text.c | 241 +++++++++++++++++++++++-------- - 3 files changed, 181 insertions(+), 63 deletions(-) - -diff --git a/include/efi_api.h b/include/efi_api.h -index ac58fd58de..0c36122107 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -304,6 +304,7 @@ struct efi_device_path_vendor { - - #define EFI_PNP_ID(ID) (u32)(((ID) << 16) | 0x41D0) - #define EISA_PNP_ID(ID) EFI_PNP_ID(ID) -+#define EISA_PNP_NUM(ID) ((ID) >> 16) - - struct efi_device_path_acpi_path { - struct efi_device_path dp; -diff --git a/include/efi_loader.h b/include/efi_loader.h -index d052b03ab7..f39c2ee6da 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -59,6 +59,8 @@ extern struct efi_simple_input_interface efi_con_in; - extern const struct efi_console_control_protocol efi_console_control; - extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; - -+uint16_t *efi_dp_str(struct efi_device_path *dp); -+ - extern const efi_guid_t efi_guid_console_control; - extern const efi_guid_t efi_guid_device_path; - extern const efi_guid_t efi_guid_loaded_image; -diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c -index f9d071ac50..1a5ef3919b 100644 ---- a/lib/efi_loader/efi_device_path_to_text.c -+++ b/lib/efi_loader/efi_device_path_to_text.c -@@ -15,82 +15,197 @@ - const efi_guid_t efi_guid_device_path_to_text_protocol = - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; - --static uint16_t *efi_convert_device_node_to_text( -- struct efi_device_path *device_node, -- bool display_only, -- bool allow_shortcuts) -+static char *dp_unknown(char *s, struct efi_device_path *dp) - { -- unsigned long buffer_size; -- efi_status_t r; -- uint16_t *buffer = NULL; -- int i; -+ s += sprintf(s, "/UNKNOWN(%04x,%04x)", dp->type, dp->sub_type); -+ return s; -+} - -- switch (device_node->type) { -- case DEVICE_PATH_TYPE_END: -- return NULL; -- case DEVICE_PATH_TYPE_MESSAGING_DEVICE: -- switch (device_node->sub_type) { -- case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { -- struct efi_device_path_mac_addr *dp = -- (struct efi_device_path_mac_addr *)device_node; -- -- if (dp->if_type != 0 && dp->if_type != 1) -- break; -- r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, -- 2 * MAC_OUTPUT_LEN, -- (void **)&buffer); -- if (r != EFI_SUCCESS) -- return NULL; -- sprintf((char *)buffer, -- "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", -- dp->mac.addr[0], dp->mac.addr[1], -- dp->mac.addr[2], dp->mac.addr[3], -- dp->mac.addr[4], dp->mac.addr[5], -- dp->if_type); -- for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i) -- buffer[i] = ((uint8_t *)buffer)[i]; -+static char *dp_hardware(char *s, struct efi_device_path *dp) -+{ -+ switch (dp->sub_type) { -+ case DEVICE_PATH_SUB_TYPE_VENDOR: { -+ struct efi_device_path_vendor *vdp = -+ (struct efi_device_path_vendor *)dp; -+ s += sprintf(s, "/VenHw(%pUl)", &vdp->guid); -+ break; -+ } -+ default: -+ s = dp_unknown(s, dp); -+ break; -+ } -+ return s; -+} -+ -+static char *dp_acpi(char *s, struct efi_device_path *dp) -+{ -+ switch (dp->sub_type) { -+ case DEVICE_PATH_SUB_TYPE_ACPI_DEVICE: { -+ struct efi_device_path_acpi_path *adp = -+ (struct efi_device_path_acpi_path *)dp; -+ s += sprintf(s, "/Acpi(PNP%04x", EISA_PNP_NUM(adp->hid)); -+ if (adp->uid) -+ s += sprintf(s, ",%d", adp->uid); -+ s += sprintf(s, ")"); -+ break; -+ } -+ default: -+ s = dp_unknown(s, dp); -+ break; -+ } -+ return s; -+} -+ -+static char *dp_msging(char *s, struct efi_device_path *dp) -+{ -+ switch (dp->sub_type) { -+ case DEVICE_PATH_SUB_TYPE_MSG_USB: { -+ struct efi_device_path_usb *udp = -+ (struct efi_device_path_usb *)dp; -+ s += sprintf(s, "/Usb(0x%x,0x%x)", udp->parent_port_number, -+ udp->usb_interface); -+ break; -+ } -+ case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: { -+ struct efi_device_path_mac_addr *mdp = -+ (struct efi_device_path_mac_addr *)dp; -+ -+ if (mdp->if_type != 0 && mdp->if_type != 1) - break; -- } -- } -+ -+ s += sprintf(s, "/MAC(%02x%02x%02x%02x%02x%02x,0x%1x)", -+ mdp->mac.addr[0], mdp->mac.addr[1], -+ mdp->mac.addr[2], mdp->mac.addr[3], -+ mdp->mac.addr[4], mdp->mac.addr[5], -+ mdp->if_type); -+ -+ break; -+ } -+ case DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS: { -+ struct efi_device_path_usb_class *ucdp = -+ (struct efi_device_path_usb_class *)dp; -+ -+ s += sprintf(s, "/USBClass(%x,%x,%x,%x,%x)", -+ ucdp->vendor_id, ucdp->product_id, -+ ucdp->device_class, ucdp->device_subclass, -+ ucdp->device_protocol); -+ -+ break; -+ } -+ case DEVICE_PATH_SUB_TYPE_MSG_SD: -+ case DEVICE_PATH_SUB_TYPE_MSG_MMC: { -+ const char *typename = -+ (dp->sub_type == DEVICE_PATH_SUB_TYPE_MSG_SD) ? -+ "SDCard" : "MMC"; -+ struct efi_device_path_sd_mmc_path *sddp = -+ (struct efi_device_path_sd_mmc_path *)dp; -+ s += sprintf(s, "/%s(Slot%u)", typename, sddp->slot_number); -+ break; -+ } -+ default: -+ s = dp_unknown(s, dp); - break; -- case DEVICE_PATH_TYPE_MEDIA_DEVICE: -- switch (device_node->sub_type) { -- case DEVICE_PATH_SUB_TYPE_FILE_PATH: { -- struct efi_device_path_file_path *fp = -- (struct efi_device_path_file_path *)device_node; -- buffer_size = device_node->length - 4; -- r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, -- buffer_size, (void **) &buffer); -- if (r != EFI_SUCCESS) -- return NULL; -- memcpy(buffer, fp->str, buffer_size); -+ } -+ return s; -+} -+ -+static char *dp_media(char *s, struct efi_device_path *dp) -+{ -+ switch (dp->sub_type) { -+ case DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH: { -+ struct efi_device_path_hard_drive_path *hddp = -+ (struct efi_device_path_hard_drive_path *)dp; -+ void *sig = hddp->partition_signature; -+ -+ switch (hddp->signature_type) { -+ case SIG_TYPE_MBR: -+ s += sprintf(s, "/HD(Part%d,Sig%08x)", -+ hddp->partition_number, -+ *(uint32_t *)sig); - break; -+ case SIG_TYPE_GUID: -+ s += sprintf(s, "/HD(Part%d,Sig%pUl)", -+ hddp->partition_number, sig); -+ default: -+ s += sprintf(s, "/HD(Part%d,MBRType=%02x,SigType=%02x)", -+ hddp->partition_number, hddp->partmap_type, -+ hddp->signature_type); - } -- } -+ -+ break; -+ } -+ case DEVICE_PATH_SUB_TYPE_CDROM_PATH: { -+ struct efi_device_path_cdrom_path *cddp = -+ (struct efi_device_path_cdrom_path *)dp; -+ s += sprintf(s, "/CDROM(0x%x)", cddp->boot_entry); -+ break; -+ } -+ case DEVICE_PATH_SUB_TYPE_FILE_PATH: { -+ struct efi_device_path_file_path *fp = -+ (struct efi_device_path_file_path *)dp; -+ int slen = (dp->length - sizeof(*dp)) / 2; -+ s += sprintf(s, "/%-*ls", slen, fp->str); -+ break; -+ } -+ default: -+ s = dp_unknown(s, dp); - break; - } -+ return s; -+} - -- /* -- * For all node types that we do not yet support return -- * 'UNKNOWN(type,subtype)'. -- */ -- if (!buffer) { -- r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, -- 2 * UNKNOWN_OUTPUT_LEN, -- (void **)&buffer); -- if (r != EFI_SUCCESS) -- return NULL; -- sprintf((char *)buffer, -- "UNKNOWN(%04x,%04x)", -- device_node->type, -- device_node->sub_type); -- for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i) -- buffer[i] = ((uint8_t *)buffer)[i]; -+static uint16_t *efi_convert_device_node_to_text( -+ struct efi_device_path *dp, -+ bool display_only, -+ bool allow_shortcuts) -+{ -+ unsigned long len; -+ efi_status_t r; -+ char buf[512]; /* this ought be be big enough for worst case */ -+ char *str = buf; -+ uint16_t *out; -+ -+ while (dp) { -+ switch (dp->type) { -+ case DEVICE_PATH_TYPE_HARDWARE_DEVICE: -+ str = dp_hardware(str, dp); -+ break; -+ case DEVICE_PATH_TYPE_ACPI_DEVICE: -+ str = dp_acpi(str, dp); -+ break; -+ case DEVICE_PATH_TYPE_MESSAGING_DEVICE: -+ str = dp_msging(str, dp); -+ break; -+ case DEVICE_PATH_TYPE_MEDIA_DEVICE: -+ str = dp_media(str, dp); -+ break; -+ default: -+ str = dp_unknown(str, dp); -+ } -+ -+ dp = efi_dp_next(dp); - } - -- return buffer; -+ *str++ = '\0'; -+ -+ len = str - buf; -+ r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, 2 * len, (void **)&out); -+ if (r != EFI_SUCCESS) -+ return NULL; -+ -+ ascii2unicode(out, buf); -+ out[len - 1] = 0; -+ -+ return out; - } - -+/* helper for debug prints.. efi_free_pool() the result. */ -+uint16_t *efi_dp_str(struct efi_device_path *dp) -+{ -+ return efi_convert_device_node_to_text(dp, true, true); -+} -+ -+ - static uint16_t EFIAPI *efi_convert_device_node_to_text_ext( - struct efi_device_path *device_node, - bool display_only, - -From patchwork Wed Sep 13 22:05:31 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,08/21] efi_loader: use proper device-paths for partitions -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813648 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-9-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:31 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Also, create disk objects for the disk itself, in addition to the -partitions. (UEFI terminology is a bit confusing, a "disk" object is -really a partition.) This helps grub properly identify the boot device -since it is trying to match up partition "disk" object with it's parent -device. - -Now instead of seeing devices like: - - /File(sdhci@07864000.blk)/EndEntire - /File(usb_mass_storage.lun0)/EndEntire - -You see: - - /ACPI(133741d0,0)/UnknownMessaging(1d)/EndEntire - /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(0,800,64000,dd904a8c00000000,1,1)/EndEntire - /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(1,64800,200000,dd904a8c00000000,1,1)/EndEntire - /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(2,264800,19a000,dd904a8c00000000,1,1)/EndEntire - /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/EndEntire - /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(0,800,60000,38ca680200000000,1,1)/EndEntire - /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(1,61000,155000,38ca680200000000,1,1)/EndEntire - /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(2,20fa800,1bbf8800,38ca680200000000,1,1)/EndEntire - /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(3,1b6800,1f44000,38ca680200000000,1,1)/EndEntire - -This is on a board with single USB disk and single sd-card. The -UnknownMessaging(1d) node in the device-path is the MMC device, -but grub_efi_print_device_path() hasn't been updated yet for some -of the newer device-path sub-types. - -This patch is inspired by a patch originally from Peter Jones, but -re-worked to use efi_device_path, so it doesn't much resemble the -original. - -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_disk.c | 54 +++++++++++++++++++++++++++-------------------- - 1 file changed, 31 insertions(+), 23 deletions(-) - -diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c -index ed06485e33..14f3e020c8 100644 ---- a/lib/efi_loader/efi_disk.c -+++ b/lib/efi_loader/efi_disk.c -@@ -28,11 +28,13 @@ struct efi_disk_obj { - /* EFI Interface Media descriptor struct, referenced by ops */ - struct efi_block_io_media media; - /* EFI device path to this block device */ -- struct efi_device_path_file_path *dp; -+ struct efi_device_path *dp; -+ /* partition # */ -+ unsigned part; - /* Offset into disk for simple partitions */ - lbaint_t offset; - /* Internal block device */ -- const struct blk_desc *desc; -+ struct blk_desc *desc; - }; - - static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this, -@@ -172,26 +174,26 @@ static const struct efi_block_io block_io_disk_template = { - - static void efi_disk_add_dev(const char *name, - const char *if_typename, -- const struct blk_desc *desc, -+ struct blk_desc *desc, - int dev_index, -- lbaint_t offset) -+ lbaint_t offset, -+ unsigned part) - { - struct efi_disk_obj *diskobj; -- struct efi_device_path_file_path *dp; -- int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2); - - /* Don't add empty devices */ - if (!desc->lba) - return; - -- diskobj = calloc(1, objlen); -+ diskobj = calloc(1, sizeof(*diskobj)); - - /* Fill in object data */ -- dp = (void *)&diskobj[1]; -+ diskobj->dp = efi_dp_from_part(desc, part); -+ diskobj->part = part; - diskobj->parent.protocols[0].guid = &efi_block_io_guid; - diskobj->parent.protocols[0].protocol_interface = &diskobj->ops; - diskobj->parent.protocols[1].guid = &efi_guid_device_path; -- diskobj->parent.protocols[1].protocol_interface = dp; -+ diskobj->parent.protocols[1].protocol_interface = diskobj->dp; - diskobj->parent.handle = diskobj; - diskobj->ops = block_io_disk_template; - diskobj->ifname = if_typename; -@@ -207,17 +209,6 @@ static void efi_disk_add_dev(const char *name, - diskobj->media.last_block = desc->lba - offset; - diskobj->ops.media = &diskobj->media; - -- /* Fill in device path */ -- diskobj->dp = dp; -- dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; -- dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; -- dp[0].dp.length = sizeof(*dp); -- ascii2unicode(dp[0].str, name); -- -- dp[1].dp.type = DEVICE_PATH_TYPE_END; -- dp[1].dp.sub_type = DEVICE_PATH_SUB_TYPE_END; -- dp[1].dp.length = sizeof(*dp); -- - /* Hook up to the device list */ - list_add_tail(&diskobj->parent.link, &efi_obj_list); - } -@@ -236,14 +227,18 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, - if (desc->part_type != PART_TYPE_ISO) - return 0; - -+ /* and devices for each partition: */ - while (!part_get_info(desc, part, &info)) { - snprintf(devname, sizeof(devname), "%s:%d", pdevname, - part); - efi_disk_add_dev(devname, if_typename, desc, diskid, -- info.start); -+ info.start, part); - part++; - disks++; - } -+ -+ /* ... and add block device: */ -+ efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0); - #endif - - return disks; -@@ -271,9 +266,22 @@ int efi_disk_register(void) - uclass_next_device_check(&dev)) { - struct blk_desc *desc = dev_get_uclass_platdata(dev); - const char *if_typename = dev->driver->name; -+ disk_partition_t info; -+ int part = 1; - - printf("Scanning disk %s...\n", dev->name); -- efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0); -+ -+ /* add devices for each partition: */ -+ while (!part_get_info(desc, part, &info)) { -+ efi_disk_add_dev(dev->name, if_typename, desc, -+ desc->devnum, 0, part); -+ part++; -+ } -+ -+ /* ... and add block device: */ -+ efi_disk_add_dev(dev->name, if_typename, desc, -+ desc->devnum, 0, 0); -+ - disks++; - - /* -@@ -309,7 +317,7 @@ int efi_disk_register(void) - - snprintf(devname, sizeof(devname), "%s%d", - if_typename, i); -- efi_disk_add_dev(devname, if_typename, desc, i, 0); -+ efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); - disks++; - - /* - -From patchwork Wed Sep 13 22:05:32 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,09/21] efi_loader: use proper device-paths for net -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813640 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-10-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:32 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_net.c | 19 ++----------------- - 1 file changed, 2 insertions(+), 17 deletions(-) - -diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c -index 0b949d86e8..aa0618fd3a 100644 ---- a/lib/efi_loader/efi_net.c -+++ b/lib/efi_loader/efi_net.c -@@ -26,9 +26,6 @@ struct efi_net_obj { - /* EFI Interface callback struct for network */ - struct efi_simple_network net; - struct efi_simple_network_mode net_mode; -- /* Device path to the network adapter */ -- struct efi_device_path_mac_addr dp_mac; -- struct efi_device_path_file_path dp_end; - /* PXE struct to transmit dhcp data */ - struct efi_pxe pxe; - struct efi_pxe_mode pxe_mode; -@@ -213,16 +210,6 @@ void efi_net_set_dhcp_ack(void *pkt, int len) - int efi_net_register(void **handle) - { - struct efi_net_obj *netobj; -- struct efi_device_path_mac_addr dp_net = { -- .dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR, -- .dp.length = sizeof(dp_net), -- }; -- struct efi_device_path_file_path dp_end = { -- .dp.type = DEVICE_PATH_TYPE_END, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, -- .dp.length = sizeof(dp_end), -- }; - - if (!eth_get_dev()) { - /* No eth device active, don't expose any */ -@@ -236,7 +223,8 @@ int efi_net_register(void **handle) - netobj->parent.protocols[0].guid = &efi_net_guid; - netobj->parent.protocols[0].protocol_interface = &netobj->net; - netobj->parent.protocols[1].guid = &efi_guid_device_path; -- netobj->parent.protocols[1].protocol_interface = &netobj->dp_mac; -+ netobj->parent.protocols[1].protocol_interface = -+ efi_dp_from_eth(); - netobj->parent.protocols[2].guid = &efi_pxe_guid; - netobj->parent.protocols[2].protocol_interface = &netobj->pxe; - netobj->parent.handle = &netobj->net; -@@ -255,9 +243,6 @@ int efi_net_register(void **handle) - netobj->net.receive = efi_net_receive; - netobj->net.mode = &netobj->net_mode; - netobj->net_mode.state = EFI_NETWORK_STARTED; -- netobj->dp_mac = dp_net; -- netobj->dp_end = dp_end; -- memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6); - memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6); - netobj->net_mode.max_packet_size = PKTSIZE; - - -From patchwork Wed Sep 13 22:05:33 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v3, - 10/21] efi_loader: refactor boot device and loaded_image handling -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813642 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-11-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:33 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Get rid of the hacky fake boot-device and duplicate device-path -constructing (which needs to match what efi_disk and efi_net do). -Instead convert over to use efi_device_path helpers to construct -device-paths, and use that to look up the actual boot device. - -Also, extract out a helper to plug things in properly to the -loaded_image. In a following patch we'll want to re-use this in -efi_load_image() to handle the case of loading an image from a -file_path. - -Signed-off-by: Rob Clark ---- - cmd/bootefi.c | 201 +++++++++++++----------------------------- - include/efi_loader.h | 5 +- - lib/efi_loader/efi_boottime.c | 36 ++++++++ - lib/efi_loader/efi_net.c | 5 +- - 4 files changed, 100 insertions(+), 147 deletions(-) - -diff --git a/cmd/bootefi.c b/cmd/bootefi.c -index 3196d86040..0980088668 100644 ---- a/cmd/bootefi.c -+++ b/cmd/bootefi.c -@@ -22,97 +22,14 @@ DECLARE_GLOBAL_DATA_PTR; - - static uint8_t efi_obj_list_initalized; - --/* -- * When booting using the "bootefi" command, we don't know which -- * physical device the file came from. So we create a pseudo-device -- * called "bootefi" with the device path /bootefi. -- * -- * In addition to the originating device we also declare the file path -- * of "bootefi" based loads to be /bootefi. -- */ --static struct efi_device_path_file_path bootefi_image_path[] = { -- { -- .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, -- .dp.length = sizeof(bootefi_image_path[0]), -- .str = { 'b','o','o','t','e','f','i' }, -- }, { -- .dp.type = DEVICE_PATH_TYPE_END, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, -- .dp.length = sizeof(bootefi_image_path[0]), -- } --}; -- --static struct efi_device_path_file_path bootefi_device_path[] = { -- { -- .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, -- .dp.length = sizeof(bootefi_image_path[0]), -- .str = { 'b','o','o','t','e','f','i' }, -- }, { -- .dp.type = DEVICE_PATH_TYPE_END, -- .dp.sub_type = DEVICE_PATH_SUB_TYPE_END, -- .dp.length = sizeof(bootefi_image_path[0]), -- } --}; -- --/* The EFI loaded_image interface for the image executed via "bootefi" */ --static struct efi_loaded_image loaded_image_info = { -- .device_handle = bootefi_device_path, -- .file_path = bootefi_image_path, --}; -- --/* The EFI object struct for the image executed via "bootefi" */ --static struct efi_object loaded_image_info_obj = { -- .handle = &loaded_image_info, -- .protocols = { -- { -- /* -- * When asking for the loaded_image interface, just -- * return handle which points to loaded_image_info -- */ -- .guid = &efi_guid_loaded_image, -- .protocol_interface = &loaded_image_info, -- }, -- { -- /* -- * When asking for the device path interface, return -- * bootefi_device_path -- */ -- .guid = &efi_guid_device_path, -- .protocol_interface = bootefi_device_path, -- }, -- { -- .guid = &efi_guid_console_control, -- .protocol_interface = (void *) &efi_console_control -- }, -- { -- .guid = &efi_guid_device_path_to_text_protocol, -- .protocol_interface = (void *) &efi_device_path_to_text -- }, -- }, --}; -- --/* The EFI object struct for the device the "bootefi" image was loaded from */ --static struct efi_object bootefi_device_obj = { -- .handle = bootefi_device_path, -- .protocols = { -- { -- /* When asking for the device path interface, return -- * bootefi_device_path */ -- .guid = &efi_guid_device_path, -- .protocol_interface = bootefi_device_path -- } -- }, --}; -+static struct efi_device_path *bootefi_image_path; -+static struct efi_device_path *bootefi_device_path; - - /* Initialize and populate EFI object list */ - static void efi_init_obj_list(void) - { - efi_obj_list_initalized = 1; - -- list_add_tail(&loaded_image_info_obj.link, &efi_obj_list); -- list_add_tail(&bootefi_device_obj.link, &efi_obj_list); - efi_console_register(); - #ifdef CONFIG_PARTITIONS - efi_disk_register(); -@@ -121,13 +38,7 @@ static void efi_init_obj_list(void) - efi_gop_register(); - #endif - #ifdef CONFIG_NET -- void *nethandle = loaded_image_info.device_handle; -- efi_net_register(&nethandle); -- -- if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6)) -- loaded_image_info.device_handle = nethandle; -- else -- loaded_image_info.device_handle = bootefi_device_path; -+ efi_net_register(); - #endif - #ifdef CONFIG_GENERATE_SMBIOS_TABLE - efi_smbios_register(); -@@ -210,14 +121,27 @@ static unsigned long efi_run_in_el2(asmlinkage ulong (*entry)( - * Load an EFI payload into a newly allocated piece of memory, register all - * EFI objects it would want to access and jump to it. - */ --static unsigned long do_bootefi_exec(void *efi, void *fdt) -+static unsigned long do_bootefi_exec(void *efi, void *fdt, -+ struct efi_device_path *device_path, -+ struct efi_device_path *image_path) - { -+ struct efi_loaded_image loaded_image_info = {}; -+ struct efi_object loaded_image_info_obj = {}; -+ ulong ret; -+ - ulong (*entry)(void *image_handle, struct efi_system_table *st) - asmlinkage; - ulong fdt_pages, fdt_size, fdt_start, fdt_end; - const efi_guid_t fdt_guid = EFI_FDT_GUID; - bootm_headers_t img = { 0 }; - -+ /* Initialize and populate EFI object list */ -+ if (!efi_obj_list_initalized) -+ efi_init_obj_list(); -+ -+ efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj, -+ device_path, image_path); -+ - /* - * gd lives in a fixed register which may get clobbered while we execute - * the payload. So save it here and restore it on every callback entry -@@ -252,18 +176,18 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) - - /* Load the EFI payload */ - entry = efi_load_pe(efi, &loaded_image_info); -- if (!entry) -- return -ENOENT; -- -- /* Initialize and populate EFI object list */ -- if (!efi_obj_list_initalized) -- efi_init_obj_list(); -+ if (!entry) { -+ ret = -ENOENT; -+ goto exit; -+ } - - /* Call our payload! */ - debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); - - if (setjmp(&loaded_image_info.exit_jmp)) { -- return loaded_image_info.exit_status; -+ ret = loaded_image_info.exit_status; -+ EFI_EXIT(ret); -+ goto exit; - } - - #ifdef CONFIG_ARM64 -@@ -282,7 +206,13 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) - } - #endif - -- return efi_do_enter(&loaded_image_info, &systab, entry); -+ ret = efi_do_enter(&loaded_image_info, &systab, entry); -+ -+exit: -+ /* image has returned, loaded-image obj goes *poof*: */ -+ list_del(&loaded_image_info_obj.link); -+ -+ return ret; - } - - -@@ -315,7 +245,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) - } - - printf("## Starting EFI application at %08lx ...\n", addr); -- r = do_bootefi_exec((void *)addr, (void*)fdt_addr); -+ r = do_bootefi_exec((void *)addr, (void *)fdt_addr, -+ bootefi_device_path, bootefi_image_path); - printf("## Application terminated, r = %lu\n", - r & ~EFI_ERROR_MASK); - -@@ -344,58 +275,44 @@ U_BOOT_CMD( - bootefi_help_text - ); - --void efi_set_bootdev(const char *dev, const char *devnr, const char *path) -+static int parse_partnum(const char *devnr) - { -- __maybe_unused struct blk_desc *desc; -- char devname[32] = { 0 }; /* dp->str is u16[32] long */ -- char *colon, *s; -- --#if defined(CONFIG_BLK) || CONFIG_IS_ENABLED(ISO_PARTITION) -- desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10)); --#endif -- --#ifdef CONFIG_BLK -- if (desc) { -- snprintf(devname, sizeof(devname), "%s", desc->bdev->name); -- } else --#endif -- -- { -- /* Assemble the condensed device name we use in efi_disk.c */ -- snprintf(devname, sizeof(devname), "%s%s", dev, devnr); -+ const char *str = strchr(devnr, ':'); -+ if (str) { -+ str++; -+ return simple_strtoul(str, NULL, 16); - } -+ return 0; -+} - -- colon = strchr(devname, ':'); -- --#if CONFIG_IS_ENABLED(ISO_PARTITION) -- /* For ISOs we create partition block devices */ -- if (desc && (desc->type != DEV_TYPE_UNKNOWN) && -- (desc->part_type == PART_TYPE_ISO)) { -- if (!colon) -- snprintf(devname, sizeof(devname), "%s:1", devname); -+void efi_set_bootdev(const char *dev, const char *devnr, const char *path) -+{ -+ char filename[32] = { 0 }; /* dp->str is u16[32] long */ -+ char *s; - -- colon = NULL; -- } --#endif -+ if (strcmp(dev, "Net")) { -+ struct blk_desc *desc; -+ int part; - -- if (colon) -- *colon = '\0'; -+ desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10)); -+ part = parse_partnum(devnr); - -- /* Patch bootefi_device_path to the target device */ -- memset(bootefi_device_path[0].str, 0, sizeof(bootefi_device_path[0].str)); -- ascii2unicode(bootefi_device_path[0].str, devname); -+ bootefi_device_path = efi_dp_from_part(desc, part); -+ } else { -+#ifdef CONFIG_NET -+ bootefi_device_path = efi_dp_from_eth(); -+#endif -+ } - -- /* Patch bootefi_image_path to the target file path */ -- memset(bootefi_image_path[0].str, 0, sizeof(bootefi_image_path[0].str)); - if (strcmp(dev, "Net")) { - /* Add leading / to fs paths, because they're absolute */ -- snprintf(devname, sizeof(devname), "/%s", path); -+ snprintf(filename, sizeof(filename), "/%s", path); - } else { -- snprintf(devname, sizeof(devname), "%s", path); -+ snprintf(filename, sizeof(filename), "%s", path); - } - /* DOS style file path: */ -- s = devname; -+ s = filename; - while ((s = strchr(s, '/'))) - *s++ = '\\'; -- ascii2unicode(bootefi_image_path[0].str, devname); -+ bootefi_image_path = efi_dp_from_file(NULL, 0, filename); - } -diff --git a/include/efi_loader.h b/include/efi_loader.h -index f39c2ee6da..ec8803f588 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -136,7 +136,7 @@ int efi_disk_register(void); - /* Called by bootefi to make GOP (graphical) interface available */ - int efi_gop_register(void); - /* Called by bootefi to make the network interface available */ --int efi_net_register(void **handle); -+int efi_net_register(void); - /* Called by bootefi to make SMBIOS tables available */ - void efi_smbios_register(void); - -@@ -193,6 +193,9 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, - int efi_memory_init(void); - /* Adds new or overrides configuration table entry to the system table */ - efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table); -+void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, -+ struct efi_device_path *device_path, -+ struct efi_device_path *file_path); - - #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER - extern void *efi_bounce_buffer; -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index b962b62a97..837e61d8fe 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -726,6 +726,42 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, - return EFI_EXIT(efi_install_configuration_table(guid, table)); - } - -+/* Initialize a loaded_image_info + loaded_image_info object with correct -+ * protocols, boot-device, etc. -+ */ -+void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, -+ struct efi_device_path *device_path, -+ struct efi_device_path *file_path) -+{ -+ obj->handle = info; -+ -+ /* -+ * When asking for the device path interface, return -+ * bootefi_device_path -+ */ -+ obj->protocols[0].guid = &efi_guid_device_path; -+ obj->protocols[0].protocol_interface = device_path; -+ -+ /* -+ * When asking for the loaded_image interface, just -+ * return handle which points to loaded_image_info -+ */ -+ obj->protocols[1].guid = &efi_guid_loaded_image; -+ obj->protocols[1].protocol_interface = info; -+ -+ obj->protocols[2].guid = &efi_guid_console_control; -+ obj->protocols[2].protocol_interface = (void *)&efi_console_control; -+ -+ obj->protocols[3].guid = &efi_guid_device_path_to_text_protocol; -+ obj->protocols[3].protocol_interface = -+ (void *)&efi_device_path_to_text; -+ -+ info->file_path = file_path; -+ info->device_handle = efi_dp_find_obj(device_path, NULL); -+ -+ list_add_tail(&obj->link, &efi_obj_list); -+} -+ - static efi_status_t EFIAPI efi_load_image(bool boot_policy, - efi_handle_t parent_image, - struct efi_device_path *file_path, -diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c -index aa0618fd3a..91f1e4a69e 100644 ---- a/lib/efi_loader/efi_net.c -+++ b/lib/efi_loader/efi_net.c -@@ -207,7 +207,7 @@ void efi_net_set_dhcp_ack(void *pkt, int len) - } - - /* This gets called from do_bootefi_exec(). */ --int efi_net_register(void **handle) -+int efi_net_register(void) - { - struct efi_net_obj *netobj; - -@@ -253,8 +253,5 @@ int efi_net_register(void **handle) - /* Hook net up to the device list */ - list_add_tail(&netobj->parent.link, &efi_obj_list); - -- if (handle) -- *handle = &netobj->net; -- - return 0; - } - -From patchwork Wed Sep 13 22:05:34 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,11/21] efi_loader: add file/filesys support -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813652 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-12-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:34 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -fallback.efi (and probably other things) use UEFI's simple-file-system -protocol and file support to search for OS's to boot. - -Signed-off-by: Rob Clark ---- - include/efi.h | 2 + - include/efi_api.h | 65 +++++ - include/efi_loader.h | 13 + - lib/efi_loader/Makefile | 1 + - lib/efi_loader/efi_disk.c | 32 +++ - lib/efi_loader/efi_file.c | 560 ++++++++++++++++++++++++++++++++++++++ - lib/efi_loader/efi_image_loader.c | 3 + - 7 files changed, 676 insertions(+) - create mode 100644 lib/efi_loader/efi_file.c - -diff --git a/include/efi.h b/include/efi.h -index 87b0b43f20..ddd2b96417 100644 ---- a/include/efi.h -+++ b/include/efi.h -@@ -81,6 +81,8 @@ typedef struct { - #define EFI_IP_ADDRESS_CONFLICT (EFI_ERROR_MASK | 34) - #define EFI_HTTP_ERROR (EFI_ERROR_MASK | 35) - -+#define EFI_WARN_DELETE_FAILURE 2 -+ - typedef unsigned long efi_status_t; - typedef u64 efi_physical_addr_t; - typedef u64 efi_virtual_addr_t; -diff --git a/include/efi_api.h b/include/efi_api.h -index 0c36122107..1aae96355f 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -666,4 +666,69 @@ struct efi_pxe { - struct efi_pxe_mode *mode; - }; - -+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ -+ EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \ -+ 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) -+#define EFI_FILE_PROTOCOL_REVISION 0x00010000 -+ -+struct efi_file_handle { -+ u64 rev; -+ efi_status_t (EFIAPI *open)(struct efi_file_handle *file, -+ struct efi_file_handle **new_handle, -+ s16 *file_name, u64 open_mode, u64 attributes); -+ efi_status_t (EFIAPI *close)(struct efi_file_handle *file); -+ efi_status_t (EFIAPI *delete)(struct efi_file_handle *file); -+ efi_status_t (EFIAPI *read)(struct efi_file_handle *file, -+ u64 *buffer_size, void *buffer); -+ efi_status_t (EFIAPI *write)(struct efi_file_handle *file, -+ u64 *buffer_size, void *buffer); -+ efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file, -+ u64 *pos); -+ efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file, -+ u64 pos); -+ efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file, -+ efi_guid_t *info_type, u64 *buffer_size, void *buffer); -+ efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *file, -+ efi_guid_t *info_type, u64 buffer_size, void *buffer); -+ efi_status_t (EFIAPI *flush)(struct efi_file_handle *file); -+}; -+ -+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ -+ EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \ -+ 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) -+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 -+ -+struct efi_simple_file_system_protocol { -+ u64 rev; -+ efi_status_t (EFIAPI *open_volume)(struct efi_simple_file_system_protocol *this, -+ struct efi_file_handle **root); -+}; -+ -+#define EFI_FILE_INFO_GUID \ -+ EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, \ -+ 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b) -+ -+#define EFI_FILE_MODE_READ 0x0000000000000001 -+#define EFI_FILE_MODE_WRITE 0x0000000000000002 -+#define EFI_FILE_MODE_CREATE 0x8000000000000000 -+ -+#define EFI_FILE_READ_ONLY 0x0000000000000001 -+#define EFI_FILE_HIDDEN 0x0000000000000002 -+#define EFI_FILE_SYSTEM 0x0000000000000004 -+#define EFI_FILE_RESERVED 0x0000000000000008 -+#define EFI_FILE_DIRECTORY 0x0000000000000010 -+#define EFI_FILE_ARCHIVE 0x0000000000000020 -+#define EFI_FILE_VALID_ATTR 0x0000000000000037 -+ -+struct efi_file_info { -+ u64 size; -+ u64 file_size; -+ u64 physical_size; -+ struct efi_time create_time; -+ struct efi_time last_access_time; -+ struct efi_time modification_time; -+ u64 attribute; -+ s16 file_name[0]; -+}; -+ - #endif -diff --git a/include/efi_loader.h b/include/efi_loader.h -index ec8803f588..b0c1e8fb78 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -65,6 +65,8 @@ extern const efi_guid_t efi_guid_console_control; - extern const efi_guid_t efi_guid_device_path; - extern const efi_guid_t efi_guid_loaded_image; - extern const efi_guid_t efi_guid_device_path_to_text_protocol; -+extern const efi_guid_t efi_simple_file_system_protocol_guid; -+extern const efi_guid_t efi_file_info_guid; - - extern unsigned int __efi_runtime_start, __efi_runtime_stop; - extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; -@@ -140,6 +142,9 @@ int efi_net_register(void); - /* Called by bootefi to make SMBIOS tables available */ - void efi_smbios_register(void); - -+struct efi_simple_file_system_protocol * -+efi_fs_from_path(struct efi_device_path *fp); -+ - /* Called by networking code to memorize the dhcp ack package */ - void efi_net_set_dhcp_ack(void *pkt, int len); - -@@ -168,6 +173,14 @@ efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type, - /* Call this to signal an event */ - void efi_signal_event(struct efi_event *event); - -+/* open file system: */ -+struct efi_simple_file_system_protocol *efi_simple_file_system( -+ struct blk_desc *desc, int part, struct efi_device_path *dp); -+ -+/* open file from device-path: */ -+struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp); -+ -+ - /* Generic EFI memory allocator, call this to get memory */ - void *efi_alloc(uint64_t len, int memory_type); - /* More specific EFI memory allocator, called by EFI payloads */ -diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile -index f35e5ce8a8..cce92cfeb5 100644 ---- a/lib/efi_loader/Makefile -+++ b/lib/efi_loader/Makefile -@@ -16,6 +16,7 @@ always := $(efiprogs-y) - obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o - obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o - obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o -+obj-y += efi_file.o - obj-$(CONFIG_LCD) += efi_gop.o - obj-$(CONFIG_DM_VIDEO) += efi_gop.o - obj-$(CONFIG_PARTITIONS) += efi_disk.o -diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c -index 14f3e020c8..9805585eb1 100644 ---- a/lib/efi_loader/efi_disk.c -+++ b/lib/efi_loader/efi_disk.c -@@ -31,6 +31,8 @@ struct efi_disk_obj { - struct efi_device_path *dp; - /* partition # */ - unsigned part; -+ /* handle to filesys proto (for partition objects) */ -+ struct efi_simple_file_system_protocol *volume; - /* Offset into disk for simple partitions */ - lbaint_t offset; - /* Internal block device */ -@@ -172,6 +174,28 @@ static const struct efi_block_io block_io_disk_template = { - .flush_blocks = &efi_disk_flush_blocks, - }; - -+/* -+ * Find filesystem from a device-path. The passed in path 'p' probably -+ * contains one or more /File(name) nodes, so the comparison stops at -+ * the first /File() node, and returns the pointer to that via 'rp'. -+ * This is mostly intended to be a helper to map a device-path to an -+ * efi_file_handle object. -+ */ -+struct efi_simple_file_system_protocol * -+efi_fs_from_path(struct efi_device_path *fp) -+{ -+ struct efi_object *efiobj; -+ struct efi_disk_obj *diskobj; -+ -+ efiobj = efi_dp_find_obj(fp, NULL); -+ if (!efiobj) -+ return NULL; -+ -+ diskobj = container_of(efiobj, struct efi_disk_obj, parent); -+ -+ return diskobj->volume; -+} -+ - static void efi_disk_add_dev(const char *name, - const char *if_typename, - struct blk_desc *desc, -@@ -194,6 +218,14 @@ static void efi_disk_add_dev(const char *name, - diskobj->parent.protocols[0].protocol_interface = &diskobj->ops; - diskobj->parent.protocols[1].guid = &efi_guid_device_path; - diskobj->parent.protocols[1].protocol_interface = diskobj->dp; -+ if (part >= 1) { -+ diskobj->volume = efi_simple_file_system(desc, part, -+ diskobj->dp); -+ diskobj->parent.protocols[2].guid = -+ &efi_simple_file_system_protocol_guid; -+ diskobj->parent.protocols[2].protocol_interface = -+ diskobj->volume; -+ } - diskobj->parent.handle = diskobj; - diskobj->ops = block_io_disk_template; - diskobj->ifname = if_typename; -diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c -new file mode 100644 -index 0000000000..5e1eee5a20 ---- /dev/null -+++ b/lib/efi_loader/efi_file.c -@@ -0,0 +1,560 @@ -+/* -+ * EFI utils -+ * -+ * Copyright (c) 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct file_system { -+ struct efi_simple_file_system_protocol base; -+ struct efi_device_path *dp; -+ struct blk_desc *desc; -+ int part; -+}; -+#define to_fs(x) container_of(x, struct file_system, base) -+ -+struct file_handle { -+ struct efi_file_handle base; -+ struct file_system *fs; -+ loff_t offset; /* current file position/cursor */ -+ int isdir; -+ -+ /* for reading a directory: */ -+ struct fs_dir_stream *dirs; -+ struct fs_dirent *dent; -+ -+ char path[0]; -+}; -+#define to_fh(x) container_of(x, struct file_handle, base) -+ -+static const struct efi_file_handle efi_file_handle_protocol; -+ -+static char *basename(struct file_handle *fh) -+{ -+ char *s = strrchr(fh->path, '/'); -+ if (s) -+ return s + 1; -+ return fh->path; -+} -+ -+static int set_blk_dev(struct file_handle *fh) -+{ -+ return fs_set_blk_dev_with_part(fh->fs->desc, fh->fs->part); -+} -+ -+static int is_dir(struct file_handle *fh) -+{ -+ struct fs_dir_stream *dirs; -+ -+ set_blk_dev(fh); -+ dirs = fs_opendir(fh->path); -+ if (!dirs) -+ return 0; -+ -+ fs_closedir(dirs); -+ -+ return 1; -+} -+ -+/* -+ * Normalize a path which may include either back or fwd slashes, -+ * double slashes, . or .. entries in the path, etc. -+ */ -+static int sanitize_path(char *path) -+{ -+ char *p ; -+ -+ /* backslash to slash: */ -+ p = path; -+ while ((p = strchr(p, '\\'))) -+ *p++ = '/'; -+ -+ /* handle double-slashes: */ -+ p = path; -+ while ((p = strstr(p, "//"))) { -+ char *src = p + 1; -+ memmove(p, src, strlen(src) + 1); -+ } -+ -+ /* handle extra /.'s */ -+ p = path; -+ while ((p = strstr(p, "/."))) { -+ /* -+ * You'd be tempted to do this *after* handling ".."s -+ * below to avoid having to check if "/." is start of -+ * a "/..", but that won't have the correct results.. -+ * for example, "/foo/./../bar" would get resolved to -+ * "/foo/bar" if you did these two passes in the other -+ * order -+ */ -+ if (p[2] == '.') { -+ p += 2; -+ continue; -+ } -+ char *src = p + 2; -+ memmove(p, src, strlen(src) + 1); -+ } -+ -+ /* handle extra /..'s: */ -+ p = path; -+ while ((p = strstr(p, "/.."))) { -+ char *src = p + 3; -+ -+ p--; -+ -+ /* find beginning of previous path entry: */ -+ while (true) { -+ if (p < path) -+ return -1; -+ if (*p == '/') -+ break; -+ p--; -+ } -+ -+ memmove(p, src, strlen(src) + 1); -+ } -+ -+ return 0; -+} -+ -+/* NOTE: despite what you would expect, 'file_name' is actually a path. -+ * With windoze style backlashes, ofc. -+ */ -+static struct efi_file_handle *file_open(struct file_system *fs, -+ struct file_handle *parent, s16 *file_name, u64 mode) -+{ -+ struct file_handle *fh; -+ char f0[MAX_UTF8_PER_UTF16] = {0}; -+ int plen = 0; -+ int flen = 0; -+ -+ if (file_name) { -+ utf16_to_utf8((u8 *)f0, (u16 *)file_name, 1); -+ flen = utf16_strlen((u16 *)file_name); -+ } -+ -+ /* we could have a parent, but also an absolute path: */ -+ if (f0[0] == '\\') { -+ plen = 0; -+ } else if (parent) { -+ plen = strlen(parent->path) + 1; -+ } -+ -+ /* +2 is for null and '/' */ -+ fh = calloc(1, sizeof(*fh) + plen + (flen * MAX_UTF8_PER_UTF16) + 2); -+ -+ fh->base = efi_file_handle_protocol; -+ fh->fs = fs; -+ -+ if (parent) { -+ char *p = fh->path; -+ -+ if (plen > 0) { -+ strcpy(p, parent->path); -+ p += plen - 1; -+ *p++ = '/'; -+ } -+ -+ utf16_to_utf8((u8 *)p, (u16 *)file_name, flen); -+ -+ if (sanitize_path(fh->path)) -+ goto error; -+ -+ /* check if file exists: */ -+ if (set_blk_dev(fh)) -+ goto error; -+ -+ if (!((mode & EFI_FILE_MODE_CREATE) || fs_exists(fh->path))) -+ goto error; -+ -+ /* figure out if file is a directory: */ -+ fh->isdir = is_dir(fh); -+ } else { -+ fh->isdir = 1; -+ strcpy(fh->path, ""); -+ } -+ -+ return &fh->base; -+ -+error: -+ free(fh); -+ return NULL; -+} -+ -+static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, -+ struct efi_file_handle **new_handle, -+ s16 *file_name, u64 open_mode, u64 attributes) -+{ -+ struct file_handle *fh = to_fh(file); -+ -+ EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name, -+ open_mode, attributes); -+ -+ *new_handle = file_open(fh->fs, fh, file_name, open_mode); -+ if (!*new_handle) -+ return EFI_EXIT(EFI_NOT_FOUND); -+ -+ return EFI_EXIT(EFI_SUCCESS); -+} -+ -+static efi_status_t file_close(struct file_handle *fh) -+{ -+ fs_closedir(fh->dirs); -+ free(fh); -+ return EFI_SUCCESS; -+} -+ -+static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) -+{ -+ struct file_handle *fh = to_fh(file); -+ EFI_ENTRY("%p", file); -+ return EFI_EXIT(file_close(fh)); -+} -+ -+static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) -+{ -+ struct file_handle *fh = to_fh(file); -+ EFI_ENTRY("%p", file); -+ file_close(fh); -+ return EFI_EXIT(EFI_WARN_DELETE_FAILURE); -+} -+ -+static efi_status_t file_read(struct file_handle *fh, u64 *buffer_size, -+ void *buffer) -+{ -+ loff_t actread; -+ -+ if (fs_read(fh->path, (ulong)buffer, fh->offset, -+ *buffer_size, &actread)) -+ return EFI_DEVICE_ERROR; -+ -+ *buffer_size = actread; -+ fh->offset += actread; -+ -+ return EFI_SUCCESS; -+} -+ -+static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, -+ void *buffer) -+{ -+ struct efi_file_info *info = buffer; -+ struct fs_dirent *dent; -+ unsigned required_size; -+ -+ if (!fh->dirs) { -+ assert(fh->offset == 0); -+ fh->dirs = fs_opendir(fh->path); -+ if (!fh->dirs) -+ return EFI_DEVICE_ERROR; -+ } -+ -+ /* -+ * So this is a bit awkward. Since fs layer is stateful and we -+ * can't rewind an entry, in the EFI_BUFFER_TOO_SMALL case below -+ * we might have to return without consuming the dent.. so we -+ * have to stash it for next call. -+ */ -+ if (fh->dent) { -+ dent = fh->dent; -+ fh->dent = NULL; -+ } else { -+ dent = fs_readdir(fh->dirs); -+ } -+ -+ -+ if (!dent) { -+ /* no more files in directory: */ -+ /* workaround shim.efi bug/quirk.. as find_boot_csv() -+ * loops through directory contents, it initially calls -+ * read w/ zero length buffer to find out how much mem -+ * to allocate for the EFI_FILE_INFO, then allocates, -+ * and then calls a 2nd time. If we return size of -+ * zero the first time, it happily passes that to -+ * AllocateZeroPool(), and when that returns NULL it -+ * thinks it is EFI_OUT_OF_RESOURCES. So on first -+ * call return a non-zero size: -+ */ -+ if (*buffer_size == 0) -+ *buffer_size = sizeof(*info); -+ else -+ *buffer_size = 0; -+ return EFI_SUCCESS; -+ } -+ -+ /* check buffer size: */ -+ required_size = sizeof(*info) + 2 * (strlen(dent->name) + 1); -+ if (*buffer_size < required_size) { -+ *buffer_size = required_size; -+ fh->dent = dent; -+ return EFI_BUFFER_TOO_SMALL; -+ } -+ -+ *buffer_size = required_size; -+ memset(info, 0, required_size); -+ -+ info->size = required_size; -+ info->file_size = dent->size; -+ info->physical_size = dent->size; -+ -+ if (dent->type == FS_DT_DIR) -+ info->attribute |= EFI_FILE_DIRECTORY; -+ -+ ascii2unicode((u16 *)info->file_name, dent->name); -+ -+ fh->offset++; -+ -+ return EFI_SUCCESS; -+} -+ -+static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file, -+ u64 *buffer_size, void *buffer) -+{ -+ struct file_handle *fh = to_fh(file); -+ efi_status_t ret = EFI_SUCCESS; -+ -+ EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); -+ -+ if (set_blk_dev(fh)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ if (fh->isdir) -+ ret = dir_read(fh, buffer_size, buffer); -+ else -+ ret = file_read(fh, buffer_size, buffer); -+ -+error: -+ return EFI_EXIT(ret); -+} -+ -+static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file, -+ u64 *buffer_size, void *buffer) -+{ -+ struct file_handle *fh = to_fh(file); -+ efi_status_t ret = EFI_SUCCESS; -+ loff_t actwrite; -+ -+ EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); -+ -+ if (set_blk_dev(fh)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ if (fs_write(fh->path, (ulong)buffer, fh->offset, *buffer_size, -+ &actwrite)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ *buffer_size = actwrite; -+ fh->offset += actwrite; -+ -+error: -+ return EFI_EXIT(ret); -+} -+ -+static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file, -+ u64 *pos) -+{ -+ struct file_handle *fh = to_fh(file); -+ EFI_ENTRY("%p, %p", file, pos); -+ *pos = fh->offset; -+ return EFI_EXIT(EFI_SUCCESS); -+} -+ -+static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, -+ u64 pos) -+{ -+ struct file_handle *fh = to_fh(file); -+ efi_status_t ret = EFI_SUCCESS; -+ -+ EFI_ENTRY("%p, %llu", file, pos); -+ -+ if (fh->isdir) { -+ if (pos != 0) { -+ ret = EFI_UNSUPPORTED; -+ goto error; -+ } -+ fs_closedir(fh->dirs); -+ fh->dirs = NULL; -+ } -+ -+ if (pos == ~0ULL) { -+ loff_t file_size; -+ -+ if (set_blk_dev(fh)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ if (fs_size(fh->path, &file_size)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ pos = file_size; -+ } -+ -+ fh->offset = pos; -+ -+error: -+ return EFI_EXIT(ret); -+} -+ -+static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file, -+ efi_guid_t *info_type, u64 *buffer_size, void *buffer) -+{ -+ struct file_handle *fh = to_fh(file); -+ efi_status_t ret = EFI_SUCCESS; -+ -+ EFI_ENTRY("%p, %p, %p, %p", file, info_type, buffer_size, buffer); -+ -+ if (!guidcmp(info_type, &efi_file_info_guid)) { -+ struct efi_file_info *info = buffer; -+ char *filename = basename(fh); -+ unsigned required_size; -+ loff_t file_size; -+ -+ /* check buffer size: */ -+ required_size = sizeof(*info) + 2 * (strlen(filename) + 1); -+ if (*buffer_size < required_size) { -+ *buffer_size = required_size; -+ ret = EFI_BUFFER_TOO_SMALL; -+ goto error; -+ } -+ -+ if (set_blk_dev(fh)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ if (fs_size(fh->path, &file_size)) { -+ ret = EFI_DEVICE_ERROR; -+ goto error; -+ } -+ -+ memset(info, 0, required_size); -+ -+ info->size = required_size; -+ info->file_size = file_size; -+ info->physical_size = file_size; -+ -+ if (fh->isdir) -+ info->attribute |= EFI_FILE_DIRECTORY; -+ -+ ascii2unicode((u16 *)info->file_name, filename); -+ } else { -+ ret = EFI_UNSUPPORTED; -+ } -+ -+error: -+ return EFI_EXIT(ret); -+} -+ -+static efi_status_t EFIAPI efi_file_setinfo(struct efi_file_handle *file, -+ efi_guid_t *info_type, u64 buffer_size, void *buffer) -+{ -+ EFI_ENTRY("%p, %p, %llu, %p", file, info_type, buffer_size, buffer); -+ return EFI_EXIT(EFI_UNSUPPORTED); -+} -+ -+static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *file) -+{ -+ EFI_ENTRY("%p", file); -+ return EFI_EXIT(EFI_SUCCESS); -+} -+ -+static const struct efi_file_handle efi_file_handle_protocol = { -+ .rev = EFI_FILE_PROTOCOL_REVISION, -+ .open = efi_file_open, -+ .close = efi_file_close, -+ .delete = efi_file_delete, -+ .read = efi_file_read, -+ .write = efi_file_write, -+ .getpos = efi_file_getpos, -+ .setpos = efi_file_setpos, -+ .getinfo = efi_file_getinfo, -+ .setinfo = efi_file_setinfo, -+ .flush = efi_file_flush, -+}; -+ -+struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) -+{ -+ struct efi_simple_file_system_protocol *v; -+ struct efi_file_handle *f; -+ efi_status_t ret; -+ -+ v = efi_fs_from_path(fp); -+ if (!v) -+ return NULL; -+ -+ EFI_CALL(ret = v->open_volume(v, &f)); -+ if (ret != EFI_SUCCESS) -+ return NULL; -+ -+ /* skip over device-path nodes before the file path: */ -+ while (fp && !EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) -+ fp = efi_dp_next(fp); -+ -+ while (fp) { -+ struct efi_device_path_file_path *fdp = -+ container_of(fp, struct efi_device_path_file_path, dp); -+ struct efi_file_handle *f2; -+ -+ if (!EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) { -+ printf("bad file path!\n"); -+ f->close(f); -+ return NULL; -+ } -+ -+ EFI_CALL(ret = f->open(f, &f2, (s16 *)fdp->str, -+ EFI_FILE_MODE_READ, 0)); -+ if (ret != EFI_SUCCESS) -+ return NULL; -+ -+ fp = efi_dp_next(fp); -+ -+ EFI_CALL(f->close(f)); -+ f = f2; -+ } -+ -+ return f; -+} -+ -+static efi_status_t EFIAPI -+efi_open_volume(struct efi_simple_file_system_protocol *this, -+ struct efi_file_handle **root) -+{ -+ struct file_system *fs = to_fs(this); -+ -+ EFI_ENTRY("%p, %p", this, root); -+ -+ *root = file_open(fs, NULL, NULL, 0); -+ -+ return EFI_EXIT(EFI_SUCCESS); -+} -+ -+struct efi_simple_file_system_protocol * -+efi_simple_file_system(struct blk_desc *desc, int part, -+ struct efi_device_path *dp) -+{ -+ struct file_system *fs; -+ -+ fs = calloc(1, sizeof(*fs)); -+ fs->base.rev = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; -+ fs->base.open_volume = efi_open_volume; -+ fs->desc = desc; -+ fs->part = part; -+ fs->dp = dp; -+ -+ return &fs->base; -+} -diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c -index f961407f50..469acae082 100644 ---- a/lib/efi_loader/efi_image_loader.c -+++ b/lib/efi_loader/efi_image_loader.c -@@ -17,6 +17,9 @@ DECLARE_GLOBAL_DATA_PTR; - - const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID; - const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID; -+const efi_guid_t efi_simple_file_system_protocol_guid = -+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; -+const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID; - - static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, - unsigned long rel_size, void *efi_reloc) - -From patchwork Wed Sep 13 22:05:35 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,12/21] efi_loader: support load_image() from a file-path -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813656 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-13-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:35 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Previously we only supported the case when the EFI application loaded -the image into memory for us. But fallback.efi does not do this. - -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_boottime.c | 85 +++++++++++++++++++++++++++++++++++-------- - 1 file changed, 70 insertions(+), 15 deletions(-) - -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index 837e61d8fe..ec40f41bcb 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -762,6 +762,47 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob - list_add_tail(&obj->link, &efi_obj_list); - } - -+static efi_status_t load_image_from_path(struct efi_device_path *file_path, -+ void **buffer) -+{ -+ struct efi_file_info *info = NULL; -+ struct efi_file_handle *f; -+ static efi_status_t ret; -+ uint64_t bs; -+ -+ f = efi_file_from_path(file_path); -+ if (!f) -+ return EFI_DEVICE_ERROR; -+ -+ bs = 0; -+ EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, -+ &bs, info)); -+ if (ret == EFI_BUFFER_TOO_SMALL) { -+ info = malloc(bs); -+ EFI_CALL(ret = f->getinfo(f, (efi_guid_t *)&efi_file_info_guid, -+ &bs, info)); -+ } -+ if (ret != EFI_SUCCESS) -+ goto error; -+ -+ ret = efi_allocate_pool(EFI_LOADER_DATA, info->file_size, buffer); -+ if (ret) -+ goto error; -+ -+ EFI_CALL(ret = f->read(f, &info->file_size, *buffer)); -+ -+error: -+ free(info); -+ EFI_CALL(f->close(f)); -+ -+ if (ret != EFI_SUCCESS) { -+ efi_free_pool(*buffer); -+ *buffer = NULL; -+ } -+ -+ return ret; -+} -+ - static efi_status_t EFIAPI efi_load_image(bool boot_policy, - efi_handle_t parent_image, - struct efi_device_path *file_path, -@@ -769,25 +810,40 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, - unsigned long source_size, - efi_handle_t *image_handle) - { -- static struct efi_object loaded_image_info_obj = { -- .protocols = { -- { -- .guid = &efi_guid_loaded_image, -- }, -- }, -- }; - struct efi_loaded_image *info; - struct efi_object *obj; - - EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image, - file_path, source_buffer, source_size, image_handle); -- info = malloc(sizeof(*info)); -- loaded_image_info_obj.protocols[0].protocol_interface = info; -- obj = malloc(sizeof(loaded_image_info_obj)); -- memset(info, 0, sizeof(*info)); -- memcpy(obj, &loaded_image_info_obj, sizeof(loaded_image_info_obj)); -- obj->handle = info; -- info->file_path = file_path; -+ -+ info = calloc(1, sizeof(*info)); -+ obj = calloc(1, sizeof(*obj)); -+ -+ if (!source_buffer) { -+ struct efi_device_path *dp, *fp; -+ efi_status_t ret; -+ -+ ret = load_image_from_path(file_path, &source_buffer); -+ if (ret != EFI_SUCCESS) { -+ free(info); -+ free(obj); -+ return EFI_EXIT(ret); -+ } -+ -+ /* -+ * split file_path which contains both the device and -+ * file parts: -+ */ -+ efi_dp_split_file_path(file_path, &dp, &fp); -+ -+ efi_setup_loaded_image(info, obj, dp, fp); -+ } else { -+ /* In this case, file_path is the "device" path, ie. -+ * something like a HARDWARE_DEVICE:MEMORY_MAPPED -+ */ -+ efi_setup_loaded_image(info, obj, file_path, NULL); -+ } -+ - info->reserved = efi_load_pe(source_buffer, info); - if (!info->reserved) { - free(info); -@@ -796,7 +852,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, - } - - *image_handle = info; -- list_add_tail(&obj->link, &efi_obj_list); - - return EFI_EXIT(EFI_SUCCESS); - } - -From patchwork Wed Sep 13 22:05:36 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v3, - 13/21] efi_loader: make pool allocations cacheline aligned -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813657 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-14-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:36 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -This avoids printf() spam about file reads (such as loading an image) -into unaligned buffers (and the associated memcpy()). And generally -seems like a good idea. - -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_memory.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c -index 9e079f1fa3..1f0b9d0449 100644 ---- a/lib/efi_loader/efi_memory.c -+++ b/lib/efi_loader/efi_memory.c -@@ -43,7 +43,7 @@ void *efi_bounce_buffer; - */ - struct efi_pool_allocation { - u64 num_pages; -- char data[]; -+ char data[] __attribute__((aligned(ARCH_DMA_MINALIGN))); - }; - - /* -@@ -356,7 +356,8 @@ efi_status_t efi_allocate_pool(int pool_type, unsigned long size, - { - efi_status_t r; - efi_physical_addr_t t; -- u64 num_pages = (size + sizeof(u64) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; -+ u64 num_pages = (size + sizeof(struct efi_pool_allocation) + -+ EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; - - if (size == 0) { - *buffer = NULL; - -From patchwork Wed Sep 13 22:05:37 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,14/21] efi_loader: efi variable support -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813643 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-15-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:37 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Add EFI variable support, mapping to u-boot environment variables. -Variables are pretty important for setting up boot order, among other -things. If the board supports saveenv, then it will be called in -ExitBootServices() to persist variables set by the efi payload. (For -example, fallback.efi configuring BootOrder and BootXXXX load-option -variables.) - -Variables are *not* currently exposed at runtime, post ExitBootServices. -On boards without a dedicated device for storage, which the loaded OS -is not trying to also use, this is rather tricky. One idea, at least -for boards that can persist RAM across reboot, is to keep a "journal" -of modified variables in RAM, and then turn halt into a reboot into -u-boot, plus store variables, plus halt. Whatever the solution, it -likely involves some per-board support. - -Mapping between EFI variables and u-boot variables: - - efi_$guid_$varname = {attributes}(type)value - -For example: - - efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported= - "{ro,boot,run}(blob)0000000000000000" - efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder= - "(blob)00010000" - -The attributes are a comma separated list of these possible -attributes: - - + ro - read-only - + boot - boot-services access - + run - runtime access - -NOTE: with current implementation, no variables are available after -ExitBootServices, and all are persisted (if possible). - -If not specified, the attributes default to "{boot}". - -The required type is one of: - - + utf8 - raw utf8 string - + blob - arbitrary length hex string - -Signed-off-by: Rob Clark ---- - cmd/bootefi.c | 4 + - include/efi.h | 19 +++ - include/efi_loader.h | 10 ++ - lib/efi_loader/Makefile | 2 +- - lib/efi_loader/efi_boottime.c | 6 + - lib/efi_loader/efi_runtime.c | 17 ++- - lib/efi_loader/efi_variable.c | 335 ++++++++++++++++++++++++++++++++++++++++++ - 7 files changed, 388 insertions(+), 5 deletions(-) - create mode 100644 lib/efi_loader/efi_variable.c - -diff --git a/cmd/bootefi.c b/cmd/bootefi.c -index 0980088668..d3ae33e25b 100644 ---- a/cmd/bootefi.c -+++ b/cmd/bootefi.c -@@ -181,6 +181,10 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt, - goto exit; - } - -+ /* we don't support much: */ -+ env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported", -+ "{ro,boot}(blob)0000000000000000"); -+ - /* Call our payload! */ - debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); - -diff --git a/include/efi.h b/include/efi.h -index ddd2b96417..04e83220b4 100644 ---- a/include/efi.h -+++ b/include/efi.h -@@ -324,6 +324,25 @@ extern char image_base[]; - /* Start and end of U-Boot image (for payload) */ - extern char _binary_u_boot_bin_start[], _binary_u_boot_bin_end[]; - -+/* -+ * Variable Attributes -+ */ -+#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 -+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 -+#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 -+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 -+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 -+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 -+#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 -+ -+#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ -+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \ -+ EFI_VARIABLE_RUNTIME_ACCESS | \ -+ EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ -+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ -+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ -+ EFI_VARIABLE_APPEND_WRITE) -+ - /** - * efi_get_sys_table() - Get access to the main EFI system table - * -diff --git a/include/efi_loader.h b/include/efi_loader.h -index b0c1e8fb78..9eee62dc9c 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -277,6 +277,16 @@ efi_status_t __efi_runtime EFIAPI efi_get_time( - struct efi_time_cap *capabilities); - void efi_get_time_init(void); - -+efi_status_t EFIAPI efi_get_variable(s16 *variable_name, -+ efi_guid_t *vendor, u32 *attributes, -+ unsigned long *data_size, void *data); -+efi_status_t EFIAPI efi_get_next_variable( -+ unsigned long *variable_name_size, -+ s16 *variable_name, efi_guid_t *vendor); -+efi_status_t EFIAPI efi_set_variable(s16 *variable_name, -+ efi_guid_t *vendor, u32 attributes, -+ unsigned long data_size, void *data); -+ - #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */ - - /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ -diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile -index cce92cfeb5..f58cb13337 100644 ---- a/lib/efi_loader/Makefile -+++ b/lib/efi_loader/Makefile -@@ -16,7 +16,7 @@ always := $(efiprogs-y) - obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o - obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o - obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o --obj-y += efi_file.o -+obj-y += efi_file.o efi_variable.o - obj-$(CONFIG_LCD) += efi_gop.o - obj-$(CONFIG_DM_VIDEO) += efi_gop.o - obj-$(CONFIG_PARTITIONS) += efi_disk.o -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index ec40f41bcb..c406ff82ff 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -942,6 +943,11 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, - { - EFI_ENTRY("%p, %ld", image_handle, map_key); - -+#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE) -+ /* save any EFI variables that have been written: */ -+ env_save(); -+#endif -+ - board_quiesce_devices(); - - /* Fix up caches for EFI payloads if necessary */ -diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c -index ad7f3754bd..2f95c766ac 100644 ---- a/lib/efi_loader/efi_runtime.c -+++ b/lib/efi_loader/efi_runtime.c -@@ -184,7 +184,16 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { - /* Clean up system table */ - .ptr = &systab.boottime, - .patchto = NULL, -- }, -+ }, { -+ .ptr = &efi_runtime_services.get_variable, -+ .patchto = &efi_device_error, -+ }, { -+ .ptr = &efi_runtime_services.get_next_variable, -+ .patchto = &efi_device_error, -+ }, { -+ .ptr = &efi_runtime_services.set_variable, -+ .patchto = &efi_device_error, -+ } - }; - - static bool efi_runtime_tobedetached(void *p) -@@ -382,9 +391,9 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { - .set_wakeup_time = (void *)&efi_unimplemented, - .set_virtual_address_map = &efi_set_virtual_address_map, - .convert_pointer = (void *)&efi_invalid_parameter, -- .get_variable = (void *)&efi_device_error, -- .get_next_variable = (void *)&efi_device_error, -- .set_variable = (void *)&efi_device_error, -+ .get_variable = efi_get_variable, -+ .get_next_variable = efi_get_next_variable, -+ .set_variable = efi_set_variable, - .get_next_high_mono_count = (void *)&efi_device_error, - .reset_system = &efi_reset_system_boottime, - }; -diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c -new file mode 100644 -index 0000000000..5569b3d3f0 ---- /dev/null -+++ b/lib/efi_loader/efi_variable.c -@@ -0,0 +1,335 @@ -+/* -+ * EFI utils -+ * -+ * Copyright (c) 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+ -+#define READ_ONLY BIT(31) -+ -+/* -+ * Mapping between EFI variables and u-boot variables: -+ * -+ * efi_$guid_$varname = {attributes}(type)value -+ * -+ * For example: -+ * -+ * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported= -+ * "{ro,boot,run}(blob)0000000000000000" -+ * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder= -+ * "(blob)00010000" -+ * -+ * The attributes are a comma separated list of these possible -+ * attributes: -+ * -+ * + ro - read-only -+ * + boot - boot-services access -+ * + run - runtime access -+ * -+ * NOTE: with current implementation, no variables are available after -+ * ExitBootServices, and all are persisted (if possible). -+ * -+ * If not specified, the attributes default to "{boot}". -+ * -+ * The required type is one of: -+ * -+ * + utf8 - raw utf8 string -+ * + blob - arbitrary length hex string -+ * -+ * Maybe a utf16 type would be useful to for a string value to be auto -+ * converted to utf16? -+ */ -+ -+#define MAX_VAR_NAME 31 -+#define MAX_NATIVE_VAR_NAME \ -+ (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx_") + \ -+ (MAX_VAR_NAME * MAX_UTF8_PER_UTF16)) -+ -+static int hex(unsigned char ch) -+{ -+ if (ch >= 'a' && ch <= 'f') -+ return ch-'a'+10; -+ if (ch >= '0' && ch <= '9') -+ return ch-'0'; -+ if (ch >= 'A' && ch <= 'F') -+ return ch-'A'+10; -+ return -1; -+} -+ -+static const char *hex2mem(u8 *mem, const char *hexstr, int count) -+{ -+ memset(mem, 0, count/2); -+ -+ do { -+ int nibble; -+ -+ *mem = 0; -+ -+ if (!count || !*hexstr) -+ break; -+ -+ nibble = hex(*hexstr); -+ if (nibble < 0) -+ break; -+ -+ *mem = nibble; -+ count--; -+ hexstr++; -+ -+ if (!count || !*hexstr) -+ break; -+ -+ nibble = hex(*hexstr); -+ if (nibble < 0) -+ break; -+ -+ *mem = (*mem << 4) | nibble; -+ count--; -+ hexstr++; -+ mem++; -+ -+ } while (1); -+ -+ if (*hexstr) -+ return hexstr; -+ -+ return NULL; -+} -+ -+static char *mem2hex(char *hexstr, const u8 *mem, int count) -+{ -+ static const char hexchars[] = "0123456789abcdef"; -+ -+ while (count-- > 0) { -+ u8 ch = *mem++; -+ *hexstr++ = hexchars[ch >> 4]; -+ *hexstr++ = hexchars[ch & 0xf]; -+ } -+ -+ return hexstr; -+} -+ -+static efi_status_t efi_to_native(char *native, s16 *variable_name, -+ efi_guid_t *vendor) -+{ -+ size_t len; -+ -+ len = utf16_strlen((u16 *)variable_name); -+ if (len >= MAX_VAR_NAME) -+ return EFI_DEVICE_ERROR; -+ -+ native += sprintf(native, "efi_%pUl_", vendor); -+ native = (char *)utf16_to_utf8((u8 *)native, (u16 *)variable_name, len); -+ *native = '\0'; -+ -+ return EFI_SUCCESS; -+} -+ -+static const char *prefix(const char *str, const char *prefix) -+{ -+ size_t n = strlen(prefix); -+ if (!strncmp(prefix, str, n)) -+ return str + n; -+ return NULL; -+} -+ -+/* parse attributes part of variable value, if present: */ -+static const char *parse_attr(const char *str, u32 *attrp) -+{ -+ u32 attr = 0; -+ char sep = '{'; -+ -+ if (*str != '{') { -+ *attrp = EFI_VARIABLE_BOOTSERVICE_ACCESS; -+ return str; -+ } -+ -+ while (*str == sep) { -+ const char *s; -+ -+ str++; -+ -+ if ((s = prefix(str, "ro"))) { -+ attr |= READ_ONLY; -+ } else if ((s = prefix(str, "boot"))) { -+ attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS; -+ } else if ((s = prefix(str, "run"))) { -+ attr |= EFI_VARIABLE_RUNTIME_ACCESS; -+ } else { -+ printf("invalid attribute: %s\n", str); -+ break; -+ } -+ -+ str = s; -+ sep = ','; -+ } -+ -+ str++; -+ -+ *attrp = attr; -+ -+ return str; -+} -+ -+/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.29 */ -+efi_status_t EFIAPI efi_get_variable(s16 *variable_name, -+ efi_guid_t *vendor, u32 *attributes, -+ unsigned long *data_size, void *data) -+{ -+ char native_name[MAX_NATIVE_VAR_NAME + 1]; -+ efi_status_t ret; -+ unsigned long in_size; -+ const char *val, *s; -+ u32 attr; -+ -+ EFI_ENTRY("%p %p %p %p %p", variable_name, vendor, attributes, -+ data_size, data); -+ -+ if (!variable_name || !vendor || !data_size) -+ return EFI_EXIT(EFI_INVALID_PARAMETER); -+ -+ ret = efi_to_native(native_name, variable_name, vendor); -+ if (ret) -+ return EFI_EXIT(ret); -+ -+ debug("%s: get '%s'\n", __func__, native_name); -+ -+ val = env_get(native_name); -+ if (!val) -+ return EFI_EXIT(EFI_NOT_FOUND); -+ -+ val = parse_attr(val, &attr); -+ -+ in_size = *data_size; -+ -+ if ((s = prefix(val, "(blob)"))) { -+ unsigned len = strlen(s); -+ -+ /* two characters per byte: */ -+ len = DIV_ROUND_UP(len, 2); -+ *data_size = len; -+ -+ if (in_size < len) -+ return EFI_EXIT(EFI_BUFFER_TOO_SMALL); -+ -+ if (!data) -+ return EFI_EXIT(EFI_INVALID_PARAMETER); -+ -+ if (hex2mem(data, s, len * 2)) -+ return EFI_EXIT(EFI_DEVICE_ERROR); -+ -+ debug("%s: got value: \"%s\"\n", __func__, s); -+ } else if ((s = prefix(val, "(utf8)"))) { -+ unsigned len = strlen(s) + 1; -+ -+ *data_size = len; -+ -+ if (in_size < len) -+ return EFI_EXIT(EFI_BUFFER_TOO_SMALL); -+ -+ if (!data) -+ return EFI_EXIT(EFI_INVALID_PARAMETER); -+ -+ memcpy(data, s, len); -+ ((char *)data)[len] = '\0'; -+ -+ debug("%s: got value: \"%s\"\n", __func__, (char *)data); -+ } else { -+ debug("%s: invalid value: '%s'\n", __func__, val); -+ return EFI_EXIT(EFI_DEVICE_ERROR); -+ } -+ -+ if (attributes) -+ *attributes = attr & EFI_VARIABLE_MASK; -+ -+ return EFI_EXIT(EFI_SUCCESS); -+} -+ -+/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 */ -+efi_status_t EFIAPI efi_get_next_variable( -+ unsigned long *variable_name_size, -+ s16 *variable_name, efi_guid_t *vendor) -+{ -+ EFI_ENTRY("%p %p %p", variable_name_size, variable_name, vendor); -+ -+ return EFI_EXIT(EFI_DEVICE_ERROR); -+} -+ -+/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.29 */ -+efi_status_t EFIAPI efi_set_variable(s16 *variable_name, -+ efi_guid_t *vendor, u32 attributes, -+ unsigned long data_size, void *data) -+{ -+ char native_name[MAX_NATIVE_VAR_NAME + 1]; -+ efi_status_t ret = EFI_SUCCESS; -+ char *val, *s; -+ u32 attr; -+ -+ EFI_ENTRY("%p %p %x %lu %p", variable_name, vendor, attributes, -+ data_size, data); -+ -+ if (!variable_name || !vendor) -+ return EFI_EXIT(EFI_INVALID_PARAMETER); -+ -+ ret = efi_to_native(native_name, variable_name, vendor); -+ if (ret) -+ return EFI_EXIT(ret); -+ -+#define ACCESS_ATTR (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS) -+ -+ if ((data_size == 0) || !(attributes & ACCESS_ATTR)) { -+ /* delete the variable: */ -+ env_set(native_name, NULL); -+ return EFI_EXIT(EFI_SUCCESS); -+ } -+ -+ val = env_get(native_name); -+ if (val) { -+ parse_attr(val, &attr); -+ -+ if (attr & READ_ONLY) -+ return EFI_EXIT(EFI_WRITE_PROTECTED); -+ } -+ -+ val = malloc(2 * data_size + strlen("{ro,run,boot}(blob)") + 1); -+ if (!val) -+ return EFI_EXIT(EFI_OUT_OF_RESOURCES); -+ -+ s = val; -+ -+ /* store attributes: */ -+ attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); -+ s += sprintf(s, "{"); -+ while (attributes) { -+ u32 attr = 1 << (ffs(attributes) - 1); -+ -+ if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) -+ s += sprintf(s, "boot"); -+ else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) -+ s += sprintf(s, "run"); -+ -+ attributes &= ~attr; -+ if (attributes) -+ s += sprintf(s, ","); -+ } -+ s += sprintf(s, "}"); -+ -+ /* store payload: */ -+ s += sprintf(s, "(blob)"); -+ s = mem2hex(s, data, data_size); -+ *s = '\0'; -+ -+ debug("%s: setting: %s=%s\n", __func__, native_name, val); -+ -+ if (env_set(native_name, val)) -+ ret = EFI_DEVICE_ERROR; -+ -+ free(val); -+ -+ return EFI_EXIT(ret); -+} - -From patchwork Wed Sep 13 22:05:38 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,15/21] efi_loader: add bootmgr -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813660 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-16-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:38 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Similar to a "real" UEFI implementation, the bootmgr looks at the -BootOrder and BootXXXX variables to try to find an EFI payload to load -and boot. This is added as a sub-command of bootefi. - -The idea is that the distro bootcmd would first try loading a payload -via the bootmgr, and then if that fails (ie. first boot or corrupted -EFI variables) it would fallback to loading bootaa64.efi. (Which -would then load fallback.efi which would look for \EFI\*\boot.csv and -populate BootOrder and BootXXXX based on what it found.) - -Signed-off-by: Rob Clark ---- - cmd/bootefi.c | 48 +++++++++- - include/config_distro_bootcmd.h | 5 ++ - include/efi_api.h | 4 + - include/efi_loader.h | 6 ++ - lib/efi_loader/Makefile | 2 +- - lib/efi_loader/efi_bootmgr.c | 180 ++++++++++++++++++++++++++++++++++++++ - lib/efi_loader/efi_boottime.c | 6 +- - lib/efi_loader/efi_image_loader.c | 1 + - 8 files changed, 246 insertions(+), 6 deletions(-) - create mode 100644 lib/efi_loader/efi_bootmgr.c - -diff --git a/cmd/bootefi.c b/cmd/bootefi.c -index d3ae33e25b..fcd8dbafc1 100644 ---- a/cmd/bootefi.c -+++ b/cmd/bootefi.c -@@ -219,6 +219,36 @@ exit: - return ret; - } - -+static int do_bootefi_bootmgr_exec(unsigned long fdt_addr) -+{ -+ struct efi_device_path *device_path, *file_path; -+ void *addr; -+ efi_status_t r; -+ -+ /* Initialize and populate EFI object list */ -+ if (!efi_obj_list_initalized) -+ efi_init_obj_list(); -+ -+ /* -+ * gd lives in a fixed register which may get clobbered while we execute -+ * the payload. So save it here and restore it on every callback entry -+ */ -+ efi_save_gd(); -+ -+ addr = efi_bootmgr_load(&device_path, &file_path); -+ if (!addr) -+ return 1; -+ -+ printf("## Starting EFI application at %p ...\n", addr); -+ r = do_bootefi_exec(addr, (void *)fdt_addr, device_path, file_path); -+ printf("## Application terminated, r = %lu\n", -+ r & ~EFI_ERROR_MASK); -+ -+ if (r != EFI_SUCCESS) -+ return 1; -+ -+ return 0; -+} - - /* Interpreter command to boot an arbitrary EFI image from memory */ - static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -@@ -237,7 +267,14 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) - memcpy((char *)addr, __efi_hello_world_begin, size); - } else - #endif -- { -+ if (!strcmp(argv[1], "bootmgr")) { -+ unsigned long fdt_addr = 0; -+ -+ if (argc > 2) -+ fdt_addr = simple_strtoul(argv[2], NULL, 16); -+ -+ return do_bootefi_bootmgr_exec(fdt_addr); -+ } else { - saddr = argv[1]; - - addr = simple_strtoul(saddr, NULL, 16); -@@ -270,7 +307,11 @@ static char bootefi_help_text[] = - "hello\n" - " - boot a sample Hello World application stored within U-Boot" - #endif -- ; -+ "bootmgr [fdt addr]\n" -+ " - load and boot EFI payload based on BootOrder/BootXXXX variables.\n" -+ "\n" -+ " If specified, the device tree located at gets\n" -+ " exposed as EFI configuration table.\n"; - #endif - - U_BOOT_CMD( -@@ -308,6 +349,9 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path) - #endif - } - -+ if (!path) -+ return; -+ - if (strcmp(dev, "Net")) { - /* Add leading / to fs paths, because they're absolute */ - snprintf(filename, sizeof(filename), "/%s", path); -diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h -index 9ed6b9892c..e0d0034ed3 100644 ---- a/include/config_distro_bootcmd.h -+++ b/include/config_distro_bootcmd.h -@@ -112,6 +112,11 @@ - - #define BOOTENV_SHARED_EFI \ - "boot_efi_binary=" \ -+ "if fdt addr ${fdt_addr_r}; then " \ -+ "bootefi bootmgr ${fdt_addr_r};" \ -+ "else " \ -+ "bootefi bootmgr ${fdtcontroladdr};" \ -+ "fi;" \ - "load ${devtype} ${devnum}:${distro_bootpart} " \ - "${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \ - "if fdt addr ${fdt_addr_r}; then " \ -diff --git a/include/efi_api.h b/include/efi_api.h -index 1aae96355f..d0aefa8221 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -211,6 +211,10 @@ struct efi_runtime_services { - EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - -+#define EFI_GLOBAL_VARIABLE_GUID \ -+ EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, \ -+ 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c) -+ - #define LOADED_IMAGE_PROTOCOL_GUID \ - EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, \ - 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) -diff --git a/include/efi_loader.h b/include/efi_loader.h -index 9eee62dc9c..adc0bcf609 100644 ---- a/include/efi_loader.h -+++ b/include/efi_loader.h -@@ -61,6 +61,7 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text; - - uint16_t *efi_dp_str(struct efi_device_path *dp); - -+extern const efi_guid_t efi_global_variable_guid; - extern const efi_guid_t efi_guid_console_control; - extern const efi_guid_t efi_guid_device_path; - extern const efi_guid_t efi_guid_loaded_image; -@@ -209,6 +210,8 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table - void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, - struct efi_device_path *device_path, - struct efi_device_path *file_path); -+efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, -+ void **buffer); - - #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER - extern void *efi_bounce_buffer; -@@ -287,6 +290,9 @@ efi_status_t EFIAPI efi_set_variable(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data); - -+void *efi_bootmgr_load(struct efi_device_path **device_path, -+ struct efi_device_path **file_path); -+ - #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */ - - /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ -diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile -index f58cb13337..930c0e218e 100644 ---- a/lib/efi_loader/Makefile -+++ b/lib/efi_loader/Makefile -@@ -16,7 +16,7 @@ always := $(efiprogs-y) - obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o - obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o - obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o --obj-y += efi_file.o efi_variable.o -+obj-y += efi_file.o efi_variable.o efi_bootmgr.o - obj-$(CONFIG_LCD) += efi_gop.o - obj-$(CONFIG_DM_VIDEO) += efi_gop.o - obj-$(CONFIG_PARTITIONS) += efi_disk.o -diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c -new file mode 100644 -index 0000000000..857d88a879 ---- /dev/null -+++ b/lib/efi_loader/efi_bootmgr.c -@@ -0,0 +1,180 @@ -+/* -+ * EFI utils -+ * -+ * Copyright (c) 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static const struct efi_boot_services *bs; -+static const struct efi_runtime_services *rs; -+ -+#define LOAD_OPTION_ACTIVE 0x00000001 -+#define LOAD_OPTION_FORCE_RECONNECT 0x00000002 -+#define LOAD_OPTION_HIDDEN 0x00000008 -+ -+/* -+ * bootmgr implements the logic of trying to find a payload to boot -+ * based on the BootOrder + BootXXXX variables, and then loading it. -+ * -+ * TODO detecting a special key held (f9?) and displaying a boot menu -+ * like you would get on a PC would be clever. -+ * -+ * TODO if we had a way to write and persist variables after the OS -+ * has started, we'd also want to check OsIndications to see if we -+ * should do normal or recovery boot. -+ */ -+ -+ -+/* -+ * See section 3.1.3 in the v2.7 UEFI spec for more details on -+ * the layout of EFI_LOAD_OPTION. In short it is: -+ * -+ * typedef struct _EFI_LOAD_OPTION { -+ * UINT32 Attributes; -+ * UINT16 FilePathListLength; -+ * // CHAR16 Description[]; <-- variable length, NULL terminated -+ * // EFI_DEVICE_PATH_PROTOCOL FilePathList[]; <-- FilePathListLength bytes -+ * // UINT8 OptionalData[]; -+ * } EFI_LOAD_OPTION; -+ */ -+struct load_option { -+ u32 attributes; -+ u16 file_path_length; -+ u16 *label; -+ struct efi_device_path *file_path; -+ u8 *optional_data; -+}; -+ -+/* parse an EFI_LOAD_OPTION, as described above */ -+static void parse_load_option(struct load_option *lo, void *ptr) -+{ -+ lo->attributes = *(u32 *)ptr; -+ ptr += sizeof(u32); -+ -+ lo->file_path_length = *(u16 *)ptr; -+ ptr += sizeof(u16); -+ -+ lo->label = ptr; -+ ptr += (utf16_strlen(lo->label) + 1) * 2; -+ -+ lo->file_path = ptr; -+ ptr += lo->file_path_length; -+ -+ lo->optional_data = ptr; -+} -+ -+/* free() the result */ -+static void *get_var(u16 *name, const efi_guid_t *vendor, -+ unsigned long *size) -+{ -+ efi_guid_t *v = (efi_guid_t *)vendor; -+ efi_status_t ret; -+ void *buf = NULL; -+ -+ *size = 0; -+ EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); -+ if (ret == EFI_BUFFER_TOO_SMALL) { -+ buf = malloc(*size); -+ EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); -+ } -+ -+ if (ret != EFI_SUCCESS) { -+ free(buf); -+ *size = 0; -+ return NULL; -+ } -+ -+ return buf; -+} -+ -+/* -+ * Attempt to load load-option number 'n', returning device_path and file_path -+ * if successful. This checks that the EFI_LOAD_OPTION is active (enabled) -+ * and that the specified file to boot exists. -+ */ -+static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, -+ struct efi_device_path **file_path) -+{ -+ struct load_option lo; -+ u16 varname[] = L"Boot0000"; -+ u16 hexmap[] = L"0123456789ABCDEF"; -+ void *load_option, *image = NULL; -+ unsigned long size; -+ -+ varname[4] = hexmap[(n & 0xf000) >> 12]; -+ varname[5] = hexmap[(n & 0x0f00) >> 8]; -+ varname[6] = hexmap[(n & 0x00f0) >> 4]; -+ varname[7] = hexmap[(n & 0x000f) >> 0]; -+ -+ load_option = get_var(varname, &efi_global_variable_guid, &size); -+ if (!load_option) -+ return NULL; -+ -+ parse_load_option(&lo, load_option); -+ -+ if (lo.attributes & LOAD_OPTION_ACTIVE) { -+ efi_status_t ret; -+ u16 *str = NULL; -+ -+ debug("%s: trying to load \"%ls\" from: %ls\n", __func__, -+ lo.label, (str = efi_dp_str(lo.file_path))); -+ efi_free_pool(str); -+ -+ ret = efi_load_image_from_path(lo.file_path, &image); -+ -+ if (ret != EFI_SUCCESS) -+ goto error; -+ -+ printf("Booting: %ls\n", lo.label); -+ efi_dp_split_file_path(lo.file_path, device_path, file_path); -+ } -+ -+error: -+ free(load_option); -+ -+ return image; -+} -+ -+/* -+ * Attempt to load, in the order specified by BootOrder EFI variable, the -+ * available load-options, finding and returning the first one that can -+ * be loaded successfully. -+ */ -+void *efi_bootmgr_load(struct efi_device_path **device_path, -+ struct efi_device_path **file_path) -+{ -+ uint16_t *bootorder; -+ unsigned long size; -+ void *image = NULL; -+ int i, num; -+ -+ __efi_entry_check(); -+ -+ bs = systab.boottime; -+ rs = systab.runtime; -+ -+ bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); -+ if (!bootorder) -+ goto error; -+ -+ num = size / sizeof(uint16_t); -+ for (i = 0; i < num; i++) { -+ debug("%s: trying to load Boot%04X\n", __func__, bootorder[i]); -+ image = try_load_entry(bootorder[i], device_path, file_path); -+ if (image) -+ break; -+ } -+ -+ free(bootorder); -+ -+error: -+ __efi_exit_check(); -+ -+ return image; -+} -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index c406ff82ff..cea242cd49 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -763,8 +763,8 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob - list_add_tail(&obj->link, &efi_obj_list); - } - --static efi_status_t load_image_from_path(struct efi_device_path *file_path, -- void **buffer) -+efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, -+ void **buffer) - { - struct efi_file_info *info = NULL; - struct efi_file_handle *f; -@@ -824,7 +824,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, - struct efi_device_path *dp, *fp; - efi_status_t ret; - -- ret = load_image_from_path(file_path, &source_buffer); -+ ret = efi_load_image_from_path(file_path, &source_buffer); - if (ret != EFI_SUCCESS) { - free(info); - free(obj); -diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c -index 469acae082..242e6a504b 100644 ---- a/lib/efi_loader/efi_image_loader.c -+++ b/lib/efi_loader/efi_image_loader.c -@@ -15,6 +15,7 @@ - - DECLARE_GLOBAL_DATA_PTR; - -+const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID; - const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID; - const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID; - const efi_guid_t efi_simple_file_system_protocol_guid = - -From patchwork Wed Sep 13 22:05:39 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,16/21] efi_loader: file_path should be variable length -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813647 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-17-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt , Peter Jones -Date: Wed, 13 Sep 2017 18:05:39 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Signed-off-by: Rob Clark ---- - include/efi_api.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/efi_api.h b/include/efi_api.h -index d0aefa8221..604c5b7ec4 100644 ---- a/include/efi_api.h -+++ b/include/efi_api.h -@@ -373,7 +373,7 @@ struct efi_device_path_cdrom_path { - - struct efi_device_path_file_path { - struct efi_device_path dp; -- u16 str[32]; -+ u16 str[]; - } __packed; - - #define BLOCK_IO_GUID \ - -From patchwork Wed Sep 13 22:05:40 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot, v3, - 17/21] efi_loader: set loaded image code/data type properly -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813655 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-18-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:40 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -These should be set according to the image type. Shell.efi and SCT.efi -use these fields to determine what sort of image they are loading. - -Signed-off-by: Rob Clark ---- - include/pe.h | 6 ++++++ - lib/efi_loader/efi_image_loader.c | 22 ++++++++++++++++++++++ - 2 files changed, 28 insertions(+) - -diff --git a/include/pe.h b/include/pe.h -index deb35a0ea4..4ef3e92efa 100644 ---- a/include/pe.h -+++ b/include/pe.h -@@ -62,6 +62,12 @@ typedef struct _IMAGE_DATA_DIRECTORY { - - #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - -+/* PE32+ Subsystem type for EFI images */ -+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 -+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 -+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 -+#define IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 -+ - typedef struct _IMAGE_OPTIONAL_HEADER64 { - uint16_t Magic; /* 0x20b */ - uint8_t MajorLinkerVersion; -diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c -index 242e6a504b..af29cc4f04 100644 ---- a/lib/efi_loader/efi_image_loader.c -+++ b/lib/efi_loader/efi_image_loader.c -@@ -94,6 +94,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) - unsigned long virt_size = 0; - bool can_run_nt64 = true; - bool can_run_nt32 = true; -+ uint16_t image_type; - - #if defined(CONFIG_ARM64) - can_run_nt32 = false; -@@ -139,6 +140,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) - entry = efi_reloc + opt->AddressOfEntryPoint; - rel_size = opt->DataDirectory[rel_idx].Size; - rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; -+ image_type = opt->Subsystem; - } else if (can_run_nt32 && - (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) { - IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader; -@@ -152,12 +154,32 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) - entry = efi_reloc + opt->AddressOfEntryPoint; - rel_size = opt->DataDirectory[rel_idx].Size; - rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress; -+ image_type = opt->Subsystem; - } else { - printf("%s: Invalid optional header magic %x\n", __func__, - nt->OptionalHeader.Magic); - return NULL; - } - -+ switch (image_type) { -+ case IMAGE_SUBSYSTEM_EFI_APPLICATION: -+ loaded_image_info->image_code_type = EFI_LOADER_CODE; -+ loaded_image_info->image_data_type = EFI_LOADER_DATA; -+ break; -+ case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: -+ loaded_image_info->image_code_type = EFI_BOOT_SERVICES_CODE; -+ loaded_image_info->image_data_type = EFI_BOOT_SERVICES_DATA; -+ break; -+ case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: -+ case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER: -+ loaded_image_info->image_code_type = EFI_RUNTIME_SERVICES_CODE; -+ loaded_image_info->image_data_type = EFI_RUNTIME_SERVICES_DATA; -+ break; -+ default: -+ printf("%s: invalid image type: %u\n", __func__, image_type); -+ break; -+ } -+ - /* Load sections into RAM */ - for (i = num_sections - 1; i >= 0; i--) { - IMAGE_SECTION_HEADER *sec = §ions[i]; - -From patchwork Wed Sep 13 22:05:41 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [U-Boot,v3,18/21] efi_loader: print GUIDs -X-Patchwork-Submitter: Rob Clark -X-Patchwork-Id: 813646 -X-Patchwork-Delegate: agraf@suse.de -Message-Id: <20170913220546.19560-19-robdclark@gmail.com> -To: U-Boot Mailing List -Cc: Heinrich Schuchardt -Date: Wed, 13 Sep 2017 18:05:41 -0400 -From: Rob Clark -List-Id: U-Boot discussion - -Utilize printf GUID support to print GUIDs. - -Signed-off-by: Rob Clark ---- - lib/efi_loader/efi_boottime.c | 22 +++++++++++----------- - lib/efi_loader/efi_variable.c | 6 +++--- - 2 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c -index cea242cd49..b6f32c98d9 100644 ---- a/lib/efi_loader/efi_boottime.c -+++ b/lib/efi_loader/efi_boottime.c -@@ -514,7 +514,7 @@ static efi_status_t EFIAPI efi_install_protocol_interface_ext(void **handle, - efi_guid_t *protocol, int protocol_interface_type, - void *protocol_interface) - { -- EFI_ENTRY("%p, %p, %d, %p", handle, protocol, protocol_interface_type, -+ EFI_ENTRY("%p, %pUl, %d, %p", handle, protocol, protocol_interface_type, - protocol_interface); - - return EFI_EXIT(efi_install_protocol_interface(handle, protocol, -@@ -526,7 +526,7 @@ static efi_status_t EFIAPI efi_reinstall_protocol_interface(void *handle, - efi_guid_t *protocol, void *old_interface, - void *new_interface) - { -- EFI_ENTRY("%p, %p, %p, %p", handle, protocol, old_interface, -+ EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface, - new_interface); - return EFI_EXIT(EFI_ACCESS_DENIED); - } -@@ -575,7 +575,7 @@ out: - static efi_status_t EFIAPI efi_uninstall_protocol_interface_ext(void *handle, - efi_guid_t *protocol, void *protocol_interface) - { -- EFI_ENTRY("%p, %p, %p", handle, protocol, protocol_interface); -+ EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface); - - return EFI_EXIT(efi_uninstall_protocol_interface(handle, protocol, - protocol_interface)); -@@ -585,7 +585,7 @@ static efi_status_t EFIAPI efi_register_protocol_notify(efi_guid_t *protocol, - struct efi_event *event, - void **registration) - { -- EFI_ENTRY("%p, %p, %p", protocol, event, registration); -+ EFI_ENTRY("%pUl, %p, %p", protocol, event, registration); - return EFI_EXIT(EFI_OUT_OF_RESOURCES); - } - -@@ -655,7 +655,7 @@ static efi_status_t EFIAPI efi_locate_handle_ext( - efi_guid_t *protocol, void *search_key, - unsigned long *buffer_size, efi_handle_t *buffer) - { -- EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, -+ EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key, - buffer_size, buffer); - - return EFI_EXIT(efi_locate_handle(search_type, protocol, search_key, -@@ -723,7 +723,7 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table - static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, - void *table) - { -- EFI_ENTRY("%p, %p", guid, table); -+ EFI_ENTRY("%pUl, %p", guid, table); - return EFI_EXIT(efi_install_configuration_table(guid, table)); - } - -@@ -1012,7 +1012,7 @@ static efi_status_t EFIAPI efi_close_protocol(void *handle, - void *agent_handle, - void *controller_handle) - { -- EFI_ENTRY("%p, %p, %p, %p", handle, protocol, agent_handle, -+ EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, agent_handle, - controller_handle); - return EFI_EXIT(EFI_NOT_FOUND); - } -@@ -1022,7 +1022,7 @@ static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle, - struct efi_open_protocol_info_entry **entry_buffer, - unsigned long *entry_count) - { -- EFI_ENTRY("%p, %p, %p, %p", handle, protocol, entry_buffer, -+ EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, entry_buffer, - entry_count); - return EFI_EXIT(EFI_NOT_FOUND); - } -@@ -1088,7 +1088,7 @@ static efi_status_t EFIAPI efi_locate_handle_buffer( - efi_status_t r; - unsigned long buffer_size = 0; - -- EFI_ENTRY("%d, %p, %p, %p, %p", search_type, protocol, search_key, -+ EFI_ENTRY("%d, %pUl, %p, %p, %p", search_type, protocol, search_key, - no_handles, buffer); - - if (!no_handles || !buffer) { -@@ -1120,7 +1120,7 @@ static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol, - struct list_head *lhandle; - int i; - -- EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface); -+ EFI_ENTRY("%pUl, %p, %p", protocol, registration, protocol_interface); - - if (!protocol || !protocol_interface) - return EFI_EXIT(EFI_INVALID_PARAMETER); -@@ -1228,7 +1228,7 @@ static efi_status_t EFIAPI efi_open_protocol( - int i; - efi_status_t r = EFI_INVALID_PARAMETER; - -- EFI_ENTRY("%p, %p, %p, %p, %p, 0x%x", handle, protocol, -+ EFI_ENTRY("%p, %pUl, %p, %p, %p, 0x%x", handle, protocol, - protocol_interface, agent_handle, controller_handle, - attributes); - -diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c -index 5569b3d3f0..6c177da3a6 100644 ---- a/lib/efi_loader/efi_variable.c -+++ b/lib/efi_loader/efi_variable.c -@@ -187,7 +187,7 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name, - const char *val, *s; - u32 attr; - -- EFI_ENTRY("%p %p %p %p %p", variable_name, vendor, attributes, -+ EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes, - data_size, data); - - if (!variable_name || !vendor || !data_size) -@@ -255,7 +255,7 @@ efi_status_t EFIAPI efi_get_next_variable( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor) - { -- EFI_ENTRY("%p %p %p", variable_name_size, variable_name, vendor); -+ EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor); - - return EFI_EXIT(EFI_DEVICE_ERROR); - } -@@ -270,7 +270,7 @@ efi_status_t EFIAPI efi_set_variable(s16 *variable_name, - char *val, *s; - u32 attr; - -- EFI_ENTRY("%p %p %x %lu %p", variable_name, vendor, attributes, -+ EFI_ENTRY("\"%ls\" %pUl %x %lu %p", variable_name, vendor, attributes, - data_size, data); - - if (!variable_name || !vendor) - diff --git a/uefi-improve-fat.patch b/uefi-improve-fat.patch deleted file mode 100644 index f6445cb..0000000 --- a/uefi-improve-fat.patch +++ /dev/null @@ -1,2620 +0,0 @@ -From 45449980f80169214633f2649a27c791d0104e9d Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:52 -0400 -Subject: [PATCH 34/47] fs/fat: split out helper to init fsdata -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Want to re-use this in fat dirent iterator in next patch. - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 73 +++++++++++++++++++++++++++++++++++------------------------ - include/fat.h | 1 + - 2 files changed, 44 insertions(+), 30 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index 465a6875ed..e1c0a15dc7 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -808,35 +808,17 @@ exit: - return ret; - } - --__u8 do_fat_read_at_block[MAX_CLUSTSIZE] -- __aligned(ARCH_DMA_MINALIGN); -- --int do_fat_read_at(const char *filename, loff_t pos, void *buffer, -- loff_t maxsize, int dols, int dogetsize, loff_t *size) -+static int get_fs_info(fsdata *mydata) - { -- char fnamecopy[2048]; - boot_sector bs; - volume_info volinfo; -- fsdata datablock; -- fsdata *mydata = &datablock; -- dir_entry *dentptr = NULL; -- __u16 prevcksum = 0xffff; -- char *subname = ""; -- __u32 cursect; -- int idx, isdir = 0; -- int files = 0, dirs = 0; -- int ret = -1; -- int firsttime; - __u32 root_cluster = 0; -- __u32 read_blk; -- int rootdir_size = 0; -- int buffer_blk_cnt; -- int do_read; -- __u8 *dir_ptr; -+ int ret; - -- if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) { -+ ret = read_bootsectandvi(&bs, &volinfo, &mydata->fatsize); -+ if (ret) { - debug("Error: reading boot sector\n"); -- return -1; -+ return ret; - } - - if (mydata->fatsize == 32) { -@@ -848,8 +830,7 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - - mydata->fat_sect = bs.reserved; - -- cursect = mydata->rootdir_sect -- = mydata->fat_sect + mydata->fatlength * bs.fats; -+ mydata->rootdir_sect = mydata->fat_sect + mydata->fatlength * bs.fats; - - mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0]; - mydata->clust_size = bs.cluster_size; -@@ -863,12 +844,12 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - mydata->data_begin = mydata->rootdir_sect - - (mydata->clust_size * 2); - } else { -- rootdir_size = ((bs.dir_entries[1] * (int)256 + -- bs.dir_entries[0]) * -- sizeof(dir_entry)) / -- mydata->sect_size; -+ mydata->rootdir_size = ((bs.dir_entries[1] * (int)256 + -+ bs.dir_entries[0]) * -+ sizeof(dir_entry)) / -+ mydata->sect_size; - mydata->data_begin = mydata->rootdir_sect + -- rootdir_size - -+ mydata->rootdir_size - - (mydata->clust_size * 2); - } - -@@ -893,6 +874,38 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - debug("Sector size: %d, cluster size: %d\n", mydata->sect_size, - mydata->clust_size); - -+ return 0; -+} -+ -+__u8 do_fat_read_at_block[MAX_CLUSTSIZE] -+ __aligned(ARCH_DMA_MINALIGN); -+ -+int do_fat_read_at(const char *filename, loff_t pos, void *buffer, -+ loff_t maxsize, int dols, int dogetsize, loff_t *size) -+{ -+ char fnamecopy[2048]; -+ fsdata datablock; -+ fsdata *mydata = &datablock; -+ dir_entry *dentptr = NULL; -+ __u16 prevcksum = 0xffff; -+ char *subname = ""; -+ __u32 cursect; -+ int idx, isdir = 0; -+ int files = 0, dirs = 0; -+ int ret = -1; -+ int firsttime; -+ __u32 root_cluster = 0; -+ __u32 read_blk; -+ int rootdir_size = 0; -+ int buffer_blk_cnt; -+ int do_read; -+ __u8 *dir_ptr; -+ -+ if (get_fs_info(mydata)) -+ return -1; -+ -+ cursect = mydata->rootdir_sect; -+ - /* "cwd" is always the root... */ - while (ISDIRDELIM(*filename)) - filename++; -diff --git a/include/fat.h b/include/fat.h -index 71879f01ca..b671ee8f81 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -174,6 +174,7 @@ typedef struct { - __u16 clust_size; /* Size of clusters in sectors */ - int data_begin; /* The sector of the first cluster, can be negative */ - int fatbufnum; /* Used by get_fatent, init to -1 */ -+ int rootdir_size; /* Size of root dir for non-FAT32 */ - } fsdata; - - typedef int (file_detectfs_func)(void); --- -2.13.5 - -From c6e3baa565bc3b5828cf0d67ca6429dbe5f8687c Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:53 -0400 -Subject: [PATCH 35/47] fs/fat: introduce new director iterators -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Untangle directory traversal into a simple iterator, to replace the -existing multi-purpose do_fat_read_at() + get_dentfromdir(). - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski ---- - fs/fat/fat.c | 356 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - include/fat.h | 7 ++ - 2 files changed, 360 insertions(+), 3 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index e1c0a15dc7..ee2bbe38f1 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -812,7 +812,6 @@ static int get_fs_info(fsdata *mydata) - { - boot_sector bs; - volume_info volinfo; -- __u32 root_cluster = 0; - int ret; - - ret = read_bootsectandvi(&bs, &volinfo, &mydata->fatsize); -@@ -822,7 +821,6 @@ static int get_fs_info(fsdata *mydata) - } - - if (mydata->fatsize == 32) { -- root_cluster = bs.root_cluster; - mydata->fatlength = bs.fat32_length; - } else { - mydata->fatlength = bs.fat_length; -@@ -843,6 +841,7 @@ static int get_fs_info(fsdata *mydata) - if (mydata->fatsize == 32) { - mydata->data_begin = mydata->rootdir_sect - - (mydata->clust_size * 2); -+ mydata->root_cluster = bs.root_cluster; - } else { - mydata->rootdir_size = ((bs.dir_entries[1] * (int)256 + - bs.dir_entries[0]) * -@@ -851,6 +850,9 @@ static int get_fs_info(fsdata *mydata) - mydata->data_begin = mydata->rootdir_sect + - mydata->rootdir_size - - (mydata->clust_size * 2); -+ mydata->root_cluster = (mydata->rootdir_sect - -+ mydata->data_begin) / -+ mydata->clust_size; - } - - mydata->fatbufnum = -1; -@@ -868,7 +870,7 @@ static int get_fs_info(fsdata *mydata) - mydata->fatsize, mydata->fat_sect, mydata->fatlength); - debug("Rootdir begins at cluster: %d, sector: %d, offset: %x\n" - "Data begins at: %d\n", -- root_cluster, -+ mydata->root_cluster, - mydata->rootdir_sect, - mydata->rootdir_sect * mydata->sect_size, mydata->data_begin); - debug("Sector size: %d, cluster size: %d\n", mydata->sect_size, -@@ -1245,6 +1247,354 @@ exit: - return ret; - } - -+ -+/* -+ * Directory iterator, to simplify filesystem traversal -+ * -+ * Implements an iterator pattern to traverse directory tables, -+ * transparently handling directory tables split across multiple -+ * clusters, and the difference between FAT12/FAT16 root directory -+ * (contiguous) and subdirectories + FAT32 root (chained). -+ * -+ * Rough usage: -+ * -+ * for (fat_itr_root(&itr, fsdata); fat_itr_next(&itr); ) { -+ * // to traverse down to a subdirectory pointed to by -+ * // current iterator position: -+ * fat_itr_child(&itr, &itr); -+ * } -+ * -+ * For more complete example, see fat_itr_resolve() -+ */ -+ -+typedef struct { -+ fsdata *fsdata; /* filesystem parameters */ -+ unsigned clust; /* current cluster */ -+ int last_cluster; /* set once we've read last cluster */ -+ int is_root; /* is iterator at root directory */ -+ int remaining; /* remaining dent's in current cluster */ -+ -+ /* current iterator position values: */ -+ dir_entry *dent; /* current directory entry */ -+ char l_name[VFAT_MAXLEN_BYTES]; /* long (vfat) name */ -+ char s_name[14]; /* short 8.3 name */ -+ char *name; /* l_name if there is one, else s_name */ -+ -+ /* storage for current cluster in memory: */ -+ u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); -+} fat_itr; -+ -+static int fat_itr_isdir(fat_itr *itr); -+ -+/** -+ * fat_itr_root() - initialize an iterator to start at the root -+ * directory -+ * -+ * @itr: iterator to initialize -+ * @fsdata: filesystem data for the partition -+ * @return 0 on success, else -errno -+ */ -+static int fat_itr_root(fat_itr *itr, fsdata *fsdata) -+{ -+ if (get_fs_info(fsdata)) -+ return -ENXIO; -+ -+ itr->fsdata = fsdata; -+ itr->clust = fsdata->root_cluster; -+ itr->dent = NULL; -+ itr->remaining = 0; -+ itr->last_cluster = 0; -+ itr->is_root = 1; -+ -+ return 0; -+} -+ -+/** -+ * fat_itr_child() - initialize an iterator to descend into a sub- -+ * directory -+ * -+ * Initializes 'itr' to iterate the contents of the directory at -+ * the current cursor position of 'parent'. It is an error to -+ * call this if the current cursor of 'parent' is pointing at a -+ * regular file. -+ * -+ * Note that 'itr' and 'parent' can be the same pointer if you do -+ * not need to preserve 'parent' after this call, which is useful -+ * for traversing directory structure to resolve a file/directory. -+ * -+ * @itr: iterator to initialize -+ * @parent: the iterator pointing at a directory entry in the -+ * parent directory of the directory to iterate -+ */ -+static void fat_itr_child(fat_itr *itr, fat_itr *parent) -+{ -+ fsdata *mydata = parent->fsdata; /* for silly macros */ -+ unsigned clustnum = START(parent->dent); -+ -+ assert(fat_itr_isdir(parent)); -+ -+ itr->fsdata = parent->fsdata; -+ if (clustnum > 0) { -+ itr->clust = clustnum; -+ } else { -+ itr->clust = parent->fsdata->root_cluster; -+ } -+ itr->dent = NULL; -+ itr->remaining = 0; -+ itr->last_cluster = 0; -+ itr->is_root = 0; -+} -+ -+static void *next_cluster(fat_itr *itr) -+{ -+ fsdata *mydata = itr->fsdata; /* for silly macros */ -+ int ret; -+ u32 sect; -+ -+ /* have we reached the end? */ -+ if (itr->last_cluster) -+ return NULL; -+ -+ sect = clust_to_sect(itr->fsdata, itr->clust); -+ -+ debug("FAT read(sect=%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", -+ sect, itr->fsdata->clust_size, DIRENTSPERBLOCK); -+ -+ /* -+ * NOTE: do_fat_read_at() had complicated logic to deal w/ -+ * vfat names that span multiple clusters in the fat16 case, -+ * which get_dentfromdir() probably also needed (and was -+ * missing). And not entirely sure what fat32 didn't have -+ * the same issue.. We solve that by only caring about one -+ * dent at a time and iteratively constructing the vfat long -+ * name. -+ */ -+ ret = disk_read(sect, itr->fsdata->clust_size, -+ itr->block); -+ if (ret < 0) { -+ debug("Error: reading block\n"); -+ return NULL; -+ } -+ -+ if (itr->is_root && itr->fsdata->fatsize != 32) { -+ itr->clust++; -+ sect = clust_to_sect(itr->fsdata, itr->clust); -+ if (sect - itr->fsdata->rootdir_sect >= -+ itr->fsdata->rootdir_size) { -+ debug("cursect: 0x%x\n", itr->clust); -+ itr->last_cluster = 1; -+ } -+ } else { -+ itr->clust = get_fatent(itr->fsdata, itr->clust); -+ if (CHECK_CLUST(itr->clust, itr->fsdata->fatsize)) { -+ debug("cursect: 0x%x\n", itr->clust); -+ itr->last_cluster = 1; -+ } -+ } -+ -+ return itr->block; -+} -+ -+static dir_entry *next_dent(fat_itr *itr) -+{ -+ if (itr->remaining == 0) { -+ struct dir_entry *dent = next_cluster(itr); -+ unsigned nbytes = itr->fsdata->sect_size * -+ itr->fsdata->clust_size; -+ -+ /* have we reached the last cluster? */ -+ if (!dent) -+ return NULL; -+ -+ itr->remaining = nbytes / sizeof(dir_entry) - 1; -+ itr->dent = dent; -+ } else { -+ itr->remaining--; -+ itr->dent++; -+ } -+ -+ /* have we reached the last valid entry? */ -+ if (itr->dent->name[0] == 0) -+ return NULL; -+ -+ return itr->dent; -+} -+ -+static dir_entry *extract_vfat_name(fat_itr *itr) -+{ -+ struct dir_entry *dent = itr->dent; -+ int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK; -+ u8 chksum, alias_checksum = ((dir_slot *)dent)->alias_checksum; -+ int n = 0; -+ -+ while (seqn--) { -+ char buf[13]; -+ int idx = 0; -+ -+ slot2str((dir_slot *)dent, buf, &idx); -+ -+ /* shift accumulated long-name up and copy new part in: */ -+ memmove(itr->l_name + idx, itr->l_name, n); -+ memcpy(itr->l_name, buf, idx); -+ n += idx; -+ -+ dent = next_dent(itr); -+ if (!dent) -+ return NULL; -+ } -+ -+ itr->l_name[n] = '\0'; -+ -+ chksum = mkcksum(dent->name, dent->ext); -+ -+ /* checksum mismatch could mean deleted file, etc.. skip it: */ -+ if (chksum != alias_checksum) { -+ debug("** chksum=%x, alias_checksum=%x, l_name=%s, s_name=%8s.%3s\n", -+ chksum, alias_checksum, itr->l_name, dent->name, dent->ext); -+ return NULL; -+ } -+ -+ return dent; -+} -+ -+/** -+ * fat_itr_next() - step to the next entry in a directory -+ * -+ * Must be called once on a new iterator before the cursor is valid. -+ * -+ * @itr: the iterator to iterate -+ * @return boolean, 1 if success or 0 if no more entries in the -+ * current directory -+ */ -+static int fat_itr_next(fat_itr *itr) -+{ -+ dir_entry *dent; -+ -+ itr->name = NULL; -+ -+ while (1) { -+ dent = next_dent(itr); -+ if (!dent) -+ return 0; -+ -+ if (dent->name[0] == DELETED_FLAG || -+ dent->name[0] == aRING) -+ continue; -+ -+ if (dent->attr & ATTR_VOLUME) { -+ if (vfat_enabled && -+ (dent->attr & ATTR_VFAT) == ATTR_VFAT && -+ (dent->name[0] & LAST_LONG_ENTRY_MASK)) { -+ dent = extract_vfat_name(itr); -+ if (!dent) -+ continue; -+ itr->name = itr->l_name; -+ break; -+ } else { -+ /* Volume label or VFAT entry, skip */ -+ continue; -+ } -+ } -+ -+ break; -+ } -+ -+ get_name(dent, itr->s_name); -+ if (!itr->name) -+ itr->name = itr->s_name; -+ -+ return 1; -+} -+ -+/** -+ * fat_itr_isdir() - is current cursor position pointing to a directory -+ * -+ * @itr: the iterator -+ * @return true if cursor is at a directory -+ */ -+static int fat_itr_isdir(fat_itr *itr) -+{ -+ return !!(itr->dent->attr & ATTR_DIR); -+} -+ -+/* -+ * Helpers: -+ */ -+ -+#define TYPE_FILE 0x1 -+#define TYPE_DIR 0x2 -+#define TYPE_ANY (TYPE_FILE | TYPE_DIR) -+ -+/** -+ * fat_itr_resolve() - traverse directory structure to resolve the -+ * requested path. -+ * -+ * Traverse directory structure to the requested path. If the specified -+ * path is to a directory, this will descend into the directory and -+ * leave it iterator at the start of the directory. If the path is to a -+ * file, it will leave the iterator in the parent directory with current -+ * cursor at file's entry in the directory. -+ * -+ * @itr: iterator initialized to root -+ * @path: the requested path -+ * @type: bitmask of allowable file types -+ * @return 0 on success or -errno -+ */ -+static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type) -+{ -+ const char *next; -+ -+ /* chomp any extra leading slashes: */ -+ while (path[0] && ISDIRDELIM(path[0])) -+ path++; -+ -+ /* are we at the end? */ -+ if (strlen(path) == 0) { -+ if (!(type & TYPE_DIR)) -+ return -ENOENT; -+ return 0; -+ } -+ -+ /* find length of next path entry: */ -+ next = path; -+ while (next[0] && !ISDIRDELIM(next[0])) -+ next++; -+ -+ while (fat_itr_next(itr)) { -+ int match = 0; -+ unsigned n = max(strlen(itr->name), (size_t)(next - path)); -+ -+ /* check both long and short name: */ -+ if (!strncasecmp(path, itr->name, n)) -+ match = 1; -+ else if (itr->name != itr->s_name && -+ !strncasecmp(path, itr->s_name, n)) -+ match = 1; -+ -+ if (!match) -+ continue; -+ -+ if (fat_itr_isdir(itr)) { -+ /* recurse into directory: */ -+ fat_itr_child(itr, itr); -+ return fat_itr_resolve(itr, next, type); -+ } else if (next[0]) { -+ /* -+ * If next is not empty then we have a case -+ * like: /path/to/realfile/nonsense -+ */ -+ debug("bad trailing path: %s\n", next); -+ return -ENOENT; -+ } else if (!(type & TYPE_FILE)) { -+ return -ENOTDIR; -+ } else { -+ return 0; -+ } -+ } -+ -+ return -ENOENT; -+} -+ - int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols, - loff_t *actread) - { -diff --git a/include/fat.h b/include/fat.h -index b671ee8f81..21bb6666cf 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -175,8 +175,15 @@ typedef struct { - int data_begin; /* The sector of the first cluster, can be negative */ - int fatbufnum; /* Used by get_fatent, init to -1 */ - int rootdir_size; /* Size of root dir for non-FAT32 */ -+ __u32 root_cluster; /* First cluster of root dir for FAT32 */ - } fsdata; - -+/* TODO clean up places that are open-coding this: */ -+static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) -+{ -+ return fsdata->data_begin + clust * fsdata->clust_size; -+} -+ - typedef int (file_detectfs_func)(void); - typedef int (file_ls_func)(const char *dir); - typedef int (file_read_func)(const char *filename, void *buffer, --- -2.13.5 - -From 8eafae209c35932d9a6560809c55ee4641534236 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:54 -0400 -Subject: [PATCH 36/47] fat/fs: convert to directory iterators -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -And drop a whole lot of ugly code! - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 722 +++++++--------------------------------------------------- - include/fat.h | 6 - - 2 files changed, 76 insertions(+), 652 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index ee2bbe38f1..bbba7947ee 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -119,22 +119,6 @@ int fat_register_device(struct blk_desc *dev_desc, int part_no) - } - - /* -- * Get the first occurence of a directory delimiter ('/' or '\') in a string. -- * Return index into string if found, -1 otherwise. -- */ --static int dirdelim(char *str) --{ -- char *start = str; -- -- while (*str != '\0') { -- if (ISDIRDELIM(*str)) -- return str - start; -- str++; -- } -- return -1; --} -- --/* - * Extract zero terminated short name from a directory entry. - */ - static void get_name(dir_entry *dirent, char *s_name) -@@ -468,95 +452,6 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx) - return 0; - } - --/* -- * Extract the full long filename starting at 'retdent' (which is really -- * a slot) into 'l_name'. If successful also copy the real directory entry -- * into 'retdent' -- * Return 0 on success, -1 otherwise. -- */ --static int --get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, -- dir_entry *retdent, char *l_name) --{ -- dir_entry *realdent; -- dir_slot *slotptr = (dir_slot *)retdent; -- __u8 *buflimit = cluster + mydata->sect_size * ((curclust == 0) ? -- PREFETCH_BLOCKS : -- mydata->clust_size); -- __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff; -- int idx = 0; -- -- if (counter > VFAT_MAXSEQ) { -- debug("Error: VFAT name is too long\n"); -- return -1; -- } -- -- while ((__u8 *)slotptr < buflimit) { -- if (counter == 0) -- break; -- if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) -- return -1; -- slotptr++; -- counter--; -- } -- -- if ((__u8 *)slotptr >= buflimit) { -- dir_slot *slotptr2; -- -- if (curclust == 0) -- return -1; -- curclust = get_fatent(mydata, curclust); -- if (CHECK_CLUST(curclust, mydata->fatsize)) { -- debug("curclust: 0x%x\n", curclust); -- printf("Invalid FAT entry\n"); -- return -1; -- } -- -- if (get_cluster(mydata, curclust, get_contents_vfatname_block, -- mydata->clust_size * mydata->sect_size) != 0) { -- debug("Error: reading directory block\n"); -- return -1; -- } -- -- slotptr2 = (dir_slot *)get_contents_vfatname_block; -- while (counter > 0) { -- if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) -- & 0xff) != counter) -- return -1; -- slotptr2++; -- counter--; -- } -- -- /* Save the real directory entry */ -- realdent = (dir_entry *)slotptr2; -- while ((__u8 *)slotptr2 > get_contents_vfatname_block) { -- slotptr2--; -- slot2str(slotptr2, l_name, &idx); -- } -- } else { -- /* Save the real directory entry */ -- realdent = (dir_entry *)slotptr; -- } -- -- do { -- slotptr--; -- if (slot2str(slotptr, l_name, &idx)) -- break; -- } while (!(slotptr->id & LAST_LONG_ENTRY_MASK)); -- -- l_name[idx] = '\0'; -- if (*l_name == DELETED_FLAG) -- *l_name = '\0'; -- else if (*l_name == aRING) -- *l_name = DELETED_FLAG; -- downcase(l_name); -- -- /* Return the real directory entry */ -- memcpy(retdent, realdent, sizeof(dir_entry)); -- -- return 0; --} -- - /* Calculate short name checksum */ - static __u8 mkcksum(const char name[8], const char ext[3]) - { -@@ -573,169 +468,13 @@ static __u8 mkcksum(const char name[8], const char ext[3]) - } - - /* -- * Get the directory entry associated with 'filename' from the directory -- * starting at 'startsect' -+ * TODO these should go away once fat_write is reworked to use the -+ * directory iterator - */ - __u8 get_dentfromdir_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); -- --static dir_entry *get_dentfromdir(fsdata *mydata, int startsect, -- char *filename, dir_entry *retdent, -- int dols) --{ -- __u16 prevcksum = 0xffff; -- __u32 curclust = START(retdent); -- int files = 0, dirs = 0; -- -- debug("get_dentfromdir: %s\n", filename); -- -- while (1) { -- dir_entry *dentptr; -- -- int i; -- -- if (get_cluster(mydata, curclust, get_dentfromdir_block, -- mydata->clust_size * mydata->sect_size) != 0) { -- debug("Error: reading directory block\n"); -- return NULL; -- } -- -- dentptr = (dir_entry *)get_dentfromdir_block; -- -- for (i = 0; i < DIRENTSPERCLUST; i++) { -- char s_name[14], l_name[VFAT_MAXLEN_BYTES]; -- -- l_name[0] = '\0'; -- if (dentptr->name[0] == DELETED_FLAG) { -- dentptr++; -- continue; -- } -- if ((dentptr->attr & ATTR_VOLUME)) { -- if (vfat_enabled && -- (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && -- (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { -- prevcksum = ((dir_slot *)dentptr)->alias_checksum; -- get_vfatname(mydata, curclust, -- get_dentfromdir_block, -- dentptr, l_name); -- if (dols) { -- int isdir; -- char dirc; -- int doit = 0; -- -- isdir = (dentptr->attr & ATTR_DIR); -- -- if (isdir) { -- dirs++; -- dirc = '/'; -- doit = 1; -- } else { -- dirc = ' '; -- if (l_name[0] != 0) { -- files++; -- doit = 1; -- } -- } -- if (doit) { -- if (dirc == ' ') { -- printf(" %8u %s%c\n", -- FAT2CPU32(dentptr->size), -- l_name, -- dirc); -- } else { -- printf(" %s%c\n", -- l_name, -- dirc); -- } -- } -- dentptr++; -- continue; -- } -- debug("vfatname: |%s|\n", l_name); -- } else { -- /* Volume label or VFAT entry */ -- dentptr++; -- continue; -- } -- } -- if (dentptr->name[0] == 0) { -- if (dols) { -- printf("\n%d file(s), %d dir(s)\n\n", -- files, dirs); -- } -- debug("Dentname == NULL - %d\n", i); -- return NULL; -- } -- if (vfat_enabled) { -- __u8 csum = mkcksum(dentptr->name, dentptr->ext); -- if (dols && csum == prevcksum) { -- prevcksum = 0xffff; -- dentptr++; -- continue; -- } -- } -- -- get_name(dentptr, s_name); -- if (dols) { -- int isdir = (dentptr->attr & ATTR_DIR); -- char dirc; -- int doit = 0; -- -- if (isdir) { -- dirs++; -- dirc = '/'; -- doit = 1; -- } else { -- dirc = ' '; -- if (s_name[0] != 0) { -- files++; -- doit = 1; -- } -- } -- -- if (doit) { -- if (dirc == ' ') { -- printf(" %8u %s%c\n", -- FAT2CPU32(dentptr->size), -- s_name, dirc); -- } else { -- printf(" %s%c\n", -- s_name, dirc); -- } -- } -- -- dentptr++; -- continue; -- } -- -- if (strcmp(filename, s_name) -- && strcmp(filename, l_name)) { -- debug("Mismatch: |%s|%s|\n", s_name, l_name); -- dentptr++; -- continue; -- } -- -- memcpy(retdent, dentptr, sizeof(dir_entry)); -- -- debug("DentName: %s", s_name); -- debug(", start: 0x%x", START(dentptr)); -- debug(", size: 0x%x %s\n", -- FAT2CPU32(dentptr->size), -- (dentptr->attr & ATTR_DIR) ? "(DIR)" : ""); -- -- return retdent; -- } -- -- curclust = get_fatent(mydata, curclust); -- if (CHECK_CLUST(curclust, mydata->fatsize)) { -- debug("curclust: 0x%x\n", curclust); -- printf("Invalid FAT entry\n"); -- return NULL; -- } -- } -- -- return NULL; --} -+__u8 do_fat_read_at_block[MAX_CLUSTSIZE] -+ __aligned(ARCH_DMA_MINALIGN); - - /* - * Read boot sector and volume info from a FAT filesystem -@@ -879,374 +618,6 @@ static int get_fs_info(fsdata *mydata) - return 0; - } - --__u8 do_fat_read_at_block[MAX_CLUSTSIZE] -- __aligned(ARCH_DMA_MINALIGN); -- --int do_fat_read_at(const char *filename, loff_t pos, void *buffer, -- loff_t maxsize, int dols, int dogetsize, loff_t *size) --{ -- char fnamecopy[2048]; -- fsdata datablock; -- fsdata *mydata = &datablock; -- dir_entry *dentptr = NULL; -- __u16 prevcksum = 0xffff; -- char *subname = ""; -- __u32 cursect; -- int idx, isdir = 0; -- int files = 0, dirs = 0; -- int ret = -1; -- int firsttime; -- __u32 root_cluster = 0; -- __u32 read_blk; -- int rootdir_size = 0; -- int buffer_blk_cnt; -- int do_read; -- __u8 *dir_ptr; -- -- if (get_fs_info(mydata)) -- return -1; -- -- cursect = mydata->rootdir_sect; -- -- /* "cwd" is always the root... */ -- while (ISDIRDELIM(*filename)) -- filename++; -- -- /* Make a copy of the filename and convert it to lowercase */ -- strcpy(fnamecopy, filename); -- downcase(fnamecopy); -- --root_reparse: -- if (*fnamecopy == '\0') { -- if (!dols) -- goto exit; -- -- dols = LS_ROOT; -- } else if ((idx = dirdelim(fnamecopy)) >= 0) { -- isdir = 1; -- fnamecopy[idx] = '\0'; -- subname = fnamecopy + idx + 1; -- -- /* Handle multiple delimiters */ -- while (ISDIRDELIM(*subname)) -- subname++; -- } else if (dols) { -- isdir = 1; -- } -- -- buffer_blk_cnt = 0; -- firsttime = 1; -- while (1) { -- int i; -- -- if (mydata->fatsize == 32 || firsttime) { -- dir_ptr = do_fat_read_at_block; -- firsttime = 0; -- } else { -- /** -- * FAT16 sector buffer modification: -- * Each loop, the second buffered block is moved to -- * the buffer begin, and two next sectors are read -- * next to the previously moved one. So the sector -- * buffer keeps always 3 sectors for fat16. -- * And the current sector is the buffer second sector -- * beside the "firsttime" read, when it is the first one. -- * -- * PREFETCH_BLOCKS is 2 for FAT16 == loop[0:1] -- * n = computed root dir sector -- * loop | cursect-1 | cursect | cursect+1 | -- * 0 | sector n+0 | sector n+1 | none | -- * 1 | none | sector n+0 | sector n+1 | -- * 0 | sector n+1 | sector n+2 | sector n+3 | -- * 1 | sector n+3 | ... -- */ -- dir_ptr = (do_fat_read_at_block + mydata->sect_size); -- memcpy(do_fat_read_at_block, dir_ptr, mydata->sect_size); -- } -- -- do_read = 1; -- -- if (mydata->fatsize == 32 && buffer_blk_cnt) -- do_read = 0; -- -- if (do_read) { -- read_blk = (mydata->fatsize == 32) ? -- mydata->clust_size : PREFETCH_BLOCKS; -- -- debug("FAT read(sect=%d, cnt:%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", -- cursect, read_blk, mydata->clust_size, DIRENTSPERBLOCK); -- -- if (disk_read(cursect, read_blk, dir_ptr) < 0) { -- debug("Error: reading rootdir block\n"); -- goto exit; -- } -- -- dentptr = (dir_entry *)dir_ptr; -- } -- -- for (i = 0; i < DIRENTSPERBLOCK; i++) { -- char s_name[14], l_name[VFAT_MAXLEN_BYTES]; -- __u8 csum; -- -- l_name[0] = '\0'; -- if (dentptr->name[0] == DELETED_FLAG) { -- dentptr++; -- continue; -- } -- -- if (vfat_enabled) -- csum = mkcksum(dentptr->name, dentptr->ext); -- -- if (dentptr->attr & ATTR_VOLUME) { -- if (vfat_enabled && -- (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && -- (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { -- prevcksum = -- ((dir_slot *)dentptr)->alias_checksum; -- -- get_vfatname(mydata, -- root_cluster, -- dir_ptr, -- dentptr, l_name); -- -- if (dols == LS_ROOT) { -- char dirc; -- int doit = 0; -- int isdir = -- (dentptr->attr & ATTR_DIR); -- -- if (isdir) { -- dirs++; -- dirc = '/'; -- doit = 1; -- } else { -- dirc = ' '; -- if (l_name[0] != 0) { -- files++; -- doit = 1; -- } -- } -- if (doit) { -- if (dirc == ' ') { -- printf(" %8u %s%c\n", -- FAT2CPU32(dentptr->size), -- l_name, -- dirc); -- } else { -- printf(" %s%c\n", -- l_name, -- dirc); -- } -- } -- dentptr++; -- continue; -- } -- debug("Rootvfatname: |%s|\n", -- l_name); -- } else { -- /* Volume label or VFAT entry */ -- dentptr++; -- continue; -- } -- } else if (dentptr->name[0] == 0) { -- debug("RootDentname == NULL - %d\n", i); -- if (dols == LS_ROOT) { -- printf("\n%d file(s), %d dir(s)\n\n", -- files, dirs); -- ret = 0; -- } -- goto exit; -- } -- else if (vfat_enabled && -- dols == LS_ROOT && csum == prevcksum) { -- prevcksum = 0xffff; -- dentptr++; -- continue; -- } -- -- get_name(dentptr, s_name); -- -- if (dols == LS_ROOT) { -- int isdir = (dentptr->attr & ATTR_DIR); -- char dirc; -- int doit = 0; -- -- if (isdir) { -- dirc = '/'; -- if (s_name[0] != 0) { -- dirs++; -- doit = 1; -- } -- } else { -- dirc = ' '; -- if (s_name[0] != 0) { -- files++; -- doit = 1; -- } -- } -- if (doit) { -- if (dirc == ' ') { -- printf(" %8u %s%c\n", -- FAT2CPU32(dentptr->size), -- s_name, dirc); -- } else { -- printf(" %s%c\n", -- s_name, dirc); -- } -- } -- dentptr++; -- continue; -- } -- -- if (strcmp(fnamecopy, s_name) -- && strcmp(fnamecopy, l_name)) { -- debug("RootMismatch: |%s|%s|\n", s_name, -- l_name); -- dentptr++; -- continue; -- } -- -- if (isdir && !(dentptr->attr & ATTR_DIR)) -- goto exit; -- -- debug("RootName: %s", s_name); -- debug(", start: 0x%x", START(dentptr)); -- debug(", size: 0x%x %s\n", -- FAT2CPU32(dentptr->size), -- isdir ? "(DIR)" : ""); -- -- goto rootdir_done; /* We got a match */ -- } -- debug("END LOOP: buffer_blk_cnt=%d clust_size=%d\n", buffer_blk_cnt, -- mydata->clust_size); -- -- /* -- * On FAT32 we must fetch the FAT entries for the next -- * root directory clusters when a cluster has been -- * completely processed. -- */ -- ++buffer_blk_cnt; -- int rootdir_end = 0; -- if (mydata->fatsize == 32) { -- if (buffer_blk_cnt == mydata->clust_size) { -- int nxtsect = 0; -- int nxt_clust = 0; -- -- nxt_clust = get_fatent(mydata, root_cluster); -- rootdir_end = CHECK_CLUST(nxt_clust, 32); -- -- nxtsect = mydata->data_begin + -- (nxt_clust * mydata->clust_size); -- -- root_cluster = nxt_clust; -- -- cursect = nxtsect; -- buffer_blk_cnt = 0; -- } -- } else { -- if (buffer_blk_cnt == PREFETCH_BLOCKS) -- buffer_blk_cnt = 0; -- -- rootdir_end = (++cursect - mydata->rootdir_sect >= -- rootdir_size); -- } -- -- /* If end of rootdir reached */ -- if (rootdir_end) { -- if (dols == LS_ROOT) { -- printf("\n%d file(s), %d dir(s)\n\n", -- files, dirs); -- *size = 0; -- } -- goto exit; -- } -- } --rootdir_done: -- -- firsttime = 1; -- -- while (isdir) { -- int startsect = mydata->data_begin -- + START(dentptr) * mydata->clust_size; -- dir_entry dent; -- char *nextname = NULL; -- -- dent = *dentptr; -- dentptr = &dent; -- -- idx = dirdelim(subname); -- -- if (idx >= 0) { -- subname[idx] = '\0'; -- nextname = subname + idx + 1; -- /* Handle multiple delimiters */ -- while (ISDIRDELIM(*nextname)) -- nextname++; -- if (dols && *nextname == '\0') -- firsttime = 0; -- } else { -- if (dols && firsttime) { -- firsttime = 0; -- } else { -- isdir = 0; -- } -- } -- -- if (get_dentfromdir(mydata, startsect, subname, dentptr, -- isdir ? 0 : dols) == NULL) { -- if (dols && !isdir) -- *size = 0; -- goto exit; -- } -- -- if (isdir && !(dentptr->attr & ATTR_DIR)) -- goto exit; -- -- /* -- * If we are looking for a directory, and found a directory -- * type entry, and the entry is for the root directory (as -- * denoted by a cluster number of 0), jump back to the start -- * of the function, since at least on FAT12/16, the root dir -- * lives in a hard-coded location and needs special handling -- * to parse, rather than simply following the cluster linked -- * list in the FAT, like other directories. -- */ -- if (isdir && (dentptr->attr & ATTR_DIR) && !START(dentptr)) { -- /* -- * Modify the filename to remove the prefix that gets -- * back to the root directory, so the initial root dir -- * parsing code can continue from where we are without -- * confusion. -- */ -- strcpy(fnamecopy, nextname ?: ""); -- /* -- * Set up state the same way as the function does when -- * first started. This is required for the root dir -- * parsing code operates in its expected environment. -- */ -- subname = ""; -- cursect = mydata->rootdir_sect; -- isdir = 0; -- goto root_reparse; -- } -- -- if (idx >= 0) -- subname = nextname; -- } -- -- if (dogetsize) { -- *size = FAT2CPU32(dentptr->size); -- ret = 0; -- } else { -- ret = get_contents(mydata, dentptr, pos, buffer, maxsize, size); -- } -- debug("Size: %u, got: %llu\n", FAT2CPU32(dentptr->size), *size); -- --exit: -- free(mydata->fatbuf); -- return ret; --} -- - - /* - * Directory iterator, to simplify filesystem traversal -@@ -1595,12 +966,6 @@ static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type) - return -ENOENT; - } - --int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols, -- loff_t *actread) --{ -- return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0, actread); --} -- - int file_fat_detectfs(void) - { - boot_sector bs; -@@ -1665,31 +1030,96 @@ int file_fat_detectfs(void) - - int file_fat_ls(const char *dir) - { -- loff_t size; -+ fsdata fsdata; -+ fat_itr itrblock, *itr = &itrblock; -+ int files = 0, dirs = 0; -+ int ret; -+ -+ ret = fat_itr_root(itr, &fsdata); -+ if (ret) -+ return ret; -+ -+ ret = fat_itr_resolve(itr, dir, TYPE_DIR); -+ if (ret) -+ return ret; -+ -+ while (fat_itr_next(itr)) { -+ if (fat_itr_isdir(itr)) { -+ printf(" %s/\n", itr->name); -+ dirs++; -+ } else { -+ printf(" %8u %s\n", -+ FAT2CPU32(itr->dent->size), -+ itr->name); -+ files++; -+ } -+ } - -- return do_fat_read(dir, NULL, 0, LS_YES, &size); -+ printf("\n%d file(s), %d dir(s)\n\n", files, dirs); -+ -+ return 0; - } - - int fat_exists(const char *filename) - { -+ fsdata fsdata; -+ fat_itr itrblock, *itr = &itrblock; - int ret; -- loff_t size; - -- ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size); -+ ret = fat_itr_root(itr, &fsdata); -+ if (ret) -+ return 0; -+ -+ ret = fat_itr_resolve(itr, filename, TYPE_ANY); - return ret == 0; - } - - int fat_size(const char *filename, loff_t *size) - { -- return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size); -+ fsdata fsdata; -+ fat_itr itrblock, *itr = &itrblock; -+ int ret; -+ -+ ret = fat_itr_root(itr, &fsdata); -+ if (ret) -+ return ret; -+ -+ ret = fat_itr_resolve(itr, filename, TYPE_FILE); -+ if (ret) { -+ /* -+ * Directories don't have size, but fs_size() is not -+ * expected to fail if passed a directory path: -+ */ -+ fat_itr_root(itr, &fsdata); -+ if (!fat_itr_resolve(itr, filename, TYPE_DIR)) { -+ *size = 0; -+ return 0; -+ } -+ return ret; -+ } -+ -+ *size = FAT2CPU32(itr->dent->size); -+ -+ return 0; - } - - int file_fat_read_at(const char *filename, loff_t pos, void *buffer, - loff_t maxsize, loff_t *actread) - { -+ fsdata fsdata; -+ fat_itr itrblock, *itr = &itrblock; -+ int ret; -+ -+ ret = fat_itr_root(itr, &fsdata); -+ if (ret) -+ return ret; -+ -+ ret = fat_itr_resolve(itr, filename, TYPE_FILE); -+ if (ret) -+ return ret; -+ - printf("reading %s\n", filename); -- return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0, -- actread); -+ return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); - } - - int file_fat_read(const char *filename, void *buffer, int maxsize) -diff --git a/include/fat.h b/include/fat.h -index 21bb6666cf..18d8981c48 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -58,12 +58,6 @@ - */ - #define LAST_LONG_ENTRY_MASK 0x40 - --/* Flags telling whether we should read a file or list a directory */ --#define LS_NO 0 --#define LS_YES 1 --#define LS_DIR 1 --#define LS_ROOT 2 -- - #define ISDIRDELIM(c) ((c) == '/' || (c) == '\\') - - #define FSTYPE_NONE (-1) --- -2.13.5 - -From 4bbcc965f995564870ca02606137e60e873e0a1f Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:55 -0400 -Subject: [PATCH 37/47] fs: add fs_readdir() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Needed to support efi file protocol. The fallback.efi loader wants -to be able to read the contents of the /EFI directory to find an OS -to boot. - -Modelled after POSIX opendir()/readdir()/closedir(). Unlike the other -fs APIs, this is stateful (ie. state is held in the FS_DIR "directory -stream"), to avoid re-traversing of the directory structure at each -step. The directory stream must be released with closedir() when it -is no longer needed. - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - disk/part.c | 31 ++++++++++------- - fs/fs.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - include/fs.h | 67 +++++++++++++++++++++++++++++++++++++ - include/part.h | 9 +++++ - 4 files changed, 199 insertions(+), 12 deletions(-) - -diff --git a/disk/part.c b/disk/part.c -index c67fdacc79..aa9183d696 100644 ---- a/disk/part.c -+++ b/disk/part.c -@@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int part, - return -1; - } - -+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info) -+{ -+ info->start = 0; -+ info->size = dev_desc->lba; -+ info->blksz = dev_desc->blksz; -+ info->bootable = 0; -+ strcpy((char *)info->type, BOOT_PART_TYPE); -+ strcpy((char *)info->name, "Whole Disk"); -+#if CONFIG_IS_ENABLED(PARTITION_UUIDS) -+ info->uuid[0] = 0; -+#endif -+#ifdef CONFIG_PARTITION_TYPE_GUID -+ info->type_guid[0] = 0; -+#endif -+ -+ return 0; -+} -+ - int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, - struct blk_desc **dev_desc) - { -@@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str, - - (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); - -- info->start = 0; -- info->size = (*dev_desc)->lba; -- info->blksz = (*dev_desc)->blksz; -- info->bootable = 0; -- strcpy((char *)info->type, BOOT_PART_TYPE); -- strcpy((char *)info->name, "Whole Disk"); --#if CONFIG_IS_ENABLED(PARTITION_UUIDS) -- info->uuid[0] = 0; --#endif --#ifdef CONFIG_PARTITION_TYPE_GUID -- info->type_guid[0] = 0; --#endif -+ part_get_info_whole_disk(*dev_desc, info); - - ret = 0; - goto cleanup; -diff --git a/fs/fs.c b/fs/fs.c -index 13cd3626c6..fc0c953fcb 100644 ---- a/fs/fs.c -+++ b/fs/fs.c -@@ -21,6 +21,7 @@ - DECLARE_GLOBAL_DATA_PTR; - - static struct blk_desc *fs_dev_desc; -+static int fs_dev_part; - static disk_partition_t fs_partition; - static int fs_type = FS_TYPE_ANY; - -@@ -69,6 +70,12 @@ static inline int fs_uuid_unsupported(char *uuid_str) - return -1; - } - -+static inline int fs_opendir_unsupported(const char *filename, -+ struct fs_dir_stream **dirs) -+{ -+ return -EACCES; -+} -+ - struct fstype_info { - int fstype; - char *name; -@@ -92,6 +99,20 @@ struct fstype_info { - loff_t len, loff_t *actwrite); - void (*close)(void); - int (*uuid)(char *uuid_str); -+ /* -+ * Open a directory stream. On success return 0 and directory -+ * stream pointer via 'dirsp'. On error, return -errno. See -+ * fs_opendir(). -+ */ -+ int (*opendir)(const char *filename, struct fs_dir_stream **dirsp); -+ /* -+ * Read next entry from directory stream. On success return 0 -+ * and directory entry pointer via 'dentp'. On error return -+ * -errno. See fs_readdir(). -+ */ -+ int (*readdir)(struct fs_dir_stream *dirs, struct fs_dirent **dentp); -+ /* see fs_closedir() */ -+ void (*closedir)(struct fs_dir_stream *dirs); - }; - - static struct fstype_info fstypes[] = { -@@ -112,6 +133,7 @@ static struct fstype_info fstypes[] = { - .write = fs_write_unsupported, - #endif - .uuid = fs_uuid_unsupported, -+ .opendir = fs_opendir_unsupported, - }, - #endif - #ifdef CONFIG_FS_EXT4 -@@ -131,6 +153,7 @@ static struct fstype_info fstypes[] = { - .write = fs_write_unsupported, - #endif - .uuid = ext4fs_uuid, -+ .opendir = fs_opendir_unsupported, - }, - #endif - #ifdef CONFIG_SANDBOX -@@ -146,6 +169,7 @@ static struct fstype_info fstypes[] = { - .read = fs_read_sandbox, - .write = fs_write_sandbox, - .uuid = fs_uuid_unsupported, -+ .opendir = fs_opendir_unsupported, - }, - #endif - #ifdef CONFIG_CMD_UBIFS -@@ -161,6 +185,7 @@ static struct fstype_info fstypes[] = { - .read = ubifs_read, - .write = fs_write_unsupported, - .uuid = fs_uuid_unsupported, -+ .opendir = fs_opendir_unsupported, - }, - #endif - { -@@ -175,6 +200,7 @@ static struct fstype_info fstypes[] = { - .read = fs_read_unsupported, - .write = fs_write_unsupported, - .uuid = fs_uuid_unsupported, -+ .opendir = fs_opendir_unsupported, - }, - }; - -@@ -228,6 +254,31 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) - - if (!info->probe(fs_dev_desc, &fs_partition)) { - fs_type = info->fstype; -+ fs_dev_part = part; -+ return 0; -+ } -+ } -+ -+ return -1; -+} -+ -+/* set current blk device w/ blk_desc + partition # */ -+int fs_set_blk_dev_with_part(struct blk_desc *desc, int part) -+{ -+ struct fstype_info *info; -+ int ret, i; -+ -+ if (part >= 1) -+ ret = part_get_info(desc, part, &fs_partition); -+ else -+ ret = part_get_info_whole_disk(desc, &fs_partition); -+ if (ret) -+ return ret; -+ fs_dev_desc = desc; -+ -+ for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) { -+ if (!info->probe(fs_dev_desc, &fs_partition)) { -+ fs_type = info->fstype; - return 0; - } - } -@@ -334,6 +385,59 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, - return ret; - } - -+struct fs_dir_stream *fs_opendir(const char *filename) -+{ -+ struct fstype_info *info = fs_get_info(fs_type); -+ struct fs_dir_stream *dirs = NULL; -+ int ret; -+ -+ ret = info->opendir(filename, &dirs); -+ fs_close(); -+ if (ret) { -+ errno = -ret; -+ return NULL; -+ } -+ -+ dirs->desc = fs_dev_desc; -+ dirs->part = fs_dev_part; -+ -+ return dirs; -+} -+ -+struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs) -+{ -+ struct fstype_info *info; -+ struct fs_dirent *dirent; -+ int ret; -+ -+ fs_set_blk_dev_with_part(dirs->desc, dirs->part); -+ info = fs_get_info(fs_type); -+ -+ ret = info->readdir(dirs, &dirent); -+ fs_close(); -+ if (ret) { -+ errno = -ret; -+ return NULL; -+ } -+ -+ return dirent; -+} -+ -+void fs_closedir(struct fs_dir_stream *dirs) -+{ -+ struct fstype_info *info; -+ -+ if (!dirs) -+ return; -+ -+ fs_set_blk_dev_with_part(dirs->desc, dirs->part); -+ info = fs_get_info(fs_type); -+ -+ info->closedir(dirs); -+ fs_close(); -+} -+ -+ - int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) - { -diff --git a/include/fs.h b/include/fs.h -index 2f2aca8378..0869ad6e80 100644 ---- a/include/fs.h -+++ b/include/fs.h -@@ -27,6 +27,17 @@ - int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype); - - /* -+ * fs_set_blk_dev_with_part - Set current block device + partition -+ * -+ * Similar to fs_set_blk_dev(), but useful for cases where you already -+ * know the blk_desc and part number. -+ * -+ * Returns 0 on success. -+ * Returns non-zero if invalid partition or error accessing the disk. -+ */ -+int fs_set_blk_dev_with_part(struct blk_desc *desc, int part); -+ -+/* - * Print the list of files on the partition previously set by fs_set_blk_dev(), - * in directory "dirname". - * -@@ -79,6 +90,62 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, - loff_t *actwrite); - - /* -+ * Directory entry types, matches the subset of DT_x in posix readdir() -+ * which apply to u-boot. -+ */ -+#define FS_DT_DIR 4 /* directory */ -+#define FS_DT_REG 8 /* regular file */ -+#define FS_DT_LNK 10 /* symbolic link */ -+ -+/* -+ * A directory entry, returned by fs_readdir(). Returns information -+ * about the file/directory at the current directory entry position. -+ */ -+struct fs_dirent { -+ unsigned type; /* one of FS_DT_x (not a mask) */ -+ loff_t size; /* size in bytes */ -+ char name[256]; -+}; -+ -+/* Note: fs_dir_stream should be treated as opaque to the user of fs layer */ -+struct fs_dir_stream { -+ /* private to fs. layer: */ -+ struct blk_desc *desc; -+ int part; -+}; -+ -+/* -+ * fs_opendir - Open a directory -+ * -+ * @filename: the path to directory to open -+ * @return a pointer to the directory stream or NULL on error and errno -+ * set appropriately -+ */ -+struct fs_dir_stream *fs_opendir(const char *filename); -+ -+/* -+ * fs_readdir - Read the next directory entry in the directory stream. -+ * -+ * Works in an analogous way to posix readdir(). The previously returned -+ * directory entry is no longer valid after calling fs_readdir() again. -+ * After fs_closedir() is called, the returned directory entry is no -+ * longer valid. -+ * -+ * @dirs: the directory stream -+ * @return the next directory entry (only valid until next fs_readdir() or -+ * fs_closedir() call, do not attempt to free()) or NULL if the end of -+ * the directory is reached. -+ */ -+struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs); -+ -+/* -+ * fs_closedir - close a directory stream -+ * -+ * @dirs: the directory stream -+ */ -+void fs_closedir(struct fs_dir_stream *dirs); -+ -+/* - * Common implementation for various filesystem commands, optionally limited - * to a specific filesystem type via the fstype parameter. - */ -diff --git a/include/part.h b/include/part.h -index 0d5c99836b..86117a7ce5 100644 ---- a/include/part.h -+++ b/include/part.h -@@ -98,6 +98,12 @@ int host_get_dev_err(int dev, struct blk_desc **blk_devp); - - /* disk/part.c */ - int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info); -+/** -+ * part_get_info_whole_disk() - get partition info for the special case of -+ * a partition occupying the entire disk. -+ */ -+int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info); -+ - void part_print(struct blk_desc *dev_desc); - void part_init(struct blk_desc *dev_desc); - void dev_print(struct blk_desc *dev_desc); -@@ -203,6 +209,9 @@ static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; } - - static inline int part_get_info(struct blk_desc *dev_desc, int part, - disk_partition_t *info) { return -1; } -+static inline int part_get_info_whole_disk(struct blk_desc *dev_desc, -+ disk_partition_t *info) -+{ return -1; } - static inline void part_print(struct blk_desc *dev_desc) {} - static inline void part_init(struct blk_desc *dev_desc) {} - static inline void dev_print(struct blk_desc *dev_desc) {} --- -2.13.5 - -From 1f40366b319eac7eb02f8894fff5c94fbdb47d30 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:56 -0400 -Subject: [PATCH 38/47] fs/fat: implement opendir/readdir/closedir -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement the readdir interface using the directory iterators. - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 61 insertions(+) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index bbba7947ee..82ddb7eab1 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1146,6 +1147,66 @@ int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, - return ret; - } - -+typedef struct { -+ struct fs_dir_stream parent; -+ struct fs_dirent dirent; -+ fsdata fsdata; -+ fat_itr itr; -+} fat_dir; -+ -+int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) -+{ -+ fat_dir *dir = malloc(sizeof(*dir)); -+ int ret; -+ -+ if (!dir) -+ return -ENOMEM; -+ -+ ret = fat_itr_root(&dir->itr, &dir->fsdata); -+ if (ret) -+ goto fail; -+ -+ ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR); -+ if (ret) -+ goto fail; -+ -+ *dirsp = (struct fs_dir_stream *)dir; -+ return 0; -+ -+fail: -+ free(dir); -+ return ret; -+} -+ -+int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp) -+{ -+ fat_dir *dir = (fat_dir *)dirs; -+ struct fs_dirent *dent = &dir->dirent; -+ -+ if (!fat_itr_next(&dir->itr)) -+ return -ENOENT; -+ -+ memset(dent, 0, sizeof(*dent)); -+ strcpy(dent->name, dir->itr.name); -+ -+ if (fat_itr_isdir(&dir->itr)) { -+ dent->type = FS_DT_DIR; -+ } else { -+ dent->type = FS_DT_REG; -+ dent->size = FAT2CPU32(dir->itr.dent->size); -+ } -+ -+ *dentp = dent; -+ -+ return 0; -+} -+ -+void fat_closedir(struct fs_dir_stream *dirs) -+{ -+ fat_dir *dir = (fat_dir *)dirs; -+ free(dir); -+} -+ - void fat_close(void) - { - } --- -2.13.5 - -From 41fa83d1a6cdd8ddfb3fbe332252193ff8fb8b71 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:57 -0400 -Subject: [PATCH 39/47] fat/fs: remove a bunch of dead code -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Spotted by chance, when trying to remove file_fat_ls(), I noticed there -were some dead users of the API. - -Signed-off-by: Rob Clark -Acked-by: Stefan Brüns -Reviewed-by: Simon Glass ---- - fs/fat/Makefile | 4 -- - fs/fat/file.c | 183 -------------------------------------------------------- - include/fat.h | 20 ------- - 3 files changed, 207 deletions(-) - delete mode 100644 fs/fat/file.c - -diff --git a/fs/fat/Makefile b/fs/fat/Makefile -index b60e8486c4..3e2a6b01a8 100644 ---- a/fs/fat/Makefile -+++ b/fs/fat/Makefile -@@ -5,7 +5,3 @@ - - obj-$(CONFIG_FS_FAT) := fat.o - obj-$(CONFIG_FAT_WRITE):= fat_write.o -- --ifndef CONFIG_SPL_BUILD --obj-$(CONFIG_FS_FAT) += file.o --endif -diff --git a/fs/fat/file.c b/fs/fat/file.c -deleted file mode 100644 -index 89706117b9..0000000000 ---- a/fs/fat/file.c -+++ /dev/null -@@ -1,183 +0,0 @@ --/* -- * file.c -- * -- * Mini "VFS" by Marcus Sundberg -- * -- * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 -- * 2003-03-10 - kharris@nexus-tech.net - ported to uboot -- * -- * SPDX-License-Identifier: GPL-2.0+ -- */ -- --#include --#include --#include --#include --#include --#include -- --/* Supported filesystems */ --static const struct filesystem filesystems[] = { -- { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, --}; --#define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) -- --/* The filesystem which was last detected */ --static int current_filesystem = FSTYPE_NONE; -- --/* The current working directory */ --#define CWD_LEN 511 --char file_cwd[CWD_LEN+1] = "/"; -- --const char * --file_getfsname(int idx) --{ -- if (idx < 0 || idx >= NUM_FILESYS) -- return NULL; -- -- return filesystems[idx].name; --} -- --static void --pathcpy(char *dest, const char *src) --{ -- char *origdest = dest; -- -- do { -- if (dest-file_cwd >= CWD_LEN) { -- *dest = '\0'; -- return; -- } -- *(dest) = *(src); -- if (*src == '\0') { -- if (dest-- != origdest && ISDIRDELIM(*dest)) { -- *dest = '\0'; -- } -- return; -- } -- ++dest; -- -- if (ISDIRDELIM(*src)) -- while (ISDIRDELIM(*src)) src++; -- else -- src++; -- } while (1); --} -- --int --file_cd(const char *path) --{ -- if (ISDIRDELIM(*path)) { -- while (ISDIRDELIM(*path)) path++; -- strncpy(file_cwd+1, path, CWD_LEN-1); -- } else { -- const char *origpath = path; -- char *tmpstr = file_cwd; -- int back = 0; -- -- while (*tmpstr != '\0') tmpstr++; -- do { -- tmpstr--; -- } while (ISDIRDELIM(*tmpstr)); -- -- while (*path == '.') { -- path++; -- while (*path == '.') { -- path++; -- back++; -- } -- if (*path != '\0' && !ISDIRDELIM(*path)) { -- path = origpath; -- back = 0; -- break; -- } -- while (ISDIRDELIM(*path)) path++; -- origpath = path; -- } -- -- while (back--) { -- /* Strip off path component */ -- while (!ISDIRDELIM(*tmpstr)) { -- tmpstr--; -- } -- if (tmpstr == file_cwd) { -- /* Incremented again right after the loop. */ -- tmpstr--; -- break; -- } -- /* Skip delimiters */ -- while (ISDIRDELIM(*tmpstr)) tmpstr--; -- } -- tmpstr++; -- if (*path == '\0') { -- if (tmpstr == file_cwd) { -- *tmpstr = '/'; -- tmpstr++; -- } -- *tmpstr = '\0'; -- return 0; -- } -- *tmpstr = '/'; -- pathcpy(tmpstr+1, path); -- } -- -- return 0; --} -- --int --file_detectfs(void) --{ -- int i; -- -- current_filesystem = FSTYPE_NONE; -- -- for (i = 0; i < NUM_FILESYS; i++) { -- if (filesystems[i].detect() == 0) { -- strcpy(file_cwd, "/"); -- current_filesystem = i; -- break; -- } -- } -- -- return current_filesystem; --} -- --int --file_ls(const char *dir) --{ -- char fullpath[1024]; -- const char *arg; -- -- if (current_filesystem == FSTYPE_NONE) { -- printf("Can't list files without a filesystem!\n"); -- return -1; -- } -- -- if (ISDIRDELIM(*dir)) { -- arg = dir; -- } else { -- sprintf(fullpath, "%s/%s", file_cwd, dir); -- arg = fullpath; -- } -- return filesystems[current_filesystem].ls(arg); --} -- --int file_read(const char *filename, void *buffer, int maxsize) --{ -- char fullpath[1024]; -- const char *arg; -- -- if (current_filesystem == FSTYPE_NONE) { -- printf("Can't load file without a filesystem!\n"); -- return -1; -- } -- -- if (ISDIRDELIM(*filename)) { -- arg = filename; -- } else { -- sprintf(fullpath, "%s/%s", file_cwd, filename); -- arg = fullpath; -- } -- -- return filesystems[current_filesystem].read(arg, buffer, maxsize); --} -diff --git a/include/fat.h b/include/fat.h -index 18d8981c48..b255ce5337 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -178,25 +178,6 @@ static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) - return fsdata->data_begin + clust * fsdata->clust_size; - } - --typedef int (file_detectfs_func)(void); --typedef int (file_ls_func)(const char *dir); --typedef int (file_read_func)(const char *filename, void *buffer, -- int maxsize); -- --struct filesystem { -- file_detectfs_func *detect; -- file_ls_func *ls; -- file_read_func *read; -- const char name[12]; --}; -- --/* FAT tables */ --file_detectfs_func file_fat_detectfs; --file_ls_func file_fat_ls; --file_read_func file_fat_read; -- --/* Currently this doesn't check if the dir exists or is valid... */ --int file_cd(const char *path); - int file_fat_detectfs(void); - int file_fat_ls(const char *dir); - int fat_exists(const char *filename); -@@ -204,7 +185,6 @@ int fat_size(const char *filename, loff_t *size); - int file_fat_read_at(const char *filename, loff_t pos, void *buffer, - loff_t maxsize, loff_t *actread); - int file_fat_read(const char *filename, void *buffer, int maxsize); --const char *file_getfsname(int idx); - int fat_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info); - int fat_register_device(struct blk_desc *dev_desc, int part_no); - --- -2.13.5 - -From 89191d626793490b579e1d36e7d7a4464a20f9f6 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:58 -0400 -Subject: [PATCH 40/47] fat/fs: move ls to generic implementation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a generic implementation of 'ls' using opendir/readdir/closedir, and -replace fat's custom implementation. Other filesystems should move to -the generic implementation after they add opendir/readdir/closedir -support. - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 32 -------------------------------- - fs/fs.c | 35 +++++++++++++++++++++++++++++++++-- - include/fat.h | 5 ++++- - 3 files changed, 37 insertions(+), 35 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index 82ddb7eab1..c951d84f57 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -1029,38 +1029,6 @@ int file_fat_detectfs(void) - return 0; - } - --int file_fat_ls(const char *dir) --{ -- fsdata fsdata; -- fat_itr itrblock, *itr = &itrblock; -- int files = 0, dirs = 0; -- int ret; -- -- ret = fat_itr_root(itr, &fsdata); -- if (ret) -- return ret; -- -- ret = fat_itr_resolve(itr, dir, TYPE_DIR); -- if (ret) -- return ret; -- -- while (fat_itr_next(itr)) { -- if (fat_itr_isdir(itr)) { -- printf(" %s/\n", itr->name); -- dirs++; -- } else { -- printf(" %8u %s\n", -- FAT2CPU32(itr->dent->size), -- itr->name); -- files++; -- } -- } -- -- printf("\n%d file(s), %d dir(s)\n\n", files, dirs); -- -- return 0; --} -- - int fat_exists(const char *filename) - { - fsdata fsdata; -diff --git a/fs/fs.c b/fs/fs.c -index fc0c953fcb..3481229aa6 100644 ---- a/fs/fs.c -+++ b/fs/fs.c -@@ -37,6 +37,35 @@ static inline int fs_ls_unsupported(const char *dirname) - return -1; - } - -+/* generic implementation of ls in terms of opendir/readdir/closedir */ -+__maybe_unused -+static int fs_ls_generic(const char *dirname) -+{ -+ struct fs_dir_stream *dirs; -+ struct fs_dirent *dent; -+ int nfiles = 0, ndirs = 0; -+ -+ dirs = fs_opendir(dirname); -+ if (!dirs) -+ return -errno; -+ -+ while ((dent = fs_readdir(dirs))) { -+ if (dent->type == FS_DT_DIR) { -+ printf(" %s/\n", dent->name); -+ ndirs++; -+ } else { -+ printf(" %8lld %s\n", dent->size, dent->name); -+ nfiles++; -+ } -+ } -+ -+ fs_closedir(dirs); -+ -+ printf("\n%d file(s), %d dir(s)\n\n", nfiles, ndirs); -+ -+ return 0; -+} -+ - static inline int fs_exists_unsupported(const char *filename) - { - return 0; -@@ -123,7 +152,7 @@ static struct fstype_info fstypes[] = { - .null_dev_desc_ok = false, - .probe = fat_set_blk_dev, - .close = fat_close, -- .ls = file_fat_ls, -+ .ls = fs_ls_generic, - .exists = fat_exists, - .size = fat_size, - .read = fat_read_file, -@@ -133,7 +162,9 @@ static struct fstype_info fstypes[] = { - .write = fs_write_unsupported, - #endif - .uuid = fs_uuid_unsupported, -- .opendir = fs_opendir_unsupported, -+ .opendir = fat_opendir, -+ .readdir = fat_readdir, -+ .closedir = fat_closedir, - }, - #endif - #ifdef CONFIG_FS_EXT4 -diff --git a/include/fat.h b/include/fat.h -index b255ce5337..83cd90017e 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -11,6 +11,7 @@ - #define _FAT_H_ - - #include -+#include - - #define CONFIG_SUPPORT_VFAT - /* Maximum Long File Name length supported here is 128 UTF-16 code units */ -@@ -179,7 +180,6 @@ static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) - } - - int file_fat_detectfs(void); --int file_fat_ls(const char *dir); - int fat_exists(const char *filename); - int fat_size(const char *filename, loff_t *size); - int file_fat_read_at(const char *filename, loff_t pos, void *buffer, -@@ -192,5 +192,8 @@ int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len, - loff_t *actwrite); - int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, - loff_t *actread); -+int fat_opendir(const char *filename, struct fs_dir_stream **dirsp); -+int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); -+void fat_closedir(struct fs_dir_stream *dirs); - void fat_close(void); - #endif /* _FAT_H_ */ --- -2.13.5 - -From 21a24c3bf35bac83d66ce4a48eb0c7dd8a7227cb Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:15:59 -0400 -Subject: [PATCH 41/47] fs/fat: fix case for FAT shortnames -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Noticed when comparing our output to linux. There are some lcase bits -which control whether filename and/or extension should be downcase'd. - -Signed-off-by: Rob Clark -Reviewed-by: Łukasz Majewski -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 16 ++++++++++------ - fs/fat/fat_write.c | 4 ++-- - include/fat.h | 6 +++++- - 3 files changed, 17 insertions(+), 9 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index c951d84f57..65873a2c2a 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -29,11 +29,13 @@ static const int vfat_enabled = 0; - #endif - - /* -- * Convert a string to lowercase. -+ * Convert a string to lowercase. Converts at most 'len' characters, -+ * 'len' may be larger than the length of 'str' if 'str' is NULL -+ * terminated. - */ --static void downcase(char *str) -+static void downcase(char *str, size_t len) - { -- while (*str != '\0') { -+ while (*str != '\0' && len--) { - *str = tolower(*str); - str++; - } -@@ -131,10 +133,13 @@ static void get_name(dir_entry *dirent, char *s_name) - ptr = s_name; - while (*ptr && *ptr != ' ') - ptr++; -+ if (dirent->lcase & CASE_LOWER_BASE) -+ downcase(s_name, (unsigned)(ptr - s_name)); - if (dirent->ext[0] && dirent->ext[0] != ' ') { -- *ptr = '.'; -- ptr++; -+ *ptr++ = '.'; - memcpy(ptr, dirent->ext, 3); -+ if (dirent->lcase & CASE_LOWER_EXT) -+ downcase(ptr, 3); - ptr[3] = '\0'; - while (*ptr && *ptr != ' ') - ptr++; -@@ -144,7 +149,6 @@ static void get_name(dir_entry *dirent, char *s_name) - *s_name = '\0'; - else if (*s_name == aRING) - *s_name = DELETED_FLAG; -- downcase(s_name); - } - - static int flush_dirty_fat_buffer(fsdata *mydata); -diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c -index 4ca024c208..d0468baf8f 100644 ---- a/fs/fat/fat_write.c -+++ b/fs/fat/fat_write.c -@@ -345,7 +345,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, - *l_name = '\0'; - else if (*l_name == aRING) - *l_name = DELETED_FLAG; -- downcase(l_name); -+ downcase(l_name, INT_MAX); - - /* Return the real directory entry */ - *retdent = realdent; -@@ -981,7 +981,7 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size, - - memcpy(l_filename, filename, name_len); - l_filename[name_len] = 0; /* terminate the string */ -- downcase(l_filename); -+ downcase(l_filename, INT_MAX); - - startsect = mydata->rootdir_sect; - retdent = find_directory_entry(mydata, startsect, -diff --git a/include/fat.h b/include/fat.h -index 83cd90017e..0f58939124 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -128,10 +128,14 @@ typedef struct volume_info - /* Boot sign comes last, 2 bytes */ - } volume_info; - -+/* see dir_entry::lcase: */ -+#define CASE_LOWER_BASE 8 /* base (name) is lower case */ -+#define CASE_LOWER_EXT 16 /* extension is lower case */ -+ - typedef struct dir_entry { - char name[8],ext[3]; /* Name and extension */ - __u8 attr; /* Attribute bits */ -- __u8 lcase; /* Case for base and extension */ -+ __u8 lcase; /* Case for name and ext (CASE_LOWER_x) */ - __u8 ctime_ms; /* Creation time, milliseconds */ - __u16 ctime; /* Creation time */ - __u16 cdate; /* Creation date */ --- -2.13.5 - -From 265edc03d5a19550d92cbd6e10631d5a15bdd1d5 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 13:16:00 -0400 -Subject: [PATCH 42/47] fs/fat: Clean up open-coded sector <-> cluster - conversions - -Use the clust_to_sect() helper that was introduced earlier, and add an -inverse sect_to_clust(), plus update the various spots that open-coded -this conversion previously. - -Signed-off-by: Rob Clark -Reviewed-by: Simon Glass ---- - fs/fat/fat.c | 8 +++----- - fs/fat/fat_write.c | 8 +++----- - include/fat.h | 6 +++++- - 3 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index 65873a2c2a..f5f74c12ff 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -257,8 +257,7 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) - int ret; - - if (clustnum > 0) { -- startsect = mydata->data_begin + -- clustnum * mydata->clust_size; -+ startsect = clust_to_sect(mydata, clustnum); - } else { - startsect = mydata->rootdir_sect; - } -@@ -594,9 +593,8 @@ static int get_fs_info(fsdata *mydata) - mydata->data_begin = mydata->rootdir_sect + - mydata->rootdir_size - - (mydata->clust_size * 2); -- mydata->root_cluster = (mydata->rootdir_sect - -- mydata->data_begin) / -- mydata->clust_size; -+ mydata->root_cluster = -+ sect_to_clust(mydata, mydata->rootdir_sect); - } - - mydata->fatbufnum = -1; -diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c -index d0468baf8f..9d2e0ed74c 100644 ---- a/fs/fat/fat_write.c -+++ b/fs/fat/fat_write.c -@@ -502,8 +502,7 @@ set_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, - int ret; - - if (clustnum > 0) -- startsect = mydata->data_begin + -- clustnum * mydata->clust_size; -+ startsect = clust_to_sect(mydata, clustnum); - else - startsect = mydata->rootdir_sect; - -@@ -751,8 +750,7 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size) - __u32 startsect, sect_num, offset; - - if (clustnum > 0) { -- startsect = mydata->data_begin + -- clustnum * mydata->clust_size; -+ startsect = clust_to_sect(mydata, clustnum); - } else { - startsect = mydata->rootdir_sect; - } -@@ -791,7 +789,7 @@ static dir_entry *empty_dentptr; - static dir_entry *find_directory_entry(fsdata *mydata, int startsect, - char *filename, dir_entry *retdent, __u32 start) - { -- __u32 curclust = (startsect - mydata->data_begin) / mydata->clust_size; -+ __u32 curclust = sect_to_clust(mydata, startsect); - - debug("get_dentfromdir: %s\n", filename); - -diff --git a/include/fat.h b/include/fat.h -index 0f58939124..bdeda95e6d 100644 ---- a/include/fat.h -+++ b/include/fat.h -@@ -177,12 +177,16 @@ typedef struct { - __u32 root_cluster; /* First cluster of root dir for FAT32 */ - } fsdata; - --/* TODO clean up places that are open-coding this: */ - static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) - { - return fsdata->data_begin + clust * fsdata->clust_size; - } - -+static inline u32 sect_to_clust(fsdata *fsdata, u32 sect) -+{ -+ return (sect - fsdata->data_begin) / fsdata->clust_size; -+} -+ - int file_fat_detectfs(void); - int fat_exists(const char *filename); - int fat_size(const char *filename, loff_t *size); --- -2.13.5 - -From 725ffdb5cbcc4b8a9726a68cc6ae0713266ba5a9 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Tue, 12 Sep 2017 16:40:01 -0400 -Subject: [PATCH 43/47] fs/fat: fix fatbuf leak -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A new fatbuf was allocated by get_fs_info() (called by fat_itr_root()), -but not freed, resulting in eventually running out of memory. Spotted -by running 'ls -r' in a large FAT filesystem from Shell.efi. - -fatbuf is mainly used to cache FAT entry lookups (get_fatent()).. -possibly once fat_write.c it can move into the iterator to simplify -this. - -Signed-off-by: Rob Clark -Reviewed-by: Simon Glass -Reviewed-by: Łukasz Majewski ---- - fs/fat/fat.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/fs/fat/fat.c b/fs/fat/fat.c -index f5f74c12ff..f0284398b4 100644 ---- a/fs/fat/fat.c -+++ b/fs/fat/fat.c -@@ -1042,6 +1042,7 @@ int fat_exists(const char *filename) - return 0; - - ret = fat_itr_resolve(itr, filename, TYPE_ANY); -+ free(fsdata.fatbuf); - return ret == 0; - } - -@@ -1061,17 +1062,19 @@ int fat_size(const char *filename, loff_t *size) - * Directories don't have size, but fs_size() is not - * expected to fail if passed a directory path: - */ -+ free(fsdata.fatbuf); - fat_itr_root(itr, &fsdata); - if (!fat_itr_resolve(itr, filename, TYPE_DIR)) { - *size = 0; -- return 0; -+ ret = 0; - } -- return ret; -+ goto out; - } - - *size = FAT2CPU32(itr->dent->size); -- -- return 0; -+out: -+ free(fsdata.fatbuf); -+ return ret; - } - - int file_fat_read_at(const char *filename, loff_t pos, void *buffer, -@@ -1087,10 +1090,14 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer, - - ret = fat_itr_resolve(itr, filename, TYPE_FILE); - if (ret) -- return ret; -+ goto out; - - printf("reading %s\n", filename); -- return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); -+ ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); -+ -+out: -+ free(fsdata.fatbuf); -+ return ret; - } - - int file_fat_read(const char *filename, void *buffer, int maxsize) -@@ -1126,7 +1133,7 @@ typedef struct { - - int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) - { -- fat_dir *dir = malloc(sizeof(*dir)); -+ fat_dir *dir = calloc(1, sizeof(*dir)); - int ret; - - if (!dir) -@@ -1144,6 +1151,7 @@ int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) - return 0; - - fail: -+ free(dir->fsdata.fatbuf); - free(dir); - return ret; - } -@@ -1174,6 +1182,7 @@ int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp) - void fat_closedir(struct fs_dir_stream *dirs) - { - fat_dir *dir = (fat_dir *)dirs; -+ free(dir->fsdata.fatbuf); - free(dir); - } - --- -2.13.5 - diff --git a/uefi-vsprintf.patch b/uefi-vsprintf.patch deleted file mode 100644 index 7cd72b2..0000000 --- a/uefi-vsprintf.patch +++ /dev/null @@ -1,544 +0,0 @@ -From 4a85663ec7eddd955d22f1b0f34a9708eac82314 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 06:47:39 -0400 -Subject: [PATCH 002/105] kbuild: Enable -fshort-wchar - -EFI_LOADER really wants UTF-16 strings (ie. %ls and L"string" are 16bit -chars instead of 32bit chars). But rather than enabling -fshort-wchar -conditionally if EFI_LOADER is enabled, it was deemed preferrable to -globally switch. - -Signed-off-by: Rob Clark -Acked-by: Masahiro Yamada ---- - Makefile | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Makefile b/Makefile -index 8086f3c93e..8250b3409a 100644 ---- a/Makefile -+++ b/Makefile -@@ -360,6 +360,7 @@ KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__ - KBUILD_CFLAGS := -Wall -Wstrict-prototypes \ - -Wno-format-security \ - -fno-builtin -ffreestanding -+KBUILD_CFLAGS += -fshort-wchar - KBUILD_AFLAGS := -D__ASSEMBLY__ - - # Read UBOOTRELEASE from include/config/uboot.release (if it exists) --- -2.13.5 - -From 78178bb0c9dfe2a91a636a411291d8bab50e8a7d Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 06:47:40 -0400 -Subject: [PATCH 003/105] lib: add some utf16 handling helpers - -We'll eventually want these in a few places in efi_loader, and also -vsprintf. - -Signed-off-by: Rob Clark ---- - include/charset.h | 65 ++++++++++++++++++++++++++++ - lib/Makefile | 1 + - lib/charset.c | 101 +++++++++++++++++++++++++++++++++++++++++++ - lib/efi_loader/efi_console.c | 17 ++------ - 4 files changed, 170 insertions(+), 14 deletions(-) - create mode 100644 include/charset.h - create mode 100644 lib/charset.c - -diff --git a/include/charset.h b/include/charset.h -new file mode 100644 -index 0000000000..39279f746a ---- /dev/null -+++ b/include/charset.h -@@ -0,0 +1,65 @@ -+/* -+ * charset conversion utils -+ * -+ * Copyright (c) 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef __CHARSET_H_ -+#define __CHARSET_H_ -+ -+#define MAX_UTF8_PER_UTF16 4 -+ -+/** -+ * utf16_strlen() - Get the length of an utf16 string -+ * -+ * Returns the number of 16 bit characters in an utf16 string, not -+ * including the terminating NULL character. -+ * -+ * @in the string to measure -+ * @return the string length -+ */ -+size_t utf16_strlen(const uint16_t *in); -+ -+/** -+ * utf16_strnlen() - Get the length of a fixed-size utf16 string. -+ * -+ * Returns the number of 16 bit characters in an utf16 string, -+ * not including the terminating NULL character, but at most -+ * 'count' number of characters. In doing this, utf16_strnlen() -+ * looks at only the first 'count' characters. -+ * -+ * @in the string to measure -+ * @count the maximum number of characters to count -+ * @return the string length, up to a maximum of 'count' -+ */ -+size_t utf16_strnlen(const uint16_t *in, size_t count); -+ -+/** -+ * utf16_strcpy() - UTF16 equivalent of strcpy() -+ */ -+uint16_t *utf16_strcpy(uint16_t *dest, const uint16_t *src); -+ -+/** -+ * utf16_strdup() - UTF16 equivalent of strdup() -+ */ -+uint16_t *utf16_strdup(const uint16_t *s); -+ -+/** -+ * utf16_to_utf8() - Convert an utf16 string to utf8 -+ * -+ * Converts 'size' characters of the utf16 string 'src' to utf8 -+ * written to the 'dest' buffer. -+ * -+ * NOTE that a single utf16 character can generate up to 4 utf8 -+ * characters. See MAX_UTF8_PER_UTF16. -+ * -+ * @dest the destination buffer to write the utf8 characters -+ * @src the source utf16 string -+ * @size the number of utf16 characters to convert -+ * @return the pointer to the first unwritten byte in 'dest' -+ */ -+uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size); -+ -+#endif /* __CHARSET_H_ */ -diff --git a/lib/Makefile b/lib/Makefile -index da6a11aca3..15bba9eac2 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_OF_LIVE) += of_live.o - obj-$(CONFIG_CMD_DHRYSTONE) += dhry/ - - obj-$(CONFIG_AES) += aes.o -+obj-y += charset.o - obj-$(CONFIG_USB_TTY) += circbuf.o - obj-y += crc7.o - obj-y += crc8.o -diff --git a/lib/charset.c b/lib/charset.c -new file mode 100644 -index 0000000000..ff76e88c77 ---- /dev/null -+++ b/lib/charset.c -@@ -0,0 +1,101 @@ -+/* -+ * charset conversion utils -+ * -+ * Copyright (c) 2017 Rob Clark -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+ -+/* -+ * utf8/utf16 conversion mostly lifted from grub -+ */ -+ -+size_t utf16_strlen(const uint16_t *in) -+{ -+ size_t i; -+ for (i = 0; in[i]; i++); -+ return i; -+} -+ -+size_t utf16_strnlen(const uint16_t *in, size_t count) -+{ -+ size_t i; -+ for (i = 0; count-- && in[i]; i++); -+ return i; -+} -+ -+uint16_t *utf16_strcpy(uint16_t *dest, const uint16_t *src) -+{ -+ uint16_t *tmp = dest; -+ -+ while ((*dest++ = *src++) != '\0') -+ /* nothing */; -+ return tmp; -+ -+} -+ -+uint16_t *utf16_strdup(const uint16_t *s) -+{ -+ uint16_t *new; -+ if (!s || !(new = malloc((utf16_strlen(s) + 1) * 2))) -+ return NULL; -+ utf16_strcpy(new, s); -+ return new; -+} -+ -+/* Convert UTF-16 to UTF-8. */ -+uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size) -+{ -+ uint32_t code_high = 0; -+ -+ while (size--) { -+ uint32_t code = *src++; -+ -+ if (code_high) { -+ if (code >= 0xDC00 && code <= 0xDFFF) { -+ /* Surrogate pair. */ -+ code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000; -+ -+ *dest++ = (code >> 18) | 0xF0; -+ *dest++ = ((code >> 12) & 0x3F) | 0x80; -+ *dest++ = ((code >> 6) & 0x3F) | 0x80; -+ *dest++ = (code & 0x3F) | 0x80; -+ } else { -+ /* Error... */ -+ *dest++ = '?'; -+ /* *src may be valid. Don't eat it. */ -+ src--; -+ } -+ -+ code_high = 0; -+ } else { -+ if (code <= 0x007F) { -+ *dest++ = code; -+ } else if (code <= 0x07FF) { -+ *dest++ = (code >> 6) | 0xC0; -+ *dest++ = (code & 0x3F) | 0x80; -+ } else if (code >= 0xD800 && code <= 0xDBFF) { -+ code_high = code; -+ continue; -+ } else if (code >= 0xDC00 && code <= 0xDFFF) { -+ /* Error... */ -+ *dest++ = '?'; -+ } else if (code < 0x10000) { -+ *dest++ = (code >> 12) | 0xE0; -+ *dest++ = ((code >> 6) & 0x3F) | 0x80; -+ *dest++ = (code & 0x3F) | 0x80; -+ } else { -+ *dest++ = (code >> 18) | 0xF0; -+ *dest++ = ((code >> 12) & 0x3F) | 0x80; -+ *dest++ = ((code >> 6) & 0x3F) | 0x80; -+ *dest++ = (code & 0x3F) | 0x80; -+ } -+ } -+ } -+ -+ return dest; -+} -diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c -index 5ebce4b544..3fc82b8726 100644 ---- a/lib/efi_loader/efi_console.c -+++ b/lib/efi_loader/efi_console.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - - static bool console_size_queried; -@@ -138,20 +139,8 @@ static efi_status_t EFIAPI efi_cout_reset( - - static void print_unicode_in_utf8(u16 c) - { -- char utf8[4] = { 0 }; -- char *b = utf8; -- -- if (c < 0x80) { -- *(b++) = c; -- } else if (c < 0x800) { -- *(b++) = 192 + c / 64; -- *(b++) = 128 + c % 64; -- } else { -- *(b++) = 224 + c / 4096; -- *(b++) = 128 + c / 64 % 64; -- *(b++) = 128 + c % 64; -- } -- -+ char utf8[MAX_UTF8_PER_UTF16] = { 0 }; -+ utf16_to_utf8((u8 *)utf8, &c, 1); - puts(utf8); - } - --- -2.13.5 - -From 274325c50951dd16ad2a6f45e79dc062ad47011b Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 06:47:41 -0400 -Subject: [PATCH 004/105] vsprintf.c: add UTF-16 string (%ls) support - -This is convenient for efi_loader which deals a lot with UTF-16. Only -enabled with CC_SHORT_WCHAR, leaving room to add a UTF-32 version when -CC_SHORT_WCHAR is not enabled. - -Signed-off-by: Rob Clark -Reviewed-by: Simon Glass -Reviewed-by: Simon Glass ---- - examples/api/Makefile | 1 + - lib/vsprintf.c | 30 ++++++++++++++++++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/examples/api/Makefile b/examples/api/Makefile -index dab6398bab..87c15d0f68 100644 ---- a/examples/api/Makefile -+++ b/examples/api/Makefile -@@ -34,6 +34,7 @@ EXT_COBJ-y += lib/div64.o - EXT_COBJ-y += lib/string.o - EXT_COBJ-y += lib/time.o - EXT_COBJ-y += lib/vsprintf.o -+EXT_COBJ-y += lib/charset.o - EXT_SOBJ-$(CONFIG_PPC) += arch/powerpc/lib/ppcstring.o - ifeq ($(ARCH),arm) - EXT_SOBJ-$(CONFIG_USE_ARCH_MEMSET) += arch/arm/lib/memset.o -diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 874a2951f7..97bed9d36d 100644 ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -17,6 +17,7 @@ - #include - - #include -+#include - - #include - #define noinline __attribute__((noinline)) -@@ -270,6 +271,26 @@ static char *string(char *buf, char *end, char *s, int field_width, - return buf; - } - -+static char *string16(char *buf, char *end, u16 *s, int field_width, -+ int precision, int flags) -+{ -+ u16 *str = s ? s : L""; -+ int utf16_len = utf16_strnlen(str, precision); -+ u8 utf8[utf16_len * MAX_UTF8_PER_UTF16]; -+ int utf8_len, i; -+ -+ utf8_len = utf16_to_utf8(utf8, str, utf16_len) - utf8; -+ -+ if (!(flags & LEFT)) -+ while (utf8_len < field_width--) -+ ADDCH(buf, ' '); -+ for (i = 0; i < utf8_len; ++i) -+ ADDCH(buf, utf8[i]); -+ while (utf8_len < field_width--) -+ ADDCH(buf, ' '); -+ return buf; -+} -+ - #ifdef CONFIG_CMD_NET - static const char hex_asc[] = "0123456789abcdef"; - #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] -@@ -528,8 +549,13 @@ repeat: - continue; - - case 's': -- str = string(str, end, va_arg(args, char *), -- field_width, precision, flags); -+ if (qualifier == 'l' && !IS_ENABLED(CONFIG_SPL_BUILD)) { -+ str = string16(str, end, va_arg(args, u16 *), -+ field_width, precision, flags); -+ } else { -+ str = string(str, end, va_arg(args, char *), -+ field_width, precision, flags); -+ } - continue; - - case 'p': --- -2.13.5 - -From 22ada0c8e6d50281af72176eecdfc356c794639c Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 06:47:42 -0400 -Subject: [PATCH 005/105] vsprintf.c: add GUID printing - -This works (roughly) the same way as linux's, but we currently always -print lower-case (ie. we just keep %pUB and %pUL for compat with linux), -mostly just because that is what uuid_bin_to_str() supports. - - %pUb: 01020304-0506-0708-090a-0b0c0d0e0f10 - %pUl: 04030201-0605-0807-090a-0b0c0d0e0f10 - -It will be used by a later efi_loader paths for efi variables and for -device-path-to-text protocol, and also quite useful for debug prints -of protocol GUIDs. - -Signed-off-by: Rob Clark -Tested-by: Heinrich Schuchardt -Reviewed-by: Simon Glass ---- - examples/api/Makefile | 1 + - include/config_fallbacks.h | 1 + - lib/vsprintf.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 46 insertions(+), 2 deletions(-) - -diff --git a/examples/api/Makefile b/examples/api/Makefile -index 87c15d0f68..899527267d 100644 ---- a/examples/api/Makefile -+++ b/examples/api/Makefile -@@ -35,6 +35,7 @@ EXT_COBJ-y += lib/string.o - EXT_COBJ-y += lib/time.o - EXT_COBJ-y += lib/vsprintf.o - EXT_COBJ-y += lib/charset.o -+EXT_COBJ-$(CONFIG_LIB_UUID) += lib/uuid.o - EXT_SOBJ-$(CONFIG_PPC) += arch/powerpc/lib/ppcstring.o - ifeq ($(ARCH),arm) - EXT_SOBJ-$(CONFIG_USE_ARCH_MEMSET) += arch/arm/lib/memset.o -diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h -index 46b7a2a6f2..2c4d43d672 100644 ---- a/include/config_fallbacks.h -+++ b/include/config_fallbacks.h -@@ -58,6 +58,7 @@ - - #if (CONFIG_IS_ENABLED(PARTITION_UUIDS) || \ - CONFIG_IS_ENABLED(EFI_PARTITION) || \ -+ CONFIG_IS_ENABLED(EFI_LOADER) || \ - defined(CONFIG_RANDOM_UUID) || \ - defined(CONFIG_CMD_UUID) || \ - defined(CONFIG_BOOTP_PXE)) && \ -diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 97bed9d36d..dd572d2868 100644 ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -18,6 +18,7 @@ - - #include - #include -+#include - - #include - #define noinline __attribute__((noinline)) -@@ -366,6 +367,40 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, - } - #endif - -+#ifdef CONFIG_LIB_UUID -+/* -+ * This works (roughly) the same way as linux's, but we currently always -+ * print lower-case (ie. we just keep %pUB and %pUL for compat with linux), -+ * mostly just because that is what uuid_bin_to_str() supports. -+ * -+ * %pUb: 01020304-0506-0708-090a-0b0c0d0e0f10 -+ * %pUl: 04030201-0605-0807-090a-0b0c0d0e0f10 -+ */ -+static char *uuid_string(char *buf, char *end, u8 *addr, int field_width, -+ int precision, int flags, const char *fmt) -+{ -+ char uuid[UUID_STR_LEN + 1]; -+ int str_format = UUID_STR_FORMAT_STD; -+ -+ switch (*(++fmt)) { -+ case 'L': -+ case 'l': -+ str_format = UUID_STR_FORMAT_GUID; -+ break; -+ case 'B': -+ case 'b': -+ /* this is the default */ -+ break; -+ default: -+ break; -+ } -+ -+ uuid_bin_to_str(addr, uuid, str_format); -+ -+ return string(buf, end, uuid, field_width, precision, flags); -+} -+#endif -+ - /* - * Show a '%p' thing. A kernel extension is that the '%p' is followed - * by an extra set of alphanumeric characters that are extended format -@@ -399,8 +434,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, - flags); - #endif - --#ifdef CONFIG_CMD_NET - switch (*fmt) { -+#ifdef CONFIG_CMD_NET - case 'a': - flags |= SPECIAL | ZEROPAD; - -@@ -430,8 +465,15 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, - precision, flags); - flags &= ~SPECIAL; - break; -- } - #endif -+#ifdef CONFIG_LIB_UUID -+ case 'U': -+ return uuid_string(buf, end, ptr, field_width, precision, -+ flags, fmt); -+#endif -+ default: -+ break; -+ } - flags |= SMALL; - if (field_width == -1) { - field_width = 2*sizeof(void *); --- -2.13.5 - -From 7e3e20560784b048ff19e90cd36b6680626b1ab3 Mon Sep 17 00:00:00 2001 -From: Rob Clark -Date: Sat, 9 Sep 2017 06:47:43 -0400 -Subject: [PATCH 006/105] examples: add fallback memcpy - -Solves build issue: - - Building current source for 134 boards (12 threads, 1 job per thread) - arm: + lsxhl - +examples/api/vsprintf.o: In function `string16': - +lib/vsprintf.c:278: undefined reference to `memcpy' - +examples/api/uuid.o: In function `uuid_bin_to_str': - +lib/uuid.c:197: undefined reference to `memcpy' - +lib/uuid.c:199: undefined reference to `memcpy' - +make[3]: *** [examples/api/demo] Error 1 - +make[2]: *** [examples/api] Error 2 - +make[1]: *** [examples] Error 2 - +make: *** [sub-make] Error 2 - 133 0 1 /134 sheevaplug - -Signed-off-by: Rob Clark ---- - examples/api/glue.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/examples/api/glue.c b/examples/api/glue.c -index 8aabf32c89..575c1e55f3 100644 ---- a/examples/api/glue.c -+++ b/examples/api/glue.c -@@ -416,3 +416,15 @@ void ub_display_clear(void) - { - syscall(API_DISPLAY_CLEAR, NULL); - } -+ -+__weak void *memcpy(void *dest, const void *src, size_t size) -+{ -+ unsigned char *dptr = dest; -+ const unsigned char *ptr = src; -+ const unsigned char *end = src + size; -+ -+ while (ptr < end) -+ *dptr++ = *ptr++; -+ -+ return dest; -+} --- -2.13.5 - diff --git a/usb-kbd-fixes.patch b/usb-kbd-fixes.patch index 3b86b29..ca6fc04 100644 --- a/usb-kbd-fixes.patch +++ b/usb-kbd-fixes.patch @@ -182,3 +182,29 @@ index 4c3ad95fca..82ad93f6ca 100644 } #ifndef CONFIG_DM_USB + +From 47f22a41df082c62411389ab5bf6e9ae26d93083 Mon Sep 17 00:00:00 2001 +From: Rob Clark +Date: Wed, 19 Jul 2017 10:39:12 -0400 +Subject: [PATCH 13/23] usb: kbd: add missing \n + +Signed-off-by: Rob Clark +--- + common/usb_kbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/usb_kbd.c b/common/usb_kbd.c +index 703dd748f5..92d5e96d01 100644 +--- a/common/usb_kbd.c ++++ b/common/usb_kbd.c +@@ -655,7 +655,7 @@ static int usb_kbd_remove(struct udevice *dev) + + return 0; + err: +- printf("%s: warning, ret=%d", __func__, ret); ++ printf("%s: warning, ret=%d\n", __func__, ret); + return ret; + } + +-- +2.13.3