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

View File

@ -7,11 +7,11 @@
#include <android_image.h> #include <android_image.h>
#include <errno.h> #include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <spl.h>
#include <spl_rkfw.h> #include <spl_rkfw.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/arch/spl_resource_img.h> #include <asm/arch/spl_resource_img.h>
#ifdef CONFIG_SPL_ATF
static const __aligned(16) struct s_fip_name_id fip_name_id[] = { static const __aligned(16) struct s_fip_name_id fip_name_id[] = {
{ BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30 }, /* optional */ { BL30_IMAGE_NAME, UUID_SCP_FIRMWARE_BL30 }, /* optional */
{ BL31_IMAGE_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31 }, /* mandatory */ { 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, 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) int *found_rkfw, u32 try_count)
{ {
struct tag_tboot_header_2k hdr; 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 */ /* bl31 is mandatory */
ret = load_image(info, &hdr, sect_addr, ret = load_image(info, &hdr, sect_addr,
BL31_IMAGE_NAME, bl31_entry); BL31_IMAGE_NAME, &spl_image->entry_point);
if (ret) if (ret)
continue; continue;
/* bl32 is optional */ /* bl32 is optional */
ret = load_image(info, &hdr, sect_addr, ret = load_image(info, &hdr, sect_addr,
BL32_IMAGE_NAME, bl32_entry); BL32_IMAGE_NAME, &spl_image->entry_point_bl32);
if (ret) { if (ret) {
if (ret == -ENONET) { if (ret == -ENONET) {
*bl32_entry = -1; /* Not exist */ spl_image->entry_point_bl32 = -1; /* Not exist */
ret = 0; ret = 0;
} else { } else {
continue; continue;
@ -205,9 +205,52 @@ static int rkfw_load_trust(struct spl_load_info *info, u32 image_sector,
return ret; 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, 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; struct tag_second_loader_hdr hdr;
int i, ret, blkcnt = 4; /* header sectors, 2KB */ 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 */ /* 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; return 0;
} }
static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector, 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; struct andr_img_hdr *hdr;
int ret, cnt; int ret, cnt;
@ -311,7 +358,7 @@ static int rkfw_load_kernel(struct spl_load_info *info, u32 image_sector,
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
#ifdef CONFIG_SPL_KERNEL_BOOT
if (spl_resource_image_check_header(head)) { if (spl_resource_image_check_header(head)) {
printf("Can't find kernel dtb in spl."); printf("Can't find kernel dtb in spl.");
} else { } 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, memcpy((char *)CONFIG_SPL_FDT_ADDR, dtb_temp,
entry->f_size); entry->f_size);
} }
#endif
} else { } else {
/* Load dtb image */ /* Load dtb image */
ret = info->read(info, (dtb_sector >> 9) + image_sector, 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; ret = 0;
out: out:
free(hdr); free(hdr);
@ -349,47 +403,41 @@ out:
int spl_load_rkfw_image(struct spl_image_info *spl_image, int spl_load_rkfw_image(struct spl_image_info *spl_image,
struct spl_load_info *info, struct spl_load_info *info,
u32 trust_sector, u32 uboot_sector, u32 trust_sector, u32 uboot_sector)
u32 boot_sector)
{ {
int ret, try_count = RKFW_RETRY_SECTOR_TIMES; int ret, try_count = RKFW_RETRY_SECTOR_TIMES;
int found_rkfw = 0; int found_rkfw = 0;
ret = rkfw_load_trust(info, trust_sector, ret = rkfw_load_trust(info, trust_sector, spl_image,
&spl_image->entry_point,
&spl_image->entry_point_bl32,
&found_rkfw, try_count); &found_rkfw, try_count);
if (ret) { if (ret) {
printf("Load trust image failed! ret=%d\n", ret); printf("Load trust image failed! ret=%d\n", ret);
goto out; goto out;
} }
#ifdef CONFIG_SPL_KERNEL_BOOT
if (spl_image->next_stage == SPL_NEXT_STAGE_UBOOT) {
#endif
ret = rkfw_load_uboot(info, uboot_sector, ret = rkfw_load_uboot(info, uboot_sector,
&spl_image->entry_point_bl33, try_count); spl_image, try_count);
if (ret) if (ret)
printf("Load uboot image failed! ret=%d\n", ret); printf("Load uboot image failed! ret=%d\n", ret);
else else
goto boot; goto boot;
#ifdef CONFIG_SPL_KERNEL_BOOT
} else if (spl_image->next_stage == SPL_NEXT_STAGE_KERNEL) { ret = rkfw_load_kernel(info, uboot_sector,
#endif spl_image, try_count);
ret = rkfw_load_kernel(info, boot_sector,
&spl_image->entry_point_bl33, try_count);
if (ret) { if (ret) {
printf("Load kernel image failed! ret=%d\n", ret); printf("Load kernel image failed! ret=%d\n", ret);
goto out; goto out;
} }
#ifdef CONFIG_SPL_KERNEL_BOOT
}
#endif
boot: boot:
#if CONFIG_IS_ENABLED(LOAD_FIT) #if CONFIG_IS_ENABLED(LOAD_FIT)
spl_image->fdt_addr = 0; spl_image->fdt_addr = 0;
#endif #endif
#ifdef CONFIG_SPL_ATF
spl_image->os = IH_OS_ARM_TRUSTED_FIRMWARE; spl_image->os = IH_OS_ARM_TRUSTED_FIRMWARE;
#else
spl_image->os = IH_OS_OP_TEE;
#endif
out: out:
/* If not found rockchip firmware, try others outside */ /* 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_bl32;
uintptr_t entry_point_bl33; uintptr_t entry_point_bl33;
#endif #endif
#if CONFIG_IS_ENABLED(LOAD_FIT) #if CONFIG_IS_ENABLED(OPTEE)
void *fdt_addr; uintptr_t entry_point_os; /* point to uboot or kernel */
#endif #endif
void *fdt_addr;
u32 boot_device; u32 boot_device;
u32 next_stage; u32 next_stage;
u32 size; u32 size;

View File

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