view rvinterf/tmsh/ffs2.c @ 923:10b4bed10192

gsm-fw/L1: fix for the DSP patch corruption bug The L1 code we got from the LoCosto fw contains a feature for DSP CPU load measurement. This feature is a LoCosto-ism, i.e., not applicable to earlier DBB chips (Calypso) with their respective earlier DSP ROMs. Most of the code dealing with that feature is conditionalized as #if (DSP >= 38), but one spot was missed, and the MCU code was writing into an API word dealing with this feature. In TCS211 this DSP API word happens to be used by the DSP code patch, hence that write was corrupting the patched DSP code.
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Mon, 19 Oct 2015 17:13:56 +0000
parents b5b54feb111a
children
line wrap: on
line source

/*
 * In this module we are going to implement TMFFS2 functionality.
 */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "limits.h"
#include "localtypes.h"
#include "etm.h"
#include "ffs.h"
#include "tmffs2.h"

void
cmd_ffs2_close(argc, argv)
	char **argv;
{
	u_char cmdpkt[5];

	cmdpkt[1] = ETM_FFS2;
	cmdpkt[2] = TMFFS_CLOSE;
	cmdpkt[3] = strtoul(argv[1], 0, 0);
	send_etm_cmd(cmdpkt, 3);
}

void
cmd_ffs2_delete(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_REMOVE;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_format(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: argument exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_FORMAT;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	/* magic is 0x2BAD, 16-bit little-endian */
	*dp++ = 0xAD;
	*dp++ = 0x2B;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_mkdir(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_MKDIR;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_open(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_OPEN;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	*dp++ = strtoul(argv[2], 0, 16);
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_opendir(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_OPENDIR;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_preformat()
{
	u_char cmdpkt[6];

	cmdpkt[1] = ETM_FFS2;
	cmdpkt[2] = TMFFS_PREFORMAT;
	/* magic is 0xDEAD, 16-bit little-endian */
	cmdpkt[3] = 0xAD;
	cmdpkt[4] = 0xDE;
	send_etm_cmd(cmdpkt, 4);
}

void
cmd_ffs2_query(argc, argv)
	char **argv;
{
	u_char cmdpkt[5];

	cmdpkt[1] = ETM_FFS2;
	cmdpkt[2] = TMFFS_QUERY;
	cmdpkt[3] = strtoul(argv[1], 0, 0);
	send_etm_cmd(cmdpkt, 3);
}

void
cmd_ffs2_readfd(argc, argv)
	char **argv;
{
	u_char cmdpkt[6];

	cmdpkt[1] = ETM_FFS2;
	cmdpkt[2] = TMFFS_READ;
	cmdpkt[3] = strtoul(argv[1], 0, 0);
	cmdpkt[4] = strtoul(argv[2], 0, 0);
	send_etm_cmd(cmdpkt, 4);
}

void
cmd_ffs2_readfile(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_FILE_READ;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	*dp++ = strtoul(argv[2], 0, 0);
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_stat(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_STAT;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_version()
{
	u_char cmdpkt[4];

	cmdpkt[1] = ETM_FFS2;
	cmdpkt[2] = TMFFS_VERSION;
	send_etm_cmd(cmdpkt, 2);
}

void
cmd_ffs2_wrfile(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen, slen2;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	slen2 = strlen(argv[2]);
	if (slen2 > 64) {
		printf("error: write test data argument is too long\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_FILE_WRITE;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	*dp++ = slen2;		/* no NUL-termination on test data */
	strcpy(dp, argv[2]);
	dp += slen2;
	*dp++ = FFS_O_CREATE | FFS_O_TRUNC;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_writefd(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen2;

	slen2 = strlen(argv[2]);
	if (slen2 > 64) {
		printf("error: write test data argument is too long\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_WRITE;
	*dp++ = strtoul(argv[1], 0, 0);
	*dp++ = slen2;		/* no NUL-termination on test data */
	strcpy(dp, argv[2]);
	dp += slen2;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

void
cmd_ffs2_xlstat(argc, argv)
	char **argv;
{
	u_char cmdpkt[MAX_PKT_TO_TARGET], *dp;
	int slen;

	slen = strlen(argv[1]);
	if (slen >= TMFFS_STRING_SIZE) {
		printf("error: pathname arg exceeds string length limit\n");
		return;
	}
	dp = cmdpkt + 1;
	*dp++ = ETM_FFS2;
	*dp++ = TMFFS_XLSTAT;
	*dp++ = slen + 1;
	strcpy(dp, argv[1]);
	dp += slen + 1;
	send_etm_cmd(cmdpkt, dp - cmdpkt - 1);
}

static struct cmdtab {
	char *cmd;
	int minargs;
	int maxargs;
	void (*func)();
} ffs2_cmds[] = {
	{"close", 1, 1, cmd_ffs2_close},
	{"delete", 1, 1, cmd_ffs2_delete},
	{"format", 1, 1, cmd_ffs2_format},
	{"mkdir", 1, 1, cmd_ffs2_mkdir},
	{"open", 2, 2, cmd_ffs2_open},
	{"opendir", 1, 1, cmd_ffs2_opendir},
	{"preformat", 0, 0, cmd_ffs2_preformat},
	{"query", 1, 1, cmd_ffs2_query},
	{"readfd", 2, 2, cmd_ffs2_readfd},
	{"readfile", 2, 2, cmd_ffs2_readfile},
	{"stat", 1, 1, cmd_ffs2_stat},
	{"version", 0, 0, cmd_ffs2_version},
	{"wrfile", 2, 2, cmd_ffs2_wrfile},
	{"writefd", 2, 2, cmd_ffs2_writefd},
	{"xlstat", 1, 1, cmd_ffs2_xlstat},
	{0, 0, 0, 0}
};

void
cmd_ffs2(argc, argv)
	char **argv;
{
	struct cmdtab *tp;
	int extargs;

	for (tp = ffs2_cmds; tp->cmd; tp++)
		if (!strcmp(tp->cmd, argv[1]))
			break;
	if (!tp->func) {
		printf("error: no such ffs2 command\n");
		return;
	}
	extargs = argc - 2;
	if (extargs > tp->maxargs) {
		printf("error: too many arguments\n");
		return;
	}
	if (extargs < tp->minargs) {
		printf("error: too few arguments\n");
		return;
	}
	tp->func(argc - 1, argv + 1);
}