meta-st-stm32mp/recipes-bsp/u-boot/u-boot-stm32mp/0007-ARM-v2020.10-stm32mp-r...

947 lines
27 KiB
Diff

From 85fa6b016df48fdd465f8b5314b2e96a575c3228 Mon Sep 17 00:00:00 2001
From: Lionel Vitte <lionel.vitte@st.com>
Date: Mon, 18 Oct 2021 17:10:29 +0200
Subject: [PATCH 07/11] ARM v2020.10-stm32mp-r2 MACHINE
---
Makefile | 2 +-
arch/arm/cpu/armv7/cache_v7.c | 3 -
arch/arm/include/asm/cache.h | 1 -
arch/arm/include/asm/system.h | 18 +-
arch/arm/lib/cache-cp15.c | 13 +-
arch/arm/mach-omap2/omap-cache.c | 17 --
arch/arm/mach-stm32mp/Kconfig | 4 +-
arch/arm/mach-stm32mp/cmd_stm32key.c | 235 +++++++++++++++---
.../cmd_stm32prog/cmd_stm32prog.c | 36 ++-
.../mach-stm32mp/cmd_stm32prog/stm32prog.c | 35 ++-
.../mach-stm32mp/cmd_stm32prog/stm32prog.h | 3 +
.../cmd_stm32prog/stm32prog_serial.c | 10 +-
.../cmd_stm32prog/stm32prog_usb.c | 9 +-
arch/arm/mach-stm32mp/cpu.c | 61 ++++-
arch/arm/mach-stm32mp/dram_init.c | 19 +-
arch/arm/mach-stm32mp/syscon.c | 14 ++
16 files changed, 351 insertions(+), 129 deletions(-)
diff --git a/Makefile b/Makefile
index 59493deed3..25a42acc37 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2020
PATCHLEVEL = 10
SUBLEVEL =
-EXTRAVERSION = -stm32mp-r1.1
+EXTRAVERSION = -stm32mp-r2
NAME =
# *DOCUMENTATION*
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 146cf52608..19ff432352 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -176,9 +176,6 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
{
}
-void arm_init_domains(void)
-{
-}
#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index c20e05ec7f..b10edf805b 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -35,7 +35,6 @@ void l2_cache_disable(void);
void set_section_dcache(int section, enum dcache_option option);
void arm_init_before_mmu(void);
-void arm_init_domains(void);
void cpu_cache_initialization(void);
void dram_bank_mmu_setup(int bank);
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 932f12af1c..cab23ca7b2 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -397,20 +397,6 @@ static inline void set_cr(unsigned int val)
isb();
}
-static inline unsigned int get_dacr(void)
-{
- unsigned int val;
- asm("mrc p15, 0, %0, c3, c0, 0 @ get DACR" : "=r" (val) : : "cc");
- return val;
-}
-
-static inline void set_dacr(unsigned int val)
-{
- asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
- : : "r" (val) : "cc");
- isb();
-}
-
#ifdef CONFIG_ARMV7_LPAE
/* Long-Descriptor Translation Table Level 1/2 Bits */
#define TTB_SECT_XN_MASK (1ULL << 54)
@@ -476,7 +462,7 @@ enum dcache_option {
#define TTB_SECT_XN_MASK (1 << 4)
#define TTB_SECT_C_MASK (1 << 3)
#define TTB_SECT_B_MASK (1 << 2)
-#define TTB_SECT (2 << 0)
+#define TTB_SECT (2 << 0)
/*
* Short-descriptor format memory region attributes, without TEX remap
@@ -491,7 +477,7 @@ enum dcache_option {
enum dcache_option {
INVALID_ENTRY = 0,
DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT,
- DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
+ DCACHE_WRITETHROUGH = TTB_SECT_DOMAIN(0) | TTB_SECT | TTB_SECT_C_MASK,
DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
};
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 94e9b9c861..369be44b17 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -22,10 +22,6 @@ __weak void arm_init_before_mmu(void)
{
}
-__weak void arm_init_domains(void)
-{
-}
-
static void set_section_phys(int section, phys_addr_t phys,
enum dcache_option option)
{
@@ -209,11 +205,12 @@ static inline void mmu_setup(void)
asm volatile("mcr p15, 0, %0, c2, c0, 0"
: : "r" (gd->arch.tlb_addr) : "memory");
#endif
- /* Set the access control to all-supervisor */
+ /*
+ * initial value of Domain Access Control Register (DACR)
+ * Set the access control to client (1U) for each of the 16 domains
+ */
asm volatile("mcr p15, 0, %0, c3, c0, 0"
- : : "r" (~0));
-
- arm_init_domains();
+ : : "r" (0x55555555));
/* and enable the mmu */
reg = get_cr(); /* get control reg. */
diff --git a/arch/arm/mach-omap2/omap-cache.c b/arch/arm/mach-omap2/omap-cache.c
index 502ea6987a..451d8e4542 100644
--- a/arch/arm/mach-omap2/omap-cache.c
+++ b/arch/arm/mach-omap2/omap-cache.c
@@ -40,9 +40,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define ARMV7_DCACHE_POLICY DCACHE_WRITEBACK & ~TTB_SECT_XN_MASK
#endif
-#define ARMV7_DOMAIN_CLIENT 1
-#define ARMV7_DOMAIN_MASK (0x3 << 0)
-
void enable_caches(void)
{
@@ -66,17 +63,3 @@ void dram_bank_mmu_setup(int bank)
for (i = start; i < end; i++)
set_section_dcache(i, ARMV7_DCACHE_POLICY);
}
-
-void arm_init_domains(void)
-{
- u32 reg;
-
- reg = get_dacr();
- /*
- * Set DOMAIN to client access so that all permissions
- * set in pagetables are validated by the mmu.
- */
- reg &= ~ARMV7_DOMAIN_MASK;
- reg |= ARMV7_DOMAIN_CLIENT;
- set_dacr(reg);
-}
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index af0246d031..44bfac9000 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -130,10 +130,12 @@ config STM32_ETZPC
config CMD_STM32KEY
bool "command stm32key to fuse public key hash"
- default y
+ default n
help
fuse public key hash in corresponding fuse used to authenticate
binary.
+ This command is used to evaluate the secure boot on stm32mp SOC,
+ it is deactivated by default in real products.
config PRE_CON_BUF_ADDR
default 0xC02FF000
diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c
index f191085a12..d1755f4595 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32key.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32key.c
@@ -10,13 +10,30 @@
#include <dm/device.h>
#include <dm/uclass.h>
-#define STM32_OTP_HASH_KEY_START 24
-#define STM32_OTP_HASH_KEY_SIZE 8
+/* Closed device : bit 6 of OPT0*/
+#define STM32_OTP_CLOSE_ID 0
+#define STM32_OTP_CLOSE_MASK BIT(6)
+
+/* HASH of key: 8 OTPs, starting with OTP24) */
+#define STM32_OTP_HASH_KEY_START 24
+#define STM32_OTP_HASH_KEY_SIZE 8
+
+static int get_misc_dev(struct udevice **dev)
+{
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC, DM_GET_DRIVER(stm32mp_bsec), dev);
+ if (ret)
+ pr_err("Can't find stm32mp_bsec driver\n");
+
+ return ret;
+}
static void read_hash_value(u32 addr)
{
int i;
+ printf("Read KEY at 0x%x\n", addr);
for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i,
__be32_to_cpu(*(u32 *)addr));
@@ -24,32 +41,101 @@ static void read_hash_value(u32 addr)
}
}
-static void fuse_hash_value(u32 addr, bool print)
+static int read_hash_otp(bool print, bool *locked, bool *closed)
{
struct udevice *dev;
- u32 word, val;
- int i, ret;
+ int i, word, ret;
+ int nb_invalid = 0, nb_zero = 0, nb_lock = 0;
+ u32 val, lock;
+ bool status;
- ret = uclass_get_device_by_driver(UCLASS_MISC,
- DM_GET_DRIVER(stm32mp_bsec),
- &dev);
- if (ret) {
- pr_err("Can't find stm32mp_bsec driver\n");
- return;
+ ret = get_misc_dev(&dev);
+ if (ret)
+ return ret;
+
+ for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) {
+ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (ret != 4)
+ val = ~0x0;
+ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
+ if (ret != 4)
+ lock = -1;
+ if (print)
+ printf("OTP HASH %i: %x lock : %d\n", word, val, lock);
+ if (val == ~0x0)
+ nb_invalid++;
+ else if (val == 0x0)
+ nb_zero++;
+ if (lock == 1)
+ nb_lock++;
}
- for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
+ word = STM32_OTP_CLOSE_ID;
+ ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (ret != 4)
+ val = 0x0;
+ ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4);
+ if (ret != 4)
+ lock = -1;
+
+ status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK;
+ if (closed)
+ *closed = status;
+ if (print)
+ printf("OTP %d: closed status: %d lock : %d\n", word, status, lock);
+
+ status = (nb_lock == STM32_OTP_HASH_KEY_SIZE);
+ if (locked)
+ *locked = status;
+ if (!status && print)
+ printf("HASK key is not locked!\n");
+
+ if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) {
+ if (print)
+ printf("HASK key is invalid!\n");
+ return -EINVAL;
+ }
+ if (nb_zero == STM32_OTP_HASH_KEY_SIZE) {
if (print)
- printf("Fuse OTP %i : %x\n",
- STM32_OTP_HASH_KEY_START + i,
- __be32_to_cpu(*(u32 *)addr));
+ printf("HASK key is free!\n");
+ return -ENOENT;
+ }
+
+ return 0;
+}
- word = STM32_OTP_HASH_KEY_START + i;
+static int fuse_hash_value(u32 addr, bool print)
+{
+ struct udevice *dev;
+ u32 word, val;
+ int i, ret;
+
+ ret = get_misc_dev(&dev);
+ if (ret)
+ return ret;
+
+ for (i = 0, word = STM32_OTP_HASH_KEY_START;
+ i < STM32_OTP_HASH_KEY_SIZE;
+ i++, word++, addr += 4) {
val = __be32_to_cpu(*(u32 *)addr);
- misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (print)
+ printf("Fuse OTP %i : %x\n", word, val);
- addr += 4;
+ ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
+ if (ret != 4) {
+ printf("Fuse OTP %i failed\n", word);
+ return ret;
+ }
+ /* on success, lock the OTP for HASH key */
+ val = 1;
+ ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4);
+ if (ret != 4) {
+ printf("Lock OTP %i failed\n", word);
+ return ret;
+ }
}
+
+ return 0;
}
static int confirm_prog(void)
@@ -66,36 +152,113 @@ static int confirm_prog(void)
return 0;
}
-static int do_stm32key(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
+static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
u32 addr;
- const char *op = argc >= 2 ? argv[1] : NULL;
- int confirmed = argc > 3 && !strcmp(argv[2], "-y");
- argc -= 2 + confirmed;
- argv += 2 + confirmed;
+ if (argc == 1) {
+ read_hash_otp(true, NULL, NULL);
+ return CMD_RET_SUCCESS;
+ }
- if (argc < 1)
+ addr = simple_strtoul(argv[1], NULL, 16);
+ if (!addr)
return CMD_RET_USAGE;
- addr = simple_strtoul(argv[0], NULL, 16);
+ read_hash_value(addr);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ u32 addr;
+ bool yes = false, lock, closed;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (argc == 3) {
+ if (strcmp(argv[1], "-y"))
+ return CMD_RET_USAGE;
+ yes = true;
+ }
+
+ addr = simple_strtoul(argv[argc - 1], NULL, 16);
if (!addr)
return CMD_RET_USAGE;
- if (!strcmp(op, "read"))
- read_hash_value(addr);
+ if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) {
+ printf("Error: can't fuse again the OTP\n");
+ return CMD_RET_FAILURE;
+ }
- if (!strcmp(op, "fuse")) {
- if (!confirmed && !confirm_prog())
- return CMD_RET_FAILURE;
- fuse_hash_value(addr, !confirmed);
+ if (lock || closed) {
+ printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed);
+ return CMD_RET_FAILURE;
}
+ if (!yes && !confirm_prog())
+ return CMD_RET_FAILURE;
+
+ if (fuse_hash_value(addr, !yes))
+ return CMD_RET_FAILURE;
+
+ printf("Hash key updated !\n");
+
return CMD_RET_SUCCESS;
}
-U_BOOT_CMD(stm32key, 4, 1, do_stm32key,
- "Fuse ST Hash key",
- "read <addr>: Read the hash store at addr in memory\n"
- "stm32key fuse [-y] <addr> : Fuse hash store at addr in otp\n");
+static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ bool yes, lock, closed;
+ struct udevice *dev;
+ u32 val;
+ int ret;
+
+ yes = false;
+ if (argc == 2) {
+ if (strcmp(argv[1], "-y"))
+ return CMD_RET_USAGE;
+ yes = true;
+ }
+
+ if (read_hash_otp(!yes, &lock, &closed))
+ return CMD_RET_FAILURE;
+
+ if (closed) {
+ printf("Error: already closed!\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (!lock)
+ printf("Warning: OTP not locked, revocation is possible!\n");
+
+ if (!yes && !confirm_prog())
+ return CMD_RET_FAILURE;
+
+ ret = get_misc_dev(&dev);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ val = STM32_OTP_CLOSE_MASK;
+ ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4);
+ if (ret != 4) {
+ printf("Error: can't update OTP\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Device is closed !\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+static char stm32key_help_text[] =
+ "read [<addr>]: Read the hash stored at addr in memory or in OTP\n"
+ "stm32key fuse [-y] <addr> : Fuse hash stored at addr in OTP\n"
+ "stm32key close [-y] : Close the device, the hash stored in OTP\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Fuse ST Hash key", stm32key_help_text,
+ U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read),
+ U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse),
+ U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close));
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
index a20980a6ae..b2a17314ee 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
@@ -45,7 +45,6 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
bool reset = false;
struct image_header_s header;
struct stm32prog_data *data;
- u32 uimage, dtb;
if (argc < 3 || argc > 5)
return CMD_RET_USAGE;
@@ -78,10 +77,12 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
if (header.type == HEADER_STM32IMAGE) {
size = header.image_length + BL_HEADER_SIZE;
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
/* uImage detected in STM32IMAGE, execute the script */
if (IMAGE_FORMAT_LEGACY ==
genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
return image_source_script(addr + BL_HEADER_SIZE, "script@1");
+#endif
}
}
@@ -98,7 +99,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
ret = stm32prog_init(data, addr, size);
if (ret)
- printf("Invalid or missing layout file.");
+ log_debug("Invalid or missing layout file at 0x%lx.\n", addr);
/* prepare DFU for device read/write */
ret = stm32prog_dfu_init(data);
@@ -119,21 +120,23 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
goto cleanup;
}
- uimage = data->uimage;
- dtb = data->dtb;
-
stm32prog_clean(data);
free(stm32prog_data);
stm32prog_data = NULL;
puts("Download done\n");
- if (uimage) {
+ if (data->uimage) {
char boot_addr_start[20];
char dtb_addr[20];
+ char initrd_addr[40];
char *bootm_argv[5] = {
"bootm", boot_addr_start, "-", dtb_addr, NULL
};
+ u32 uimage = data->uimage;
+ u32 dtb = data->dtb;
+ u32 initrd = data->initrd;
+
if (!dtb)
bootm_argv[3] = env_get("fdtcontroladdr");
else
@@ -142,8 +145,15 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
"0x%x", uimage);
- printf("Booting kernel at %s - %s...\n\n\n",
- boot_addr_start, bootm_argv[3]);
+
+ if (initrd) {
+ snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%x:0x%x",
+ initrd, data->initrd_size);
+ bootm_argv[2] = initrd_addr;
+ }
+
+ printf("Booting kernel at %s %s %s...\n\n\n",
+ boot_addr_start, bootm_argv[2], bootm_argv[3]);
/* Try bootm for legacy and FIT format image */
if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
do_bootm(cmdtp, 0, 4, bootm_argv);
@@ -167,12 +177,12 @@ cleanup:
}
U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
+ "start communication with tools STM32Cubeprogrammer",
"<link> <dev> [<addr>] [<size>]\n"
- "start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
- "<link> = serial|usb\n"
- "<dev> = device instance\n"
- "<addr> = address of flashlayout\n"
- "<size> = size of flashlayout\n"
+ " <link> = serial|usb\n"
+ " <dev> = device instance\n"
+ " <addr> = address of flashlayout\n"
+ " <size> = size of flashlayout (optional for image with STM32 header)\n"
);
#ifdef CONFIG_STM32MP15x_STM32IMAGE
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index 7cd31462ba..62b386582d 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -1153,7 +1153,10 @@ static int dfu_init_entities(struct stm32prog_data *data)
struct dfu_entity *dfu;
int alt_nb;
- alt_nb = 3; /* number of virtual = CMD, OTP, PMIC*/
+ alt_nb = 2; /* number of virtual = CMD, OTP*/
+ if (CONFIG_IS_ENABLED(DM_PMIC))
+ alt_nb++; /* PMIC NVMEM*/
+
if (data->part_nb == 0)
alt_nb++; /* +1 for FlashLayout */
else
@@ -1199,13 +1202,13 @@ static int dfu_init_entities(struct stm32prog_data *data)
}
if (!ret)
- ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, 512);
+ ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE);
if (!ret)
- ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, 512);
+ ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, OTP_SIZE);
if (!ret && CONFIG_IS_ENABLED(DM_PMIC))
- ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, 8);
+ ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE);
if (ret)
stm32prog_err("dfu init failed: %d", ret);
@@ -1476,7 +1479,7 @@ error:
return ret;
}
-static void stm32prog_end_phase(struct stm32prog_data *data)
+static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset)
{
if (data->phase == PHASE_FLASHLAYOUT) {
if (parse_flash_layout(data, STM32_DDR_BASE, 0))
@@ -1492,6 +1495,10 @@ static void stm32prog_end_phase(struct stm32prog_data *data)
data->uimage = data->cur_part->addr;
if (data->cur_part->part_type == PART_FILESYSTEM)
data->dtb = data->cur_part->addr;
+ if (data->cur_part->part_type == PART_BINARY) {
+ data->initrd = data->cur_part->addr;
+ data->initrd_size = offset;
+ }
}
if (CONFIG_IS_ENABLED(MMC) &&
@@ -1750,7 +1757,7 @@ void dfu_flush_callback(struct dfu_entity *dfu)
if (dfu->dev_type == DFU_DEV_RAM) {
if (dfu->alt == 0 &&
stm32prog_data->phase == PHASE_FLASHLAYOUT) {
- stm32prog_end_phase(stm32prog_data);
+ stm32prog_end_phase(stm32prog_data, dfu->offset);
/* waiting DFU DETACH for reenumeration */
}
}
@@ -1759,7 +1766,7 @@ void dfu_flush_callback(struct dfu_entity *dfu)
return;
if (dfu->alt == stm32prog_data->cur_part->alt_id) {
- stm32prog_end_phase(stm32prog_data);
+ stm32prog_end_phase(stm32prog_data, dfu->offset);
stm32prog_next_phase(stm32prog_data);
}
}
@@ -1779,3 +1786,17 @@ void dfu_initiated_callback(struct dfu_entity *dfu)
pr_debug("dfu offset = 0x%llx\n", dfu->offset);
}
}
+
+void dfu_error_callback(struct dfu_entity *dfu, const char *msg)
+{
+ struct stm32prog_data *data = stm32prog_data;
+
+ if (!stm32prog_data)
+ return;
+
+ if (!stm32prog_data->cur_part)
+ return;
+
+ if (dfu->alt == stm32prog_data->cur_part->alt_id)
+ stm32prog_err(msg);
+}
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
index eebc4d2e71..f4243ae2ec 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
@@ -19,6 +19,7 @@
#define DEFAULT_ADDRESS 0xFFFFFFFF
+#define CMD_SIZE 512
#define OTP_SIZE 1024
#define PMIC_SIZE 8
@@ -144,6 +145,8 @@ struct stm32prog_data {
/* bootm information */
u32 uimage;
u32 dtb;
+ u32 initrd;
+ u32 initrd_size;
};
extern struct stm32prog_data *stm32prog_data;
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c
index a0bf7e1884..3d32adcf62 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c
@@ -10,6 +10,7 @@
#include <malloc.h>
#include <serial.h>
#include <watchdog.h>
+#include <asm/arch/sys_proto.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
#include <linux/delay.h>
@@ -18,8 +19,7 @@
/* - configuration part -----------------------------*/
#define USART_BL_VERSION 0x40 /* USART bootloader version V4.0*/
#define UBOOT_BL_VERSION 0x03 /* bootloader version V0.3*/
-#define DEVICE_ID_BYTE1 0x05 /* MSB byte of device ID*/
-#define DEVICE_ID_BYTE2 0x00 /* LSB byte of device ID*/
+
#define USART_RAM_BUFFER_SIZE 256 /* Size of USART_RAM_Buf buffer*/
/* - Commands -----------------------------*/
@@ -435,10 +435,12 @@ static void get_version_command(struct stm32prog_data *data)
*/
static void get_id_command(struct stm32prog_data *data)
{
+ u32 cpu = get_cpu_dev();
+
/* Send Device IDCode */
stm32prog_serial_putc(0x1);
- stm32prog_serial_putc(DEVICE_ID_BYTE1);
- stm32prog_serial_putc(DEVICE_ID_BYTE2);
+ stm32prog_serial_putc((cpu >> 8) & 0xFF);
+ stm32prog_serial_putc(cpu & 0xFF);
stm32prog_serial_result(ACK_BYTE);
}
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
index 30547f94c9..6ddf08523e 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c
@@ -178,7 +178,7 @@ int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
switch (dfu->data.virt.dev_num) {
case PHASE_CMD:
- *size = 512;
+ *size = CMD_SIZE;
break;
case PHASE_OTP:
*size = OTP_SIZE;
@@ -207,13 +207,10 @@ bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
if (stm32prog_data->phase == PHASE_FLASHLAYOUT) {
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
- if (ret || stm32prog_data->phase == PHASE_DO_RESET)
+ if (ret || stm32prog_data->phase != PHASE_FLASHLAYOUT)
return ret;
/* prepare the second enumeration with the FlashLayout */
- if (stm32prog_data->phase == PHASE_FLASHLAYOUT)
- stm32prog_dfu_init(data);
- /* found next selected partition */
- stm32prog_next_phase(data);
+ stm32prog_dfu_init(data);
}
ret = run_usb_dnl_gadget(dev, "usb_dnl_dfu");
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index b81825a0bf..2495d4aaad 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -9,6 +9,7 @@
#include <env.h>
#include <init.h>
#include <log.h>
+#include <lmb.h>
#include <misc.h>
#include <net.h>
#include <asm/io.h>
@@ -86,6 +87,8 @@
*/
u8 early_tlb[PGTABLE_SIZE] __section(".data") __aligned(0x4000);
+struct lmb lmb;
+
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
#ifndef CONFIG_TFABOOT
static void security_init(void)
@@ -207,6 +210,44 @@ u32 get_bootmode(void)
TAMP_BOOT_MODE_SHIFT;
}
+/*
+ * weak function overidde: set the DDR/SYSRAM executable before to enable the
+ * MMU and configure DACR, for early early_enable_caches (SPL or pre-reloc)
+ */
+void dram_bank_mmu_setup(int bank)
+{
+ struct bd_info *bd = gd->bd;
+ int i;
+ phys_addr_t start;
+ phys_size_t size;
+ bool use_lmb = false;
+ enum dcache_option option;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD)) {
+#ifdef CONFIG_SPL
+ start = ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE);
+ size = ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE);
+#endif
+ } else if (gd->flags & GD_FLG_RELOC) {
+ /* bd->bi_dram is available only after relocation */
+ start = bd->bi_dram[bank].start;
+ size = bd->bi_dram[bank].size;
+ use_lmb = true;
+ } else {
+ /* mark cacheable and executable the beggining of the DDR */
+ start = STM32_DDR_BASE;
+ size = CONFIG_DDR_CACHEABLE_SIZE;
+ }
+
+ for (i = start >> MMU_SECTION_SHIFT;
+ i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT);
+ i++) {
+ option = DCACHE_DEFAULT_OPTION;
+ if (use_lmb && lmb_is_reserved_flags(&lmb, i << MMU_SECTION_SHIFT, LMB_NOMAP))
+ option = INVALID_ENTRY;
+ set_section_dcache(i, option);
+ }
+}
/*
* initialize the MMU and activate cache in SPL or in U-Boot pre-reloc stage
* MMU/TLB is updated in enable_caches() for U-Boot after relocation
@@ -224,17 +265,8 @@ static void early_enable_caches(void)
gd->arch.tlb_addr = (unsigned long)&early_tlb;
#endif
+ /* enable MMU (default configuration) */
dcache_enable();
-
- if (IS_ENABLED(CONFIG_SPL_BUILD))
- mmu_set_region_dcache_behaviour(
- ALIGN_DOWN(STM32_SYSRAM_BASE, MMU_SECTION_SIZE),
- ALIGN(STM32_SYSRAM_SIZE, MMU_SECTION_SIZE),
- DCACHE_DEFAULT_OPTION);
- else
- mmu_set_region_dcache_behaviour(STM32_DDR_BASE,
- CONFIG_DDR_CACHEABLE_SIZE,
- DCACHE_DEFAULT_OPTION);
}
/*
@@ -278,6 +310,9 @@ int arch_cpu_init(void)
void enable_caches(void)
{
+ /* parse device tree when data cache is still activated */
+ lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+
/* I-cache is already enabled in start.S: icache_enable() not needed */
/* deactivate the data cache, early enabled in arch_cpu_init() */
@@ -479,7 +514,7 @@ static void setup_boot_mode(void)
gd->flags &= ~(GD_FLG_SILENT |
GD_FLG_DISABLE_CONSOLE);
printf("uart%d = %s not found in device tree!\n",
- instance, cmd);
+ instance + 1, cmd);
break;
}
sprintf(cmd, "%d", dev->seq);
@@ -517,7 +552,9 @@ static void setup_boot_mode(void)
env_set("boot_instance", "0");
break;
default:
- pr_debug("unexpected boot mode = %x\n", boot_mode);
+ env_set("boot_device", "invalid");
+ env_set("boot_instance", "");
+ log_err("unexpected boot mode = %x\n", boot_mode);
break;
}
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index 0e8ce63f4a..2c409ee217 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -10,6 +10,7 @@
#include <lmb.h>
#include <log.h>
#include <ram.h>
+#include <asm/system.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -38,17 +39,27 @@ int dram_init(void)
ulong board_get_usable_ram_top(ulong total_size)
{
+ phys_size_t size;
phys_addr_t reg;
struct lmb lmb;
+ if (!total_size)
+ return gd->ram_top;
+
/* found enough not-reserved memory to relocated U-Boot */
lmb_init(&lmb);
lmb_add(&lmb, gd->ram_base, gd->ram_size);
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
- reg = lmb_alloc(&lmb, CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K);
+ /* add 8M for reserved memory for display, fdt, gd,... */
+ size = ALIGN(SZ_8M + CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE),
+ reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
+
+ if (!reg)
+ reg = gd->ram_top - size;
- if (reg)
- return ALIGN(reg + CONFIG_SYS_MALLOC_LEN + total_size, SZ_4K);
+ /* before relocation, mark the U-Boot memory as cacheable by default */
+ if (!(gd->flags & GD_FLG_RELOC))
+ mmu_set_region_dcache_behaviour(reg, size, DCACHE_DEFAULT_OPTION);
- return gd->ram_top;
+ return reg + size;
}
diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c
index 3e61ce4097..a0e8e1dfdc 100644
--- a/arch/arm/mach-stm32mp/syscon.c
+++ b/arch/arm/mach-stm32mp/syscon.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <syscon.h>
#include <asm/arch/stm32.h>
@@ -14,9 +15,22 @@ static const struct udevice_id stm32mp_syscon_ids[] = {
{ }
};
+static int stm32mp_syscon_probe(struct udevice *dev)
+{
+ struct clk_bulk clk_bulk;
+ int ret;
+
+ ret = clk_get_bulk(dev, &clk_bulk);
+ if (!ret)
+ clk_enable_bulk(&clk_bulk);
+
+ return 0;
+}
+
U_BOOT_DRIVER(syscon_stm32mp) = {
.name = "stmp32mp_syscon",
.id = UCLASS_SYSCON,
.of_match = stm32mp_syscon_ids,
.bind = dm_scan_fdt_dev,
+ .probe = stm32mp_syscon_probe,
};
--
2.25.1