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:
Gokul Sriram Palanisamy 2017-10-10 22:48:23 +05:30 committed by Gerrit - the friendly Code Review server
parent e216c7f3ab
commit f9ad5ac9d7
7 changed files with 149 additions and 87 deletions

View file

@ -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) &param;
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);
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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
*/

View file

@ -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