Allwinner: u-boot: add support for loading Crust

This commit is contained in:
Jernej Skrabec 2021-01-21 23:23:33 +01:00
parent 338fb56238
commit 3cf9be56bd
12 changed files with 1297 additions and 0 deletions

View File

@ -5,3 +5,5 @@
CONFIG_BOOTDELAY=0
CONFIG_MACPWR=""
# CONFIG_EFI_LOADER is not set
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_IMAGE_TINY=y

View File

@ -0,0 +1,181 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 18 Nov 2020 17:32:02 +0000
Subject: [PATCH] sunxi: Factor out eGON BROM header description
To be able to easily share the Allwinner eGON BROM header structure
between the tools and the SPL code, move the struct definition into a
separate header file.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/include/asm/arch-sunxi/spl.h | 65 +--------------------
include/sunxi_image.h | 81 +++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 64 deletions(-)
create mode 100644 include/sunxi_image.h
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -7,19 +7,7 @@
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#define BOOT0_MAGIC "eGON.BT0"
-#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */
-#define SPL_MAJOR_BITS 3
-#define SPL_MINOR_BITS 5
-#define SPL_VERSION(maj, min) \
- ((((maj) & ((1U << SPL_MAJOR_BITS) - 1)) << SPL_MINOR_BITS) | \
- ((min) & ((1U << SPL_MINOR_BITS) - 1)))
-
-#define SPL_HEADER_VERSION SPL_VERSION(0, 2)
-
-#define SPL_ENV_HEADER_VERSION SPL_VERSION(0, 1)
-#define SPL_DT_HEADER_VERSION SPL_VERSION(0, 2)
-#define SPL_DRAM_HEADER_VERSION SPL_VERSION(0, 3)
+#include <sunxi_image.h>
#define SPL_ADDR CONFIG_SUNXI_SRAM_ADDRESS
@@ -31,57 +19,6 @@
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
-/* boot head definition from sun4i boot code */
-struct boot_file_head {
- uint32_t b_instruction; /* one intruction jumping to real code */
- uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
- uint32_t check_sum; /* generated by PC */
- uint32_t length; /* generated by PC */
- /*
- * We use a simplified header, only filling in what is needed
- * by the boot ROM. To be compatible with Allwinner tools we
- * would need to implement the proper fields here instead of
- * padding.
- *
- * Actually we want the ability to recognize our "sunxi" variant
- * of the SPL. To do so, let's place a special signature into the
- * "pub_head_size" field. We can reasonably expect Allwinner's
- * boot0 to always have the upper 16 bits of this set to 0 (after
- * all the value shouldn't be larger than the limit imposed by
- * SRAM size).
- * If the signature is present (at 0x14), then we know it's safe
- * to use the remaining 8 bytes (at 0x18) for our own purposes.
- * (E.g. sunxi-tools "fel" utility can pass information there.)
- */
- union {
- uint32_t pub_head_size;
- uint8_t spl_signature[4];
- };
- uint32_t fel_script_address; /* since v0.1, set by sunxi-fel */
- /*
- * If the fel_uEnv_length member below is set to a non-zero value,
- * it specifies the size (byte count) of data at fel_script_address.
- * At the same time this indicates that the data is in uEnv.txt
- * compatible format, ready to be imported via "env import -t".
- */
- uint32_t fel_uEnv_length; /* since v0.1, set by sunxi-fel */
- /*
- * Offset of an ASCIIZ string (relative to the SPL header), which
- * contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE).
- * This is optional and may be set to NULL. Is intended to be used
- * by flash programming tools for providing nice informative messages
- * to the users.
- */
- uint32_t dt_name_offset; /* since v0.2, set by mksunxiboot */
- uint32_t dram_size; /* in MiB, since v0.3, set by SPL */
- uint32_t boot_media; /* written here by the boot ROM */
- /* A padding area (may be used for storing text strings) */
- uint32_t string_pool[13]; /* since v0.2, filled by mksunxiboot */
- /* The header must be a multiple of 32 bytes (for VBAR alignment) */
-};
-
-/* Compile time check to assure proper alignment of structure */
-typedef char boot_file_head_not_multiple_of_32[1 - 2*(sizeof(struct boot_file_head) % 32)];
#define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
--- /dev/null
+++ b/include/sunxi_image.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Constants and data structures used in Allwinner "eGON" images, as
+ * parsed by the Boot-ROM.
+ *
+ * Shared between mkimage and the SPL.
+ */
+#ifndef SUNXI_IMAGE_H
+#define SUNXI_IMAGE_H
+
+#define BOOT0_MAGIC "eGON.BT0"
+#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */
+#define SPL_MAJOR_BITS 3
+#define SPL_MINOR_BITS 5
+#define SPL_VERSION(maj, min) \
+ ((((maj) & ((1U << SPL_MAJOR_BITS) - 1)) << SPL_MINOR_BITS) | \
+ ((min) & ((1U << SPL_MINOR_BITS) - 1)))
+
+#define SPL_HEADER_VERSION SPL_VERSION(0, 2)
+
+#define SPL_ENV_HEADER_VERSION SPL_VERSION(0, 1)
+#define SPL_DT_HEADER_VERSION SPL_VERSION(0, 2)
+#define SPL_DRAM_HEADER_VERSION SPL_VERSION(0, 3)
+
+/* boot head definition from sun4i boot code */
+struct boot_file_head {
+ uint32_t b_instruction; /* one intruction jumping to real code */
+ uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
+ uint32_t check_sum; /* generated by PC */
+ uint32_t length; /* generated by PC */
+ /*
+ * We use a simplified header, only filling in what is needed
+ * by the boot ROM. To be compatible with Allwinner tools we
+ * would need to implement the proper fields here instead of
+ * padding.
+ *
+ * Actually we want the ability to recognize our "sunxi" variant
+ * of the SPL. To do so, let's place a special signature into the
+ * "pub_head_size" field. We can reasonably expect Allwinner's
+ * boot0 to always have the upper 16 bits of this set to 0 (after
+ * all the value shouldn't be larger than the limit imposed by
+ * SRAM size).
+ * If the signature is present (at 0x14), then we know it's safe
+ * to use the remaining 8 bytes (at 0x18) for our own purposes.
+ * (E.g. sunxi-tools "fel" utility can pass information there.)
+ */
+ union {
+ uint32_t pub_head_size;
+ uint8_t spl_signature[4];
+ };
+ uint32_t fel_script_address; /* since v0.1, set by sunxi-fel */
+ /*
+ * If the fel_uEnv_length member below is set to a non-zero value,
+ * it specifies the size (byte count) of data at fel_script_address.
+ * At the same time this indicates that the data is in uEnv.txt
+ * compatible format, ready to be imported via "env import -t".
+ */
+ uint32_t fel_uEnv_length; /* since v0.1, set by sunxi-fel */
+ /*
+ * Offset of an ASCIIZ string (relative to the SPL header), which
+ * contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE).
+ * This is optional and may be set to NULL. Is intended to be used
+ * by flash programming tools for providing nice informative messages
+ * to the users.
+ */
+ uint32_t dt_name_offset; /* since v0.2, set by mksunxiboot */
+ uint32_t dram_size; /* in MiB, since v0.3, set by SPL */
+ uint32_t boot_media; /* written here by the boot ROM */
+ /* A padding area (may be used for storing text strings) */
+ uint32_t string_pool[13]; /* since v0.2, filled by mksunxiboot */
+ /* The header must be a multiple of 32 bytes (for VBAR alignment) */
+};
+
+/* Compile time check to assure proper alignment of structure */
+typedef char boot_file_head_not_multiple_of_32[1 - 2*(sizeof(struct boot_file_head) % 32)];
+
+#endif

View File

@ -0,0 +1,202 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 18 Nov 2020 17:32:03 +0000
Subject: [PATCH] tools: mkimage: Add Allwinner eGON support
So far we used the separate mksunxiboot tool for generating a bootable
image for Allwinner SPLs, probably just for historical reasons.
Use the mkimage framework to generate a so called eGON image the
Allwinner BROM expects.
The new image type is called "sunxi_egon", to differentiate it
from the (still to be implemented) secure boot TOC0 image.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
common/image.c | 1 +
include/image.h | 1 +
include/sunxi_image.h | 1 +
tools/Makefile | 1 +
tools/sunxi_egon.c | 136 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 140 insertions(+)
create mode 100644 tools/sunxi_egon.c
--- a/common/image.c
+++ b/common/image.c
@@ -189,6 +189,7 @@ static const table_entry_t uimage_type[]
{ IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
{ IH_TYPE_MTKIMAGE, "mtk_image", "MediaTek BootROM loadable Image" },
{ IH_TYPE_COPRO, "copro", "Coprocessor Image"},
+ { IH_TYPE_SUNXI_EGON, "sunxi_egon", "Allwinner eGON Boot Image" },
{ -1, "", "", },
};
--- a/include/image.h
+++ b/include/image.h
@@ -308,6 +308,7 @@ enum {
IH_TYPE_IMX8MIMAGE, /* Freescale IMX8MBoot Image */
IH_TYPE_IMX8IMAGE, /* Freescale IMX8Boot Image */
IH_TYPE_COPRO, /* Coprocessor Image for remoteproc*/
+ IH_TYPE_SUNXI_EGON, /* Allwinner eGON Boot Image */
IH_TYPE_COUNT, /* Number of image types */
};
--- a/include/sunxi_image.h
+++ b/include/sunxi_image.h
@@ -13,6 +13,7 @@
#define SUNXI_IMAGE_H
#define BOOT0_MAGIC "eGON.BT0"
+#define BROM_STAMP_VALUE 0x5f0a6c39
#define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */
#define SPL_MAJOR_BITS 3
#define SPL_MINOR_BITS 5
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -104,6 +104,7 @@ dumpimage-mkimage-objs := aisimage.o \
stm32image.o \
$(ROCKCHIP_OBS) \
socfpgaimage.o \
+ sunxi_egon.o \
lib/crc16.o \
lib/sha1.o \
lib/sha256.o \
--- /dev/null
+++ b/tools/sunxi_egon.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Arm Ltd.
+ */
+
+#include "imagetool.h"
+#include <image.h>
+
+#include <sunxi_image.h>
+
+/*
+ * NAND requires 8K padding. SD/eMMC gets away with 512 bytes,
+ * but let's use the larger padding to cover both.
+ */
+#define PAD_SIZE 8192
+
+static int egon_check_params(struct image_tool_params *params)
+{
+ /* We just need a binary image file. */
+ return !params->dflag;
+}
+
+static int egon_verify_header(unsigned char *ptr, int image_size,
+ struct image_tool_params *params)
+{
+ const struct boot_file_head *header = (void *)ptr;
+ uint32_t length;
+
+ /* First 4 bytes must be an ARM branch instruction. */
+ if ((le32_to_cpu(header->b_instruction) & 0xff000000) != 0xea000000)
+ return EXIT_FAILURE;
+
+ if (memcmp(header->magic, BOOT0_MAGIC, sizeof(header->magic)))
+ return EXIT_FAILURE;
+
+ length = le32_to_cpu(header->length);
+ /* Must be at least 512 byte aligned. */
+ if (length & 511)
+ return EXIT_FAILURE;
+
+ /*
+ * Image could also contain U-Boot proper, so could be bigger.
+ * But it must not be shorter.
+ */
+ if (image_size < length)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+
+static void egon_print_header(const void *buf)
+{
+ const struct boot_file_head *header = buf;
+
+ printf("Allwinner eGON image, size: %d bytes\n",
+ le32_to_cpu(header->length));
+
+ if (memcmp(header->spl_signature, SPL_SIGNATURE, 3))
+ return;
+
+ printf("\tSPL header version %d.%d\n",
+ header->spl_signature[3] >> SPL_MINOR_BITS,
+ header->spl_signature[3] & ((1U << SPL_MINOR_BITS) - 1));
+ if (header->spl_signature[3] >= SPL_DT_HEADER_VERSION) {
+ uint32_t dt_name_offs = le32_to_cpu(header->dt_name_offset);
+
+ if (dt_name_offs > 0)
+ printf("\tDT name: %s\n", (char *)buf + dt_name_offs);
+ }
+}
+
+static void egon_set_header(void *buf, struct stat *sbuf, int infd,
+ struct image_tool_params *params)
+{
+ struct boot_file_head *header = buf;
+ uint32_t *buf32 = buf;
+ uint32_t checksum = 0, value;
+ int i;
+
+ /* Generate an ARM branch instruction to jump over the header. */
+ value = 0xea000000 | (sizeof(struct boot_file_head) / 4 - 2);
+ header->b_instruction = cpu_to_le32(value);
+
+ memcpy(header->magic, BOOT0_MAGIC, sizeof(header->magic));
+ header->check_sum = cpu_to_le32(BROM_STAMP_VALUE);
+ header->length = cpu_to_le32(params->file_size);
+
+ memcpy(header->spl_signature, SPL_SIGNATURE, 3);
+
+ /* If an image name has been provided, use it as the DT name. */
+ if (params->imagename && params->imagename[0]) {
+ header->spl_signature[3] = SPL_DT_HEADER_VERSION;
+
+ value = offsetof(struct boot_file_head, string_pool);
+ header->dt_name_offset = cpu_to_le32(value);
+
+ strncpy((char *)header->string_pool, params->imagename, 52);
+ /* Make sure we have a terminating zero byte. */
+ ((char *)header->string_pool)[51] = 0;
+ } else
+ header->spl_signature[3] = SPL_ENV_HEADER_VERSION;
+
+ /* Calculate the checksum. Yes, it's that simple. */
+ for (i = 0; i < sbuf->st_size / 4; i++)
+ checksum += le32_to_cpu(buf32[i]);
+ header->check_sum = cpu_to_le32(checksum);
+}
+
+static int egon_check_image_type(uint8_t type)
+{
+ return type == IH_TYPE_SUNXI_EGON ? 0 : 1;
+}
+
+static int egon_vrec_header(struct image_tool_params *params,
+ struct image_type_params *tparams)
+{
+ tparams->hdr = calloc(sizeof(struct boot_file_head), 1);
+
+ /* Return padding to 8K blocks. */
+ return ALIGN(params->file_size, PAD_SIZE) - params->file_size;
+}
+
+U_BOOT_IMAGE_TYPE(
+ sunxi_egon,
+ "Allwinner eGON Boot Image support",
+ sizeof(struct boot_file_head),
+ NULL,
+ egon_check_params,
+ egon_verify_header,
+ egon_print_header,
+ egon_set_header,
+ NULL,
+ egon_check_image_type,
+ NULL,
+ egon_vrec_header
+);

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 18 Nov 2020 17:32:04 +0000
Subject: [PATCH] sunxi: Use mkimage for SPL boot image generation
Switch the SPL boot image generation from using mksunxiboot to the new
sunxi_egon format of mkimage.
Verified to create identical results for all 152 Allwinner boards.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
---
scripts/Makefile.spl | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -382,11 +382,11 @@ endif
$(obj)/$(SPL_BIN).sfp: $(obj)/$(SPL_BIN).bin FORCE
$(call if_changed,mkimage)
-quiet_cmd_mksunxiboot = MKSUNXI $@
-cmd_mksunxiboot = $(objtree)/tools/mksunxiboot \
- --default-dt $(CONFIG_DEFAULT_DEVICE_TREE) $< $@
+MKIMAGEFLAGS_sunxi-spl.bin = -T sunxi_egon \
+ -n $(CONFIG_DEFAULT_DEVICE_TREE)
+
$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE
- $(call if_changed,mksunxiboot)
+ $(call if_changed,mkimage)
quiet_cmd_sunxi_spl_image_builder = SUNXI_SPL_IMAGE_BUILDER $@
cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \

View File

@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 20 Nov 2020 01:26:34 -0600
Subject: [PATCH] sunxi: Put secure monitor in SRAM A2
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/include/asm/arch-sunxi/cpu.h | 9 +++++++++
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 1 -
include/configs/sunxi-common.h | 2 ++
3 files changed, 11 insertions(+), 1 deletion(-)
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -14,6 +14,15 @@
#include <asm/arch/cpu_sun4i.h>
#endif
+#if defined(CONFIG_MACH_SUN4I)
+#define SUNXI_SRAM_A2_BASE 0x00004000
+#elif defined(CONFIG_MACH_SUN6I) || \
+ defined(CONFIG_MACH_SUN8I) || \
+ defined(CONFIG_MACH_SUN50I) || \
+ defined(CONFIG_MACH_SUN50I_H5)
+#define SUNXI_SRAM_A2_BASE 0x00040000
+#endif
+
#define SOCID_A64 0x1689
#define SOCID_H3 0x1680
#define SOCID_V3S 0x1681
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -11,7 +11,6 @@
#define SUNXI_SRAM_A1_BASE 0x00000000
#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */
-#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */
#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */
#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */
#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -192,6 +192,8 @@
#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */
+#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_A2_BASE + 0x4000
+#define CONFIG_ARMV7_SECURE_MAX_SIZE (16 * 1024) /* 16 KB */
/* I2C */
#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \

View File

@ -0,0 +1,575 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 20 Nov 2020 01:25:26 -0600
Subject: [PATCH] sunxi: A wild PSCI implementation appears...
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/Kconfig | 1 -
arch/arm/cpu/armv7/sunxi/Makefile | 2 +-
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 463 +++++++++++++++++++++++++++
arch/arm/include/asm/psci.h | 9 +-
arch/arm/include/asm/system.h | 13 +-
tools/sunxi_egon.c | 2 +-
6 files changed, 480 insertions(+), 10 deletions(-)
create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -44,7 +44,6 @@ config ARMV7_PSCI
choice
prompt "Supported PSCI version"
depends on ARMV7_PSCI
- default ARMV7_PSCI_0_1 if ARCH_SUNXI
default ARMV7_PSCI_1_0
help
Select the supported PSCI version.
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_MACH_SUN6I) += tzpc.o
obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
+obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o
endif
ifdef CONFIG_SPL_BUILD
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * Based on assembly code by Marc Zyngier <marc.zyngier@arm.com>,
+ * which was based on code by Carl van Schaik <carl@ok-labs.com>.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/cache.h>
+
+#include <asm/arch/cpu.h>
+#include <asm/arch/cpucfg.h>
+#include <asm/arch/prcm.h>
+#include <asm/armv7.h>
+#include <asm/gic.h>
+#include <asm/io.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <asm/system.h>
+
+#define SUNXI_SCP_BASE 0x00048000
+#define SUNXI_SCP_MAGIC 0xb4400012
+
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+
+#define HW_ON 0
+#define HW_OFF 1
+#define HW_STANDBY 2
+
+#define MPIDR_AFFLVL0(mpidr) (mpidr & 0xf)
+#define MPIDR_AFFLVL1(mpidr) (mpidr >> 8 & 0xf)
+
+enum {
+ CORE_POWER_LEVEL = 0,
+ CLUSTER_POWER_LEVEL = 1,
+ CSS_POWER_LEVEL = 2,
+};
+
+enum {
+ SCPI_CMD_SCP_READY = 0x01,
+ SCPI_CMD_SET_CSS_POWER_STATE = 0x03,
+ SCPI_CMD_GET_CSS_POWER_STATE = 0x04,
+ SCPI_CMD_SET_SYS_POWER_STATE = 0x05,
+};
+
+enum {
+ SCPI_E_OK = 0,
+ SCPI_E_PARAM = 1,
+ SCPI_E_ALIGN = 2,
+ SCPI_E_SIZE = 3,
+ SCPI_E_HANDLER = 4,
+ SCPI_E_ACCESS = 5,
+ SCPI_E_RANGE = 6,
+ SCPI_E_TIMEOUT = 7,
+ SCPI_E_NOMEM = 8,
+ SCPI_E_PWRSTATE = 9,
+ SCPI_E_SUPPORT = 10,
+ SCPI_E_DEVICE = 11,
+ SCPI_E_BUSY = 12,
+ SCPI_E_OS = 13,
+ SCPI_E_DATA = 14,
+ SCPI_E_STATE = 15,
+};
+
+enum {
+ SCPI_POWER_ON = 0x00,
+ SCPI_POWER_RETENTION = 0x01,
+ SCPI_POWER_OFF = 0x03,
+};
+
+enum {
+ SCPI_SYSTEM_SHUTDOWN = 0x00,
+ SCPI_SYSTEM_REBOOT = 0x01,
+ SCPI_SYSTEM_RESET = 0x02,
+};
+
+#define SCPI_SHMEM_BASE 0x0004be00
+#define SCPI_SHMEM ((struct scpi_shmem *)SCPI_SHMEM_BASE)
+
+#define SCPI_MESSAGE_SIZE 0x100
+#define SCPI_PAYLOAD_SIZE (SCPI_MESSAGE_SIZE - sizeof(struct scpi_header))
+
+#define SCPI_RX_CHANNEL 1
+#define SCPI_TX_CHANNEL 0
+#define SCPI_VIRTUAL_CHANNEL BIT(0)
+
+struct scpi_header {
+ u8 command;
+ u8 sender;
+ u16 size;
+ u32 status;
+};
+
+struct scpi_message {
+ struct scpi_header header;
+ u8 payload[SCPI_PAYLOAD_SIZE];
+};
+
+struct scpi_shmem {
+ struct scpi_message rx;
+ struct scpi_message tx;
+};
+
+#define SUNXI_MSGBOX_BASE 0x01c17000
+#define REMOTE_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0050)
+#define LOCAL_IRQ_STAT_REG (SUNXI_MSGBOX_BASE + 0x0070)
+#define MSG_STAT_REG(n) (SUNXI_MSGBOX_BASE + 0x0140 + 0x4 * (n))
+#define MSG_DATA_REG(n) (SUNXI_MSGBOX_BASE + 0x0180 + 0x4 * (n))
+
+#define RX_IRQ(n) BIT(0 + 2 * (n))
+#define TX_IRQ(n) BIT(1 + 2 * (n))
+
+static u32 __secure_data ccu_save[2];
+
+static u32 __secure_data lock;
+
+static inline u32 __secure read_mpidr(void)
+{
+ u32 v;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (v));
+ return v;
+}
+
+static void __secure scpi_begin_command(void)
+{
+ u32 mpidr = read_mpidr();
+
+ do {
+ while (readl(&lock));
+ writel(mpidr, &lock);
+ dsb();
+ } while (readl(&lock) != mpidr);
+ while (readl(REMOTE_IRQ_STAT_REG) & RX_IRQ(SCPI_TX_CHANNEL));
+}
+
+static void __secure scpi_send_command(void)
+{
+ writel(SCPI_VIRTUAL_CHANNEL, MSG_DATA_REG(SCPI_TX_CHANNEL));
+}
+
+static void __secure scpi_wait_response(void)
+{
+ while (!readl(MSG_STAT_REG(SCPI_RX_CHANNEL)));
+}
+
+static void __secure scpi_end_command(void)
+{
+ while (readl(MSG_STAT_REG(SCPI_RX_CHANNEL)))
+ readl(MSG_DATA_REG(SCPI_RX_CHANNEL));
+ writel(RX_IRQ(SCPI_RX_CHANNEL), LOCAL_IRQ_STAT_REG);
+ writel(0, &lock);
+}
+
+static void __secure scpi_set_css_power_state(u32 target_cpu, u32 core_state,
+ u32 cluster_state, u32 css_state)
+{
+ struct scpi_shmem *shmem = SCPI_SHMEM;
+
+ scpi_begin_command();
+
+ shmem->tx.header.command = SCPI_CMD_SET_CSS_POWER_STATE;
+ shmem->tx.header.size = 4;
+
+ shmem->tx.payload[0] = target_cpu >> 4 | target_cpu;
+ shmem->tx.payload[1] = cluster_state << 4 | core_state;
+ shmem->tx.payload[2] = css_state;
+ shmem->tx.payload[3] = 0;
+
+ scpi_send_command();
+ scpi_end_command();
+}
+
+static s32 __secure scpi_get_css_power_state(u32 target_cpu, u8 *core_states,
+ u8 *cluster_state)
+{
+ struct scpi_shmem *shmem = SCPI_SHMEM;
+ u32 cluster = MPIDR_AFFLVL1(target_cpu);
+ u32 offset;
+ s32 ret;
+
+ scpi_begin_command();
+
+ shmem->tx.header.command = SCPI_CMD_GET_CSS_POWER_STATE;
+ shmem->tx.header.size = 0;
+
+ scpi_send_command();
+ scpi_wait_response();
+
+ for (offset = 0; offset < shmem->rx.header.size; offset += 2) {
+ if ((shmem->rx.payload[offset] & 0xf) == cluster) {
+ *cluster_state = shmem->rx.payload[offset+0] >> 4;
+ *core_states = shmem->rx.payload[offset+1];
+
+ break;
+ }
+ }
+
+ ret = shmem->rx.header.status;
+
+ scpi_end_command();
+
+ return ret;
+}
+
+static s32 __secure scpi_set_sys_power_state(u32 sys_state)
+{
+ struct scpi_shmem *shmem = SCPI_SHMEM;
+ s32 ret;
+
+ scpi_begin_command();
+
+ shmem->tx.header.command = SCPI_CMD_SET_SYS_POWER_STATE;
+ shmem->tx.header.size = 1;
+
+ shmem->tx.payload[0] = sys_state;
+
+ scpi_send_command();
+ scpi_wait_response();
+
+ ret = shmem->rx.header.status;
+
+ scpi_end_command();
+
+ return ret;
+}
+
+void psci_enable_smp(void);
+
+static s32 __secure psci_suspend_common(u32 pc, u32 context_id, u32 core_state,
+ u32 cluster_state, u32 css_state)
+
+{
+ u32 target_cpu = read_mpidr();
+
+ if (core_state == SCPI_POWER_OFF) {
+ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id);
+
+ if (MPIDR_AFFLVL0(target_cpu) == 0) {
+ ccu_save[0] = readl(0x1c20050);
+ ccu_save[1] = readl(0x1c20054);
+ writel((ccu_save[1] & ~(3 << 12)) | (1 << 12), 0x1c20054);
+ }
+ }
+
+ scpi_set_css_power_state(target_cpu, core_state,
+ cluster_state, css_state);
+
+ psci_cpu_off_common();
+
+ wfi();
+
+ psci_enable_smp();
+
+ return ARM_PSCI_RET_SUCCESS;
+}
+
+u32 __secure psci_version(void)
+{
+ return ARM_PSCI_VER_1_1;
+}
+
+s32 __secure psci_cpu_suspend(u32 __always_unused function_id,
+ u32 power_state, u32 pc, u32 context_id)
+{
+ return psci_suspend_common(pc, context_id,
+ power_state >> 0 & 0xf,
+ power_state >> 4 & 0xf,
+ power_state >> 8 & 0xf);
+}
+
+s32 __secure psci_cpu_off(void)
+{
+ u32 pc = 0, context_id = 0;
+
+ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF,
+ SCPI_POWER_OFF, SCPI_POWER_ON);
+}
+
+s32 __secure psci_cpu_on(u32 __always_unused function_id,
+ u32 target_cpu, u32 pc, u32 context_id)
+{
+ psci_save(MPIDR_AFFLVL0(target_cpu), pc, context_id);
+
+ scpi_set_css_power_state(target_cpu, SCPI_POWER_ON,
+ SCPI_POWER_ON, SCPI_POWER_ON);
+
+ return ARM_PSCI_RET_SUCCESS;
+}
+
+s32 __secure psci_affinity_info(u32 function_id,
+ u32 target_cpu, u32 power_level)
+{
+ if (power_level != CORE_POWER_LEVEL)
+ return ARM_PSCI_RET_INVAL;
+
+ /* This happens to have the same HW_ON/HW_OFF encoding. */
+ return psci_node_hw_state(function_id, target_cpu, power_level);
+}
+
+void __secure psci_system_off(void)
+{
+ scpi_set_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+
+ /* Wait to be turned off. */
+ for (;;) wfi();
+}
+
+void __secure psci_system_reset(void)
+{
+ scpi_set_sys_power_state(SCPI_SYSTEM_REBOOT);
+
+ /* Wait to be turned off. */
+ for (;;) wfi();
+}
+
+s32 __secure psci_features(u32 __always_unused function_id,
+ u32 psci_fid)
+{
+ switch (psci_fid) {
+ case ARM_PSCI_0_2_FN_PSCI_VERSION:
+ case ARM_PSCI_0_2_FN_CPU_SUSPEND:
+ case ARM_PSCI_0_2_FN_CPU_OFF:
+ case ARM_PSCI_0_2_FN_CPU_ON:
+ case ARM_PSCI_0_2_FN_AFFINITY_INFO:
+ case ARM_PSCI_0_2_FN_SYSTEM_OFF:
+ case ARM_PSCI_0_2_FN_SYSTEM_RESET:
+ case ARM_PSCI_1_0_FN_PSCI_FEATURES:
+ case ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND:
+ case ARM_PSCI_1_0_FN_NODE_HW_STATE:
+ case ARM_PSCI_1_0_FN_SYSTEM_SUSPEND:
+ case ARM_PSCI_1_1_FN_SYSTEM_RESET2:
+ return ARM_PSCI_RET_SUCCESS;
+ default:
+ return ARM_PSCI_RET_NI;
+ }
+}
+
+s32 __secure psci_cpu_default_suspend(u32 __always_unused function_id,
+ u32 pc, u32 context_id)
+{
+ return psci_suspend_common(pc, context_id, SCPI_POWER_RETENTION,
+ SCPI_POWER_RETENTION, SCPI_POWER_RETENTION);
+}
+
+s32 __secure psci_node_hw_state(u32 __always_unused function_id,
+ u32 target_cpu, u32 power_level)
+{
+ u32 core = MPIDR_AFFLVL0(target_cpu);
+ u8 core_states, cluster_state;
+
+ if (power_level >= CSS_POWER_LEVEL)
+ return HW_ON;
+ if (scpi_get_css_power_state(target_cpu, &core_states, &cluster_state))
+ return ARM_PSCI_RET_NI;
+ if (power_level == CLUSTER_POWER_LEVEL) {
+ if (cluster_state == SCPI_POWER_ON)
+ return HW_ON;
+ if (cluster_state < SCPI_POWER_OFF)
+ return HW_STANDBY;
+ return HW_OFF;
+ }
+
+ return (core_states & BIT(core)) ? HW_ON : HW_OFF;
+}
+
+s32 __secure psci_system_suspend(u32 __always_unused function_id,
+ u32 pc, u32 context_id)
+{
+ return psci_suspend_common(pc, context_id, SCPI_POWER_OFF,
+ SCPI_POWER_OFF, SCPI_POWER_OFF);
+}
+
+s32 __secure psci_system_reset2(u32 __always_unused function_id,
+ u32 reset_type, u32 cookie)
+{
+ s32 ret;
+
+ if (reset_type)
+ return ARM_PSCI_RET_INVAL;
+
+ ret = scpi_set_sys_power_state(SCPI_SYSTEM_RESET);
+ if (ret)
+ return ARM_PSCI_RET_INVAL;
+
+ /* Wait to be turned off. */
+ for (;;) wfi();
+}
+
+/*
+ * R40 is different from other single cluster SoCs. The secondary core
+ * entry address register is in the SRAM controller address range.
+ */
+#define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0 (0xbc)
+
+#ifdef CONFIG_MACH_SUN8I_R40
+/* secondary core entry address is programmed differently on R40 */
+static void __secure sunxi_set_entry_address(void *entry)
+{
+ writel((u32)entry,
+ SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
+}
+#else
+static void __secure sunxi_set_entry_address(void *entry)
+{
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+ writel((u32)entry, &cpucfg->priv0);
+}
+#endif
+
+void __secure psci_arch_init(void)
+{
+ static bool __secure_data once;
+
+ /* Be cool with non-secure. */
+ writel(0xff, GICC_BASE + GICC_PMR);
+
+ if (!once) {
+ once = true;
+
+ /* Redirect CPU0 to PSCI. */
+ writel(0x16aaefe8, 0x1f01da0);
+ writel(0xaa16efe8, 0x1f01da0);
+ writel(0x47000, 0x1f01da8);
+
+ /* Set secondary core power-on PC. */
+ sunxi_set_entry_address(psci_cpu_entry);
+
+ /* Wait for the SCP firmware to boot. */
+ scpi_begin_command();
+ scpi_wait_response();
+ scpi_end_command();
+ } else if (MPIDR_AFFLVL0(read_mpidr()) == 0) {
+ writel(ccu_save[0], 0x1c20050);
+ writel(ccu_save[1], 0x1c20054);
+ }
+}
+
+void psci_board_init(void)
+{
+ /* Check for a valid SCP firmware, and boot the SCP if found. */
+ if (readl(SUNXI_SCP_BASE) == SUNXI_SCP_MAGIC) {
+ /* Program exception vectors to the firmware entry point. */
+ for (u32 i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ u32 vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
+ u32 offset = SUNXI_SCP_BASE - vector;
+
+ writel(offset >> 2, vector);
+ }
+
+ /* Take the SCP out of reset. */
+ writel(0x1, SUNXI_CPUCFG_BASE);
+ }
+}
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -22,8 +22,9 @@
#include <linux/bitops.h>
#endif
-#define ARM_PSCI_VER_1_0 (0x00010000)
#define ARM_PSCI_VER_0_2 (0x00000002)
+#define ARM_PSCI_VER_1_0 (0x00010000)
+#define ARM_PSCI_VER_1_1 (0x00010001)
/* PSCI 0.1 interface */
#define ARM_PSCI_FN_BASE 0x95c1ba5e
@@ -68,7 +69,6 @@
#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
-#define ARM_PSCI_0_2_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
/* PSCI 1.0 interface */
#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
@@ -86,6 +86,11 @@
#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
+/* PSCI 1.1 interface */
+#define ARM_PSCI_1_1_FN_SYSTEM_RESET2 ARM_PSCI_0_2_FN(18)
+
+#define ARM_PSCI_1_1_FN64_SYSTEM_RESET2 ARM_PSCI_0_2_FN64(18)
+
/* 1KB stack per core */
#define ARM_PSCI_STACK_SHIFT 10
#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT)
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -549,17 +549,20 @@ void mmu_page_table_flush(unsigned long
#ifdef CONFIG_ARMV7_PSCI
void psci_arch_cpu_entry(void);
void psci_arch_init(void);
+
u32 psci_version(void);
-s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_suspend(u32 function_id, u32 power_state, u32 pc, u32 context_id);
s32 psci_cpu_off(void);
-s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
- u32 context_id);
-s32 psci_affinity_info(u32 function_id, u32 target_affinity,
- u32 lowest_affinity_level);
+s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc, u32 context_id);
+s32 psci_affinity_info(u32 function_id, u32 target_affinity, u32 power_level);
u32 psci_migrate_info_type(void);
void psci_system_off(void);
void psci_system_reset(void);
s32 psci_features(u32 function_id, u32 psci_fid);
+s32 psci_cpu_default_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_node_hw_state(u32 function_id, u32 target_cpu, u32 power_level);
+s32 psci_system_suspend(u32 function_id, u32 pc, u32 context_id);
+s32 psci_system_reset2(u32 function_id, u32 reset_type, u32 cookie);
#endif
#endif /* __ASSEMBLY__ */
--- a/tools/sunxi_egon.c
+++ b/tools/sunxi_egon.c
@@ -12,7 +12,7 @@
* NAND requires 8K padding. SD/eMMC gets away with 512 bytes,
* but let's use the larger padding to cover both.
*/
-#define PAD_SIZE 8192
+#define PAD_SIZE 1024
static int egon_check_params(struct image_tool_params *params)
{

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 12 Dec 2020 23:55:04 -0600
Subject: [PATCH] Makefile: Add support for building a sunxi resume shim
---
.gitignore | 1 +
Makefile | 15 +++++++++++++++
2 files changed, 16 insertions(+)
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,7 @@ fit-dtb.blob*
/u-boot*
/boards.cfg
/*.log
+/resume.*
#
# git files that we don't want to ignore even it they are dot-files
--- a/Makefile
+++ b/Makefile
@@ -961,6 +961,21 @@ INPUTS-$(CONFIG_X86) += u-boot-x86-start
$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
$(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin)
+INPUTS-$(CONFIG_ARCH_SUNXI) += resume.egon
+
+MKIMAGEFLAGS_resume.egon := -T sunxi_egon
+
+resume.egon: resume.bin
+ $(call if_changed,mkimage)
+
+OBJCOPYFLAGS_resume.bin := -O binary
+
+resume.bin: resume.o
+ $(call if_changed,objcopy)
+
+resume.S: u-boot
+ @sed -En 's/(0x[[:xdigit:]]+) +psci_cpu_entry/ldr pc, =\1/p' $<.map > $@
+
LDFLAGS_u-boot += $(LDFLAGS_FINAL)
# Avoid 'Not enough room for program headers' error on binutils 2.28 onwards.

View File

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:00:07 -0600
Subject: [PATCH] sunxi: binman: Respect the default FIT configuration
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -82,7 +82,7 @@
};
configurations {
- default = "config-1";
+ default = "@config-DEFAULT-SEQ";
@config-SEQ {
description = "NAME";

View File

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:04:49 -0600
Subject: [PATCH] sunxi: binman: Do not hardcode U-Boot load address
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -40,7 +40,7 @@
os = "u-boot";
arch = "arm64";
compression = "none";
- load = <0x4a000000>;
+ load = <CONFIG_SYS_TEXT_BASE>;
u-boot-nodtb {
};

View File

@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:27:07 -0600
Subject: [PATCH] sunxi: binman: Explicitly pad SPL to expected size
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -30,6 +30,7 @@
#ifdef CONFIG_ARM64
fit {
description = "Configuration to load ATF before U-Boot";
+ offset = <CONFIG_SPL_PAD_TO>;
#address-cells = <1>;
fit,fdt-list = "of-list";

View File

@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 18 Nov 2020 23:31:47 -0600
Subject: [PATCH] sunxi: binman: Support FIT images for 32-bit boards
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 58 ++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,5 +1,6 @@
#include <config.h>
+#ifdef CONFIG_ARM64
#ifdef CONFIG_MACH_SUN50I_H6
#define BL31_ADDR 0x104000
#define SCP_ADDR 0x114000
@@ -7,6 +8,9 @@
#define BL31_ADDR 0x44000
#define SCP_ADDR 0x50000
#endif
+#else
+#define SCP_ADDR 0x48000
+#endif
/ {
aliases {
@@ -27,6 +31,7 @@
filename = "spl/sunxi-spl.bin";
};
+#ifdef CONFIG_SPL_FIT
#ifdef CONFIG_ARM64
fit {
description = "Configuration to load ATF before U-Boot";
@@ -94,6 +99,59 @@
};
};
#else
+ fit {
+ description = "Configuration to load SCP firmware with U-Boot";
+ offset = <CONFIG_SPL_PAD_TO>;
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+
+ images {
+ uboot {
+ description = "U-Boot (32-bit)";
+ type = "standalone";
+ os = "u-boot";
+ arch = "arm";
+ compression = "none";
+ load = <CONFIG_SYS_TEXT_BASE>;
+
+ u-boot-nodtb {
+ };
+ };
+
+ scp {
+ description = "SCP firmware";
+ type = "firmware";
+ arch = "or1k";
+ compression = "none";
+ load = <SCP_ADDR>;
+
+ scp {
+ filename = "scp.bin";
+ missing-msg = "scp-sunxi";
+ };
+ };
+
+ @fdt-SEQ {
+ description = "NAME";
+ type = "flat_dt";
+ compression = "none";
+
+ };
+ };
+
+ configurations {
+ default = "@config-DEFAULT-SEQ";
+
+ @config-SEQ {
+ description = "NAME";
+ firmware = "uboot";
+ loadables = "scp";
+ fdt = "fdt-SEQ";
+ };
+ };
+ };
+#endif
+#else
u-boot-img {
offset = <CONFIG_SPL_PAD_TO>;
};

View File

@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 13 Dec 2020 00:07:28 -0600
Subject: [PATCH] sunxi: binman: Add a resume shim
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -10,6 +10,7 @@
#endif
#else
#define SCP_ADDR 0x48000
+#define RESUME_ADDR 0x47000
#endif
/ {
@@ -118,6 +119,18 @@
};
};
+ resume {
+ description = "resume shim";
+ type = "standalone";
+ arch = "arm";
+ compression = "none";
+ load = <RESUME_ADDR>;
+
+ blob-ext {
+ filename = "resume.egon";
+ };
+ };
+
scp {
description = "SCP firmware";
type = "firmware";
@@ -145,7 +158,7 @@
@config-SEQ {
description = "NAME";
firmware = "uboot";
- loadables = "scp";
+ loadables = "resume", "scp";
fdt = "fdt-SEQ";
};
};