Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
authorTom Rini <trini@konsulko.com>
Wed, 5 Feb 2020 12:19:52 +0000 (07:19 -0500)
committerTom Rini <trini@konsulko.com>
Wed, 5 Feb 2020 12:19:52 +0000 (07:19 -0500)
- Bug fixes on ls1012a, ls1021a, ls1028ardb platforms Integrate fspi for
  ls1028a, add DM-I2C support, update secure boot header offset

81 files changed:
.azure-pipelines.yml
MAINTAINERS
arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
arch/arm/dts/k3-j721e-common-proc-board.dts
arch/arm/dts/k3-j721e-main.dtsi
arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
arch/arm/dts/k3-j721e-r5-common-proc-board.dts
arch/arm/dts/k3-j721e.dtsi
arch/arm/mach-bcm283x/init.c
arch/arm/mach-k3/include/mach/j721e_spl.h
arch/arm/mach-k3/sysfw-loader.c
arch/x86/Kconfig
arch/x86/cpu/apollolake/Kconfig
arch/x86/cpu/apollolake/Makefile
arch/x86/cpu/apollolake/itss.c [deleted file]
arch/x86/cpu/i386/cpu.c
arch/x86/cpu/intel_common/Makefile
arch/x86/cpu/intel_common/itss.c [new file with mode: 0644]
arch/x86/cpu/slimbootloader/serial.c
arch/x86/cpu/start.S
arch/x86/cpu/start16.S
arch/x86/dts/chromebook_coral.dts
arch/x86/dts/coreboot.dts
arch/x86/include/asm/arch-apollolake/itss.h [deleted file]
arch/x86/include/asm/coreboot_tables.h
arch/x86/include/asm/itss.h [new file with mode: 0644]
cmd/Kconfig
cmd/Makefile
cmd/abootimg.c [new file with mode: 0644]
common/Makefile
common/image-android.c
configs/am57xx_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/am57xx_hs_evm_usb_defconfig
configs/edison_defconfig
configs/j721e_evm_a72_defconfig
configs/j721e_evm_r5_defconfig
configs/rpi_4_32b_defconfig
configs/rpi_4_defconfig
configs/rpi_arm64_defconfig
configs/sandbox_defconfig
doc/android/ab.rst [new file with mode: 0644]
doc/android/ab.txt [deleted file]
doc/android/avb2.rst [new file with mode: 0644]
doc/android/avb2.txt [deleted file]
doc/android/bcb.rst [new file with mode: 0644]
doc/android/bcb.txt [deleted file]
doc/android/boot-image.rst [new file with mode: 0644]
doc/android/fastboot-protocol.rst [new file with mode: 0644]
doc/android/fastboot-protocol.txt [deleted file]
doc/android/fastboot.rst [new file with mode: 0644]
doc/android/fastboot.txt [deleted file]
doc/android/index.rst [new file with mode: 0644]
doc/board/google/chromebook_coral.rst
doc/board/intel/slimbootloader.rst
doc/index.rst
drivers/dfu/dfu_mmc.c
drivers/gpio/da8xx_gpio.c
drivers/gpio/intel_gpio.c
drivers/gpio/pca953x_gpio.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/bcmgenet.c [new file with mode: 0644]
drivers/pinctrl/intel/pinctrl.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/ns16550.c
drivers/serial/serial_coreboot.c [new file with mode: 0644]
drivers/spi/ich.c
drivers/usb/gadget/dwc2_udc_otg.c
drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
drivers/watchdog/omap_wdt.c
include/configs/j721e_evm.h
include/configs/rpi.h
include/configs/slimbootloader.h
include/configs/ti_armv7_common.h
include/environment/ti/boot.h
include/image.h
include/ns16550.h
test/py/tests/test_android/test_abootimg.py [new file with mode: 0644]
test/py/tests/test_android/test_avb.py

index 916ab84ea0c49e177094ee239486d1dcf3eb293b..a0713dd66c0ad25d46ec8988e7b9accd28414217 100644 (file)
@@ -1,5 +1,5 @@
 variables:
-  windows_vm: vs2015-win2012r2
+  windows_vm: vs2017-win2016
   ubuntu_vm: ubuntu-18.04
   ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20200112-17Jan2020
   # Add '-u 0' options for Azure pipelines, otherwise we get "permission
index b0634b23bc875a05240d75a402e639fddb5ec928..9dce9f10f23ee1d269da3a144cf9c14e8b1d0204 100644 (file)
@@ -56,7 +56,7 @@ R:    Sam Protsenko <joe.skb7@gmail.com>
 S:     Maintained
 F:     cmd/ab_select.c
 F:     common/android_ab.c
-F:     doc/android/ab.txt
+F:     doc/android/ab.rst
 F:     include/android_ab.h
 F:     test/py/tests/test_android/test_ab.py
 
@@ -65,7 +65,7 @@ M:    Igor Opaniuk <igor.opaniuk@gmail.com>
 S:     Maintained
 F:     cmd/avb.c
 F:     common/avb_verify.c
-F:     doc/android/avb2.txt
+F:     doc/android/avb2.rst
 F:     include/avb_verify.h
 F:     lib/libavb/
 F:     test/py/tests/test_android/test_avb.py
index 7ea4d8de367e07007885d3ea4fd11fa476adde27..a3a81932168e76c9a01d4c7c9fe99b6a218ebd45 100644 (file)
 &wkup_i2c0 {
        u-boot,dm-spl;
 };
+
+&main_i2c0 {
+       u-boot,dm-spl;
+};
+
+&main_i2c0_pins_default {
+       u-boot,dm-spl;
+};
+
+&exp2 {
+       u-boot,dm-spl;
+};
index f33a6d5bcff566cea0005ba57abc10caa09c7d3d..d216b707fd2cbc144c8002f4450a47d19dbb1910 100644 (file)
                        J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
                >;
        };
+
+       main_i2c0_pins_default: main-i2c0-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (AC5) I2C0_SCL */
+                       J721E_IOPAD(0x224, PIN_INPUT_PULLUP, 0) /* (AA5) I2C0_SDA */
+               >;
+       };
 };
 
 &wkup_pmx0 {
        pinctrl-0 = <&wkup_i2c0_pins_default>;
        clock-frequency = <400000>;
 };
+
+&main_i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c0_pins_default>;
+       clock-frequency = <400000>;
+
+       exp1: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       exp2: gpio@22 {
+               compatible = "ti,tca6424";
+               reg = <0x22>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
index 5083a0c3aef05cff2d197db2e98e75f0a005f292..45ac98c47ed37f5aff21ae52572daa17b657a230 100644 (file)
                clock-names = "fclk";
        };
 
+       main_gpio0: gpio@600000 {
+               compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+               reg = <0x0 0x00600000 0x0 0x100>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupts = <105 0 IRQ_TYPE_EDGE_RISING>,
+                            <105 1 IRQ_TYPE_EDGE_RISING>,
+                            <105 2 IRQ_TYPE_EDGE_RISING>,
+                            <105 3 IRQ_TYPE_EDGE_RISING>,
+                            <105 4 IRQ_TYPE_EDGE_RISING>,
+                            <105 5 IRQ_TYPE_EDGE_RISING>,
+                            <105 6 IRQ_TYPE_EDGE_RISING>,
+                            <105 7 IRQ_TYPE_EDGE_RISING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               ti,ngpio = <128>;
+               ti,davinci-gpio-unbanked = <0>;
+               power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 105 0>;
+               clock-names = "gpio";
+       };
+
        main_sdhci0: sdhci@4f80000 {
                compatible = "ti,j721e-sdhci-8bit";
                reg = <0x0 0x4f80000 0x0 0x1000>, <0x0 0x4f88000 0x0 0x400>;
                        dma-coherent;
                };
        };
+
+       main_i2c0: i2c@2000000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2000000 0x0 0x100>;
+               interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 187 0>;
+               power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c1: i2c@2010000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2010000 0x0 0x100>;
+               interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 188 0>;
+               power-domains = <&k3_pds 188 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c2: i2c@2020000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2020000 0x0 0x100>;
+               interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 189 0>;
+               power-domains = <&k3_pds 189 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c3: i2c@2030000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2030000 0x0 0x100>;
+               interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 190 0>;
+               power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c4: i2c@2040000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2040000 0x0 0x100>;
+               interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 191 0>;
+               power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c5: i2c@2050000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2050000 0x0 0x100>;
+               interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 192 0>;
+               power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c6: i2c@2060000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2060000 0x0 0x100>;
+               interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 193 0>;
+               power-domains = <&k3_pds 193 TI_SCI_PD_EXCLUSIVE>;
+       };
 };
index 5dd07ac4daf7380ba8897332506d47bc1f30cb06..fe52fd1b2f9f07fde90abd79b48d1376b1f59d7d 100644 (file)
                        assigned-clock-rates = <250000000>;
                };
        };
+
+       mcu_i2c0: i2c@40b00000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x40b00000 0x0 0x100>;
+               interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 194 0>;
+               power-domains = <&k3_pds 194 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       mcu_i2c1: i2c@40b10000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x40b10000 0x0 0x100>;
+               interrupts = <GIC_SPI 853 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 195 0>;
+               power-domains = <&k3_pds 195 TI_SCI_PD_EXCLUSIVE>;
+       };
 };
index 28a355d49c9b10af64bb28a1bbe9c59b993c73b0..1f14d71438b4ff800a75f521e35fe446787fde14 100644 (file)
                clock-frequency = <200000000>;
                u-boot,dm-spl;
        };
+
+       clk_19_2mhz: dummy_clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <19200000>;
+               u-boot,dm-spl;
+       };
 };
 
 &cbass_mcu_wakeup {
                        J721E_IOPAD(0x25c, PIN_INPUT, 0) /* (R28) MMC1_SDWP */
                >;
        };
+
+       main_i2c0_pins_default: main-i2c0-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (AC5) I2C0_SCL */
+                       J721E_IOPAD(0x224, PIN_INPUT_PULLUP, 0) /* (AA5) I2C0_SDA */
+               >;
+       };
 };
 
 &wkup_uart0 {
        u-boot,dm-spl;
 };
 
+&usbss0 {
+       /delete-property/ power-domains;
+       /delete-property/ assigned-clocks;
+       /delete-property/ assigned-clock-parents;
+       clocks = <&clk_19_2mhz>;
+       clock-names = "usb2_refclk";
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_usbss0_pins_default>;
+       ti,vbus-divider;
+};
+
+&main_i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c0_pins_default>;
+       clock-frequency = <400000>;
+
+       exp1: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       exp2: gpio@22 {
+               compatible = "ti,tca6424";
+               reg = <0x22>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
 #include "k3-j721e-common-proc-board-u-boot.dtsi"
index aea17e25a29142bd8270c672b1f84af009289518..68ba517e50098afd17850e534883f658cab420f4 100644 (file)
                serial9 = &main_uart7;
                serial10 = &main_uart8;
                serial11 = &main_uart9;
+               i2c0 = &wkup_i2c0;
+               i2c1 = &mcu_i2c0;
+               i2c2 = &mcu_i2c1;
+               i2c3 = &main_i2c0;
+               i2c4 = &main_i2c1;
+               i2c5 = &main_i2c2;
+               i2c6 = &main_i2c3;
+               i2c7 = &main_i2c4;
+               i2c8 = &main_i2c5;
+               i2c9 = &main_i2c6;
        };
 
        chosen { };
index 3b5f45b431ac24df3e8beade2d98d45896077698..9966d6c8336bd850129a0d0809d5d674cfbba151 100644 (file)
@@ -42,9 +42,9 @@ static struct mm_region bcm2711_mem_map[] = {
                .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
                         PTE_BLOCK_INNER_SHARE
        }, {
-               .virt = 0xfe000000UL,
-               .phys = 0xfe000000UL,
-               .size = 0x01800000UL,
+               .virt = 0xfc000000UL,
+               .phys = 0xfc000000UL,
+               .size = 0x03800000UL,
                .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
                         PTE_BLOCK_NON_SHARE |
                         PTE_BLOCK_PXN | PTE_BLOCK_UXN
index 2b52faf9443b852b1cbb72ef44a40291eae84c04..475278bd041a752da2629e49409fd6f137ba83cc 100644 (file)
@@ -18,7 +18,7 @@
 /* With BootMode B = 1 */
 #define BOOT_DEVICE_MMC2               0x10
 #define BOOT_DEVICE_MMC1               0x11
-#define BOOT_DEVICE_USB                        0x12
+#define BOOT_DEVICE_DFU                        0x12
 #define BOOT_DEVICE_UFS                        0x13
 #define BOOT_DEVIE_GPMC                        0x14
 #define BOOT_DEVICE_PCIE               0x15
index 5903bbe12aa3b46231c2f106b8789efec1eb21c7..94dbeb9437d9472ca3e469a741c82156bf44c896 100644 (file)
 #include <malloc.h>
 #include <remoteproc.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <g_dnl.h>
+#include <usb.h>
+#include <dfu.h>
+
 #include <asm/arch/sys_proto.h>
 #include "common.h"
 
@@ -172,6 +176,27 @@ static void k3_sysfw_configure_using_fit(void *fit,
                      ret);
 }
 
+#if CONFIG_IS_ENABLED(DFU)
+static int k3_sysfw_dfu_download(void *addr)
+{
+       char dfu_str[50];
+       int ret;
+
+       sprintf(dfu_str, "sysfw.itb ram 0x%p 0x%x", addr,
+               CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
+       ret = dfu_config_entities(dfu_str, "ram", "0");
+       if (ret) {
+               dfu_free_entities();
+               goto exit;
+       }
+
+       run_usb_dnl_gadget(0, "usb_dnl_dfu");
+exit:
+       dfu_free_entities();
+       return ret;
+}
+#endif
+
 void k3_sysfw_loader(void (*config_pm_done_callback)(void))
 {
        struct spl_image_info spl_image = { 0 };
@@ -235,6 +260,11 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
 #endif
                ret = spl_ymodem_load_image(&spl_image, &bootdev);
                break;
+#endif
+#if CONFIG_IS_ENABLED(DFU)
+       case BOOT_DEVICE_DFU:
+               ret = k3_sysfw_dfu_download(sysfw_load_address);
+               break;
 #endif
        default:
                panic("Loading SYSFW image from device %u not supported!\n",
index 89b93e5de25aa7228a7699ec373efa189697a089..b733d2264efa1595c839e2fd73d6f8cb919909ff 100644 (file)
@@ -709,6 +709,12 @@ config ROM_TABLE_SIZE
        hex
        default 0x10000
 
+config HAVE_ITSS
+       bool "Enable ITSS"
+       help
+         Select this to include the driver for the Interrupt Timer
+         Subsystem (ITSS) which is found on several Intel devices.
+
 menu "System tables"
        depends on !EFI && !SYS_COREBOOT
 
index fcff176c27d11aa9d34b834893615632a408c5b8..a760e0ac68ea27aa6813a52580634095e1ceab49 100644 (file)
@@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE
        imply HAVE_X86_FIT
        imply INTEL_GPIO
        imply SMP
+       imply HAVE_ITSS
 
 if INTEL_APOLLOLAKE
 
index 1760df54d810d069e59ca57a3723c307b927f6d4..f99f2c6473971cf474c64da4063e226c99abbefb 100644 (file)
@@ -19,7 +19,6 @@ obj-y += fsp_s.o
 endif
 
 obj-y += hostbridge.o
-obj-y += itss.o
 obj-y += lpc.o
 obj-y += p2sb.o
 obj-y += pch.o
diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c
deleted file mode 100644 (file)
index 8789f8e..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Something to do with Interrupts, but I don't know what ITSS stands for
- *
- * Copyright (C) 2017 Intel Corporation.
- * Copyright (C) 2017 Siemens AG
- * Copyright 2019 Google LLC
- *
- * Taken from coreboot itss.c
- */
-
-#include <common.h>
-#include <dm.h>
-#include <dt-structs.h>
-#include <irq.h>
-#include <p2sb.h>
-#include <spl.h>
-#include <asm/arch/itss.h>
-
-struct apl_itss_platdata {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-       /* Put this first since driver model will copy the data here */
-       struct dtd_intel_apl_itss dtplat;
-#endif
-};
-
-/* struct pmc_route - Routing for PMC to GPIO */
-struct pmc_route {
-       u32 pmc;
-       u32 gpio;
-};
-
-struct apl_itss_priv {
-       struct pmc_route *route;
-       uint route_count;
-       u32 irq_snapshot[NUM_IPC_REGS];
-};
-
-static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
-{
-       u32 mask;
-       uint reg;
-
-       if (irq > ITSS_MAX_IRQ)
-               return -EINVAL;
-
-       reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC);
-       mask = 1 << (irq % IRQS_PER_IPC);
-
-       pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0);
-
-       return 0;
-}
-
-#ifndef CONFIG_TPL_BUILD
-static int apl_snapshot_polarities(struct udevice *dev)
-{
-       struct apl_itss_priv *priv = dev_get_priv(dev);
-       const int start = GPIO_IRQ_START;
-       const int end = GPIO_IRQ_END;
-       int reg_start;
-       int reg_end;
-       int i;
-
-       reg_start = start / IRQS_PER_IPC;
-       reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
-
-       for (i = reg_start; i < reg_end; i++) {
-               uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
-
-               priv->irq_snapshot[i] = pcr_read32(dev, reg);
-       }
-
-       return 0;
-}
-
-static void show_polarities(struct udevice *dev, const char *msg)
-{
-       int i;
-
-       log_info("ITSS IRQ Polarities %s:\n", msg);
-       for (i = 0; i < NUM_IPC_REGS; i++) {
-               uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
-
-               log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
-       }
-}
-
-static int apl_restore_polarities(struct udevice *dev)
-{
-       struct apl_itss_priv *priv = dev_get_priv(dev);
-       const int start = GPIO_IRQ_START;
-       const int end = GPIO_IRQ_END;
-       int reg_start;
-       int reg_end;
-       int i;
-
-       show_polarities(dev, "Before");
-
-       reg_start = start / IRQS_PER_IPC;
-       reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
-
-       for (i = reg_start; i < reg_end; i++) {
-               u32 mask;
-               u16 reg;
-               int irq_start;
-               int irq_end;
-
-               irq_start = i * IRQS_PER_IPC;
-               irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
-
-               if (start > irq_end)
-                       continue;
-               if (end < irq_start)
-                       break;
-
-               /* Track bits within the bounds of of the register */
-               irq_start = max(start, irq_start) % IRQS_PER_IPC;
-               irq_end = min(end, irq_end) % IRQS_PER_IPC;
-
-               /* Create bitmask of the inclusive range of start and end */
-               mask = (((1U << irq_end) - 1) | (1U << irq_end));
-               mask &= ~((1U << irq_start) - 1);
-
-               reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
-               pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]);
-       }
-
-       show_polarities(dev, "After");
-
-       return 0;
-}
-#endif
-
-static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
-{
-       struct apl_itss_priv *priv = dev_get_priv(dev);
-       struct pmc_route *route;
-       int i;
-
-       for (i = 0, route = priv->route; i < priv->route_count; i++, route++) {
-               if (pmc_gpe_num == route->pmc)
-                       return route->gpio;
-       }
-
-       return -ENOENT;
-}
-
-static int apl_itss_ofdata_to_platdata(struct udevice *dev)
-{
-       struct apl_itss_priv *priv = dev_get_priv(dev);
-       int ret;
-
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-       struct apl_itss_platdata *plat = dev_get_platdata(dev);
-       struct dtd_intel_apl_itss *dtplat = &plat->dtplat;
-
-       /*
-        * It would be nice to do this in the bind() method, but with
-        * of-platdata binding happens in the order that DM finds things in the
-        * linker list (i.e. alphabetical order by driver name). So the GPIO
-        * device may well be bound before its parent (p2sb), and this call
-        * will fail if p2sb is not bound yet.
-        *
-        * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
-        */
-       ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id);
-       if (ret)
-               return log_msg_ret("Could not set port id", ret);
-       priv->route = (struct pmc_route *)dtplat->intel_pmc_routes;
-       priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) /
-                sizeof(struct pmc_route);
-#else
-       int size;
-
-       size = dev_read_size(dev, "intel,pmc-routes");
-       if (size < 0)
-               return size;
-       priv->route = malloc(size);
-       if (!priv->route)
-               return -ENOMEM;
-       ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route,
-                                size / sizeof(fdt32_t));
-       if (ret)
-               return log_msg_ret("Cannot read pmc-routes", ret);
-       priv->route_count = size / sizeof(struct pmc_route);
-#endif
-
-       return 0;
-}
-
-static const struct irq_ops apl_itss_ops = {
-       .route_pmc_gpio_gpe     = apl_route_pmc_gpio_gpe,
-       .set_polarity   = apl_set_polarity,
-#ifndef CONFIG_TPL_BUILD
-       .snapshot_polarities = apl_snapshot_polarities,
-       .restore_polarities = apl_restore_polarities,
-#endif
-};
-
-static const struct udevice_id apl_itss_ids[] = {
-       { .compatible = "intel,apl-itss"},
-       { }
-};
-
-U_BOOT_DRIVER(apl_itss_drv) = {
-       .name           = "intel_apl_itss",
-       .id             = UCLASS_IRQ,
-       .of_match       = apl_itss_ids,
-       .ops            = &apl_itss_ops,
-       .ofdata_to_platdata = apl_itss_ofdata_to_platdata,
-       .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata),
-       .priv_auto_alloc_size = sizeof(struct apl_itss_priv),
-};
index 1592b2c9d3b3a503251af4317b6541db89721e29..c8da7f10e9b611739b821d5d4c004b3acfc482f0 100644 (file)
@@ -136,10 +136,14 @@ void arch_setup_gd(gd_t *new_gd)
        /* DS: data, read/write, 4 GB, base 0 */
        gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
 
-       /* FS: data, read/write, 4 GB, base (Global Data Pointer) */
+       /*
+        * FS: data, read/write, sizeof (Global Data Pointer),
+        * base (Global Data Pointer)
+        */
        new_gd->arch.gd_addr = new_gd;
-       gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
-                    (ulong)&new_gd->arch.gd_addr, 0xfffff);
+       gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093,
+                                       (ulong)&new_gd->arch.gd_addr,
+                                       sizeof(new_gd->arch.gd_addr) - 1);
 
        /* 16-bit CS: code, read/execute, 64 kB, base 0 */
        gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);
index cc4e1c962b99542e4eab09369064e54bd948706b..e22c70781d60644ef5661c1ee29de3b1e411b08d 100644 (file)
@@ -27,6 +27,7 @@ obj-y += microcode.o
 endif
 endif
 obj-y += pch.o
+obj-$(CONFIG_HAVE_ITSS) += itss.o
 
 ifdef CONFIG_SPL
 ifndef CONFIG_SPL_BUILD
diff --git a/arch/x86/cpu/intel_common/itss.c b/arch/x86/cpu/intel_common/itss.c
new file mode 100644 (file)
index 0000000..9df51ad
--- /dev/null
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt Timer Subsystem
+ *
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright (C) 2017 Siemens AG
+ * Copyright 2019 Google LLC
+ *
+ * Taken from coreboot itss.c
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <irq.h>
+#include <p2sb.h>
+#include <spl.h>
+#include <asm/itss.h>
+
+struct itss_platdata {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       /* Put this first since driver model will copy the data here */
+       struct dtd_intel_itss dtplat;
+#endif
+};
+
+/* struct pmc_route - Routing for PMC to GPIO */
+struct pmc_route {
+       u32 pmc;
+       u32 gpio;
+};
+
+struct itss_priv {
+       struct pmc_route *route;
+       uint route_count;
+       u32 irq_snapshot[NUM_IPC_REGS];
+};
+
+static int set_polarity(struct udevice *dev, uint irq, bool active_low)
+{
+       u32 mask;
+       uint reg;
+
+       if (irq > ITSS_MAX_IRQ)
+               return -EINVAL;
+
+       reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC);
+       mask = 1 << (irq % IRQS_PER_IPC);
+
+       pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0);
+
+       return 0;
+}
+
+#ifndef CONFIG_TPL_BUILD
+static int snapshot_polarities(struct udevice *dev)
+{
+       struct itss_priv *priv = dev_get_priv(dev);
+       const int start = GPIO_IRQ_START;
+       const int end = GPIO_IRQ_END;
+       int reg_start;
+       int reg_end;
+       int i;
+
+       reg_start = start / IRQS_PER_IPC;
+       reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
+
+       for (i = reg_start; i < reg_end; i++) {
+               uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+
+               priv->irq_snapshot[i] = pcr_read32(dev, reg);
+       }
+
+       return 0;
+}
+
+static void show_polarities(struct udevice *dev, const char *msg)
+{
+       int i;
+
+       log_info("ITSS IRQ Polarities %s:\n", msg);
+       for (i = 0; i < NUM_IPC_REGS; i++) {
+               uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+
+               log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg));
+       }
+}
+
+static int restore_polarities(struct udevice *dev)
+{
+       struct itss_priv *priv = dev_get_priv(dev);
+       const int start = GPIO_IRQ_START;
+       const int end = GPIO_IRQ_END;
+       int reg_start;
+       int reg_end;
+       int i;
+
+       show_polarities(dev, "Before");
+
+       reg_start = start / IRQS_PER_IPC;
+       reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
+
+       for (i = reg_start; i < reg_end; i++) {
+               u32 mask;
+               u16 reg;
+               int irq_start;
+               int irq_end;
+
+               irq_start = i * IRQS_PER_IPC;
+               irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
+
+               if (start > irq_end)
+                       continue;
+               if (end < irq_start)
+                       break;
+
+               /* Track bits within the bounds of of the register */
+               irq_start = max(start, irq_start) % IRQS_PER_IPC;
+               irq_end = min(end, irq_end) % IRQS_PER_IPC;
+
+               /* Create bitmask of the inclusive range of start and end */
+               mask = (((1U << irq_end) - 1) | (1U << irq_end));
+               mask &= ~((1U << irq_start) - 1);
+
+               reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i;
+               pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]);
+       }
+
+       show_polarities(dev, "After");
+
+       return 0;
+}
+#endif
+
+static int route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
+{
+       struct itss_priv *priv = dev_get_priv(dev);
+       struct pmc_route *route;
+       int i;
+
+       for (i = 0, route = priv->route; i < priv->route_count; i++, route++) {
+               if (pmc_gpe_num == route->pmc)
+                       return route->gpio;
+       }
+
+       return -ENOENT;
+}
+
+static int itss_ofdata_to_platdata(struct udevice *dev)
+{
+       struct itss_priv *priv = dev_get_priv(dev);
+       int ret;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+       struct itss_platdata *plat = dev_get_platdata(dev);
+       struct dtd_intel_itss *dtplat = &plat->dtplat;
+
+       /*
+        * It would be nice to do this in the bind() method, but with
+        * of-platdata binding happens in the order that DM finds things in the
+        * linker list (i.e. alphabetical order by driver name). So the GPIO
+        * device may well be bound before its parent (p2sb), and this call
+        * will fail if p2sb is not bound yet.
+        *
+        * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc
+        */
+       ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id);
+       if (ret)
+               return log_msg_ret("Could not set port id", ret);
+       priv->route = (struct pmc_route *)dtplat->intel_pmc_routes;
+       priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) /
+                sizeof(struct pmc_route);
+#else
+       int size;
+
+       size = dev_read_size(dev, "intel,pmc-routes");
+       if (size < 0)
+               return size;
+       priv->route = malloc(size);
+       if (!priv->route)
+               return -ENOMEM;
+       ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route,
+                                size / sizeof(fdt32_t));
+       if (ret)
+               return log_msg_ret("Cannot read pmc-routes", ret);
+       priv->route_count = size / sizeof(struct pmc_route);
+#endif
+
+       return 0;
+}
+
+static const struct irq_ops itss_ops = {
+       .route_pmc_gpio_gpe     = route_pmc_gpio_gpe,
+       .set_polarity   = set_polarity,
+#ifndef CONFIG_TPL_BUILD
+       .snapshot_polarities = snapshot_polarities,
+       .restore_polarities = restore_polarities,
+#endif
+};
+
+static const struct udevice_id itss_ids[] = {
+       { .compatible = "intel,itss"},
+       { }
+};
+
+U_BOOT_DRIVER(itss_drv) = {
+       .name           = "intel_itss",
+       .id             = UCLASS_IRQ,
+       .of_match       = itss_ids,
+       .ops            = &itss_ops,
+       .ofdata_to_platdata = itss_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct itss_platdata),
+       .priv_auto_alloc_size = sizeof(struct itss_priv),
+};
index 7b44a59bffec462b4cbbc4273e3fe2bba9635bb4..bab54b18df67d3c62a5ee900b4857dc021c3f07b 100644 (file)
@@ -34,18 +34,15 @@ static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev)
              data->stride,
              data->clk);
 
-       /*
-        * The data->type provides port io or mmio access type info,
-        * but the access type will be controlled by
-        * CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32.
-        *
-        * TBD: ns16550 access type configuration in runtime.
-        *      ex) plat->access_type = data->type
-        */
        plat->base = data->base;
        /* ns16550 uses reg_shift, then covert stride to shift */
        plat->reg_shift = data->stride >> 1;
+       plat->reg_width = data->stride;
        plat->clock = data->clk;
+       plat->fcr = UART_FCR_DEFVAL;
+       plat->flags = 0;
+       if (data->type == 1)
+               plat->flags |= NS16550_FLAG_IO;
 
        return 0;
 }
index 01524635e9c82d9a498653605dc36d2107ea8d90..26cf995db2d01c8eb5475ee47070ad1aab2c13ae 100644 (file)
@@ -50,7 +50,7 @@ _x86boot_start:
        movl    %cr0, %eax
        orl     $(X86_CR0_NW | X86_CR0_CD), %eax
        movl    %eax, %cr0
-       wbinvd
+       invd
 
        /*
         * Zero the BIST (Built-In Self Test) value since we don't have it.
index 54f4ff6662a8d8999311be3e7553882b1b245c2a..292e750508149aae68770160f1a39090a12a9912 100644 (file)
@@ -28,7 +28,7 @@ start16:
        movl    %cr0, %eax
        orl     $(X86_CR0_NW | X86_CR0_CD), %eax
        movl    %eax, %cr0
-       wbinvd
+       invd
 
        /* load the temporary Global Descriptor Table */
 data32 cs      lidt    idt_ptr
index 24fcbb5063128600586253d88038a95dc0bab8a8..a1820fa1870e1c04b66cefeabf3155e428e25b3b 100644 (file)
 
                        itss {
                                u-boot,dm-pre-reloc;
-                               compatible = "intel,apl-itss";
+                               compatible = "intel,itss";
                                intel,p2sb-port-id = <PID_ITSS>;
                                intel,pmc-routes = <
                                        PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0
index a88da6eafd68f472008046a5cd0015fae9fbcd47..38ddaafa1981a12de5aabb0deb840a9c972e1897 100644 (file)
@@ -8,7 +8,6 @@
 /dts-v1/;
 
 /include/ "skeleton.dtsi"
-/include/ "serial.dtsi"
 /include/ "keyboard.dtsi"
 /include/ "pcspkr.dtsi"
 /include/ "reset.dtsi"
                u-boot,dm-pre-reloc;
        };
 
+       serial: serial {
+               u-boot,dm-pre-reloc;
+               compatible = "coreboot-serial";
+       };
+
        coreboot-fb {
                compatible = "coreboot-fb";
        };
diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/arch-apollolake/itss.h
deleted file mode 100644 (file)
index 1e29503..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2017 Intel Corporation.
- * Copyright 2019 Google LLC
- *
- * Modified from coreboot itss.h
- */
-
-#ifndef _ASM_ARCH_ITSS_H
-#define _ASM_ARCH_ITSS_H
-
-#define GPIO_IRQ_START 50
-#define GPIO_IRQ_END   ITSS_MAX_IRQ
-
-#define ITSS_MAX_IRQ   119
-#define IRQS_PER_IPC   32
-#define NUM_IPC_REGS   ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC)
-
-/* Max PXRC registers in ITSS */
-#define MAX_PXRC_CONFIG        (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1)
-
-/* PIRQA Routing Control Register */
-#define PCR_ITSS_PIRQA_ROUT    0x3100
-/* PIRQB Routing Control Register */
-#define PCR_ITSS_PIRQB_ROUT    0x3101
-/* PIRQC Routing Control Register */
-#define PCR_ITSS_PIRQC_ROUT    0x3102
-/* PIRQD Routing Control Register */
-#define PCR_ITSS_PIRQD_ROUT    0x3103
-/* PIRQE Routing Control Register */
-#define PCR_ITSS_PIRQE_ROUT    0x3104
-/* PIRQF Routing Control Register */
-#define PCR_ITSS_PIRQF_ROUT    0x3105
-/* PIRQG Routing Control Register */
-#define PCR_ITSS_PIRQG_ROUT    0x3106
-/* PIRQH Routing Control Register */
-#define PCR_ITSS_PIRQH_ROUT    0x3107
-/* ITSS Interrupt polarity control */
-#define PCR_ITSS_IPC0_CONF     0x3200
-/* ITSS Power reduction control */
-#define PCR_ITSS_ITSSPRC       0x3300
-
-#endif /* _ASM_ARCH_ITSS_H */
index 2c54e24e02fb2614c75ece13926ad5be5cbf4276..61de0077d72cfcd99b92ea3a131b8afa81a7c132 100644 (file)
@@ -97,6 +97,25 @@ struct cb_serial {
        u32 type;
        u32 baseaddr;
        u32 baud;
+       u32 regwidth;
+
+       /*
+        * Crystal or input frequency to the chip containing the UART.
+        * Provide the board specific details to allow the payload to
+        * initialize the chip containing the UART and make independent
+        * decisions as to which dividers to select and their values
+        * to eventually arrive at the desired console baud-rate.
+        */
+       u32 input_hertz;
+
+       /*
+        * UART PCI address: bus, device, function
+        * 1 << 31 - Valid bit, PCI UART in use
+        * Bus << 20
+        * Device << 15
+        * Function << 12
+        */
+       u32 uart_pci_addr;
 };
 
 #define CB_TAG_CONSOLE                 0x0010
diff --git a/arch/x86/include/asm/itss.h b/arch/x86/include/asm/itss.h
new file mode 100644 (file)
index 0000000..c75d8fe
--- /dev/null
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Interrupt Timer Subsystem
+ *
+ * Copyright (C) 2017 Intel Corporation.
+ * Copyright 2019 Google LLC
+ *
+ * Modified from coreboot itss.h
+ */
+
+#ifndef _ASM_ARCH_ITSS_H
+#define _ASM_ARCH_ITSS_H
+
+#define GPIO_IRQ_START 50
+#define GPIO_IRQ_END   ITSS_MAX_IRQ
+
+#define ITSS_MAX_IRQ   119
+#define IRQS_PER_IPC   32
+#define NUM_IPC_REGS   ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC)
+
+/* Max PXRC registers in ITSS */
+#define MAX_PXRC_CONFIG        (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1)
+
+/* PIRQA Routing Control Register */
+#define PCR_ITSS_PIRQA_ROUT    0x3100
+/* PIRQB Routing Control Register */
+#define PCR_ITSS_PIRQB_ROUT    0x3101
+/* PIRQC Routing Control Register */
+#define PCR_ITSS_PIRQC_ROUT    0x3102
+/* PIRQD Routing Control Register */
+#define PCR_ITSS_PIRQD_ROUT    0x3103
+/* PIRQE Routing Control Register */
+#define PCR_ITSS_PIRQE_ROUT    0x3104
+/* PIRQF Routing Control Register */
+#define PCR_ITSS_PIRQF_ROUT    0x3105
+/* PIRQG Routing Control Register */
+#define PCR_ITSS_PIRQG_ROUT    0x3106
+/* PIRQH Routing Control Register */
+#define PCR_ITSS_PIRQH_ROUT    0x3107
+/* ITSS Interrupt polarity control */
+#define PCR_ITSS_IPC0_CONF     0x3200
+/* ITSS Power reduction control */
+#define PCR_ITSS_ITSSPRC       0x3300
+
+#endif /* _ASM_ARCH_ITSS_H */
index 6e1efaaf85d76b600c51093819861a4189bae9f1..e6ba57035e25e14dfc1c8b6c5f97153f273921b7 100644 (file)
@@ -386,6 +386,16 @@ config CMD_ADTIMG
          files should be merged in one dtb further, which needs to be passed to
          the kernel, as part of a boot process.
 
+config CMD_ABOOTIMG
+       bool "abootimg"
+       depends on ANDROID_BOOT_IMAGE
+       help
+         Android Boot Image manipulation commands. Allows one to extract
+         images contained in boot.img, like kernel, ramdisk, dtb, etc, and
+         obtain corresponding meta-information from boot.img.
+
+         See doc/android/boot-image.rst for details.
+
 config CMD_ELF
        bool "bootelf, bootvx"
        default y
@@ -870,7 +880,7 @@ config CMD_FASTBOOT
          Android devices. Fastboot requires either the network stack
          enabled or support for acting as a USB device.
 
-         See doc/android/fastboot.txt for more information.
+         See doc/android/fastboot.rst for more information.
 
 config CMD_FLASH
        bool "flinfo, erase, protect"
index 4f29b72c695c98b77ed5eba491d5a9329ee8707a..f1dd513a4b41032e636b747c9e6d26b038745814 100644 (file)
@@ -48,6 +48,7 @@ ifdef CONFIG_POST
 obj-$(CONFIG_CMD_DIAG) += diag.o
 endif
 obj-$(CONFIG_CMD_ADTIMG) += adtimg.o
+obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o
 obj-$(CONFIG_CMD_ECHO) += echo.o
 obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
 obj-$(CONFIG_CMD_EEPROM) += eeprom.o
diff --git a/cmd/abootimg.c b/cmd/abootimg.c
new file mode 100644 (file)
index 0000000..670bcb3
--- /dev/null
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020
+ * Sam Protsenko <joe.skb7@gmail.com>
+ */
+
+#include <android_image.h>
+#include <common.h>
+#include <mapmem.h>
+
+#define abootimg_addr() \
+       (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr)
+
+/* Please use abootimg_addr() macro to obtain the boot image address */
+static ulong _abootimg_addr = -1;
+
+static int abootimg_get_ver(int argc, char * const argv[])
+{
+       const struct andr_img_hdr *hdr;
+       int res = CMD_RET_SUCCESS;
+
+       if (argc > 1)
+               return CMD_RET_USAGE;
+
+       hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               res = CMD_RET_FAILURE;
+               goto exit;
+       }
+
+       if (argc == 0)
+               printf("%u\n", hdr->header_version);
+       else
+               env_set_ulong(argv[0], hdr->header_version);
+
+exit:
+       unmap_sysmem(hdr);
+       return res;
+}
+
+static int abootimg_get_recovery_dtbo(int argc, char * const argv[])
+{
+       ulong addr;
+       u32 size;
+
+       if (argc > 2)
+               return CMD_RET_USAGE;
+
+       if (!android_image_get_dtbo(abootimg_addr(), &addr, &size))
+               return CMD_RET_FAILURE;
+
+       if (argc == 0) {
+               printf("%lx\n", addr);
+       } else {
+               env_set_hex(argv[0], addr);
+               if (argc == 2)
+                       env_set_hex(argv[1], size);
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+static int abootimg_get_dtb_load_addr(int argc, char * const argv[])
+{
+       const struct andr_img_hdr *hdr;
+       int res = CMD_RET_SUCCESS;
+
+       if (argc > 1)
+               return CMD_RET_USAGE;
+
+       hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               res = CMD_RET_FAILURE;
+               goto exit;
+       }
+
+       if (hdr->header_version < 2) {
+               printf("Error: header_version must be >= 2 for this\n");
+               res = CMD_RET_FAILURE;
+               goto exit;
+       }
+
+       if (argc == 0)
+               printf("%lx\n", (ulong)hdr->dtb_addr);
+       else
+               env_set_hex(argv[0], (ulong)hdr->dtb_addr);
+
+exit:
+       unmap_sysmem(hdr);
+       return res;
+}
+
+static int abootimg_get_dtb_by_index(int argc, char * const argv[])
+{
+       const char *index_str;
+       u32 num;
+       char *endp;
+       ulong addr;
+       u32 size;
+
+       if (argc < 1 || argc > 3)
+               return CMD_RET_USAGE;
+
+       index_str = argv[0] + strlen("--index=");
+       if (index_str[0] == '\0') {
+               printf("Error: Wrong index num\n");
+               return CMD_RET_FAILURE;
+       }
+
+       num = simple_strtoul(index_str, &endp, 0);
+       if (*endp != '\0') {
+               printf("Error: Wrong index num\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (!android_image_get_dtb_by_index(abootimg_addr(), num,
+                                           &addr, &size)) {
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc == 1) {
+               printf("%lx\n", addr);
+       } else {
+               if (env_set_hex(argv[1], addr)) {
+                       printf("Error: Can't set [addr_var]\n");
+                       return CMD_RET_FAILURE;
+               }
+
+               if (argc == 3) {
+                       if (env_set_hex(argv[2], size)) {
+                               printf("Error: Can't set [size_var]\n");
+                               return CMD_RET_FAILURE;
+                       }
+               }
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+static int abootimg_get_dtb(int argc, char * const argv[])
+{
+       if (argc < 1)
+               return CMD_RET_USAGE;
+
+       if (strstr(argv[0], "--index="))
+               return abootimg_get_dtb_by_index(argc, argv);
+
+       return CMD_RET_USAGE;
+}
+
+static int do_abootimg_addr(cmd_tbl_t *cmdtp, int flag, int argc,
+                           char * const argv[])
+{
+       char *endp;
+       ulong img_addr;
+
+       if (argc != 2)
+               return CMD_RET_USAGE;
+
+       img_addr = simple_strtoul(argv[1], &endp, 16);
+       if (*endp != '\0') {
+               printf("Error: Wrong image address\n");
+               return CMD_RET_FAILURE;
+       }
+
+       _abootimg_addr = img_addr;
+       return CMD_RET_SUCCESS;
+}
+
+static int do_abootimg_get(cmd_tbl_t *cmdtp, int flag, int argc,
+                          char * const argv[])
+{
+       const char *param;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       param = argv[1];
+       argc -= 2;
+       argv += 2;
+       if (!strcmp(param, "ver"))
+               return abootimg_get_ver(argc, argv);
+       else if (!strcmp(param, "recovery_dtbo"))
+               return abootimg_get_recovery_dtbo(argc, argv);
+       else if (!strcmp(param, "dtb_load_addr"))
+               return abootimg_get_dtb_load_addr(argc, argv);
+       else if (!strcmp(param, "dtb"))
+               return abootimg_get_dtb(argc, argv);
+
+       return CMD_RET_USAGE;
+}
+
+static int do_abootimg_dump(cmd_tbl_t *cmdtp, int flag, int argc,
+                           char * const argv[])
+{
+       if (argc != 2)
+               return CMD_RET_USAGE;
+
+       if (!strcmp(argv[1], "dtb")) {
+               if (android_image_print_dtb_contents(abootimg_addr()))
+                       return CMD_RET_FAILURE;
+       } else {
+               return CMD_RET_USAGE;
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+static cmd_tbl_t cmd_abootimg_sub[] = {
+       U_BOOT_CMD_MKENT(addr, 2, 1, do_abootimg_addr, "", ""),
+       U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""),
+       U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""),
+};
+
+static int do_abootimg(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char * const argv[])
+{
+       cmd_tbl_t *cp;
+
+       cp = find_cmd_tbl(argv[1], cmd_abootimg_sub,
+                         ARRAY_SIZE(cmd_abootimg_sub));
+
+       /* Strip off leading 'abootimg' command argument */
+       argc--;
+       argv++;
+
+       if (!cp || argc > cp->maxargs)
+               return CMD_RET_USAGE;
+       if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
+               return CMD_RET_SUCCESS;
+
+       return cp->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+       abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg,
+       "manipulate Android Boot Image",
+       "addr <addr>\n"
+       "    - set the address in RAM where boot image is located\n"
+       "      ($loadaddr is used by default)\n"
+       "abootimg dump dtb\n"
+       "    - print info for all DT blobs in DTB area\n"
+       "abootimg get ver [varname]\n"
+       "    - get header version\n"
+       "abootimg get recovery_dtbo [addr_var [size_var]]\n"
+       "    - get address and size (hex) of recovery DTBO area in the image\n"
+       "      [addr_var]: variable name to contain DTBO area address\n"
+       "      [size_var]: variable name to contain DTBO area size\n"
+       "abootimg get dtb_load_addr [varname]\n"
+       "    - get load address (hex) of DTB, from image header\n"
+       "abootimg get dtb --index=<num> [addr_var [size_var]]\n"
+       "    - get address and size (hex) of DT blob in the image by index\n"
+       "      <num>: index number of desired DT blob in DTB area\n"
+       "      [addr_var]: variable name to contain DT blob address\n"
+       "      [size_var]: variable name to contain DT blob size"
+);
index 5f62b8d0b136afdcd8ae58485d3dedb9a5c94641..896e4af91d4cdaeb5ad0d7086a60777ed55d0aad 100644 (file)
@@ -108,7 +108,7 @@ endif
 
 obj-y += image.o
 obj-$(CONFIG_ANDROID_AB) += android_ab.o
-obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
+obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
 obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
 obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
 obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
index 3564a64221d2dd37de4095112b171ddb1f47fd7d..6af9baa121dbab45a827454b41f02bff895e657f 100644 (file)
@@ -6,10 +6,12 @@
 #include <common.h>
 #include <env.h>
 #include <image.h>
+#include <image-android-dt.h>
 #include <android_image.h>
 #include <malloc.h>
 #include <errno.h>
 #include <asm/unaligned.h>
+#include <mapmem.h>
 
 #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR      0x10008000
 
@@ -195,6 +197,182 @@ int android_image_get_second(const struct andr_img_hdr *hdr,
        return 0;
 }
 
+/**
+ * android_image_get_dtbo() - Get address and size of recovery DTBO image.
+ * @hdr_addr: Boot image header address
+ * @addr: If not NULL, will contain address of recovery DTBO image
+ * @size: If not NULL, will contain size of recovery DTBO image
+ *
+ * Get the address and size of DTBO image in "Recovery DTBO" area of Android
+ * Boot Image in RAM. The format of this image is Android DTBO (see
+ * corresponding "DTB/DTBO Partitions" AOSP documentation for details). Once
+ * the address is obtained from this function, one can use 'adtimg' U-Boot
+ * command or android_dt_*() functions to extract desired DTBO blob.
+ *
+ * This DTBO (included in boot image) is only needed for non-A/B devices, and it
+ * only can be found in recovery image. On A/B devices we can always rely on
+ * "dtbo" partition. See "Including DTBO in Recovery for Non-A/B Devices" in
+ * AOSP documentation for details.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size)
+{
+       const struct andr_img_hdr *hdr;
+       ulong dtbo_img_addr;
+       bool ret = true;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->header_version < 1) {
+               printf("Error: header_version must be >= 1 to get dtbo\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->recovery_dtbo_size == 0) {
+               printf("Error: recovery_dtbo_size is 0\n");
+               ret = false;
+               goto exit;
+       }
+
+       /* Calculate the address of DTB area in boot image */
+       dtbo_img_addr = hdr_addr;
+       dtbo_img_addr += hdr->page_size;
+       dtbo_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
+       dtbo_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
+       dtbo_img_addr += ALIGN(hdr->second_size, hdr->page_size);
+
+       if (addr)
+               *addr = dtbo_img_addr;
+       if (size)
+               *size = hdr->recovery_dtbo_size;
+
+exit:
+       unmap_sysmem(hdr);
+       return ret;
+}
+
+/**
+ * android_image_get_dtb_img_addr() - Get the address of DTB area in boot image.
+ * @hdr_addr: Boot image header address
+ * @addr: Will contain the address of DTB area in boot image
+ *
+ * Return: true on success or false on fail.
+ */
+static bool android_image_get_dtb_img_addr(ulong hdr_addr, ulong *addr)
+{
+       const struct andr_img_hdr *hdr;
+       ulong dtb_img_addr;
+       bool ret = true;
+
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       if (android_image_check_header(hdr)) {
+               printf("Error: Boot Image header is incorrect\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->header_version < 2) {
+               printf("Error: header_version must be >= 2 to get dtb\n");
+               ret = false;
+               goto exit;
+       }
+
+       if (hdr->dtb_size == 0) {
+               printf("Error: dtb_size is 0\n");
+               ret = false;
+               goto exit;
+       }
+
+       /* Calculate the address of DTB area in boot image */
+       dtb_img_addr = hdr_addr;
+       dtb_img_addr += hdr->page_size;
+       dtb_img_addr += ALIGN(hdr->kernel_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->ramdisk_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->second_size, hdr->page_size);
+       dtb_img_addr += ALIGN(hdr->recovery_dtbo_size, hdr->page_size);
+
+       *addr = dtb_img_addr;
+
+exit:
+       unmap_sysmem(hdr);
+       return ret;
+}
+
+/**
+ * android_image_get_dtb_by_index() - Get address and size of blob in DTB area.
+ * @hdr_addr: Boot image header address
+ * @index: Index of desired DTB in DTB area (starting from 0)
+ * @addr: If not NULL, will contain address to specified DTB
+ * @size: If not NULL, will contain size of specified DTB
+ *
+ * Get the address and size of DTB blob by its index in DTB area of Android
+ * Boot Image in RAM.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr,
+                                   u32 *size)
+{
+       const struct andr_img_hdr *hdr;
+       bool res;
+       ulong dtb_img_addr;     /* address of DTB part in boot image */
+       u32 dtb_img_size;       /* size of DTB payload in boot image */
+       ulong dtb_addr;         /* address of DTB blob with specified index  */
+       u32 i;                  /* index iterator */
+
+       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
+       if (!res)
+               return false;
+
+       /* Check if DTB area of boot image is in DTBO format */
+       if (android_dt_check_header(dtb_img_addr)) {
+               return android_dt_get_fdt_by_index(dtb_img_addr, index, addr,
+                                                  size);
+       }
+
+       /* Find out the address of DTB with specified index in concat blobs */
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       dtb_img_size = hdr->dtb_size;
+       unmap_sysmem(hdr);
+       i = 0;
+       dtb_addr = dtb_img_addr;
+       while (dtb_addr < dtb_img_addr + dtb_img_size) {
+               const struct fdt_header *fdt;
+               u32 dtb_size;
+
+               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
+               if (fdt_check_header(fdt) != 0) {
+                       unmap_sysmem(fdt);
+                       printf("Error: Invalid FDT header for index %u\n", i);
+                       return false;
+               }
+
+               dtb_size = fdt_totalsize(fdt);
+               unmap_sysmem(fdt);
+
+               if (i == index) {
+                       if (size)
+                               *size = dtb_size;
+                       if (addr)
+                               *addr = dtb_addr;
+                       return true;
+               }
+
+               dtb_addr += dtb_size;
+               ++i;
+       }
+
+       printf("Error: Index is out of bounds (%u/%u)\n", index, i);
+       return false;
+}
+
 #if !defined(CONFIG_SPL_BUILD)
 /**
  * android_print_contents - prints out the contents of the Android format image
@@ -246,4 +424,108 @@ void android_print_contents(const struct andr_img_hdr *hdr)
                printf("%sdtb addr:             %llx\n", p, hdr->dtb_addr);
        }
 }
+
+/**
+ * android_image_print_dtb_info - Print info for one DTB blob in DTB area.
+ * @fdt: DTB header
+ * @index: Number of DTB blob in DTB area.
+ *
+ * Return: true on success or false on error.
+ */
+static bool android_image_print_dtb_info(const struct fdt_header *fdt,
+                                        u32 index)
+{
+       int root_node_off;
+       u32 fdt_size;
+       const char *model;
+       const char *compatible;
+
+       root_node_off = fdt_path_offset(fdt, "/");
+       if (root_node_off < 0) {
+               printf("Error: Root node not found\n");
+               return false;
+       }
+
+       fdt_size = fdt_totalsize(fdt);
+       compatible = fdt_getprop(fdt, root_node_off, "compatible",
+                                NULL);
+       model = fdt_getprop(fdt, root_node_off, "model", NULL);
+
+       printf(" - DTB #%u:\n", index);
+       printf("           (DTB)size = %d\n", fdt_size);
+       printf("          (DTB)model = %s\n", model ? model : "(unknown)");
+       printf("     (DTB)compatible = %s\n",
+              compatible ? compatible : "(unknown)");
+
+       return true;
+}
+
+/**
+ * android_image_print_dtb_contents() - Print info for DTB blobs in DTB area.
+ * @hdr_addr: Boot image header address
+ *
+ * DTB payload in Android Boot Image v2+ can be in one of following formats:
+ *   1. Concatenated DTB blobs
+ *   2. Android DTBO format (see CONFIG_CMD_ADTIMG for details)
+ *
+ * This function does next:
+ *   1. Prints out the format used in DTB area
+ *   2. Iterates over all DTB blobs in DTB area and prints out the info for
+ *      each blob.
+ *
+ * Return: true on success or false on error.
+ */
+bool android_image_print_dtb_contents(ulong hdr_addr)
+{
+       const struct andr_img_hdr *hdr;
+       bool res;
+       ulong dtb_img_addr;     /* address of DTB part in boot image */
+       u32 dtb_img_size;       /* size of DTB payload in boot image */
+       ulong dtb_addr;         /* address of DTB blob with specified index  */
+       u32 i;                  /* index iterator */
+
+       res = android_image_get_dtb_img_addr(hdr_addr, &dtb_img_addr);
+       if (!res)
+               return false;
+
+       /* Check if DTB area of boot image is in DTBO format */
+       if (android_dt_check_header(dtb_img_addr)) {
+               printf("## DTB area contents (DTBO format):\n");
+               android_dt_print_contents(dtb_img_addr);
+               return true;
+       }
+
+       printf("## DTB area contents (concat format):\n");
+
+       /* Iterate over concatenated DTB blobs */
+       hdr = map_sysmem(hdr_addr, sizeof(*hdr));
+       dtb_img_size = hdr->dtb_size;
+       unmap_sysmem(hdr);
+       i = 0;
+       dtb_addr = dtb_img_addr;
+       while (dtb_addr < dtb_img_addr + dtb_img_size) {
+               const struct fdt_header *fdt;
+               u32 dtb_size;
+
+               fdt = map_sysmem(dtb_addr, sizeof(*fdt));
+               if (fdt_check_header(fdt) != 0) {
+                       unmap_sysmem(fdt);
+                       printf("Error: Invalid FDT header for index %u\n", i);
+                       return false;
+               }
+
+               res = android_image_print_dtb_info(fdt, i);
+               if (!res) {
+                       unmap_sysmem(fdt);
+                       return false;
+               }
+
+               dtb_size = fdt_totalsize(fdt);
+               unmap_sysmem(fdt);
+               dtb_addr += dtb_size;
+               ++i;
+       }
+
+       return true;
+}
 #endif
index e429d0e20066ee6be213409cc79b7c6f3cd25c94..f39f553afba84f09ed5124296d50977c5eb6f855 100644 (file)
@@ -22,6 +22,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_MISC_INIT_R is not set
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_AVB_VERIFY=y
+CONFIG_ANDROID_AB=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA=y
@@ -31,11 +33,14 @@ CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ADTIMG=y
+CONFIG_CMD_ABOOTIMG=y
 CONFIG_CMD_SPL=y
 CONFIG_CMD_BCB=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_AB_SELECT=y
 # CONFIG_CMD_PMIC is not set
+CONFIG_CMD_AVB=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am572x-idk"
@@ -102,3 +107,4 @@ CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
+CONFIG_LIBAVB=y
index bebaae874311e24c795f020b34e174a83d2f7057..4480f1c84d067131fa0e019f2c971c5285718533 100644 (file)
@@ -27,6 +27,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_MISC_INIT_R is not set
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_AVB_VERIFY=y
+CONFIG_ANDROID_AB=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA=y
@@ -34,10 +36,13 @@ CONFIG_SPL_DMA=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000
 CONFIG_CMD_ADTIMG=y
+CONFIG_CMD_ABOOTIMG=y
 CONFIG_CMD_BCB=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_AB_SELECT=y
 # CONFIG_CMD_PMIC is not set
+CONFIG_CMD_AVB=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15"
@@ -98,3 +103,4 @@ CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
+CONFIG_LIBAVB=y
index d96640d44f4cd783997d1133d25b324fe9149034..1e9268f68dd809561fc155dda2b6acd991333ce3 100644 (file)
@@ -28,6 +28,8 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_MISC_INIT_R is not set
 CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_AVB_VERIFY=y
+CONFIG_ANDROID_AB=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA=y
@@ -39,10 +41,13 @@ CONFIG_SPL_USB_GADGET=y
 CONFIG_SPL_DFU=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ADTIMG=y
+CONFIG_CMD_ABOOTIMG=y
 CONFIG_CMD_BCB=y
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_AB_SELECT=y
 # CONFIG_CMD_PMIC is not set
+CONFIG_CMD_AVB=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am57xx-beagle-x15"
@@ -105,3 +110,4 @@ CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
 CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
+CONFIG_LIBAVB=y
index 14b2eec3ba99e8987945072e90f27c8019295e04..58707d619a23efd41a14075e408b670fb86d9ef8 100644 (file)
@@ -6,10 +6,10 @@ CONFIG_NR_DRAM_BANKS=3
 CONFIG_VENDOR_INTEL=y
 CONFIG_TARGET_EDISON=y
 CONFIG_SMP=y
+CONFIG_GENERATE_ACPI_TABLE=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_LAST_STAGE_INIT=y
 CONFIG_HUSH_PARSER=y
-# CONFIG_CMDLINE_EDITING is not set
 CONFIG_CMD_CPU=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
index d5e54a228d074f8943016f9b08ebb8bd72c15217..8355abbaa7f2aff56bca3eccc0ab70968088c7da 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_K3=y
+CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_SYS_MALLOC_F_LEN=0x8000
@@ -32,13 +33,18 @@ CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_DFU=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
+CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_MTD=y
@@ -60,7 +66,7 @@ CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_ENV_OFFSET_REDUND=0x700000
+CONFIG_ENV_OFFSET_REDUND=0x6A0000
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
@@ -85,6 +91,9 @@ CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DM_GPIO=y
+CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
@@ -117,6 +126,7 @@ CONFIG_PINCTRL_SINGLE=y
 CONFIG_POWER_DOMAIN=y
 CONFIG_TI_SCI_POWER_DOMAIN=y
 CONFIG_RAM=y
+CONFIG_SPL_RAM=y
 CONFIG_REMOTEPROC_TI_K3_DSP=y
 CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_DM_RESET=y
@@ -139,6 +149,7 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_CDNS3=y
 CONFIG_USB_CDNS3_GADGET=y
 CONFIG_USB_CDNS3_HOST=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0451
index a90ab62195e34ac07f5aca2f0edd671a0093759b..19fbd450c7547da11324e10f3a360eb8adc050f3 100644 (file)
@@ -3,7 +3,7 @@ CONFIG_ARCH_K3=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x55000
+CONFIG_SYS_MALLOC_F_LEN=0x70000
 CONFIG_SOC_K3_J721E=y
 CONFIG_TARGET_J721E_R5_EVM=y
 CONFIG_ENV_SIZE=0x20000
@@ -36,8 +36,11 @@ CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_DFU=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_HUSH_PARSER=y
+CONFIG_CMD_DFU=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
 CONFIG_CMD_MMC=y
@@ -63,6 +66,7 @@ CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
+CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_OMAP24XX=y
@@ -104,5 +108,17 @@ CONFIG_SYSRESET_TI_SCI=y
 CONFIG_TIMER=y
 CONFIG_SPL_TIMER=y
 CONFIG_OMAP_TIMER=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_CDNS3=y
+CONFIG_USB_CDNS3_GADGET=y
+CONFIG_SPL_USB_CDNS3_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6163
+CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
index 00f80f71ad66d23e9df7005857d0164b8d6a7444..a67ed3abeb35017c460fa52dbd5f9b5aea9777b1 100644 (file)
@@ -12,6 +12,8 @@ CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_FS_UUID=y
@@ -20,13 +22,25 @@ CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_DM_ETH=y
+CONFIG_BCMGENET=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="FSL"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0525
+CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_DM_VIDEO=y
 CONFIG_VIDEO_BPP32=y
 CONFIG_SYS_WHITE_ON_BLACK=y
index 8cf1bb81fff568d314f71ead9e5fb33652aa00c6..17ecad3aa5afc506f8607713e707c1abf1b11152 100644 (file)
@@ -12,6 +12,8 @@ CONFIG_MISC_INIT_R=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_DFU=y
+# CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_FS_UUID=y
@@ -20,13 +22,25 @@ CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DFU_MMC=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_DM_ETH=y
+CONFIG_BCMGENET=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="FSL"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0525
+CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_DM_VIDEO=y
 CONFIG_VIDEO_BPP32=y
 CONFIG_SYS_WHITE_ON_BLACK=y
index 10fbe0db922178385aa4d6a2a74d2cd6b5ba9a36..00b30964810dc0c11259c74b58b7887388973275 100644 (file)
@@ -36,6 +36,7 @@ CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_LAN78XX=y
 CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_BCMGENET=y
 CONFIG_DM_VIDEO=y
 CONFIG_VIDEO_BPP32=y
 CONFIG_SYS_WHITE_ON_BLACK=y
index fc018bdd2ca47c00e71cd23745b709f63d5efb98..790dcb0592b9247d082ba9a72e2a3238c6c4d8ee 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_ANDROID_AB=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_ABOOTIMG=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
diff --git a/doc/android/ab.rst b/doc/android/ab.rst
new file mode 100644 (file)
index 0000000..961895c
--- /dev/null
@@ -0,0 +1,72 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Android A/B updates
+===================
+
+Overview
+--------
+
+A/B system updates ensures modern approach for system update. This feature
+allows one to use two sets (or more) of partitions referred to as slots
+(normally slot A and slot B). The system runs from the current slot while the
+partitions in the unused slot can be updated [1]_.
+
+A/B enablement
+--------------
+
+The A/B updates support can be activated by specifying next options in
+your board configuration file::
+
+    CONFIG_ANDROID_AB=y
+    CONFIG_CMD_AB_SELECT=y
+
+The disk space on target device must be partitioned in a way so that each
+partition which needs to be updated has two or more instances. The name of
+each instance must be formed by adding suffixes: ``_a``, ``_b``, ``_c``, etc.
+For example: ``boot_a``, ``boot_b``, ``system_a``, ``system_b``, ``vendor_a``,
+``vendor_b``.
+
+As a result you can use ``ab_select`` command to ensure A/B boot process in your
+boot script. This command analyzes and processes A/B metadata stored on a
+special partition (e.g. ``misc``) and determines which slot should be used for
+booting up.
+
+Command usage
+-------------
+
+.. code-block:: none
+
+    ab_select <slot_var_name> <interface> <dev[:part_number|#part_name]>
+
+for example::
+
+    => ab_select slot_name mmc 1:4
+
+or::
+
+    => ab_select slot_name mmc 1#misc
+
+Result::
+
+    => printenv slot_name
+    slot_name=a
+
+Based on this slot information, the current boot partition should be defined,
+and next kernel command line parameters should be generated:
+
+* ``androidboot.slot_suffix=``
+* ``root=``
+
+For example::
+
+    androidboot.slot_suffix=_a root=/dev/mmcblk1p12
+
+A/B metadata is organized according to AOSP reference [2]_. On the first system
+start with A/B enabled, when ``misc`` partition doesn't contain required data,
+the default A/B metadata will be created and written to ``misc`` partition.
+
+References
+----------
+
+.. [1] https://source.android.com/devices/tech/ota/ab
+.. [2] https://android.googlesource.com/platform/bootable/recovery/+/refs/tags/android-10.0.0_r25/bootloader_message/include/bootloader_message/bootloader_message.h
diff --git a/doc/android/ab.txt b/doc/android/ab.txt
deleted file mode 100644 (file)
index 9f37ed5..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-Android A/B updates
-===================
-
-Overview
---------
-
-A/B system updates ensures modern approach for system update. This feature
-allows one to use two sets (or more) of partitions referred to as slots
-(normally slot A and slot B). The system runs from the current slot while the
-partitions in the unused slot can be updated [1].
-
-A/B enablement
---------------
-
-The A/B updates support can be activated by specifying next options in
-your board configuration file:
-
-    CONFIG_ANDROID_AB=y
-    CONFIG_CMD_AB_SELECT=y
-
-The disk space on target device must be partitioned in a way so that each
-partition which needs to be updated has two or more instances. The name of
-each instance must be formed by adding suffixes: _a, _b, _c, etc.
-For example: boot_a, boot_b, system_a, system_b, vendor_a, vendor_b.
-
-As a result you can use 'ab_select' command to ensure A/B boot process in your
-boot script. This command analyzes and processes A/B metadata stored on a
-special partition (e.g. "misc") and determines which slot should be used for
-booting up.
-
-Command usage
--------------
-
-    ab_select <slot_var_name> <interface> <dev[:part_number|#part_name]>
-
-for example:
-
-    => ab_select slot_name mmc 1:4
-
-or
-
-    => ab_select slot_name mmc 1#misc
-
-Result:
-
-    => printenv slot_name
-    slot_name=a
-
-Based on this slot information, the current boot partition should be defined,
-and next kernel command line parameters should be generated:
-
- - androidboot.slot_suffix=
- - root=
-
-For example:
-
-    androidboot.slot_suffix=_a root=/dev/mmcblk1p12
-
-A/B metadata is organized according to AOSP reference [2]. On the first system
-start with A/B enabled, when 'misc' partition doesn't contain required data,
-the default A/B metadata will be created and written to 'misc' partition.
-
-References
-----------
-
-[1] https://source.android.com/devices/tech/ota/ab
-[2] bootable/recovery/bootloader_message/include/bootloader_message/bootloader_message.h
diff --git a/doc/android/avb2.rst b/doc/android/avb2.rst
new file mode 100644 (file)
index 0000000..a072119
--- /dev/null
@@ -0,0 +1,133 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Android Verified Boot 2.0
+=========================
+
+This file contains information about the current support of Android Verified
+Boot 2.0 in U-Boot.
+
+Overview
+--------
+
+Verified Boot establishes a chain of trust from the bootloader to system images:
+
+* Provides integrity checking for:
+
+  * Android Boot image: Linux kernel + ramdisk. RAW hashing of the whole
+    partition is done and the hash is compared with the one stored in
+    the VBMeta image
+  * ``system``/``vendor`` partitions: verifying root hash of dm-verity hashtrees
+
+* Provides capabilities for rollback protection
+
+Integrity of the bootloader (U-Boot BLOB and environment) is out of scope.
+
+For additional details check [1]_.
+
+AVB using OP-TEE (optional)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If AVB is configured to use OP-TEE (see `Enable on your board`_) rollback
+indexes and device lock state are stored in RPMB. The RPMB partition is managed
+by OP-TEE (see [2]_ for details) which is a secure OS leveraging ARM
+TrustZone.
+
+AVB 2.0 U-Boot shell commands
+-----------------------------
+
+Provides CLI interface to invoke AVB 2.0 verification + misc. commands for
+different testing purposes::
+
+    avb init <dev> - initialize avb 2.0 for <dev>
+    avb verify - run verification process using hash data from vbmeta structure
+    avb read_rb <num> - read rollback index at location <num>
+    avb write_rb <num> <rb> - write rollback index <rb> to <num>
+    avb is_unlocked - returns unlock status of the device
+    avb get_uuid <partname> - read and print uuid of partition <partname>
+    avb read_part <partname> <offset> <num> <addr> - read <num> bytes from
+    partition <partname> to buffer <addr>
+    avb write_part <partname> <offset> <num> <addr> - write <num> bytes to
+    <partname> by <offset> using data from <addr>
+
+Partitions tampering (example)
+------------------------------
+
+Boot or system/vendor (dm-verity metadata section) is tampered::
+
+   => avb init 1
+   => avb verify
+   avb_slot_verify.c:175: ERROR: boot: Hash of data does not match digest in
+   descriptor.
+   Slot verification result: ERROR_IO
+
+Vbmeta partition is tampered::
+
+   => avb init 1
+   => avb verify
+   avb_vbmeta_image.c:206: ERROR: Hash does not match!
+   avb_slot_verify.c:388: ERROR: vbmeta: Error verifying vbmeta image:
+   HASH_MISMATCH
+   Slot verification result: ERROR_IO
+
+Enable on your board
+--------------------
+
+The following options must be enabled::
+
+   CONFIG_LIBAVB=y
+   CONFIG_AVB_VERIFY=y
+   CONFIG_CMD_AVB=y
+
+In addtion optionally if storing rollback indexes in RPMB with help of
+OP-TEE::
+
+   CONFIG_TEE=y
+   CONFIG_OPTEE=y
+   CONFIG_OPTEE_TA_AVB=y
+   CONFIG_SUPPORT_EMMC_RPMB=y
+
+Then add ``avb verify`` invocation to your android boot sequence of commands,
+e.g.::
+
+   => avb_verify=avb init $mmcdev; avb verify;
+   => if run avb_verify; then                       \
+           echo AVB verification OK. Continue boot; \
+           set bootargs $bootargs $avb_bootargs;    \
+      else                                          \
+           echo AVB verification failed;            \
+           exit;                                    \
+      fi;                                           \
+
+   => emmc_android_boot=                                   \
+          echo Trying to boot Android from eMMC ...;       \
+          ...                                              \
+          run avb_verify;                                  \
+          mmc read ${fdtaddr} ${fdt_start} ${fdt_size};    \
+          mmc read ${loadaddr} ${boot_start} ${boot_size}; \
+               bootm $loadaddr $loadaddr $fdtaddr;         \
+
+If partitions you want to verify are slotted (have A/B suffixes), then current
+slot suffix should be passed to ``avb verify`` sub-command, e.g.::
+
+   => avb verify _a
+
+To switch on automatic generation of vbmeta partition in AOSP build, add these
+lines to device configuration mk file::
+
+   BOARD_AVB_ENABLE := true
+   BOARD_AVB_ALGORITHM := SHA512_RSA4096
+   BOARD_BOOTIMAGE_PARTITION_SIZE := <boot partition size>
+
+After flashing U-Boot don't forget to update environment and write new
+partition table::
+
+   => env default -f -a
+   => setenv partitions $partitions_android
+   => env save
+   => gpt write mmc 1 $partitions_android
+
+References
+----------
+
+.. [1] https://android.googlesource.com/platform/external/avb/+/master/README.md
+.. [2] https://www.op-tee.org/
diff --git a/doc/android/avb2.txt b/doc/android/avb2.txt
deleted file mode 100644 (file)
index 48e9297..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-Android Verified Boot 2.0
-
-This file contains information about the current support of Android Verified
-Boot 2.0 in U-boot
-
-1. OVERVIEW
----------------------------------
-Verified Boot establishes a chain of trust from the bootloader to system images
-* Provides integrity checking for:
-  - Android Boot image: Linux kernel + ramdisk. RAW hashing of the whole
-    partition is done and the hash is compared with the one stored in
-    the VBMeta image
-  - system/vendor partitions: verifying root hash of dm-verity hashtrees.
-* Provides capabilities for rollback protection.
-
-Integrity of the bootloader (U-boot BLOB and environment) is out of scope.
-
-For additional details check:
-https://android.googlesource.com/platform/external/avb/+/master/README.md
-
-1.1. AVB using OP-TEE (optional)
----------------------------------
-If AVB is configured to use OP-TEE (see 4. below) rollback indexes and
-device lock state are stored in RPMB. The RPMB partition is managed by
-OP-TEE (https://www.op-tee.org/) which is a secure OS leveraging ARM
-TrustZone.
-
-
-2. AVB 2.0 U-BOOT SHELL COMMANDS
------------------------------------
-Provides CLI interface to invoke AVB 2.0 verification + misc. commands for
-different testing purposes:
-
-avb init <dev> - initialize avb 2.0 for <dev>
-avb verify - run verification process using hash data from vbmeta structure
-avb read_rb <num> - read rollback index at location <num>
-avb write_rb <num> <rb> - write rollback index <rb> to <num>
-avb is_unlocked - returns unlock status of the device
-avb get_uuid <partname> - read and print uuid of partition <partname>
-avb read_part <partname> <offset> <num> <addr> - read <num> bytes from
-partition <partname> to buffer <addr>
-avb write_part <partname> <offset> <num> <addr> - write <num> bytes to
-<partname> by <offset> using data from <addr>
-
-
-3. PARTITIONS TAMPERING (EXAMPLE)
------------------------------------
-Boot or system/vendor (dm-verity metadata section) is tampered:
-=> avb init 1
-=> avb verify
-avb_slot_verify.c:175: ERROR: boot: Hash of data does not match digest in
-descriptor.
-Slot verification result: ERROR_IO
-
-Vbmeta partition is tampered:
-=> avb init 1
-=> avb verify
-avb_vbmeta_image.c:206: ERROR: Hash does not match!
-avb_slot_verify.c:388: ERROR: vbmeta: Error verifying vbmeta image:
-HASH_MISMATCH
-Slot verification result: ERROR_IO
-
-
-4. ENABLE ON YOUR BOARD
------------------------------------
-The following options must be enabled:
-CONFIG_LIBAVB=y
-CONFIG_AVB_VERIFY=y
-CONFIG_CMD_AVB=y
-
-In addtion optionally if storing rollback indexes in RPMB with help of
-OP-TEE:
-CONFIG_TEE=y
-CONFIG_OPTEE=y
-CONFIG_OPTEE_TA_AVB=y
-CONFIG_SUPPORT_EMMC_RPMB=y
-
-Then add `avb verify` invocation to your android boot sequence of commands,
-e.g.:
-
-=> avb_verify=avb init $mmcdev; avb verify;
-=> if run avb_verify; then                       \
-        echo AVB verification OK. Continue boot; \
-        set bootargs $bootargs $avb_bootargs;    \
-   else                                          \
-        echo AVB verification failed;            \
-        exit;                                    \
-   fi;                                           \
-
-=> emmc_android_boot=                                   \
-       echo Trying to boot Android from eMMC ...;       \
-       ...                                              \
-       run avb_verify;                                  \
-       mmc read ${fdtaddr} ${fdt_start} ${fdt_size};    \
-       mmc read ${loadaddr} ${boot_start} ${boot_size}; \
-       bootm $loadaddr $loadaddr $fdtaddr;              \
-
-If partitions you want to verify are slotted (have A/B suffixes), then current
-slot suffix should be passed to 'avb verify' sub-command, e.g.:
-
-=> avb verify _a
-
-To switch on automatic generation of vbmeta partition in AOSP build, add these
-lines to device configuration mk file:
-
-BOARD_AVB_ENABLE := true
-BOARD_AVB_ALGORITHM := SHA512_RSA4096
-BOARD_BOOTIMAGE_PARTITION_SIZE := <boot partition size>
-
-After flashing U-boot don't forget to update environment and write new
-partition table:
-=> env default -f -a
-=> setenv partitions $partitions_android
-=> env save
-=> gpt write mmc 1 $partitions_android
diff --git a/doc/android/bcb.rst b/doc/android/bcb.rst
new file mode 100644 (file)
index 0000000..8861608
--- /dev/null
@@ -0,0 +1,100 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Android Bootloader Control Block (BCB)
+======================================
+
+The purpose behind this file is to:
+
+* give an overview of BCB w/o duplicating public documentation
+* describe the main BCB use-cases which concern U-Boot
+* reflect current support status in U-Boot
+* mention any relevant U-Boot build-time tunables
+* precisely exemplify one or more use-cases
+
+Additions and fixes are welcome!
+
+Overview
+--------
+
+Bootloader Control Block (BCB) is a well established term/acronym in
+the Android namespace which refers to a location in a dedicated raw
+(i.e. FS-unaware) flash (e.g. eMMC) partition, usually called ``misc``,
+which is used as media for exchanging messages between Android userspace
+(particularly recovery [1]_) and an Android-capable bootloader.
+
+On higher level, BCB provides a way to implement a subset of Android
+Bootloader Requirements [2]_, amongst which are:
+
+* Android-specific bootloader flow [3]_
+* Get the "reboot reason" (and act accordingly) [4]_
+* Get/pass a list of commands from/to recovery [1]_
+* TODO
+
+
+'bcb'. Shell command overview
+-----------------------------
+
+The ``bcb`` command provides a CLI to facilitate the development of the
+requirements enumerated above. Below is the command's help message::
+
+   => bcb
+   bcb - Load/set/clear/test/dump/store Android BCB fields
+
+   Usage:
+   bcb load  <dev> <part>       - load  BCB from mmc <dev>:<part>
+   bcb set   <field> <val>      - set   BCB <field> to <val>
+   bcb clear [<field>]          - clear BCB <field> or all fields
+   bcb test  <field> <op> <val> - test  BCB <field> against <val>
+   bcb dump  <field>            - dump  BCB <field>
+   bcb store                    - store BCB back to mmc
+
+   Legend:
+   <dev>   - MMC device index containing the BCB partition
+   <part>  - MMC partition index or name containing the BCB
+   <field> - one of {command,status,recovery,stage,reserved}
+   <op>    - the binary operator used in 'bcb test':
+             '=' returns true if <val> matches the string stored in <field>
+             '~' returns true if <val> matches a subset of <field>'s string
+   <val>   - string/text provided as input to bcb {set,test}
+             NOTE: any ':' character in <val> will be replaced by line feed
+             during 'bcb set' and used as separator by upper layers
+
+
+'bcb'. Example of getting reboot reason
+---------------------------------------
+
+.. code-block:: bash
+
+   if bcb load 1 misc; then
+       # valid BCB found
+       if bcb test command = bootonce-bootloader; then
+           bcb clear command; bcb store;
+           # do the equivalent of AOSP ${fastbootcmd}
+           # i.e. call fastboot
+       else if bcb test command = boot-recovery; then
+           bcb clear command; bcb store;
+           # do the equivalent of AOSP ${recoverycmd}
+           # i.e. do anything required for booting into recovery
+       else
+           # boot Android OS normally
+       fi
+   else
+       # corrupted/non-existent BCB
+       # report error or boot non-Android OS (platform-specific)
+   fi
+
+
+Enable on your board
+--------------------
+
+The following Kconfig options must be enabled::
+
+   CONFIG_PARTITIONS=y
+   CONFIG_MMC=y
+   CONFIG_BCB=y
+
+.. [1] https://android.googlesource.com/platform/bootable/recovery
+.. [2] https://source.android.com/devices/bootloader
+.. [3] https://patchwork.ozlabs.org/patch/746835/
+       ("[U-Boot,5/6] Initial support for the Android Bootloader flow")
+.. [4] https://source.android.com/devices/bootloader/boot-reason
diff --git a/doc/android/bcb.txt b/doc/android/bcb.txt
deleted file mode 100644 (file)
index 7b7177c..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-Android Bootloader Control Block (BCB)
-
-The purpose behind this file is to:
- - give an overview of BCB w/o duplicating public documentation
- - describe the main BCB use-cases which concern U-Boot
- - reflect current support status in U-Boot
- - mention any relevant U-Boot build-time tunables
- - precisely exemplify one or more use-cases
-
-Additions and fixes are welcome!
-
-
-1. OVERVIEW
----------------------------------
-Bootloader Control Block (BCB) is a well established term/acronym in
-the Android namespace which refers to a location in a dedicated raw
-(i.e. FS-unaware) flash (e.g. eMMC) partition, usually called "misc",
-which is used as media for exchanging messages between Android userspace
-(particularly recovery [1]) and an Android-capable bootloader.
-
-On higher level, BCB provides a way to implement a subset of Android
-Bootloader Requirements [2], amongst which are:
- - Android-specific bootloader flow [3]
- - Get the "reboot reason" (and act accordingly) [4]
- - Get/pass a list of commands from/to recovery [1]
- - TODO
-
-
-2. 'BCB'. SHELL COMMAND OVERVIEW
------------------------------------
-The 'bcb' command provides a CLI to facilitate the development of the
-requirements enumerated above. Below is the command's help message:
-
-=> bcb
-bcb - Load/set/clear/test/dump/store Android BCB fields
-
-Usage:
-bcb load  <dev> <part>       - load  BCB from mmc <dev>:<part>
-bcb set   <field> <val>      - set   BCB <field> to <val>
-bcb clear [<field>]          - clear BCB <field> or all fields
-bcb test  <field> <op> <val> - test  BCB <field> against <val>
-bcb dump  <field>            - dump  BCB <field>
-bcb store                    - store BCB back to mmc
-
-Legend:
-<dev>   - MMC device index containing the BCB partition
-<part>  - MMC partition index or name containing the BCB
-<field> - one of {command,status,recovery,stage,reserved}
-<op>    - the binary operator used in 'bcb test':
-          '=' returns true if <val> matches the string stored in <field>
-          '~' returns true if <val> matches a subset of <field>'s string
-<val>   - string/text provided as input to bcb {set,test}
-          NOTE: any ':' character in <val> will be replaced by line feed
-          during 'bcb set' and used as separator by upper layers
-
-
-3. 'BCB'. EXAMPLE OF GETTING REBOOT REASON
------------------------------------
-if bcb load 1 misc; then
-    # valid BCB found
-    if bcb test command = bootonce-bootloader; then
-        bcb clear command; bcb store;
-        # do the equivalent of AOSP ${fastbootcmd}
-        # i.e. call fastboot
-    else if bcb test command = boot-recovery; then
-        bcb clear command; bcb store;
-        # do the equivalent of AOSP ${recoverycmd}
-        # i.e. do anything required for booting into recovery
-    else
-        # boot Android OS normally
-    fi
-else
-    # corrupted/non-existent BCB
-    # report error or boot non-Android OS (platform-specific)
-fi
-
-
-4. ENABLE ON YOUR BOARD
------------------------------------
-The following Kconfig options must be enabled:
-CONFIG_PARTITIONS=y
-CONFIG_MMC=y
-CONFIG_BCB=y
-
-[1] https://android.googlesource.com/platform/bootable/recovery
-[2] https://source.android.com/devices/bootloader
-[3] https://patchwork.ozlabs.org/patch/746835/
-    ("[U-Boot,5/6] Initial support for the Android Bootloader flow")
-[4] https://source.android.com/devices/bootloader/boot-reason
diff --git a/doc/android/boot-image.rst b/doc/android/boot-image.rst
new file mode 100644 (file)
index 0000000..195da68
--- /dev/null
@@ -0,0 +1,154 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Sam Protsenko <joe.skb7@gmail.com>
+
+Android Boot Image
+==================
+
+Overview
+--------
+
+Android Boot Image is used to boot Android OS. It usually contains kernel image
+(like ``zImage`` file) and ramdisk. Sometimes it can contain additional
+binaries. This image is built as a part of AOSP (called ``boot.img``), and being
+flashed into ``boot`` partition on eMMC. Bootloader then reads that image from
+``boot`` partition to RAM and boots the kernel from it. Kernel than starts
+``init`` process from the ramdisk. It should be mentioned that recovery image
+(``recovery.img``) also has Android Boot Image format.
+
+Android Boot Image format is described at [1]_. At the moment it can have one of
+next image headers:
+
+* v0: it's called *legacy* boot image header; used in devices launched before
+  Android 9; contains kernel image, ramdisk and second stage bootloader
+  (usually unused)
+* v1: used in devices launched with Android 9; adds ``recovery_dtbo`` field,
+  which should be used for non-A/B devices in ``recovery.img`` (see [2]_ for
+  details)
+* v2: used in devices launched with Android 10; adds ``dtb`` field, which
+  references payload containing DTB blobs (either concatenated one after the
+  other, or in Android DTBO image format)
+
+v2, v1 and v0 formats are backward compatible.
+
+Android Boot Image format is represented by :c:type:`struct andr_img_hdr` in
+U-Boot, and can be seen in ``include/android_image.h``. U-Boot supports booting
+Android Boot Image and also has associated command
+
+Booting
+-------
+
+U-Boot is able to boot the Android OS from Android Boot Image using ``bootm``
+command. In order to use Android Boot Image format support, next option should
+be enabled::
+
+    CONFIG_ANDROID_BOOT_IMAGE=y
+
+Then one can use next ``bootm`` command call to run Android:
+
+.. code-block:: bash
+
+    => bootm $loadaddr $loadaddr $fdtaddr
+
+where ``$loadaddr`` - address in RAM where boot image was loaded; ``$fdtaddr`` -
+address in RAM where DTB blob was loaded.
+
+And parameters are, correspondingly:
+
+  1. Where kernel image is located in RAM
+  2. Where ramdisk is located in RAM (can be ``"-"`` if not applicable)
+  3. Where DTB blob is located in RAM
+
+``bootm`` command will figure out that image located in ``$loadaddr`` has
+Android Boot Image format, will parse that and boot the kernel from it,
+providing DTB blob to kernel (from 3rd parameter), passing info about ramdisk to
+kernel via DTB.
+
+DTB and DTBO blobs
+------------------
+
+``bootm`` command can't just use DTB blob from Android Boot Image (``dtb``
+field), because:
+
+* there is no DTB area in Android Boot Image before v2
+* there may be several DTB blobs in DTB area (e.g. for different SoCs)
+* some DTBO blobs may have to be merged in DTB blobs before booting
+  (e.g. for different boards)
+
+So user has to prepare DTB blob manually and provide it in a 3rd parameter
+of ``bootm`` command. Next commands can be used to do so:
+
+1. ``abootimg``: manipulates Anroid Boot Image, allows one to extract
+   meta-information and payloads from it
+2. ``adtimg``: manipulates Android DTB/DTBO image [3]_, allows one to extract
+   DTB/DTBO blobs from it
+
+In order to use those, please enable next config options::
+
+    CONFIG_CMD_ABOOTIMG=y
+    CONFIG_CMD_ADTIMG=y
+
+For example, let's assume we have next Android partitions on eMMC:
+
+* ``boot``: contains Android Boot Image v2 (including DTB blobs)
+* ``dtbo``: contains DTBO blobs
+
+Then next command sequence can be used to boot Android:
+
+.. code-block:: bash
+
+    => mmc dev 1
+
+       # Read boot image to RAM (into $loadaddr)
+    => part start mmc 1 boot boot_start
+    => part size mmc 1 boot boot_size
+    => mmc read $loadaddr $boot_start $boot_size
+
+       # Read DTBO image to RAM (into $dtboaddr)
+    => part start mmc 1 dtbo dtbo_start
+    => part size mmc 1 dtbo dtbo_size
+    => mmc read $dtboaddr $dtbo_start $dtbo_size
+
+       # Copy required DTB blob (into $fdtaddr)
+    => abootimg get dtb --index=0 dtb0_start dtb0_size
+    => cp.b $dtb0_start $fdtaddr $dtb0_size
+
+       # Merge required DTBO blobs into DTB blob
+    => fdt addr $fdtaddr 0x100000
+    => adtimg addr $dtboaddr
+    => adtimg get dt --index=0 $dtbo0_addr
+    => fdt apply $dtbo0_addr
+
+       # Boot Android
+    => bootm $loadaddr $loadaddr $fdtaddr
+
+This sequence should be used for Android 10 boot. Of course, the whole Android
+boot procedure includes much more actions, like:
+
+* obtaining reboot reason from BCB (see [4]_)
+* implementing recovery boot
+* implementing fastboot boot
+* implementing A/B slotting (see [5]_)
+* implementing AVB2.0 (see [6]_)
+
+But Android Boot Image booting is the most crucial part in Android boot scheme.
+
+All Android bootloader requirements documentation is available at [7]_. Some
+overview on the whole Android 10 boot process can be found at [8]_.
+
+C API for working with Android Boot Image format
+------------------------------------------------
+
+.. kernel-doc:: common/image-android.c
+   :internal:
+
+References
+----------
+
+.. [1] https://source.android.com/devices/bootloader/boot-image-header
+.. [2] https://source.android.com/devices/bootloader/recovery-image
+.. [3] https://source.android.com/devices/architecture/dto/partitions
+.. [4] :doc:`bcb`
+.. [5] :doc:`ab`
+.. [6] :doc:`avb2`
+.. [7] https://source.android.com/devices/bootloader
+.. [8] https://connect.linaro.org/resources/san19/san19-217/
diff --git a/doc/android/fastboot-protocol.rst b/doc/android/fastboot-protocol.rst
new file mode 100644 (file)
index 0000000..e723659
--- /dev/null
@@ -0,0 +1,173 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+FastBoot Version 0.4
+====================
+
+The fastboot protocol is a mechanism for communicating with bootloaders
+over USB.  It is designed to be very straightforward to implement, to
+allow it to be used across a wide range of devices and from hosts running
+Linux, Windows, or OSX.
+
+Basic Requirements
+------------------
+
+* Two bulk endpoints (in, out) are required
+* Max packet size must be 64 bytes for full-speed and 512 bytes for
+  high-speed USB
+* The protocol is entirely host-driven and synchronous (unlike the
+  multi-channel, bi-directional, asynchronous ADB protocol)
+
+
+Transport and Framing
+---------------------
+
+1. Host sends a command, which is an ascii string in a single
+   packet no greater than 64 bytes.
+
+2. Client response with a single packet no greater than 64 bytes.
+   The first four bytes of the response are "OKAY", "FAIL", "DATA",
+   or "INFO".  Additional bytes may contain an (ascii) informative
+   message.
+
+   a. INFO -> the remaining 60 bytes are an informative message
+      (providing progress or diagnostic messages).  They should
+      be displayed and then step #2 repeats
+
+   b. FAIL -> the requested command failed.  The remaining 60 bytes
+      of the response (if present) provide a textual failure message
+      to present to the user.  Stop.
+
+   c. OKAY -> the requested command completed successfully.  Go to #5
+
+   d. DATA -> the requested command is ready for the data phase.
+      A DATA response packet will be 12 bytes long, in the form of
+      DATA00000000 where the 8 digit hexidecimal number represents
+      the total data size to transfer.
+
+3. Data phase.  Depending on the command, the host or client will
+   send the indicated amount of data.  Short packets are always
+   acceptable and zero-length packets are ignored.  This phase continues
+   until the client has sent or received the number of bytes indicated
+   in the "DATA" response above.
+
+4. Client responds with a single packet no greater than 64 bytes.
+   The first four bytes of the response are "OKAY", "FAIL", or "INFO".
+   Similar to #2:
+
+   a. INFO -> display the remaining 60 bytes and return to #4
+
+   b. FAIL -> display the remaining 60 bytes (if present) as a failure
+      reason and consider the command failed.  Stop.
+
+   c. OKAY -> success.  Go to #5
+
+5. Success.  Stop.
+
+
+Example Session
+---------------
+
+.. code-block:: none
+
+    Host:    "getvar:version"        request version variable
+
+    Client:  "OKAY0.4"               return version "0.4"
+
+    Host:    "getvar:nonexistant"    request some undefined variable
+
+    Client:  "OKAY"                  return value ""
+
+    Host:    "download:00001234"     request to send 0x1234 bytes of data
+
+    Client:  "DATA00001234"          ready to accept data
+
+    Host:    < 0x1234 bytes >        send data
+
+    Client:  "OKAY"                  success
+
+    Host:    "flash:bootloader"      request to flash the data to the bootloader
+
+    Client:  "INFOerasing flash"     indicate status / progress
+             "INFOwriting flash"
+             "OKAY"                  indicate success
+
+    Host:    "powerdown"             send a command
+
+    Client:  "FAILunknown command"   indicate failure
+
+
+Command Reference
+-----------------
+
+* Command parameters are indicated by printf-style escape sequences.
+
+* Commands are ascii strings and sent without the quotes (which are
+  for illustration only here) and without a trailing 0 byte.
+
+* Commands that begin with a lowercase letter are reserved for this
+  specification.  OEM-specific commands should not begin with a
+  lowercase letter, to prevent incompatibilities with future specs.
+
+.. code-block:: none
+
+ "getvar:%s"           Read a config/version variable from the bootloader.
+                       The variable contents will be returned after the
+                       OKAY response.
+
+ "download:%08x"       Write data to memory which will be later used
+                       by "boot", "ramdisk", "flash", etc.  The client
+                       will reply with "DATA%08x" if it has enough
+                       space in RAM or "FAIL" if not.  The size of
+                       the download is remembered.
+
+  "verify:%08x"        Send a digital signature to verify the downloaded
+                       data.  Required if the bootloader is "secure"
+                       otherwise "flash" and "boot" will be ignored.
+
+  "flash:%s"           Write the previously downloaded image to the
+                       named partition (if possible).
+
+  "erase:%s"           Erase the indicated partition (clear to 0xFFs)
+
+  "boot"               The previously downloaded data is a boot.img
+                       and should be booted according to the normal
+                       procedure for a boot.img
+
+  "continue"           Continue booting as normal (if possible)
+
+  "reboot"             Reboot the device.
+
+  "reboot-bootloader"  Reboot back into the bootloader.
+                       Useful for upgrade processes that require upgrading
+                       the bootloader and then upgrading other partitions
+                       using the new bootloader.
+
+  "powerdown"          Power off the device.
+
+Client Variables
+----------------
+
+The ``getvar:%s`` command is used to read client variables which
+represent various information about the device and the software
+on it.
+
+The various currently defined names are::
+
+  version             Version of FastBoot protocol supported.
+                      It should be "0.3" for this document.
+
+  version-bootloader  Version string for the Bootloader.
+
+  version-baseband    Version string of the Baseband Software
+
+  product             Name of the product
+
+  serialno            Product serial number
+
+  secure              If the value is "yes", this is a secure
+                      bootloader requiring a signature before
+                      it will install or boot images.
+
+Names starting with a lowercase character are reserved by this
+specification.  OEM-specific names should not start with lowercase
+characters.
diff --git a/doc/android/fastboot-protocol.txt b/doc/android/fastboot-protocol.txt
deleted file mode 100644 (file)
index e9e7166..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-FastBoot  Version  0.4
-----------------------
-
-The fastboot protocol is a mechanism for communicating with bootloaders
-over USB.  It is designed to be very straightforward to implement, to
-allow it to be used across a wide range of devices and from hosts running
-Linux, Windows, or OSX.
-
-
-Basic Requirements
-------------------
-
-* Two bulk endpoints (in, out) are required
-* Max packet size must be 64 bytes for full-speed and 512 bytes for
-  high-speed USB
-* The protocol is entirely host-driven and synchronous (unlike the
-  multi-channel, bi-directional, asynchronous ADB protocol)
-
-
-Transport and Framing
----------------------
-
-1. Host sends a command, which is an ascii string in a single
-   packet no greater than 64 bytes.
-
-2. Client response with a single packet no greater than 64 bytes.
-   The first four bytes of the response are "OKAY", "FAIL", "DATA",
-   or "INFO".  Additional bytes may contain an (ascii) informative
-   message.
-
-   a. INFO -> the remaining 60 bytes are an informative message
-      (providing progress or diagnostic messages).  They should
-      be displayed and then step #2 repeats
-
-   b. FAIL -> the requested command failed.  The remaining 60 bytes
-      of the response (if present) provide a textual failure message
-      to present to the user.  Stop.
-
-   c. OKAY -> the requested command completed successfully.  Go to #5
-
-   d. DATA -> the requested command is ready for the data phase.
-      A DATA response packet will be 12 bytes long, in the form of
-      DATA00000000 where the 8 digit hexidecimal number represents
-      the total data size to transfer.
-
-3. Data phase.  Depending on the command, the host or client will
-   send the indicated amount of data.  Short packets are always
-   acceptable and zero-length packets are ignored.  This phase continues
-   until the client has sent or received the number of bytes indicated
-   in the "DATA" response above.
-
-4. Client responds with a single packet no greater than 64 bytes.
-   The first four bytes of the response are "OKAY", "FAIL", or "INFO".
-   Similar to #2:
-
-   a. INFO -> display the remaining 60 bytes and return to #4
-
-   b. FAIL -> display the remaining 60 bytes (if present) as a failure
-      reason and consider the command failed.  Stop.
-
-   c. OKAY -> success.  Go to #5
-
-5. Success.  Stop.
-
-
-Example Session
----------------
-
-Host:    "getvar:version"        request version variable
-
-Client:  "OKAY0.4"               return version "0.4"
-
-Host:    "getvar:nonexistant"    request some undefined variable
-
-Client:  "OKAY"                  return value ""
-
-Host:    "download:00001234"     request to send 0x1234 bytes of data
-
-Client:  "DATA00001234"          ready to accept data
-
-Host:    < 0x1234 bytes >        send data
-
-Client:  "OKAY"                  success
-
-Host:    "flash:bootloader"      request to flash the data to the bootloader
-
-Client:  "INFOerasing flash"     indicate status / progress
-         "INFOwriting flash"
-         "OKAY"                  indicate success
-
-Host:    "powerdown"             send a command
-
-Client:  "FAILunknown command"   indicate failure
-
-
-Command Reference
------------------
-
-* Command parameters are indicated by printf-style escape sequences.
-
-* Commands are ascii strings and sent without the quotes (which are
-  for illustration only here) and without a trailing 0 byte.
-
-* Commands that begin with a lowercase letter are reserved for this
-  specification.  OEM-specific commands should not begin with a
-  lowercase letter, to prevent incompatibilities with future specs.
-
- "getvar:%s"           Read a config/version variable from the bootloader.
-                       The variable contents will be returned after the
-                       OKAY response.
-
- "download:%08x"       Write data to memory which will be later used
-                       by "boot", "ramdisk", "flash", etc.  The client
-                       will reply with "DATA%08x" if it has enough
-                       space in RAM or "FAIL" if not.  The size of
-                       the download is remembered.
-
-  "verify:%08x"        Send a digital signature to verify the downloaded
-                       data.  Required if the bootloader is "secure"
-                       otherwise "flash" and "boot" will be ignored.
-
-  "flash:%s"           Write the previously downloaded image to the
-                       named partition (if possible).
-
-  "erase:%s"           Erase the indicated partition (clear to 0xFFs)
-
-  "boot"               The previously downloaded data is a boot.img
-                       and should be booted according to the normal
-                       procedure for a boot.img
-
-  "continue"           Continue booting as normal (if possible)
-
-  "reboot"             Reboot the device.
-
-  "reboot-bootloader"  Reboot back into the bootloader.
-                       Useful for upgrade processes that require upgrading
-                       the bootloader and then upgrading other partitions
-                       using the new bootloader.
-
-  "powerdown"          Power off the device.
-
-
-
-Client Variables
-----------------
-
-The "getvar:%s" command is used to read client variables which
-represent various information about the device and the software
-on it.
-
-The various currently defined names are:
-
-  version             Version of FastBoot protocol supported.
-                      It should be "0.3" for this document.
-
-  version-bootloader  Version string for the Bootloader.
-
-  version-baseband    Version string of the Baseband Software
-
-  product             Name of the product
-
-  serialno            Product serial number
-
-  secure              If the value is "yes", this is a secure
-                      bootloader requiring a signature before
-                      it will install or boot images.
-
-Names starting with a lowercase character are reserved by this
-specification.  OEM-specific names should not start with lowercase
-characters.
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
new file mode 100644 (file)
index 0000000..de3f6c3
--- /dev/null
@@ -0,0 +1,206 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Android Fastboot
+================
+
+Overview
+--------
+
+The protocol that is used over USB and UDP is described in [1]_.
+
+The current implementation supports the following standard commands:
+
+- ``boot``
+- ``continue``
+- ``download``
+- ``erase`` (if enabled)
+- ``flash`` (if enabled)
+- ``getvar``
+- ``reboot``
+- ``reboot-bootloader``
+- ``set_active`` (only a stub implementation which always succeeds)
+
+The following OEM commands are supported (if enabled):
+
+- ``oem format`` - this executes ``gpt write mmc %x $partitions``
+
+Support for both eMMC and NAND devices is included.
+
+Client installation
+-------------------
+
+The counterpart to this is the fastboot client which can be found in
+Android's ``platform/system/core`` repository in the fastboot
+folder. It runs on Windows, Linux and OSX. The fastboot client is
+part of the Android SDK Platform-Tools and can be downloaded from [2]_.
+
+Board specific
+--------------
+
+USB configuration
+^^^^^^^^^^^^^^^^^
+
+The fastboot gadget relies on the USB download gadget, so the following
+options must be configured:
+
+::
+
+   CONFIG_USB_GADGET_DOWNLOAD
+   CONFIG_USB_GADGET_VENDOR_NUM
+   CONFIG_USB_GADGET_PRODUCT_NUM
+   CONFIG_USB_GADGET_MANUFACTURER
+
+NOTE: The ``CONFIG_USB_GADGET_VENDOR_NUM`` must be one of the numbers
+supported by the fastboot client. The list of vendor IDs supported can
+be found in the fastboot client source code.
+
+General configuration
+^^^^^^^^^^^^^^^^^^^^^
+
+The fastboot protocol requires a large memory buffer for
+downloads. This buffer should be as large as possible for a
+platform. The location of the buffer and size are set with
+``CONFIG_FASTBOOT_BUF_ADDR`` and ``CONFIG_FASTBOOT_BUF_SIZE``. These
+may be overridden on the fastboot command line using ``-l`` and
+``-s``.
+
+Fastboot environment variables
+------------------------------
+
+Partition aliases
+^^^^^^^^^^^^^^^^^
+
+Fastboot partition aliases can also be defined for devices where GPT
+limitations prevent user-friendly partition names such as ``boot``, ``system``
+and ``cache``.  Or, where the actual partition name doesn't match a standard
+partition name used commonly with fastboot.
+
+The current implementation checks aliases when accessing partitions by
+name (flash_write and erase functions).  To define a partition alias
+add an environment variable similar to::
+
+    fastboot_partition_alias_<alias partition name>=<actual partition name>
+
+for example::
+
+    fastboot_partition_alias_boot=LNX
+
+Variable overrides
+^^^^^^^^^^^^^^^^^^
+
+Variables retrived through ``getvar`` can be overridden by defining
+environment variables of the form ``fastboot.<variable>``. These are
+looked up first so can be used to override values which would
+otherwise be returned. Using this mechanism you can also return types
+for NAND filesystems, as the fully parameterised variable is looked
+up, e.g.::
+
+    fastboot.partition-type:boot=jffs2
+
+Boot command
+^^^^^^^^^^^^
+
+When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set
+then that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
+
+Partition Names
+---------------
+
+The Fastboot implementation in U-Boot allows to write images into disk
+partitions. Target partitions are referred on the host computer by
+their names.
+
+For GPT/EFI the respective partition name is used.
+
+For MBR the partitions are referred by generic names according to the
+following schema::
+
+    <device type><device index letter><partition index>
+
+Example: ``hda3``, ``sdb1``, ``usbda1``.
+
+The device type is as follows:
+
+  * IDE, ATAPI and SATA disks: ``hd``
+  * SCSI disks: ``sd``
+  * USB media: ``usbd``
+  * MMC and SD cards: ``mmcsd``
+  * Disk on chip: ``docd``
+  * other: ``xx``
+
+The device index starts from ``a`` and refers to the interface (e.g. USB
+controller, SD/MMC controller) or disk index. The partition index starts
+from ``1`` and describes the partition number on the particular device.
+
+Writing Partition Table
+-----------------------
+
+Fastboot also allows to write the partition table to the media. This can be
+done by writing the respective partition table image to a special target
+"gpt" or "mbr". These names can be customized by defining the following
+configuration options:
+
+::
+
+   CONFIG_FASTBOOT_GPT_NAME
+   CONFIG_FASTBOOT_MBR_NAME
+
+In Action
+---------
+
+Enter into fastboot by executing the fastboot command in U-Boot for either USB::
+
+   => fastboot usb 0
+
+or UDP::
+
+   => fastboot udp
+   link up on port 0, speed 100, full duplex
+   Using ethernet@4a100000 device
+   Listening for fastboot command on 192.168.0.102
+
+On the client side you can fetch the bootloader version for instance::
+
+   $ fastboot getvar version-bootloader
+   version-bootloader: U-Boot 2019.07-rc4-00240-g00c9f2a2ec
+   Finished. Total time: 0.005s
+
+or initiate a reboot::
+
+   $ fastboot reboot
+
+and once the client comes back, the board should reset.
+
+You can also specify a kernel image to boot. You have to either specify
+the an image in Android format *or* pass a binary kernel and let the
+fastboot client wrap the Android suite around it. On OMAP for instance you
+take zImage kernel and pass it to the fastboot client::
+
+   $ fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0 mem=128M" boot zImage
+   creating boot image...
+   creating boot image - 1847296 bytes
+   downloading 'boot.img'...
+   OKAY [  2.766s]
+   booting...
+   OKAY [ -0.000s]
+   finished. total time: 2.766s
+
+and on the U-Boot side you should see::
+
+   Starting download of 1847296 bytes
+   ........................................................
+   downloading of 1847296 bytes finished
+   Booting kernel..
+   ## Booting Android Image at 0x81000000 ...
+   Kernel load addr 0x80008000 size 1801 KiB
+   Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
+      Loading Kernel Image ... OK
+   OK
+
+   Starting kernel ...
+
+References
+----------
+
+.. [1] :doc:`fastboot-protocol`
+.. [2] https://developer.android.com/studio/releases/platform-tools
diff --git a/doc/android/fastboot.txt b/doc/android/fastboot.txt
deleted file mode 100644 (file)
index 9de1322..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-================
-Android Fastboot
-================
-
-Overview
-========
-
-The protocol that is used over USB and UDP is described in
-``doc/android/fastboot-protocol.txt``.
-
-The current implementation supports the following standard commands:
-
-- ``boot``
-- ``continue``
-- ``download``
-- ``erase`` (if enabled)
-- ``flash`` (if enabled)
-- ``getvar``
-- ``reboot``
-- ``reboot-bootloader``
-- ``set_active`` (only a stub implementation which always succeeds)
-
-The following OEM commands are supported (if enabled):
-
-- oem format - this executes ``gpt write mmc %x $partitions``
-
-Support for both eMMC and NAND devices is included.
-
-Client installation
-===================
-
-The counterpart to this is the fastboot client which can be found in
-Android's ``platform/system/core`` repository in the fastboot
-folder. It runs on Windows, Linux and OSX. The fastboot client is
-part of the Android SDK Platform-Tools and can be downloaded from:
-
-https://developer.android.com/studio/releases/platform-tools
-
-Board specific
-==============
-
-USB configuration
------------------
-
-The fastboot gadget relies on the USB download gadget, so the following
-options must be configured:
-
-::
-
-   CONFIG_USB_GADGET_DOWNLOAD
-   CONFIG_USB_GADGET_VENDOR_NUM
-   CONFIG_USB_GADGET_PRODUCT_NUM
-   CONFIG_USB_GADGET_MANUFACTURER
-
-NOTE: The ``CONFIG_USB_GADGET_VENDOR_NUM`` must be one of the numbers
-supported by the fastboot client. The list of vendor IDs supported can
-be found in the fastboot client source code.
-
-General configuration
----------------------
-
-The fastboot protocol requires a large memory buffer for
-downloads. This buffer should be as large as possible for a
-platform. The location of the buffer and size are set with
-``CONFIG_FASTBOOT_BUF_ADDR`` and ``CONFIG_FASTBOOT_BUF_SIZE``. These
-may be overridden on the fastboot command line using ``-l`` and
-``-s``.
-
-Fastboot environment variables
-==============================
-
-Partition aliases
------------------
-
-Fastboot partition aliases can also be defined for devices where GPT
-limitations prevent user-friendly partition names such as "boot", "system"
-and "cache".  Or, where the actual partition name doesn't match a standard
-partition name used commonly with fastboot.
-
-The current implementation checks aliases when accessing partitions by
-name (flash_write and erase functions).  To define a partition alias
-add an environment variable similar to:
-
-``fastboot_partition_alias_<alias partition name>=<actual partition name>``
-
-for example:
-
-``fastboot_partition_alias_boot=LNX``
-
-Variable overrides
-------------------
-
-Variables retrived through ``getvar`` can be overridden by defining
-environment variables of the form ``fastboot.<variable>``. These are
-looked up first so can be used to override values which would
-otherwise be returned. Using this mechanism you can also return types
-for NAND filesystems, as the fully parameterised variable is looked
-up, e.g.
-
-``fastboot.partition-type:boot=jffs2``
-
-Boot command
-------------
-
-When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set then
-that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
-
-Partition Names
-===============
-
-The Fastboot implementation in U-Boot allows to write images into disk
-partitions. Target partitions are referred on the host computer by
-their names.
-
-For GPT/EFI the respective partition name is used.
-
-For MBR the partitions are referred by generic names according to the
-following schema:
-
-  <device type><device index letter><partition index>
-
-Example: ``hda3``, ``sdb1``, ``usbda1``
-
-The device type is as follows:
-
-  * IDE, ATAPI and SATA disks: ``hd``
-  * SCSI disks: ``sd``
-  * USB media: ``usbd``
-  * MMC and SD cards: ``mmcsd``
-  * Disk on chip: ``docd``
-  * other: ``xx``
-
-The device index starts from ``a`` and refers to the interface (e.g. USB
-controller, SD/MMC controller) or disk index. The partition index starts
-from ``1`` and describes the partition number on the particular device.
-
-Writing Partition Table
-=======================
-
-Fastboot also allows to write the partition table to the media. This can be
-done by writing the respective partition table image to a special target
-"gpt" or "mbr". These names can be customized by defining the following
-configuration options:
-
-::
-
-   CONFIG_FASTBOOT_GPT_NAME
-   CONFIG_FASTBOOT_MBR_NAME
-
-In Action
-=========
-
-Enter into fastboot by executing the fastboot command in U-Boot for either USB:
-
-::
-
-   => fastboot usb 0
-
-or UDP:
-
-::
-
-   => fastboot udp
-   link up on port 0, speed 100, full duplex
-   Using ethernet@4a100000 device
-   Listening for fastboot command on 192.168.0.102
-
-On the client side you can fetch the bootloader version for instance:
-
-::
-
-   $ fastboot getvar version-bootloader
-   version-bootloader: U-Boot 2019.07-rc4-00240-g00c9f2a2ec
-   Finished. Total time: 0.005s
-
-or initiate a reboot:
-
-::
-
-   $ fastboot reboot
-
-and once the client comes back, the board should reset.
-
-You can also specify a kernel image to boot. You have to either specify
-the an image in Android format *or* pass a binary kernel and let the
-fastboot client wrap the Android suite around it. On OMAP for instance you
-take zImage kernel and pass it to the fastboot client:
-
-::
-
-   $ fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0 mem=128M" boot zImage
-   creating boot image...
-   creating boot image - 1847296 bytes
-   downloading 'boot.img'...
-   OKAY [  2.766s]
-   booting...
-   OKAY [ -0.000s]
-   finished. total time: 2.766s
-
-and on the U-Boot side you should see:
-
-::
-
-   Starting download of 1847296 bytes
-   ........................................................
-   downloading of 1847296 bytes finished
-   Booting kernel..
-   ## Booting Android Image at 0x81000000 ...
-   Kernel load addr 0x80008000 size 1801 KiB
-   Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
-      Loading Kernel Image ... OK
-   OK
-
-   Starting kernel ...
diff --git a/doc/android/index.rst b/doc/android/index.rst
new file mode 100644 (file)
index 0000000..225d6f1
--- /dev/null
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Android-specific doc
+====================
+
+.. toctree::
+   :maxdepth: 2
+
+   ab
+   avb2
+   bcb
+   boot-image
+   fastboot-protocol
+   fastboot
index 515fd06d769fd5000dd5b6d0b834ab0504ab01e6..5dc3c97c3d1a1ffbb6e1c14ffdfa2dd15b745943 100644 (file)
@@ -112,7 +112,7 @@ U-Boot then shuts down CAR and jumps to its relocated version.
 
 
 Boot flow - U-Boot post-relocation
----------------------------------
+----------------------------------
 
 U-Boot starts up normally, running near the top of RAM. After driver model is
 running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
@@ -142,54 +142,56 @@ Performance
 -----------
 
 Bootstage is used through all phases of U-Boot to keep accurate timimgs for
-boot. Use 'bootstage report' in U-Boot to see the report, e.g.:
-
-Timer summary in microseconds (16 records):
-       Mark    Elapsed  Stage
-          0          0  reset
-    155,325    155,325  TPL
-    204,014     48,689  end TPL
-    204,385        371  SPL
-    738,633    534,248  end SPL
-    739,161        528  board_init_f
-    842,764    103,603  board_init_r
-  1,166,233    323,469  main_loop
-  1,166,283         50  id=175
-
-Accumulated time:
-                    62  fast_spi
-                   202  dm_r
-                 7,779  dm_spl
-                15,555  dm_f
-               208,357  fsp-m
-               239,847  fsp-s
-               292,143  mmap_spi
-
-CPU performance is about 3500 DMIPS:
-
-=> dhry
-1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
+boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
+
+    Timer summary in microseconds (16 records):
+           Mark    Elapsed  Stage
+              0          0  reset
+        155,325    155,325  TPL
+        204,014     48,689  end TPL
+        204,385        371  SPL
+        738,633    534,248  end SPL
+        739,161        528  board_init_f
+        842,764    103,603  board_init_r
+      1,166,233    323,469  main_loop
+      1,166,283         50  id=175
+
+    Accumulated time:
+                        62  fast_spi
+                       202  dm_r
+                     7,779  dm_spl
+                    15,555  dm_f
+                   208,357  fsp-m
+                   239,847  fsp-s
+                   292,143  mmap_spi
+
+CPU performance is about 3500 DMIPS::
+
+    => dhry
+    1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
 
 
 Partial memory map
 ------------------
 
-ffffffff       Top of ROM (and last byte of 32-bit address space)
-ffff8000       TPL loaded here (from IFWI)
-ff000000       Bottom of ROM
-fefc000                 Top of CAR region
-fef96000       Stack for FSP-M
-fef40000 59000 FSP-M
-fef11000       SPL loaded here
-fef10000       CONFIG_BLOBLIST_ADDR
-fef10000       Stack top in TPL, SPL and U-Boot before relocation
-fef00000  1000 CONFIG_BOOTSTAGE_STASH_ADDR
-fef00000       Base of CAR region
-
-   f0000       CONFIG_ROM_TABLE_ADDR
-  120000       BSS (defined in u-boot-spl.lds)
-  200000       FSP-S (which is run after U-Boot is relocated)
- 1110000       CONFIG_SYS_TEXT_BASE
+::
+
+    ffffffff       Top of ROM (and last byte of 32-bit address space)
+    ffff8000       TPL loaded here (from IFWI)
+    ff000000       Bottom of ROM
+     fefc000       Top of CAR region
+    fef96000       Stack for FSP-M
+    fef40000 59000 FSP-M
+    fef11000       SPL loaded here
+    fef10000       CONFIG_BLOBLIST_ADDR
+    fef10000       Stack top in TPL, SPL and U-Boot before relocation
+    fef00000  1000 CONFIG_BOOTSTAGE_STASH_ADDR
+    fef00000       Base of CAR region
+
+       f0000       CONFIG_ROM_TABLE_ADDR
+      120000       BSS (defined in u-boot-spl.lds)
+      200000       FSP-S (which is run after U-Boot is relocated)
+     1110000       CONFIG_SYS_TEXT_BASE
 
 
 Supported peripherals
index 375e6768045824fb448a761851f50750e3c84e25..a8c41b1aa70fcf14e085d2b3dabf65f67f125392 100644 (file)
@@ -111,35 +111,16 @@ Download it from http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/mach
 Build Instruction for Slim Bootloader for LeafHill (APL) target
 ---------------------------------------------------------------
 
-LeafHill is using PCI UART2 device as a serial port.
-For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
+Prepare U-Boot and Slim Bootloader as described at the beginning of this page.
+Also, the PayloadId needs to be set for APL board.
 
-1. Enable CONFIG_SYS_NS16550_MEM32 in U-Boot::
-
-    $ vi include/configs/slimbootloader.h
-    +#define CONFIG_SYS_NS16550_MEM32
-     #ifdef CONFIG_SYS_NS16550_MEM3
-
-2. Build U-Boot::
-
-   $ make disclean
-   $ make slimbootloader_defconfig
-   $ make all
-
-3. Copy u-boot-dtb.bin to Slim Bootloader.
-   Slim Bootloader looks for a payload from the specific location.
-   Copy the build u-boot-dtb.bin to the expected location::
-
-   $ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
-   $ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
-
-4. Update PayloadId. Let's use 'U-BT' as an example::
+1. Update PayloadId. Let's use 'U-BT' as an example::
 
     $ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt
     -GEN_CFG_DATA.PayloadId                     | 'AUTO
     +GEN_CFG_DATA.PayloadId                     | 'U-BT'
 
-5. Update payload text base.
+2. Update payload text base.
 
 * PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE
   in board/intel/slimbootloader/Kconfig.
@@ -149,18 +130,18 @@ For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
     +               self.PAYLOAD_LOAD_HIGH    = 0
     +               self.PAYLOAD_EXE_BASE     = 0x00100000
 
-6. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
+3. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
    in build command. The output is Outputs/apl/Stitch_Components.zip::
 
    $ python BuildLoader.py build apl -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
 
-7. Stitch IFWI.
+4. Stitch IFWI.
 
    Refer to Apollolake_ page in Slim Bootloader document site::
 
    $ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py -i <Existing IFWI> -s Outputs/apl/Stitch_Components.zip -o <Output IFWI>
 
-8. Flash IFWI.
+5. Flash IFWI.
 
    Use DediProg to flash IFWI. You should reach at U-Boot serial console.
 
@@ -175,7 +156,7 @@ Build Instruction to use ELF U-Boot
 
 2. Build U-Boot::
 
-   $ make disclean
+   $ make distclean
    $ make slimbootloader_defconfig
    $ make all
    $ strip u-boot (removing symbol for reduced size)
index 206a04590fa0cd6057683c9a7edcf3c27925c53a..cd98be6cc5fdaab0f20bb4eea301b25465965e23 100644 (file)
@@ -86,6 +86,18 @@ organized in a vendor subdirectory.
 
    board/index
 
+Android-specific doc
+--------------------
+
+These books provide information about booting the Android OS from U-Boot,
+manipulating Android images from U-Boot shell and discusses other
+Android-specific features available in U-Boot.
+
+.. toctree::
+   :maxdepth: 2
+
+   android/index
+
 Indices and tables
 ==================
 
index 5b551f6ae115c91f4757f150fe491e6d77e57fe1..0d495a785bc3200e5b5ad4300761abe18a16dc57 100644 (file)
@@ -17,7 +17,7 @@
 
 static unsigned char *dfu_file_buf;
 static u64 dfu_file_buf_len;
-static long dfu_file_buf_filled;
+static u64 dfu_file_buf_offset;
 
 static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len)
@@ -91,22 +91,8 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
        return 0;
 }
 
-static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len)
-{
-       if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE) {
-               dfu_file_buf_len = 0;
-               return -EINVAL;
-       }
-
-       /* Add to the current buffer. */
-       memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len);
-       dfu_file_buf_len += *len;
-
-       return 0;
-}
-
 static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
-                       void *buf, u64 *len)
+                       u64 offset, void *buf, u64 *len)
 {
        char dev_part_str[8];
        int ret;
@@ -137,7 +123,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
 
        switch (op) {
        case DFU_OP_READ:
-               ret = fs_read(dfu->name, (size_t)buf, 0, 0, &size);
+               ret = fs_read(dfu->name, (size_t)buf, offset, *len, &size);
                if (ret) {
                        puts("dfu: fs_read error!\n");
                        return ret;
@@ -145,7 +131,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
                *len = size;
                break;
        case DFU_OP_WRITE:
-               ret = fs_write(dfu->name, (size_t)buf, 0, *len, &size);
+               ret = fs_write(dfu->name, (size_t)buf, offset, *len, &size);
                if (ret) {
                        puts("dfu: fs_write error!\n");
                        return ret;
@@ -166,6 +152,43 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
        return ret;
 }
 
+static int mmc_file_buf_write(struct dfu_entity *dfu, u64 offset, void *buf, long *len)
+{
+       int ret = 0;
+
+       if (offset == 0) {
+               dfu_file_buf_len = 0;
+               dfu_file_buf_offset = 0;
+       }
+
+       /* Add to the current buffer. */
+       if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE)
+               *len = CONFIG_SYS_DFU_MAX_FILE_SIZE - dfu_file_buf_len;
+       memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len);
+       dfu_file_buf_len += *len;
+
+       if (dfu_file_buf_len == CONFIG_SYS_DFU_MAX_FILE_SIZE) {
+               ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf_offset,
+                                 dfu_file_buf, &dfu_file_buf_len);
+               dfu_file_buf_offset += dfu_file_buf_len;
+               dfu_file_buf_len = 0;
+       }
+
+       return ret;
+}
+
+static int mmc_file_buf_write_finish(struct dfu_entity *dfu)
+{
+       int ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf_offset,
+                       dfu_file_buf, &dfu_file_buf_len);
+
+       /* Now that we're done */
+       dfu_file_buf_len = 0;
+       dfu_file_buf_offset = 0;
+
+       return ret;
+}
+
 int dfu_write_medium_mmc(struct dfu_entity *dfu,
                u64 offset, void *buf, long *len)
 {
@@ -177,7 +200,7 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
                break;
        case DFU_FS_FAT:
        case DFU_FS_EXT4:
-               ret = mmc_file_buffer(dfu, buf, len);
+               ret = mmc_file_buf_write(dfu, offset, buf, len);
                break;
        default:
                printf("%s: Layout (%s) not (yet) supported!\n", __func__,
@@ -193,11 +216,7 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
 
        if (dfu->layout != DFU_RAW_ADDR) {
                /* Do stuff here. */
-               ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf,
-                               &dfu_file_buf_len);
-
-               /* Now that we're done */
-               dfu_file_buf_len = 0;
+               ret = mmc_file_buf_write_finish(dfu);
        }
 
        return ret;
@@ -213,12 +232,9 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 *size)
                return 0;
        case DFU_FS_FAT:
        case DFU_FS_EXT4:
-               dfu_file_buf_filled = -1;
-               ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, size);
+               ret = mmc_file_op(DFU_OP_SIZE, dfu, 0, NULL, size);
                if (ret < 0)
                        return ret;
-               if (*size > CONFIG_SYS_DFU_MAX_FILE_SIZE)
-                       return -1;
                return 0;
        default:
                printf("%s: Layout (%s) not (yet) supported!\n", __func__,
@@ -227,23 +243,28 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 *size)
        }
 }
 
-static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf,
+
+static int mmc_file_buf_read(struct dfu_entity *dfu, u64 offset, void *buf,
                             long *len)
 {
        int ret;
-       u64 file_len;
 
-       if (dfu_file_buf_filled == -1) {
-               ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len);
+       if (offset == 0 || offset >= dfu_file_buf_offset + dfu_file_buf_len ||
+           offset + *len < dfu_file_buf_offset) {
+               u64 file_len = CONFIG_SYS_DFU_MAX_FILE_SIZE;
+
+               ret = mmc_file_op(DFU_OP_READ, dfu, offset, dfu_file_buf,
+                                 &file_len);
                if (ret < 0)
                        return ret;
-               dfu_file_buf_filled = file_len;
+               dfu_file_buf_len = file_len;
+               dfu_file_buf_offset = offset;
        }
-       if (offset + *len > dfu_file_buf_filled)
+       if (offset + *len > dfu_file_buf_offset + dfu_file_buf_len)
                return -EINVAL;
 
        /* Add to the current buffer. */
-       memcpy(buf, dfu_file_buf + offset, *len);
+       memcpy(buf, dfu_file_buf + offset - dfu_file_buf_offset, *len);
 
        return 0;
 }
@@ -259,7 +280,7 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf,
                break;
        case DFU_FS_FAT:
        case DFU_FS_EXT4:
-               ret = mmc_file_unbuffer(dfu, offset, buf, len);
+               ret = mmc_file_buf_read(dfu, offset, buf, len);
                break;
        default:
                printf("%s: Layout (%s) not (yet) supported!\n", __func__,
index bd5a366aef3282ff332788821d393e534c66a4e8..ac88f0ca8d8e195fbb92cf0f4d7830b240045987 100644 (file)
@@ -434,7 +434,7 @@ int gpio_set_value(unsigned int gpio, int value)
 static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
 {
        struct davinci_gpio_bank *bank = dev_get_priv(dev);
-       unsigned int addr;
+       unsigned long addr;
 
        /*
         * The device tree is not broken into banks but the infrastructure is
@@ -535,6 +535,7 @@ static int davinci_gpio_probe(struct udevice *dev)
 static const struct udevice_id davinci_gpio_ids[] = {
        { .compatible = "ti,dm6441-gpio" },
        { .compatible = "ti,k2g-gpio" },
+       { .compatible = "ti,keystone-gpio" },
        { }
 };
 
index 4bf1c9ddc4e7057544d287b9aa08f41612955814..67b8b80b9d68c07cc021540bdb213ceab8f8975a 100644 (file)
@@ -39,9 +39,9 @@ static int intel_gpio_direction_output(struct udevice *dev, uint offset,
        struct udevice *pinctrl = dev_get_parent(dev);
        uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
 
-       pcr_clrsetbits32(dev, config_offset,
+       pcr_clrsetbits32(pinctrl, config_offset,
                         PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
-                                 PAD_CFG0_TX_DISABLE,
+                                 PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
                         PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
                                  (value ? PAD_CFG0_TX_STATE : 0));
 
@@ -59,9 +59,9 @@ static int intel_gpio_get_value(struct udevice *dev, uint offset)
        if (!mode) {
                rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
                if (rx_tx == PAD_CFG0_TX_DISABLE)
-                       return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0;
+                       return reg & PAD_CFG0_RX_STATE ? 1 : 0;
                else if (rx_tx == PAD_CFG0_RX_DISABLE)
-                       return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0;
+                       return reg & PAD_CFG0_TX_STATE ? 1 : 0;
        }
 
        return 0;
@@ -72,7 +72,7 @@ static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int value)
        struct udevice *pinctrl = dev_get_parent(dev);
        uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
 
-       pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE,
+       pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
                         value ? PAD_CFG0_TX_STATE : 0);
 
        return 0;
index 07a3356b3c8713c003212d0b0b719acfc53d473f..5c2944067bc15374519e7ec5f7c87a167460f27f 100644 (file)
@@ -15,8 +15,7 @@
  *
  * TODO:
  * 1. Support PCA957X_TYPE
- * 2. Support 24 gpio pins
- * 3. Support Polarity Inversion
+ * 2. Support Polarity Inversion
  */
 
 #include <common.h>
@@ -118,6 +117,10 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
                ret = dm_i2c_read(dev, reg, val, 1);
        } else if (info->gpio_count <= 16) {
                ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
+       } else if (info->gpio_count <= 24) {
+               /* Auto increment */
+               ret = dm_i2c_read(dev, (reg << 2) | 0x80, val,
+                                 info->bank_count);
        } else if (info->gpio_count == 40) {
                /* Auto increment */
                ret = dm_i2c_read(dev, (reg << 3) | 0x80, val,
@@ -139,6 +142,10 @@ static int pca953x_write_regs(struct udevice *dev, int reg, u8 *val)
                ret = dm_i2c_write(dev, reg, val, 1);
        } else if (info->gpio_count <= 16) {
                ret = dm_i2c_write(dev, reg << 1, val, info->bank_count);
+       } else if (info->gpio_count <= 24) {
+               /* Auto increment */
+               ret = dm_i2c_write(dev, (reg << 2) | 0x80, val,
+                                  info->bank_count);
        } else if (info->gpio_count == 40) {
                /* Auto increment */
                ret = dm_i2c_write(dev, (reg << 3) | 0x80, val, info->bank_count);
index 01d087f229f7310f9da0b2c557412b3ea13c65a5..4d1013c98466ad58c00077b177c7453aebffcac9 100644 (file)
@@ -136,6 +136,13 @@ config BCM6368_ETH
        help
          This driver supports the BCM6368 Ethernet MAC.
 
+config BCMGENET
+       bool "BCMGENET V5 support"
+       depends on DM_ETH
+       select PHYLIB
+       help
+         This driver supports the BCMGENET Ethernet MAC.
+
 config DWC_ETH_QOS
        bool "Synopsys DWC Ethernet QOS device support"
        depends on DM_ETH
index 30991834ecf61bb20836c0748dea9d3aaa36e266..6e0a68834d972850692789b14d490babcbd1debd 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_AG7XXX) += ag7xxx.o
 obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
 obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o
 obj-$(CONFIG_BCM6368_ETH) += bcm6368-eth.o
+obj-$(CONFIG_BCMGENET) += bcmgenet.o
 obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
 obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcmgenet.c b/drivers/net/bcmgenet.c
new file mode 100644 (file)
index 0000000..8f4848a
--- /dev/null
@@ -0,0 +1,729 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Amit Singh Tomar <amittomer25@gmail.com>
+ *
+ * Driver for Broadcom GENETv5 Ethernet controller (as found on the RPi4)
+ * This driver is based on the Linux driver:
+ *      drivers/net/ethernet/broadcom/genet/bcmgenet.c
+ *      which is: Copyright (c) 2014-2017 Broadcom
+ *
+ * The hardware supports multiple queues (16 priority queues and one
+ * default queue), both for RX and TX. There are 256 DMA descriptors (both
+ * for TX and RX), and they live in MMIO registers. The hardware allows
+ * assigning descriptor ranges to queues, but we choose the most simple setup:
+ * All 256 descriptors are assigned to the default queue (#16).
+ * Also the Linux driver supports multiple generations of the MAC, whereas
+ * we only support v5, as used in the Raspberry Pi 4.
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <linux/err.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <net.h>
+#include <dm/of_access.h>
+#include <dm/ofnode.h>
+#include <linux/iopoll.h>
+#include <linux/sizes.h>
+#include <asm/dma-mapping.h>
+#include <wait_bit.h>
+
+/* Register definitions derived from Linux source */
+#define SYS_REV_CTRL                   0x00
+
+#define SYS_PORT_CTRL                  0x04
+#define PORT_MODE_EXT_GPHY             3
+
+#define GENET_SYS_OFF                  0x0000
+#define SYS_RBUF_FLUSH_CTRL            (GENET_SYS_OFF  + 0x08)
+#define SYS_TBUF_FLUSH_CTRL            (GENET_SYS_OFF  + 0x0c)
+
+#define GENET_EXT_OFF                  0x0080
+#define EXT_RGMII_OOB_CTRL             (GENET_EXT_OFF + 0x0c)
+#define RGMII_LINK                     BIT(4)
+#define OOB_DISABLE                    BIT(5)
+#define RGMII_MODE_EN                  BIT(6)
+#define ID_MODE_DIS                    BIT(16)
+
+#define GENET_RBUF_OFF                 0x0300
+#define RBUF_TBUF_SIZE_CTRL            (GENET_RBUF_OFF + 0xb4)
+#define RBUF_CTRL                      (GENET_RBUF_OFF + 0x00)
+#define RBUF_ALIGN_2B                  BIT(1)
+
+#define GENET_UMAC_OFF                 0x0800
+#define UMAC_MIB_CTRL                  (GENET_UMAC_OFF + 0x580)
+#define UMAC_MAX_FRAME_LEN             (GENET_UMAC_OFF + 0x014)
+#define UMAC_MAC0                      (GENET_UMAC_OFF + 0x00c)
+#define UMAC_MAC1                      (GENET_UMAC_OFF + 0x010)
+#define UMAC_CMD                       (GENET_UMAC_OFF + 0x008)
+#define MDIO_CMD                       (GENET_UMAC_OFF + 0x614)
+#define UMAC_TX_FLUSH                  (GENET_UMAC_OFF + 0x334)
+#define MDIO_START_BUSY                        BIT(29)
+#define MDIO_READ_FAIL                 BIT(28)
+#define MDIO_RD                                (2 << 26)
+#define MDIO_WR                                BIT(26)
+#define MDIO_PMD_SHIFT                 21
+#define MDIO_PMD_MASK                  0x1f
+#define MDIO_REG_SHIFT                 16
+#define MDIO_REG_MASK                  0x1f
+
+#define CMD_TX_EN                      BIT(0)
+#define CMD_RX_EN                      BIT(1)
+#define UMAC_SPEED_10                  0
+#define UMAC_SPEED_100                 1
+#define UMAC_SPEED_1000                        2
+#define UMAC_SPEED_2500                        3
+#define CMD_SPEED_SHIFT                        2
+#define CMD_SPEED_MASK                 3
+#define CMD_SW_RESET                   BIT(13)
+#define CMD_LCL_LOOP_EN                        BIT(15)
+#define CMD_TX_EN                      BIT(0)
+#define CMD_RX_EN                      BIT(1)
+
+#define MIB_RESET_RX                   BIT(0)
+#define MIB_RESET_RUNT                 BIT(1)
+#define MIB_RESET_TX                   BIT(2)
+
+/* total number of Buffer Descriptors, same for Rx/Tx */
+#define TOTAL_DESCS                    256
+#define RX_DESCS                       TOTAL_DESCS
+#define TX_DESCS                       TOTAL_DESCS
+
+#define DEFAULT_Q                      0x10
+
+/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
+ * 1536 is multiple of 256 bytes
+ */
+#define ENET_BRCM_TAG_LEN              6
+#define ENET_PAD                       8
+#define ENET_MAX_MTU_SIZE              (ETH_DATA_LEN + ETH_HLEN +       \
+                                        VLAN_HLEN + ENET_BRCM_TAG_LEN + \
+                                        ETH_FCS_LEN + ENET_PAD)
+
+/* Tx/Rx Dma Descriptor common bits */
+#define DMA_EN                         BIT(0)
+#define DMA_RING_BUF_EN_SHIFT          0x01
+#define DMA_RING_BUF_EN_MASK           0xffff
+#define DMA_BUFLENGTH_MASK             0x0fff
+#define DMA_BUFLENGTH_SHIFT            16
+#define DMA_RING_SIZE_SHIFT            16
+#define DMA_OWN                                0x8000
+#define DMA_EOP                                0x4000
+#define DMA_SOP                                0x2000
+#define DMA_WRAP                       0x1000
+#define DMA_MAX_BURST_LENGTH           0x8
+/* Tx specific DMA descriptor bits */
+#define DMA_TX_UNDERRUN                        0x0200
+#define DMA_TX_APPEND_CRC              0x0040
+#define DMA_TX_OW_CRC                  0x0020
+#define DMA_TX_DO_CSUM                 0x0010
+#define DMA_TX_QTAG_SHIFT              7
+
+/* DMA rings size */
+#define DMA_RING_SIZE                  0x40
+#define DMA_RINGS_SIZE                 (DMA_RING_SIZE * (DEFAULT_Q + 1))
+
+/* DMA descriptor */
+#define DMA_DESC_LENGTH_STATUS         0x00
+#define DMA_DESC_ADDRESS_LO            0x04
+#define DMA_DESC_ADDRESS_HI            0x08
+#define DMA_DESC_SIZE                  12
+
+#define GENET_RX_OFF                   0x2000
+#define GENET_RDMA_REG_OFF                                     \
+       (GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
+#define GENET_TX_OFF                   0x4000
+#define GENET_TDMA_REG_OFF                                     \
+       (GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
+
+#define DMA_FC_THRESH_HI               (RX_DESCS >> 4)
+#define DMA_FC_THRESH_LO               5
+#define DMA_FC_THRESH_VALUE            ((DMA_FC_THRESH_LO << 16) |     \
+                                         DMA_FC_THRESH_HI)
+
+#define DMA_XOFF_THRESHOLD_SHIFT       16
+
+#define TDMA_RING_REG_BASE                                     \
+       (GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
+#define TDMA_READ_PTR                  (TDMA_RING_REG_BASE + 0x00)
+#define TDMA_CONS_INDEX                        (TDMA_RING_REG_BASE + 0x08)
+#define TDMA_PROD_INDEX                        (TDMA_RING_REG_BASE + 0x0c)
+#define DMA_RING_BUF_SIZE              0x10
+#define DMA_START_ADDR                 0x14
+#define DMA_END_ADDR                   0x1c
+#define DMA_MBUF_DONE_THRESH           0x24
+#define TDMA_FLOW_PERIOD               (TDMA_RING_REG_BASE + 0x28)
+#define TDMA_WRITE_PTR                 (TDMA_RING_REG_BASE + 0x2c)
+
+#define RDMA_RING_REG_BASE                                     \
+       (GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
+#define RDMA_WRITE_PTR                 (RDMA_RING_REG_BASE + 0x00)
+#define RDMA_PROD_INDEX                        (RDMA_RING_REG_BASE + 0x08)
+#define RDMA_CONS_INDEX                        (RDMA_RING_REG_BASE + 0x0c)
+#define RDMA_XON_XOFF_THRESH           (RDMA_RING_REG_BASE + 0x28)
+#define RDMA_READ_PTR                  (RDMA_RING_REG_BASE + 0x2c)
+
+#define TDMA_REG_BASE                  (GENET_TDMA_REG_OFF + DMA_RINGS_SIZE)
+#define RDMA_REG_BASE                  (GENET_RDMA_REG_OFF + DMA_RINGS_SIZE)
+#define DMA_RING_CFG                   0x00
+#define DMA_CTRL                       0x04
+#define DMA_SCB_BURST_SIZE             0x0c
+
+#define RX_BUF_LENGTH                  2048
+#define RX_TOTAL_BUFSIZE               (RX_BUF_LENGTH * RX_DESCS)
+#define RX_BUF_OFFSET                  2
+
+struct bcmgenet_eth_priv {
+       char rxbuffer[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN);
+       void *mac_reg;
+       void *tx_desc_base;
+       void *rx_desc_base;
+       int tx_index;
+       int rx_index;
+       int c_index;
+       int phyaddr;
+       u32 interface;
+       u32 speed;
+       struct phy_device *phydev;
+       struct mii_dev *bus;
+};
+
+static void bcmgenet_umac_reset(struct bcmgenet_eth_priv *priv)
+{
+       u32 reg;
+
+       reg = readl(priv->mac_reg + SYS_RBUF_FLUSH_CTRL);
+       reg |= BIT(1);
+       writel(reg, (priv->mac_reg + SYS_RBUF_FLUSH_CTRL));
+       udelay(10);
+
+       reg &= ~BIT(1);
+       writel(reg, (priv->mac_reg + SYS_RBUF_FLUSH_CTRL));
+       udelay(10);
+
+       writel(0, (priv->mac_reg + SYS_RBUF_FLUSH_CTRL));
+       udelay(10);
+
+       writel(0, priv->mac_reg + UMAC_CMD);
+
+       writel(CMD_SW_RESET | CMD_LCL_LOOP_EN, priv->mac_reg + UMAC_CMD);
+       udelay(2);
+       writel(0, priv->mac_reg + UMAC_CMD);
+
+       /* clear tx/rx counter */
+       writel(MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT,
+              priv->mac_reg + UMAC_MIB_CTRL);
+       writel(0, priv->mac_reg + UMAC_MIB_CTRL);
+
+       writel(ENET_MAX_MTU_SIZE, priv->mac_reg + UMAC_MAX_FRAME_LEN);
+
+       /* init rx registers, enable ip header optimization */
+       reg = readl(priv->mac_reg + RBUF_CTRL);
+       reg |= RBUF_ALIGN_2B;
+       writel(reg, (priv->mac_reg + RBUF_CTRL));
+
+       writel(1, (priv->mac_reg + RBUF_TBUF_SIZE_CTRL));
+}
+
+static int bcmgenet_gmac_write_hwaddr(struct udevice *dev)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       uchar *addr = pdata->enetaddr;
+       u32 reg;
+
+       reg = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
+       writel_relaxed(reg, priv->mac_reg + UMAC_MAC0);
+
+       reg = addr[4] << 8 | addr[5];
+       writel_relaxed(reg, priv->mac_reg + UMAC_MAC1);
+
+       return 0;
+}
+
+static void bcmgenet_disable_dma(struct bcmgenet_eth_priv *priv)
+{
+       clrbits_32(priv->mac_reg + TDMA_REG_BASE + DMA_CTRL, DMA_EN);
+       clrbits_32(priv->mac_reg + RDMA_REG_BASE + DMA_CTRL, DMA_EN);
+
+       writel(1, priv->mac_reg + UMAC_TX_FLUSH);
+       udelay(10);
+       writel(0, priv->mac_reg + UMAC_TX_FLUSH);
+}
+
+static void bcmgenet_enable_dma(struct bcmgenet_eth_priv *priv)
+{
+       u32 dma_ctrl = (1 << (DEFAULT_Q + DMA_RING_BUF_EN_SHIFT)) | DMA_EN;
+
+       writel(dma_ctrl, priv->mac_reg + TDMA_REG_BASE + DMA_CTRL);
+
+       setbits_32(priv->mac_reg + RDMA_REG_BASE + DMA_CTRL, dma_ctrl);
+}
+
+static int bcmgenet_gmac_eth_send(struct udevice *dev, void *packet, int length)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       void *desc_base = priv->tx_desc_base + priv->tx_index * DMA_DESC_SIZE;
+       u32 len_stat = length << DMA_BUFLENGTH_SHIFT;
+       ulong packet_aligned = rounddown((ulong)packet, ARCH_DMA_MINALIGN);
+       u32 prod_index, cons;
+       u32 tries = 100;
+
+       prod_index = readl(priv->mac_reg + TDMA_PROD_INDEX);
+
+       /* There is actually no reason for the rounding here, but the ARMv7
+        * implementation of flush_dcache_range() checks for aligned
+        * boundaries of the flushed range.
+        * Adjust them here to pass that check and avoid misleading messages.
+        */
+       flush_dcache_range(packet_aligned,
+                          packet_aligned + roundup(length, ARCH_DMA_MINALIGN));
+
+       len_stat |= 0x3F << DMA_TX_QTAG_SHIFT;
+       len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP;
+
+       /* Set-up packet for transmission */
+       writel(lower_32_bits((ulong)packet), (desc_base + DMA_DESC_ADDRESS_LO));
+       writel(upper_32_bits((ulong)packet), (desc_base + DMA_DESC_ADDRESS_HI));
+       writel(len_stat, (desc_base + DMA_DESC_LENGTH_STATUS));
+
+       /* Increment index and start transmission */
+       if (++priv->tx_index >= TX_DESCS)
+               priv->tx_index = 0;
+
+       prod_index++;
+
+       /* Start Transmisson */
+       writel(prod_index, priv->mac_reg + TDMA_PROD_INDEX);
+
+       do {
+               cons = readl(priv->mac_reg + TDMA_CONS_INDEX);
+       } while ((cons & 0xffff) < prod_index && --tries);
+       if (!tries)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+/* Check whether all cache lines affected by an invalidate are within
+ * the buffer, to make sure we don't accidentally lose unrelated dirty
+ * data stored nearby.
+ * Alignment of the buffer start address will be checked in the implementation
+ * of invalidate_dcache_range().
+ */
+static void invalidate_dcache_check(unsigned long addr, size_t size,
+                                   size_t buffer_size)
+{
+       size_t inval_size = roundup(size, ARCH_DMA_MINALIGN);
+
+       if (unlikely(inval_size > buffer_size))
+               printf("WARNING: Cache invalidate area exceeds buffer size\n");
+
+       invalidate_dcache_range(addr, addr + inval_size);
+}
+
+static int bcmgenet_gmac_eth_recv(struct udevice *dev,
+                                 int flags, uchar **packetp)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       void *desc_base = priv->rx_desc_base + priv->rx_index * DMA_DESC_SIZE;
+       u32 prod_index = readl(priv->mac_reg + RDMA_PROD_INDEX);
+       u32 length, addr;
+
+       if (prod_index == priv->c_index)
+               return -EAGAIN;
+
+       length = readl(desc_base + DMA_DESC_LENGTH_STATUS);
+       length = (length >> DMA_BUFLENGTH_SHIFT) & DMA_BUFLENGTH_MASK;
+       addr = readl(desc_base + DMA_DESC_ADDRESS_LO);
+
+       invalidate_dcache_check(addr, length, RX_BUF_LENGTH);
+
+       /* To cater for the IP header alignment the hardware does.
+        * This would actually not be needed if we don't program
+        * RBUF_ALIGN_2B
+        */
+       *packetp = (uchar *)(ulong)addr + RX_BUF_OFFSET;
+
+       return length - RX_BUF_OFFSET;
+}
+
+static int bcmgenet_gmac_free_pkt(struct udevice *dev, uchar *packet,
+                                 int length)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+
+       /* Tell the MAC we have consumed that last receive buffer. */
+       priv->c_index = (priv->c_index + 1) & 0xFFFF;
+       writel(priv->c_index, priv->mac_reg + RDMA_CONS_INDEX);
+
+       /* Forward our descriptor pointer, wrapping around if needed. */
+       if (++priv->rx_index >= RX_DESCS)
+               priv->rx_index = 0;
+
+       return 0;
+}
+
+static void rx_descs_init(struct bcmgenet_eth_priv *priv)
+{
+       char *rxbuffs = &priv->rxbuffer[0];
+       u32 len_stat, i;
+       void *desc_base = priv->rx_desc_base;
+
+       priv->c_index = 0;
+
+       len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
+
+       for (i = 0; i < RX_DESCS; i++) {
+               writel(lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]),
+                      desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO);
+               writel(upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]),
+                      desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI);
+               writel(len_stat,
+                      desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS);
+       }
+}
+
+static void rx_ring_init(struct bcmgenet_eth_priv *priv)
+{
+       writel(DMA_MAX_BURST_LENGTH,
+              priv->mac_reg + RDMA_REG_BASE + DMA_SCB_BURST_SIZE);
+
+       writel(0x0, priv->mac_reg + RDMA_RING_REG_BASE + DMA_START_ADDR);
+       writel(0x0, priv->mac_reg + RDMA_READ_PTR);
+       writel(0x0, priv->mac_reg + RDMA_WRITE_PTR);
+       writel(RX_DESCS * DMA_DESC_SIZE / 4 - 1,
+              priv->mac_reg + RDMA_RING_REG_BASE + DMA_END_ADDR);
+
+       writel(0x0, priv->mac_reg + RDMA_PROD_INDEX);
+       writel(0x0, priv->mac_reg + RDMA_CONS_INDEX);
+       writel((RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH,
+              priv->mac_reg + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE);
+       writel(DMA_FC_THRESH_VALUE, priv->mac_reg + RDMA_XON_XOFF_THRESH);
+       writel(1 << DEFAULT_Q, priv->mac_reg + RDMA_REG_BASE + DMA_RING_CFG);
+}
+
+static void tx_ring_init(struct bcmgenet_eth_priv *priv)
+{
+       writel(DMA_MAX_BURST_LENGTH,
+              priv->mac_reg + TDMA_REG_BASE + DMA_SCB_BURST_SIZE);
+
+       writel(0x0, priv->mac_reg + TDMA_RING_REG_BASE + DMA_START_ADDR);
+       writel(0x0, priv->mac_reg + TDMA_READ_PTR);
+       writel(0x0, priv->mac_reg + TDMA_WRITE_PTR);
+       writel(TX_DESCS * DMA_DESC_SIZE / 4 - 1,
+              priv->mac_reg + TDMA_RING_REG_BASE + DMA_END_ADDR);
+       writel(0x0, priv->mac_reg + TDMA_PROD_INDEX);
+       writel(0x0, priv->mac_reg + TDMA_CONS_INDEX);
+       writel(0x1, priv->mac_reg + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH);
+       writel(0x0, priv->mac_reg + TDMA_FLOW_PERIOD);
+       writel((TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH,
+              priv->mac_reg + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE);
+
+       writel(1 << DEFAULT_Q, priv->mac_reg + TDMA_REG_BASE + DMA_RING_CFG);
+}
+
+static int bcmgenet_adjust_link(struct bcmgenet_eth_priv *priv)
+{
+       struct phy_device *phy_dev = priv->phydev;
+       u32 speed;
+
+       switch (phy_dev->speed) {
+       case SPEED_1000:
+               speed = UMAC_SPEED_1000;
+               break;
+       case SPEED_100:
+               speed = UMAC_SPEED_100;
+               break;
+       case SPEED_10:
+               speed = UMAC_SPEED_10;
+               break;
+       default:
+               printf("bcmgenet: Unsupported PHY speed: %d\n", phy_dev->speed);
+               return -EINVAL;
+       }
+
+       clrsetbits_32(priv->mac_reg + EXT_RGMII_OOB_CTRL, OOB_DISABLE,
+                       RGMII_LINK | RGMII_MODE_EN | ID_MODE_DIS);
+
+       writel(speed << CMD_SPEED_SHIFT, (priv->mac_reg + UMAC_CMD));
+
+       return 0;
+}
+
+static int bcmgenet_gmac_eth_start(struct udevice *dev)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       priv->tx_desc_base = priv->mac_reg + GENET_TX_OFF;
+       priv->rx_desc_base = priv->mac_reg + GENET_RX_OFF;
+       priv->tx_index = 0x0;
+       priv->rx_index = 0x0;
+
+       bcmgenet_umac_reset(priv);
+
+       bcmgenet_gmac_write_hwaddr(dev);
+
+       /* Disable RX/TX DMA and flush TX queues */
+       bcmgenet_disable_dma(priv);
+
+       rx_ring_init(priv);
+       rx_descs_init(priv);
+
+       tx_ring_init(priv);
+
+       /* Enable RX/TX DMA */
+       bcmgenet_enable_dma(priv);
+
+       /* read PHY properties over the wire from generic PHY set-up */
+       ret = phy_startup(priv->phydev);
+       if (ret) {
+               printf("bcmgenet: PHY startup failed: %d\n", ret);
+               return ret;
+       }
+
+       /* Update MAC registers based on PHY property */
+       ret = bcmgenet_adjust_link(priv);
+       if (ret) {
+               printf("bcmgenet: adjust PHY link failed: %d\n", ret);
+               return ret;
+       }
+
+       /* Enable Rx/Tx */
+       setbits_32(priv->mac_reg + UMAC_CMD, CMD_TX_EN | CMD_RX_EN);
+
+       return 0;
+}
+
+static int bcmgenet_phy_init(struct bcmgenet_eth_priv *priv, void *dev)
+{
+       struct phy_device *phydev;
+       int ret;
+
+       phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
+       if (!phydev)
+               return -ENODEV;
+
+       phydev->supported &= PHY_GBIT_FEATURES;
+       if (priv->speed) {
+               ret = phy_set_supported(priv->phydev, priv->speed);
+               if (ret)
+                       return ret;
+       }
+       phydev->advertising = phydev->supported;
+
+       phy_connect_dev(phydev, dev);
+
+       priv->phydev = phydev;
+       phy_config(priv->phydev);
+
+       return 0;
+}
+
+static void bcmgenet_mdio_start(struct bcmgenet_eth_priv *priv)
+{
+       setbits_32(priv->mac_reg + MDIO_CMD, MDIO_START_BUSY);
+}
+
+static int bcmgenet_mdio_write(struct mii_dev *bus, int addr, int devad,
+                              int reg, u16 value)
+{
+       struct udevice *dev = bus->priv;
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       u32 val;
+
+       /* Prepare the read operation */
+       val = MDIO_WR | (addr << MDIO_PMD_SHIFT) |
+               (reg << MDIO_REG_SHIFT) | (0xffff & value);
+       writel_relaxed(val,  priv->mac_reg + MDIO_CMD);
+
+       /* Start MDIO transaction */
+       bcmgenet_mdio_start(priv);
+
+       return wait_for_bit_32(priv->mac_reg + MDIO_CMD,
+                              MDIO_START_BUSY, false, 20, true);
+}
+
+static int bcmgenet_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+       struct udevice *dev = bus->priv;
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       u32 val;
+       int ret;
+
+       /* Prepare the read operation */
+       val = MDIO_RD | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
+       writel_relaxed(val, priv->mac_reg + MDIO_CMD);
+
+       /* Start MDIO transaction */
+       bcmgenet_mdio_start(priv);
+
+       ret = wait_for_bit_32(priv->mac_reg + MDIO_CMD,
+                             MDIO_START_BUSY, false, 20, true);
+       if (ret)
+               return ret;
+
+       val = readl_relaxed(priv->mac_reg + MDIO_CMD);
+
+       return val & 0xffff;
+}
+
+static int bcmgenet_mdio_init(const char *name, struct udevice *priv)
+{
+       struct mii_dev *bus = mdio_alloc();
+
+       if (!bus) {
+               debug("Failed to allocate MDIO bus\n");
+               return -ENOMEM;
+       }
+
+       bus->read = bcmgenet_mdio_read;
+       bus->write = bcmgenet_mdio_write;
+       snprintf(bus->name, sizeof(bus->name), name);
+       bus->priv = (void *)priv;
+
+       return mdio_register(bus);
+}
+
+/* We only support RGMII (as used on the RPi4). */
+static int bcmgenet_interface_set(struct bcmgenet_eth_priv *priv)
+{
+       phy_interface_t phy_mode = priv->interface;
+
+       switch (phy_mode) {
+       case PHY_INTERFACE_MODE_RGMII:
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+               writel(PORT_MODE_EXT_GPHY, priv->mac_reg + SYS_PORT_CTRL);
+               break;
+       default:
+               printf("unknown phy mode: %d\n", priv->interface);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int bcmgenet_eth_probe(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       ofnode mdio_node;
+       const char *name;
+       u32 reg;
+       int ret;
+       u8 major;
+
+       priv->mac_reg = map_physmem(pdata->iobase, SZ_64K, MAP_NOCACHE);
+       priv->interface = pdata->phy_interface;
+       priv->speed = pdata->max_speed;
+
+       /* Read GENET HW version */
+       reg = readl_relaxed(priv->mac_reg + SYS_REV_CTRL);
+       major = (reg >> 24) & 0x0f;
+       if (major != 6) {
+               if (major == 5)
+                       major = 4;
+               else if (major == 0)
+                       major = 1;
+
+               printf("Unsupported GENETv%d.%d\n", major, (reg >> 16) & 0x0f);
+               return -ENODEV;
+       }
+
+       ret = bcmgenet_interface_set(priv);
+       if (ret)
+               return ret;
+
+       writel(0, priv->mac_reg + SYS_RBUF_FLUSH_CTRL);
+       udelay(10);
+       /* disable MAC while updating its registers */
+       writel(0, priv->mac_reg + UMAC_CMD);
+       /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
+       writel(CMD_SW_RESET | CMD_LCL_LOOP_EN, priv->mac_reg + UMAC_CMD);
+
+       mdio_node = dev_read_first_subnode(dev);
+       name = ofnode_get_name(mdio_node);
+
+       ret = bcmgenet_mdio_init(name, dev);
+       if (ret)
+               return ret;
+
+       priv->bus = miiphy_get_dev_by_name(name);
+
+       return bcmgenet_phy_init(priv, dev);
+}
+
+static void bcmgenet_gmac_eth_stop(struct udevice *dev)
+{
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+
+       clrbits_32(priv->mac_reg + UMAC_CMD, CMD_TX_EN | CMD_RX_EN);
+
+       bcmgenet_disable_dma(priv);
+}
+
+static const struct eth_ops bcmgenet_gmac_eth_ops = {
+       .start                  = bcmgenet_gmac_eth_start,
+       .write_hwaddr           = bcmgenet_gmac_write_hwaddr,
+       .send                   = bcmgenet_gmac_eth_send,
+       .recv                   = bcmgenet_gmac_eth_recv,
+       .free_pkt               = bcmgenet_gmac_free_pkt,
+       .stop                   = bcmgenet_gmac_eth_stop,
+};
+
+static int bcmgenet_eth_ofdata_to_platdata(struct udevice *dev)
+{
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+       struct bcmgenet_eth_priv *priv = dev_get_priv(dev);
+       struct ofnode_phandle_args phy_node;
+       const char *phy_mode;
+       int ret;
+
+       pdata->iobase = dev_read_addr(dev);
+
+       /* Get phy mode from DT */
+       pdata->phy_interface = -1;
+       phy_mode = dev_read_string(dev, "phy-mode");
+       if (phy_mode)
+               pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+       if (pdata->phy_interface == -1) {
+               debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+               return -EINVAL;
+       }
+
+       ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+                                        &phy_node);
+       if (!ret) {
+               ofnode_read_s32(phy_node.node, "reg", &priv->phyaddr);
+               ofnode_read_s32(phy_node.node, "max-speed", &pdata->max_speed);
+       }
+
+       return 0;
+}
+
+/* The BCM2711 implementation has a limited burst length compared to a generic
+ * GENETv5 version, but we go with that shorter value (8) in both cases, for
+ * the sake of simplicity.
+ */
+static const struct udevice_id bcmgenet_eth_ids[] = {
+       {.compatible = "brcm,genet-v5"},
+       {.compatible = "brcm,bcm2711-genet-v5"},
+       {}
+};
+
+U_BOOT_DRIVER(eth_bcmgenet) = {
+       .name   = "eth_bcmgenet",
+       .id     = UCLASS_ETH,
+       .of_match = bcmgenet_eth_ids,
+       .ofdata_to_platdata = bcmgenet_eth_ofdata_to_platdata,
+       .probe  = bcmgenet_eth_probe,
+       .ops    = &bcmgenet_gmac_eth_ops,
+       .priv_auto_alloc_size = sizeof(struct bcmgenet_eth_priv),
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+       .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
index 4875a3b0b52eb22b7426adb09eabb82f21de19ed..5bf5d8b0e24abb4c4094828155f8b5543f8c1bc5 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/intel_pinctrl.h>
 #include <asm/intel_pinctrl_defs.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/itss.h>
+#include <asm/itss.h>
 #include <dm/device-internal.h>
 #include <dt-bindings/gpio/gpio.h>
 
index bd95f70b61c7768d2f9e086342a811d027a38d87..cd2e098883f7acc2bf67c4f4088f8a72e7807f12 100644 (file)
@@ -542,6 +542,17 @@ config BCM6345_SERIAL
        help
          Select this to enable UART on BCM6345 SoCs.
 
+config COREBOOT_SERIAL
+       bool "Coreboot UART support"
+       depends on DM_SERIAL
+       default y if SYS_COREBOOT
+       select SYS_NS16550
+       help
+         Select this to enable a ns16550-style UART where the platform data
+         comes from the coreboot 'sysinfo' tables. This allows U-Boot to have
+         a serial console on any platform without needing to change the
+         device tree, etc.
+
 config FSL_LINFLEXUART
        bool "Freescale Linflex UART support"
        depends on DM_SERIAL
@@ -601,6 +612,27 @@ config SYS_NS16550
          be used. It can be a constant or a function to get clock, eg,
          get_serial_clock().
 
+config NS16550_DYNAMIC
+       bool "Allow NS16550 to be configured at runtime"
+       default y if SYS_COREBOOT || SYS_SLIMBOOTLOADER
+       help
+         Enable this option to allow device-tree control of the driver.
+
+         Normally this driver is controlled by the following options:
+
+         CONFIG_SYS_NS16550_PORT_MAPPED - indicates that port I/O is used for
+            access. If not enabled, then the UART is memory-mapped.
+         CONFIG_SYS_NS16550_MEM32 - if memory-mapped, indicates that 32-bit
+            access should be used (instead of 8-bit)
+         CONFIG_SYS_NS16550_REG_SIZE - indicates register width and also
+            endianness. If positive, big-endian access is used. If negative,
+            little-endian is used.
+
+         It is not a good practice for a driver to be statically configured,
+         since it prevents the same driver being used for different types of
+         UARTs in a system. This option avoids this problem at the cost of a
+         slightly increased code size.
+
 config INTEL_MID_SERIAL
        bool "Intel MID platform UART support"
        depends on DM_SERIAL && OF_CONTROL
index 06ee30697deb0d5e486ba0f155a99327b7623ac5..76b1811510d138b075b722125cc2f11e86b7bcad 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
 obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
+obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
 obj-$(CONFIG_EFI_APP) += serial_efi.o
 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
 obj-$(CONFIG_MCFUART) += mcfuart.o
index 9851663dc54f8a301fb8bb075898473621cc8538..31f6cfe421c26e6e59b7301096a3525779b422dc 100644 (file)
@@ -93,19 +93,79 @@ static inline int serial_in_shift(void *addr, int shift)
 #define CONFIG_SYS_NS16550_CLK  0
 #endif
 
+/*
+ * Use this #ifdef for now since many platforms don't define in(), out(),
+ * out_le32(), etc. but we don't have #defines to indicate this.
+ *
+ * TODO(sjg@chromium.org): Add CONFIG options to indicate what I/O is available
+ * on a platform
+ */
+#ifdef CONFIG_NS16550_DYNAMIC
+static void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
+                              int value)
+{
+       if (plat->flags & NS16550_FLAG_IO) {
+               outb(value, addr);
+       } else if (plat->reg_width == 4) {
+               if (plat->flags & NS16550_FLAG_ENDIAN) {
+                       if (plat->flags & NS16550_FLAG_BE)
+                               out_be32(addr, value);
+                       else
+                               out_le32(addr, value);
+               } else {
+                       writel(value, addr);
+               }
+       } else if (plat->flags & NS16550_FLAG_BE) {
+               writeb(value, addr + (1 << plat->reg_shift) - 1);
+       } else {
+               writeb(value, addr);
+       }
+}
+
+static int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+       if (plat->flags & NS16550_FLAG_IO) {
+               return inb(addr);
+       } else if (plat->reg_width == 4) {
+               if (plat->flags & NS16550_FLAG_ENDIAN) {
+                       if (plat->flags & NS16550_FLAG_BE)
+                               return in_be32(addr);
+                       else
+                               return in_le32(addr);
+               } else {
+                       return readl(addr);
+               }
+       } else if (plat->flags & NS16550_FLAG_BE) {
+               return readb(addr + (1 << plat->reg_shift) - 1);
+       } else {
+               return readb(addr);
+       }
+}
+#else
+static inline void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
+                                     int value)
+{
+}
+
+static inline int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+       return 0;
+}
+
+#endif /* CONFIG_NS16550_DYNAMIC */
+
 static void ns16550_writeb(NS16550_t port, int offset, int value)
 {
        struct ns16550_platdata *plat = port->plat;
        unsigned char *addr;
 
        offset *= 1 << plat->reg_shift;
-       addr = (unsigned char *)plat->base + offset;
+       addr = (unsigned char *)plat->base + offset + plat->reg_offset;
 
-       /*
-        * As far as we know it doesn't make sense to support selection of
-        * these options at run-time, so use the existing CONFIG options.
-        */
-       serial_out_shift(addr + plat->reg_offset, plat->reg_shift, value);
+       if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+               serial_out_dynamic(plat, addr, value);
+       else
+               serial_out_shift(addr, plat->reg_shift, value);
 }
 
 static int ns16550_readb(NS16550_t port, int offset)
@@ -114,9 +174,12 @@ static int ns16550_readb(NS16550_t port, int offset)
        unsigned char *addr;
 
        offset *= 1 << plat->reg_shift;
-       addr = (unsigned char *)plat->base + offset;
+       addr = (unsigned char *)plat->base + offset + plat->reg_offset;
 
-       return serial_in_shift(addr + plat->reg_offset, plat->reg_shift);
+       if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+               return serial_in_dynamic(plat, addr);
+       else
+               return serial_in_shift(addr, plat->reg_shift);
 }
 
 static u32 ns16550_getfcr(NS16550_t port)
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644 (file)
index 0000000..ccab347
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UART support for U-Boot when launched from Coreboot
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/sysinfo.h>
+
+static int coreboot_ofdata_to_platdata(struct udevice *dev)
+{
+       struct ns16550_platdata *plat = dev_get_platdata(dev);
+       struct cb_serial *cb_info = lib_sysinfo.serial;
+
+       plat->base = cb_info->baseaddr;
+       plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0;
+       plat->reg_width = cb_info->regwidth;
+       plat->clock = cb_info->input_hertz;
+       plat->fcr = UART_FCR_DEFVAL;
+       plat->flags = 0;
+       if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED)
+               plat->flags |= NS16550_FLAG_IO;
+
+       return 0;
+}
+
+static const struct udevice_id coreboot_serial_ids[] = {
+       { .compatible = "coreboot-serial" },
+       { },
+};
+
+U_BOOT_DRIVER(coreboot_uart) = {
+       .name   = "coreboot_uart",
+       .id     = UCLASS_SERIAL,
+       .of_match       = coreboot_serial_ids,
+       .priv_auto_alloc_size = sizeof(struct NS16550),
+       .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+       .ofdata_to_platdata  = coreboot_ofdata_to_platdata,
+       .probe  = ns16550_serial_probe,
+       .ops    = &ns16550_serial_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
+};
index 133b25b72e48c0960eb7393e05365ba23c74922b..a9d7715a556a5356d4526f6f33148a0ca19bd5df 100644 (file)
@@ -562,16 +562,8 @@ static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
                return 0;  /* ignore */
        case SPINOR_OP_BE_4K:
                cycle = HSFSTS_CYCLE_4K_ERASE;
-               while (len) {
-                       uint xfer_len = 0x1000;
-
-                       ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
-                       if (ret)
-                               return ret;
-                       offset += xfer_len;
-                       len -= xfer_len;
-               }
-               return 0;
+               ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
+               return ret;
        default:
                debug("Unknown cycle %x\n", op->cmd.opcode);
                return -EINVAL;
index 35f4147840efe1a768405b12d0fd002ce779c0cd..49f342eb211f321520060083f5b5cf143e4acb22 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/gadget.h>
 
+#include <phys2bus.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 #include <asm/io.h>
@@ -1213,6 +1214,7 @@ static int dwc2_udc_otg_remove(struct udevice *dev)
 
 static const struct udevice_id dwc2_udc_otg_ids[] = {
        { .compatible = "snps,dwc2" },
+       { .compatible = "brcm,bcm2835-usb" },
        { .compatible = "st,stm32mp1-hsotg",
          .data = (ulong)dwc2_set_stm32mp1_hsotg_params },
        {},
index b68c2b2686cad798f58ea373bc5d0d26f7859f67..d4fbb75cc9bcb318ca9bcc05fd8afea17b652de0 100644 (file)
@@ -31,7 +31,7 @@ static inline void dwc2_udc_ep0_zlp(struct dwc2_udc *dev)
 {
        u32 ep_ctrl;
 
-       writel(usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->in_endp[EP0_CON].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(1), &reg->in_endp[EP0_CON].dieptsiz);
 
        ep_ctrl = readl(&reg->in_endp[EP0_CON].diepctl);
@@ -52,7 +52,7 @@ static void dwc2_udc_pre_setup(void)
 
        writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest),
               &reg->out_endp[EP0_CON].doeptsiz);
-       writel(usb_ctrl_dma_addr, &reg->out_endp[EP0_CON].doepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->out_endp[EP0_CON].doepdma);
 
        ep_ctrl = readl(&reg->out_endp[EP0_CON].doepctl);
        writel(ep_ctrl|DEPCTL_EPENA, &reg->out_endp[EP0_CON].doepctl);
@@ -78,7 +78,7 @@ static inline void dwc2_ep0_complete_out(void)
 
        writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest),
               &reg->out_endp[EP0_CON].doeptsiz);
-       writel(usb_ctrl_dma_addr, &reg->out_endp[EP0_CON].doepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->out_endp[EP0_CON].doepdma);
 
        ep_ctrl = readl(&reg->out_endp[EP0_CON].doepctl);
        writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK,
@@ -116,7 +116,7 @@ static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req)
                                (unsigned long) ep->dma_buf +
                                ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE));
 
-       writel((unsigned long) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
+       writel(phys_to_bus((unsigned long)ep->dma_buf), &reg->out_endp[ep_num].doepdma);
        writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
               &reg->out_endp[ep_num].doeptsiz);
        writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);
@@ -164,7 +164,7 @@ static int setdma_tx(struct dwc2_ep *ep, struct dwc2_request *req)
        while (readl(&reg->grstctl) & TX_FIFO_FLUSH)
                ;
 
-       writel((unsigned long) ep->dma_buf, &reg->in_endp[ep_num].diepdma);
+       writel(phys_to_bus((unsigned long)ep->dma_buf), &reg->in_endp[ep_num].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length),
               &reg->in_endp[ep_num].dieptsiz);
 
@@ -924,7 +924,7 @@ static int dwc2_udc_get_status(struct dwc2_udc *dev,
                           (unsigned long) usb_ctrl +
                           ROUND(sizeof(g_status), CONFIG_SYS_CACHELINE_SIZE));
 
-       writel(usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
+       writel(phys_to_bus(usb_ctrl_dma_addr), &reg->in_endp[EP0_CON].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(1) | DIEPT_SIZ_XFER_SIZE(2),
               &reg->in_endp[EP0_CON].dieptsiz);
 
index 284cfbb2a891b57825ce1b713ea44d887719d255..5199d914edd9d2d5e2c5036c3d649ef0662ea80c 100644 (file)
@@ -150,24 +150,24 @@ static int omap3_wdt_reset(struct udevice *dev)
 {
        struct omap3_wdt_priv *priv = dev_get_priv(dev);
 
-/*
- * Somebody just triggered watchdog reset and write to WTGR register
- * is in progress. It is resetting right now, no need to trigger it
- * again
- */
+       /*
       * Somebody just triggered watchdog reset and write to WTGR register
       * is in progress. It is resetting right now, no need to trigger it
       * again
       */
        if ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
                return 0;
 
        priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern);
        writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr);
-/*
- * Don't wait for posted write to complete, i.e. don't check
- * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
- * WTGR register outside of this func, and if entering it
- * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
- * was just triggered. This prevents us from wasting time in busy
- * polling of WDT_WWPS_PEND_WTGR bit.
- */
+       /*
       * Don't wait for posted write to complete, i.e. don't check
       * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to
       * WTGR register outside of this func, and if entering it
       * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset
       * was just triggered. This prevents us from wasting time in busy
       * polling of WDT_WWPS_PEND_WTGR bit.
       */
        return 0;
 }
 
@@ -175,7 +175,7 @@ static int omap3_wdt_stop(struct udevice *dev)
 {
        struct omap3_wdt_priv *priv = dev_get_priv(dev);
 
-/* disable watchdog */
+       /* disable watchdog */
        writel(0xAAAA, &priv->regs->wdtwspr);
        while (readl(&priv->regs->wdtwwps) != 0x0)
                ;
@@ -188,29 +188,29 @@ static int omap3_wdt_stop(struct udevice *dev)
 static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
        struct omap3_wdt_priv *priv = dev_get_priv(dev);
-       u32 pre_margin = GET_WLDR_VAL(timeout_ms);
-/*
- * Make sure the watchdog is disabled. This is unfortunately required
- * because writing to various registers with the watchdog running has no
* effect.
- */
+       u32 pre_margin = GET_WLDR_VAL(timeout_ms / 1000);
+       /*
       * Make sure the watchdog is disabled. This is unfortunately required
+        * because writing to various registers with the watchdog running has
       * no effect.
       */
        omap3_wdt_stop(dev);
 
-/* initialize prescaler */
+       /* initialize prescaler */
        while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
                ;
 
        writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &priv->regs->wdtwclr);
        while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR)
                ;
-/* just count up at 32 KHz */
+       /* just count up at 32 KHz */
        while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
                ;
 
        writel(pre_margin, &priv->regs->wdtwldr);
        while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR)
                ;
-/* Sequence to enable the watchdog */
+       /* Sequence to enable the watchdog */
        writel(0xBBBB, &priv->regs->wdtwspr);
        while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
                ;
@@ -219,6 +219,16 @@ static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
        while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR)
                ;
 
+       /* Trigger the watchdog to actually reload the counter. */
+       while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+               ;
+
+       priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern);
+       writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr);
+
+       while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+               ;
+
        return 0;
 }
 
index eaed520e6be0e1c6e6db893462e656e23051eb0e..4371c471e5a9f3c30cbbad578d9c8510c832ffe2 100644 (file)
@@ -23,6 +23,8 @@
 #ifdef CONFIG_TARGET_J721E_A72_EVM
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SPL_TEXT_BASE +        \
                                         CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
+/* Image load address in RAM for DFU boot*/
+#define CONFIG_SPL_LOAD_FIT_ADDRESS    0x81000000
 #else
 /*
  * Maximum size in memory allocated to the SPL BSS. Keep it as tight as
@@ -45,6 +47,8 @@
 /* Configure R5 SPL post-relocation malloc pool in DDR */
 #define CONFIG_SYS_SPL_MALLOC_START    0x84000000
 #define CONFIG_SYS_SPL_MALLOC_SIZE     SZ_16M
+/* Image load address in RAM for DFU boot*/
+#define CONFIG_SPL_LOAD_FIT_ADDRESS    0x80080000
 #endif
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
index 83e258a6b958b69ed423f3d8311ef51601ef7449..b53a4b65d0bf2dfa9114e4f5ede8932d310a0107 100644 (file)
 #define CONFIG_TFTP_TSIZE
 #endif
 
+/* DFU over USB/UDC */
+#ifdef CONFIG_CMD_DFU
+#define CONFIG_SYS_DFU_DATA_BUF_SIZE   SZ_1M
+#define CONFIG_SYS_DFU_MAX_FILE_SIZE   SZ_2M
+
+#ifdef CONFIG_ARM64
+#define KERNEL_FILENAME                "Image"
+#else
+#define KERNEL_FILENAME                "zImage"
+#endif
+
+#define ENV_DFU_SETTINGS \
+       "dfu_alt_info=u-boot.bin fat 0 1;uboot.env fat 0 1;" \
+                     "config.txt fat 0 1;" \
+                     KERNEL_FILENAME " fat 0 1\0"
+#else
+#define ENV_DFU_SETTINGS ""
+#endif
+
 /* Console configuration */
 #define CONFIG_SYS_CBSIZE              1024
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
        "dhcpuboot=usb start; dhcp u-boot.uimg; bootm\0" \
        ENV_DEVICE_SETTINGS \
+       ENV_DFU_SETTINGS \
        ENV_MEM_LAYOUT_SETTINGS \
        BOOTENV
 
index e0011ed4461bcbf12b860232d26dacbcba896797..b8169072cc86a2c10b978ab3d41a092047ef8038 100644 (file)
@@ -8,19 +8,6 @@
 
 #include <configs/x86-common.h>
 
-/*
- * By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial.
- * To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable
- * CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port
- * configuration in run-time.
- *
- * #define CONFIG_SYS_NS16550_MEM32
- * #undef CONFIG_SYS_NS16550_PORT_MAPPED
- */
-#ifdef CONFIG_SYS_NS16550_MEM32
-#undef CONFIG_SYS_NS16550_PORT_MAPPED
-#endif
-
 #define CONFIG_STD_DEVICES_SETTINGS            \
        "stdin=serial,i8042-kbd,usbkbd\0"       \
        "stdout=serial\0"                       \
index a1a053e67500efc26749855d0496c7ae3fcbf640..a612bb5b4a8e99b8c7b861078019ff6779de0057 100644 (file)
  * seen large trees).  We say all of this must be within the first 256MB
  * as that will normally be within the kernel lowmem and thus visible via
  * bootm_size and we only run on platforms with 256MB or more of memory.
+ *
+ * As a temporary storage for DTBO blobs (which should be applied into DTB
+ * blob), we use the location 15.5 MB above the ramdisk. If someone wants to
+ * use ramdisk bigger than 15.5 MB, then DTBO can be loaded and applied to DTB
+ * blob before loading the ramdisk, as DTBO location is only used as a temporary
+ * storage, and can be re-used after 'fdt apply' command is done.
  */
 #define DEFAULT_LINUX_BOOT_ENV \
        "loadaddr=0x82000000\0" \
        "kernel_addr_r=0x82000000\0" \
        "fdtaddr=0x88000000\0" \
+       "dtboaddr=0x89000000\0" \
        "fdt_addr_r=0x88000000\0" \
        "rdaddr=0x88080000\0" \
        "ramdisk_addr_r=0x88080000\0" \
index 6313f3e328a07fd91b075dbb478b929522110738..523c8fc4fe9a80ce1fd87909e6697893ce2930d9 100644 (file)
 #define CONSOLEDEV "ttyS2"
 #endif
 
-#define VBMETA_PART_SIZE               (64 * 1024)
-
-#if defined(CONFIG_LIBAVB)
-#define VBMETA_PART \
-       "name=vbmeta,size=" __stringify(VBMETA_PART_SIZE) \
-       ",uuid=${uuid_gpt_vbmeta};"
-#else
-#define VBMETA_PART                    ""
-#endif
-
-#if defined(CONFIG_CMD_AB_SELECT)
-#define COMMON_PARTS \
-       "name=boot_a,size=20M,uuid=${uuid_gpt_boot_a};" \
-       "name=boot_b,size=20M,uuid=${uuid_gpt_boot_b};" \
-       "name=system_a,size=1024M,uuid=${uuid_gpt_system_a};" \
-       "name=system_b,size=1024M,uuid=${uuid_gpt_system_b};"
-#else
-#define COMMON_PARTS \
-       "name=boot,size=20M,uuid=${uuid_gpt_boot};" \
-       "name=system,size=1024M,uuid=${uuid_gpt_system};"
-#endif
-
 #ifndef PARTS_DEFAULT
-/* Define the default GPT table for eMMC */
+/*
+ * Default GPT tables for eMMC (Linux and Android). Notes:
+ *   1. Keep partitions aligned to erase group size (512 KiB) when possible
+ *   2. Keep partitions in sync with DFU_ALT_INFO_EMMC (see dfu.h)
+ *   3. Keep 'bootloader' partition (U-Boot proper) start address in sync with
+ *      CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR (see common/spl/Kconfig)
+ */
 #define PARTS_DEFAULT \
        /* Linux partitions */ \
        "uuid_disk=${uuid_gpt_disk};" \
        "name=bootloader,size=2048K,uuid=${uuid_gpt_bootloader};" \
        "name=uboot-env,start=2432K,size=256K,uuid=${uuid_gpt_reserved};" \
        "name=misc,size=128K,uuid=${uuid_gpt_misc};" \
-       "name=recovery,size=40M,uuid=${uuid_gpt_recovery};" \
-       COMMON_PARTS \
-       "name=vendor,size=256M,uuid=${uuid_gpt_vendor};" \
-       VBMETA_PART \
+       "name=boot_a,size=20M,uuid=${uuid_gpt_boot_a};" \
+       "name=boot_b,size=20M,uuid=${uuid_gpt_boot_b};" \
+       "name=dtbo_a,size=8M,uuid=${uuid_gpt_dtbo_a};" \
+       "name=dtbo_b,size=8M,uuid=${uuid_gpt_dtbo_b};" \
+       "name=vbmeta_a,size=64K,uuid=${uuid_gpt_vbmeta_a};" \
+       "name=vbmeta_b,size=64K,uuid=${uuid_gpt_vbmeta_b};" \
+       "name=recovery,size=64M,uuid=${uuid_gpt_recovery};" \
+       "name=super,size=2560M,uuid=${uuid_gpt_super};" \
+       "name=metadata,size=16M,uuid=${uuid_gpt_metadata};" \
        "name=userdata,size=-,uuid=${uuid_gpt_userdata}"
 #endif /* PARTS_DEFAULT */
 
@@ -63,7 +52,7 @@
                        "else " \
                                "echo AVB verification failed.;" \
                        "exit; fi;"
-#define AVB_VERIFY_CMD "avb_verify=avb init 1; avb verify;\0"
+#define AVB_VERIFY_CMD "avb_verify=avb init 1; avb verify $slot_suffix;\0"
 #else
 #define AVB_VERIFY_CHECK ""
 #define AVB_VERIFY_CMD ""
@@ -72,7 +61,7 @@
 #define CONTROL_PARTITION "misc"
 
 #if defined(CONFIG_CMD_AB_SELECT)
-#define AB_SELECT \
+#define AB_SELECT_SLOT \
        "if part number mmc 1 " CONTROL_PARTITION " control_part_number; " \
        "then " \
                "echo " CONTROL_PARTITION \
                "echo " CONTROL_PARTITION " partition not found;" \
                "exit;" \
        "fi;" \
-       "setenv slot_suffix _${slot_name};" \
-       "if part number mmc ${mmcdev} system${slot_suffix} " \
-       "system_part_number; then " \
-               "setenv bootargs_ab " \
-               "ro root=/dev/mmcblk${mmcdev}p${system_part_number} " \
-               "rootwait init=/init skip_initramfs " \
-               "androidboot.slot_suffix=${slot_suffix};" \
-               "echo A/B cmdline addition: ${bootargs_ab};" \
-               "setenv bootargs ${bootargs} ${bootargs_ab};" \
-       "else " \
-               "echo system${slot_suffix} partition not found;" \
-       "fi;"
+       "setenv slot_suffix _${slot_name};"
+#define AB_SELECT_ARGS \
+       "setenv bootargs_ab androidboot.slot_suffix=${slot_suffix}; " \
+       "echo A/B cmdline addition: ${bootargs_ab};" \
+       "setenv bootargs ${bootargs} ${bootargs_ab};"
 #else
-#define AB_SELECT ""
+#define AB_SELECT_SLOT ""
+#define AB_SELECT_ARGS ""
 #endif
 
+/*
+ * Prepares complete device tree blob for current board (for Android boot).
+ *
+ * Boot image or recovery image should be loaded into $loadaddr prior to running
+ * these commands. The logic of these commnads is next:
+ *
+ *   1. Read correct DTB for current SoC/board from boot image in $loadaddr
+ *      to $fdtaddr
+ *   2. Merge all needed DTBO for current board from 'dtbo' partition into read
+ *      DTB
+ *   3. User should provide $fdtaddr as 3rd argument to 'bootm'
+ */
+#define PREPARE_FDT \
+       "echo Preparing FDT...; " \
+       "if test $board_name = am57xx_evm_reva3; then " \
+               "echo \"  Reading DTBO partition...\"; " \
+               "part start mmc ${mmcdev} dtbo${slot_suffix} p_dtbo_start; " \
+               "part size mmc ${mmcdev} dtbo${slot_suffix} p_dtbo_size; " \
+               "mmc read ${dtboaddr} ${p_dtbo_start} ${p_dtbo_size}; " \
+               "echo \"  Reading DTB for AM57x EVM RevA3...\"; " \
+               "abootimg get dtb --index=0 dtb_start dtb_size; " \
+               "cp.b $dtb_start $fdtaddr $dtb_size; " \
+               "fdt addr $fdtaddr; " \
+               "echo \"  Applying DTBOs for AM57x EVM RevA3...\"; " \
+               "adtimg addr $dtboaddr; " \
+               "adtimg get dt --index=0 dtbo0_addr; " \
+               "fdt apply $dtbo0_addr; " \
+               "adtimg get dt --index=1 dtbo1_addr; " \
+               "fdt apply $dtbo1_addr; " \
+       "elif test $board_name = beagle_x15_revc; then " \
+               "echo \"  Reading DTB for Beagle X15 RevC...\"; " \
+               "abootimg get dtb --index=0 dtb_start dtb_size; " \
+               "cp.b $dtb_start $fdtaddr $dtb_size; " \
+               "fdt addr $fdtaddr; " \
+       "else " \
+               "echo Error: Android boot is not supported for $board_name; " \
+               "exit; " \
+       "fi; " \
+
 #define FASTBOOT_CMD \
        "echo Booting into fastboot ...; " \
        "fastboot " __stringify(CONFIG_FASTBOOT_USB_DEV) "; "
                "setenv mmcroot /dev/mmcblk0p2 rw; " \
                "run mmcboot;\0" \
        "emmc_android_boot=" \
+               "setenv mmcdev 1; " \
+               "mmc dev $mmcdev; " \
+               "mmc rescan; " \
+               AB_SELECT_SLOT \
                "if bcb load " __stringify(CONFIG_FASTBOOT_FLASH_MMC_DEV) " " \
                CONTROL_PARTITION "; then " \
+                       "setenv ardaddr -; " \
                        "if bcb test command = bootonce-bootloader; then " \
-                               "echo BCB: Bootloader boot...; " \
+                               "echo Android: Bootloader boot...; " \
                                "bcb clear command; bcb store; " \
                                FASTBOOT_CMD \
+                               "exit; " \
                        "elif bcb test command = boot-recovery; then " \
-                               "echo BCB: Recovery boot...; " \
-                               "echo Warning: recovery is not implemented; " \
-                               "echo Performing normal boot for now...; " \
-                               "bcb clear command; bcb store; " \
-                               "run emmc_android_normal_boot; " \
+                               "echo Android: Recovery boot...; " \
+                               "setenv ardaddr $loadaddr;" \
+                               "setenv apart recovery; " \
                        "else " \
-                               "echo BCB: Normal boot requested...; " \
-                               "run emmc_android_normal_boot; " \
+                               "echo Android: Normal boot...; " \
+                               "setenv ardaddr $loadaddr; " \
+                               "setenv apart boot${slot_suffix}; " \
                        "fi; " \
                "else " \
                        "echo Warning: BCB is corrupted or does not exist; " \
-                       "echo Performing normal boot...; " \
-                       "run emmc_android_normal_boot; " \
-               "fi;\0" \
-       "emmc_android_normal_boot=" \
-               "echo Trying to boot Android from eMMC ...; " \
-               "run update_to_fit; " \
+                       "echo Android: Normal boot...; " \
+               "fi; " \
                "setenv eval_bootargs setenv bootargs $bootargs; " \
                "run eval_bootargs; " \
-               "setenv mmcdev 1; " \
                "setenv machid fe6; " \
-               "mmc dev $mmcdev; " \
-               "mmc rescan; " \
                AVB_VERIFY_CHECK \
-               AB_SELECT \
-               "if part start mmc ${mmcdev} boot${slot_suffix} boot_start; " \
-               "then " \
-                       "part size mmc ${mmcdev} boot${slot_suffix} " \
-                               "boot_size; " \
-                       "mmc read ${loadaddr} ${boot_start} ${boot_size}; " \
-                       "bootm ${loadaddr}#${fdtfile}; " \
+               AB_SELECT_ARGS \
+               "if part start mmc $mmcdev $apart boot_start; then " \
+                       "part size mmc $mmcdev $apart boot_size; " \
+                       "mmc read $loadaddr $boot_start $boot_size; " \
+                       PREPARE_FDT \
+                       "bootm $loadaddr $ardaddr $fdtaddr; " \
                "else " \
-                       "echo boot${slot_suffix} partition not found; " \
+                       "echo $apart partition not found; " \
+                       "exit; " \
                "fi;\0"
 
 #ifdef CONFIG_OMAP54XX
index 9c6b6d6054b9964c2153aaa5b5ebb6151ce004bf..b316d167d8d7f50be9f1b7f2b291ad05306c9338 100644 (file)
@@ -1425,10 +1425,16 @@ int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
                              ulong *rd_data, ulong *rd_len);
 int android_image_get_second(const struct andr_img_hdr *hdr,
                              ulong *second_data, ulong *second_len);
+bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size);
+bool android_image_get_dtb_by_index(ulong hdr_addr, u32 index, ulong *addr,
+                                   u32 *size);
 ulong android_image_get_end(const struct andr_img_hdr *hdr);
 ulong android_image_get_kload(const struct andr_img_hdr *hdr);
 ulong android_image_get_kcomp(const struct andr_img_hdr *hdr);
 void android_print_contents(const struct andr_img_hdr *hdr);
+#if !defined(CONFIG_SPL_BUILD)
+bool android_image_print_dtb_contents(ulong hdr_addr);
+#endif
 
 #endif /* CONFIG_ANDROID_BOOT_IMAGE */
 
index 701efeea855f3eb5d2564d85cf796bbb1279bfc0..18c9077755bef823f388c8219d0bdc3de8fd86ee 100644 (file)
@@ -31,6 +31,9 @@
 #define CONFIG_SYS_NS16550_REG_SIZE (-1)
 #endif
 
+#ifdef CONFIG_NS16550_DYNAMIC
+#define UART_REG(x)    unsigned char x
+#else
 #if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
 #error "Please define NS16550 registers size."
 #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_DM_SERIAL)
        unsigned char x;                                                \
        unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
 #endif
+#endif /* CONFIG_NS16550_DYNAMIC */
+
+enum ns16550_flags {
+       NS16550_FLAG_IO         = 1 << 0, /* Use I/O access (else mem-mapped) */
+       NS16550_FLAG_ENDIAN     = 1 << 1, /* Use out_le/be_32() */
+       NS16550_FLAG_BE         = 1 << 2, /* Big-endian access (else little) */
+};
 
 /**
  * struct ns16550_platdata - information about a NS16550 port
  *
  * @base:              Base register address
- * @reg_width:         IO accesses size of registers (in bytes)
+ * @reg_width:         IO accesses size of registers (in bytes, 1 or 4)
  * @reg_shift:         Shift size of registers (0=byte, 1=16bit, 2=32bit...)
+ * @reg_offset:                Offset to start of registers (normally 0)
  * @clock:             UART base clock speed in Hz
+ * @fcr:               Offset of FCR register (normally UART_FCR_DEFVAL)
+ * @flags:             A few flags (enum ns16550_flags)
  * @bdf:               PCI slot/function (pci_dev_t)
  */
 struct ns16550_platdata {
@@ -61,6 +74,7 @@ struct ns16550_platdata {
        int reg_offset;
        int clock;
        u32 fcr;
+       int flags;
 #if defined(CONFIG_PCI) && defined(CONFIG_SPL)
        int bdf;
 #endif
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py
new file mode 100644 (file)
index 0000000..43a7099
--- /dev/null
@@ -0,0 +1,159 @@
+# SPDX-License-Identifier:  GPL-2.0+
+# Copyright (c) 2020
+# Author: Sam Protsenko <joe.skb7@gmail.com>
+
+# Test U-Boot's "abootimg" commands.
+
+import os
+import pytest
+import u_boot_utils
+
+"""
+These tests rely on disk image (boot.img), which is automatically created by
+the test from the stored hex dump. This is done to avoid the dependency on the
+most recent mkbootimg tool from AOSP/master. Here is the list of commands which
+was used to generate the boot.img and obtain compressed hex dump from it:
+
+    $ echo '/dts-v1/; / { model = "x1"; compatible = "y1,z1"; };' > test1.dts
+    $ echo '/dts-v1/; / { model = "x2"; compatible = "y2,z2"; };' > test2.dts
+    $ dtc test1.dts > dt1.dtb
+    $ dtc test2.dts > dt2.dtb
+    $ cat dt1.dtb dt2.dtb > dtb.img
+    $ echo 'kernel payload' > kernel
+    $ echo 'ramdisk payload' > ramdisk.img
+    $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img  \
+                --cmdline "cmdline test" --dtb ./dtb.img   \
+                --os_version R --os_patch_level 2019-06-05 \
+                --header_version 2 --output boot.img
+    $ gzip -9 boot.img
+    $ xxd -p boot.img.gz > boot.img.gz.hex
+
+Now one can obtain original boot.img from this hex dump like this:
+
+    $ xxd -r -p boot.img.gz.hex boot.img.gz
+    $ gunzip -9 boot.img.gz
+"""
+
+# boot.img.gz hex dump
+img_hex = """1f8b08084844af5d0203626f6f742e696d670073f47309f2f77451e46700
+820606010106301084501f04181819041838181898803c3346060c909c9b
+92939997aa50925a5cc2300a461c3078b2e1793c4b876fd92db97939fb6c
+b7762ffff07d345446c1281805e8a0868d81e117a45e111c0d8dc101b253
+8bf25273140a122b73f21353b8460364148c8251300a46c1281801a02831
+3725b3387bb401300a46c1281805a360148c207081f7df5b20550bc41640
+9c03c41a0c90f17fe85400986d82452b6c3680198a192a0ce17c3610ae34
+d4a9820881a70f3873f35352731892f3730b124b32937252a96bb9119ae5
+463a5546f82c1f05a360148c8251300a462e000085bf67f200200000"""
+# Expected response for "abootimg dtb_dump" command
+dtb_dump_resp="""## DTB area contents (concat format):
+ - DTB #0:
+           (DTB)size = 125
+          (DTB)model = x1
+     (DTB)compatible = y1,z1
+ - DTB #1:
+           (DTB)size = 125
+          (DTB)model = x2
+     (DTB)compatible = y2,z2"""
+# Address in RAM where to load the boot image ('abootimg' looks in $loadaddr)
+loadaddr = 0x1000
+# Expected DTB #1 offset from the boot image start address
+dtb1_offset = 0x187d
+# DTB #1 start address in RAM
+dtb1_addr = loadaddr + dtb1_offset
+
+class AbootimgTestDiskImage(object):
+    """Disk image used by abootimg tests."""
+
+    def __init__(self, u_boot_console):
+        """Initialize a new AbootimgDiskImage object.
+
+        Args:
+            u_boot_console: A U-Boot console.
+
+        Returns:
+            Nothing.
+        """
+
+        gz_hex = u_boot_console.config.persistent_data_dir + '/boot.img.gz.hex'
+        gz = u_boot_console.config.persistent_data_dir + '/boot.img.gz'
+
+        filename = 'boot.img'
+        persistent = u_boot_console.config.persistent_data_dir + '/' + filename
+        self.path = u_boot_console.config.result_dir  + '/' + filename
+
+        with u_boot_utils.persistent_file_helper(u_boot_console.log, persistent):
+            if os.path.exists(persistent):
+                u_boot_console.log.action('Disk image file ' + persistent +
+                    ' already exists')
+            else:
+                u_boot_console.log.action('Generating ' + persistent)
+
+                f = open(gz_hex, "w")
+                f.write(img_hex)
+                f.close()
+
+                cmd = ('xxd', '-r', '-p', gz_hex, gz)
+                u_boot_utils.run_and_log(u_boot_console, cmd)
+
+                cmd = ('gunzip', '-9', gz)
+                u_boot_utils.run_and_log(u_boot_console, cmd)
+
+        cmd = ('cp', persistent, self.path)
+        u_boot_utils.run_and_log(u_boot_console, cmd)
+
+gtdi = None
+@pytest.fixture(scope='function')
+def abootimg_disk_image(u_boot_console):
+    """pytest fixture to provide a AbootimgTestDiskImage object to tests.
+    This is function-scoped because it uses u_boot_console, which is also
+    function-scoped. However, we don't need to actually do any function-scope
+    work, so this simply returns the same object over and over each time."""
+
+    global gtdi
+    if not gtdi:
+        gtdi = AbootimgTestDiskImage(u_boot_console)
+    return gtdi
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('android_boot_image')
+@pytest.mark.buildconfigspec('cmd_abootimg')
+@pytest.mark.buildconfigspec('cmd_fdt')
+@pytest.mark.requiredtool('xxd')
+@pytest.mark.requiredtool('gunzip')
+def test_abootimg(abootimg_disk_image, u_boot_console):
+    """Test the 'abootimg' command."""
+
+    u_boot_console.log.action('Loading disk image to RAM...')
+    u_boot_console.run_command('setenv loadaddr 0x%x' % (loadaddr))
+    u_boot_console.run_command('host load hostfs - 0x%x %s' % (loadaddr,
+        abootimg_disk_image.path))
+
+    u_boot_console.log.action('Testing \'abootimg get ver\'...')
+    response = u_boot_console.run_command('abootimg get ver')
+    assert response == "2"
+    u_boot_console.run_command('abootimg get ver v')
+    response = u_boot_console.run_command('env print v')
+    assert response == 'v=2'
+
+    u_boot_console.log.action('Testing \'abootimg get recovery_dtbo\'...')
+    response = u_boot_console.run_command('abootimg get recovery_dtbo a')
+    assert response == 'Error: recovery_dtbo_size is 0'
+
+    u_boot_console.log.action('Testing \'abootimg dump dtb\'...')
+    response = u_boot_console.run_command('abootimg dump dtb').replace('\r', '')
+    assert response == dtb_dump_resp
+
+    u_boot_console.log.action('Testing \'abootimg get dtb_load_addr\'...')
+    u_boot_console.run_command('abootimg get dtb_load_addr a')
+    response = u_boot_console.run_command('env print a')
+    assert response == 'a=11f00000'
+
+    u_boot_console.log.action('Testing \'abootimg get dtb --index\'...')
+    u_boot_console.run_command('abootimg get dtb --index=1 dtb1_start')
+    response = u_boot_console.run_command('env print dtb1_start')
+    correct_str = "dtb1_start=%x" % (dtb1_addr)
+    assert response == correct_str
+    u_boot_console.run_command('fdt addr $dtb1_start')
+    u_boot_console.run_command('fdt get value v / model')
+    response = u_boot_console.run_command('env print v')
+    assert response == 'v=x2'
index 20ccaf6712f2008282a35c8524f3a370b83409d7..a04a7ff264cad938c23823afd65d4a07019a0497 100644 (file)
@@ -8,7 +8,7 @@
 This tests Android Verified Boot 2.0 support in U-boot:
 
 For additional details about how to build proper vbmeta partition
-check doc/android/avb2.txt
+check doc/android/avb2.rst
 
 For configuration verification:
 - Corrupt boot partition and check for failure