mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-01-28 01:47:24 +01:00
ipq40xx : Enable crashdump support
Change-Id: Ibd3b04dcc7870be1922409f81f3011b7edac35bc Signed-off-by: Ajay Kishore <akisho@codeaurora.org>
This commit is contained in:
parent
66f90c81e5
commit
3491df2edd
7 changed files with 135 additions and 43 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue