Skip to content

Commit aa11f49

Browse files
radubacrauintelAlif Zakuan Yuslaimi
authored andcommitted
arch: arm: rsu: Multiboot selection Uboot SSBL for RSU
Use different Uboot in QSPI for each RSU bitstream based on the SPL. Selection is based on the naming of SSBL partition, e.g: P1 SPL will select SSBL.P1 for loading the Uboot SSBL. Signed-off-by: Kah Jing Lee <kah.jing.lee@intel.com> Signed-off-by: Radu Bacrau <radu.bacrau@intel.com>
1 parent cc2f57f commit aa11f49

File tree

6 files changed

+224
-1
lines changed

6 files changed

+224
-1
lines changed

arch/arm/mach-socfpga/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ config ERR_PTR_OFFSET
66
config NR_DRAM_BANKS
77
default 1
88

9+
config SOCFPGA_RSU_MULTIBOOT
10+
bool "Enable RSU Multiboot Selection Feature"
11+
depends on TARGET_SOCFPGA_SOC64 && SPI_FLASH
12+
default y
13+
help
14+
Multiboot u-boot proper image (SSBL) selection feature for RSU.
15+
SPL will select the respective SSBL based on the partition it resides
16+
inside RSU QSPI flash layout.
17+
918
config SOCFPGA_SECURE_VAB_AUTH
1019
bool "Enable boot image authentication with Secure Device Manager"
1120
depends on TARGET_SOCFPGA_AGILEX || TARGET_SOCFPGA_N5X || \

arch/arm/mach-socfpga/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
154154
obj-$(CONFIG_SPL_ATF) += smc_api.o
155155
endif
156156

157+
ifdef CONFIG_SOCFPGA_RSU_MULTIBOOT
158+
obj-y+= rsu_spl.o
159+
endif
160+
157161
ifdef CONFIG_TARGET_SOCFPGA_GEN5
158162
# QTS-generated config file wrappers
159163
CFLAGS_wrap_iocsr_config.o+= -I$(srctree)/board/$(BOARDDIR)

arch/arm/mach-socfpga/include/mach/rsu_s10.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ extern u32 smc_rsu_update_address;
1414
#define SPT0_INDEX1
1515
#define SPT1_INDEX3
1616

17+
#define MAX_PART_NAME_LENGTH 16
18+
1719
/* CMF pointer block */
1820
struct socfpga_rsu_s10_cpb {
1921
u32 magic_number;
@@ -28,7 +30,7 @@ struct socfpga_rsu_s10_cpb {
2830

2931
/* sub partition slot */
3032
struct socfpga_rsu_s10_spt_slot {
31-
char name[16];
33+
char name[MAX_PART_NAME_LENGTH];
3234
u32 offset[2];
3335
u32 length;
3436
u32 flag;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) 2022 Intel Corporation <www.intel.com>
4+
*
5+
*/
6+
7+
#ifndef _RSU_S10_SPL_H_
8+
#define _RSU_S10_SPL_H_
9+
#include <asm/arch/rsu_s10.h>
10+
11+
u32 rsu_spl_ssbl_address(void);
12+
u32 rsu_spl_ssbl_size(void);
13+
14+
#endif /* _RSU_S10_SPL__H_ */

arch/arm/mach-socfpga/rsu_spl.c

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2022 Intel Corporation <www.intel.com>
4+
*
5+
*/
6+
#include <common.h>
7+
#include <linux/errno.h>
8+
#include <spi.h>
9+
#include <spi_flash.h>
10+
#include <asm/arch/mailbox_s10.h>
11+
#include <asm/arch/rsu.h>
12+
#include <asm/arch/rsu_s10.h>
13+
#include <asm/arch/rsu_spl.h>
14+
15+
#define SSBL_PART_PREFIX"SSBL."
16+
#define RSU_ADDR_MASK0xFFFFFFFF
17+
#define RSU_ADDR_SHIFT32
18+
19+
static int get_ssbl_slot(struct socfpga_rsu_s10_spt_slot *rsu_ssbl_slot)
20+
{
21+
struct socfpga_rsu_s10_spt rsu_spt = {0};
22+
u32 rsu_spt0_offset = 0, rsu_spt1_offset = 0;
23+
u32 spt_offset[4];
24+
struct rsu_status_info rsu_status;
25+
int crt_spt_index = -EINVAL;
26+
char *result;
27+
struct spi_flash *flash;
28+
int i;
29+
30+
rsu_ssbl_slot->offset[0] = -EINVAL;
31+
32+
/* get rsu status */
33+
if (mbox_rsu_status((u32 *)&rsu_status, sizeof(rsu_status) / 4)) {
34+
puts("RSU: Error - mbox_rsu_status failed!\n");
35+
return -EOPNOTSUPP;
36+
}
37+
38+
/* get spt offsets */
39+
if (mbox_rsu_get_spt_offset(spt_offset, 4)) {
40+
puts("RSU: Error - mbox_rsu_get_spt_offset failed!\n");
41+
return -EINVAL;
42+
}
43+
44+
rsu_spt0_offset = spt_offset[SPT0_INDEX];
45+
rsu_spt1_offset = spt_offset[SPT1_INDEX];
46+
47+
/* initialize flash */
48+
flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
49+
CONFIG_SF_DEFAULT_CS,
50+
CONFIG_SF_DEFAULT_SPEED,
51+
CONFIG_SF_DEFAULT_MODE);
52+
if (!flash) {
53+
puts("RSU: Error - spi_flash_probe failed!\n");
54+
return -EINVAL;
55+
}
56+
57+
/* read spt0 */
58+
if (spi_flash_read(flash, rsu_spt0_offset, sizeof(rsu_spt), &rsu_spt)) {
59+
puts("RSU: Error - spi_flash_read failed!\n");
60+
return -EINVAL;
61+
}
62+
63+
/* if spt0 does not have the correct magic number */
64+
if (rsu_spt.magic_number != RSU_S10_SPT_MAGIC_NUMBER) {
65+
/* read spt1 */
66+
if (spi_flash_read(flash, rsu_spt1_offset, sizeof(rsu_spt), &rsu_spt)) {
67+
printf("RSU: Error - spi_flash_read failed!\n");
68+
return -EINVAL;
69+
}
70+
71+
/* bail out if spt1 does not have the correct magic number */
72+
if (rsu_spt.magic_number != RSU_S10_SPT_MAGIC_NUMBER) {
73+
printf("RSU: Error: spt table magic number not match 0x%08x!\n",
74+
rsu_spt.magic_number);
75+
return -EINVAL;
76+
}
77+
}
78+
79+
/* display status */
80+
debug("RSU current image: 0x%08x\n", (u32)rsu_status.current_image);
81+
debug("RSU state: 0x%08x\n", rsu_status.state);
82+
debug("RSU error location: 0x%08x\n", rsu_status.error_location);
83+
debug("RSU error details: 0x%08x\n", rsu_status.error_details);
84+
85+
/* display partitions */
86+
for (i = 0; i < rsu_spt.entries; i++) {
87+
debug("RSU: Partition '%s' start=0x%08x length=0x%08x\n",
88+
rsu_spt.spt_slot[i].name, rsu_spt.spt_slot[i].offset[0],
89+
rsu_spt.spt_slot[i].length);
90+
}
91+
92+
/* locate the SPT entry for currently loaded image */
93+
for (i = 0; i < rsu_spt.entries; i++) {
94+
if (((rsu_status.current_image & RSU_ADDR_MASK) ==
95+
rsu_spt.spt_slot[i].offset[0]) &&
96+
((rsu_status.current_image >> RSU_ADDR_SHIFT) ==
97+
rsu_spt.spt_slot[i].offset[1])) {
98+
crt_spt_index = i;
99+
break;
100+
}
101+
}
102+
103+
if (crt_spt_index == -EINVAL) {
104+
puts("RSU: Error - could not locate partition in the SPT table!\n");
105+
return -EINVAL;
106+
}
107+
108+
/* locate the u-boot proper(SSBL) partition and return its address */
109+
for (i = 0; i < rsu_spt.entries; i++) {
110+
/* get the substring ptr to the first occurrence of SSBL. prefix */
111+
result = strstr(rsu_spt.spt_slot[i].name, SSBL_PART_PREFIX);
112+
113+
/* skip if not found the SSBL prefix */
114+
if (!result)
115+
continue;
116+
117+
/* check if the prefix is located at the first */
118+
if (result == rsu_spt.spt_slot[i].name) {
119+
/* move to the substring after SSBL. prefix */
120+
result += strlen(SSBL_PART_PREFIX);
121+
122+
/* compare SPL's spt name after the prefix */
123+
if (!strncmp(result, rsu_spt.spt_slot[crt_spt_index].name,
124+
MAX_PART_NAME_LENGTH - strlen(SSBL_PART_PREFIX))) {
125+
printf("RSU: found SSBL partition %s at address 0x%08x.\n",
126+
result, (int)rsu_spt.spt_slot[i].offset[0]);
127+
memcpy(rsu_ssbl_slot, &rsu_spt.spt_slot[i],
128+
sizeof(struct socfpga_rsu_s10_spt_slot));
129+
130+
return 0;
131+
}
132+
}
133+
}
134+
135+
/* fail to find u-boot proper(SSBL) */
136+
printf("RSU: Error - could not find u-boot proper partition SSBL.%s!\n",
137+
rsu_spt.spt_slot[crt_spt_index].name);
138+
139+
return -EINVAL;
140+
}
141+
142+
u32 rsu_spl_ssbl_address(void)
143+
{
144+
int ret;
145+
struct socfpga_rsu_s10_spt_slot rsu_ssbl_slot = {0};
146+
147+
ret = get_ssbl_slot(&rsu_ssbl_slot);
148+
if (ret) {
149+
if (ret == -EOPNOTSUPP) {
150+
puts("RSU: Error - mbox_rsu_status failed! Check for RSU image.\n");
151+
return CONFIG_SYS_SPI_U_BOOT_OFFS;
152+
}
153+
154+
/* should throw error if cannot find u-boot proper(SSBL) address */
155+
panic("ERROR: could not find u-boot proper(SSBL) address!");
156+
}
157+
158+
printf("RSU: Success found SSBL at offset: %08x.\n", rsu_ssbl_slot.offset[0]);
159+
return rsu_ssbl_slot.offset[0];
160+
}
161+
162+
u32 rsu_spl_ssbl_size(void)
163+
{
164+
struct socfpga_rsu_s10_spt_slot rsu_ssbl_slot = {0};
165+
166+
/* check for valid u-boot proper(SSBL) address for the size */
167+
if (get_ssbl_slot(&rsu_ssbl_slot) == -EOPNOTSUPP) {
168+
printf("ERROR: Invalid address, could not retrieve SSBL size!");
169+
return 0;
170+
}
171+
172+
if (!rsu_ssbl_slot.length) {
173+
/* throw error if cannot find u-boot proper(SSBL) size */
174+
panic("ERROR: could not retrieve u-boot proper(SSBL) size!");
175+
}
176+
177+
printf("RSU: Success found SSBL with length: %08x.\n", rsu_ssbl_slot.length);
178+
return rsu_ssbl_slot.length;
179+
}
180+
181+
unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)
182+
{
183+
return rsu_spl_ssbl_address();
184+
}

env/sf.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include <asm/global_data.h>
2222
#include <dm/device-internal.h>
2323
#include <u-boot/crc.h>
24+
#if (CONFIG_IS_ENABLED(SOCFPGA_RSU_MULTIBOOT))
25+
#include <asm/arch/rsu_spl.h>
26+
#endif
2427

2528
#defineOFFSET_INVALID(~(u32)0)
2629

@@ -36,6 +39,13 @@ static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND;
3639

3740
#endif /* CONFIG_ENV_OFFSET_REDUND */
3841

42+
#if (CONFIG_IS_ENABLED(SOCFPGA_RSU_MULTIBOOT))
43+
#undef CONFIG_ENV_OFFSET
44+
#define CONFIG_ENV_OFFSET (rsu_spl_ssbl_address() +\
45+
rsu_spl_ssbl_size() -\
46+
CONFIG_ENV_SIZE)
47+
#endif
48+
3949
DECLARE_GLOBAL_DATA_PTR;
4050

4151
__weak int spi_get_env_dev(void)

0 commit comments

Comments
 (0)