mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-14 21:10:27 +01:00
ipq807x: Modified scm calls to support both 32 bit and 64 bit
Change-Id: Iee99423239f7de49a9fc7a4c2e6244df385f5f09 Signed-off-by: Gopinath Sekar <gsekar@qti.qualcomm.com> Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
This commit is contained in:
parent
e216c7f3ab
commit
f9ad5ac9d7
7 changed files with 149 additions and 87 deletions
|
|
@ -225,8 +225,6 @@ int scm_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
|
||||
int __qca_scm_call_armv8_32(u32 x0, u32 x1, u32 x2, u32 x3, u32 x4, u32 x5,
|
||||
u32 *ret1, u32 *ret2, u32 *ret3)
|
||||
{
|
||||
|
|
@ -298,6 +296,42 @@ static int scm_call_64(u32 svc_id, u32 cmd_id, struct qca_scm_desc *desc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static enum scm_interface_version {
|
||||
SCM_UNKNOWN,
|
||||
SCM_LEGACY,
|
||||
SCM_ARMV8_32,
|
||||
} scm_version = SCM_UNKNOWN;
|
||||
|
||||
/* This function is used to find whether TZ is in AARCH64 mode.
|
||||
* If this function returns 1, then its in AARCH64 mode and
|
||||
* calling conventions for AARCH64 TZ is different, we need to
|
||||
* use them.
|
||||
*/
|
||||
bool is_scm_armv8(void)
|
||||
{
|
||||
int ret;
|
||||
u32 ret1, x0;
|
||||
|
||||
if (likely(scm_version != SCM_UNKNOWN))
|
||||
return (scm_version == SCM_ARMV8_32);
|
||||
|
||||
/* Try SMC32 call */
|
||||
ret1 = 0;
|
||||
x0 = QCA_SCM_SIP_FNID(SCM_SVC_INFO, QCA_IS_CALL_AVAIL_CMD) |
|
||||
QCA_SMC_ATOMIC_MASK;
|
||||
|
||||
ret = __qca_scm_call_armv8_32(x0, QCA_SCM_ARGS(1), x0, 0, 0, 0,
|
||||
&ret1, NULL, NULL);
|
||||
if (ret || !ret1)
|
||||
scm_version = SCM_LEGACY;
|
||||
else
|
||||
scm_version = SCM_ARMV8_32;
|
||||
|
||||
pr_debug("scm_call: scm version is %x\n", scm_version);
|
||||
|
||||
return (scm_version == SCM_ARMV8_32);
|
||||
}
|
||||
|
||||
void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
|
||||
void *fdt_addr)
|
||||
{
|
||||
|
|
@ -312,6 +346,11 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
|
|||
desc.args[0] = (u32) ¶m;
|
||||
desc.args[1] = sizeof(param);
|
||||
|
||||
if (!is_scm_armv8()) {
|
||||
printf("Can't boot kernel: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
printf("Jumping to AARCH64 kernel via monitor\n");
|
||||
ret = scm_call_64(SCM_ARCH64_SWITCH_ID, SCM_EL1SWITCH_CMD_ID,
|
||||
&desc);
|
||||
|
|
@ -320,22 +359,24 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
|
|||
hang();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
struct qca_scm_desc desc = {0};
|
||||
if (is_scm_armv8())
|
||||
{
|
||||
struct qca_scm_desc desc = {0};
|
||||
|
||||
desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP);
|
||||
desc.args[0] = (u32)buf;
|
||||
desc.args[1] = len;
|
||||
ret = scm_call_64(svc_id, cmd_id, &desc);
|
||||
#else
|
||||
ret = scm_call(svc_id, cmd_id, NULL, 0, buf, len);
|
||||
#endif
|
||||
desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP);
|
||||
desc.args[0] = (u32)buf;
|
||||
desc.args[1] = len;
|
||||
ret = scm_call_64(svc_id, cmd_id, &desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = scm_call(svc_id, cmd_id, NULL, 0, buf, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -343,19 +384,22 @@ int qca_scm_fuseipq(u32 svc_id, u32 cmd_id, void *buf, size_t len)
|
|||
{
|
||||
int ret = 0;
|
||||
uint32_t *status;
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
struct qca_scm_desc desc = {0};
|
||||
if (is_scm_armv8())
|
||||
{
|
||||
struct qca_scm_desc desc = {0};
|
||||
|
||||
desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP);
|
||||
desc.args[0] = *((unsigned int *)buf);
|
||||
desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP);
|
||||
desc.args[0] = *((unsigned int *)buf);
|
||||
|
||||
ret = scm_call_64(svc_id, cmd_id, &desc);
|
||||
ret = scm_call_64(svc_id, cmd_id, &desc);
|
||||
|
||||
status = (uint32_t *)(*(((uint32_t *)buf) + 1));
|
||||
*status = desc.ret[0];
|
||||
#else
|
||||
ret = scm_call(svc_id, cmd_id, buf, len, NULL, 0);
|
||||
#endif
|
||||
status = (uint32_t *)(*(((uint32_t *)buf) + 1));
|
||||
*status = desc.ret[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = scm_call(svc_id, cmd_id, buf, len, NULL, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -364,23 +408,25 @@ int qca_scm_auth_kernel(void *cmd_buf,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
struct qca_scm_desc desc = {0};
|
||||
desc.arginfo = QCA_SCM_ARGS(1, SCM_VAL);
|
||||
/* args[0] has the kernel load address */
|
||||
desc.args[0] = * ((unsigned int *)cmd_buf);
|
||||
/* args[1] has the kernel image size */
|
||||
desc.args[1] = * (((unsigned int *)cmd_buf) + 1);
|
||||
ret = scm_call_64(SCM_SVC_BOOT, KERNEL_AUTH_CMD, &desc);
|
||||
#else
|
||||
ret = scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD, cmd_buf, cmd_len,
|
||||
NULL, 0);
|
||||
#endif
|
||||
if (is_scm_armv8())
|
||||
{
|
||||
struct qca_scm_desc desc = {0};
|
||||
desc.arginfo = QCA_SCM_ARGS(1, SCM_VAL);
|
||||
/* args[0] has the kernel load address */
|
||||
desc.args[0] = * ((unsigned int *)cmd_buf);
|
||||
/* args[1] has the kernel image size */
|
||||
desc.args[1] = * (((unsigned int *)cmd_buf) + 1);
|
||||
ret = scm_call_64(SCM_SVC_BOOT, KERNEL_AUTH_CMD, &desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD, cmd_buf, cmd_len,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
int qca_scm_call_read(u32 svc_id, u32 cmd_id, u32 *addr, u32 *rsp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -406,7 +452,7 @@ int qca_scm_call_write(u32 svc_id, u32 cmd_id, u32 *addr, u32 val)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int qca_scm_sdi_v8(void)
|
||||
static int qca_scm_sdi_v8(void)
|
||||
{
|
||||
struct qca_scm_desc desc = {0};
|
||||
int ret;
|
||||
|
|
@ -422,4 +468,33 @@ int qca_scm_sdi_v8(void)
|
|||
|
||||
return le32_to_cpu(desc.ret[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int qca_scm_sdi(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int clear_info[] = {
|
||||
1 /* Disable wdog debug */, 0 /* SDI enable*/, };
|
||||
|
||||
if (is_scm_armv8())
|
||||
return qca_scm_sdi_v8();
|
||||
|
||||
ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_CONFIG_HW_FOR_RAM_DUMP_ID, &clear_info,
|
||||
sizeof(clear_info), NULL, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qca_scm_dload(unsigned int magic_cookie)
|
||||
{
|
||||
int ret;
|
||||
if (is_scm_armv8())
|
||||
{
|
||||
ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE,
|
||||
0x193D100, magic_cookie);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_FORCE_DLOAD_ID, &magic_cookie,
|
||||
sizeof(magic_cookie), NULL, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,10 @@ extern int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len);
|
|||
|
||||
int qca_scm_call_write(u32, u32, u32 *, u32);
|
||||
int qca_scm_call_read(u32, u32, u32 *, u32 *);
|
||||
int qca_scm_sdi_v8(void);
|
||||
int qca_scm_sdi(void);
|
||||
int qca_scm_dload(u32);
|
||||
int qca_scm_fuseipq(u32, u32, void *, size_t);
|
||||
bool is_scm_armv8(void);
|
||||
|
||||
#define MAX_QCA_SCM_RETS 3
|
||||
#define MAX_QCA_SCM_ARGS 10
|
||||
|
|
@ -141,11 +143,11 @@ struct qca_scm_desc {
|
|||
#define QCA_SCM_ARGS(...) QCA_SCM_ARGS_IMPL(__VA_ARGS__, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
|
||||
#define QCA_SCM_SIP_FNID(s, c) (((((s) & 0xFF) << 8) | \
|
||||
((c) & 0xFF)) | 0x02000000)
|
||||
|
||||
#define QCA_SMC_ATOMIC_MASK 0x80000000
|
||||
|
||||
#define QCA_MAX_ARG_LEN 5
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -162,6 +164,7 @@ typedef struct {
|
|||
} kernel_params;
|
||||
|
||||
#define SCM_ARCH64_SWITCH_ID 0x1
|
||||
#define QCA_IS_CALL_AVAIL_CMD 0x1
|
||||
#define SCM_EL1SWITCH_CMD_ID 0xf
|
||||
|
||||
#define SCM_NULL_OP 0
|
||||
|
|
@ -172,4 +175,3 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
|
|||
void *fdt_addr);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@
|
|||
#ifdef CONFIG_ARMV7_NONSEC
|
||||
#include <asm/armv7.h>
|
||||
#endif
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
#include <asm/arch-qca-common/scm.h>
|
||||
#endif
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static struct tag *params;
|
||||
|
|
@ -260,7 +258,6 @@ bool armv7_boot_nonsec(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
struct aarch64_hdr {
|
||||
u32 code0; /* Executable code */
|
||||
u32 code1; /* Executable code */
|
||||
|
|
@ -275,7 +272,6 @@ struct aarch64_hdr {
|
|||
};
|
||||
#define AARCH64_LINUX_MAGIC 0x644d5241
|
||||
#define TEST_AARCH64(ptr) (ptr->magic == AARCH64_LINUX_MAGIC) ? true : false
|
||||
#endif
|
||||
|
||||
/* Subcommand: GO */
|
||||
static void boot_jump_linux(bootm_headers_t *images, int flag)
|
||||
|
|
@ -326,11 +322,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
|||
else
|
||||
r2 = gd->bd->bi_boot_params;
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
if (TEST_AARCH64(((struct aarch64_hdr *)kernel_entry))) {
|
||||
jump_kernel64(kernel_entry, images->ft_addr);
|
||||
} else {
|
||||
#endif
|
||||
if (!fake) {
|
||||
#ifdef CONFIG_ARMV7_NONSEC
|
||||
if (armv7_boot_nonsec()) {
|
||||
|
|
@ -341,10 +335,8 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
|
|||
#endif
|
||||
kernel_entry(0, machid, r2);
|
||||
}
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Main Entry point for arm bootm implementation
|
||||
|
|
|
|||
|
|
@ -258,39 +258,42 @@ void qca_appsbl_dload(void) {
|
|||
unsigned long * dmagic1 = (unsigned long *) 0x2A03F000;
|
||||
unsigned long * dmagic2 = (unsigned long *) 0x2A03F004;
|
||||
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
ret = qca_scm_call_read(SCM_SVC_IO, SCM_IO_READ, addr, &rsp);
|
||||
if (rsp == DLOAD_MAGIC_COOKIE) {
|
||||
val = 0x0;
|
||||
|
||||
ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, addr, val);
|
||||
if (ret)
|
||||
printf ("Error in reseting the Magic cookie\n");
|
||||
dump_func();
|
||||
}
|
||||
#else
|
||||
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val));
|
||||
if (ret) {
|
||||
if (*dmagic1 == 0xE47B337D && *dmagic2 == 0x0501CAB0) {
|
||||
/* clear the magic and run the dump command */
|
||||
*dmagic1 = 0;
|
||||
*dmagic2 = 0;
|
||||
dump_func();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* check if we are in download mode */
|
||||
if (val == DLOAD_MAGIC_COOKIE) {
|
||||
/* clear the magic and run the dump command */
|
||||
if (is_scm_armv8())
|
||||
{
|
||||
ret = qca_scm_call_read(SCM_SVC_IO, SCM_IO_READ, addr, &rsp);
|
||||
if (rsp == DLOAD_MAGIC_COOKIE) {
|
||||
val = 0x0;
|
||||
|
||||
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val));
|
||||
ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, addr, val);
|
||||
if (ret)
|
||||
printf ("Error in reseting the Magic cookie\n");
|
||||
dump_func();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val));
|
||||
if (ret) {
|
||||
if (*dmagic1 == 0xE47B337D && *dmagic2 == 0x0501CAB0) {
|
||||
/* clear the magic and run the dump command */
|
||||
*dmagic1 = 0;
|
||||
*dmagic2 = 0;
|
||||
dump_func();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* check if we are in download mode */
|
||||
if (val == DLOAD_MAGIC_COOKIE) {
|
||||
/* clear the magic and run the dump command */
|
||||
val = 0x0;
|
||||
|
||||
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val));
|
||||
if (ret)
|
||||
printf ("Error in reseting the Magic cookie\n");
|
||||
dump_func();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -185,9 +185,8 @@ unsigned long timer_read_counter(void)
|
|||
void reset_crashdump(void)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
qca_scm_sdi_v8();
|
||||
ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE,
|
||||
0x193D100, CLEAR_MAGIC);
|
||||
qca_scm_sdi();
|
||||
ret = qca_scm_dload(CLEAR_MAGIC);
|
||||
if (ret)
|
||||
printf ("Error in reseting the Magic cookie\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,6 @@ extern loff_t board_env_size;
|
|||
#define QCA_SPI_NOR_DEVICE "spi0.0"
|
||||
#define CONFIG_QUP_SPI_USE_DMA 1
|
||||
|
||||
#define CONFIG_SCM_TZ64 1
|
||||
/*
|
||||
* U-Boot Env Configs
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -713,12 +713,8 @@ static inline int image_check_target_arch(const image_header_t *hdr)
|
|||
#ifndef IH_ARCH_DEFAULT
|
||||
# error "please define IH_ARCH_DEFAULT in your arch asm/u-boot.h"
|
||||
#endif
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
return image_check_arch(hdr, IH_ARCH_DEFAULT) || image_check_arch(hdr,
|
||||
IH_ARCH_ARM64);
|
||||
#else
|
||||
return image_check_arch(hdr, IH_ARCH_DEFAULT);
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
|
|
@ -1105,12 +1101,8 @@ struct image_region *fit_region_make_list(const void *fit,
|
|||
static inline int fit_image_check_target_arch(const void *fdt, int node)
|
||||
{
|
||||
#ifndef USE_HOSTCC
|
||||
#ifdef CONFIG_SCM_TZ64
|
||||
return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT) ||
|
||||
fit_image_check_arch(fdt, node, IH_ARCH_ARM64);
|
||||
#else
|
||||
return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue