common: spl: rkfw: support bing-up arm32 firmware

1. the arm32 trust firmware is diffirent with arm64, support it.
2. add entry_point_os to indicate the uboot or kernel entry point.

Signed-off-by: Jason Zhu <jason.zhu@rock-chips.com>
Change-Id: I24d1601323e99f40e81d18f1937f762b2ecc137f
(cherry picked from commit a64fd729d4)

Change-Id: I3b1420989d158c52259365d90011524b047b5750
This commit is contained in:
Jason Zhu 2020-03-09 10:58:41 +08:00 committed by Joseph Chen
parent 5d2498f1da
commit 1cb393f1c8
4 changed files with 93 additions and 43 deletions

View File

@ -65,7 +65,6 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
#ifdef CONFIG_SPL_LOAD_RKFW
u32 trust_sectors = CONFIG_RKFW_TRUST_SECTOR;
u32 uboot_sectors = CONFIG_RKFW_U_BOOT_SECTOR;
u32 boot_sectors = CONFIG_RKFW_BOOT_SECTOR;
struct spl_load_info load;
load.dev = mmc;
@ -85,8 +84,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
#endif
ret = spl_load_rkfw_image(spl_image, &load,
trust_sectors,
uboot_sectors,
boot_sectors);
uboot_sectors);
/* If boot successfully or can't try others, just go end */
if (!ret || ret != -EAGAIN)
goto end;

View File

@ -7,11 +7,11 @@
#include <android_image.h>
#include <errno.h>
#include <malloc.h>
#include <spl.h>
#include <spl_rkfw.h>
#include <linux/kernel.h>
#include <asm/arch/spl_resource_img.h>
#ifdef CONFIG_SPL_ATF
static const __aligned(16) struct s_fip_name_id fip_name_id[] = {
{ BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30 }, /* optional */
{ BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31 }, /* mandatory */
@ -164,7 +164,7 @@ static int load_image(struct spl_load_info *info,
}
static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector,
uintptr_t *bl31_entry, uintptr_t *bl32_entry,
struct spl_image_info *spl_image,
int *found_rkfw, u32 try_count)
{
struct tag_tboot_header_2k hdr;
@ -184,16 +184,16 @@ static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector,
/* bl31 is mandatory */
ret = load_image(info, &hdr, sect_addr,
BL31_IMAGE_NAME, bl31_entry);
BL31_IMAGE_NAME, &spl_image->entry_point);
if (ret)
continue;
/* bl32 is optional */
ret = load_image(info, &hdr, sect_addr,
BL32_IMAGE_NAME, bl32_entry);
BL32_IMAGE_NAME, &spl_image->entry_point_bl32);
if (ret) {
if (ret == -ENONET) {
*bl32_entry = -1; /* Not exist */
spl_image->entry_point_bl32 = -1; /* Not exist */
ret = 0;
} else {
continue;
@ -205,9 +205,52 @@ static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector,
return ret;
}
#else
static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector,
struct spl_image_info *spl_image,
int *found_rkfw, u32 try_count)
{
struct tag_second_loader_hdr hdr;
int i, ret, blkcnt = 4; /* header sectors, 2KB */
char *load_addr;
u32 sect_addr;
/* Detect valid image header */
for (i = 0; i < try_count; i++) {
sect_addr = image_sector + (i * RKFW_RETRY_SECTOR_SIZE);
ret = info->read(info, sect_addr, blkcnt, &hdr);
if (ret != blkcnt)
continue;
if (!memcmp(hdr.magic, TBOOT_HEAD_TAG, 6)) {
*found_rkfw = 1;
spl_image->entry_point = (uintptr_t)hdr.loader_load_addr;
/* Load full binary image(right behind header) */
sect_addr += blkcnt;
load_addr = (char *)((size_t)hdr.loader_load_addr);
blkcnt = DIV_ROUND_UP(hdr.loader_load_size, 512);
printf("tee.bin: addr=0x%lx, size=0x%lx\n",
(ulong)load_addr, (ulong)blkcnt * 512);
ret = info->read(info, sect_addr, blkcnt, load_addr);
if (ret != blkcnt)
continue;
break;
}
}
if (i == try_count) {
printf("Can not find usable uboot\n");
return -ENONET;
}
return 0;
}
#endif
static int rkfw_load_uboot(struct spl_load_info *info, u32 image_sector,
uintptr_t *bl33_entry, u32 try_count)
struct spl_image_info *spl_image, u32 try_count)
{
struct tag_second_loader_hdr hdr;
int i, ret, blkcnt = 4; /* header sectors, 2KB */
@ -243,13 +286,17 @@ static int rkfw_load_uboot(struct spl_load_info *info, u32 image_sector,
}
/* Fill entry point */
*bl33_entry = (uintptr_t)hdr.loader_load_addr;
#ifdef CONFIG_SPL_ATF
spl_image->entry_point_bl33 = (uintptr_t)hdr.loader_load_addr;
#endif
#ifdef CONFIG_SPL_OPTEE
spl_image->entry_point_os = (uintptr_t)hdr.loader_load_addr;
#endif
return 0;
}
static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector,
uintptr_t *bl33_entry, u32 try_count)
struct spl_image_info *spl_image, u32 try_count)
{
struct andr_img_hdr *hdr;
int ret, cnt;
@ -311,7 +358,7 @@ static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector,
ret = -EIO;
goto out;
}
#ifdef CONFIG_SPL_KERNEL_BOOT
if (spl_resource_image_check_header(head)) {
printf("Can't find kernel dtb in spl.");
} else {
@ -328,6 +375,7 @@ static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector,
memcpy((char *)CONFIG_SPL_FDT_ADDR, dtb_temp,
entry->f_size);
}
#endif
} else {
/* Load dtb image */
ret = info->read(info, (dtb_sector >> 9) + image_sector,
@ -339,7 +387,13 @@ static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector,
}
}
*bl33_entry = CONFIG_SPL_KERNEL_ADDR;
spl_image->fdt_addr = (void *)CONFIG_SPL_FDT_ADDR;
#ifdef CONFIG_SPL_OPTEE
spl_image->entry_point_os = (uintptr_t)CONFIG_SPL_KERNEL_ADDR;
#endif
#ifdef CONFIG_SPL_ATF
spl_image->entry_point_bl33 = CONFIG_SPL_KERNEL_ADDR;
#endif
ret = 0;
out:
free(hdr);
@ -349,47 +403,41 @@ out:
int spl_load_rkfw_image(struct spl_image_info *spl_image,
struct spl_load_info *info,
u32 trust_sector, u32 uboot_sector,
u32 boot_sector)
u32 trust_sector, u32 uboot_sector)
{
int ret, try_count = RKFW_RETRY_SECTOR_TIMES;
int found_rkfw = 0;
ret = rkfw_load_trust(info, trust_sector,
&spl_image->entry_point,
&spl_image->entry_point_bl32,
ret = rkfw_load_trust(info, trust_sector, spl_image,
&found_rkfw, try_count);
if (ret) {
printf("Load trust image failed! ret=%d\n", ret);
goto out;
}
#ifdef CONFIG_SPL_KERNEL_BOOT
if (spl_image->next_stage == SPL_NEXT_STAGE_UBOOT) {
#endif
ret = rkfw_load_uboot(info, uboot_sector,
&spl_image->entry_point_bl33, try_count);
spl_image, try_count);
if (ret)
printf("Load uboot image failed! ret=%d\n", ret);
else
goto boot;
#ifdef CONFIG_SPL_KERNEL_BOOT
} else if (spl_image->next_stage == SPL_NEXT_STAGE_KERNEL) {
#endif
ret = rkfw_load_kernel(info, boot_sector,
&spl_image->entry_point_bl33, try_count);
ret = rkfw_load_kernel(info, uboot_sector,
spl_image, try_count);
if (ret) {
printf("Load kernel image failed! ret=%d\n", ret);
goto out;
}
#ifdef CONFIG_SPL_KERNEL_BOOT
}
#endif
boot:
#if CONFIG_IS_ENABLED(LOAD_FIT)
spl_image->fdt_addr = 0;
#endif
#ifdef CONFIG_SPL_ATF
spl_image->os = IH_OS_ARM_TRUSTED_FIRMWARE;
#else
spl_image->os = IH_OS_OP_TEE;
#endif
out:
/* If not found rockchip firmware, try others outside */

View File

@ -33,9 +33,10 @@ struct spl_image_info {
uintptr_t entry_point_bl32;
uintptr_t entry_point_bl33;
#endif
#if CONFIG_IS_ENABLED(LOAD_FIT)
void *fdt_addr;
#if CONFIG_IS_ENABLED(OPTEE)
uintptr_t entry_point_os; /* point to uboot or kernel */
#endif
void *fdt_addr;
u32 boot_device;
u32 next_stage;
u32 size;

View File

@ -9,7 +9,11 @@
#include <spl.h>
#define LOADER_HARD_STR "LOADER"
#ifdef CONFIG_SPL_ATF
#define TBOOT_HEAD_TAG 0x58334c42 /* 'B', 'L', '3', 'X' */
#else
#define TBOOT_HEAD_TAG "TOS "
#endif
#define BL30_IMAGE_NAME "bl30.bin" /* SCP Firmware BL3-0 */
#define BL31_IMAGE_NAME "bl31.bin" /* EL3 Runtime Firmware BL31 */
@ -99,6 +103,5 @@ typedef struct tag_second_loader_hdr {
*/
int spl_load_rkfw_image(struct spl_image_info *spl_image,
struct spl_load_info *info,
u32 trust_sector, u32 uboot_sector,
u32 boot_sector);
u32 trust_sector, u32 uboot_sector);
#endif