changeset 790:0bbe0213812d

fc-simint put together, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 19 Mar 2021 04:40:05 +0000
parents 464a531122ab
children a31ae776de6e
files .hgignore loadtools/Makefile loadtools/simatr.c loadtools/simmain.c loadtools/simup.c
diffstat 5 files changed, 336 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Mar 14 23:55:32 2021 +0000
+++ b/.hgignore	Fri Mar 19 04:40:05 2021 +0000
@@ -28,6 +28,7 @@
 ^loadtools/fc-dspromdump$
 ^loadtools/fc-iram$
 ^loadtools/fc-loadtool$
+^loadtools/fc-simint$
 ^loadtools/fc-xram$
 
 ^miscutil/arfcn2ti$
--- a/loadtools/Makefile	Sun Mar 14 23:55:32 2021 +0000
+++ b/loadtools/Makefile	Fri Mar 19 04:40:05 2021 +0000
@@ -1,6 +1,7 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	fc-iram fc-loadtool fc-xram fc-compalram fc-buzplay fc-dspromdump
+PROGS=	fc-iram fc-loadtool fc-xram fc-compalram fc-buzplay fc-dspromdump \
+	fc-simint
 
 INSTALL_PREFIX=	/opt/freecalypso
 
@@ -34,6 +35,10 @@
 		labaud.o ltexit.o romdump.o romload.o srecreader.o tpinterf.o \
 		tpinterf2.o
 
+SIMINT_OBJS=	compalload.o defexitstub.o defpath.o flashstubs.o hexdecode.o \
+		hwparam.o labaud.o romload.o simatr.o simmain.o simup.o \
+		srecreader.o tpinterf.o tpinterf2.o
+
 LIBPWON=	../libpwon/libpwon.a
 LIBSERIAL=	../libserial/libserial.a
 
@@ -57,6 +62,9 @@
 fc-dspromdump:	${ROMDUMP_OBJS} ${LIBPWON} ${LIBSERIAL}
 	${CC} ${CFLAGS} -o $@ ${ROMDUMP_OBJS} ${LIBPWON} ${LIBSERIAL}
 
+fc-simint:	${SIMINT_OBJS} ${LIBPWON} ${LIBSERIAL}
+	${CC} ${CFLAGS} -o $@ ${SIMINT_OBJS} ${LIBPWON} ${LIBSERIAL}
+
 install:
 	mkdir -p ${INSTBIN}
 	install -c ${PROGS} ${INSTBIN}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/simatr.c	Fri Mar 19 04:40:05 2021 +0000
@@ -0,0 +1,92 @@
+/*
+ * This module implements the stage in fc-simint where ATR bytes
+ * received from simagent are validated.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int sim_allow_spenh;
+
+extern u_char sim_atr[];
+extern unsigned sim_atr_len;
+
+void
+sim_atr_validate()
+{
+	unsigned b, p, y, nhist, have_tck;
+
+	if (sim_atr_len < 2) {
+too_short:	fprintf(stderr, "error: ATR from simagent is too short\n");
+		exit(1);
+	}
+	b = sim_atr[1];
+	p = 2;
+	nhist = b & 0xF;
+	y = b & 0xF0;
+	have_tck = 0;
+	while (y) {
+		if (y & 0x10) {
+			if (p >= sim_atr_len)
+				goto too_short;
+			p++;
+		}
+		if (y & 0x20) {
+			if (p >= sim_atr_len)
+				goto too_short;
+			p++;
+		}
+		if (y & 0x40) {
+			if (p >= sim_atr_len)
+				goto too_short;
+			p++;
+		}
+		if (y & 0x80) {
+			if (p >= sim_atr_len)
+				goto too_short;
+			b = sim_atr[p++];
+			y = b & 0xF0;
+			if (b & 0x0F)
+				have_tck = 1;
+		} else
+			y = 0;
+	}
+	p += nhist + have_tck;
+	if (p > sim_atr_len)
+		goto too_short;
+	if (p < sim_atr_len) {
+		fprintf(stderr, "error: ATR from simagent is too long\n");
+		exit(1);
+	}
+	if (!have_tck)
+		return;
+	/* validate TCK */
+	b = 0;
+	for (p = 1; p < sim_atr_len; p++)
+		b ^= sim_atr[p];
+	if (b) {
+		fprintf(stderr, "error: ATR checksum is bad\n");
+		exit(1);
+	}
+}
+
+void
+sim_spenh_logic()
+{
+	static char *targv[2] = {"spenh", 0};
+
+	if (sim_atr_len < 3 || !(sim_atr[1] & 0x10) || (sim_atr[2] < 0x94)) {
+		printf("ATR indicates no support for speed enhancement\n");
+		return;
+	}
+	if (!sim_allow_spenh) {
+		printf("Speed enhancement disabled with -n option\n");
+		return;
+	}
+	tpinterf_make_cmd(targv);
+	if (tpinterf_send_cmd() < 0)
+		exit(1);
+	if (tpinterf_pass_output(10))
+		exit(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/simmain.c	Fri Mar 19 04:40:05 2021 +0000
@@ -0,0 +1,168 @@
+/*
+ * This module contains the main() function for fc-simint.
+ */
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../libserial/baudrate.h"
+#include "srecreader.h"
+
+char *target_ttydev;
+
+extern struct srecreader iramimage;
+extern struct baudrate *current_baud_rate;
+extern void (*default_exit)();
+
+extern struct baudrate *find_baudrate_by_name();
+
+static char simagent_pathname[] = "/opt/freecalypso/target-bin/simagent.srec";
+static char simtool_pathname[] = "/opt/freecalypso/bin/fc-simtool";
+static char uicc_tool_pathname[] = "/opt/freecalypso/bin/fc-uicc-tool";
+
+static char *selected_simtool = simtool_pathname;
+static struct baudrate *session_baudrate;
+
+int sim_voltage_mode_1v8;
+int sim_allow_spenh = 1;
+
+static void
+tool_select_arg(arg)
+	char *arg;
+{
+	if (!strcmp(arg, "sim"))
+		selected_simtool = simtool_pathname;
+	else if (!strcmp(arg, "uicc"))
+		selected_simtool = uicc_tool_pathname;
+	else {
+		fprintf(stderr, "error: invalid -T argument\n");
+		exit(1);
+	}
+}
+
+static void
+voltage_select_arg(arg)
+	char *arg;
+{
+	if (!strcmp(arg, "1.8"))
+		sim_voltage_mode_1v8 = 1;
+	else if (!strcmp(arg, "3") || !strcmp(arg, "3.0"))
+		sim_voltage_mode_1v8 = 0;
+	else {
+		fprintf(stderr, "error: invalid -v argument\n");
+		exit(1);
+	}
+}
+
+static void
+exec_simtool(passon_argc, passon_argv)
+	char **passon_argv;
+{
+	char **exec_argv, *prog_base_name;
+	char **sp, **dp;
+	extern int target_fd;
+	char desc_arg[16];
+
+	prog_base_name = rindex(selected_simtool, '/') + 1;
+	sprintf(desc_arg, "-C%d", target_fd);
+	exec_argv = (char **) malloc(sizeof(char *) * (passon_argc + 3));
+	if (!exec_argv) {
+		perror("malloc argv for execv");
+		exit(1);
+	}
+	sp = passon_argv;
+	dp = exec_argv;
+	*dp++ = prog_base_name;
+	*dp++ = desc_arg;
+	while (*sp)
+		*dp++ = *sp++;
+	*dp = NULL;
+	execv(selected_simtool, exec_argv);
+	fprintf(stderr, "Unable to exec %s\n", selected_simtool);
+	exit(1);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int c;
+
+	while ((c = getopt(argc, argv, "a:b:B:c:C:h:H:i:nP:t:T:v:")) != EOF)
+		switch (c) {
+		case 'a':
+			iramimage.filename = optarg;
+			continue;
+		case 'b':
+			set_romload_baudrate(optarg);
+			continue;
+		case 'B':
+			session_baudrate = find_baudrate_by_name(optarg);
+			if (!session_baudrate)
+				exit(1);	/* error msg already printed */
+			continue;
+		case 'c':
+			set_compalstage_short(optarg);
+			continue;
+		case 'C':
+			set_compalstage_fullpath(optarg);
+			continue;
+		case 'h':
+			read_hwparam_file_shortname(optarg);
+			continue;
+		case 'H':
+			read_hwparam_file_fullpath(optarg);
+			continue;
+		case 'i':
+			set_beacon_interval(optarg);
+			continue;
+		case 'n':
+			sim_allow_spenh = 0;
+			continue;
+		case 'P':
+			if (find_bootctrl_entry(optarg) < 0)
+				exit(1);	/* error msg already printed */
+			continue;
+		case 't':
+			set_romload_timeout(optarg);
+			continue;
+		case 'T':
+			tool_select_arg(optarg);
+			continue;
+		case 'v':
+			voltage_select_arg(optarg);
+			continue;
+		case '?':
+		default:
+usage:			fprintf(stderr,
+			"usage: fc-simint [options] ttyport [batch command]\n");
+			exit(1);
+		}
+	if (argc - optind < 1)
+		goto usage;
+	target_ttydev = argv[optind];
+	if (!iramimage.filename)
+		iramimage.filename = simagent_pathname;
+
+	open_serial_port(target_ttydev);
+	pwon_if_needed();
+	perform_compal_stage();
+	perform_romload();
+	/* simagent target program should be running now */
+	if (tpinterf_pass_output(1) < 0)
+		exit(1);
+	if (session_baudrate && session_baudrate != current_baud_rate) {
+		c = loadagent_switch_baud(session_baudrate);
+		if (c)
+			exit(1);
+	}
+	do_sim_up();
+	sim_atr_validate();
+	sim_spenh_logic();
+	exec_simtool(argc - optind - 1, argv + optind + 1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/simup.c	Fri Mar 19 04:40:05 2021 +0000
@@ -0,0 +1,66 @@
+/*
+ * This module implements the stage in fc-simint where the sim-up
+ * command is fed to simagent and the ATR response is parsed.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+extern int sim_voltage_mode_1v8;
+
+#define	MAX_ATR_BYTES	33
+
+u_char sim_atr[MAX_ATR_BYTES];
+unsigned sim_atr_len;
+
+static
+sim_up_callback(line)
+	char *line;
+{
+	char *cp;
+
+	puts(line);
+	if (strncmp(line, "ATR:", 4))
+		return(1);
+	sim_atr_len = 0;
+	for (cp = line + 4; *cp; cp += 3) {
+		if (cp[0] != ' ' || !isxdigit(cp[1]) || !isxdigit(cp[2])) {
+			fprintf(stderr,
+				"error: invalid ATR line from simagent\n");
+			return(1);
+		}
+		if (sim_atr_len >= MAX_ATR_BYTES) {
+			fprintf(stderr,
+				"error: ATR from simagent is too long\n");
+			return(1);
+		}
+		sim_atr[sim_atr_len++] = decode_hex_byte(cp + 1);
+	}
+	return(0);
+}
+
+void
+do_sim_up()
+{
+	char *targv[3];
+
+	targv[0] = "sim-up";
+	if (sim_voltage_mode_1v8)
+		targv[1] = "1.8";
+	else
+		targv[2] = "3";
+	targv[2] = 0;
+	tpinterf_make_cmd(targv);
+	if (tpinterf_send_cmd() < 0)
+		exit(1);
+	if (tpinterf_capture_output(20, sim_up_callback))
+		exit(1);
+	if (!sim_atr_len) {
+		fprintf(stderr, "error: no ATR returned from simagent\n");
+		exit(1);
+	}
+}