iBoot/drivers/apple/csi/debug.c

284 lines
7.2 KiB
C

/*
* Copyright (C) 2011-2012 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include <platform.h>
#include <arch.h>
#include <debug.h>
#include <sys.h>
#include <sys/menu.h>
#include <sys/task.h>
#include <drivers/csi.h>
#include <drivers/a7iop/a7iop.h>
#include <platform/timer.h>
#include <platform/soc/hwregbase.h>
#include "csi_private.h"
#include "endpoints/management_ep.h"
#include "endpoints/syslog_ep.h"
#include "endpoints/console_ep.h"
#include "endpoints/crashlog_ep.h"
#if defined(WITH_MENU) && WITH_MENU
static int csi_debug_main(int argc, struct cmd_arg *args);
MENU_COMMAND_DEBUG(csi, csi_debug_main, "Test CSI driver", NULL);
static void usage() {
printf("usage: csi ans|<other iop> <command>\n"
" info\n"
" crashlog|cl nmi|ml|mc\n"
" ping [count]\n"
" syslog|sl [1|0|on|off]\n"
" state|st\n"
" quiesce|qs\n"
" hibernate|hb\n"
" resume|rs\n"
" powerstate|ps [ps]\n"
" console ...\n"
" ... v <verbosity>\n"
" ... c <cmd arg>\n"
" timebase|tb\n"
" stimeout|sto [timeout in us]\n");
}
static inline uint64_t read_akf_timebase(uint64_t regs_base)
{
uint32_t hi1 = rAKF_KIC_GLB_TIME_BASE_HI(regs_base);
uint32_t lo = rAKF_KIC_GLB_TIME_BASE_LO(regs_base);
uint32_t hi2 = rAKF_KIC_GLB_TIME_BASE_HI(regs_base);
return ((((uint64_t)hi2) << 32) | ((hi1!=hi2) ? rAKF_KIC_GLB_TIME_BASE_LO(regs_base) : lo));
}
static int
csi_debug_main (int argc, struct cmd_arg *args)
{
csi_coproc_t which_coproc;
const char *s;
csi_status_t status;
uint64_t akf_base_addr = 0;
if (argc < 3) {
usage();
return -1;
}
//
// Find the targeted coproc
//
s = args[1].str;
if (strnicmp(s, "ans", strlen(s)) == 0) {
which_coproc = CSI_COPROC_ANS;
akf_base_addr = ANS_AKF_BASE_ADDR;
} else if (strnicmp(s, "sep", strlen(s)) == 0) {
which_coproc = CSI_COPROC_SEP;
#if ASEP_AKF_BASE_ADDR
akf_base_addr = ASEP_AKF_BASE_ADDR;
#endif
} else if (strnicmp(s, "isp", strlen(s)) == 0) {
which_coproc = CSI_COPROC_ISP;
#if ISP_AKF_BASE_ADDR
akf_base_addr = ISP_AKF_BASE_ADDR;
#endif
} else if (strnicmp(s, "sio", strlen(s)) == 0) {
which_coproc = CSI_COPROC_SIO;
#if ASIO_AKF_BASE_ADDR
akf_base_addr = ASIO_AKF_BASE_ADDR;
#endif
} else {
printf("csi: %s unknown\n", s);
usage();
return -1;
}
if (akf_base_addr == 0) {
printf("csi: %s not supported\n", IOP_NAME(which_coproc));
usage();
return -1;
}
//
// Parse command
//
status = CSI_STATUS_OK;
s = args[2].str;
// information
if (strnicmp(s, "info", strlen(s)) == 0) {
csi_info (which_coproc);
return 0;
}
// crashlog
if ((strnicmp(s, "crashlog", strlen(s)) == 0) || (strcmp(s, "cl") == 0)) {
csi_crashlog_t cl;
if (argc < 4) {
usage();
return -1;
}
s = args[3].str;
if (strnicmp(s, "nmi", strlen(s)) == 0) {
cl = CSI_CRASHLOG_TYPE_NMI;
} else if (strnicmp(s, "ml", strlen(s)) == 0) {
cl = CSI_CRASHLOG_TYPE_MSG_LOG;
} else if (strnicmp(s, "mc", strlen(s)) == 0) {
cl = CSI_CRASHLOG_TYPE_MSG_CRASH;
} else {
usage();
return -1;
}
printf("csi: force crashlog from %s iop\n", IOP_NAME(which_coproc));
status = bi_ep_crashlog_force_event(which_coproc, cl);
}
// ping
else if (strnicmp(s, "ping", strlen(s)) == 0) {
int ping_count = 1;
if (argc >= 4) {
ping_count = atoi(args[3].str);
if (ping_count<=0) {
ping_count = 1;
}
}
status = bi_ep_mgmt_send_ping(which_coproc, ping_count);
}
// syslog
else if ((strnicmp(s, "syslog", strlen(s)) == 0) || (strcmp(s, "sl") == 0)) {
if (argc < 4) {
usage();
return -1;
}
status = bi_ep_syslog_verbosity(which_coproc, atoi(args[3].str));
}
// state
else if ((strnicmp(s, "state", strlen(s)) == 0) || (strcmp(s, "st") == 0)) {
mgmt_state_t state = bi_ep_mgmt_get_state(which_coproc);
csi_power_state_t ps = bi_ep_mgmt_get_power_state(which_coproc);
printf("csi: %s state - %s - ps=0x%x\n", IOP_NAME(which_coproc), COPROC_STATE(state), ps);
}
// quiesce
else if ((strnicmp(s, "quiesce", strlen(s)) == 0) || (strcmp(s, "qs") == 0)) {
status = quiesce_iop (which_coproc);
}
// start
else if ((strnicmp(s, "hibernate", strlen(s)) == 0) || (strcmp(s, "hb") == 0)) {
status = hibernate_iop (which_coproc);
}
// start
else if ((strnicmp(s, "resume", strlen(s)) == 0) || (strcmp(s, "rs") == 0)) {
// restart the IOP
status = csi_start (which_coproc);
}
// powerstate
else if ((strnicmp(s, "powerstate", strlen(s)) == 0) || (strcmp(s, "ps") == 0)) {
if (argc < 4) {
printf("powerstate requires a powerstate argument\n");
return -1;
}
csi_power_state_t ps = strtol(args[3].str, (char **)NULL, 0);
status = request_iop_power_state (which_coproc, ps);
}
// console
else if (strnicmp(s, "console", strlen(s)) == 0) {
if (argc != 5) {
usage();
return -1;
}
if (args[3].str[0] == 'v') {
status = bi_ep_console_set_verbosity(which_coproc, strtol(args[4].str, (char **)NULL, 0));
} else if (args[3].str[0] == 'c') {
status = bi_ep_console_send_custom_cmd(which_coproc, strtol(args[4].str, (char **)NULL, 0));
} else {
usage();
return -1;
}
}
// timebase
else if ((strnicmp(s, "timebase", strlen(s)) == 0) || (strcmp(s, "tb") == 0)) {
uint64_t tb_host_1, tb_host_2, tb_iop_1, tb_iop_2;
tb_host_1 = timer_get_ticks();
tb_iop_1 = read_akf_timebase(akf_base_addr);
tb_iop_2 = read_akf_timebase(akf_base_addr);
tb_host_2 = timer_get_ticks();
printf("csi: host vs %s timebase\n", IOP_NAME(which_coproc));
printf("\thost:\t 0x%llx\n", tb_host_1);
printf("\tiop:\t 0x%llx (%llu)\n", tb_iop_1, (tb_iop_1-tb_host_1));
printf("\tiop:\t 0x%llx (%llu)\n", tb_iop_2, (tb_iop_2-tb_iop_1));
printf("\thost:\t 0x%llx (%llu)\n", tb_host_2, (tb_host_2-tb_iop_2));
}
// send timeout
else if ((strnicmp(s, "stimeout", strlen(s)) == 0) || (strcmp(s, "sto") == 0)) {
if (argc < 4) {
printf("current send timeout for %s: %uus\n", IOP_NAME(which_coproc), get_send_timeout(which_coproc));
return 0;
}
uint32_t timeout = strtol(args[3].str, (char **)NULL, 0);
if (0 == timeout) {
// the A7 express no timeout as a wait forever.
timeout = A7IOP_WAIT_FOREVER;
printf("csi: %s send timeout disabled (%u)\n", IOP_NAME(which_coproc), timeout);
} else {
printf("csi: setting %s send timeout to %uus\n", IOP_NAME(which_coproc), timeout);
}
status = set_send_timeout (which_coproc, timeout);
}
// unknown command
else {
printf("unknown command %s\n", s);
usage();
return -1;
}
if (status != CSI_STATUS_OK) {
printf("csi %s %s - error reported: %s\n", IOP_NAME(which_coproc), args[2].str, CSI_STATUS_STR(status));
}
return 0;
}
#endif // defined(WITH_MENU) && WITH_MENU