Merge tag 'signed-rpi-next' of git://github.com/agraf/u-boot
authorTom Rini <trini@konsulko.com>
Mon, 3 Dec 2018 22:52:53 +0000 (17:52 -0500)
committerTom Rini <trini@konsulko.com>
Mon, 3 Dec 2018 22:52:53 +0000 (17:52 -0500)
Patch queue for rpi - 2018-12-03

A few Raspberry Pi specific changes this time:

  - Allow 2nd MMC device
  - Support RPi 3 Model A+
  - Allow UUID to find filesystem

142 files changed:
Kconfig
MAINTAINERS
arch/arc/include/asm/arcregs.h
arch/arc/lib/cpu.c
arch/arm/cpu/armv7/smccc-call.S
arch/arm/cpu/armv8/Kconfig
arch/arm/cpu/armv8/fwcall.c
arch/arm/cpu/armv8/smccc-call.S
arch/arm/dts/am335x-baltos.dts [new file with mode: 0644]
arch/arm/dts/meson-gx.dtsi
arch/arm/dts/meson-gxbb-nanopi-k2.dts
arch/arm/dts/meson-gxbb.dtsi
arch/arm/dts/meson-gxl-mali.dtsi
arch/arm/dts/meson-gxl-s905x-libretech-cc.dts
arch/arm/dts/meson-gxl-s905x-p212.dtsi
arch/arm/dts/meson-gxl.dtsi
arch/arm/dts/meson-gxm-khadas-vim2.dts
arch/arm/dts/r8a77990-ebisu.dts
arch/arm/dts/salvator-common.dtsi
arch/arm/dts/ulcb.dtsi
arch/arm/lib/crt0_aarch64_efi.S
arch/arm/lib/crt0_arm_efi.S
arch/powerpc/cpu/mpc8xx/start.S
arch/powerpc/dts/Makefile
arch/powerpc/dts/mcr3000.dts [new file with mode: 0644]
arch/riscv/lib/crt0_riscv_efi.S
arch/x86/config.mk
board/cssi/MCR3000/MCR3000.c
board/cssi/MCR3000/u-boot.lds
board/synopsys/axs10x/axs10x.c
board/synopsys/emsdp/emsdp.c
board/synopsys/hsdk/hsdk.c
board/synopsys/iot_devkit/iot_devkit.c
board/vscom/baltos/board.c
board/vscom/baltos/mux.c
cmd/bootefi.c
cmd/eeprom.c
common/board_r.c
common/fdt_support.c
common/image-fit.c
common/image-sig.c
configs/MCR3000_defconfig
configs/am335x_baltos_defconfig
configs/bk4r1_defconfig
configs/m53menlo_defconfig
configs/pcm052_defconfig
configs/r8a7795_salvator-x_defconfig
configs/r8a7795_ulcb_defconfig
configs/r8a77965_salvator-x_defconfig
configs/r8a7796_salvator-x_defconfig
configs/r8a7796_ulcb_defconfig
configs/r8a77990_ebisu_defconfig
configs/sandbox_defconfig
configs/vf610twr_defconfig
configs/vf610twr_nand_defconfig
configs/x600_defconfig
doc/README.iscsi
doc/uImage.FIT/signature.txt
drivers/clk/clk_meson.c
drivers/clk/renesas/clk-rcar-gen3.c
drivers/firmware/psci.c
drivers/mmc/mmc-uclass.c
drivers/mmc/renesas-sdhi.c
drivers/mmc/tmio-common.c
drivers/mmc/tmio-common.h
drivers/mmc/uniphier-sd.c
drivers/rtc/Kconfig
drivers/rtc/m41t62.c
drivers/serial/serial.c
drivers/serial/serial_mpc8xx.c
drivers/spi/mpc8xx_spi.c
drivers/usb/Kconfig
drivers/watchdog/Kconfig
drivers/watchdog/mpc8xx_wdt.c
fs/fs.c
include/asm-generic/pe.h
include/common.h
include/configs/baltos.h
include/configs/emsdp.h
include/configs/m53menlo.h
include/configs/pcm052.h
include/configs/x600.h
include/efi.h
include/efi_api.h
include/efi_loader.h
include/efi_selftest.h
include/image.h
include/linux/psci.h
include/serial.h
include/u-boot/rsa.h
lib/Makefile
lib/efi/efi.c
lib/efi_loader/efi_bootmgr.c
lib/efi_loader/efi_boottime.c
lib/efi_loader/efi_console.c
lib/efi_loader/efi_device_path.c
lib/efi_loader/efi_device_path_to_text.c
lib/efi_loader/efi_disk.c
lib/efi_loader/efi_file.c
lib/efi_loader/efi_gop.c
lib/efi_loader/efi_memory.c
lib/efi_loader/efi_net.c
lib/efi_loader/efi_runtime.c
lib/efi_loader/efi_smbios.c
lib/efi_loader/helloworld.c
lib/efi_selftest/Kconfig
lib/efi_selftest/Makefile
lib/efi_selftest/efi_selftest.c
lib/efi_selftest/efi_selftest_config_table.c
lib/efi_selftest/efi_selftest_controllers.c
lib/efi_selftest/efi_selftest_crc32.c
lib/efi_selftest/efi_selftest_devicepath.c
lib/efi_selftest/efi_selftest_event_groups.c
lib/efi_selftest/efi_selftest_events.c
lib/efi_selftest/efi_selftest_exception.c [new file with mode: 0644]
lib/efi_selftest/efi_selftest_fdt.c
lib/efi_selftest/efi_selftest_loaded_image.c
lib/efi_selftest/efi_selftest_manageprotocols.c
lib/efi_selftest/efi_selftest_memory.c [new file with mode: 0644]
lib/efi_selftest/efi_selftest_snp.c
lib/efi_selftest/efi_selftest_textinput.c
lib/efi_selftest/efi_selftest_tpl.c
lib/efi_selftest/efi_selftest_unicode_collation.c
lib/efi_selftest/efi_selftest_variables.c
lib/efi_selftest/efi_selftest_watchdog.c
lib/fdtdec.c
lib/rsa/rsa-sign.c
lib/rsa/rsa-verify.c
lib/smbios.c
scripts/Makefile.lib
scripts/config_whitelist.txt
test/py/tests/test_efi_selftest.py
test/py/tests/test_vboot.py
test/py/tests/vboot/sign-configs-sha1-pss.its [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha1.its
test/py/tests/vboot/sign-configs-sha256-pss.its [new file with mode: 0644]
test/py/tests/vboot/sign-configs-sha256.its
test/py/tests/vboot/sign-images-sha1-pss.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha1.its
test/py/tests/vboot/sign-images-sha256-pss.its [new file with mode: 0644]
test/py/tests/vboot/sign-images-sha256.its
tools/image-host.c

diff --git a/Kconfig b/Kconfig
index dca9bb4..42672a9 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -86,6 +86,7 @@ config DISTRO_DEFAULTS
        select SUPPORT_RAW_INITRD
        select SYS_LONGHELP
        imply CMD_MII if NET
+       imply USB_STORAGE
        imply USE_BOOTCOMMAND
        help
          Select this to enable various options and commands which are suitable
@@ -290,6 +291,14 @@ config FIT_SIGNATURE_MAX_SIZE
          device memory. Assure this size does not extend past expected storage
          space.
 
+config FIT_ENABLE_RSASSA_PSS_SUPPORT
+       bool "Support rsassa-pss signature scheme of FIT image contents"
+       depends on FIT_SIGNATURE
+       default n
+       help
+         Enable this to support the pss padding algorithm as described
+         in the rfc8017 (https://tools.ietf.org/html/rfc8017).
+
 config FIT_VERBOSE
        bool "Show verbose messages when FIT images fail"
        help
index 214629e..8ea8ef9 100644 (file)
@@ -2,6 +2,8 @@ Descriptions of section entries:
 
        P: Person (obsolete)
        M: Mail patches to: FullName <address@domain>
+       R: Designated reviewer: FullName <address@domain>
+          These reviewers should be CCed on patches.
        L: Mailing list that is relevant to this area
        W: Web-page with status/info
        Q: Patchwork web based patch tracking system site
@@ -414,6 +416,7 @@ F:  test/dm/
 
 EFI PAYLOAD
 M:     Alexander Graf <agraf@suse.de>
+R:     Heinrich Schuchardt <xypron.glpk@gmx.de>
 S:     Maintained
 T:     git git://github.com/agraf/u-boot.git
 F:     doc/README.uefi
index 9920d2e..fff6591 100644 (file)
  * access: "lr"/"sr".
  */
 
+/*
+ * Typically 8 least significant bits of Build Configuration Register (BCR)
+ * describe version of the HW block in question. Moreover if decoded version
+ * is 0 this means given HW block is absent - this is especially useful because
+ * we may safely read BRC regardless HW block existence while an attempt to
+ * access any other AUX regs associated with this HW block lead to imediate
+ * "instruction error" exception.
+ *
+ * I.e. before using any cofigurable HW block it's required to make sure it
+ * exists at all, and for that we introduce a special macro below.
+ */
+#define ARC_BCR_VERSION_MASK   GENMASK(7, 0)
+#define ARC_FEATURE_EXISTS(bcr)        !!(__builtin_arc_lr(bcr) & ARC_BCR_VERSION_MASK)
+
 #define ARC_AUX_IDENTITY       0x04
 #define ARC_AUX_STATUS32       0x0a
 
@@ -73,7 +87,7 @@
 #define ARC_BCR_CLUSTER                0xcf
 
 /* MMU Management regs */
-#define ARC_AUX_MMU_BCR                0x06f
+#define ARC_AUX_MMU_BCR                0x6f
 
 /* IO coherency related auxiliary registers */
 #define ARC_AUX_IO_COH_ENABLE  0x500
 #define ARC_AUX_IO_COH_AP0_BASE        0x508
 #define ARC_AUX_IO_COH_AP0_SIZE        0x509
 
+/* XY-memory related */
+#define ARC_AUX_XY_BUILD       0x79
+
+/* DSP-extensions related auxiliary registers */
+#define ARC_AUX_DSP_BUILD      0x7A
+
+/* ARC Subsystems related auxiliary registers */
+#define ARC_AUX_SUBSYS_BUILD   0xF0
+
 #ifndef __ASSEMBLY__
 /* Accessors for auxiliary registers */
 #define read_aux_reg(reg)      __builtin_arc_lr(reg)
index a969a16..07daaa8 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
 
@@ -35,34 +36,193 @@ int dram_init(void)
 }
 
 #ifdef CONFIG_DISPLAY_CPUINFO
-const char *decode_identity(void)
+const char *arc_700_version(int arcver, char *name, int name_len)
 {
-       int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+       const char *arc_ver;
+
+       switch (arcver) {
+       case 0x32:
+               arc_ver = "v4.4-4.5";
+               break;
+       case 0x33:
+               arc_ver = "v4.6-v4.9";
+               break;
+       case 0x34:
+               arc_ver = "v4.10";
+               break;
+       case 0x35:
+               arc_ver = "v4.11";
+               break;
+       default:
+               arc_ver = "unknown version";
+       }
+
+       snprintf(name, name_len, "ARC 700 %s", arc_ver);
+
+       return name;
+}
+
+struct em_template_t {
+       const bool cache;
+       const bool dsp;
+       const bool xymem;
+       const char name[8];
+};
+
+static const struct em_template_t em_versions[] = {
+       {false, false,  false,  "EM4"},
+       {true,  false,  false,  "EM6"},
+       {false, true,   false,  "EM5D"},
+       {true,  true,   false,  "EM7D"},
+       {false, true,   true,   "EM9D"},
+       {true,  true,   true,   "EM11D"},
+};
+
+const char *arc_em_version(int arcver, char *name, int name_len)
+{
+       const char *arc_name = "EM";
+       const char *arc_ver;
+       bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+       bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+       bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
+       int i;
+
+       for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) {
+               if (em_versions[i].cache == cache &&
+                   em_versions[i].dsp == dsp &&
+                   em_versions[i].xymem == xymem) {
+                       arc_name = em_versions[i].name;
+                       break;
+               }
+       }
+
+       switch (arcver) {
+       case 0x41:
+               arc_ver = "v1.1a";
+               break;
+       case 0x42:
+               arc_ver = "v3.0";
+               break;
+       case 0x43:
+               arc_ver = "v4.0";
+               break;
+       case 0x44:
+               arc_ver = "v5.0";
+               break;
+       default:
+               arc_ver = "unknown version";
+       }
+
+       snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+       return name;
+}
+
+struct hs_template_t {
+       const bool cache;
+       const bool mmu;
+       const bool dual_issue;
+       const bool dsp;
+       const char name[8];
+};
+
+static const struct hs_template_t hs_versions[] = {
+       {false, false,  false,  false,  "HS34"},
+       {true,  false,  false,  false,  "HS36"},
+       {true,  true,   false,  false,  "HS38"},
+       {false, false,  true,   false,  "HS44"},
+       {true,  false,  true,   false,  "HS46"},
+       {true,  true,   true,   false,  "HS48"},
+       {false, false,  true,   true,   "HS45D"},
+       {true,  false,  true,   true,   "HS47D"},
+};
+
+const char *arc_hs_version(int arcver, char *name, int name_len)
+{
+       const char *arc_name = "HS";
+       const char *arc_ver;
+       bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
+       bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
+       bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
+       bool dual_issue = arcver == 0x54 ? true : false;
+       int i;
+
+       for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) {
+               if (hs_versions[i].cache == cache &&
+                   hs_versions[i].mmu == mmu &&
+                   hs_versions[i].dual_issue == dual_issue &&
+                   hs_versions[i].dsp == dsp) {
+                       arc_name = hs_versions[i].name;
+                       break;
+               }
+       }
 
        switch (arcver) {
-       /* ARCompact cores */
-       case 0x32: return "ARC 700 v4.4-4.5";
-       case 0x33: return "ARC 700 v4.6-v4.9";
-       case 0x34: return "ARC 700 v4.10";
-       case 0x35: return "ARC 700 v4.11";
-
-       /* ARCv2 cores */
-       case 0x41: return "ARC EM v1.1a";
-       case 0x42: return "ARC EM v3.0";
-       case 0x43: return "ARC EM v4.0";
-       case 0x50: return "ARC HS v1.0";
-       case 0x51: return "ARC EM v2.0";
-       case 0x52: return "ARC EM v2.1";
-       case 0x53: return "ARC HS v3.0";
-       case 0x54: return "ARC HS v4.0";
-
-       default: return "Unknown ARC core";
+       case 0x50:
+               arc_ver = "v1.0";
+               break;
+       case 0x51:
+               arc_ver = "v2.0";
+               break;
+       case 0x52:
+               arc_ver = "v2.1c";
+               break;
+       case 0x53:
+               arc_ver = "v3.0";
+               break;
+       case 0x54:
+               arc_ver = "v4.0";
+               break;
+       default:
+               arc_ver = "unknown version";
        }
+
+       snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);
+
+       return name;
+}
+
+const char *decode_identity(void)
+{
+#define MAX_CPU_NAME_LEN       64
+
+       int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+       char *name = malloc(MAX_CPU_NAME_LEN);
+
+       if (arcver >= 0x50)
+               return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
+       else if (arcver >= 0x40)
+               return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
+       else if (arcver >= 0x30)
+               return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
+       else
+               return "Unknown ARC core";
+}
+
+const char *decode_subsystem(void)
+{
+       int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);
+
+       switch (subsys_type) {
+       case 0: return NULL;
+       case 2: return "ARC Sensor & Control IP Subsystem";
+       case 3: return "ARC Data Fusion IP Subsystem";
+       case 4: return "ARC Secure Subsystem";
+       default: return "Unknown subsystem";
+       };
 }
 
 __weak int print_cpuinfo(void)
 {
-       printf("CPU:   %s\n", decode_identity());
+       const char *subsys_name = decode_subsystem();
+       char mhz[8];
+
+       printf("CPU:   %s at %s MHz\n", decode_identity(),
+              strmhz(mhz, gd->cpu_clk));
+
+       if (subsys_name)
+               printf("Subsys:%s\n", subsys_name);
+
        return 0;
 }
 #endif /* CONFIG_DISPLAY_CPUINFO */
index 0d8b59e..eae69e3 100644 (file)
@@ -7,6 +7,8 @@
 #include <asm/opcodes-sec.h>
 #include <asm/opcodes-virt.h>
 
+       .section        .text.efi_runtime
+
 #define UNWIND(x...)
        /*
         * Wrap c macros in asm macros to delay expansion until after the
index ff42791..1c12bbd 100644 (file)
@@ -96,6 +96,7 @@ endmenu
 config PSCI_RESET
        bool "Use PSCI for reset and shutdown"
        default y
+       select ARM_SMCCC if OF_CONTROL
        depends on !ARCH_EXYNOS7 && !ARCH_BCM283X && \
                   !TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
                   !TARGET_LS2080ARDB && !TARGET_LS2080A_EMU && \
index 0ba3dad..9957c29 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <asm-offsets.h>
 #include <config.h>
-#include <efi_loader.h>
 #include <version.h>
 #include <asm/macro.h>
 #include <asm/psci.h>
@@ -19,7 +18,7 @@
  * x0~x7: input arguments
  * x0~x3: output arguments
  */
-static void __efi_runtime hvc_call(struct pt_regs *args)
+static void hvc_call(struct pt_regs *args)
 {
        asm volatile(
                "ldr x0, %0\n"
@@ -53,7 +52,7 @@ static void __efi_runtime hvc_call(struct pt_regs *args)
  * x0~x3: output arguments
  */
 
-void __efi_runtime smc_call(struct pt_regs *args)
+void smc_call(struct pt_regs *args)
 {
        asm volatile(
                "ldr x0, %0\n"
@@ -83,9 +82,9 @@ void __efi_runtime smc_call(struct pt_regs *args)
  * use PSCI on U-Boot running below a hypervisor, please detect
  * this and set the flag accordingly.
  */
-static const __efi_runtime_data bool use_smc_for_psci = true;
+static const bool use_smc_for_psci = true;
 
-void __noreturn __efi_runtime psci_system_reset(void)
+void __noreturn psci_system_reset(void)
 {
        struct pt_regs regs;
 
@@ -100,7 +99,7 @@ void __noreturn __efi_runtime psci_system_reset(void)
                ;
 }
 
-void __noreturn __efi_runtime psci_system_off(void)
+void __noreturn psci_system_off(void)
 {
        struct pt_regs regs;
 
@@ -114,44 +113,3 @@ void __noreturn __efi_runtime psci_system_off(void)
        while (1)
                ;
 }
-
-#ifdef CONFIG_CMD_POWEROFF
-int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       puts("poweroff ...\n");
-
-       udelay(50000); /* wait 50 ms */
-
-       disable_interrupts();
-
-       psci_system_off();
-
-       /*NOTREACHED*/
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_PSCI_RESET
-void reset_misc(void)
-{
-       psci_system_reset();
-}
-
-#ifdef CONFIG_EFI_LOADER
-void __efi_runtime EFIAPI efi_reset_system(
-                       enum efi_reset_type reset_type,
-                       efi_status_t reset_status,
-                       unsigned long data_size, void *reset_data)
-{
-       if (reset_type == EFI_RESET_COLD ||
-           reset_type == EFI_RESET_WARM ||
-           reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
-               psci_system_reset();
-       } else if (reset_type == EFI_RESET_SHUTDOWN) {
-               psci_system_off();
-       }
-
-       while (1) { }
-}
-#endif /* CONFIG_EFI_LOADER */
-#endif /* CONFIG_PSCI_RESET */
index 16c9e29..86de4b4 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/arm-smccc.h>
 #include <generated/asm-offsets.h>
 
+       .section        .text.efi_runtime
+
        .macro SMCCC instr
        .cfi_startproc
        \instr  #0
diff --git a/arch/arm/dts/am335x-baltos.dts b/arch/arm/dts/am335x-baltos.dts
new file mode 100644 (file)
index 0000000..f939cf6
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * VScom OnRISC
+ * http://www.vscom.de
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       model = "OnRISC Baltos";
+       compatible = "vscom,onrisc", "ti,am33xx";
+
+       chosen {
+               stdout-path = &uart0;
+       };
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vdd1_reg>;
+               };
+       };
+
+       vbat: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vbat";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+       };
+};
+
+&am33xx_pinmux {
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0xf0 (MUX_MODE0 | INPUT_EN | PULL_UP)   /* mmc0_dat3.mmc0_dat3 */
+                       0xf4 (MUX_MODE0 | INPUT_EN | PULL_UP)   /* mmc0_dat2.mmc0_dat2 */
+                       0xf8 (MUX_MODE0 | INPUT_EN | PULL_UP)   /* mmc0_dat1.mmc0_dat1 */
+                       0xfc (MUX_MODE0 | INPUT_EN | PULL_UP)   /* mmc0_dat0.mmc0_dat0 */
+                       0x100 (MUX_MODE0 | INPUT_EN | PULL_UP)  /* mmc0_clk.mmc0_clk */
+                       0x104 (MUX_MODE0 | INPUT_EN | PULL_UP)  /* mmc0_cmd.mmc0_cmd */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0x158 0x2a      /* spi0_d1.i2c1_sda_mux3, INPUT | MODE2 */
+                       0x15c 0x2a      /* spi0_cs0.i2c1_scl_mux3, INPUT | MODE2 */
+               >;
+       };
+
+       tps65910_pins: pinmux_tps65910_pins {
+               pinctrl-single,pins = <
+                       0x078 (PIN_INPUT_PULLUP | MUX_MODE7)      /* gpmc_ben1.gpio1[28] */
+               >;
+
+       };
+       tca6416_pins: pinmux_tca6416_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9b4, PIN_INPUT_PULLUP | MUX_MODE7)      /* xdma_event_intr1.gpio0[20] tca6416 stuff */
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+                       0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)         /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)       /* mii1_crs.rmii1_crs_dv */
+                       0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_tx_en.rmii1_txen */
+                       0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd1.rmii1_txd1 */
+                       0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE1)      /* mii1_txd0.rmii1_txd0 */
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd1.rmii1_rxd1 */
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)      /* mii1_rxd0.rmii1_rxd0 */
+                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)      /* rmii1_ref_clk.rmii1_refclk */
+
+
+                       /* Slave 2 */
+                       0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
+                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
+                       0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
+                       0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
+                       0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
+                       0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
+                       0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
+                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
+                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
+                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
+                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
+                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+                       /* Slave 2 reset value*/
+                       0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
+                       0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)                   /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       nandflash_pins_s0: nandflash_pins_s0 {
+               pinctrl-single,pins = <
+                       0x0 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad0.gpmc_ad0 */
+                       0x4 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad1.gpmc_ad1 */
+                       0x8 (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad2.gpmc_ad2 */
+                       0xc (PIN_INPUT_PULLUP | MUX_MODE0)      /* gpmc_ad3.gpmc_ad3 */
+                       0x10 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad4.gpmc_ad4 */
+                       0x14 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad5.gpmc_ad5 */
+                       0x18 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad6.gpmc_ad6 */
+                       0x1c (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_ad7.gpmc_ad7 */
+                       0x70 (PIN_INPUT_PULLUP | MUX_MODE0)     /* gpmc_wait0.gpmc_wait0 */
+                       0x74 (PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_wpn.gpio0_30 */
+                       0x7c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_csn0.gpmc_csn0  */
+                       0x90 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_advn_ale.gpmc_advn_ale */
+                       0x94 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_oen_ren.gpmc_oen_ren */
+                       0x98 (PIN_OUTPUT | MUX_MODE0)           /* gpmc_wen.gpmc_wen */
+                       0x9c (PIN_OUTPUT | MUX_MODE0)           /* gpmc_be0n_cle.gpmc_be0n_cle */
+               >;
+       };
+};
+
+&elm {
+       status = "okay";
+};
+
+&gpmc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nandflash_pins_s0>;
+       ranges = <0 0 0x08000000 0x10000000>;   /* CS0: NAND */
+       status = "okay";
+
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               nand-bus-width = <8>;
+               ti,nand-ecc-opt = "bch8";
+               ti,nand-xfer-type = "polled";
+
+               gpmc,device-nand = "true";
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,wait-on-read = "true";
+               gpmc,wait-on-write = "true";
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wait-monitoring-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+               elm_id = <&elm>;
+
+               boot@0 {
+                      label = "SPL";
+                      reg = <0x0 0x20000>;
+               };
+               boot@20000{
+                      label = "SPL.backup1";
+                      reg = <0x20000 0x20000>;
+               };
+               boot@40000 {
+                      label = "SPL.backup2";
+                      reg = <0x40000 0x20000>;
+               };
+               boot@60000 {
+                      label = "SPL.backup3";
+                      reg = <0x60000 0x20000>;
+               };
+               boot@80000 {
+                      label = "u-boot";
+                      reg = <0x80000 0x1e0000>;
+               };
+               boot@260000 {
+                      label = "UBI";
+                      reg = <0x260000 0xfda0000>;
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       status = "okay";
+       clock-frequency = <1000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <28 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tps65910_pins>;
+       };
+
+       at24@50 {
+               compatible = "at24,24c02";
+               pagesize = <8>;
+               reg = <0x50>;
+       };
+
+       tca6416: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <20 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&tca6416_pins>;
+       };
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&usb1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+/include/ "tps65910.dtsi"
+
+&tps {
+       vcc1-supply = <&vbat>;
+       vcc2-supply = <&vbat>;
+       vcc3-supply = <&vbat>;
+       vcc4-supply = <&vbat>;
+       vcc5-supply = <&vbat>;
+       vcc6-supply = <&vbat>;
+       vcc7-supply = <&vbat>;
+       vccio-supply = <&vbat>;
+
+       ti,en-ck32k-xtal = <1>;
+
+       regulators {
+               vrtc_reg: regulator@0 {
+                       regulator-always-on;
+               };
+
+               vio_reg: regulator@1 {
+                       regulator-always-on;
+               };
+
+               vdd1_reg: regulator@2 {
+                       /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <912500>;
+                       regulator-max-microvolt = <1312500>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd2_reg: regulator@3 {
+                       /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <912500>;
+                       regulator-max-microvolt = <1150000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd3_reg: regulator@4 {
+                       regulator-always-on;
+               };
+
+               vdig1_reg: regulator@5 {
+                       regulator-always-on;
+               };
+
+               vdig2_reg: regulator@6 {
+                       regulator-always-on;
+               };
+
+               vpll_reg: regulator@7 {
+                       regulator-always-on;
+               };
+
+               vdac_reg: regulator@8 {
+                       regulator-always-on;
+               };
+
+               vaux1_reg: regulator@9 {
+                       regulator-always-on;
+               };
+
+               vaux2_reg: regulator@10 {
+                       regulator-always-on;
+               };
+
+               vaux33_reg: regulator@11 {
+                       regulator-always-on;
+               };
+
+               vmmc_reg: regulator@12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+};
+
+&mac {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       dual_emac = <1>;
+
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rmii";
+       dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+       phy_id = <&davinci_mdio>, <7>;
+       phy-mode = "rgmii-txid";
+       dual_emac_res_vlan = <2>;
+};
+
+&phy_sel {
+       rmii-clock-ext = <1>;
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vmmc_reg>;
+       status = "okay";
+};
+
+&gpio0 {
+       ti,no-reset-on-init;
+};
index 3c31e21..f1e5cdb 100644 (file)
                        no-map;
                };
 
+               /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved_alt: secmon@5000000 {
+                       reg = <0x0 0x05000000 0x0 0x300000>;
+                       no-map;
+               };
+
                linux,cma {
                        compatible = "shared-dma-pool";
                        reusable;
-                       size = <0x0 0xbc00000>;
+                       size = <0x0 0x10000000>;
                        alignment = <0x0 0x400000>;
                        linux,cma-default;
                };
                        ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>;
 
                        sysctrl_AO: sys-ctrl@0 {
-                               compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd";
+                               compatible = "amlogic,meson-gx-ao-sysctrl", "simple-mfd", "syscon";
                                reg =  <0x0 0x0 0x0 0x100>;
 
                                pwrc_vpu: power-controller-vpu {
                        };
                };
 
+               dmcbus: bus@c8838000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xc8838000 0x0 0x400>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xc8838000 0x0 0x400>;
+
+                       canvas: video-lut@48 {
+                               compatible = "amlogic,canvas";
+                               reg = <0x0 0x48 0x0 0x14>;
+                       };
+               };
+
                hiubus: bus@c883c000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc883c000 0x0 0x2000>;
                        ranges = <0x0 0x0 0x0 0xc883c000 0x0 0x2000>;
 
                        sysctrl: system-controller@0 {
-                               compatible = "amlogic,meson-gx-hhi-sysctrl", "syscon", "simple-mfd";
+                               compatible = "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon";
                                reg = <0 0 0 0x400>;
                        };
 
 
                        sd_emmc_a: mmc@70000 {
                                compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-                               reg = <0x0 0x70000 0x0 0x2000>;
+                               reg = <0x0 0x70000 0x0 0x800>;
                                interrupts = <GIC_SPI 216 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        sd_emmc_b: mmc@72000 {
                                compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-                               reg = <0x0 0x72000 0x0 0x2000>;
+                               reg = <0x0 0x72000 0x0 0x800>;
                                interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        sd_emmc_c: mmc@74000 {
                                compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc";
-                               reg = <0x0 0x74000 0x0 0x2000>;
+                               reg = <0x0 0x74000 0x0 0x800>;
                                interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
index 7d5709c..cbe99bd 100644 (file)
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
        };
+
+       /* CVBS is available on CON1 pin 36, disabled by default */
+       cvbs-connector {
+               compatible = "composite-video-connector";
+               status = "disabled";
+
+               port {
+                       cvbs_connector_in: endpoint {
+                               remote-endpoint = <&cvbs_vdac_out>;
+                       };
+               };
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+};
+
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+       cvbs_vdac_out: endpoint {
+               remote-endpoint = <&cvbs_connector_in>;
+       };
 };
 
 &ethmac {
        };
 };
 
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
 &ir {
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
index 562c26a..1ade7e4 100644 (file)
        clock-names = "isfr", "iahb", "venci";
 };
 
-&hiubus {
-       clkc: clock-controller@0 {
+&sysctrl {
+       clkc: clock-controller {
                compatible = "amlogic,gxbb-clkc";
                #clock-cells = <1>;
-               reg = <0x0 0x0 0x0 0x3db>;
        };
 };
 
                        };
                };
 
-               spi_pins: spi {
+               spi_pins: spi-pins {
                        mux {
                                groups = "spi_miso",
                                        "spi_mosi",
                 <&clkc CLKID_SD_EMMC_A_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_A>;
 };
 
 &sd_emmc_b {
                 <&clkc CLKID_SD_EMMC_B_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_B>;
 };
 
 &sd_emmc_c {
                 <&clkc CLKID_SD_EMMC_C_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_C>;
 };
 
 &spicc {
 };
 
 &uart_AO {
-       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
        clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_AO_B {
-       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
        clock-names = "xtal", "pclk", "baud";
 };
 
index eb32766..6aaafff 100644 (file)
@@ -6,7 +6,7 @@
 
 &apb {
        mali: gpu@c0000 {
-               compatible = "amlogic,meson-gxbb-mali", "arm,mali-450";
+               compatible = "amlogic,meson-gxl-mali", "arm,mali-450";
                reg = <0x0 0xc0000 0x0 0x40000>;
                interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
index 3e3eb31..90a56af 100644 (file)
@@ -13,7 +13,7 @@
 
 / {
        compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
-       model = "Libre Technology CC";
+       model = "Libre Computer Board AML-S905X-CC";
 
        aliases {
                serial0 = &uart_AO;
 
        bus-width = <4>;
        cap-sd-highspeed;
-       sd-uhs-sdr12;
-       sd-uhs-sdr25;
-       sd-uhs-sdr50;
        max-frequency = <100000000>;
        disable-wp;
 
index 3bd4050..a1b3101 100644 (file)
 };
 
 &usb2_phy0 {
-        /*
-         * HDMI_5V is also used as supply for the USB VBUS.
-         */
-        phy-supply = <&hdmi_5v>;
+       /*
+        * HDMI_5V is also used as supply for the USB VBUS.
+        */
+       phy-supply = <&hdmi_5v>;
 };
index dba365e..8f0bb3c 100644 (file)
 / {
        compatible = "amlogic,meson-gxl";
 
-       reserved-memory {
-               /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
-               secmon_reserved_alt: secmon@5000000 {
-                       reg = <0x0 0x05000000 0x0 0x300000>;
-                       no-map;
-               };
-       };
-
        soc {
                usb0: usb@c9000000 {
                        status = "disabled";
        clock-names = "isfr", "iahb", "venci";
 };
 
-&hiubus {
-       clkc: clock-controller@0 {
-               compatible = "amlogic,gxl-clkc", "amlogic,gxbb-clkc";
+&sysctrl {
+       clkc: clock-controller {
+               compatible = "amlogic,gxl-clkc";
                #clock-cells = <1>;
-               reg = <0x0 0x0 0x0 0x3db>;
        };
 };
 
                        };
                };
 
-               spi_pins: spi {
+               spi_pins: spi-pins {
                        mux {
                                groups = "spi_miso",
                                        "spi_mosi",
                 <&clkc CLKID_SD_EMMC_A_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_A>;
 };
 
 &sd_emmc_b {
        clocks = <&clkc CLKID_SD_EMMC_B>,
                 <&clkc CLKID_SD_EMMC_B_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
-       clock-names = "core", "clkin0", "clkin1";
+       clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_B>;
 };
 
 &sd_emmc_c {
                 <&clkc CLKID_SD_EMMC_C_CLK0>,
                 <&clkc CLKID_FCLK_DIV2>;
        clock-names = "core", "clkin0", "clkin1";
+       resets = <&reset RESET_SD_EMMC_C>;
 };
 
 &spicc {
 };
 
 &uart_AO {
-       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
        clock-names = "xtal", "pclk", "baud";
 };
 
 &uart_AO_B {
-       clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>;
+       clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
        clock-names = "xtal", "pclk", "baud";
 };
 
index 0868da4..313f88f 100644 (file)
        #cooling-cells = <2>;
 };
 
+&cpu1 {
+       #cooling-cells = <2>;
+};
+
+&cpu2 {
+       #cooling-cells = <2>;
+};
+
+&cpu3 {
+       #cooling-cells = <2>;
+};
+
 &cpu4 {
        #cooling-cells = <2>;
 };
 
+&cpu5 {
+       #cooling-cells = <2>;
+};
+
+&cpu6 {
+       #cooling-cells = <2>;
+};
+
+&cpu7 {
+       #cooling-cells = <2>;
+};
+
 &ethmac {
        pinctrl-0 = <&eth_pins>;
        pinctrl-names = "default";
index 5e3c195..0f269d0 100644 (file)
                regulator-boot-on;
                regulator-always-on;
        };
+
+       vcc_sdhi0: regulator-vcc-sdhi0 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI0 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi0: regulator-vccq-sdhi0 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI0 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
+
+       vcc_sdhi1: regulator-vcc-sdhi1 {
+               compatible = "regulator-fixed";
+
+               regulator-name = "SDHI1 Vcc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vccq_sdhi1: regulator-vccq-sdhi1 {
+               compatible = "regulator-gpio";
+
+               regulator-name = "SDHI1 VccQ";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+               gpios-states = <1>;
+               states = <3300000 1
+                         1800000 0>;
+       };
 };
 
 &avb {
                function = "scif_clk";
        };
 
+       sdhi0_pins: sd0 {
+               groups = "sdhi0_data4", "sdhi0_ctrl";
+               function = "sdhi0";
+               power-source = <3300>;
+       };
+
+       sdhi0_pins_uhs: sd0_uhs {
+               groups = "sdhi0_data4", "sdhi0_ctrl";
+               function = "sdhi0";
+               power-source = <1800>;
+       };
+
+       sdhi1_pins: sd1 {
+               groups = "sdhi1_data4", "sdhi1_ctrl";
+               function = "sdhi1";
+               power-source = <3300>;
+       };
+
+       sdhi1_pins_uhs: sd1_uhs {
+               groups = "sdhi1_data4", "sdhi1_ctrl";
+               function = "sdhi1";
+               power-source = <1800>;
+       };
+
        sdhi3_pins: sd2 {
-               groups = "sdhi3_data8", "sdhi3_ctrl";
+               groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
                function = "sdhi3";
                power-source = <1800>;
        };
 
        sdhi3_pins_uhs: sd2_uhs {
-               groups = "sdhi3_data8", "sdhi3_ctrl";
+               groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
                function = "sdhi3";
                power-source = <1800>;
        };
 };
 
 &sdhi0 {
+       /* full size SD */
+       pinctrl-0 = <&sdhi0_pins>;
+       pinctrl-1 = <&sdhi0_pins_uhs>;
+       pinctrl-names = "default", "state_uhs";
+
+       vmmc-supply = <&vcc_sdhi0>;
+       vqmmc-supply = <&vccq_sdhi0>;
+       cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+       bus-width = <4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
+       max-frequency = <208000000>;
 };
 
 &sdhi1 {
+       /* microSD */
+       pinctrl-0 = <&sdhi1_pins>;
+       pinctrl-1 = <&sdhi1_pins_uhs>;
+       pinctrl-names = "default", "state_uhs";
+
+       vmmc-supply = <&vcc_sdhi1>;
+       vqmmc-supply = <&vccq_sdhi1>;
+       cd-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
+       max-frequency = <208000000>;
 };
 
 &sdhi3 {
        vqmmc-supply = <&reg_1p8v>;
        bus-width = <8>;
        mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
        non-removable;
        status = "okay";
 };
index a36e0eb..b036a71 100644 (file)
        };
 
        sdhi2_pins: sd2 {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
 
        sdhi2_pins_uhs: sd2_uhs {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
        cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
        wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
+
+       max-frequency = <208000000>;
 };
 
 &sdhi2 {
        vqmmc-supply = <&reg_1p8v>;
        bus-width = <8>;
        mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
        non-removable;
        fixed-emmc-driver-type = <1>;
        status = "okay";
+       max-frequency = <200000000>;
 };
 
 &sdhi3 {
        cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
        wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
        bus-width = <4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
+       max-frequency = <208000000>;
 };
 
 &ssi1 {
index ab88665..e16c7f2 100644 (file)
        };
 
        sdhi2_pins: sd2 {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
 
        sdhi2_pins_uhs: sd2_uhs {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
        vqmmc-supply = <&vccq_sdhi0>;
        cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
        bus-width = <4>;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
        sd-uhs-sdr50;
+       sd-uhs-sdr104;
        status = "okay";
+       max-frequency = <208000000>;
 };
 
 &sdhi2 {
        vqmmc-supply = <&reg_1p8v>;
        bus-width = <8>;
        mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
        non-removable;
        status = "okay";
+       max-frequency = <200000000>;
 };
 
 &ssi1 {
index 0db4360..cb205fa 100644 (file)
@@ -28,13 +28,13 @@ coff_header:
        .short  2                               /* nr_sections */
        .long   0                               /* TimeDateStamp */
        .long   0                               /* PointerToSymbolTable */
-       .long   1                               /* NumberOfSymbols */
+       .long   0                               /* NumberOfSymbols */
        .short  section_table - optional_header /* SizeOfOptionalHeader */
-       /*
-        * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
-        * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
-        */
-       .short  0x206
+       /* Characteristics */
+       .short  (IMAGE_FILE_EXECUTABLE_IMAGE | \
+                IMAGE_FILE_LINE_NUMS_STRIPPED | \
+                IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+                IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
        .short  0x20b                           /* PE32+ format */
        .byte   0x02                            /* MajorLinkerVersion */
index 23db49f..5470e2f 100644 (file)
@@ -27,16 +27,16 @@ coff_header:
        .short  2                               /* nr_sections */
        .long   0                               /* TimeDateStamp */
        .long   0                               /* PointerToSymbolTable */
-       .long   1                               /* NumberOfSymbols */
+       .long   0                               /* NumberOfSymbols */
        .short  section_table - optional_header /* SizeOfOptionalHeader */
-       /*
-        * Characteristics: IMAGE_FILE_32BIT_MACHINE |
-        * IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
-        * IMAGE_FILE_LINE_NUMS_STRIPPED
-        */
-       .short  0x306
+       /* Characteristics */
+       .short  (IMAGE_FILE_EXECUTABLE_IMAGE | \
+                IMAGE_FILE_LINE_NUMS_STRIPPED | \
+                IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+                IMAGE_FILE_32BIT_MACHINE | \
+                IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
-       .short  0x10b                           /* PE32+ format */
+       .short  0x10b                           /* PE32 format */
        .byte   0x02                            /* MajorLinkerVersion */
        .byte   0x14                            /* MinorLinkerVersion */
        .long   _edata - _start                 /* SizeOfCode */
index 8dde4be..b8bdaae 100644 (file)
@@ -144,9 +144,11 @@ in_flash:
        ori     r2, r2, CONFIG_SYS_DER@l
        mtspr   DER, r2
 
-       /* set up the stack in internal DPRAM */
+       /* set up the stack on top of internal DPRAM */
        lis     r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@h
        ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)@l
+       stw     r0, -4(r3)
+       stw     r0, -8(r3)
        addi    r1, r3, -8
 
        bl      board_init_f_alloc_reserve
index a19aa56..172bed4 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 dtb-$(CONFIG_TARGET_T2080QDS) += t2080qds.dtb
+dtb-$(CONFIG_MCR3000) += mcr3000.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts
new file mode 100644 (file)
index 0000000..5abf111
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * MCR3000 Device Tree Source
+ *
+ * Copyright 2017 CS Systemes d'Information
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/dts-v1/;
+
+/ {
+       WDT: watchdog@0 {
+               compatible = "fsl,pq1-wdt";
+       };
+       SERIAL: smc@0 {
+               compatible = "fsl,pq1-smc";
+       };
+
+       chosen {
+               stdout-path = &SERIAL;
+       };
+};
index 18f61f5..b7b5329 100644 (file)
@@ -41,13 +41,13 @@ coff_header:
        .short  2                               /* nr_sections */
        .long   0                               /* TimeDateStamp */
        .long   0                               /* PointerToSymbolTable */
-       .long   1                               /* NumberOfSymbols */
+       .long   0                               /* NumberOfSymbols */
        .short  section_table - optional_header /* SizeOfOptionalHeader */
-       /*
-        * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
-        * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
-        */
-       .short  0x206
+       /* Characteristics */
+       .short  (IMAGE_FILE_EXECUTABLE_IMAGE | \
+                IMAGE_FILE_LINE_NUMS_STRIPPED | \
+                IMAGE_FILE_LOCAL_SYMS_STRIPPED | \
+                IMAGE_FILE_DEBUG_STRIPPED)
 optional_header:
        .short  0x20b                           /* PE32+ format */
        .byte   0x02                            /* MajorLinkerVersion */
index 8151e47..b5e8f46 100644 (file)
@@ -34,7 +34,7 @@ PLATFORM_LDFLAGS += -m $(if $(IS_32BIT),elf_i386,elf_x86_64)
 
 # This is used in the top-level Makefile which does not include
 # PLATFORM_LDFLAGS
-LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
+LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined -s
 
 OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
        -j .rel -j .rela -j .reloc
@@ -65,7 +65,7 @@ CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
 ifeq ($(CONFIG_EFI_APP),y)
 
 PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
-LDFLAGS_FINAL += -znocombreloc -shared
+LDFLAGS_FINAL += -znocombreloc -shared -s
 LDSCRIPT := $(LDSCRIPT_EFI)
 
 else
index ffbeb14..d26ac35 100644 (file)
@@ -12,6 +12,8 @@
 #include <mpc8xx.h>
 #include <fdt_support.h>
 #include <asm/io.h>
+#include <dm/uclass.h>
+#include <wdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -143,3 +145,17 @@ int board_early_init_f(void)
 
        return 0;
 }
+
+int board_early_init_r(void)
+{
+       struct udevice *watchdog_dev = NULL;
+
+       if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
+               puts("Cannot find watchdog!\n");
+       } else {
+               puts("Enabling watchdog.\n");
+               wdt_start(watchdog_dev, 0xffff, 0);
+       }
+
+       return 0;
+}
index a32c0e7..70aef32 100644 (file)
@@ -19,7 +19,6 @@ SECTIONS
                arch/powerpc/cpu/mpc8xx/start.o (.text)
                arch/powerpc/cpu/mpc8xx/traps.o (.text*)
                arch/powerpc/lib/built-in.o             (.text*)
-               board/cssi/MCR3000/built-in.o   (.text*)
                drivers/net/built-in.o          (.text*)
 
                . = DEFINED(env_offset) ? env_offset : .;
@@ -69,6 +68,12 @@ SECTIONS
        __ex_table : { *(__ex_table) }
        __stop___ex_table = .;
 
+       /*
+        * _end - This is end of u-boot.bin image.
+        * dtb will be appended here to make u-boot-dtb.bin
+        */
+       _end = .;
+
        . = ALIGN(4096);
        __init_begin = .;
        .text.init : { *(.text.init) }
index c95f7af..ffa7c15 100644 (file)
@@ -109,3 +109,11 @@ void smp_kick_all_cpus(void)
        writel(cmd, (void __iomem *)AXC003_CREG_CPU_START);
 }
 #endif
+
+int checkboard(void)
+{
+       printf("Board: ARC Software Development Platform AXS%s\n",
+            is_isa_arcv2() ? "103" : "101");
+
+       return 0;
+};
index b5ec7f1..c0770b5 100644 (file)
@@ -7,10 +7,46 @@
 #include <dwmmc.h>
 #include <malloc.h>
 
+#include <asm/arcregs.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
-#define ARC_PERIPHERAL_BASE    0xF0000000
-#define SDIO_BASE              (ARC_PERIPHERAL_BASE + 0x10000)
+#define ARC_PERIPHERAL_BASE            0xF0000000
+
+#define CGU_ARC_FMEAS_ARC              (void *)(ARC_PERIPHERAL_BASE + 0x84)
+#define CGU_ARC_FMEAS_ARC_START                BIT(31)
+#define CGU_ARC_FMEAS_ARC_DONE         BIT(30)
+#define CGU_ARC_FMEAS_ARC_CNT_MASK     GENMASK(14, 0)
+#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET  0
+#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET  15
+
+#define SDIO_BASE                      (void *)(ARC_PERIPHERAL_BASE + 0x10000)
+
+int mach_cpu_init(void)
+{
+       int rcnt, fcnt;
+       u32 data;
+
+       /* Start frequency measurement */
+       writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
+
+       /* Poll DONE bit */
+       do {
+               data = readl(CGU_ARC_FMEAS_ARC);
+       } while (!(data & CGU_ARC_FMEAS_ARC_DONE));
+
+       /* Amount of reference 100 MHz clocks */
+       rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+       /* Amount of CPU clocks */
+       fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
+              CGU_ARC_FMEAS_ARC_CNT_MASK);
+
+       gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
+
+       return 0;
+}
 
 int board_mmc_init(bd_t *bis)
 {
@@ -24,7 +60,7 @@ int board_mmc_init(bd_t *bis)
 
        memset(host, 0, sizeof(struct dwmci_host));
        host->name = "Synopsys Mobile storage";
-       host->ioaddr = (void *)SDIO_BASE;
+       host->ioaddr = SDIO_BASE;
        host->buswidth = 4;
        host->dev_index = 0;
        host->bus_hz = 50000000;
@@ -42,31 +78,32 @@ int board_mmc_getcd(struct mmc *mmc)
 }
 
 #define CREG_BASE              0xF0001000
-#define CREG_BOOT_OFFSET       0
-#define CREG_BOOT_WP_OFFSET    8
+#define CREG_BOOT              (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_SW_RESET       (void *)(CREG_BASE + 0x0FF0)
+#define CREG_IP_VERSION                (void *)(CREG_BASE + 0x0FF8)
 
-#define CGU_BASE               0xF0000000
-#define CGU_IP_SW_RESET                0x0FF0
+/* Bits in CREG_BOOT register */
+#define CREG_BOOT_WP_BIT       BIT(8)
 
 void reset_cpu(ulong addr)
 {
-       writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+       writel(1, CREG_IP_SW_RESET);
        while (1)
                ; /* loop forever till reset */
 }
 
 static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-       u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+       u32 creg_boot = readl(CREG_BOOT);
 
        if (!strcmp(argv[1], "unlock"))
-               creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+               creg_boot &= ~CREG_BOOT_WP_BIT;
        else if (!strcmp(argv[1], "lock"))
-               creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+               creg_boot |= CREG_BOOT_WP_BIT;
        else
                return CMD_RET_USAGE;
 
-       writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+       writel(creg_boot, CREG_BOOT);
 
        return CMD_RET_SUCCESS;
 }
@@ -97,3 +134,12 @@ U_BOOT_CMD(
        "rom unlock - Unlock non-volatile memory for writing\n"
        "emsdp rom lock - Lock non-volatile memory to prevent writing\n"
 );
+
+int checkboard(void)
+{
+       int version = readl(CREG_IP_VERSION);
+
+       printf("Board: ARC EM Software Development Platform v%d.%d\n",
+              (version >> 16) & 0xff, version & 0xff);
+       return 0;
+};
index b6aefdb..8a2c201 100644 (file)
@@ -1054,10 +1054,8 @@ int board_mmc_init(bd_t *bis)
        return 0;
 }
 
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
+int checkboard(void)
 {
-       printf("CPU:   ARC HS38 v2.1c\n");
+       puts("Board: Synopsys ARC HS Development Kit\n");
        return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
+};
index f8838fb..8424e09 100644 (file)
@@ -189,13 +189,3 @@ int checkboard(void)
        puts("Board: Synopsys IoT Development Kit\n");
        return 0;
 };
-
-#ifdef CONFIG_DISPLAY_CPUINFO
-int print_cpuinfo(void)
-{
-       char mhz[8];
-
-       printf("CPU:   ARC EM9D at %s MHz\n", strmhz(mhz, gd->cpu_clk));
-       return 0;
-}
-#endif /* CONFIG_DISPLAY_CPUINFO */
index df0a2d2..c5949ad 100644 (file)
@@ -27,7 +27,6 @@
 #include <i2c.h>
 #include <miiphy.h>
 #include <cpsw.h>
-#include <power/tps65217.h>
 #include <power/tps65910.h>
 #include <environment.h>
 #include <watchdog.h>
@@ -35,8 +34,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* GPIO that controls power to DDR on EVM-SK */
-#define GPIO_DDR_VTT_EN                7
+/* GPIO that controls DIP switch and mPCIe slot */
 #define DIP_S1                 44
 #define MPCIE_SW               100
 
@@ -248,9 +246,6 @@ const struct ctrl_ioregs ioregs_baltos = {
 
 void sdram_init(void)
 {
-       gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
-       gpio_direction_output(GPIO_DDR_VTT_EN, 1);
-
        config_ddr(400, &ioregs_baltos,
                   &ddr3_baltos_data,
                   &ddr3_baltos_cmd_ctrl_data,
index 94410ae..9c5542e 100644 (file)
@@ -34,7 +34,6 @@ static struct module_pin_mux mmc0_pin_mux[] = {
        {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT0 */
        {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CLK */
        {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CMD */
-       //{OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */
        {-1},
 };
 
@@ -46,11 +45,6 @@ static struct module_pin_mux i2c1_pin_mux[] = {
        {-1},
 };
 
-static struct module_pin_mux gpio0_7_pin_mux[] = {
-       {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN)},      /* GPIO0_7 */
-       {-1},
-};
-
 static struct module_pin_mux rmii1_pin_mux[] = {
        {OFFSET(mii1_crs), MODE(1) | RXACTIVE},                 /* RGMII1_TCTL */
        {OFFSET(mii1_txen), MODE(1)},                   /* RGMII1_TCTL */
@@ -114,7 +108,6 @@ void enable_i2c1_pin_mux(void)
 void enable_board_pin_mux()
 {
        configure_module_pin_mux(i2c1_pin_mux);
-       configure_module_pin_mux(gpio0_7_pin_mux);
        configure_module_pin_mux(rgmii2_pin_mux);
        configure_module_pin_mux(rmii1_pin_mux);
        configure_module_pin_mux(mmc0_pin_mux);
index 4d68d80..38679ff 100644 (file)
@@ -148,16 +148,16 @@ static void set_load_options(struct efi_loaded_image *loaded_image_info,
 /**
  * copy_fdt() - Copy the device tree to a new location available to EFI
  *
- * The FDT is relocated into a suitable location within the EFI memory map.
- * An additional 12KB is added to the space in case the device tree needs to be
+ * The FDT is copied to a suitable location within the EFI memory map.
+ * Additional 12 KiB are added to the space in case the device tree needs to be
  * expanded later with fdt_open_into().
  *
- * @fdt_addr: On entry, address of start of FDT. On exit, address of relocated
- *     FDT start
- * @fdt_sizep: Returns new size of FDT, including
- * @return new relocated address of FDT
+ * @fdtp:      On entry a pointer to the flattened device tree.
+ *             On exit a pointer to the copy of the flattened device tree.
+ *             FDT start
+ * Return:     status code
  */
-static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
+static efi_status_t copy_fdt(void **fdtp)
 {
        unsigned long fdt_ram_start = -1L, fdt_pages;
        efi_status_t ret = 0;
@@ -178,17 +178,19 @@ static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
        }
 
        /*
-        * Give us at least 4KB of breathing room in case the device tree needs
-        * to be expanded later. Round up to the nearest EFI page boundary.
+        * Give us at least 12 KiB of breathing room in case the device tree
+        * needs to be expanded later.
         */
-       fdt = map_sysmem(*fdt_addrp, 0);
-       fdt_size = fdt_totalsize(fdt);
-       fdt_size += 4096 * 3;
-       fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
-       fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
-
-       /* Safe fdt location is at 127MB */
-       new_fdt_addr = fdt_ram_start + (127 * 1024 * 1024) + fdt_size;
+       fdt = *fdtp;
+       fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
+       fdt_size = fdt_pages << EFI_PAGE_SHIFT;
+
+       /*
+        * Safe fdt location is at 127 MiB.
+        * On the sandbox convert from the sandbox address space.
+        */
+       new_fdt_addr = (uintptr_t)map_sysmem(fdt_ram_start + 0x7f00000 +
+                                            fdt_size, 0);
        ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
                                 EFI_RUNTIME_SERVICES_DATA, fdt_pages,
                                 &new_fdt_addr);
@@ -203,13 +205,11 @@ static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
                        goto done;
                }
        }
-
-       new_fdt = map_sysmem(new_fdt_addr, fdt_size);
+       new_fdt = (void *)(uintptr_t)new_fdt_addr;
        memcpy(new_fdt, fdt, fdt_totalsize(fdt));
        fdt_set_totalsize(new_fdt, fdt_size);
 
-       *fdt_addrp = new_fdt_addr;
-       *fdt_sizep = fdt_size;
+       *fdtp = (void *)(uintptr_t)new_fdt_addr;
 done:
        return ret;
 }
@@ -277,7 +277,11 @@ static void efi_carve_out_dt_rsv(void *fdt)
                if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
                        continue;
 
-               pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+               /* Convert from sandbox address space. */
+               addr = (uintptr_t)map_sysmem(addr, 0);
+
+               pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK));
+               addr &= ~EFI_PAGE_MASK;
                if (!efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
                                        false))
                        printf("FDT memrsv map %d: Failed to add to map\n", i);
@@ -287,7 +291,6 @@ static void efi_carve_out_dt_rsv(void *fdt)
 static efi_status_t efi_install_fdt(ulong fdt_addr)
 {
        bootm_headers_t img = { 0 };
-       ulong fdt_pages, fdt_size, fdt_start;
        efi_status_t ret;
        void *fdt;
 
@@ -297,34 +300,58 @@ static efi_status_t efi_install_fdt(ulong fdt_addr)
                return EFI_INVALID_PARAMETER;
        }
 
+       /* Create memory reservation as indicated by the device tree */
+       efi_carve_out_dt_rsv(fdt);
+
        /* Prepare fdt for payload */
-       ret = copy_fdt(&fdt_addr, &fdt_size);
+       ret = copy_fdt(&fdt);
        if (ret)
                return ret;
 
-       unmap_sysmem(fdt);
-       fdt = map_sysmem(fdt_addr, 0);
-       fdt_size = fdt_totalsize(fdt);
        if (image_setup_libfdt(&img, fdt, 0, NULL)) {
                printf("ERROR: failed to process device tree\n");
                return EFI_LOAD_ERROR;
        }
 
-       efi_carve_out_dt_rsv(fdt);
-
        /* Link to it in the efi tables */
        ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
        if (ret != EFI_SUCCESS)
                return EFI_OUT_OF_RESOURCES;
 
-       /* And reserve the space in the memory map */
-       fdt_start = fdt_addr;
-       fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
+       return ret;
+}
+
+static efi_status_t bootefi_run_prepare(const char *load_options_path,
+               struct efi_device_path *device_path,
+               struct efi_device_path *image_path,
+               struct efi_loaded_image_obj **image_objp,
+               struct efi_loaded_image **loaded_image_infop)
+{
+       efi_status_t ret;
 
-       ret = efi_add_memory_map(fdt_start, fdt_pages,
-                                EFI_BOOT_SERVICES_DATA, true);
+       ret = efi_setup_loaded_image(device_path, image_path, image_objp,
+                                    loaded_image_infop);
+       if (ret != EFI_SUCCESS)
+               return ret;
 
-       return ret;
+       /* Transfer environment variable as load options */
+       set_load_options(*loaded_image_infop, load_options_path);
+
+       return 0;
+}
+
+/**
+ * bootefi_run_finish() - finish up after running an EFI test
+ *
+ * @loaded_image_info: Pointer to a struct which holds the loaded image info
+ * @image_objj: Pointer to a struct which holds the loaded image object
+ */
+static void bootefi_run_finish(struct efi_loaded_image_obj *image_obj,
+                              struct efi_loaded_image *loaded_image_info)
+{
+       efi_restore_gd();
+       free(loaded_image_info->load_options);
+       efi_delete_handle(&image_obj->header);
 }
 
 /**
@@ -345,7 +372,7 @@ static efi_status_t do_bootefi_exec(void *efi,
        efi_handle_t mem_handle = NULL;
        struct efi_device_path *memdp = NULL;
        efi_status_t ret;
-       struct efi_loaded_image_obj *image_handle = NULL;
+       struct efi_loaded_image_obj *image_obj = NULL;
        struct efi_loaded_image *loaded_image_info = NULL;
 
        EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
@@ -354,7 +381,7 @@ static efi_status_t do_bootefi_exec(void *efi,
        /*
         * Special case for efi payload not loaded from disk, such as
         * 'bootefi hello' or for example payload loaded directly into
-        * memory via jtag, etc:
+        * memory via JTAG, etc:
         */
        if (!device_path && !image_path) {
                printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
@@ -367,27 +394,25 @@ static efi_status_t do_bootefi_exec(void *efi,
                 */
                ret = efi_create_handle(&mem_handle);
                if (ret != EFI_SUCCESS)
-                       goto exit;
+                       return ret; /* TODO: leaks device_path */
                ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
                                       device_path);
                if (ret != EFI_SUCCESS)
-                       goto exit;
+                       goto err_add_protocol;
        } else {
                assert(device_path && image_path);
        }
 
-       ret = efi_setup_loaded_image(device_path, image_path, &image_handle,
-                                    &loaded_image_info);
-       if (ret != EFI_SUCCESS)
-               goto exit;
+       ret = bootefi_run_prepare("bootargs", device_path, image_path,
+                                 &image_obj, &loaded_image_info);
+       if (ret)
+               goto err_prepare;
 
-       /* Transfer environment variable bootargs as load options */
-       set_load_options(loaded_image_info, "bootargs");
        /* Load the EFI payload */
-       entry = efi_load_pe(image_handle, efi, loaded_image_info);
+       entry = efi_load_pe(image_obj, efi, loaded_image_info);
        if (!entry) {
                ret = EFI_LOAD_ERROR;
-               goto exit;
+               goto err_prepare;
        }
 
        if (memdp) {
@@ -405,9 +430,9 @@ static efi_status_t do_bootefi_exec(void *efi,
        /* Call our payload! */
        debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
 
-       if (setjmp(&image_handle->exit_jmp)) {
-               ret = image_handle->exit_status;
-               goto exit;
+       if (setjmp(&image_obj->exit_jmp)) {
+               ret = image_obj->exit_status;
+               goto err_prepare;
        }
 
 #ifdef CONFIG_ARM64
@@ -418,7 +443,7 @@ static efi_status_t do_bootefi_exec(void *efi,
 
                /* Move into EL2 and keep running there */
                armv8_switch_to_el2((ulong)entry,
-                                   (ulong)image_handle,
+                                   (ulong)&image_obj->header,
                                    (ulong)&systab, 0, (ulong)efi_run_in_el2,
                                    ES_TO_AARCH64);
 
@@ -435,7 +460,7 @@ static efi_status_t do_bootefi_exec(void *efi,
                secure_ram_addr(_do_nonsec_entry)(
                                        efi_run_in_hyp,
                                        (uintptr_t)entry,
-                                       (uintptr_t)image_handle,
+                                       (uintptr_t)&image_obj->header,
                                        (uintptr_t)&systab);
 
                /* Should never reach here, efi exits with longjmp */
@@ -443,18 +468,59 @@ static efi_status_t do_bootefi_exec(void *efi,
        }
 #endif
 
-       ret = efi_do_enter(image_handle, &systab, entry);
+       ret = efi_do_enter(&image_obj->header, &systab, entry);
 
-exit:
+err_prepare:
        /* image has returned, loaded-image obj goes *poof*: */
-       if (image_handle)
-               efi_delete_handle(&image_handle->parent);
+       bootefi_run_finish(image_obj, loaded_image_info);
+
+err_add_protocol:
        if (mem_handle)
                efi_delete_handle(mem_handle);
 
        return ret;
 }
 
+#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
+/**
+ * bootefi_test_prepare() - prepare to run an EFI test
+ *
+ * This sets things up so we can call EFI functions. This involves preparing
+ * the 'gd' pointer and setting up the load ed image data structures.
+ *
+ * @image_objp: loaded_image_infop: Pointer to a struct which will hold the
+ *    loaded image object. This struct will be inited by this function before
+ *    use.
+ * @loaded_image_infop: Pointer to a struct which will hold the loaded image
+ *    info. This struct will be inited by this function before use.
+ * @path: File path to the test being run (often just the test name with a
+ *    backslash before it
+ * @test_func: Address of the test function that is being run
+ * @load_options_path: U-Boot environment variable to use as load options
+ * @return 0 if OK, -ve on error
+ */
+static efi_status_t bootefi_test_prepare
+               (struct efi_loaded_image_obj **image_objp,
+               struct efi_loaded_image **loaded_image_infop, const char *path,
+               ulong test_func, const char *load_options_path)
+{
+       /* Construct a dummy device path */
+       bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
+                                             (uintptr_t)test_func,
+                                             (uintptr_t)test_func);
+       if (!bootefi_device_path)
+               return EFI_OUT_OF_RESOURCES;
+       bootefi_image_path = efi_dp_from_file(NULL, 0, path);
+       if (!bootefi_image_path)
+               return EFI_OUT_OF_RESOURCES;
+
+       return bootefi_run_prepare(load_options_path, bootefi_device_path,
+                                  bootefi_image_path, image_objp,
+                                  loaded_image_infop);
+}
+
+#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
+
 static int do_bootefi_bootmgr_exec(void)
 {
        struct efi_device_path *device_path, *file_path;
@@ -527,29 +593,17 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
        if (!strcmp(argv[1], "selftest")) {
-               struct efi_loaded_image_obj *image_handle;
+               struct efi_loaded_image_obj *image_obj;
                struct efi_loaded_image *loaded_image_info;
 
-               /* Construct a dummy device path. */
-               bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
-                                                     (uintptr_t)&efi_selftest,
-                                                     (uintptr_t)&efi_selftest);
-               bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest");
-
-               r = efi_setup_loaded_image(bootefi_device_path,
-                                          bootefi_image_path, &image_handle,
-                                          &loaded_image_info);
-               if (r != EFI_SUCCESS)
+               if (bootefi_test_prepare(&image_obj, &loaded_image_info,
+                                        "\\selftest", (uintptr_t)&efi_selftest,
+                                        "efi_selftest"))
                        return CMD_RET_FAILURE;
 
-               efi_save_gd();
-               /* Transfer environment variable efi_selftest as load options */
-               set_load_options(loaded_image_info, "efi_selftest");
                /* Execute the test */
-               r = efi_selftest(image_handle, &systab);
-               efi_restore_gd();
-               free(loaded_image_info->load_options);
-               efi_delete_handle(&image_handle->parent);
+               r = efi_selftest(&image_obj->header, &systab);
+               bootefi_run_finish(image_obj, loaded_image_info);
                return r != EFI_SUCCESS;
        } else
 #endif
@@ -608,45 +662,19 @@ U_BOOT_CMD(
 
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 {
-       char filename[32] = { 0 }; /* dp->str is u16[32] long */
-       char *s;
+       struct efi_device_path *device, *image;
+       efi_status_t ret;
 
        /* efi_set_bootdev is typically called repeatedly, recover memory */
        efi_free_pool(bootefi_device_path);
        efi_free_pool(bootefi_image_path);
-       /* If blk_get_device_part_str fails, avoid duplicate free. */
-       bootefi_device_path = NULL;
-       bootefi_image_path = NULL;
-
-       if (strcmp(dev, "Net")) {
-               struct blk_desc *desc;
-               disk_partition_t fs_partition;
-               int part;
-
-               part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
-                                              1);
-               if (part < 0)
-                       return;
-
-               bootefi_device_path = efi_dp_from_part(desc, part);
-       } else {
-#ifdef CONFIG_NET
-               bootefi_device_path = efi_dp_from_eth();
-#endif
-       }
-
-       if (!path)
-               return;
 
-       if (strcmp(dev, "Net")) {
-               /* Add leading / to fs paths, because they're absolute */
-               snprintf(filename, sizeof(filename), "/%s", path);
+       ret = efi_dp_from_name(dev, devnr, path, &device, &image);
+       if (ret == EFI_SUCCESS) {
+               bootefi_device_path = device;
+               bootefi_image_path = image;
        } else {
-               snprintf(filename, sizeof(filename), "%s", path);
+               bootefi_device_path = NULL;
+               bootefi_image_path = NULL;
        }
-       /* DOS style file path: */
-       s = filename;
-       while ((s = strchr(s, '/')))
-               *s++ = '\\';
-       bootefi_image_path = efi_dp_from_file(NULL, 0, filename);
 }
index 4052cf4..e88cb13 100644 (file)
@@ -137,6 +137,23 @@ static int eeprom_rw_block(unsigned offset, uchar *addr, unsigned alen,
                spi_write(addr, alen, buffer, len);
 #else  /* I2C */
 
+#if defined(CONFIG_DM_I2C) && defined(CONFIG_SYS_I2C_EEPROM_BUS)
+       struct udevice *dev;
+
+       ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_EEPROM_BUS, addr[0],
+                                     alen - 1, &dev);
+       if (ret) {
+               printf("%s: Cannot find udev for a bus %d\n", __func__,
+                      CONFIG_SYS_I2C_EEPROM_BUS);
+               return CMD_RET_FAILURE;
+       }
+
+       if (read)
+               ret = dm_i2c_read(dev, offset, buffer, len);
+       else
+               ret = dm_i2c_write(dev, offset, buffer, len);
+
+#else /* Non DM I2C support - will be removed */
 #if defined(CONFIG_SYS_I2C_EEPROM_BUS)
        i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS);
 #endif
@@ -145,10 +162,11 @@ static int eeprom_rw_block(unsigned offset, uchar *addr, unsigned alen,
                ret = i2c_read(addr[0], offset, alen - 1, buffer, len);
        else
                ret = i2c_write(addr[0], offset, alen - 1, buffer, len);
-
-       if (ret)
-               ret = 1;
 #endif
+#endif /* CONFIG_DM_I2C && CONFIG_SYS_I2C_EEPROM_BUS */
+       if (ret)
+               ret = CMD_RET_FAILURE;
+
        return ret;
 }
 
index c55e33e..21d3b3c 100644 (file)
@@ -453,7 +453,8 @@ static int initr_env(void)
        else
                set_default_env(NULL, 0);
 #ifdef CONFIG_OF_CONTROL
-       env_set_addr("fdtcontroladdr", gd->fdt_blob);
+       env_set_hex("fdtcontroladdr",
+                   (unsigned long)map_to_sysmem(gd->fdt_blob));
 #endif
 
        /* Initialize from environment */
@@ -743,7 +744,7 @@ static init_fnc_t init_sequence_r[] = {
        /* initialize higher level parts of CPU like time base and timers */
        cpu_init_r,
 #endif
-#ifdef CONFIG_PPC
+#if defined(CONFIG_PPC) && !defined(CONFIG_DM_SPI)
        initr_spi,
 #endif
 #ifdef CONFIG_CMD_NAND
index e6daa67..3440e42 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <mapmem.h>
 #include <stdio_dev.h>
 #include <linux/ctype.h>
 #include <linux/types.h>
@@ -633,7 +634,7 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize)
        fdt_set_totalsize(blob, actualsize);
 
        /* Add the new reservation */
-       ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
+       ret = fdt_add_mem_rsv(blob, map_to_sysmem(blob), actualsize);
        if (ret < 0)
                return ret;
 
index 8d39a24..ac901e1 100644 (file)
@@ -165,6 +165,7 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p,
        uint8_t *value;
        int value_len;
        char *algo;
+       const char *padding;
        int required;
        int ret, i;
 
@@ -184,6 +185,10 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p,
                printf(" (required)");
        printf("\n");
 
+       padding = fdt_getprop(fit, noffset, "padding", NULL);
+       if (padding)
+               printf("%s  %s padding: %s\n", p, type, padding);
+
        ret = fit_image_hash_get_value(fit, noffset, &value,
                                       &value_len);
        printf("%s  %s value:   ", p, type);
index 5d860e1..4f6b4ec 100644 (file)
@@ -71,6 +71,19 @@ struct crypto_algo crypto_algos[] = {
 
 };
 
+struct padding_algo padding_algos[] = {
+       {
+               .name = "pkcs-1.5",
+               .verify = padding_pkcs_15_verify,
+       },
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+       {
+               .name = "pss",
+               .verify = padding_pss_verify,
+       }
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
+};
+
 struct checksum_algo *image_get_checksum_algo(const char *full_name)
 {
        int i;
@@ -106,6 +119,21 @@ struct crypto_algo *image_get_crypto_algo(const char *full_name)
        return NULL;
 }
 
+struct padding_algo *image_get_padding_algo(const char *name)
+{
+       int i;
+
+       if (!name)
+               return NULL;
+
+       for (i = 0; i < ARRAY_SIZE(padding_algos); i++) {
+               if (!strcmp(padding_algos[i].name, name))
+                       return &padding_algos[i];
+       }
+
+       return NULL;
+}
+
 /**
  * fit_region_make_list() - Make a list of image regions
  *
@@ -155,6 +183,7 @@ static int fit_image_setup_verify(struct image_sign_info *info,
                char **err_msgp)
 {
        char *algo_name;
+       const char *padding_name;
 
        if (fdt_totalsize(fit) > CONFIG_FIT_SIGNATURE_MAX_SIZE) {
                *err_msgp = "Total size too large";
@@ -165,6 +194,11 @@ static int fit_image_setup_verify(struct image_sign_info *info,
                *err_msgp = "Can't get hash algo property";
                return -1;
        }
+
+       padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+       if (!padding_name)
+               padding_name = RSA_DEFAULT_PADDING_NAME;
+
        memset(info, '\0', sizeof(*info));
        info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
        info->fit = (void *)fit;
@@ -172,6 +206,7 @@ static int fit_image_setup_verify(struct image_sign_info *info,
        info->name = algo_name;
        info->checksum = image_get_checksum_algo(algo_name);
        info->crypto = image_get_crypto_algo(algo_name);
+       info->padding = image_get_padding_algo(padding_name);
        info->fdt_blob = gd_fdt_blob();
        info->required_keynode = required_keynode;
        printf("%s:%s", algo_name, info->keyname);
index 29a60e3..33c6073 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_BOOTDELAY=5
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="run flashboot"
 CONFIG_MISC_INIT_R=y
+CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_HUSH_PARSER=y
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_SYS_PROMPT="S3K> "
@@ -73,3 +74,9 @@ CONFIG_MPC8XX_FEC=y
 CONFIG_SHA256=y
 CONFIG_LZMA=y
 CONFIG_OF_LIBFDT=y
+CONFIG_DM=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="mcr3000"
+CONFIG_WDT=y
+CONFIG_WDT_MPC8xx=y
+CONFIG_DM_SERIAL=y
index a61b13b..05d41ae 100644 (file)
@@ -1,6 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARCH_OMAP2PLUS=y
-CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_AM33XX=y
@@ -39,17 +38,26 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(SPL),128k(SPL.backup1),128k(SPL.backup2),128k(SPL.backup3),1920k(u-boot),-(UBI)"
 CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-baltos"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_SYS_OMAP24_I2C_SPEED=1000
+CONFIG_DM_MMC=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_OMAP_HS_ADMA=y
 CONFIG_NAND=y
+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
+CONFIG_SYS_NAND_U_BOOT_OFFS=0x00080000
 CONFIG_PHY_ADDR_ENABLE=y
-CONFIG_DRIVER_TI_CPSW=y
+CONFIG_PHY_ATHEROS=y
+CONFIG_PHY_SMSC=y
 CONFIG_MII=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
+CONFIG_DM_USB=y
 CONFIG_USB_MUSB_HOST=y
 CONFIG_USB_MUSB_GADGET=y
 CONFIG_USB_MUSB_DSPS=y
@@ -59,7 +67,7 @@ CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
 CONFIG_USB_GADGET_VENDOR_NUM=0x0403
 CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_MASS_STORAGE=y
 CONFIG_USB_ETHER=y
 CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00"
 CONFIG_FAT_WRITE=y
-CONFIG_OF_LIBFDT=y
index cf1fd0b..9e31b4a 100644 (file)
@@ -40,6 +40,7 @@ CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
 CONFIG_SPI=y
index 795f8a3..dd7aed3 100644 (file)
@@ -49,6 +49,7 @@ CONFIG_NAND=y
 CONFIG_NAND_MXC=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
+CONFIG_RTC_M41T62=y
 CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_HOST_ETHER=y
index 0c8e31a..e207df5 100644 (file)
@@ -35,5 +35,6 @@ CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
index 40712a4..149d627 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index f1d150b..8d765e2 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index 72549e2..2d6b86f 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index 7c39268..3525045 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index ef5c944..b68bb7c 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index 7363310..5a8fc04 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_DM_MMC=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
 CONFIG_RENESAS_SDHI=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
index 5a744f4..1a76785 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_FIT=y
 CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
index a928cd4..504eebb 100644 (file)
@@ -41,4 +41,4 @@ CONFIG_PHY_MICREL=y
 CONFIG_MII=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
-# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_EFI_LOADER is not set
index 560776f..0a1e28e 100644 (file)
@@ -41,4 +41,4 @@ CONFIG_PHY_MICREL=y
 CONFIG_MII=y
 CONFIG_DM_SERIAL=y
 CONFIG_FSL_LPUART=y
-# CONFIG_EFI_UNICODE_CAPITALIZATION is not set
+# CONFIG_EFI_LOADER is not set
index c8f5f66..a96f54c 100644 (file)
@@ -52,6 +52,7 @@ CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
+CONFIG_RTC_M41T62=y
 CONFIG_CONS_INDEX=0
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
index faee636..3a12438 100644 (file)
@@ -1,8 +1,6 @@
-iSCSI booting with U-Boot and iPXE
-==================================
+# iSCSI booting with U-Boot and iPXE
 
-Motivation
-----------
+## Motivation
 
 U-Boot has only a reduced set of supported network protocols. The focus for
 network booting has been on UDP based protocols. A TCP stack and HTTP support
@@ -41,8 +39,7 @@ fine grained control of the boot process and can provide a command shell.
 iPXE can be built as an EFI application (named snp.efi) which can be loaded and
 run by U-Boot.
 
-Boot sequence
--------------
+## Boot sequence
 
 U-Boot loads the EFI application iPXE snp.efi using the bootefi command. This
 application has network access via the simple network protocol offered by
@@ -106,19 +103,16 @@ the EFI stub Linux is called as an EFI application::
                                                                       |        |
                                                                       | ~ ~ ~ ~|
 
-Security
---------
+## Security
 
 The iSCSI protocol is not encrypted. The traffic could be secured using IPsec
 but neither U-Boot nor iPXE does support this. So we should at least separate
 the iSCSI traffic from all other network traffic. This can be achieved using a
 virtual local area network (VLAN).
 
-Configuration
--------------
+## Configuration
 
-iPXE
-^^^^
+### iPXE
 
 For running iPXE on arm64 the bin-arm64-efi/snp.efi build target is needed::
 
@@ -157,9 +151,20 @@ following into src/config/local/general.h is sufficient for most use cases::
     #define DOWNLOAD_PROTO_NFS      /* Network File System Protocol */
     #define DOWNLOAD_PROTO_FILE     /* Local file system access */
 
-Links
------
+### Open-iSCSI
+
+When the root file system is on an iSCSI drive you should disable pings and set
+the replacement timer to a high value [3]:
+
+    node.conn[0].timeo.noop_out_interval = 0
+    node.conn[0].timeo.noop_out_timeout = 0
+    node.session.timeo.replacement_timeout = 86400
+
+## Links
 
 * [1](https://ipxe.org) https://ipxe.org - iPXE open source boot firmware
 * [2](https://www.gnu.org/software/grub/) https://www.gnu.org/software/grub/ -
-  GNU GRUB (Grand Unified Bootloader)
+     GNU GRUB (Grand Unified Bootloader)
+* [3](https://github.com/open-iscsi/open-iscsi/blob/master/README)
+     https://github.com/open-iscsi/open-iscsi/blob/master/README -
+     Open-iSCSI README
index a765722..bfff6fd 100644 (file)
@@ -106,6 +106,9 @@ When the image is signed, the following properties are optional:
 
 - comment: Additional information about the signer or image
 
+- padding: The padding algorithm, it may be pkcs-1.5 or pss,
+       if no value is provided we assume pkcs-1.5
+
 For config bindings (see Signed Configurations below), the following
 additional properties are optional:
 
index 0df8b91..2cb53fb 100644 (file)
@@ -11,6 +11,8 @@
 #include <clk-uclass.h>
 #include <div64.h>
 #include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
 #include <dt-bindings/clock/gxbb-clkc.h>
 #include "clk_meson.h"
 
@@ -65,7 +67,7 @@
 #define XTAL_RATE 24000000
 
 struct meson_clk {
-       void __iomem *addr;
+       struct regmap *map;
 };
 
 static ulong meson_div_get_rate(struct clk *clk, unsigned long id);
@@ -217,8 +219,8 @@ static int meson_set_gate_by_id(struct clk *clk, unsigned long id, bool on)
 
        debug("%s: really %sabling %ld\n", __func__, on ? "en" : "dis", id);
 
-       clrsetbits_le32(priv->addr + gate->reg,
-                       BIT(gate->bit), on ? BIT(gate->bit) : 0);
+       regmap_update_bits(priv->map, gate->reg,
+                          BIT(gate->bit), on ? BIT(gate->bit) : 0);
 
        /* Propagate to next gate(s) */
        switch (id) {
@@ -269,7 +271,7 @@ static ulong meson_div_get_rate(struct clk *clk, unsigned long id)
        unsigned int rate, parent_rate;
        struct parm *parm;
        int parent;
-       u32 reg;
+       uint reg;
 
        switch (id) {
        case CLKID_VPU_0_DIV:
@@ -292,7 +294,7 @@ static ulong meson_div_get_rate(struct clk *clk, unsigned long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + parm->reg_off);
+       regmap_read(priv->map, parm->reg_off, &reg);
        reg = PARM_GET(parm->width, parm->shift, reg);
 
        debug("%s: div of %ld is %d\n", __func__, id, reg + 1);
@@ -318,7 +320,6 @@ static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
        unsigned long parent_rate;
        struct parm *parm;
        int parent;
-       u32 reg;
        int ret;
 
        if (current_rate == rate)
@@ -383,9 +384,8 @@ static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate,
 
        debug("%s: setting div of %ld to %d\n", __func__, id, new_div);
 
-       reg = readl(priv->addr + parm->reg_off);
-       writel(PARM_SET(parm->width, parm->shift, reg, new_div - 1),
-              priv->addr + parm->reg_off);
+       regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
+                          (new_div - 1) << parm->shift);
 
        debug("%s: new rate of %ld is %ld\n",
              __func__, id, meson_div_get_rate(clk, id));
@@ -446,7 +446,7 @@ static ulong meson_mux_get_parent(struct clk *clk, unsigned long id)
        struct meson_clk *priv = dev_get_priv(clk->dev);
        struct parm *parm;
        int *parents;
-       u32 reg;
+       uint reg;
 
        switch (id) {
        case CLKID_VPU:
@@ -477,7 +477,7 @@ static ulong meson_mux_get_parent(struct clk *clk, unsigned long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + parm->reg_off);
+       regmap_read(priv->map, parm->reg_off, &reg);
        reg = PARM_GET(parm->width, parm->shift, reg);
 
        debug("%s: parent of %ld is %d (%d)\n",
@@ -494,7 +494,6 @@ static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
        unsigned int new_index = -EINVAL;
        struct parm *parm;
        int *parents;
-       u32 reg;
        int i;
 
        if (IS_ERR_VALUE(cur_parent))
@@ -546,9 +545,8 @@ static ulong meson_mux_set_parent(struct clk *clk, unsigned long id,
 
        debug("%s: new index of %ld is %d\n", __func__, id, new_index);
 
-       reg = readl(priv->addr + parm->reg_off);
-       writel(PARM_SET(parm->width, parm->shift, reg, new_index),
-              priv->addr + parm->reg_off);
+       regmap_update_bits(priv->map, parm->reg_off, SETPMASK(parm->width, parm->shift),
+                          new_index << parm->shift);
 
        debug("%s: new parent of %ld is %ld\n",
              __func__, id, meson_mux_get_parent(clk, id));
@@ -570,7 +568,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk)
 {
        struct meson_clk *priv = dev_get_priv(clk->dev);
        unsigned long parent_rate;
-       u32 reg;
+       uint reg;
        int parents[] = {
                -1,
                -1,
@@ -583,7 +581,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk)
        };
 
        /* mux */
-       reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+       regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
        reg = (reg >> 12) & 7;
 
        switch (reg) {
@@ -597,7 +595,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk)
        }
 
        /* divider */
-       reg = readl(priv->addr + HHI_MPEG_CLK_CNTL);
+       regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
        reg = reg & ((1 << 7) - 1);
 
        /* clk81 divider is zero based */
@@ -641,8 +639,9 @@ static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
 {
        struct meson_clk *priv = dev_get_priv(clk->dev);
        struct parm *psdm, *pn2;
-       unsigned long reg, sdm, n2;
+       unsigned long sdm, n2;
        unsigned long parent_rate;
+       uint reg;
 
        switch (id) {
        case CLKID_MPLL0:
@@ -665,10 +664,10 @@ static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
        if (IS_ERR_VALUE(parent_rate))
                return parent_rate;
 
-       reg = readl(priv->addr + psdm->reg_off);
+       regmap_read(priv->map, psdm->reg_off, &reg);
        sdm = PARM_GET(psdm->width, psdm->shift, reg);
 
-       reg = readl(priv->addr + pn2->reg_off);
+       regmap_read(priv->map, pn2->reg_off, &reg);
        n2 = PARM_GET(pn2->width, pn2->shift, reg);
 
        return mpll_rate_from_params(parent_rate, sdm, n2);
@@ -692,7 +691,7 @@ static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
        struct parm *pm, *pn, *pod;
        unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
        u16 n, m, od;
-       u32 reg;
+       uint reg;
 
        switch (id) {
        case CLKID_FIXED_PLL:
@@ -709,13 +708,13 @@ static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
                return -ENOENT;
        }
 
-       reg = readl(priv->addr + pn->reg_off);
+       regmap_read(priv->map, pn->reg_off, &reg);
        n = PARM_GET(pn->width, pn->shift, reg);
 
-       reg = readl(priv->addr + pm->reg_off);
+       regmap_read(priv->map, pm->reg_off, &reg);
        m = PARM_GET(pm->width, pm->shift, reg);
 
-       reg = readl(priv->addr + pod->reg_off);
+       regmap_read(priv->map, pod->reg_off, &reg);
        od = PARM_GET(pod->width, pod->shift, reg);
 
        return ((parent_rate_mhz * m / n) >> od) * 1000000;
@@ -876,8 +875,8 @@ static ulong meson_clk_set_rate(struct clk *clk, ulong rate)
        if (IS_ERR_VALUE(ret))
                return ret;
 
-       printf("clock %lu has new rate %lu\n", clk->id,
-              meson_clk_get_rate_by_id(clk, clk->id));
+       debug("clock %lu has new rate %lu\n", clk->id,
+             meson_clk_get_rate_by_id(clk, clk->id));
 
        return 0;
 }
@@ -886,9 +885,11 @@ static int meson_clk_probe(struct udevice *dev)
 {
        struct meson_clk *priv = dev_get_priv(dev);
 
-       priv->addr = dev_read_addr_ptr(dev);
+       priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+       if (IS_ERR(priv->map))
+               return PTR_ERR(priv->map);
 
-       debug("meson-clk: probed at addr %p\n", priv->addr);
+       debug("meson-clk: probed\n");
 
        return 0;
 }
index 99698b1..0529fc8 100644 (file)
@@ -107,7 +107,7 @@ static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
        return renesas_clk_get_parent(clk, info, parent);
 }
 
-static int gen3_clk_setup_sdif_div(struct clk *clk)
+static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
 {
        struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
        struct cpg_mssr_info *info = priv->info;
@@ -133,7 +133,7 @@ static int gen3_clk_setup_sdif_div(struct clk *clk)
 
        debug("%s[%i] SDIF offset=%x\n", __func__, __LINE__, core->offset);
 
-       writel(1, priv->base + core->offset);
+       writel((rate == 400000000) ? 0x4 : 0x1, priv->base + core->offset);
 
        return 0;
 }
@@ -141,10 +141,6 @@ static int gen3_clk_setup_sdif_div(struct clk *clk)
 static int gen3_clk_enable(struct clk *clk)
 {
        struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
-       int ret = gen3_clk_setup_sdif_div(clk);
-
-       if (ret)
-               return ret;
 
        return renesas_clk_endisable(clk, priv->base, true);
 }
@@ -328,7 +324,7 @@ static ulong gen3_clk_get_rate(struct clk *clk)
 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
 {
        /* Force correct SD-IF divider configuration if applicable */
-       gen3_clk_setup_sdif_div(clk);
+       gen3_clk_setup_sdif_div(clk, rate);
        return gen3_clk_get_rate64(clk);
 }
 
index 2cb35f3..c8c47ac 100644 (file)
@@ -9,31 +9,38 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/lists.h>
+#include <efi_loader.h>
 #include <linux/libfdt.h>
 #include <linux/arm-smccc.h>
 #include <linux/errno.h>
 #include <linux/printk.h>
 #include <linux/psci.h>
 
-psci_fn *invoke_psci_fn;
+#define DRIVER_NAME "psci"
 
-static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
-                       unsigned long arg0, unsigned long arg1,
-                       unsigned long arg2)
-{
-       struct arm_smccc_res res;
+#define PSCI_METHOD_HVC 1
+#define PSCI_METHOD_SMC 2
 
-       arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
-       return res.a0;
-}
+int __efi_runtime_data psci_method;
 
-static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
-                       unsigned long arg0, unsigned long arg1,
-                       unsigned long arg2)
+unsigned long __efi_runtime invoke_psci_fn
+               (unsigned long function_id, unsigned long arg0,
+                unsigned long arg1, unsigned long arg2)
 {
        struct arm_smccc_res res;
 
-       arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+       /*
+        * In the __efi_runtime we need to avoid the switch statement. In some
+        * cases the compiler creates lookup tables to implement switch. These
+        * tables are not correctly relocated when SetVirtualAddressMap is
+        * called.
+        */
+       if (psci_method == PSCI_METHOD_SMC)
+               arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+       else if (psci_method == PSCI_METHOD_HVC)
+               arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+       else
+               res.a0 = PSCI_RET_DISABLED;
        return res.a0;
 }
 
@@ -67,9 +74,9 @@ static int psci_probe(struct udevice *dev)
        }
 
        if (!strcmp("hvc", method)) {
-               invoke_psci_fn = __invoke_psci_fn_hvc;
+               psci_method = PSCI_METHOD_HVC;
        } else if (!strcmp("smc", method)) {
-               invoke_psci_fn = __invoke_psci_fn_smc;
+               psci_method = PSCI_METHOD_SMC;
        } else {
                pr_warn("invalid \"method\" property: %s\n", method);
                return -EINVAL;
@@ -78,6 +85,67 @@ static int psci_probe(struct udevice *dev)
        return 0;
 }
 
+/**
+ * void do_psci_probe() - probe PSCI firmware driver
+ *
+ * Ensure that psci_method is initialized.
+ */
+static void __maybe_unused do_psci_probe(void)
+{
+       struct udevice *dev;
+
+       uclass_get_device_by_name(UCLASS_FIRMWARE, DRIVER_NAME, &dev);
+}
+
+#if IS_ENABLED(CONFIG_EFI_LOADER) && IS_ENABLED(CONFIG_PSCI_RESET)
+efi_status_t efi_reset_system_init(void)
+{
+       do_psci_probe();
+       return EFI_SUCCESS;
+}
+
+void __efi_runtime EFIAPI efi_reset_system(enum efi_reset_type reset_type,
+                                          efi_status_t reset_status,
+                                          unsigned long data_size,
+                                          void *reset_data)
+{
+       if (reset_type == EFI_RESET_COLD ||
+           reset_type == EFI_RESET_WARM ||
+           reset_type == EFI_RESET_PLATFORM_SPECIFIC) {
+               invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+       } else if (reset_type == EFI_RESET_SHUTDOWN) {
+               invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+       }
+       while (1)
+               ;
+}
+#endif /* IS_ENABLED(CONFIG_EFI_LOADER) && IS_ENABLED(CONFIG_PSCI_RESET) */
+
+#ifdef CONFIG_PSCI_RESET
+void reset_misc(void)
+{
+       do_psci_probe();
+       invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+#endif /* CONFIG_PSCI_RESET */
+
+#ifdef CONFIG_CMD_POWEROFF
+int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       do_psci_probe();
+
+       puts("poweroff ...\n");
+       udelay(50000); /* wait 50 ms */
+
+       disable_interrupts();
+       invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+       enable_interrupts();
+
+       log_err("Power off not supported on this platform\n");
+       return CMD_RET_FAILURE;
+}
+#endif
+
 static const struct udevice_id psci_of_match[] = {
        { .compatible = "arm,psci" },
        { .compatible = "arm,psci-0.2" },
@@ -86,7 +154,7 @@ static const struct udevice_id psci_of_match[] = {
 };
 
 U_BOOT_DRIVER(psci) = {
-       .name = "psci",
+       .name = DRIVER_NAME,
        .id = UCLASS_FIRMWARE,
        .of_match = psci_of_match,
        .bind = psci_bind,
index f73f072..76225b7 100644 (file)
@@ -166,6 +166,10 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
                cfg->host_caps |= MMC_CAP(MMC_HS_200);
        if (dev_read_bool(dev, "mmc-hs200-1_2v"))
                cfg->host_caps |= MMC_CAP(MMC_HS_200);
+       if (dev_read_bool(dev, "mmc-hs400-1_8v"))
+               cfg->host_caps |= MMC_CAP(MMC_HS_400);
+       if (dev_read_bool(dev, "mmc-hs400-1_2v"))
+               cfg->host_caps |= MMC_CAP(MMC_HS_400);
 
        return 0;
 }
index e7f96f8..733b6d6 100644 (file)
@@ -17,7 +17,9 @@
 
 #include "tmio-common.h"
 
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
 
 /* SCC registers */
 #define RENESAS_SDHI_SCC_DTCNTL                        0x800
@@ -107,6 +109,56 @@ static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv)
        tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
 }
 
+static int renesas_sdhi_hs400(struct udevice *dev)
+{
+       struct tmio_sd_priv *priv = dev_get_priv(dev);
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+       bool hs400 = (mmc->selected_mode == MMC_HS_400);
+       int ret, taps = hs400 ? priv->nrtaps : 8;
+       u32 reg;
+
+       if (taps == 4)  /* HS400 on 4tap SoC needs different clock */
+               ret = clk_set_rate(&priv->clk, 400000000);
+       else
+               ret = clk_set_rate(&priv->clk, 200000000);
+       if (ret < 0)
+               return ret;
+
+       tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ);
+
+       reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_TMPPORT2);
+       if (hs400) {
+               reg |= RENESAS_SDHI_SCC_TMPPORT2_HS400EN |
+                      RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL;
+       } else {
+               reg &= ~(RENESAS_SDHI_SCC_TMPPORT2_HS400EN |
+                      RENESAS_SDHI_SCC_TMPPORT2_HS400OSEL);
+       }
+
+       tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_TMPPORT2);
+
+       tmio_sd_writel(priv, (taps << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) |
+                            RENESAS_SDHI_SCC_DTCNTL_TAPEN,
+                            RENESAS_SDHI_SCC_DTCNTL);
+
+       if (taps == 4) {
+               tmio_sd_writel(priv, priv->tap_set >> 1,
+                              RENESAS_SDHI_SCC_TAPSET);
+       } else {
+               tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET);
+       }
+
+       reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL);
+       reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL;
+       tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL);
+
+       reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
+       reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN;
+       tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL);
+
+       return 0;
+}
+
 static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv,
                                       unsigned long tap)
 {
@@ -125,7 +177,6 @@ static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv,
                                     unsigned int smpcmp)
 {
        unsigned long tap_cnt;  /* counter of tuning success */
-       unsigned long tap_set;  /* tap position */
        unsigned long tap_start;/* start position of tuning success */
        unsigned long tap_end;  /* end position of tuning success */
        unsigned long ntap;     /* temporary counter of tuning success */
@@ -209,12 +260,12 @@ static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv,
                select = true;
 
        if (select)
-               tap_set = ((tap_start + tap_end) / 2) % tap_num;
+               priv->tap_set = ((tap_start + tap_end) / 2) % tap_num;
        else
                return -EIO;
 
        /* Set SCC */
-       tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET);
+       tmio_sd_writel(priv, priv->tap_set, RENESAS_SDHI_SCC_TAPSET);
 
        /* Enable auto re-tuning */
        reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL);
@@ -240,6 +291,7 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode)
 
        /* clock tuning is not needed for upto 52MHz */
        if (!((mmc->selected_mode == MMC_HS_200) ||
+             (mmc->selected_mode == MMC_HS_400) ||
              (mmc->selected_mode == UHS_SDR104) ||
              (mmc->selected_mode == UHS_SDR50)))
                return 0;
@@ -287,19 +339,42 @@ out:
 
        return ret;
 }
+#else
+static int renesas_sdhi_hs400(struct udevice *dev)
+{
+       return 0;
+}
 #endif
 
 static int renesas_sdhi_set_ios(struct udevice *dev)
 {
-       int ret = tmio_sd_set_ios(dev);
+       struct tmio_sd_priv *priv = dev_get_priv(dev);
+       u32 tmp;
+       int ret;
 
-       mdelay(10);
+       /* Stop the clock before changing its rate to avoid a glitch signal */
+       tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
+       tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+       tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
-       struct tmio_sd_priv *priv = dev_get_priv(dev);
+       ret = renesas_sdhi_hs400(dev);
+       if (ret)
+               return ret;
+
+       ret = tmio_sd_set_ios(dev);
 
-       if (priv->caps & TMIO_SD_CAP_RCAR_UHS)
+       mdelay(10);
+
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+       struct mmc *mmc = mmc_get_mmc_dev(dev);
+       if ((priv->caps & TMIO_SD_CAP_RCAR_UHS) &&
+           (mmc->selected_mode != UHS_SDR104) &&
+           (mmc->selected_mode != MMC_HS_200) &&
+           (mmc->selected_mode != MMC_HS_400)) {
                renesas_sdhi_reset_tuning(priv);
+       }
 #endif
 
        return ret;
@@ -331,7 +406,9 @@ static const struct dm_mmc_ops renesas_sdhi_ops = {
        .send_cmd = tmio_sd_send_cmd,
        .set_ios = renesas_sdhi_set_ios,
        .get_cd = tmio_sd_get_cd,
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
        .execute_tuning = renesas_sdhi_execute_tuning,
 #endif
 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
@@ -358,15 +435,45 @@ static const struct udevice_id renesas_sdhi_match[] = {
        { /* sentinel */ }
 };
 
+static ulong renesas_sdhi_clk_get_rate(struct tmio_sd_priv *priv)
+{
+       return clk_get_rate(&priv->clk);
+}
+
+static void renesas_sdhi_filter_caps(struct udevice *dev)
+{
+       struct tmio_sd_plat *plat = dev_get_platdata(dev);
+       struct tmio_sd_priv *priv = dev_get_priv(dev);
+
+       if (!(priv->caps & TMIO_SD_CAP_RCAR_GEN3))
+               return;
+
+       /* HS400 is not supported on H3 ES1.x and M3W ES1.0,ES1.1 */
+       if (((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) &&
+           (rmobile_get_cpu_rev_integer() <= 1)) ||
+           ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7796) &&
+           (rmobile_get_cpu_rev_integer() == 1) &&
+           (rmobile_get_cpu_rev_fraction() <= 1)))
+               plat->cfg.host_caps &= ~MMC_MODE_HS400;
+
+       /* H3 ES2.0 uses 4 tuning taps */
+       if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A7795) &&
+           (rmobile_get_cpu_rev_integer() == 2))
+               priv->nrtaps = 4;
+       else
+               priv->nrtaps = 8;
+}
+
 static int renesas_sdhi_probe(struct udevice *dev)
 {
        struct tmio_sd_priv *priv = dev_get_priv(dev);
        u32 quirks = dev_get_driver_data(dev);
        struct fdt_resource reg_res;
-       struct clk clk;
        DECLARE_GLOBAL_DATA_PTR;
        int ret;
 
+       priv->clk_get_rate = renesas_sdhi_clk_get_rate;
+
        if (quirks == RENESAS_GEN2_QUIRKS) {
                ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev),
                                       "reg", 0, &reg_res);
@@ -380,29 +487,33 @@ static int renesas_sdhi_probe(struct udevice *dev)
                        quirks |= TMIO_SD_CAP_16BIT;
        }
 
-       ret = clk_get_by_index(dev, 0, &clk);
+       ret = clk_get_by_index(dev, 0, &priv->clk);
        if (ret < 0) {
                dev_err(dev, "failed to get host clock\n");
                return ret;
        }
 
        /* set to max rate */
-       priv->mclk = clk_set_rate(&clk, ULONG_MAX);
-       if (IS_ERR_VALUE(priv->mclk)) {
+       ret = clk_set_rate(&priv->clk, 200000000);
+       if (ret < 0) {
                dev_err(dev, "failed to set rate for host clock\n");
-               clk_free(&clk);
-               return priv->mclk;
+               clk_free(&priv->clk);
+               return ret;
        }
 
-       ret = clk_enable(&clk);
-       clk_free(&clk);
+       ret = clk_enable(&priv->clk);
        if (ret) {
                dev_err(dev, "failed to enable host clock\n");
                return ret;
        }
 
        ret = tmio_sd_probe(dev, quirks);
-#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+
+       renesas_sdhi_filter_caps(dev);
+
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
        if (!ret && (priv->caps & TMIO_SD_CAP_RCAR_UHS))
                renesas_sdhi_reset_tuning(priv);
 #endif
index 0eca83a..2014920 100644 (file)
@@ -555,55 +555,76 @@ static void tmio_sd_set_ddr_mode(struct tmio_sd_priv *priv,
        tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE);
 }
 
-static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv,
-                                    struct mmc *mmc)
+static ulong tmio_sd_clk_get_rate(struct tmio_sd_priv *priv)
 {
-       unsigned int divisor;
-       u32 val, tmp;
+       return priv->clk_get_rate(priv);
+}
 
-       if (!mmc->clock)
-               return;
-
-       divisor = DIV_ROUND_UP(priv->mclk, mmc->clock);
-
-       if (divisor <= 1)
-               val = (priv->caps & TMIO_SD_CAP_RCAR) ?
-                     TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1;
-       else if (divisor <= 2)
-               val = TMIO_SD_CLKCTL_DIV2;
-       else if (divisor <= 4)
-               val = TMIO_SD_CLKCTL_DIV4;
-       else if (divisor <= 8)
-               val = TMIO_SD_CLKCTL_DIV8;
-       else if (divisor <= 16)
-               val = TMIO_SD_CLKCTL_DIV16;
-       else if (divisor <= 32)
-               val = TMIO_SD_CLKCTL_DIV32;
-       else if (divisor <= 64)
-               val = TMIO_SD_CLKCTL_DIV64;
-       else if (divisor <= 128)
-               val = TMIO_SD_CLKCTL_DIV128;
-       else if (divisor <= 256)
-               val = TMIO_SD_CLKCTL_DIV256;
-       else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024))
-               val = TMIO_SD_CLKCTL_DIV512;
-       else
-               val = TMIO_SD_CLKCTL_DIV1024;
+static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv, struct mmc *mmc)
+{
+       unsigned int divisor;
+       u32 tmp, val = 0;
+       ulong mclk;
+
+       if (mmc->clock) {
+               mclk = tmio_sd_clk_get_rate(priv);
+
+               divisor = DIV_ROUND_UP(mclk, mmc->clock);
+
+               /* Do not set divider to 0xff in DDR mode */
+               if (mmc->ddr_mode && (divisor == 1))
+                       divisor = 2;
+
+               if (divisor <= 1)
+                       val = (priv->caps & TMIO_SD_CAP_RCAR) ?
+                             TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1;
+               else if (divisor <= 2)
+                       val = TMIO_SD_CLKCTL_DIV2;
+               else if (divisor <= 4)
+                       val = TMIO_SD_CLKCTL_DIV4;
+               else if (divisor <= 8)
+                       val = TMIO_SD_CLKCTL_DIV8;
+               else if (divisor <= 16)
+                       val = TMIO_SD_CLKCTL_DIV16;
+               else if (divisor <= 32)
+                       val = TMIO_SD_CLKCTL_DIV32;
+               else if (divisor <= 64)
+                       val = TMIO_SD_CLKCTL_DIV64;
+               else if (divisor <= 128)
+                       val = TMIO_SD_CLKCTL_DIV128;
+               else if (divisor <= 256)
+                       val = TMIO_SD_CLKCTL_DIV256;
+               else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024))
+                       val = TMIO_SD_CLKCTL_DIV512;
+               else
+                       val = TMIO_SD_CLKCTL_DIV1024;
+       }
 
        tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL);
-       if (tmp & TMIO_SD_CLKCTL_SCLKEN &&
-           (tmp & TMIO_SD_CLKCTL_DIV_MASK) == val)
-               return;
+       if (mmc->clock &&
+           !((tmp & TMIO_SD_CLKCTL_SCLKEN) &&
+             ((tmp & TMIO_SD_CLKCTL_DIV_MASK) == val))) {
+               /*
+                * Stop the clock before changing its rate
+                * to avoid a glitch signal
+                */
+               tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+               tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
-       /* stop the clock before changing its rate to avoid a glitch signal */
-       tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
-       tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
+               /* Change the clock rate. */
+               tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
+               tmp |= val;
+       }
 
-       tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
-       tmp |= val | TMIO_SD_CLKCTL_OFFEN;
-       tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
+       /* Enable or Disable the clock */
+       if (mmc->clk_disable) {
+               tmp |= TMIO_SD_CLKCTL_OFFEN;
+               tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+       } else {
+               tmp &= ~TMIO_SD_CLKCTL_OFFEN;
+               tmp |= TMIO_SD_CLKCTL_SCLKEN;
+       }
 
-       tmp |= TMIO_SD_CLKCTL_SCLKEN;
        tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
        udelay(1000);
@@ -708,6 +729,7 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
        struct tmio_sd_priv *priv = dev_get_priv(dev);
        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
        fdt_addr_t base;
+       ulong mclk;
        int ret;
 
        base = devfdt_get_addr(dev);
@@ -750,10 +772,12 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
 
        tmio_sd_host_init(priv);
 
+       mclk = tmio_sd_clk_get_rate(priv);
+
        plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
-       plat->cfg.f_min = priv->mclk /
+       plat->cfg.f_min = mclk /
                        (priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
-       plat->cfg.f_max = priv->mclk;
+       plat->cfg.f_max = mclk;
        plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
 
        upriv->mmc = &plat->mmc;
index 792b1ba..192026c 100644 (file)
@@ -117,7 +117,6 @@ struct tmio_sd_plat {
 
 struct tmio_sd_priv {
        void __iomem                    *regbase;
-       unsigned long                   mclk;
        unsigned int                    version;
        u32                             caps;
 #define TMIO_SD_CAP_NONREMOVABLE       BIT(0)  /* Nonremovable e.g. eMMC */
@@ -133,6 +132,14 @@ struct tmio_sd_priv {
 #ifdef CONFIG_DM_REGULATOR
        struct udevice *vqmmc_dev;
 #endif
+#if CONFIG_IS_ENABLED(CLK)
+       struct clk                      clk;
+#endif
+#if CONFIG_IS_ENABLED(RENESAS_SDHI)
+       u8                              tap_set;
+       u8                              nrtaps;
+#endif
+       ulong (*clk_get_rate)(struct tmio_sd_priv *);
 };
 
 int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
index 813c284..6539880 100644 (file)
@@ -31,35 +31,45 @@ static const struct udevice_id uniphier_sd_match[] = {
        { /* sentinel */ }
 };
 
+static ulong uniphier_sd_clk_get_rate(struct tmio_sd_priv *priv)
+{
+#if CONFIG_IS_ENABLED(CLK)
+       return clk_get_rate(&priv->clk);
+#elif CONFIG_SPL_BUILD
+       return 100000000;
+#else
+       return 0;
+#endif
+}
+
 static int uniphier_sd_probe(struct udevice *dev)
 {
        struct tmio_sd_priv *priv = dev_get_priv(dev);
+
+       priv->clk_get_rate = uniphier_sd_clk_get_rate;
+
 #ifndef CONFIG_SPL_BUILD
-       struct clk clk;
        int ret;
 
-       ret = clk_get_by_index(dev, 0, &clk);
+       ret = clk_get_by_index(dev, 0, &priv->clk);
        if (ret < 0) {
                dev_err(dev, "failed to get host clock\n");
                return ret;
        }
 
        /* set to max rate */
-       priv->mclk = clk_set_rate(&clk, ULONG_MAX);
-       if (IS_ERR_VALUE(priv->mclk)) {
+       ret = clk_set_rate(&priv->clk, ULONG_MAX);
+       if (ret < 0) {
                dev_err(dev, "failed to set rate for host clock\n");
-               clk_free(&clk);
-               return priv->mclk;
+               clk_free(&priv->clk);
+               return ret;
        }
 
-       ret = clk_enable(&clk);
-       clk_free(&clk);
+       ret = clk_enable(&priv->clk);
        if (ret) {
                dev_err(dev, "failed to enable host clock\n");
                return ret;
        }
-#else
-       priv->mclk = 100000000;
 #endif
 
        return tmio_sd_probe(dev, 0);
index 6038b43..fd0009b 100644 (file)
@@ -104,4 +104,10 @@ config RTC_MC146818
          clock with a wide array of features and 50 bytes of general-purpose,
          battery-backed RAM. The driver supports access to the clock and RAM.
 
+config RTC_M41T62
+       bool "Enable M41T62 driver"
+       help
+         Enable driver for ST's M41T62 compatible RTC devices (like RV-4162).
+         It is a serial (I2C) real-time clock (RTC) with alarm.
+
 endmenu
index 1374383..2ee7e00 100644 (file)
@@ -1,5 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
+ * (C) Copyright 2018
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de.
+ *
  * (C) Copyright 2008
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
@@ -15,6 +18,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <rtc.h>
 #include <i2c.h>
 
 
 #define M41T80_ALHOUR_HT       (1 << 6)        /* HT: Halt Update Bit */
 
-int rtc_get(struct rtc_time *tm)
+static void m41t62_update_rtc_time(struct rtc_time *tm, u8 *buf)
 {
-       u8 buf[M41T62_DATETIME_REG_SIZE];
-
-       i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
-
        debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
              "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
              __FUNCTION__,
@@ -77,20 +77,14 @@ int rtc_get(struct rtc_time *tm)
              __FUNCTION__,
              tm->tm_sec, tm->tm_min, tm->tm_hour,
              tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-
-       return 0;
 }
 
-int rtc_set(struct rtc_time *tm)
+static void m41t62_set_rtc_buf(const struct rtc_time *tm, u8 *buf)
 {
-       u8 buf[M41T62_DATETIME_REG_SIZE];
-
        debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
              tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
              tm->tm_hour, tm->tm_min, tm->tm_sec);
 
-       i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
-
        /* Merge time-data and register flags into buf[0..7] */
        buf[M41T62_REG_SSEC] = 0;
        buf[M41T62_REG_SEC] =
@@ -107,8 +101,99 @@ int rtc_set(struct rtc_time *tm)
                bin2bcd(tm->tm_mon) | (buf[M41T62_REG_MON] & ~0x1f);
        /* assume 20YY not 19YY */
        buf[M41T62_REG_YEAR] = bin2bcd(tm->tm_year % 100);
+}
+
+#ifdef CONFIG_DM_RTC
+static int m41t62_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+       u8 buf[M41T62_DATETIME_REG_SIZE];
+       int ret;
+
+       ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
+       if (ret)
+               return ret;
+
+       m41t62_update_rtc_time(tm, buf);
+
+       return 0;
+}
+
+static int m41t62_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+       u8 buf[M41T62_DATETIME_REG_SIZE];
+       int ret;
+
+       ret = dm_i2c_read(dev, 0, buf, sizeof(buf));
+       if (ret)
+               return ret;
+
+       m41t62_set_rtc_buf(tm, buf);
+
+       ret = dm_i2c_write(dev, 0, buf, sizeof(buf));
+       if (ret) {
+               printf("I2C write failed in %s()\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int m41t62_rtc_reset(struct udevice *dev)
+{
+       u8 val;
+
+       /*
+        * M41T82: Make sure HT (Halt Update) bit is cleared.
+        * This bit is 0 in M41T62 so its save to clear it always.
+        */
+
+       int ret = dm_i2c_read(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val));
+
+       val &= ~M41T80_ALHOUR_HT;
+       ret |= dm_i2c_write(dev, M41T62_REG_ALARM_HOUR, &val, sizeof(val));
+
+       return ret;
+}
+
+static const struct rtc_ops m41t62_rtc_ops = {
+       .get = m41t62_rtc_get,
+       .set = m41t62_rtc_set,
+       .reset = m41t62_rtc_reset,
+};
+
+static const struct udevice_id m41t62_rtc_ids[] = {
+       { .compatible = "st,m41t62" },
+       { .compatible = "microcrystal,rv4162" },
+       { }
+};
+
+U_BOOT_DRIVER(rtc_m41t62) = {
+       .name   = "rtc-m41t62",
+       .id     = UCLASS_RTC,
+       .of_match = m41t62_rtc_ids,
+       .ops    = &m41t62_rtc_ops,
+};
+
+#else /* NON DM RTC code - will be removed */
+int rtc_get(struct rtc_time *tm)
+{
+       u8 buf[M41T62_DATETIME_REG_SIZE];
+
+       i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+       m41t62_update_rtc_time(tm, buf);
+
+       return 0;
+}
+
+int rtc_set(struct rtc_time *tm)
+{
+       u8 buf[M41T62_DATETIME_REG_SIZE];
+
+       i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE);
+       m41t62_set_rtc_buf(tm, buf);
 
-       if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf, M41T62_DATETIME_REG_SIZE)) {
+       if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 1, buf,
+                     M41T62_DATETIME_REG_SIZE)) {
                printf("I2C write failed in %s()\n", __func__);
                return -1;
        }
@@ -128,3 +213,4 @@ void rtc_reset(void)
        val &= ~M41T80_ALHOUR_HT;
        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
 }
+#endif /* CONFIG_DM_RTC */
index c499601..09365ba 100644 (file)
@@ -119,7 +119,6 @@ U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
 serial_initfunc(atmel_serial_initialize);
 serial_initfunc(mcf_serial_initialize);
 serial_initfunc(mpc85xx_serial_initialize);
-serial_initfunc(mpc8xx_serial_initialize);
 serial_initfunc(mxc_serial_initialize);
 serial_initfunc(ns16550_serial_initialize);
 serial_initfunc(pl01x_serial_initialize);
@@ -173,7 +172,6 @@ void serial_initialize(void)
        atmel_serial_initialize();
        mcf_serial_initialize();
        mpc85xx_serial_initialize();
-       mpc8xx_serial_initialize();
        mxc_serial_initialize();
        ns16550_serial_initialize();
        pl01x_serial_initialize();
index 292912b..50d6e70 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <serial.h>
 #include <watchdog.h>
 #include <asm/cpm_8xx.h>
@@ -35,9 +36,9 @@ struct serialbuffer {
        uchar   txbuf;  /* tx buffers */
 };
 
-static void serial_setdivisor(cpm8xx_t __iomem *cp)
+static void serial_setdivisor(cpm8xx_t __iomem *cp, int baudrate)
 {
-       int divisor = (gd->cpu_clk + 8 * gd->baudrate) / 16 / gd->baudrate;
+       int divisor = (gd->cpu_clk + 8 * baudrate) / 16 / baudrate;
 
        if (divisor / 16 > 0x1000) {
                /* bad divisor, assume 50MHz clock and 9600 baud */
@@ -58,7 +59,7 @@ static void serial_setdivisor(cpm8xx_t __iomem *cp)
  * as serial console interface.
  */
 
-static void smc_setbrg(void)
+static int serial_mpc8xx_setbrg(struct udevice *dev, int baudrate)
 {
        immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t __iomem *cp = &(im->im_cpm);
@@ -71,10 +72,12 @@ static void smc_setbrg(void)
 
        out_be32(&cp->cp_simode, 0);
 
-       serial_setdivisor(cp);
+       serial_setdivisor(cp, baudrate);
+
+       return 0;
 }
 
-static int smc_init(void)
+static int serial_mpc8xx_probe(struct udevice *dev)
 {
        immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
        smc_t __iomem *sp;
@@ -139,7 +142,7 @@ static int smc_init(void)
        out_8(&sp->smc_smce, 0xff);
 
        /* Set up the baud rate generator */
-       smc_setbrg();
+       serial_mpc8xx_setbrg(dev, gd->baudrate);
 
        /* Make the first buffer the only buffer. */
        setbits_be16(&rtx->txbd.cbd_sc, BD_SC_WRAP);
@@ -166,14 +169,14 @@ static int smc_init(void)
        return 0;
 }
 
-static void smc_putc(const char c)
+static int serial_mpc8xx_putc(struct udevice *dev, const char c)
 {
        immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t        __iomem *cpmp = &(im->im_cpm);
        struct serialbuffer     __iomem *rtx;
 
        if (c == '\n')
-               smc_putc('\r');
+               serial_mpc8xx_putc(dev, '\r');
 
        rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];
 
@@ -184,15 +187,11 @@ static void smc_putc(const char c)
 
        while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY)
                WATCHDOG_RESET();
-}
 
-static void smc_puts(const char *s)
-{
-       while (*s)
-               smc_putc(*s++);
+       return 0;
 }
 
-static int smc_getc(void)
+static int serial_mpc8xx_getc(struct udevice *dev)
 {
        immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t        __iomem *cpmp = &(im->im_cpm);
@@ -222,34 +221,37 @@ static int smc_getc(void)
        return c;
 }
 
-static int smc_tstc(void)
+static int serial_mpc8xx_pending(struct udevice *dev, bool input)
 {
        immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t        __iomem *cpmp = &(im->im_cpm);
        struct serialbuffer     __iomem *rtx;
 
+       if (!input)
+               return 0;
+
        rtx = (struct serialbuffer __iomem *)&cpmp->cp_dpmem[CPM_SERIAL_BASE];
 
        return !(in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY);
 }
 
-struct serial_device serial_smc_device = {
-       .name   = "serial_smc",
-       .start  = smc_init,
-       .stop   = NULL,
-       .setbrg = smc_setbrg,
-       .getc   = smc_getc,
-       .tstc   = smc_tstc,
-       .putc   = smc_putc,
-       .puts   = smc_puts,
+static const struct dm_serial_ops serial_mpc8xx_ops = {
+       .putc = serial_mpc8xx_putc,
+       .pending = serial_mpc8xx_pending,
+       .getc = serial_mpc8xx_getc,
+       .setbrg = serial_mpc8xx_setbrg,
 };
 
-__weak struct serial_device *default_serial_console(void)
-{
-       return &serial_smc_device;
-}
+static const struct udevice_id serial_mpc8xx_ids[] = {
+       { .compatible = "fsl,pq1-smc" },
+       { }
+};
 
-void mpc8xx_serial_initialize(void)
-{
-       serial_register(&serial_smc_device);
-}
+U_BOOT_DRIVER(serial_mpc8xx) = {
+       .name   = "serial_mpc8xx",
+       .id     = UCLASS_SERIAL,
+       .of_match = serial_mpc8xx_ids,
+       .probe = serial_mpc8xx_probe,
+       .ops    = &serial_mpc8xx_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
index 285fd4d..b020ce2 100644 (file)
  */
 
 #include <common.h>
+#include <dm.h>
 #include <mpc8xx.h>
+#include <spi.h>
+
 #include <asm/cpm_8xx.h>
-#include <linux/ctype.h>
-#include <malloc.h>
-#include <post.h>
-#include <serial.h>
-
-#define SPI_EEPROM_WREN                0x06
-#define SPI_EEPROM_RDSR                0x05
-#define SPI_EEPROM_READ                0x03
-#define SPI_EEPROM_WRITE       0x02
-
-/* ---------------------------------------------------------------
- * Offset for initial SPI buffers in DPRAM:
- * We need a 520 byte scratch DPRAM area to use at an early stage.
- * It is used between the two initialization calls (spi_init_f()
- * and spi_init_r()).
- * The value 0xb00 makes it far enough from the start of the data
- * area (as well as from the stack pointer).
- * --------------------------------------------------------------- */
-#ifndef        CONFIG_SYS_SPI_INIT_OFFSET
-#define        CONFIG_SYS_SPI_INIT_OFFSET      0xB00
-#endif
+#include <asm/io.h>
 
 #define CPM_SPI_BASE_RX        CPM_SPI_BASE
 #define CPM_SPI_BASE_TX        (CPM_SPI_BASE + sizeof(cbd_t))
 
-/* -------------------
- * Function prototypes
- * ------------------- */
-ssize_t spi_xfer(size_t);
-
-/* -------------------
- * Variables
- * ------------------- */
-
 #define MAX_BUFFER     0x104
 
-/* ----------------------------------------------------------------------
- * Initially we place the RX and TX buffers at a fixed location in DPRAM!
- * ---------------------------------------------------------------------- */
-static uchar *rxbuf =
-       (uchar *)&((cpm8xx_t *)&((immap_t *)CONFIG_SYS_IMMR)->im_cpm)->cp_dpmem
-                       [CONFIG_SYS_SPI_INIT_OFFSET];
-static uchar *txbuf =
-       (uchar *)&((cpm8xx_t *)&((immap_t *)CONFIG_SYS_IMMR)->im_cpm)->cp_dpmem
-                       [CONFIG_SYS_SPI_INIT_OFFSET+MAX_BUFFER];
-
-/* **************************************************************************
- *
- *  Function:    spi_init_f
- *
- *  Description: Init SPI-Controller (ROM part)
- *
- *  return:      ---
- *
- * *********************************************************************** */
-void spi_init_f(void)
+static int mpc8xx_spi_probe(struct udevice *dev)
 {
        immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t __iomem *cp = &immr->im_cpm;
@@ -180,117 +135,24 @@ void spi_init_f(void)
        clrbits_be16(&tbdf->cbd_sc, BD_SC_READY);
        clrbits_be16(&rbdf->cbd_sc, BD_SC_EMPTY);
 
-       /* Set the bd's rx and tx buffer address pointers */
-       out_be32(&rbdf->cbd_bufaddr, (ulong)rxbuf);
-       out_be32(&tbdf->cbd_bufaddr, (ulong)txbuf);
-
 /* 10 + 11 */
        out_8(&cp->cp_spim, 0);                 /* Mask  all SPI events */
        out_8(&cp->cp_spie, SPI_EMASK);         /* Clear all SPI events */
 
-       return;
+       return 0;
 }
 
-/* **************************************************************************
- *
- *  Function:    spi_init_r
- *
- *  Description: Init SPI-Controller (RAM part) -
- *              The malloc engine is ready and we can move our buffers to
- *              normal RAM
- *
- *  return:      ---
- *
- * *********************************************************************** */
-void spi_init_r(void)
+static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                           const void *dout, void *din, unsigned long flags)
 {
        immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
        cpm8xx_t __iomem *cp = &immr->im_cpm;
-       spi_t __iomem *spi = (spi_t __iomem *)&cp->cp_dparam[PROFF_SPI];
-       cbd_t __iomem *tbdf, *rbdf;
-
-       /* Disable relocation */
-       out_be16(&spi->spi_rpbase, 0);
-
-       /* tx and rx buffer descriptors */
-       tbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_TX];
-       rbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_RX];
-
-       /* Allocate memory for RX and TX buffers */
-       rxbuf = (uchar *)malloc(MAX_BUFFER);
-       txbuf = (uchar *)malloc(MAX_BUFFER);
-
-       out_be32(&rbdf->cbd_bufaddr, (ulong)rxbuf);
-       out_be32(&tbdf->cbd_bufaddr, (ulong)txbuf);
-
-       return;
-}
-
-/****************************************************************************
- *  Function:    spi_write
- **************************************************************************** */
-ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len)
-{
-       int i;
-
-       memset(rxbuf, 0, MAX_BUFFER);
-       memset(txbuf, 0, MAX_BUFFER);
-       *txbuf = SPI_EEPROM_WREN;               /* write enable         */
-       spi_xfer(1);
-       memcpy(txbuf, addr, alen);
-       *txbuf = SPI_EEPROM_WRITE;              /* WRITE memory array   */
-       memcpy(alen + txbuf, buffer, len);
-       spi_xfer(alen + len);
-                                               /* ignore received data */
-       for (i = 0; i < 1000; i++) {
-               *txbuf = SPI_EEPROM_RDSR;       /* read status          */
-               txbuf[1] = 0;
-               spi_xfer(2);
-               if (!(rxbuf[1] & 1))
-                       break;
-               udelay(1000);
-       }
-       if (i >= 1000)
-               printf("*** spi_write: Time out while writing!\n");
-
-       return len;
-}
-
-/****************************************************************************
- *  Function:    spi_read
- **************************************************************************** */
-ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len)
-{
-       memset(rxbuf, 0, MAX_BUFFER);
-       memset(txbuf, 0, MAX_BUFFER);
-       memcpy(txbuf, addr, alen);
-       *txbuf = SPI_EEPROM_READ;               /* READ memory array    */
-
-       /*
-        * There is a bug in 860T (?) that cuts the last byte of input
-        * if we're reading into DPRAM. The solution we choose here is
-        * to always read len+1 bytes (we have one extra byte at the
-        * end of the buffer).
-        */
-       spi_xfer(alen + len + 1);
-       memcpy(buffer, alen + rxbuf, len);
-
-       return len;
-}
-
-/****************************************************************************
- *  Function:    spi_xfer
- **************************************************************************** */
-ssize_t spi_xfer(size_t count)
-{
-       immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
-       cpm8xx_t __iomem *cp = &immr->im_cpm;
-       spi_t __iomem *spi = (spi_t __iomem *)&cp->cp_dparam[PROFF_SPI];
        cbd_t __iomem *tbdf, *rbdf;
        int tm;
+       size_t count = (bitlen + 7) / 8;
 
-       /* Disable relocation */
-       out_be16(&spi->spi_rpbase, 0);
+       if (count > MAX_BUFFER)
+               return -EINVAL;
 
        tbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_TX];
        rbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_RX];
@@ -299,10 +161,12 @@ ssize_t spi_xfer(size_t count)
        clrbits_be32(&cp->cp_pbdat, 0x0001);
 
        /* Setting tx bd status and data length */
+       out_be32(&tbdf->cbd_bufaddr, (ulong)dout);
        out_be16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_LAST | BD_SC_WRAP);
        out_be16(&tbdf->cbd_datlen, count);
 
        /* Setting rx bd status and data length */
+       out_be32(&rbdf->cbd_bufaddr, (ulong)din);
        out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_WRAP);
        out_be16(&rbdf->cbd_datlen, 0);  /* rx length has no significance */
 
@@ -333,3 +197,20 @@ ssize_t spi_xfer(size_t count)
 
        return count;
 }
+
+static const struct dm_spi_ops mpc8xx_spi_ops = {
+       .xfer           = mpc8xx_spi_xfer,
+};
+
+static const struct udevice_id mpc8xx_spi_ids[] = {
+       { .compatible = "fsl,mpc8xx-spi" },
+       { }
+};
+
+U_BOOT_DRIVER(mpc8xx_spi) = {
+       .name   = "mpc8xx_spi",
+       .id     = UCLASS_SPI,
+       .of_match = mpc8xx_spi_ids,
+       .ops    = &mpc8xx_spi_ops,
+       .probe  = mpc8xx_spi_probe,
+};
index 03746dd..d456beb 100644 (file)
@@ -70,6 +70,7 @@ comment "USB peripherals"
 
 config USB_STORAGE
        bool "USB Mass Storage support"
+       depends on !(BLK && !DM_USB)
        ---help---
          Say Y here if you want to connect USB mass storage devices to your
          board's USB port.
index 4a9ebb6..b6974ad 100644 (file)
@@ -144,4 +144,11 @@ config WDT_MT7621
           Select this to enable Ralink / Mediatek watchdog timer,
           which can be found on some MediaTek chips.
 
+config WDT_MPC8xx
+       bool "MPC8xx watchdog timer support"
+       depends on WDT && MPC8xx
+       select CONFIG_MPC8xx_WATCHDOG
+       help
+          Select this to enable mpc8xx watchdog timer
+
 endmenu
index ccb06ac..c24c2a9 100644 (file)
@@ -4,6 +4,8 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <wdt.h>
 #include <mpc8xx.h>
 #include <asm/cpm_8xx.h>
 #include <asm/io.h>
@@ -16,3 +18,52 @@ void hw_watchdog_reset(void)
        out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39);  /* write magic2 */
 }
 
+#ifdef CONFIG_WDT_MPC8xx
+static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+       immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+       out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR);
+
+       if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
+               return -EBUSY;
+       return 0;
+
+}
+
+static int mpc8xx_wdt_stop(struct udevice *dev)
+{
+       immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
+
+       out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
+
+       if (in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE)
+               return -EBUSY;
+       return 0;
+}
+
+static int mpc8xx_wdt_reset(struct udevice *dev)
+{
+       hw_watchdog_reset();
+
+       return 0;
+}
+
+static const struct wdt_ops mpc8xx_wdt_ops = {
+       .start = mpc8xx_wdt_start,
+       .reset = mpc8xx_wdt_reset,
+       .stop = mpc8xx_wdt_stop,
+};
+
+static const struct udevice_id mpc8xx_wdt_ids[] = {
+       { .compatible = "fsl,pq1-wdt" },
+       {}
+};
+
+U_BOOT_DRIVER(wdt_mpc8xx) = {
+       .name = "wdt_mpc8xx",
+       .id = UCLASS_WDT,
+       .of_match = mpc8xx_wdt_ids,
+       .ops = &mpc8xx_wdt_ops,
+};
+#endif /* CONFIG_WDT_MPC8xx */
diff --git a/fs/fs.c b/fs/fs.c
index adae98d..cb26517 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -365,6 +365,7 @@ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part)
        for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) {
                if (!info->probe(fs_dev_desc, &fs_partition)) {
                        fs_type = info->fstype;
+                       fs_dev_part = part;
                        return 0;
                }
        }
index 9a8b5e8..faae534 100644 (file)
 #ifndef _ASM_PE_H
 #define _ASM_PE_H
 
+/* Characteristics */
+#define IMAGE_FILE_RELOCS_STRIPPED             0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE            0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED          0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED         0x0008
+#define IMAGE_FILE_AGGRESSIVE_WS_TRIM          0x0010
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE         0x0020
+/* Reserved                                    0x0040 */
+#define IMAGE_FILE_BYTES_REVERSED_LO           0x0080
+#define IMAGE_FILE_32BIT_MACHINE               0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED              0x0200
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP     0x0400
+#define IMAGE_FILE_NET_RUN_FROM_SWAP           0x0800
+#define IMAGE_FILE_SYSTEM                      0x1000
+#define IMAGE_FILE_DLL                         0x2000
+#define IMAGE_FILE_UP_SYSTEM_ONLY              0x4000
+#define IMAGE_FILE_BYTES_REVERSED_HI           0x8000
+
 /* Subsystem type */
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION                10
 #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER        11
index 8b56137..a8e879e 100644 (file)
@@ -106,6 +106,17 @@ int mdm_init(void);
 void board_show_dram(phys_size_t size);
 
 /**
+ * Get the uppermost pointer that is valid to access
+ *
+ * Some systems may not map all of their address space. This function allows
+ * boards to indicate what their highest support pointer value is for DRAM
+ * access.
+ *
+ * @param total_size   Size of U-Boot (unused?)
+ */
+ulong board_get_usable_ram_top(ulong total_size);
+
+/**
  * arch_fixup_fdt() - Write arch-specific information to fdt
  *
  * Defined in arch/$(ARCH)/lib/bootm-fdt.c
index 006b049..ccbdc0a 100644 (file)
 /* FIT support */
 #define CONFIG_SYS_BOOTM_LEN         SZ_64M
 
-/* UBI Support */
-
-/* I2C configuration */
-
 #ifdef CONFIG_NAND
-#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x00080000
-#ifdef CONFIG_SPL_OS_BOOT
-#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 /* kernel offset */
-#endif
+
 #define NANDARGS \
        "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
        "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \
 #define CONFIG_AM335X_USB1
 #define CONFIG_AM335X_USB1_MODE MUSB_OTG
 
-/* Network. */
-#define CONFIG_PHY_SMSC
-#define CONFIG_PHY_ATHEROS
-
 /* NAND support */
 #ifdef CONFIG_NAND
 #define GPMC_NAND_ECC_LP_x8_LAYOUT     1
index 385d59e..9a205ed 100644 (file)
@@ -11,7 +11,7 @@
 #define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
 
 #define CONFIG_SYS_SDRAM_BASE          0x10000000
-#define CONFIG_SYS_SDRAM_SIZE          SZ_8M
+#define CONFIG_SYS_SDRAM_SIZE          SZ_16M
 
 #define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + SZ_1M)
 
index 94214b1..3fca28d 100644 (file)
  * RTC
  */
 #ifdef CONFIG_CMD_DATE
-#define CONFIG_RTC_M41T62
 #define CONFIG_SYS_I2C_RTC_ADDR                0x68
 #define CONFIG_SYS_M41T11_BASE_YEAR    2000
 #endif
index 9997795..e125a38 100644 (file)
@@ -58,7 +58,6 @@
 #define CONFIG_SYS_I2C_MXC
 
 /* RTC (actually an RV-4162 but M41T62-compatible) */
-#define CONFIG_RTC_M41T62
 #define CONFIG_SYS_I2C_RTC_ADDR 0x68
 #define CONFIG_SYS_RTC_BUS_NUM 2
 
index a6835eb..639da80 100644 (file)
@@ -75,7 +75,6 @@
 #define CONFIG_SYS_I2C_SLAVE                   0x02
 #define CONFIG_I2C_CHIPADDRESS                 0x50
 
-#define CONFIG_RTC_M41T62      1
 #define CONFIG_SYS_I2C_RTC_ADDR        0x68
 
 /* FPGA config options */
index b1deb60..b5e2c64 100644 (file)
@@ -96,7 +96,7 @@ typedef struct {
 typedef unsigned long efi_status_t;
 typedef u64 efi_physical_addr_t;
 typedef u64 efi_virtual_addr_t;
-typedef void *efi_handle_t;
+typedef struct efi_object *efi_handle_t;
 
 #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
        {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
index e850b95..aef77b6 100644 (file)
@@ -85,10 +85,10 @@ struct efi_boot_services {
        efi_status_t (EFIAPI *check_event)(struct efi_event *event);
 #define EFI_NATIVE_INTERFACE   0x00000000
        efi_status_t (EFIAPI *install_protocol_interface)(
-                       void **handle, const efi_guid_t *protocol,
+                       efi_handle_t *handle, const efi_guid_t *protocol,
                        int protocol_interface_type, void *protocol_interface);
        efi_status_t (EFIAPI *reinstall_protocol_interface)(
-                       void *handle, const efi_guid_t *protocol,
+                       efi_handle_t handle, const efi_guid_t *protocol,
                        void *old_interface, void *new_interface);
        efi_status_t (EFIAPI *uninstall_protocol_interface)(
                        efi_handle_t handle, const efi_guid_t *protocol,
@@ -164,9 +164,9 @@ struct efi_boot_services {
        efi_status_t (EFIAPI *locate_protocol)(const efi_guid_t *protocol,
                        void *registration, void **protocol_interface);
        efi_status_t (EFIAPI *install_multiple_protocol_interfaces)(
-                       void **handle, ...);
+                       efi_handle_t *handle, ...);
        efi_status_t (EFIAPI *uninstall_multiple_protocol_interfaces)(
-                       void *handle, ...);
+                       efi_handle_t handle, ...);
        efi_status_t (EFIAPI *calculate_crc32)(const void *data,
                                               efi_uintn_t data_size,
                                               u32 *crc32);
@@ -241,8 +241,8 @@ struct efi_runtime_services {
        efi_status_t (EFIAPI *query_capsule_caps)(
                        struct efi_capsule_header **capsule_header_array,
                        efi_uintn_t capsule_count,
-                       u64 maximum_capsule_size,
-                       u32 reset_type);
+                       u64 *maximum_capsule_size,
+                       u32 *reset_type);
        efi_status_t (EFIAPI *query_variable_info)(
                        u32 attributes,
                        u64 *maximum_variable_storage_size,
@@ -965,7 +965,7 @@ struct efi_file_info {
        struct efi_time last_access_time;
        struct efi_time modification_time;
        u64 attribute;
-       s16 file_name[0];
+       u16 file_name[0];
 };
 
 struct efi_file_system_info {
index 1417c35..53f0816 100644 (file)
@@ -167,28 +167,41 @@ struct efi_handler {
        struct list_head open_infos;
 };
 
-/*
- * UEFI has a poor man's OO model where one "object" can be polymorphic and have
- * multiple different protocols (classes) attached to it.
+/**
+ * struct efi_object - dereferenced EFI handle
+ *
+ * @link:      pointers to put the handle into a linked list
+ * @protocols: linked list with the protocol interfaces installed on this
+ *             handle
+ *
+ * UEFI offers a flexible and expandable object model. The objects in the UEFI
+ * API are devices, drivers, and loaded images. struct efi_object is our storage
+ * structure for these objects.
  *
- * This struct is the parent struct for all of our actual implementation objects
- * that can include it to make themselves an EFI object
+ * When including this structure into a larger structure always put it first so
+ * that when deleting a handle the whole encompassing structure can be freed.
+ *
+ * A pointer to this structure is referred to as a handle. Typedef efi_handle_t
+ * has been created for such pointers.
  */
 struct efi_object {
        /* Every UEFI object is part of a global object list */
        struct list_head link;
        /* The list of protocols */
        struct list_head protocols;
-       /* The object spawner can either use this for data or as identifier */
-       void *handle;
 };
 
 /**
  * struct efi_loaded_image_obj - handle of a loaded image
+ *
+ * @header:            EFI object header
+ * @reloc_base:                base address for the relocated image
+ * @reloc_size:                size of the relocated image
+ * @exit_jmp:          long jump buffer for returning form started image
+ * @entry:             entry address of the relocated image
  */
 struct efi_loaded_image_obj {
-       /* Generic EFI object parent class data */
-       struct efi_object parent;
+       struct efi_object header;
        void *reloc_base;
        aligned_u64 reloc_size;
        efi_status_t exit_status;
@@ -290,11 +303,11 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map);
 /* Call this to set the current device name */
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path);
 /* Add a new object to the object list. */
-void efi_add_handle(struct efi_object *obj);
+void efi_add_handle(efi_handle_t obj);
 /* Create handle */
 efi_status_t efi_create_handle(efi_handle_t *handle);
 /* Delete handle */
-void efi_delete_handle(struct efi_object *obj);
+void efi_delete_handle(efi_handle_t obj);
 /* Call this to validate a handle and find the EFI object for it */
 struct efi_object *efi_search_obj(const efi_handle_t handle);
 /* Find a protocol on a handle */
@@ -331,7 +344,16 @@ struct efi_simple_file_system_protocol *efi_simple_file_system(
 /* open file from device-path: */
 struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
 
-
+/**
+ * efi_size_in_pages() - convert size in bytes to size in pages
+ *
+ * This macro returns the number of EFI memory pages required to hold 'size'
+ * bytes.
+ *
+ * @size:      size in bytes
+ * Return:     size in pages
+ */
+#define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
 /* Generic EFI memory allocator, call this to get memory */
 void *efi_alloc(uint64_t len, int memory_type);
 /* More specific EFI memory allocator, called by EFI payloads */
@@ -419,6 +441,10 @@ const struct efi_device_path *efi_dp_last_node(
 efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
                                    struct efi_device_path **device_path,
                                    struct efi_device_path **file_path);
+efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
+                             const char *path,
+                             struct efi_device_path **device,
+                             struct efi_device_path **file);
 
 #define EFI_DP_TYPE(_dp, _type, _subtype) \
        (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
@@ -492,6 +518,29 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
                                     u32 attributes, efi_uintn_t data_size,
                                     void *data);
 
+/*
+ * See section 3.1.3 in the v2.7 UEFI spec for more details on
+ * the layout of EFI_LOAD_OPTION.  In short it is:
+ *
+ *    typedef struct _EFI_LOAD_OPTION {
+ *        UINT32 Attributes;
+ *        UINT16 FilePathListLength;
+ *        // CHAR16 Description[];   <-- variable length, NULL terminated
+ *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];
+ *                                              <-- FilePathListLength bytes
+ *        // UINT8 OptionalData[];
+ *    } EFI_LOAD_OPTION;
+ */
+struct efi_load_option {
+       u32 attributes;
+       u16 file_path_length;
+       u16 *label;
+       struct efi_device_path *file_path;
+       u8 *optional_data;
+};
+
+void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
+unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
 void *efi_bootmgr_load(struct efi_device_path **device_path,
                       struct efi_device_path **file_path);
 
index 56beac3..49d3d6d 100644 (file)
@@ -129,7 +129,6 @@ u16 efi_st_get_key(void);
  * @setup:     set up the unit test
  * @teardown:  tear down the unit test
  * @execute:   execute the unit test
- * @setup_ok:  setup was successful (set at runtime)
  * @on_request:        test is only executed on request
  */
 struct efi_unit_test {
@@ -139,7 +138,6 @@ struct efi_unit_test {
                     const struct efi_system_table *systable);
        int (*execute)(void);
        int (*teardown)(void);
-       int setup_ok;
        bool on_request;
 };
 
index f67502e..83a2d41 100644 (file)
@@ -30,6 +30,7 @@ struct fdt_region;
 #define IMAGE_ENABLE_FIT       1
 #define IMAGE_ENABLE_OF_LIBFDT 1
 #define CONFIG_FIT_VERBOSE     1 /* enable fit_format_{error,warning}() */
+#define CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT 1
 #define CONFIG_FIT_ENABLE_SHA256_SUPPORT
 #define CONFIG_SHA1
 #define CONFIG_SHA256
@@ -1101,6 +1102,7 @@ struct image_sign_info {
        int node_offset;                /* Offset of signature node */
        const char *name;               /* Algorithm name */
        struct checksum_algo *checksum; /* Checksum algorithm information */
+       struct padding_algo *padding;   /* Padding algorithm information */
        struct crypto_algo *crypto;     /* Crypto algorithm information */
        const void *fdt_blob;           /* FDT containing public keys */
        int required_keynode;           /* Node offset of key to use: -1=any */
@@ -1186,6 +1188,13 @@ struct crypto_algo {
                      uint8_t *sig, uint sig_len);
 };
 
+struct padding_algo {
+       const char *name;
+       int (*verify)(struct image_sign_info *info,
+                     uint8_t *pad, int pad_len,
+                     const uint8_t *hash, int hash_len);
+};
+
 /**
  * image_get_checksum_algo() - Look up a checksum algorithm
  *
@@ -1203,6 +1212,14 @@ struct checksum_algo *image_get_checksum_algo(const char *full_name);
 struct crypto_algo *image_get_crypto_algo(const char *full_name);
 
 /**
+ * image_get_padding_algo() - Look up a padding algorithm
+ *
+ * @param name         Name of padding algorithm
+ * @return pointer to algorithm information, or NULL if not found
+ */
+struct padding_algo *image_get_padding_algo(const char *name);
+
+/**
  * fit_image_verify_required_sigs() - Verify signatures marked as 'required'
  *
  * @fit:               FIT to check
index 8d13bd2..9433df8 100644 (file)
 #define PSCI_RET_DISABLED                      -8
 
 #ifdef CONFIG_ARM_PSCI_FW
-typedef unsigned long (psci_fn)(unsigned long, unsigned long,
-                               unsigned long, unsigned long);
-
-extern psci_fn *invoke_psci_fn;
+unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
+                            unsigned long a2, unsigned long a3);
 #else
 unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1,
                             unsigned long a2, unsigned long a3)
index ec25db6..9133d07 100644 (file)
@@ -224,7 +224,6 @@ struct serial_dev_priv {
 void atmel_serial_initialize(void);
 void mcf_serial_initialize(void);
 void mpc85xx_serial_initialize(void);
-void mpc8xx_serial_initialize(void);
 void mxc_serial_initialize(void);
 void ns16550_serial_initialize(void);
 void pl01x_serial_initialize(void);
index 68bcb14..2d3024d 100644 (file)
@@ -97,6 +97,16 @@ static inline int rsa_add_verify_data(struct image_sign_info *info,
 int rsa_verify(struct image_sign_info *info,
               const struct image_region region[], int region_count,
               uint8_t *sig, uint sig_len);
+
+int padding_pkcs_15_verify(struct image_sign_info *info,
+                          uint8_t *msg, int msg_len,
+                          const uint8_t *hash, int hash_len);
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+int padding_pss_verify(struct image_sign_info *info,
+                      uint8_t *msg, int msg_len,
+                      const uint8_t *hash, int hash_len);
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
 #else
 static inline int rsa_verify(struct image_sign_info *info,
                const struct image_region region[], int region_count,
@@ -104,8 +114,26 @@ static inline int rsa_verify(struct image_sign_info *info,
 {
        return -ENXIO;
 }
+
+static inline int padding_pkcs_15_verify(struct image_sign_info *info,
+                                        uint8_t *msg, int msg_len,
+                                        const uint8_t *hash, int hash_len)
+{
+       return -ENXIO;
+}
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+static inline int padding_pss_verify(struct image_sign_info *info,
+                                    uint8_t *msg, int msg_len,
+                                    const uint8_t *hash, int hash_len)
+{
+       return -ENXIO;
+}
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
 #endif
 
+#define RSA_DEFAULT_PADDING_NAME               "pkcs-1.5"
+
 #define RSA2048_BYTES  (2048 / 8)
 #define RSA4096_BYTES  (4096 / 8)
 
index 4d2e220..8321355 100644 (file)
@@ -8,7 +8,7 @@ ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_EFI) += efi/
 obj-$(CONFIG_EFI_LOADER) += efi_driver/
 obj-$(CONFIG_EFI_LOADER) += efi_loader/
-obj-$(CONFIG_EFI_LOADER) += efi_selftest/
+obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest/
 obj-$(CONFIG_LZMA) += lzma/
 obj-$(CONFIG_BZIP2) += bzip2/
 obj-$(CONFIG_TIZEN) += tizen/
index c6639f9..2c6a508 100644 (file)
@@ -69,7 +69,7 @@ int efi_init(struct efi_priv *priv, const char *banner, efi_handle_t image,
        efi_putc(priv, ' ');
 
        ret = boot->open_protocol(priv->parent_image, &loaded_image_guid,
-                                 (void **)&loaded_image, &priv->parent_image,
+                                 (void **)&loaded_image, priv->parent_image,
                                  NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
        if (ret) {
                efi_puts(priv, "Failed to get loaded image protocol\n");
index 0c5764d..a095df3 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  EFI utils
+ *  EFI boot manager
  *
  *  Copyright (c) 2017 Rob Clark
  */
@@ -9,6 +9,7 @@
 #include <charset.h>
 #include <malloc.h>
 #include <efi_loader.h>
+#include <asm/unaligned.h>
 
 static const struct efi_boot_services *bs;
 static const struct efi_runtime_services *rs;
@@ -30,42 +31,68 @@ static const struct efi_runtime_services *rs;
  */
 
 
-/*
- * See section 3.1.3 in the v2.7 UEFI spec for more details on
- * the layout of EFI_LOAD_OPTION.  In short it is:
- *
- *    typedef struct _EFI_LOAD_OPTION {
- *        UINT32 Attributes;
- *        UINT16 FilePathListLength;
- *        // CHAR16 Description[];   <-- variable length, NULL terminated
- *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];  <-- FilePathListLength bytes
- *        // UINT8 OptionalData[];
- *    } EFI_LOAD_OPTION;
- */
-struct load_option {
-       u32 attributes;
-       u16 file_path_length;
-       u16 *label;
-       struct efi_device_path *file_path;
-       u8 *optional_data;
-};
-
-/* parse an EFI_LOAD_OPTION, as described above */
-static void parse_load_option(struct load_option *lo, void *ptr)
+/* Parse serialized data and transform it into efi_load_option structure */
+void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data)
 {
-       lo->attributes = *(u32 *)ptr;
-       ptr += sizeof(u32);
+       lo->attributes = get_unaligned_le32(data);
+       data += sizeof(u32);
+
+       lo->file_path_length = get_unaligned_le16(data);
+       data += sizeof(u16);
 
-       lo->file_path_length = *(u16 *)ptr;
-       ptr += sizeof(u16);
+       /* FIXME */
+       lo->label = (u16 *)data;
+       data += (u16_strlen(lo->label) + 1) * sizeof(u16);
 
-       lo->label = ptr;
-       ptr += (u16_strlen(lo->label) + 1) * 2;
+       /* FIXME */
+       lo->file_path = (struct efi_device_path *)data;
+       data += lo->file_path_length;
 
-       lo->file_path = ptr;
-       ptr += lo->file_path_length;
+       lo->optional_data = data;
+}
 
-       lo->optional_data = ptr;
+/*
+ * Serialize efi_load_option structure into byte stream for BootXXXX.
+ * Return a size of allocated data.
+ */
+unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
+{
+       unsigned long label_len, option_len;
+       unsigned long size;
+       u8 *p;
+
+       label_len = (u16_strlen(lo->label) + 1) * sizeof(u16);
+       option_len = strlen((char *)lo->optional_data);
+
+       /* total size */
+       size = sizeof(lo->attributes);
+       size += sizeof(lo->file_path_length);
+       size += label_len;
+       size += lo->file_path_length;
+       size += option_len + 1;
+       p = malloc(size);
+       if (!p)
+               return 0;
+
+       /* copy data */
+       *data = p;
+       memcpy(p, &lo->attributes, sizeof(lo->attributes));
+       p += sizeof(lo->attributes);
+
+       memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length));
+       p += sizeof(lo->file_path_length);
+
+       memcpy(p, lo->label, label_len);
+       p += label_len;
+
+       memcpy(p, lo->file_path, lo->file_path_length);
+       p += lo->file_path_length;
+
+       memcpy(p, lo->optional_data, option_len);
+       p += option_len;
+       *(char *)p = '\0';
+
+       return size;
 }
 
 /* free() the result */
@@ -100,7 +127,7 @@ static void *get_var(u16 *name, const efi_guid_t *vendor,
 static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
                            struct efi_device_path **file_path)
 {
-       struct load_option lo;
+       struct efi_load_option lo;
        u16 varname[] = L"Boot0000";
        u16 hexmap[] = L"0123456789ABCDEF";
        void *load_option, *image = NULL;
@@ -115,7 +142,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
        if (!load_option)
                return NULL;
 
-       parse_load_option(&lo, load_option);
+       efi_deserialize_load_option(&lo, load_option);
 
        if (lo.attributes & LOAD_OPTION_ACTIVE) {
                efi_status_t ret;
index da978d2..cc9efbb 100644 (file)
@@ -26,6 +26,14 @@ LIST_HEAD(efi_obj_list);
 /* List of all events */
 LIST_HEAD(efi_events);
 
+/*
+ * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
+ * we need to do trickery with caches. Since we don't want to break the EFI
+ * aware boot path, only apply hacks when loading exiting directly (breaking
+ * direct Linux EFI booting along the way - oh well).
+ */
+static bool efi_is_direct_boot = true;
+
 #ifdef CONFIG_ARM
 /*
  * The "gd" pointer lives in a register on ARM and AArch64 that we declare
@@ -416,13 +424,12 @@ static efi_status_t EFIAPI efi_free_pool_ext(void *buffer)
  *
  * The protocols list is initialized. The object handle is set.
  */
-void efi_add_handle(struct efi_object *obj)
+void efi_add_handle(efi_handle_t handle)
 {
-       if (!obj)
+       if (!handle)
                return;
-       INIT_LIST_HEAD(&obj->protocols);
-       obj->handle = obj;
-       list_add_tail(&obj->link, &efi_obj_list);
+       INIT_LIST_HEAD(&handle->protocols);
+       list_add_tail(&handle->link, &efi_obj_list);
 }
 
 /**
@@ -440,7 +447,7 @@ efi_status_t efi_create_handle(efi_handle_t *handle)
                return EFI_OUT_OF_RESOURCES;
 
        efi_add_handle(obj);
-       *handle = obj->handle;
+       *handle = obj;
 
        return EFI_SUCCESS;
 }
@@ -536,13 +543,13 @@ efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
  *
  * @obj: handle to delete
  */
-void efi_delete_handle(struct efi_object *obj)
+void efi_delete_handle(efi_handle_t handle)
 {
-       if (!obj)
+       if (!handle)
                return;
-       efi_remove_all_protocols(obj->handle);
-       list_del(&obj->link);
-       free(obj);
+       efi_remove_all_protocols(handle);
+       list_del(&handle->link);
+       free(handle);
 }
 
 /**
@@ -927,7 +934,7 @@ struct efi_object *efi_search_obj(const efi_handle_t handle)
        struct efi_object *efiobj;
 
        list_for_each_entry(efiobj, &efi_obj_list, link) {
-               if (efiobj->handle == handle)
+               if (efiobj == handle)
                        return efiobj;
        }
 
@@ -1019,7 +1026,7 @@ efi_status_t efi_add_protocol(const efi_handle_t handle,
  * Return: status code
  */
 static efi_status_t EFIAPI efi_install_protocol_interface(
-                       void **handle, const efi_guid_t *protocol,
+                       efi_handle_t *handle, const efi_guid_t *protocol,
                        int protocol_interface_type, void *protocol_interface)
 {
        efi_status_t r;
@@ -1052,7 +1059,7 @@ out:
 
 /**
  * efi_get_drivers() - get all drivers associated to a controller
- * @efiobj:               handle of the controller
+ * @handle:               handle of the controller
  * @protocol:             protocol GUID (optional)
  * @number_of_drivers:    number of child controllers
  * @driver_handle_buffer: handles of the the drivers
@@ -1061,7 +1068,7 @@ out:
  *
  * Return: status code
  */
-static efi_status_t efi_get_drivers(struct efi_object *efiobj,
+static efi_status_t efi_get_drivers(efi_handle_t handle,
                                    const efi_guid_t *protocol,
                                    efi_uintn_t *number_of_drivers,
                                    efi_handle_t **driver_handle_buffer)
@@ -1072,7 +1079,7 @@ static efi_status_t efi_get_drivers(struct efi_object *efiobj,
        bool duplicate;
 
        /* Count all driver associations */
-       list_for_each_entry(handler, &efiobj->protocols, link) {
+       list_for_each_entry(handler, &handle->protocols, link) {
                if (protocol && guidcmp(handler->guid, protocol))
                        continue;
                list_for_each_entry(item, &handler->open_infos, link) {
@@ -1090,7 +1097,7 @@ static efi_status_t efi_get_drivers(struct efi_object *efiobj,
        if (!*driver_handle_buffer)
                return EFI_OUT_OF_RESOURCES;
        /* Collect unique driver handles */
-       list_for_each_entry(handler, &efiobj->protocols, link) {
+       list_for_each_entry(handler, &handle->protocols, link) {
                if (protocol && guidcmp(handler->guid, protocol))
                        continue;
                list_for_each_entry(item, &handler->open_infos, link) {
@@ -1117,7 +1124,7 @@ static efi_status_t efi_get_drivers(struct efi_object *efiobj,
 
 /**
  * efi_disconnect_all_drivers() - disconnect all drivers from a controller
- * @efiobj:       handle of the controller
+ * @handle:       handle of the controller
  * @protocol:     protocol GUID (optional)
  * @child_handle: handle of the child to destroy
  *
@@ -1128,16 +1135,16 @@ static efi_status_t efi_get_drivers(struct efi_object *efiobj,
  *
  * Return: status code
  */
-static efi_status_t efi_disconnect_all_drivers(
-                               struct efi_object *efiobj,
-                               const efi_guid_t *protocol,
-                               efi_handle_t child_handle)
+static efi_status_t efi_disconnect_all_drivers
+                               (efi_handle_t handle,
+                                const efi_guid_t *protocol,
+                                efi_handle_t child_handle)
 {
        efi_uintn_t number_of_drivers;
        efi_handle_t *driver_handle_buffer;
        efi_status_t r, ret;
 
-       ret = efi_get_drivers(efiobj, protocol, &number_of_drivers,
+       ret = efi_get_drivers(handle, protocol, &number_of_drivers,
                              &driver_handle_buffer);
        if (ret != EFI_SUCCESS)
                return ret;
@@ -1145,7 +1152,7 @@ static efi_status_t efi_disconnect_all_drivers(
        ret = EFI_NOT_FOUND;
        while (number_of_drivers) {
                r = EFI_CALL(efi_disconnect_controller(
-                               efiobj->handle,
+                               handle,
                                driver_handle_buffer[--number_of_drivers],
                                child_handle));
                if (r == EFI_SUCCESS)
@@ -1156,21 +1163,19 @@ static efi_status_t efi_disconnect_all_drivers(
 }
 
 /**
- * efi_uninstall_protocol_interface() - uninstall protocol interface
+ * efi_uninstall_protocol() - uninstall protocol interface
+ *
  * @handle:             handle from which the protocol shall be removed
  * @protocol:           GUID of the protocol to be removed
  * @protocol_interface: interface to be removed
  *
- * This function implements the UninstallProtocolInterface service.
- *
- * See the Unified Extensible Firmware Interface (UEFI) specification for
- * details.
+ * This function DOES NOT delete a handle without installed protocol.
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_uninstall_protocol_interface(
-                               efi_handle_t handle, const efi_guid_t *protocol,
-                               void *protocol_interface)
+static efi_status_t efi_uninstall_protocol
+                       (efi_handle_t handle, const efi_guid_t *protocol,
+                        void *protocol_interface)
 {
        struct efi_object *efiobj;
        struct efi_handler *handler;
@@ -1178,8 +1183,6 @@ static efi_status_t EFIAPI efi_uninstall_protocol_interface(
        struct efi_open_protocol_info_item *pos;
        efi_status_t r;
 
-       EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
-
        /* Check handle */
        efiobj = efi_search_obj(handle);
        if (!efiobj) {
@@ -1210,7 +1213,41 @@ static efi_status_t EFIAPI efi_uninstall_protocol_interface(
        }
        r = efi_remove_protocol(handle, protocol, protocol_interface);
 out:
-       return EFI_EXIT(r);
+       return r;
+}
+
+/**
+ * efi_uninstall_protocol_interface() - uninstall protocol interface
+ * @handle:             handle from which the protocol shall be removed
+ * @protocol:           GUID of the protocol to be removed
+ * @protocol_interface: interface to be removed
+ *
+ * This function implements the UninstallProtocolInterface service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI efi_uninstall_protocol_interface
+                       (efi_handle_t handle, const efi_guid_t *protocol,
+                        void *protocol_interface)
+{
+       efi_status_t ret;
+
+       EFI_ENTRY("%p, %pUl, %p", handle, protocol, protocol_interface);
+
+       ret = efi_uninstall_protocol(handle, protocol, protocol_interface);
+       if (ret != EFI_SUCCESS)
+               goto out;
+
+       /* If the last protocol has been removed, delete the handle. */
+       if (list_empty(&handle->protocols)) {
+               list_del(&handle->link);
+               free(handle);
+       }
+out:
+       return EFI_EXIT(ret);
 }
 
 /**
@@ -1240,7 +1277,7 @@ static efi_status_t EFIAPI efi_register_protocol_notify(
  * @search_type: selection criterion
  * @protocol:    GUID of the protocol
  * @search_key:  registration key
- * @efiobj:      handle
+ * @handle:      handle
  *
  * See the documentation of the LocateHandle service in the UEFI specification.
  *
@@ -1248,7 +1285,7 @@ static efi_status_t EFIAPI efi_register_protocol_notify(
  */
 static int efi_search(enum efi_locate_search_type search_type,
                      const efi_guid_t *protocol, void *search_key,
-                     struct efi_object *efiobj)
+                     efi_handle_t handle)
 {
        efi_status_t ret;
 
@@ -1259,7 +1296,7 @@ static int efi_search(enum efi_locate_search_type search_type,
                /* TODO: RegisterProtocolNotify is not implemented yet */
                return -1;
        case BY_PROTOCOL:
-               ret = efi_search_protocol(efiobj->handle, protocol, NULL);
+               ret = efi_search_protocol(handle, protocol, NULL);
                return (ret != EFI_SUCCESS);
        default:
                /* Invalid search type */
@@ -1331,7 +1368,7 @@ static efi_status_t efi_locate_handle(
        /* Then fill the array */
        list_for_each_entry(efiobj, &efi_obj_list, link) {
                if (!efi_search(search_type, protocol, search_key, efiobj))
-                       *buffer++ = efiobj->handle;
+                       *buffer++ = efiobj;
        }
 
        return EFI_SUCCESS;
@@ -1489,7 +1526,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
        }
 
        /* Add internal object to object list */
-       efi_add_handle(&obj->parent);
+       efi_add_handle(&obj->header);
 
        if (info_ptr)
                *info_ptr = info;
@@ -1506,7 +1543,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
                 * When asking for the device path interface, return
                 * bootefi_device_path
                 */
-               ret = efi_add_protocol(obj->parent.handle,
+               ret = efi_add_protocol(&obj->header,
                                       &efi_guid_device_path, device_path);
                if (ret != EFI_SUCCESS)
                        goto failure;
@@ -1516,7 +1553,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
         * When asking for the loaded_image interface, just
         * return handle which points to loaded_image_info
         */
-       ret = efi_add_protocol(obj->parent.handle,
+       ret = efi_add_protocol(&obj->header,
                               &efi_guid_loaded_image, info);
        if (ret != EFI_SUCCESS)
                goto failure;
@@ -1678,6 +1715,8 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
 
        EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
 
+       efi_is_direct_boot = false;
+
        /* call the image! */
        if (setjmp(&image_obj->exit_jmp)) {
                /*
@@ -1786,6 +1825,21 @@ static efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
 }
 
 /**
+ * efi_exit_caches() - fix up caches for EFI payloads if necessary
+ */
+static void efi_exit_caches(void)
+{
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
+       /*
+        * Grub on 32bit ARM needs to have caches disabled before jumping into
+        * a zImage, but does not know of all cache layers. Give it a hand.
+        */
+       if (efi_is_direct_boot)
+               cleanup_before_linux();
+#endif
+}
+
+/**
  * efi_exit_boot_services() - stop all boot services
  * @image_handle: handle of the loaded image
  * @map_key:      key of the memory map
@@ -1838,6 +1892,9 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
 
        board_quiesce_devices();
 
+       /* Fix up caches for EFI payloads if necessary */
+       efi_exit_caches();
+
        /* This stops all lingering devices */
        bootm_disable_interrupts();
 
@@ -2176,7 +2233,7 @@ static efi_status_t EFIAPI efi_locate_protocol(const efi_guid_t *protocol,
 
                efiobj = list_entry(lhandle, struct efi_object, link);
 
-               ret = efi_search_protocol(efiobj->handle, protocol, &handler);
+               ret = efi_search_protocol(efiobj, protocol, &handler);
                if (ret == EFI_SUCCESS) {
                        *protocol_interface = handler->protocol_interface;
                        return EFI_EXIT(EFI_SUCCESS);
@@ -2279,8 +2336,8 @@ out:
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
-                       void **handle, ...)
+static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
+                               (efi_handle_t *handle, ...)
 {
        EFI_ENTRY("%p", handle);
 
@@ -2316,7 +2373,7 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
        for (; i; --i) {
                protocol = efi_va_arg(argptr, efi_guid_t*);
                protocol_interface = efi_va_arg(argptr, void*);
-               EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
+               EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
                                                          protocol_interface));
        }
        efi_va_end(argptr);
@@ -2339,7 +2396,7 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
  * Return: status code
  */
 static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
-                       void *handle, ...)
+                       efi_handle_t handle, ...)
 {
        EFI_ENTRY("%p", handle);
 
@@ -2358,16 +2415,21 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
                if (!protocol)
                        break;
                protocol_interface = efi_va_arg(argptr, void*);
-               r = EFI_CALL(efi_uninstall_protocol_interface(
-                                               handle, protocol,
-                                               protocol_interface));
+               r = efi_uninstall_protocol(handle, protocol,
+                                          protocol_interface);
                if (r != EFI_SUCCESS)
                        break;
                i++;
        }
        efi_va_end(argptr);
-       if (r == EFI_SUCCESS)
+       if (r == EFI_SUCCESS) {
+               /* If the last protocol has been removed, delete the handle. */
+               if (list_empty(&handle->protocols)) {
+                       list_del(&handle->link);
+                       free(handle);
+               }
                return EFI_EXIT(r);
+       }
 
        /* If an error occurred undo all changes. */
        efi_va_start(argptr, handle);
@@ -2380,7 +2442,8 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
        }
        efi_va_end(argptr);
 
-       return EFI_EXIT(r);
+       /* In case of an error always return EFI_INVALID_PARAMETER */
+       return EFI_EXIT(EFI_INVALID_PARAMETER);
 }
 
 /**
@@ -2553,10 +2616,10 @@ out:
  *
  * Return: status code
  */
-static efi_status_t EFIAPI efi_open_protocol(
-                       void *handle, const efi_guid_t *protocol,
-                       void **protocol_interface, void *agent_handle,
-                       void *controller_handle, uint32_t attributes)
+static efi_status_t EFIAPI efi_open_protocol
+                       (efi_handle_t handle, const efi_guid_t *protocol,
+                        void **protocol_interface, efi_handle_t agent_handle,
+                        efi_handle_t controller_handle, uint32_t attributes)
 {
        struct efi_handler *handler;
        efi_status_t r = EFI_INVALID_PARAMETER;
@@ -2828,13 +2891,19 @@ static efi_status_t EFIAPI efi_reinstall_protocol_interface(
 
        EFI_ENTRY("%p, %pUl, %p, %p", handle, protocol, old_interface,
                  new_interface);
-       ret = EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
-                                                       old_interface));
+
+       /* Uninstall protocol but do not delete handle */
+       ret = efi_uninstall_protocol(handle, protocol, old_interface);
        if (ret != EFI_SUCCESS)
                goto out;
-       ret = EFI_CALL(efi_install_protocol_interface(&handle, protocol,
-                                                     EFI_NATIVE_INTERFACE,
-                                                     new_interface));
+
+       /* Install the new protocol */
+       ret = efi_add_protocol(handle, protocol, new_interface);
+       /*
+        * The UEFI spec does not specify what should happen to the handle
+        * if in case of an error no protocol interface remains on the handle.
+        * So let's do nothing here.
+        */
        if (ret != EFI_SUCCESS)
                goto out;
        /*
index 0225222..66c33a5 100644 (file)
@@ -205,7 +205,7 @@ static int query_console_serial(int *rows, int *cols)
        /*
         * Not all terminals understand CSI [18t for querying the console size.
         * We should adhere to escape sequences documented in the console_codes
-        * manpage and the ECMA-48 standard.
+        * man page and the ECMA-48 standard.
         *
         * So here we follow a different approach. We position the cursor to the
         * bottom right and query its position. Before leaving the function we
@@ -480,7 +480,7 @@ void set_shift_mask(int mod, struct efi_key_state *key_state)
  *
  * This gets called when we have already parsed CSI.
  *
- * @modifiers:  bitmask (shift, alt, ctrl)
+ * @modifiers:  bit mask (shift, alt, ctrl)
  * @return:    the unmodified code
  */
 static int analyze_modifiers(struct efi_key_state *key_state)
@@ -1051,34 +1051,34 @@ static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
 efi_status_t efi_console_register(void)
 {
        efi_status_t r;
-       struct efi_object *efi_console_output_obj;
-       struct efi_object *efi_console_input_obj;
+       efi_handle_t console_output_handle;
+       efi_handle_t console_input_handle;
 
        /* Set up mode information */
        query_console_size();
 
        /* Create handles */
-       r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
+       r = efi_create_handle(&console_output_handle);
        if (r != EFI_SUCCESS)
                goto out_of_memory;
 
-       r = efi_add_protocol(efi_console_output_obj->handle,
+       r = efi_add_protocol(console_output_handle,
                             &efi_guid_text_output_protocol, &efi_con_out);
        if (r != EFI_SUCCESS)
                goto out_of_memory;
-       systab.con_out_handle = efi_console_output_obj->handle;
-       systab.stderr_handle = efi_console_output_obj->handle;
+       systab.con_out_handle = console_output_handle;
+       systab.stderr_handle = console_output_handle;
 
-       r = efi_create_handle((efi_handle_t *)&efi_console_input_obj);
+       r = efi_create_handle(&console_input_handle);
        if (r != EFI_SUCCESS)
                goto out_of_memory;
 
-       r = efi_add_protocol(efi_console_input_obj->handle,
+       r = efi_add_protocol(console_input_handle,
                             &efi_guid_text_input_protocol, &efi_con_in);
        if (r != EFI_SUCCESS)
                goto out_of_memory;
-       systab.con_in_handle = efi_console_input_obj->handle;
-       r = efi_add_protocol(efi_console_input_obj->handle,
+       systab.con_in_handle = console_input_handle;
+       r = efi_add_protocol(console_input_handle,
                             &efi_guid_text_input_ex_protocol, &efi_con_in_ex);
        if (r != EFI_SUCCESS)
                goto out_of_memory;
index 46a24f7..d949823 100644 (file)
@@ -82,7 +82,7 @@ struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
 
 /*
  * Compare two device-paths, stopping when the shorter of the two hits
- * an End* node.  This is useful to, for example, compare a device-path
+ * an End* node. This is useful to, for example, compare a device-path
  * representing a device with one representing a file on the device, or
  * a device with a parent device.
  */
@@ -109,16 +109,17 @@ int efi_dp_match(const struct efi_device_path *a,
 }
 
 /*
- * See UEFI spec (section 3.1.2, about short-form device-paths..
- * tl;dr: we can have a device-path that starts with a USB WWID
- * or USB Class node, and a few other cases which don't encode
- * the full device path with bus hierarchy:
+ * We can have device paths that start with a USB WWID or a USB Class node,
+ * and a few other cases which don't encode the full device path with bus
+ * hierarchy:
  *
  *   - MESSAGING:USB_WWID
  *   - MESSAGING:USB_CLASS
  *   - MEDIA:FILE_PATH
  *   - MEDIA:HARD_DRIVE
  *   - MESSAGING:URI
+ *
+ * See UEFI spec (section 3.1.2, about short-form device-paths)
  */
 static struct efi_device_path *shorten_path(struct efi_device_path *dp)
 {
@@ -150,7 +151,7 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
                struct efi_device_path *obj_dp;
                efi_status_t ret;
 
-               ret = efi_search_protocol(efiobj->handle,
+               ret = efi_search_protocol(efiobj,
                                          &efi_guid_device_path, &handler);
                if (ret != EFI_SUCCESS)
                        continue;
@@ -644,7 +645,7 @@ static unsigned dp_part_size(struct blk_desc *desc, int part)
 /*
  * Create a device node for a block device partition.
  *
- * @buf                buffer to which the device path is wirtten
+ * @buf                buffer to which the device path is written
  * @desc       block device descriptor
  * @part       partition number, 0 identifies a block device
  */
@@ -709,7 +710,7 @@ static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
 /*
  * Create a device path for a block device or one of its partitions.
  *
- * @buf                buffer to which the device path is wirtten
+ * @buf                buffer to which the device path is written
  * @desc       block device descriptor
  * @part       partition number, 0 identifies a block device
  */
@@ -728,7 +729,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
        /*
         * We *could* make a more accurate path, by looking at if_type
         * and handling all the different cases like we do for non-
-        * legacy (ie CONFIG_BLK=y) case.  But most important thing
+        * legacy (i.e. CONFIG_BLK=y) case. But most important thing
         * is just to have a unique device-path for if_type+devnum.
         * So map things to a fictitious USB device.
         */
@@ -752,7 +753,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
        return dp_part_node(buf, desc, part);
 }
 
-/* Construct a device-path from a partition on a blk device: */
+/* Construct a device-path from a partition on a block device: */
 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
 {
        void *buf, *start;
@@ -771,7 +772,7 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
 /*
  * Create a device node for a block device partition.
  *
- * @buf                buffer to which the device path is wirtten
+ * @buf                buffer to which the device path is written
  * @desc       block device descriptor
  * @part       partition number, 0 identifies a block device
  */
@@ -791,7 +792,7 @@ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
        return buf;
 }
 
-/* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */
+/* convert path to an UEFI style path (i.e. DOS style backslashes and UTF-16) */
 static void path_to_uefi(u16 *uefi, const char *path)
 {
        while (*path) {
@@ -941,3 +942,53 @@ efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
        *file_path = fp;
        return EFI_SUCCESS;
 }
+
+efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
+                             const char *path,
+                             struct efi_device_path **device,
+                             struct efi_device_path **file)
+{
+       int is_net;
+       struct blk_desc *desc = NULL;
+       disk_partition_t fs_partition;
+       int part = 0;
+       char filename[32] = { 0 }; /* dp->str is u16[32] long */
+       char *s;
+
+       if (path && !file)
+               return EFI_INVALID_PARAMETER;
+
+       is_net = !strcmp(dev, "Net");
+       if (!is_net) {
+               part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
+                                              1);
+               if (part < 0)
+                       return EFI_INVALID_PARAMETER;
+
+               if (device)
+                       *device = efi_dp_from_part(desc, part);
+       } else {
+#ifdef CONFIG_NET
+               if (device)
+                       *device = efi_dp_from_eth();
+#endif
+       }
+
+       if (!path)
+               return EFI_SUCCESS;
+
+       if (!is_net) {
+               /* Add leading / to fs paths, because they're absolute */
+               snprintf(filename, sizeof(filename), "/%s", path);
+       } else {
+               snprintf(filename, sizeof(filename), "%s", path);
+       }
+       /* DOS style file path: */
+       s = filename;
+       while ((s = strchr(s, '/')))
+               *s++ = '\\';
+       *file = efi_dp_from_file(((!is_net && device) ? desc : NULL),
+                                part, filename);
+
+       return EFI_SUCCESS;
+}
index 0082236..e219f84 100644 (file)
@@ -269,9 +269,9 @@ static char *efi_convert_single_device_node_to_text(
  * for details.
  *
  * device_node         device node to be converted
- * display_only                true if the shorter text represenation shall be used
+ * display_only                true if the shorter text representation shall be used
  * allow_shortcuts     true if shortcut forms may be used
- * @return             text represenation of the device path
+ * @return             text representation of the device path
  *                     NULL if out of memory of device_path is NULL
  */
 static uint16_t EFIAPI *efi_convert_device_node_to_text(
@@ -302,9 +302,9 @@ out:
  * for details.
  *
  * device_path         device path to be converted
- * display_only                true if the shorter text represenation shall be used
+ * display_only                true if the shorter text representation shall be used
  * allow_shortcuts     true if shortcut forms may be used
- * @return             text represenation of the device path
+ * @return             text representation of the device path
  *                     NULL if out of memory of device_path is NULL
  */
 static uint16_t EFIAPI *efi_convert_device_path_to_text(
index 13fcc1b..c037526 100644 (file)
 
 const efi_guid_t efi_block_io_guid = BLOCK_IO_GUID;
 
+/**
+ * struct efi_disk_obj - EFI disk object
+ *
+ * @header:    EFI object header
+ * @ops:       EFI disk I/O protocol interface
+ * @ifname:    interface name for block device
+ * @dev_index: device index of block device
+ * @media:     block I/O media information
+ * @dp:                device path to the block device
+ * @part:      partition
+ * @volume:    simple file system protocol of the partition
+ * @offset:    offset into disk for simple partition
+ * @desc:      internal block device descriptor
+ */
 struct efi_disk_obj {
-       /* Generic EFI object parent class data */
-       struct efi_object parent;
-       /* EFI Interface callback struct for block I/O */
+       struct efi_object header;
        struct efi_block_io ops;
-       /* U-Boot ifname for block device */
        const char *ifname;
-       /* U-Boot dev_index for block device */
        int dev_index;
-       /* EFI Interface Media descriptor struct, referenced by ops */
        struct efi_block_io_media media;
-       /* EFI device path to this block device */
        struct efi_device_path *dp;
-       /* partition # */
        unsigned int part;
-       /* handle to filesys proto (for partition objects) */
        struct efi_simple_file_system_protocol *volume;
-       /* Offset into disk for simple partitions */
        lbaint_t offset;
-       /* Internal block device */
        struct blk_desc *desc;
 };
 
@@ -246,7 +250,7 @@ static efi_status_t efi_disk_add_dev(
                return EFI_OUT_OF_RESOURCES;
 
        /* Hook up to the device list */
-       efi_add_handle(&diskobj->parent);
+       efi_add_handle(&diskobj->header);
 
        /* Fill in object data */
        if (part) {
@@ -258,18 +262,18 @@ static efi_status_t efi_disk_add_dev(
                diskobj->dp = efi_dp_from_part(desc, part);
        }
        diskobj->part = part;
-       ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid,
+       ret = efi_add_protocol(&diskobj->header, &efi_block_io_guid,
                               &diskobj->ops);
        if (ret != EFI_SUCCESS)
                return ret;
-       ret = efi_add_protocol(diskobj->parent.handle, &efi_guid_device_path,
+       ret = efi_add_protocol(&diskobj->header, &efi_guid_device_path,
                               diskobj->dp);
        if (ret != EFI_SUCCESS)
                return ret;
        if (part >= 1) {
                diskobj->volume = efi_simple_file_system(desc, part,
                                                         diskobj->dp);
-               ret = efi_add_protocol(diskobj->parent.handle,
+               ret = efi_add_protocol(&diskobj->header,
                                       &efi_simple_file_system_protocol_guid,
                                       diskobj->volume);
                if (ret != EFI_SUCCESS)
@@ -381,7 +385,7 @@ efi_status_t efi_disk_register(void)
 
                /* Partitions show up as block devices in EFI */
                disks += efi_disk_create_partitions(
-                                       disk->parent.handle, desc, if_typename,
+                                       &disk->header, desc, if_typename,
                                        desc->devnum, dev->name);
        }
 #else
@@ -426,9 +430,9 @@ efi_status_t efi_disk_register(void)
                        disks++;
 
                        /* Partitions show up as block devices in EFI */
-                       disks += efi_disk_create_partitions(
-                                               disk->parent.handle, desc,
-                                               if_typename, i, devname);
+                       disks += efi_disk_create_partitions
+                                               (&disk->header, desc,
+                                                if_typename, i, devname);
                }
        }
 #endif
index beb4fba..128cb0a 100644 (file)
@@ -563,7 +563,7 @@ static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file,
                if (fh->isdir)
                        info->attribute |= EFI_FILE_DIRECTORY;
 
-               ascii2unicode((u16 *)info->file_name, filename);
+               ascii2unicode(info->file_name, filename);
        } else if (!guidcmp(info_type, &efi_file_system_info_guid)) {
                struct efi_file_system_info *info = buffer;
                disk_partition_t part;
index a4aa9bc..d62ce45 100644 (file)
@@ -16,15 +16,22 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static const efi_guid_t efi_gop_guid = EFI_GOP_GUID;
 
+/**
+ * struct efi_gop_obj - graphical output protocol object
+ *
+ * @header:    EFI object header
+ * @ops:       graphical output protocol interface
+ * @info:      graphical output mode information
+ * @mode:      graphical output mode
+ * @bpix:      bits per pixel
+ * @fb:                frame buffer
+ */
 struct efi_gop_obj {
-       /* Generic EFI object parent class data */
-       struct efi_object parent;
-       /* EFI Interface callback struct for gop */
+       struct efi_object header;
        struct efi_gop ops;
-       /* The only mode we support */
        struct efi_gop_mode_info info;
        struct efi_gop_mode mode;
-       /* Fields we only have acces to during init */
+       /* Fields we only have access to during init */
        u32 bpix;
        void *fb;
 };
@@ -236,12 +243,12 @@ static efi_uintn_t gop_get_bpp(struct efi_gop *this)
 }
 
 /*
- * Gcc can't optimize our BLT function well, but we need to make sure that
+ * GCC can't optimize our BLT function well, but we need to make sure that
  * our 2-dimensional loop gets executed very quickly, otherwise the system
  * will feel slow.
  *
  * By manually putting all obvious branch targets into functions which call
- * our generic blt function with constants, the compiler can successfully
+ * our generic BLT function with constants, the compiler can successfully
  * optimize for speed.
  */
 static efi_status_t gop_blt_video_fill(struct efi_gop *this,
@@ -439,13 +446,13 @@ efi_status_t efi_gop_register(void)
        }
 
        /* Hook up to the device list */
-       efi_add_handle(&gopobj->parent);
+       efi_add_handle(&gopobj->header);
 
        /* Fill in object data */
-       ret = efi_add_protocol(gopobj->parent.handle, &efi_gop_guid,
+       ret = efi_add_protocol(&gopobj->header, &efi_gop_guid,
                               &gopobj->ops);
        if (ret != EFI_SUCCESS) {
-               printf("ERROR: Failure adding gop protocol\n");
+               printf("ERROR: Failure adding GOP protocol\n");
                return ret;
        }
        gopobj->ops.query_mode = gop_query_mode;
@@ -463,7 +470,10 @@ efi_status_t efi_gop_register(void)
        if (bpix == LCD_COLOR32)
 #endif
        {
-               /* With 32bit color space we can directly expose the fb */
+               /*
+                * With 32bit color space we can directly expose the frame
+                * buffer
+                */
                gopobj->mode.fb_base = fb_base;
                gopobj->mode.fb_size = fb_size;
        }
index 5bd4f4d..4bb5174 100644 (file)
@@ -11,6 +11,7 @@
 #include <mapmem.h>
 #include <watchdog.h>
 #include <linux/list_sort.h>
+#include <linux/sizes.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -294,6 +295,12 @@ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
 {
        struct list_head *lhandle;
 
+       /*
+        * Prealign input max address, so we simplify our matching
+        * logic below and can just reuse it as return pointer.
+        */
+       max_addr &= ~EFI_PAGE_MASK;
+
        list_for_each(lhandle, &efi_mem) {
                struct efi_mem_list *lmem = list_entry(lhandle,
                        struct efi_mem_list, link);
@@ -378,7 +385,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
                /* Reserve that map in our memory maps */
                ret = efi_add_memory_map(addr, pages, memory_type, true);
                if (ret == addr) {
-                       *memory = (uintptr_t)map_sysmem(addr, len);
+                       *memory = addr;
                } else {
                        /* Map would overlap, bail out */
                        r = EFI_OUT_OF_RESOURCES;
@@ -391,7 +398,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
 void *efi_alloc(uint64_t len, int memory_type)
 {
        uint64_t ret = 0;
-       uint64_t pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+       uint64_t pages = efi_size_in_pages(len);
        efi_status_t r;
 
        r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type, pages,
@@ -412,12 +419,11 @@ void *efi_alloc(uint64_t len, int memory_type)
 efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
 {
        uint64_t r = 0;
-       uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
 
-       r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
+       r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
        /* Merging of adjacent free regions is missing */
 
-       if (r == addr)
+       if (r == memory)
                return EFI_SUCCESS;
 
        return EFI_NOT_FOUND;
@@ -435,8 +441,8 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
 {
        efi_status_t r;
        struct efi_pool_allocation *alloc;
-       u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
-                        EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+       u64 num_pages = efi_size_in_pages(size +
+                                         sizeof(struct efi_pool_allocation));
 
        if (!buffer)
                return EFI_INVALID_PARAMETER;
@@ -545,17 +551,51 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
 
 __weak void efi_add_known_memory(void)
 {
+       u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
        int i;
 
+       /* Fix for 32bit targets with ram_top at 4G */
+       if (!ram_top)
+               ram_top = 0x100000000ULL;
+
        /* Add RAM */
        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-               u64 ram_start = gd->bd->bi_dram[i].start;
-               u64 ram_size = gd->bd->bi_dram[i].size;
-               u64 start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
-               u64 pages = (ram_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+               u64 ram_end, ram_start, pages;
+
+               ram_start = (uintptr_t)map_sysmem(gd->bd->bi_dram[i].start, 0);
+               ram_end = ram_start + gd->bd->bi_dram[i].size;
+
+               /* Remove partial pages */
+               ram_end &= ~EFI_PAGE_MASK;
+               ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+
+               if (ram_end <= ram_start) {
+                       /* Invalid mapping, keep going. */
+                       continue;
+               }
+
+               pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+
+               efi_add_memory_map(ram_start, pages,
+                                  EFI_CONVENTIONAL_MEMORY, false);
 
-               efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY,
-                                  false);
+               /*
+                * Boards may indicate to the U-Boot memory core that they
+                * can not support memory above ram_top. Let's honor this
+                * in the efi_loader subsystem too by declaring any memory
+                * above ram_top as "already occupied by firmware".
+                */
+               if (ram_top < ram_start) {
+                       /* ram_top is before this region, reserve all */
+                       efi_add_memory_map(ram_start, pages,
+                                          EFI_BOOT_SERVICES_DATA, true);
+               } else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
+                       /* ram_top is inside this region, reserve parts */
+                       pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
+
+                       efi_add_memory_map(ram_top, pages,
+                                          EFI_BOOT_SERVICES_DATA, true);
+               }
        }
 }
 
@@ -563,6 +603,7 @@ __weak void efi_add_known_memory(void)
 static void add_u_boot_and_runtime(void)
 {
        unsigned long runtime_start, runtime_end, runtime_pages;
+       unsigned long runtime_mask = EFI_PAGE_MASK;
        unsigned long uboot_start, uboot_pages;
        unsigned long uboot_stack_size = 16 * 1024 * 1024;
 
@@ -571,10 +612,22 @@ static void add_u_boot_and_runtime(void)
        uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
        efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false);
 
-       /* Add Runtime Services */
-       runtime_start = (ulong)&__efi_runtime_start & ~EFI_PAGE_MASK;
+#if defined(__aarch64__)
+       /*
+        * Runtime Services must be 64KiB aligned according to the
+        * "AArch64 Platforms" section in the UEFI spec (2.7+).
+        */
+
+       runtime_mask = SZ_64K - 1;
+#endif
+
+       /*
+        * Add Runtime Services. We mark surrounding boottime code as runtime as
+        * well to fulfill the runtime alignment constraints but avoid padding.
+        */
+       runtime_start = (ulong)&__efi_runtime_start & ~runtime_mask;
        runtime_end = (ulong)&__efi_runtime_stop;
-       runtime_end = (runtime_end + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+       runtime_end = (runtime_end + runtime_mask) & ~runtime_mask;
        runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
        efi_add_memory_map(runtime_start, runtime_pages,
                           EFI_RUNTIME_SERVICES_CODE, false);
index 4e8b2d5..c7d9da8 100644 (file)
@@ -14,6 +14,8 @@ static const efi_guid_t efi_pxe_guid = EFI_PXE_GUID;
 static struct efi_pxe_packet *dhcp_ack;
 static bool new_rx_packet;
 static void *new_tx_packet;
+static void *transmit_buffer;
+
 /*
  * The notification function of this event is called in every timer cycle
  * to check if a new network packet has been received.
@@ -24,33 +26,85 @@ static struct efi_event *network_timer_event;
  */
 static struct efi_event *wait_for_packet;
 
+/**
+ * struct efi_net_obj - EFI object representing a network interface
+ *
+ * @header:    EFI object header
+ * @net:       simple network protocol interface
+ * @net_mode:  status of the network interface
+ * @pxe:       PXE base code protocol interface
+ * @pxe_mode:  status of the PXE base code protocol
+ */
 struct efi_net_obj {
-       /* Generic EFI object parent class data */
-       struct efi_object parent;
-       /* EFI Interface callback struct for network */
+       struct efi_object header;
        struct efi_simple_network net;
        struct efi_simple_network_mode net_mode;
-       /* PXE struct to transmit dhcp data */
        struct efi_pxe pxe;
        struct efi_pxe_mode pxe_mode;
 };
 
+/*
+ * efi_net_start() - start the network interface
+ *
+ * This function implements the Start service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * Return:     status code
+ */
 static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p", this);
 
-       return EFI_EXIT(EFI_SUCCESS);
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       if (this->mode->state != EFI_NETWORK_STOPPED)
+               ret = EFI_ALREADY_STARTED;
+       else
+               this->mode->state = EFI_NETWORK_STARTED;
+out:
+       return EFI_EXIT(ret);
 }
 
+/*
+ * efi_net_stop() - stop the network interface
+ *
+ * This function implements the Stop service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * Return:     status code
+ */
 static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p", this);
 
-       return EFI_EXIT(EFI_SUCCESS);
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       if (this->mode->state == EFI_NETWORK_STOPPED)
+               ret = EFI_NOT_STARTED;
+       else
+               this->mode->state = EFI_NETWORK_STOPPED;
+out:
+       return EFI_EXIT(ret);
 }
 
 /*
- * Initialize network adapter and allocate transmit and receive buffers.
+ * efi_net_initialize() - initialize the network interface
  *
  * This function implements the Initialize service of the
  * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
@@ -59,7 +113,7 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
  * @this:      pointer to the protocol instance
  * @extra_rx:  extra receive buffer to be allocated
  * @extra_tx:  extra transmit buffer to be allocated
- * @return:    status code
+ * Return:     status code
  */
 static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
                                              ulong extra_rx, ulong extra_tx)
@@ -69,9 +123,10 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
 
        EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx);
 
+       /* Check parameters */
        if (!this) {
                r = EFI_INVALID_PARAMETER;
-               goto error;
+               goto out;
        }
 
        /* Setup packet buffers */
@@ -84,32 +139,83 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
        ret = eth_init();
        if (ret < 0) {
                eth_halt();
+               this->mode->state = EFI_NETWORK_STOPPED;
                r = EFI_DEVICE_ERROR;
+               goto out;
+       } else {
+               this->mode->state = EFI_NETWORK_INITIALIZED;
        }
-
-error:
+out:
        return EFI_EXIT(r);
 }
 
+/*
+ * efi_net_reset() - reinitialize the network interface
+ *
+ * This function implements the Reset service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:                      pointer to the protocol instance
+ * @extended_verification:     execute exhaustive verification
+ * Return:                     status code
+ */
 static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
                                         int extended_verification)
 {
        EFI_ENTRY("%p, %x", this, extended_verification);
 
-       return EFI_EXIT(EFI_SUCCESS);
+       return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0)));
 }
 
+/*
+ * efi_net_shutdown() - shut down the network interface
+ *
+ * This function implements the Shutdown service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * Return:     status code
+ */
 static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p", this);
 
-       return EFI_EXIT(EFI_SUCCESS);
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       eth_halt();
+       this->mode->state = EFI_NETWORK_STOPPED;
+
+out:
+       return EFI_EXIT(ret);
 }
 
-static efi_status_t EFIAPI efi_net_receive_filters(
-               struct efi_simple_network *this, u32 enable, u32 disable,
-               int reset_mcast_filter, ulong mcast_filter_count,
-               struct efi_mac_address *mcast_filter)
+/*
+ * efi_net_receive_filters() - mange multicast receive filters
+ *
+ * This function implements the ReceiveFilters service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:              pointer to the protocol instance
+ * @enable:            bit mask of receive filters to enable
+ * @disable:           bit mask of receive filters to disable
+ * @reset_mcast_filter:        true resets contents of the filters
+ * @mcast_filter_count:        number of hardware MAC addresses in the new filters list
+ * @mcast_filter:      list of new filters
+ * Return:             status code
+ */
+static efi_status_t EFIAPI efi_net_receive_filters
+               (struct efi_simple_network *this, u32 enable, u32 disable,
+                int reset_mcast_filter, ulong mcast_filter_count,
+                struct efi_mac_address *mcast_filter)
 {
        EFI_ENTRY("%p, %x, %x, %x, %lx, %p", this, enable, disable,
                  reset_mcast_filter, mcast_filter_count, mcast_filter);
@@ -117,15 +223,40 @@ static efi_status_t EFIAPI efi_net_receive_filters(
        return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
-static efi_status_t EFIAPI efi_net_station_address(
-               struct efi_simple_network *this, int reset,
-               struct efi_mac_address *new_mac)
+/*
+ * efi_net_station_address() - set the hardware MAC address
+ *
+ * This function implements the StationAddress service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * @reset:     if true reset the address to default
+ * @new_mac:   new MAC address
+ * Return:     status code
+ */
+static efi_status_t EFIAPI efi_net_station_address
+               (struct efi_simple_network *this, int reset,
+                struct efi_mac_address *new_mac)
 {
        EFI_ENTRY("%p, %x, %p", this, reset, new_mac);
 
        return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * efi_net_statistics() - reset or collect statistics of the network interface
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * @reset:     if true, the statistics are reset
+ * @stat_size: size of the statistics table
+ * @stat_table:        table to receive the statistics
+ * Return:     status code
+ */
 static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
                                              int reset, ulong *stat_size,
                                              void *stat_table)
@@ -135,6 +266,19 @@ static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
        return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * efi_net_mcastiptomac() - translate multicast IP address to MAC address
+ *
+ * This function implements the Statistics service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:      pointer to the protocol instance
+ * @ipv6:      true if the IP address is an IPv6 address
+ * @ip:                IP address
+ * @mac:       MAC address
+ * Return:     status code
+ */
 static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
                                                int ipv6,
                                                struct efi_ip_address *ip,
@@ -145,6 +289,19 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
        return EFI_EXIT(EFI_INVALID_PARAMETER);
 }
 
+/**
+ * efi_net_nvdata() - read or write NVRAM
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this:              the instance of the Simple Network Protocol
+ * @readwrite:         true for read, false for write
+ * @offset:            offset in NVRAM
+ * @buffer_size:       size of buffer
+ * @buffer:            buffer
+ * Return:             status code
+ */
 static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this,
                                          int read_write, ulong offset,
                                          ulong buffer_size, char *buffer)
@@ -155,13 +312,42 @@ static efi_status_t EFIAPI efi_net_nvdata(struct efi_simple_network *this,
        return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/**
+ * efi_net_get_status() - get interrupt status
+ *
+ * This function implements the GetStatus service of the Simple Network
+ * Protocol. See the UEFI spec for details.
+ *
+ * @this:              the instance of the Simple Network Protocol
+ * @int_status:                interface status
+ * @txbuf:             transmission buffer
+ */
 static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
                                              u32 *int_status, void **txbuf)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p, %p, %p", this, int_status, txbuf);
 
        efi_timer_check();
 
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       switch (this->mode->state) {
+       case EFI_NETWORK_STOPPED:
+               ret = EFI_NOT_STARTED;
+               goto out;
+       case EFI_NETWORK_STARTED:
+               ret = EFI_DEVICE_ERROR;
+               goto out;
+       default:
+               break;
+       }
+
        if (int_status) {
                /* We send packets synchronously, so nothing is outstanding */
                *int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
@@ -172,65 +358,103 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
                *txbuf = new_tx_packet;
 
        new_tx_packet = NULL;
-
-       return EFI_EXIT(EFI_SUCCESS);
+out:
+       return EFI_EXIT(ret);
 }
 
-static efi_status_t EFIAPI efi_net_transmit(struct efi_simple_network *this,
-               size_t header_size, size_t buffer_size, void *buffer,
-               struct efi_mac_address *src_addr,
-               struct efi_mac_address *dest_addr, u16 *protocol)
+/**
+ * efi_net_transmit() - transmit a packet
+ *
+ * This function implements the Transmit service of the Simple Network Protocol.
+ * See the UEFI spec for details.
+ *
+ * @this:              the instance of the Simple Network Protocol
+ * @header_size:       size of the media header
+ * @buffer_size:       size of the buffer to receive the packet
+ * @buffer:            buffer to receive the packet
+ * @src_addr:          source hardware MAC address
+ * @dest_addr:         destination hardware MAC address
+ * @protocol:          type of header to build
+ * Return:             status code
+ */
+static efi_status_t EFIAPI efi_net_transmit
+               (struct efi_simple_network *this, size_t header_size,
+                size_t buffer_size, void *buffer,
+                struct efi_mac_address *src_addr,
+                struct efi_mac_address *dest_addr, u16 *protocol)
 {
+       efi_status_t ret = EFI_SUCCESS;
+
        EFI_ENTRY("%p, %lu, %lu, %p, %p, %p, %p", this,
                  (unsigned long)header_size, (unsigned long)buffer_size,
                  buffer, src_addr, dest_addr, protocol);
 
        efi_timer_check();
 
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       /* We do not support jumbo packets */
+       if (buffer_size > PKTSIZE_ALIGN) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
        if (header_size) {
-               /* We would need to create the header if header_size != 0 */
-               return EFI_EXIT(EFI_INVALID_PARAMETER);
+               /*
+                * TODO: We would need to create the header
+                * if header_size != 0
+                */
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       switch (this->mode->state) {
+       case EFI_NETWORK_STOPPED:
+               ret = EFI_NOT_STARTED;
+               goto out;
+       case EFI_NETWORK_STARTED:
+               ret = EFI_DEVICE_ERROR;
+               goto out;
+       default:
+               break;
        }
 
-#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
        /* Ethernet packets always fit, just bounce */
-       memcpy(efi_bounce_buffer, buffer, buffer_size);
-       net_send_packet(efi_bounce_buffer, buffer_size);
-#else
-       net_send_packet(buffer, buffer_size);
-#endif
+       memcpy(transmit_buffer, buffer, buffer_size);
+       net_send_packet(transmit_buffer, buffer_size);
 
        new_tx_packet = buffer;
 
-       return EFI_EXIT(EFI_SUCCESS);
-}
-
-static void efi_net_push(void *pkt, int len)
-{
-       new_rx_packet = true;
-       wait_for_packet->is_signaled = true;
+out:
+       return EFI_EXIT(ret);
 }
 
-/*
- * Receive a packet from a network interface.
+/**
+ * efi_net_receive() - receive a packet from a network interface
  *
  * This function implements the Receive service of the Simple Network Protocol.
  * See the UEFI spec for details.
  *
- * @this       the instance of the Simple Network Protocol
- * @header_size        size of the media header
- * @buffer_size        size of the buffer to receive the packet
- * @buffer     buffer to receive the packet
- * @src_addr   source MAC address
- * @dest_addr  destination MAC address
- * @protocol   protocol
- * @return     status code
+ * @this:              the instance of the Simple Network Protocol
+ * @header_size:       size of the media header
+ * @buffer_size:       size of the buffer to receive the packet
+ * @buffer:            buffer to receive the packet
+ * @src_addr:          source MAC address
+ * @dest_addr:         destination MAC address
+ * @protocol:          protocol
+ * Return:             status code
  */
-static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
-               size_t *header_size, size_t *buffer_size, void *buffer,
-               struct efi_mac_address *src_addr,
-               struct efi_mac_address *dest_addr, u16 *protocol)
+static efi_status_t EFIAPI efi_net_receive
+               (struct efi_simple_network *this, size_t *header_size,
+                size_t *buffer_size, void *buffer,
+                struct efi_mac_address *src_addr,
+                struct efi_mac_address *dest_addr, u16 *protocol)
 {
+       efi_status_t ret = EFI_SUCCESS;
        struct ethernet_hdr *eth_hdr;
        size_t hdr_size = sizeof(struct ethernet_hdr);
        u16 protlen;
@@ -238,14 +462,35 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
        EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size,
                  buffer_size, buffer, src_addr, dest_addr, protocol);
 
+       /* Execute events */
        efi_timer_check();
 
-       if (!new_rx_packet)
-               return EFI_EXIT(EFI_NOT_READY);
+       /* Check parameters */
+       if (!this) {
+               ret = EFI_INVALID_PARAMETER;
+               goto out;
+       }
+
+       switch (this->mode->state) {
+       case EFI_NETWORK_STOPPED:
+               ret = EFI_NOT_STARTED;
+               goto out;
+       case EFI_NETWORK_STARTED:
+               ret = EFI_DEVICE_ERROR;
+               goto out;
+       default:
+               break;
+       }
+
+       if (!new_rx_packet) {
+               ret = EFI_NOT_READY;
+               goto out;
+       }
        /* Check that we at least received an Ethernet header */
        if (net_rx_packet_len < sizeof(struct ethernet_hdr)) {
                new_rx_packet = false;
-               return EFI_EXIT(EFI_NOT_READY);
+               ret = EFI_NOT_READY;
+               goto out;
        }
        /* Fill export parameters */
        eth_hdr = (struct ethernet_hdr *)net_rx_packet;
@@ -263,18 +508,24 @@ static efi_status_t EFIAPI efi_net_receive(struct efi_simple_network *this,
        if (protocol)
                *protocol = protlen;
        if (*buffer_size < net_rx_packet_len) {
-               /* Packet doesn't fit, try again with bigger buf */
+               /* Packet doesn't fit, try again with bigger buffer */
                *buffer_size = net_rx_packet_len;
-               return EFI_EXIT(EFI_BUFFER_TOO_SMALL);
+               ret = EFI_BUFFER_TOO_SMALL;
+               goto out;
        }
        /* Copy packet */
        memcpy(buffer, net_rx_packet, net_rx_packet_len);
        *buffer_size = net_rx_packet_len;
        new_rx_packet = false;
-
-       return EFI_EXIT(EFI_SUCCESS);
+out:
+       return EFI_EXIT(ret);
 }
 
+/**
+ * efi_net_set_dhcp_ack() - take note of a selected DHCP IP address
+ *
+ * This function is called by dhcp_handler().
+ */
 void efi_net_set_dhcp_ack(void *pkt, int len)
 {
        int maxsize = sizeof(*dhcp_ack);
@@ -285,8 +536,22 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
        memcpy(dhcp_ack, pkt, min(len, maxsize));
 }
 
-/*
- * Check if a new network packet has been received.
+/**
+ * efi_net_push() - callback for received network packet
+ *
+ * This function is called when a network packet is received by eth_rx().
+ *
+ * @pkt:       network packet
+ * @len:       length
+ */
+static void efi_net_push(void *pkt, int len)
+{
+       new_rx_packet = true;
+       wait_for_packet->is_signaled = true;
+}
+
+/**
+ * efi_network_timer_notify() - check if a new network packet has been received
  *
  * This notification function is called in every timer cycle.
  *
@@ -296,47 +561,65 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
 static void EFIAPI efi_network_timer_notify(struct efi_event *event,
                                            void *context)
 {
+       struct efi_simple_network *this = (struct efi_simple_network *)context;
+
        EFI_ENTRY("%p, %p", event, context);
 
+       /*
+        * Some network drivers do not support calling eth_rx() before
+        * initialization.
+        */
+       if (!this || this->mode->state != EFI_NETWORK_INITIALIZED)
+               goto out;
+
        if (!new_rx_packet) {
                push_packet = efi_net_push;
                eth_rx();
                push_packet = NULL;
        }
+out:
        EFI_EXIT(EFI_SUCCESS);
 }
 
-/* This gets called from do_bootefi_exec(). */
+/**
+ * efi_net_register() - register the simple network protocol
+ *
+ * This gets called from do_bootefi_exec().
+ */
 efi_status_t efi_net_register(void)
 {
-       struct efi_net_obj *netobj;
+       struct efi_net_obj *netobj = NULL;
        efi_status_t r;
 
        if (!eth_get_dev()) {
-               /* No eth device active, don't expose any */
+               /* No network device active, don't expose any */
                return EFI_SUCCESS;
        }
 
-       /* We only expose the "active" eth device, so one is enough */
+       /* We only expose the "active" network device, so one is enough */
        netobj = calloc(1, sizeof(*netobj));
-       if (!netobj) {
-               printf("ERROR: Out of memory\n");
-               return EFI_OUT_OF_RESOURCES;
-       }
+       if (!netobj)
+               goto out_of_resources;
+
+       /* Allocate an aligned transmit buffer */
+       transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
+       if (!transmit_buffer)
+               goto out_of_resources;
+       transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN);
 
        /* Hook net up to the device list */
-       efi_add_handle(&netobj->parent);
+       efi_add_handle(&netobj->header);
 
        /* Fill in object data */
-       r = efi_add_protocol(netobj->parent.handle, &efi_net_guid,
+       r = efi_add_protocol(&netobj->header, &efi_net_guid,
                             &netobj->net);
        if (r != EFI_SUCCESS)
                goto failure_to_add_protocol;
-       r = efi_add_protocol(netobj->parent.handle, &efi_guid_device_path,
+       r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
                             efi_dp_from_eth());
        if (r != EFI_SUCCESS)
                goto failure_to_add_protocol;
-       r = efi_add_protocol(netobj->parent.handle, &efi_pxe_guid,
+       r = efi_add_protocol(&netobj->header, &efi_pxe_guid,
                             &netobj->pxe);
        if (r != EFI_SUCCESS)
                goto failure_to_add_protocol;
@@ -385,13 +668,13 @@ efi_status_t efi_net_register(void)
         * iPXE is running at TPL_CALLBACK most of the time. Use a higher TPL.
         */
        r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
-                            efi_network_timer_notify, NULL, NULL,
+                            efi_network_timer_notify, &netobj->net, NULL,
                             &network_timer_event);
        if (r != EFI_SUCCESS) {
                printf("ERROR: Failed to register network event\n");
                return r;
        }
-       /* Network is time critical, create event in every timer cyle */
+       /* Network is time critical, create event in every timer cycle */
        r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0);
        if (r != EFI_SUCCESS) {
                printf("ERROR: Failed to set network timer\n");
@@ -402,4 +685,9 @@ efi_status_t efi_net_register(void)
 failure_to_add_protocol:
        printf("ERROR: Failure to add protocol\n");
        return r;
+out_of_resources:
+       free(netobj);
+       /* free(transmit_buffer) not needed yet */
+       printf("ERROR: Out of memory\n");
+       return EFI_OUT_OF_RESOURCES;
 }
index f059dc9..95844ef 100644 (file)
@@ -141,7 +141,9 @@ static void EFIAPI efi_reset_system_boottime(
                do_reset(NULL, 0, 0, NULL);
                break;
        case EFI_RESET_SHUTDOWN:
-               /* We don't have anything to map this to */
+#ifdef CONFIG_CMD_POWEROFF
+               do_poweroff(NULL, 0, 0, NULL);
+#endif
                break;
        }
 
@@ -282,7 +284,7 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = {
        }, {
                /* invalidate_*cache_all are gone */
                .ptr = &efi_runtime_services.set_virtual_address_map,
-               .patchto = &efi_invalid_parameter,
+               .patchto = &efi_unimplemented,
        }, {
                /* RTC accessors are gone */
                .ptr = &efi_runtime_services.get_time,
@@ -378,6 +380,9 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
                        ulong symidx = rel->info >> SYM_INDEX;
                        extern struct dyn_sym __dyn_sym_start[];
                        newaddr = __dyn_sym_start[symidx].addr + offset;
+#ifdef IS_RELA
+                       newaddr -= CONFIG_SYS_TEXT_BASE;
+#endif
                        break;
                }
 #endif
@@ -623,8 +628,8 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
 efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
                        struct efi_capsule_header **capsule_header_array,
                        efi_uintn_t capsule_count,
-                       u64 maximum_capsule_size,
-                       u32 reset_type)
+                       u64 *maximum_capsule_size,
+                       u32 *reset_type)
 {
        return EFI_UNSUPPORTED;
 }
index 38e42fa..a814884 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <efi_loader.h>
+#include <mapmem.h>
 #include <smbios.h>
 
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
@@ -19,17 +20,19 @@ static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
 efi_status_t efi_smbios_register(void)
 {
        /* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
-       u64 dmi = U32_MAX;
+       u64 dmi_addr = U32_MAX;
        efi_status_t ret;
+       void *dmi;
 
        /* Reserve 4kiB page for SMBIOS */
        ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
-                                EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+                                EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr);
 
        if (ret != EFI_SUCCESS) {
                /* Could not find space in lowmem, use highmem instead */
                ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
-                                        EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+                                        EFI_RUNTIME_SERVICES_DATA, 1,
+                                        &dmi_addr);
 
                if (ret != EFI_SUCCESS)
                        return ret;
@@ -39,11 +42,14 @@ efi_status_t efi_smbios_register(void)
         * Generate SMBIOS tables - we know that efi_allocate_pages() returns
         * a 4k-aligned address, so it is safe to assume that
         * write_smbios_table() will write the table at that address.
+        *
+        * Note that on sandbox, efi_allocate_pages() unfortunately returns a
+        * pointer even though it uses a uint64_t type. Convert it.
         */
-       assert(!(dmi & 0xf));
-       write_smbios_table(dmi);
+       assert(!(dmi_addr & 0xf));
+       dmi = (void *)(uintptr_t)dmi_addr;
+       write_smbios_table(map_to_sysmem(dmi));
 
        /* And expose them to our EFI payload */
-       return efi_install_configuration_table(&smbios_guid,
-                                              (void *)(uintptr_t)dmi);
+       return efi_install_configuration_table(&smbios_guid, dmi);
 }
index 3b8de5b..2905479 100644 (file)
@@ -17,6 +17,16 @@ static const efi_guid_t fdt_guid = EFI_FDT_GUID;
 static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
 
+/**
+ * hw_memcmp() - compare memory areas
+ *
+ * @buf1:      pointer to first area
+ * @buf2:      pointer to second area
+ * @length:    number of bytes to compare
+ * Return:     0 if both memory areas are the same, otherwise the sign of the
+ *             result value is the same as the sign of ghe difference between
+ *             the first differing pair of bytes taken as u8.
+ */
 static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
 {
        const u8 *pos1 = buf1;
@@ -31,12 +41,12 @@ static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
        return 0;
 }
 
-/*
- * Entry point of the EFI application.
+/**
+ * efi_main() - entry point of the EFI application.
  *
- * @handle     handle of the loaded image
- * @systable   system table
- * @return     status code
+ * @handle:    handle of the loaded image
+ * @systable:  system table
+ * @return:    status code
  */
 efi_status_t EFIAPI efi_main(efi_handle_t handle,
                             struct efi_system_table *systable)
@@ -48,7 +58,8 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
        efi_uintn_t i;
        u16 rev[] = L"0.0.0";
 
-       con_out->output_string(con_out, L"Hello, world!\n");
+       /* UEFI requires CR LF */
+       con_out->output_string(con_out, L"Hello, world!\r\n");
 
        /* Print the revision number */
        rev[0] = (systable->hdr.revision >> 16) + '0';
@@ -65,27 +76,30 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
 
        con_out->output_string(con_out, L"Running on UEFI ");
        con_out->output_string(con_out, rev);
-       con_out->output_string(con_out, L"\n");
+       con_out->output_string(con_out, L"\r\n");
 
        /* Get the loaded image protocol */
        ret = boottime->handle_protocol(handle, &loaded_image_guid,
                                        (void **)&loaded_image);
        if (ret != EFI_SUCCESS) {
-               con_out->output_string(con_out,
-                                      L"Cannot open loaded image protocol\n");
+               con_out->output_string
+                       (con_out, L"Cannot open loaded image protocol\r\n");
                goto out;
        }
        /* Find configuration tables */
        for (i = 0; i < systable->nr_tables; ++i) {
                if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid,
                               sizeof(efi_guid_t)))
-                       con_out->output_string(con_out, L"Have device tree\n");
+                       con_out->output_string
+                                       (con_out, L"Have device tree\r\n");
                if (!hw_memcmp(&systable->tables[i].guid, &acpi_guid,
                               sizeof(efi_guid_t)))
-                       con_out->output_string(con_out, L"Have ACPI 2.0 table\n");
+                       con_out->output_string
+                                       (con_out, L"Have ACPI 2.0 table\r\n");
                if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid,
                               sizeof(efi_guid_t)))
-                       con_out->output_string(con_out, L"Have SMBIOS table\n");
+                       con_out->output_string
+                                       (con_out, L"Have SMBIOS table\r\n");
        }
        /* Output the load options */
        con_out->output_string(con_out, L"Load options: ");
@@ -94,7 +108,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
                                       (u16 *)loaded_image->load_options);
        else
                con_out->output_string(con_out, L"<none>");
-       con_out->output_string(con_out, L"\n");
+       con_out->output_string(con_out, L"\r\n");
 
 out:
        boottime->exit(handle, ret, 0, NULL);
index b526967..59f9f36 100644 (file)
@@ -1,6 +1,6 @@
 config CMD_BOOTEFI_SELFTEST
        bool "Allow booting an EFI efi_selftest"
-       depends on CMD_BOOTEFI && !SANDBOX
+       depends on CMD_BOOTEFI
        imply FAT
        imply FAT_WRITE
        help
index 2f55d9d..743b482 100644 (file)
@@ -10,7 +10,7 @@ CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) -Os
 CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding
 CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) -Os
 
-obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
+obj-y += \
 efi_selftest.o \
 efi_selftest_bitblt.o \
 efi_selftest_config_table.o \
@@ -21,11 +21,13 @@ efi_selftest_devicepath.o \
 efi_selftest_devicepath_util.o \
 efi_selftest_events.o \
 efi_selftest_event_groups.o \
+efi_selftest_exception.o \
 efi_selftest_exitbootservices.o \
 efi_selftest_fdt.o \
 efi_selftest_gop.o \
 efi_selftest_loaded_image.o \
 efi_selftest_manageprotocols.o \
+efi_selftest_memory.o \
 efi_selftest_rtc.o \
 efi_selftest_snp.o \
 efi_selftest_textinput.o \
@@ -37,20 +39,16 @@ efi_selftest_util.o \
 efi_selftest_variables.o \
 efi_selftest_watchdog.o
 
-ifeq ($(CONFIG_CMD_BOOTEFI_SELFTEST),y)
 obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
-endif
 
 ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
-obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o
+obj-y += efi_selftest_block_device.o
 endif
 
 # TODO: As of v2018.01 the relocation code for the EFI application cannot
 # be built on x86_64.
 ifeq ($(CONFIG_X86_64)$(CONFIG_SANDBOX),)
 
-ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
-
 obj-y += \
 efi_selftest_startimage_exit.o \
 efi_selftest_startimage_return.o
@@ -74,5 +72,3 @@ $(obj)/efi_selftest_startimage_exit.o: $(obj)/efi_miniapp_file_image_exit.h
 $(obj)/efi_selftest_startimage_return.o: $(obj)/efi_miniapp_file_image_return.h
 
 endif
-
-endif
index dd338db..5b01610 100644 (file)
@@ -18,6 +18,7 @@ static const struct efi_boot_services *boottime;
 static const struct efi_runtime_services *runtime;
 static efi_handle_t handle;
 static u16 reset_message[] = L"Selftest completed";
+static int *setup_status;
 
 /*
  * Exit the boot services.
@@ -74,20 +75,20 @@ void efi_st_exit_boot_services(void)
  */
 static int setup(struct efi_unit_test *test, unsigned int *failures)
 {
-       if (!test->setup) {
-               test->setup_ok = EFI_ST_SUCCESS;
+       int ret;
+
+       if (!test->setup)
                return EFI_ST_SUCCESS;
-       }
        efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name);
-       test->setup_ok = test->setup(handle, systable);
-       if (test->setup_ok != EFI_ST_SUCCESS) {
+       ret = test->setup(handle, systable);
+       if (ret != EFI_ST_SUCCESS) {
                efi_st_error("Setting up '%s' failed\n", test->name);
                ++*failures;
        } else {
                efi_st_printc(EFI_LIGHTGREEN,
                              "Setting up '%s' succeeded\n", test->name);
        }
-       return test->setup_ok;
+       return ret;
 }
 
 /*
@@ -186,18 +187,20 @@ static void list_all_tests(void)
 void efi_st_do_tests(const u16 *testname, unsigned int phase,
                     unsigned int steps, unsigned int *failures)
 {
+       int i = 0;
        struct efi_unit_test *test;
 
        for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
-            test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
+            test < ll_entry_end(struct efi_unit_test, efi_unit_test);
+            ++test, ++i) {
                if (testname ?
                    efi_st_strcmp_16_8(testname, test->name) : test->on_request)
                        continue;
                if (test->phase != phase)
                        continue;
                if (steps & EFI_ST_SETUP)
-                       setup(test, failures);
-               if (steps & EFI_ST_EXECUTE && test->setup_ok == EFI_ST_SUCCESS)
+                       setup_status[i] = setup(test, failures);
+               if (steps & EFI_ST_EXECUTE && setup_status[i] == EFI_ST_SUCCESS)
                        execute(test, failures);
                if (steps & EFI_ST_TEARDOWN)
                        teardown(test, failures);
@@ -271,6 +274,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
                              ll_entry_count(struct efi_unit_test,
                                             efi_unit_test));
 
+       /* Allocate buffer for setup results */
+       ret = boottime->allocate_pool(EFI_RUNTIME_SERVICES_DATA, sizeof(int) *
+                                     ll_entry_count(struct efi_unit_test,
+                                                    efi_unit_test),
+                                     (void **)&setup_status);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("Allocate pool failed\n");
+               return ret;
+       }
+
        /* Execute boottime tests */
        efi_st_do_tests(testname, EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
                        EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,
index 2aa3fc7..0bc5da6 100644 (file)
@@ -18,7 +18,7 @@ static efi_guid_t table_guid =
                 0x17, 0x2e, 0x51, 0x6b, 0x49, 0x75);
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event      notified event
@@ -33,23 +33,23 @@ static void EFIAPI notify(struct efi_event *event, void *context)
 }
 
 /*
- * Check crc32 of a table.
+ * Check CRC32 of a table.
  */
 static int check_table(const void *table)
 {
        efi_status_t ret;
        u32 crc32, res;
-       /* Casting from const to not const */
+       /* Casting from constant to not constant */
        struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
 
        crc32 = hdr->crc32;
        /*
-        * Setting the crc32 of the 'const' table to zero is easier than
+        * Setting the CRC32 of the 'const' table to zero is easier than
         * copying
         */
        hdr->crc32 = 0;
        ret = boottime->calculate_crc32(table, hdr->headersize, &res);
-       /* Reset table crc32 so it stays constant */
+       /* Reset table CRC32 so it stays constant */
        hdr->crc32 = crc32;
        if (ret != EFI_ST_SUCCESS) {
                efi_st_error("CalculateCrc32 failed\n");
@@ -203,7 +203,7 @@ static int execute(void)
                return EFI_ST_FAILURE;
        }
        if (tabcnt > 1) {
-               efi_st_error("Duplicate table guid\n");
+               efi_st_error("Duplicate table GUID\n");
                return EFI_ST_FAILURE;
        }
        if (table != &tables[1]) {
index d08c377..38720bb 100644 (file)
@@ -33,7 +33,7 @@ static efi_handle_t handle_driver;
  * Count child controllers
  *
  * @handle     handle on which child controllers are installed
- * @protocol   protocol for which the child controlles where installed
+ * @protocol   protocol for which the child controllers were installed
  * @count      number of child controllers
  * @return     status code
  */
index 8555b8f..4881e8a 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
  * This unit test checks the CalculateCrc32 bootservice and checks the
- * headers of the system table, the boot services tablle, and the runtime
+ * headers of the system table, the boot services table, and the runtime
  * services table before and after ExitBootServices().
  */
 
@@ -19,7 +19,7 @@ static int check_table(const void *table)
 {
        efi_status_t ret;
        u32 crc32, res;
-       /* Casting from const to not const */
+       /* Casting from constant to not constant */
        struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
 
        if (!hdr->signature) {
index adcf531..105ce2c 100644 (file)
@@ -257,7 +257,7 @@ static int teardown(void)
 static int execute(void)
 {
        struct efi_device_path *remaining_dp;
-       void *handle;
+       efi_handle_t handle;
        /*
         * This device path node ends with the letter 't' of 'u-boot'.
         * The following '.bin' does not belong to the node but is
index 9b3c513..5a7980c 100644 (file)
@@ -19,7 +19,7 @@ static efi_guid_t event_group =
                 0x0e, 0x5b, 0x45, 0xc0, 0x56, 0x91);
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event      notified event
@@ -114,7 +114,7 @@ static int execute(void)
                                              (unsigned int)i, (unsigned int)j,
                                              (unsigned int)counter[j]);
                                efi_st_error(
-                                       "Nofification function not called\n");
+                                       "Notification function not called\n");
                                return EFI_ST_FAILURE;
                        }
                }
index 47f9f99..ed99a53 100644 (file)
@@ -17,7 +17,7 @@ static unsigned int timer_ticks;
 static struct efi_boot_services *boottime;
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event      notified event
diff --git a/lib/efi_selftest/efi_selftest_exception.c b/lib/efi_selftest/efi_selftest_exception.c
new file mode 100644 (file)
index 0000000..76cfb88
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_exception
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test the handling of exceptions by trying to execute an undefined
+ * instruction.
+ */
+
+#include <efi_selftest.h>
+
+/**
+ * undefined_instruction() - try to executed an undefined instruction
+ */
+static void undefined_instruction(void)
+{
+#if defined(CONFIG_ARM)
+       /*
+        * 0xe7f...f.   is undefined in ARM mode
+        * 0xde..       is undefined in Thumb mode
+        */
+       asm volatile (".word 0xe7f7defb\n");
+#elif defined(CONFIG_RISCV)
+       asm volatile (".word 0xffffffff\n");
+#elif defined(CONFIG_X86)
+       asm volatile (".word 0xffff\n");
+#endif
+}
+
+/**
+ * execute() - execute unit test
+ *
+ * Return:     EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+       undefined_instruction();
+
+       efi_st_error("An undefined instruction exception was not raised\n");
+
+       return EFI_ST_FAILURE;
+}
+
+EFI_UNIT_TEST(exception) = {
+       .name = "exception",
+       .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+       .execute = execute,
+       .on_request = true,
+};
index c7bc242..d545d51 100644 (file)
@@ -16,7 +16,7 @@
 static struct efi_boot_services *boottime;
 static const char *fdt;
 
-/* This should be sufficent for */
+/* This should be sufficient for */
 #define BUFFERSIZE 0x100000
 
 static efi_guid_t fdt_guid = EFI_FDT_GUID;
index f9b54ae..ea2b380 100644 (file)
@@ -53,7 +53,7 @@ static int execute(void)
                efi_st_error("ProtocolsPerHandle failed\n");
                return EFI_ST_FAILURE;
        }
-       if (!protocol_buffer_count | !protocol_buffer) {
+       if (!protocol_buffer_count || !protocol_buffer) {
                efi_st_error("ProtocolsPerHandle returned no protocol\n");
                return EFI_ST_FAILURE;
        }
index b09e4cd..0ff35ce 100644 (file)
@@ -189,7 +189,14 @@ static int execute(void)
        /*
         * Test error handling in UninstallMultipleProtocols
         *
-        * Try to uninstall more protocols than there are installed.
+        * These are the installed protocol interfaces on handle 2:
+        *
+        *   guid1 interface4
+        *   guid2 interface2
+        *
+        * Try to uninstall more protocols than there are installed. This
+        * should return an error EFI_INVALID_PARAMETER. All deleted protocols
+        * should be reinstalled.
         */
        ret = boottime->uninstall_multiple_protocol_interfaces(
                                                handle2,
@@ -197,13 +204,18 @@ static int execute(void)
                                                &guid2, &interface2,
                                                &guid3, &interface3,
                                                NULL);
-       if (ret == EFI_SUCCESS) {
+       if (ret != EFI_INVALID_PARAMETER) {
+               printf("%lx", ret);
                efi_st_error("UninstallMultipleProtocolInterfaces did not catch error\n");
                return EFI_ST_FAILURE;
        }
 
        /*
         * Test LocateHandleBuffer with ByProtocol
+        *
+        * These are the handles with a guid1 protocol interface installed:
+        *
+        *      handle1, handle2
         */
        count = buffer_size;
        ret = boottime->locate_handle_buffer(BY_PROTOCOL, &guid1, NULL,
@@ -213,7 +225,7 @@ static int execute(void)
                return EFI_ST_FAILURE;
        }
        if (count != 2) {
-               efi_st_error("LocateHandleBuffer failed to locate new handles\n");
+               efi_st_error("UninstallMultipleProtocolInterfaces deleted handle\n");
                return EFI_ST_FAILURE;
        }
        ret = find_in_buffer(handle1, count, buffer);
diff --git a/lib/efi_selftest/efi_selftest_memory.c b/lib/efi_selftest/efi_selftest_memory.c
new file mode 100644 (file)
index 0000000..24b4438
--- /dev/null
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_memory
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This unit test checks the following runtime services:
+ * AllocatePages, FreePages, GetMemoryMap
+ *
+ * The memory type used for the device tree is checked.
+ */
+
+#include <efi_selftest.h>
+
+#define EFI_ST_NUM_PAGES 8
+
+static const efi_guid_t fdt_guid = EFI_FDT_GUID;
+static struct efi_boot_services *boottime;
+static u64 fdt_addr;
+
+/**
+ * setup() - setup unit test
+ *
+ * @handle:    handle of the loaded image
+ * @systable:  system table
+ * Return:     EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+                const struct efi_system_table *systable)
+{
+       size_t i;
+
+       boottime = systable->boottime;
+
+       for (i = 0; i < systable->nr_tables; ++i) {
+               if (!efi_st_memcmp(&systable->tables[i].guid, &fdt_guid,
+                                  sizeof(efi_guid_t))) {
+                       if (fdt_addr) {
+                               efi_st_error("Duplicate device tree\n");
+                               return EFI_ST_FAILURE;
+                       }
+                       fdt_addr = (uintptr_t)systable->tables[i].table;
+               }
+       }
+       return EFI_ST_SUCCESS;
+}
+
+/**
+ * find_in_memory_map() - check matching memory map entry exists
+ *
+ * @memory_map:                memory map
+ * @desc_size:         number of memory map entries
+ * @addr:              physical address to find in the map
+ * @type:              expected memory type
+ * Return:             EFI_ST_SUCCESS for success
+ */
+static int find_in_memory_map(efi_uintn_t map_size,
+                             struct efi_mem_desc *memory_map,
+                             efi_uintn_t desc_size,
+                             u64 addr, int memory_type)
+{
+       efi_uintn_t i;
+       bool found = false;
+
+       for (i = 0; map_size; ++i, map_size -= desc_size) {
+               struct efi_mem_desc *entry = &memory_map[i];
+
+               if (addr >= entry->physical_start &&
+                   addr < entry->physical_start +
+                           (entry->num_pages << EFI_PAGE_SHIFT)) {
+                       if (found) {
+                               efi_st_error("Duplicate memory map entry\n");
+                               return EFI_ST_FAILURE;
+                       }
+                       found = true;
+                       if (memory_type != entry->type) {
+                               efi_st_error
+                                       ("Wrong memory type %d, expected %d\n",
+                                        entry->type, memory_type);
+                               return EFI_ST_FAILURE;
+                       }
+               }
+       }
+       if (!found) {
+               efi_st_error("Missing memory map entry\n");
+               return EFI_ST_FAILURE;
+       }
+       return EFI_ST_SUCCESS;
+}
+
+/*
+ * execute() - execute unit test
+ *
+ * Return:     EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+       u64 p1;
+       u64 p2;
+       efi_uintn_t map_size = 0;
+       efi_uintn_t map_key;
+       efi_uintn_t desc_size;
+       u32 desc_version;
+       struct efi_mem_desc *memory_map;
+       efi_status_t ret;
+
+       /* Allocate two page ranges with different memory type */
+       ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+                                      EFI_RUNTIME_SERVICES_CODE,
+                                      EFI_ST_NUM_PAGES, &p1);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+                                      EFI_RUNTIME_SERVICES_DATA,
+                                      EFI_ST_NUM_PAGES, &p2);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Load memory map */
+       ret = boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size,
+                                      &desc_version);
+       if (ret != EFI_BUFFER_TOO_SMALL) {
+               efi_st_error
+                       ("GetMemoryMap did not return EFI_BUFFER_TOO_SMALL\n");
+               return EFI_ST_FAILURE;
+       }
+       /* Allocate extra space for newly allocated memory */
+       map_size += sizeof(struct efi_mem_desc);
+       ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size,
+                                     (void **)&memory_map);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePool did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->get_memory_map(&map_size, memory_map, &map_key,
+                                      &desc_size, &desc_version);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("GetMemoryMap did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Check memory map entries */
+       if (find_in_memory_map(map_size, memory_map, desc_size, p1,
+                              EFI_RUNTIME_SERVICES_CODE) != EFI_ST_SUCCESS)
+               return EFI_ST_FAILURE;
+       if (find_in_memory_map(map_size, memory_map, desc_size, p2,
+                              EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS)
+               return EFI_ST_FAILURE;
+
+       /* Free memory */
+       ret = boottime->free_pages(p1, EFI_ST_NUM_PAGES);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->free_pages(p2, EFI_ST_NUM_PAGES);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->free_pool(memory_map);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePool did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Check memory reservation for the device tree */
+       if (fdt_addr &&
+           find_in_memory_map(map_size, memory_map, desc_size, fdt_addr,
+                              EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS) {
+               efi_st_error
+                       ("Device tree not marked as runtime services data\n");
+               return EFI_ST_FAILURE;
+       }
+       return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(memory) = {
+       .name = "memory",
+       .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+       .setup = setup,
+       .execute = execute,
+};
index 09bd53d..e10a34b 100644 (file)
@@ -103,7 +103,7 @@ static efi_status_t send_dhcp_discover(void)
        struct dhcp p = {};
 
        /*
-        * Fill ethernet header
+        * Fill Ethernet header
         */
        boottime->copy_mem(p.eth_hdr.et_dest, (void *)BROADCAST_MAC, ARP_HLEN);
        boottime->copy_mem(p.eth_hdr.et_src, &net->mode->current_address,
@@ -229,19 +229,19 @@ static int setup(const efi_handle_t handle,
                return EFI_ST_FAILURE;
        }
        /*
-        * Initialize network adapter.
+        * Start network adapter.
         */
-       ret = net->initialize(net, 0, 0);
-       if (ret != EFI_SUCCESS) {
-               efi_st_error("Failed to initialize network adapter\n");
+       ret = net->start(net);
+       if (ret != EFI_SUCCESS && ret != EFI_ALREADY_STARTED) {
+               efi_st_error("Failed to start network adapter\n");
                return EFI_ST_FAILURE;
        }
        /*
-        * Start network adapter.
+        * Initialize network adapter.
         */
-       ret = net->start(net);
+       ret = net->initialize(net, 0, 0);
        if (ret != EFI_SUCCESS) {
-               efi_st_error("Failed to start network adapter\n");
+               efi_st_error("Failed to initialize network adapter\n");
                return EFI_ST_FAILURE;
        }
        return EFI_ST_SUCCESS;
index 164fbff..b90671c 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
  * Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
- * The unicode character and the scan code are printed for text
+ * The Unicode character and the scan code are printed for text
  * input. To run the test:
  *
  *     setenv efi_selftest text input
index 61ae46b..97d256a 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * efi_selftest_events
+ * efi_selftest_tpl
  *
  * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
index 9765bd3..7529430 100644 (file)
@@ -52,7 +52,7 @@ static int test_stri_coll(void)
                                                    c1, c2);
        if (ret) {
                efi_st_error(
-                       "stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c2, ret);
+                       "stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c2, (int)ret);
                return EFI_ST_FAILURE;
        }
 
@@ -60,7 +60,7 @@ static int test_stri_coll(void)
                                                    c1, c3);
        if (ret >= 0) {
                efi_st_error(
-                       "stri_coll(\"%ps\", \"%ps\") = %zu\n", c1, c3, ret);
+                       "stri_coll(\"%ps\", \"%ps\") = %d\n", c1, c3, (int)ret);
                return EFI_ST_FAILURE;
        }
 
@@ -68,7 +68,7 @@ static int test_stri_coll(void)
                                                    c3, c1);
        if (ret <= 0) {
                efi_st_error(
-                       "stri_coll(\"%ps\", \"%ps\") = %zu\n", c3, c1, ret);
+                       "stri_coll(\"%ps\", \"%ps\") = %d\n", c3, c1, (int)ret);
                return EFI_ST_FAILURE;
        }
 
index 146378f..e4c389a 100644 (file)
@@ -4,10 +4,8 @@
  *
  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  *
- * This unit test checks the following protocol services:
- * ConnectController, DisconnectController,
- * InstallProtocol, ReinstallProtocol, UninstallProtocol,
- * OpenProtocol, CloseProtcol, OpenProtocolInformation
+ * This unit test checks the runtime services for variables:
+ * GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
  */
 
 #include <efi_selftest.h>
index bff2330..cbc6761 100644 (file)
@@ -35,7 +35,7 @@ static struct notify_context notification_context;
 static bool watchdog_reset;
 
 /*
- * Notification function, increments the notfication count if parameter
+ * Notification function, increments the notification count if parameter
  * context is provided.
  *
  * @event      notified event
index d28f2cb..cbdc077 100644 (file)
@@ -11,6 +11,7 @@
 #include <errno.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
+#include <mapmem.h>
 #include <linux/libfdt.h>
 #include <serial.h>
 #include <asm/sections.h>
@@ -1253,8 +1254,9 @@ int fdtdec_setup(void)
 #  if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
        gd->fdt_blob = (void *)prior_stage_fdt_address;
 #  else
-       gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
-                                               (uintptr_t)gd->fdt_blob);
+       gd->fdt_blob = map_sysmem
+               (env_get_ulong("fdtcontroladdr", 16,
+                              (unsigned long)map_to_sysmem(gd->fdt_blob)), 0);
 #  endif
 # endif
 
index 05ac67b..fb5e07b 100644 (file)
@@ -387,13 +387,16 @@ static void rsa_engine_remove(ENGINE *e)
        }
 }
 
-static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
+static int rsa_sign_with_key(RSA *rsa, struct padding_algo *padding_algo,
+                            struct checksum_algo *checksum_algo,
                const struct image_region region[], int region_count,
                uint8_t **sigp, uint *sig_size)
 {
        EVP_PKEY *key;
+       EVP_PKEY_CTX *ckey;
        EVP_MD_CTX *context;
-       int size, ret = 0;
+       int ret = 0;
+       size_t size;
        uint8_t *sig;
        int i;
 
@@ -409,7 +412,7 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
        size = EVP_PKEY_size(key);
        sig = malloc(size);
        if (!sig) {
-               fprintf(stderr, "Out of memory for signature (%d bytes)\n",
+               fprintf(stderr, "Out of memory for signature (%zu bytes)\n",
                        size);
                ret = -ENOMEM;
                goto err_alloc;
@@ -421,22 +424,43 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
                goto err_create;
        }
        EVP_MD_CTX_init(context);
-       if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
+
+       ckey = EVP_PKEY_CTX_new(key, NULL);
+       if (!ckey) {
+               ret = rsa_err("EVP key context creation failed");
+               goto err_create;
+       }
+
+       if (EVP_DigestSignInit(context, &ckey,
+                              checksum_algo->calculate_sign(),
+                              NULL, key) <= 0) {
                ret = rsa_err("Signer setup failed");
                goto err_sign;
        }
 
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+       if (padding_algo && !strcmp(padding_algo->name, "pss")) {
+               if (EVP_PKEY_CTX_set_rsa_padding(ckey,
+                                                RSA_PKCS1_PSS_PADDING) <= 0) {
+                       ret = rsa_err("Signer padding setup failed");
+                       goto err_sign;
+               }
+       }
+#endif /* CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT */
+
        for (i = 0; i < region_count; i++) {
-               if (!EVP_SignUpdate(context, region[i].data, region[i].size)) {
+               if (!EVP_DigestSignUpdate(context, region[i].data,
+                                         region[i].size)) {
                        ret = rsa_err("Signing data failed");
                        goto err_sign;
                }
        }
 
-       if (!EVP_SignFinal(context, sig, sig_size, key)) {
+       if (!EVP_DigestSignFinal(context, sig, &size)) {
                ret = rsa_err("Could not obtain signature");
                goto err_sign;
        }
+
        #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
                (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
                EVP_MD_CTX_cleanup(context);
@@ -446,7 +470,7 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
        EVP_MD_CTX_destroy(context);
        EVP_PKEY_free(key);
 
-       debug("Got signature: %d bytes, expected %d\n", *sig_size, size);
+       debug("Got signature: %d bytes, expected %zu\n", *sig_size, size);
        *sigp = sig;
        *sig_size = size;
 
@@ -483,7 +507,7 @@ int rsa_sign(struct image_sign_info *info,
        ret = rsa_get_priv_key(info->keydir, info->keyname, e, &rsa);
        if (ret)
                goto err_priv;
-       ret = rsa_sign_with_key(rsa, info->checksum, region,
+       ret = rsa_sign_with_key(rsa, info->padding, info->checksum, region,
                                region_count, sigp, sig_len);
        if (ret)
                goto err_sign;
index bc83354..9734f6d 100644 (file)
@@ -57,31 +57,247 @@ static int rsa_verify_padding(const uint8_t *msg, const int pad_len,
        return ret;
 }
 
+int padding_pkcs_15_verify(struct image_sign_info *info,
+                          uint8_t *msg, int msg_len,
+                          const uint8_t *hash, int hash_len)
+{
+       struct checksum_algo *checksum = info->checksum;
+       int ret, pad_len = msg_len - checksum->checksum_len;
+
+       /* Check pkcs1.5 padding bytes. */
+       ret = rsa_verify_padding(msg, pad_len, checksum);
+       if (ret) {
+               debug("In RSAVerify(): Padding check failed!\n");
+               return -EINVAL;
+       }
+
+       /* Check hash. */
+       if (memcmp((uint8_t *)msg + pad_len, hash, msg_len - pad_len)) {
+               debug("In RSAVerify(): Hash check failed!\n");
+               return -EACCES;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_FIT_ENABLE_RSASSA_PSS_SUPPORT
+static void u32_i2osp(uint32_t val, uint8_t *buf)
+{
+       buf[0] = (uint8_t)((val >> 24) & 0xff);
+       buf[1] = (uint8_t)((val >> 16) & 0xff);
+       buf[2] = (uint8_t)((val >>  8) & 0xff);
+       buf[3] = (uint8_t)((val >>  0) & 0xff);
+}
+
+/**
+ * mask_generation_function1() - generate an octet string
+ *
+ * Generate an octet string used to check rsa signature.
+ * It use an input octet string and a hash function.
+ *
+ * @checksum:  A Hash function
+ * @seed:      Specifies an input variable octet string
+ * @seed_len:  Size of the input octet string
+ * @output:    Specifies the output octet string
+ * @output_len:        Size of the output octet string
+ * @return 0 if the octet string was correctly generated, others on error
+ */
+static int mask_generation_function1(struct checksum_algo *checksum,
+                                    uint8_t *seed, int seed_len,
+                                    uint8_t *output, int output_len)
+{
+       struct image_region region[2];
+       int ret = 0, i, i_output = 0, region_count = 2;
+       uint32_t counter = 0;
+       uint8_t buf_counter[4], *tmp;
+       int hash_len = checksum->checksum_len;
+
+       memset(output, 0, output_len);
+
+       region[0].data = seed;
+       region[0].size = seed_len;
+       region[1].data = &buf_counter[0];
+       region[1].size = 4;
+
+       tmp = malloc(hash_len);
+       if (!tmp) {
+               debug("%s: can't allocate array tmp\n", __func__);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       while (i_output < output_len) {
+               u32_i2osp(counter, &buf_counter[0]);
+
+               ret = checksum->calculate(checksum->name,
+                                         region, region_count,
+                                         tmp);
+               if (ret < 0) {
+                       debug("%s: Error in checksum calculation\n", __func__);
+                       goto out;
+               }
+
+               i = 0;
+               while ((i_output < output_len) && (i < hash_len)) {
+                       output[i_output] = tmp[i];
+                       i_output++;
+                       i++;
+               }
+
+               counter++;
+       }
+
+out:
+       free(tmp);
+
+       return ret;
+}
+
+static int compute_hash_prime(struct checksum_algo *checksum,
+                             uint8_t *pad, int pad_len,
+                             uint8_t *hash, int hash_len,
+                             uint8_t *salt, int salt_len,
+                             uint8_t *hprime)
+{
+       struct image_region region[3];
+       int ret, region_count = 3;
+
+       region[0].data = pad;
+       region[0].size = pad_len;
+       region[1].data = hash;
+       region[1].size = hash_len;
+       region[2].data = salt;
+       region[2].size = salt_len;
+
+       ret = checksum->calculate(checksum->name, region, region_count, hprime);
+       if (ret < 0) {
+               debug("%s: Error in checksum calculation\n", __func__);
+               goto out;
+       }
+
+out:
+       return ret;
+}
+
+int padding_pss_verify(struct image_sign_info *info,
+                      uint8_t *msg, int msg_len,
+                      const uint8_t *hash, int hash_len)
+{
+       uint8_t *masked_db = NULL;
+       int masked_db_len = msg_len - hash_len - 1;
+       uint8_t *h = NULL, *hprime = NULL;
+       int h_len = hash_len;
+       uint8_t *db_mask = NULL;
+       int db_mask_len = masked_db_len;
+       uint8_t *db = NULL, *salt = NULL;
+       int db_len = masked_db_len, salt_len = msg_len - hash_len - 2;
+       uint8_t pad_zero[8] = { 0 };
+       int ret, i, leftmost_bits = 1;
+       uint8_t leftmost_mask;
+       struct checksum_algo *checksum = info->checksum;
+
+       /* first, allocate everything */
+       masked_db = malloc(masked_db_len);
+       h = malloc(h_len);
+       db_mask = malloc(db_mask_len);
+       db = malloc(db_len);
+       salt = malloc(salt_len);
+       hprime = malloc(hash_len);
+       if (!masked_db || !h || !db_mask || !db || !salt || !hprime) {
+               printf("%s: can't allocate some buffer\n", __func__);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       /* step 4: check if the last byte is 0xbc */
+       if (msg[msg_len - 1] != 0xbc) {
+               printf("%s: invalid pss padding (0xbc is missing)\n", __func__);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* step 5 */
+       memcpy(masked_db, msg, masked_db_len);
+       memcpy(h, msg + masked_db_len, h_len);
+
+       /* step 6 */
+       leftmost_mask = (0xff >> (8 - leftmost_bits)) << (8 - leftmost_bits);
+       if (masked_db[0] & leftmost_mask) {
+               printf("%s: invalid pss padding ", __func__);
+               printf("(leftmost bit of maskedDB not zero)\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* step 7 */
+       mask_generation_function1(checksum, h, h_len, db_mask, db_mask_len);
+
+       /* step 8 */
+       for (i = 0; i < db_len; i++)
+               db[i] = masked_db[i] ^ db_mask[i];
+
+       /* step 9 */
+       db[0] &= 0xff >> leftmost_bits;
+
+       /* step 10 */
+       if (db[0] != 0x01) {
+               printf("%s: invalid pss padding ", __func__);
+               printf("(leftmost byte of db isn't 0x01)\n");
+               ret = EINVAL;
+               goto out;
+       }
+
+       /* step 11 */
+       memcpy(salt, &db[1], salt_len);
+
+       /* step 12 & 13 */
+       compute_hash_prime(checksum, pad_zero, 8,
+                          (uint8_t *)hash, hash_len,
+                          salt, salt_len, hprime);
+
+       /* step 14 */
+       ret = memcmp(h, hprime, hash_len);
+
+out:
+       free(hprime);
+       free(salt);
+       free(db);
+       free(db_mask);
+       free(h);
+       free(masked_db);
+
+       return ret;
+}
+#endif
+
 /**
  * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
  * Verify a RSA PKCS1.5 signature against an expected hash using
  * the RSA Key properties in prop structure.
  *
+ * @info:      Specifies key and FIT information
  * @prop:      Specifies key
  * @sig:       Signature
  * @sig_len:   Number of bytes in signature
  * @hash:      Pointer to the expected hash
  * @key_len:   Number of bytes in rsa key
- * @algo:      Checksum algo structure having information on DER encoding etc.
  * @return 0 if verified, -ve on error
  */
-static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
+static int rsa_verify_key(struct image_sign_info *info,
+                         struct key_prop *prop, const uint8_t *sig,
                          const uint32_t sig_len, const uint8_t *hash,
-                         const uint32_t key_len, struct checksum_algo *algo)
+                         const uint32_t key_len)
 {
-       int pad_len;
        int ret;
 #if !defined(USE_HOSTCC)
        struct udevice *mod_exp_dev;
 #endif
+       struct checksum_algo *checksum = info->checksum;
+       struct padding_algo *padding = info->padding;
+       int hash_len = checksum->checksum_len;
 
-       if (!prop || !sig || !hash || !algo)
+       if (!prop || !sig || !hash || !checksum)
                return -EIO;
 
        if (sig_len != (prop->num_bits / 8)) {
@@ -89,7 +305,7 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
                return -EINVAL;
        }
 
-       debug("Checksum algorithm: %s", algo->name);
+       debug("Checksum algorithm: %s", checksum->name);
 
        /* Sanity check for stack size */
        if (sig_len > RSA_MAX_SIG_BITS / 8) {
@@ -116,19 +332,10 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
                return ret;
        }
 
-       pad_len = key_len - algo->checksum_len;
-
-       /* Check pkcs1.5 padding bytes. */
-       ret = rsa_verify_padding(buf, pad_len, algo);
+       ret = padding->verify(info, buf, key_len, hash, hash_len);
        if (ret) {
-               debug("In RSAVerify(): Padding check failed!\n");
-               return -EINVAL;
-       }
-
-       /* Check hash. */
-       if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
-               debug("In RSAVerify(): Hash check failed!\n");
-               return -EACCES;
+               debug("In RSAVerify(): padding check failed!\n");
+               return ret;
        }
 
        return 0;
@@ -182,8 +389,8 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
                return -EFAULT;
        }
 
-       ret = rsa_verify_key(&prop, sig, sig_len, hash,
-                            info->crypto->key_len, info->checksum);
+       ret = rsa_verify_key(info, &prop, sig, sig_len, hash,
+                            info->crypto->key_len);
 
        return ret;
 }
index 326eb00..e8ee55c 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <mapmem.h>
 #include <smbios.h>
 #include <tables_csum.h>
 #include <version.h>
@@ -72,9 +73,10 @@ static int smbios_string_table_len(char *start)
 
 static int smbios_write_type0(ulong *current, int handle)
 {
-       struct smbios_type0 *t = (struct smbios_type0 *)*current;
+       struct smbios_type0 *t;
        int len = sizeof(struct smbios_type0);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type0));
        fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
        t->vendor = smbios_add_string(t->eos, "U-Boot");
@@ -101,16 +103,18 @@ static int smbios_write_type0(ulong *current, int handle)
 
        len = t->length + smbios_string_table_len(t->eos);
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
 
 static int smbios_write_type1(ulong *current, int handle)
 {
-       struct smbios_type1 *t = (struct smbios_type1 *)*current;
+       struct smbios_type1 *t;
        int len = sizeof(struct smbios_type1);
        char *serial_str = env_get("serial#");
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type1));
        fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
        t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -122,15 +126,17 @@ static int smbios_write_type1(ulong *current, int handle)
 
        len = t->length + smbios_string_table_len(t->eos);
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
 
 static int smbios_write_type2(ulong *current, int handle)
 {
-       struct smbios_type2 *t = (struct smbios_type2 *)*current;
+       struct smbios_type2 *t;
        int len = sizeof(struct smbios_type2);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type2));
        fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
        t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -140,15 +146,17 @@ static int smbios_write_type2(ulong *current, int handle)
 
        len = t->length + smbios_string_table_len(t->eos);
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
 
 static int smbios_write_type3(ulong *current, int handle)
 {
-       struct smbios_type3 *t = (struct smbios_type3 *)*current;
+       struct smbios_type3 *t;
        int len = sizeof(struct smbios_type3);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type3));
        fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
        t->manufacturer = smbios_add_string(t->eos, CONFIG_SMBIOS_MANUFACTURER);
@@ -160,6 +168,7 @@ static int smbios_write_type3(ulong *current, int handle)
 
        len = t->length + smbios_string_table_len(t->eos);
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
@@ -198,9 +207,10 @@ static void smbios_write_type4_dm(struct smbios_type4 *t)
 
 static int smbios_write_type4(ulong *current, int handle)
 {
-       struct smbios_type4 *t = (struct smbios_type4 *)*current;
+       struct smbios_type4 *t;
        int len = sizeof(struct smbios_type4);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type4));
        fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
        t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
@@ -214,32 +224,37 @@ static int smbios_write_type4(ulong *current, int handle)
 
        len = t->length + smbios_string_table_len(t->eos);
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
 
 static int smbios_write_type32(ulong *current, int handle)
 {
-       struct smbios_type32 *t = (struct smbios_type32 *)*current;
+       struct smbios_type32 *t;
        int len = sizeof(struct smbios_type32);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type32));
        fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
 
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
 
 static int smbios_write_type127(ulong *current, int handle)
 {
-       struct smbios_type127 *t = (struct smbios_type127 *)*current;
+       struct smbios_type127 *t;
        int len = sizeof(struct smbios_type127);
 
+       t = map_sysmem(*current, len);
        memset(t, 0, sizeof(struct smbios_type127));
        fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
 
        *current += len;
+       unmap_sysmem(t);
 
        return len;
 }
@@ -257,6 +272,7 @@ static smbios_write_type smbios_write_funcs[] = {
 ulong write_smbios_table(ulong addr)
 {
        struct smbios_entry *se;
+       ulong table_addr;
        ulong tables;
        int len = 0;
        int max_struct_size = 0;
@@ -268,7 +284,7 @@ ulong write_smbios_table(ulong addr)
        /* 16 byte align the table address */
        addr = ALIGN(addr, 16);
 
-       se = (struct smbios_entry *)(uintptr_t)addr;
+       se = map_sysmem(addr, sizeof(struct smbios_entry));
        memset(se, 0, sizeof(struct smbios_entry));
 
        addr += sizeof(struct smbios_entry);
@@ -290,7 +306,24 @@ ulong write_smbios_table(ulong addr)
        se->max_struct_size = max_struct_size;
        memcpy(se->intermediate_anchor, "_DMI_", 5);
        se->struct_table_length = len;
-       se->struct_table_address = tables;
+
+       /*
+        * We must use a pointer here so things work correctly on sandbox. The
+        * user of this table is not aware of the mapping of addresses to
+        * sandbox's DRAM buffer.
+        */
+       table_addr = (ulong)map_sysmem(tables, 0);
+       if (sizeof(table_addr) > sizeof(u32) && table_addr > (ulong)UINT_MAX) {
+               /*
+                * We need to put this >32-bit pointer into the table but the
+                * field is only 32 bits wide.
+                */
+               printf("WARNING: SMBIOS table_address overflow %llx\n",
+                      (unsigned long long)table_addr);
+               table_addr = 0;
+       }
+       se->struct_table_address = table_addr;
+
        se->struct_count = handle;
 
        /* calculate checksums */
@@ -298,6 +331,7 @@ ulong write_smbios_table(ulong addr)
        isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
        se->intermediate_checksum = table_compute_checksum(istart, isize);
        se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
+       unmap_sysmem(se);
 
        return addr;
 }
index 4dceb6d..a4f16bb 100644 (file)
@@ -381,7 +381,7 @@ $(obj)/%.efi: $(obj)/%_efi.so
 
 quiet_cmd_efi_ld = LD      $@
 cmd_efi_ld = $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared \
-               -Bsymbolic $^ -o $@
+               -Bsymbolic -s $^ -o $@
 
 EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
 
index b3f525f..bd14fe2 100644 (file)
@@ -1661,7 +1661,6 @@ CONFIG_RTC_DS3231
 CONFIG_RTC_FTRTC010
 CONFIG_RTC_IMXDI
 CONFIG_RTC_M41T11
-CONFIG_RTC_M41T62
 CONFIG_RTC_MC13XXX
 CONFIG_RTC_MCFRRTC
 CONFIG_RTC_MCP79411
index e0833ff..36b35ee 100644 (file)
@@ -8,12 +8,14 @@ import u_boot_utils
 
 @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
 def test_efi_selftest(u_boot_console):
-       """
-       Run bootefi selftest
-       """
+       """Test the UEFI implementation
+
+       :param u_boot_console: U-Boot console
 
+       This function executes all selftests that are not marked as on request.
+       """
        u_boot_console.run_command(cmd='setenv efi_selftest')
-       u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
+       u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
        m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any key'])
        if m != 0:
                raise Exception('Failures occurred during the EFI selftest')
index 92144d4..4627ceb 100644 (file)
@@ -126,7 +126,7 @@ def test_vboot(u_boot_console):
             handle.write(struct.pack(">I", size))
         return struct.unpack(">I", total_size)[0]
 
-    def test_with_algo(sha_algo):
+    def test_with_algo(sha_algo, padding):
         """Test verified boot with the given hash algorithm.
 
         This is the main part of the test code. The same procedure is followed
@@ -144,7 +144,7 @@ def test_vboot(u_boot_console):
 
         # Build the FIT, but don't sign anything yet
         cons.log.action('%s: Test FIT with signed images' % sha_algo)
-        make_fit('sign-images-%s.its' % sha_algo)
+        make_fit('sign-images-%s%s.its' % (sha_algo , padding))
         run_bootm(sha_algo, 'unsigned images', 'dev-', True)
 
         # Sign images with our dev keys
@@ -155,7 +155,7 @@ def test_vboot(u_boot_console):
         dtc('sandbox-u-boot.dts')
 
         cons.log.action('%s: Test FIT with signed configuration' % sha_algo)
-        make_fit('sign-configs-%s.its' % sha_algo)
+        make_fit('sign-configs-%s%s.its' % (sha_algo , padding))
         run_bootm(sha_algo, 'unsigned config', '%s+ OK' % sha_algo, True)
 
         # Sign images with our dev keys
@@ -204,7 +204,7 @@ def test_vboot(u_boot_console):
     fit_check_sign = cons.config.build_dir + '/tools/fit_check_sign'
     dtc_args = '-I dts -O dtb -i %s' % tmpdir
     dtb = '%ssandbox-u-boot.dtb' % tmpdir
-    sig_node = '/configurations/conf@1/signature@1'
+    sig_node = '/configurations/conf-1/signature'
 
     # Create an RSA key pair
     public_exponent = 65537
@@ -226,8 +226,10 @@ def test_vboot(u_boot_console):
         # afterwards.
         old_dtb = cons.config.dtb
         cons.config.dtb = dtb
-        test_with_algo('sha1')
-        test_with_algo('sha256')
+        test_with_algo('sha1','')
+        test_with_algo('sha1','-pss')
+        test_with_algo('sha256','')
+        test_with_algo('sha256','-pss')
     finally:
         # Go back to the original U-Boot with the correct dtb.
         cons.config.dtb = old_dtb
diff --git a/test/py/tests/vboot/sign-configs-sha1-pss.its b/test/py/tests/vboot/sign-configs-sha1-pss.its
new file mode 100644 (file)
index 0000000..72a5637
--- /dev/null
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash-1 {
+                               algo = "sha1";
+                       };
+               };
+               fdt-1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash-1 {
+                               algo = "sha1";
+                       };
+               };
+       };
+       configurations {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+                       signature {
+                               algo = "sha1,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
index db2ed79..d8bc1fa 100644 (file)
@@ -5,7 +5,7 @@
        #address-cells = <1>;
 
        images {
-               kernel@1 {
+               kernel {
                        data = /incbin/("test-kernel.bin");
                        type = "kernel_noload";
                        arch = "sandbox";
                        load = <0x4>;
                        entry = <0x8>;
                        kernel-version = <1>;
-                       hash@1 {
+                       hash-1 {
                                algo = "sha1";
                        };
                };
-               fdt@1 {
+               fdt-1 {
                        description = "snow";
                        data = /incbin/("sandbox-kernel.dtb");
                        type = "flat_dt";
                        arch = "sandbox";
                        compression = "none";
                        fdt-version = <1>;
-                       hash@1 {
+                       hash-1 {
                                algo = "sha1";
                        };
                };
        };
        configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+                       signature {
                                algo = "sha1,rsa2048";
                                key-name-hint = "dev";
                                sign-images = "fdt", "kernel";
diff --git a/test/py/tests/vboot/sign-configs-sha256-pss.its b/test/py/tests/vboot/sign-configs-sha256-pss.its
new file mode 100644 (file)
index 0000000..7bdcc7e
--- /dev/null
@@ -0,0 +1,46 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash-1 {
+                               algo = "sha256";
+                       };
+               };
+               fdt-1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash-1 {
+                               algo = "sha256";
+                       };
+               };
+       };
+       configurations {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+                       signature {
+                               algo = "sha256,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
index 1b3432e..f5591aa 100644 (file)
@@ -5,7 +5,7 @@
        #address-cells = <1>;
 
        images {
-               kernel@1 {
+               kernel {
                        data = /incbin/("test-kernel.bin");
                        type = "kernel_noload";
                        arch = "sandbox";
                        load = <0x4>;
                        entry = <0x8>;
                        kernel-version = <1>;
-                       hash@1 {
+                       hash-1 {
                                algo = "sha256";
                        };
                };
-               fdt@1 {
+               fdt-1 {
                        description = "snow";
                        data = /incbin/("sandbox-kernel.dtb");
                        type = "flat_dt";
                        arch = "sandbox";
                        compression = "none";
                        fdt-version = <1>;
-                       hash@1 {
+                       hash-1 {
                                algo = "sha256";
                        };
                };
        };
        configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
-                       signature@1 {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+                       signature {
                                algo = "sha256,rsa2048";
                                key-name-hint = "dev";
                                sign-images = "fdt", "kernel";
diff --git a/test/py/tests/vboot/sign-images-sha1-pss.its b/test/py/tests/vboot/sign-images-sha1-pss.its
new file mode 100644 (file)
index 0000000..ded7ae4
--- /dev/null
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature {
+                               algo = "sha1,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt-1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature {
+                               algo = "sha1,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+               };
+       };
+};
index f69326a..18c759e 100644 (file)
@@ -5,7 +5,7 @@
        #address-cells = <1>;
 
        images {
-               kernel@1 {
+               kernel {
                        data = /incbin/("test-kernel.bin");
                        type = "kernel_noload";
                        arch = "sandbox";
                        load = <0x4>;
                        entry = <0x8>;
                        kernel-version = <1>;
-                       signature@1 {
+                       signature {
                                algo = "sha1,rsa2048";
                                key-name-hint = "dev";
                        };
                };
-               fdt@1 {
+               fdt-1 {
                        description = "snow";
                        data = /incbin/("sandbox-kernel.dtb");
                        type = "flat_dt";
                        arch = "sandbox";
                        compression = "none";
                        fdt-version = <1>;
-                       signature@1 {
+                       signature {
                                algo = "sha1,rsa2048";
                                key-name-hint = "dev";
                        };
                };
        };
        configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
                };
        };
 };
diff --git a/test/py/tests/vboot/sign-images-sha256-pss.its b/test/py/tests/vboot/sign-images-sha256-pss.its
new file mode 100644 (file)
index 0000000..34850cc
--- /dev/null
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature {
+                               algo = "sha256,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt-1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature {
+                               algo = "sha256,rsa2048";
+                               padding = "pss";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
+               };
+       };
+};
index e6aa9fc..bb0f8ee 100644 (file)
@@ -5,7 +5,7 @@
        #address-cells = <1>;
 
        images {
-               kernel@1 {
+               kernel {
                        data = /incbin/("test-kernel.bin");
                        type = "kernel_noload";
                        arch = "sandbox";
                        load = <0x4>;
                        entry = <0x8>;
                        kernel-version = <1>;
-                       signature@1 {
+                       signature {
                                algo = "sha256,rsa2048";
                                key-name-hint = "dev";
                        };
                };
-               fdt@1 {
+               fdt-1 {
                        description = "snow";
                        data = /incbin/("sandbox-kernel.dtb");
                        type = "flat_dt";
                        arch = "sandbox";
                        compression = "none";
                        fdt-version = <1>;
-                       signature@1 {
+                       signature {
                                algo = "sha256,rsa2048";
                                key-name-hint = "dev";
                        };
                };
        };
        configurations {
-               default = "conf@1";
-               conf@1 {
-                       kernel = "kernel@1";
-                       fdt = "fdt@1";
+               default = "conf-1";
+               conf-1 {
+                       kernel = "kernel";
+                       fdt = "fdt-1";
                };
        };
 };
index 09e4f47..88b3295 100644 (file)
@@ -157,6 +157,7 @@ static int fit_image_setup_sig(struct image_sign_info *info,
 {
        const char *node_name;
        char *algo_name;
+       const char *padding_name;
 
        node_name = fit_get_name(fit, noffset, NULL);
        if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
@@ -165,6 +166,8 @@ static int fit_image_setup_sig(struct image_sign_info *info,
                return -1;
        }
 
+       padding_name = fdt_getprop(fit, noffset, "padding", NULL);
+
        memset(info, '\0', sizeof(*info));
        info->keydir = keydir;
        info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
@@ -173,6 +176,7 @@ static int fit_image_setup_sig(struct image_sign_info *info,
        info->name = strdup(algo_name);
        info->checksum = image_get_checksum_algo(algo_name);
        info->crypto = image_get_crypto_algo(algo_name);
+       info->padding = image_get_padding_algo(padding_name);
        info->require_keys = require_keys;
        info->engine_id = engine_id;
        if (!info->checksum || !info->crypto) {