ipq40xx : Enable crashdump support

Change-Id: Ibd3b04dcc7870be1922409f81f3011b7edac35bc
Signed-off-by: Ajay Kishore <akisho@codeaurora.org>
This commit is contained in:
Ajay Kishore 2016-09-15 15:29:02 +05:30 committed by Gerrit - the friendly Code Review server
parent 66f90c81e5
commit 3491df2edd
7 changed files with 135 additions and 43 deletions

View file

@ -266,7 +266,7 @@ int __qca_scm_call_armv8_32(u32 x0, u32 x1, u32 x2, u32 x3, u32 x4, u32 x5,
/**
* qca_scm_call() - Invoke a syscall in the secure world
* scm_call_64() - Invoke a syscall in the secure world
* <at> svc_id: service identifier
* <at> cmd_id: command identifier
* <at> fn_id: The function ID for this syscall
@ -275,7 +275,7 @@ int __qca_scm_call_armv8_32(u32 x0, u32 x1, u32 x2, u32 x3, u32 x4, u32 x5,
* Sends a command to the SCM and waits for the command to finish processing.
*
*/
static int qca_scm_call(u32 svc_id, u32 cmd_id, struct qca_scm_desc *desc)
static int scm_call_64(u32 svc_id, u32 cmd_id, struct qca_scm_desc *desc)
{
int arglen = desc->arginfo & 0xf;
int ret;
@ -313,7 +313,7 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
desc.args[1] = sizeof(param);
printf("Jumping to AARCH64 kernel via monitor\n");
ret = qca_scm_call(SCM_ARCH64_SWITCH_ID, SCM_EL1SWITCH_CMD_ID,
ret = scm_call_64(SCM_ARCH64_SWITCH_ID, SCM_EL1SWITCH_CMD_ID,
&desc);
printf("Can't boot kernel: %d\n", ret);
@ -321,3 +321,19 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
}
#endif
int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len)
{
struct qca_scm_desc desc = {0};
int ret = 0;
desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP);
desc.args[0] = buf;
desc.args[1] = len;
#ifdef CONFIG_SCM_TZ64
ret = scm_call_64(svc_id, cmd_id, &desc);
#else
ret = scm_call(svc_id, cmd_id, NULL, 0, buf, len);
#endif
return ret;
}

View file

@ -39,6 +39,15 @@ typedef struct {
int qca_mmc_init(bd_t *, qca_mmc *);
void board_mmc_deinit(void);
struct dumpinfo_t{
char name[16]; /* use only file name in 8.3 format */
uint32_t start;
uint32_t size;
int is_aligned_access; /* non zero represent 4 byte access */
};
extern struct dumpinfo_t dumpinfo[];
extern int dump_entries;
#define MSM_SDC1_BASE 0x7824000
#define MMC_IDENTIFY_MODE 0
#define MMC_DATA_TRANSFER_MODE 1

View file

@ -90,11 +90,31 @@ struct scm_response {
int scm_init(void);
extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
void *resp_buf, size_t resp_len);
extern int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len);
#ifdef CONFIG_SCM_TZ64
#define MAX_QCA_SCM_RETS 3
#define MAX_QCA_SCM_ARGS 10
#define SCM_READ_OP 1
#define QCA_SCM_SIP_FNID(s, c) (((((s) & 0xFF) << 8) | \
((c) & 0xFF)) | 0x02000000)
/**
* struct qca_scm_desc
* <at> arginfo: Metadata describi`ng the arguments in args[]
* <at> args: The array of arguments for the secure syscall
* <at> ret: The values returned by the secure syscall
* <at> extra_arg_buf: The buffer containing extra arguments
(that don't fit in available registers)
* <at> x5: The 4rd argument to the secure syscall or physical address of
extra_arg_buf
*/
struct qca_scm_desc {
u32 arginfo;
u32 args[MAX_QCA_SCM_ARGS];
u32 ret[MAX_QCA_SCM_RETS];
/* private */
void *extra_arg_buf;
u64 x5;
};
#define QCA_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
(((a) & 0xff) << 4) | \
@ -112,6 +132,11 @@ extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
#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_MAX_ARG_LEN 5
typedef struct {
@ -131,33 +156,9 @@ typedef struct {
#define SCM_EL1SWITCH_CMD_ID 0xf
#define SCM_NULL_OP 0
#define SCM_READ_OP 1
#define SCM_RW_OP 2
#define SCM_BUF_VAL 3
#define MAX_QCA_SCM_RETS 3
#define MAX_QCA_SCM_ARGS 10
/**
* struct qca_scm_desc
* <at> arginfo: Metadata describi`ng the arguments in args[]
* <at> args: The array of arguments for the secure syscall
* <at> ret: The values returned by the secure syscall
* <at> extra_arg_buf: The buffer containing extra arguments
(that don't fit in available registers)
* <at> x5: The 4rd argument to the secure syscall or physical address of
extra_arg_buf
*/
struct qca_scm_desc {
u32 arginfo;
u32 args[MAX_QCA_SCM_ARGS];
u32 ret[MAX_QCA_SCM_RETS];
/* private */
void *extra_arg_buf;
u64 x5;
};
void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry,
void *fdt_addr);

View file

@ -25,7 +25,7 @@
#include <fdtdec.h>
#include "fdt_info.h"
#define DLOAD_MAGIC_COOKIE0x10
#define DLOAD_MAGIC_COOKIE 0x10
#define XMK_STR(x)#x
#define MK_STR(x)XMK_STR(x)
@ -61,6 +61,55 @@ typedef struct {
kernel_img_info_t kernel_img_info;
static int do_dumpqca_data(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
{
char runcmd[128];
char *serverip = NULL;
/* dump to root of TFTP server if none specified */
char *dumpdir;
uint32_t memaddr;
int indx;
if (argc == 2) {
serverip = argv[1];
printf("Using given serverip %s\n", serverip);
setenv("serverip", serverip);
} else {
serverip = getenv("serverip");
if (serverip != NULL) {
printf("Using serverip from env %s\n", serverip);
} else {
printf("\nServer ip not found, run dhcp or configure\n");
return CMD_RET_FAILURE;
}
}
if ((dumpdir = getenv("dumpdir")) != NULL) {
printf("Using directory %s in TFTP server\n", dumpdir);
} else {
dumpdir = "";
printf("Env 'dumpdir' not set. Using / dir in TFTP server\n");
}
for (indx = 0; indx < dump_entries; indx++) {
printf("\nProcessing %s:", dumpinfo[indx].name);
memaddr = dumpinfo[indx].start;
snprintf(runcmd, sizeof(runcmd), "tftpput 0x%x 0x%x %s/%s",
memaddr, dumpinfo[indx].size,
dumpdir, dumpinfo[indx].name);
if (run_command(runcmd, 0) != CMD_RET_SUCCESS)
return CMD_RET_FAILURE;
udelay(10000); /* give some delay for server */
}
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(dumpipq_data, 2, 0, do_dumpqca_data,
"dumpipq_data crashdump collection from memory",
"dumpipq_data [serverip] - Crashdump collection from memory vi tftp\n");
/**
* Inovke the dump routine and in case of failure, do not stop unless the user
* requested to stop
@ -202,14 +251,12 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
#ifdef CONFIG_QCA_APPSBL_DLOAD
ret = scm_call(SCM_SVC_BOOT, SCM_SVC_RD, NULL,
0, (void *)&val, sizeof(val));
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val));
/* check if we are in download mode */
if (val == DLOAD_MAGIC_COOKIE) {
/* clear the magic and run the dump command */
val = 0x0;
ret = scm_call(SCM_SVC_BOOT, SCM_SVC_WR,
(void *)&val, sizeof(val), NULL, 0);
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val));
if (ret)
printf ("Error in reseting the Magic cookie\n");
@ -338,8 +385,8 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a
request += sizeof(mbn_header_t);
ret = scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD, &kernel_img_info,
sizeof(kernel_img_info_t), NULL, 0);
ret = qca_scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD,
(void *)&kernel_img_info, sizeof(kernel_img_info_t));
if (ret) {
printf("Kernel image authentication failed \n");
@ -388,14 +435,12 @@ static int do_boot_unsignedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const
if (argc == 2 && strncmp(argv[1], "debug", 5) == 0)
debug = 1;
#ifdef CONFIG_QCA_APPSBL_DLOAD
ret = scm_call(SCM_SVC_BOOT, SCM_SVC_RD, NULL,
0, (void *)&val, sizeof(val));
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val));
/* check if we are in download mode */
if (val == DLOAD_MAGIC_COOKIE) {
/* clear the magic and run the dump command */
val = 0x0;
ret = scm_call(SCM_SVC_BOOT, SCM_SVC_WR,
(void *)&val, sizeof(val), NULL, 0);
ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val));
if (ret)
printf ("Error in reseting the Magic cookie\n");
@ -568,8 +613,7 @@ static int do_bootipq(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
return CMD_RET_FAILURE;
}
ret = scm_call(SCM_SVC_FUSE, QFPROM_IS_AUTHENTICATE_CMD,
NULL, 0, &buf, sizeof(char));
ret = qca_scm_call(SCM_SVC_FUSE, QFPROM_IS_AUTHENTICATE_CMD, &buf, sizeof(char));
if (ret == 0 && buf == 1) {
return do_boot_signedimg(cmdtp, flag, argc, argv);

View file

@ -52,6 +52,12 @@ const add_node_t add_node[] = {
}
};
struct dumpinfo_t dumpinfo[] = {
{ "EBICS0.BIN", 0x80000000, 0x10000000, 0 },
};
int dump_entries = ARRAY_SIZE(dumpinfo);
extern loff_t board_env_offset;
extern loff_t board_env_range;
extern loff_t board_env_size;

View file

@ -238,6 +238,21 @@ typedef struct {
#define CONFIG_LIB_UUID
/*
* CRASH DUMP ENABLE
*/
#define CONFIG_QCA_APPSBL_DLOAD 1
#ifdef CONFIG_QCA_APPSBL_DLOAD
#define CONFIG_CMD_TFTPPUT
/* We will be uploading very big files */
#undef CONFIG_NET_RETRY_COUNT
#define CONFIG_NET_RETRY_COUNT 500
#endif
#define CONFIG_QCA_MMC 1
#ifdef CONFIG_QCA_MMC

View file

@ -498,6 +498,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
int block = ntohs(*s);
int ack_ok = (tftp_cur_block == block);
tftp_prev_block = tftp_cur_block;
tftp_cur_block = (unsigned short)(block + 1);
update_block_number();
if (ack_ok)