FreeCalypso > hg > freecalypso-sw
view rvinterf/lowlevel/tfc139.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 | 15e69d31c96f |
children | 0d7cc054ef72 |
line wrap: on
line source
/* * This program is a contender for the title of the ugliest hack * in the FreeCalypso project. It will attempt to break into a * locked-down TracFone C139 by mimicking the actions of the * mot931c.exe TF "unlocker". */ #include <sys/types.h> #include <sys/errno.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include "../include/pktmux.h" #include "../include/limits.h" extern int target_fd; extern char *baudrate_name; extern u_char rxpkt[]; extern size_t rxpkt_len; char *logfname; FILE *logF; time_t logtime; int no_output; /* for output.c */ int wakeup_after_sec = 7; /* see ../../target-utils/tf-breakin/payload.S for the source */ static u_char iram_payload[112] = { 0xD3, 0xF0, 0x21, 0xE3, 0x58, 0x10, 0x9F, 0xE5, 0xF5, 0x00, 0xA0, 0xE3, 0xB2, 0x00, 0xC1, 0xE1, 0xA0, 0x00, 0xA0, 0xE3, 0xB2, 0x00, 0xC1, 0xE1, 0x48, 0x60, 0x9F, 0xE5, 0x05, 0x00, 0xD6, 0xE5, 0x20, 0x00, 0x10, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A, 0x2C, 0x10, 0x8F, 0xE2, 0x06, 0x20, 0xA0, 0xE3, 0x01, 0x00, 0xD1, 0xE4, 0x00, 0x00, 0xC6, 0xE5, 0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x05, 0x00, 0xD6, 0xE5, 0x40, 0x00, 0x10, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A, 0x18, 0x10, 0x9F, 0xE5, 0x01, 0x2C, 0xA0, 0xE3, 0xB0, 0x20, 0xC1, 0xE1, 0x00, 0xF0, 0xA0, 0xE3, 0x02, 0x02, 0x02, 0x4F, 0x4B, 0x02, 0x00, 0x00, 0x02, 0xF8, 0xFF, 0xFF, 0x00, 0x58, 0xFF, 0xFF, 0x10, 0xFB, 0xFF, 0xFF }; static unsigned iram_load_addr = 0x800000; static unsigned stack_smash_addr = 0x837C54; static u_char stack_smash_payload[4]; static char *target_tty_port; static void send_compal_memwrite(addr, payload, payload_len) unsigned addr; u_char *payload; { u_char pkt[MAX_PKT_TO_TARGET]; int i, csum, csum_offset; pkt[0] = RVT_TM_HEADER; pkt[1] = 0x40; /* Compal's non-standard addition */ pkt[2] = addr; pkt[3] = addr >> 8; pkt[4] = addr >> 16; pkt[5] = addr >> 24; bcopy(payload, pkt + 6, payload_len); csum_offset = payload_len + 6; csum = 0; for (i = 1; i < csum_offset; i++) csum ^= pkt[i]; pkt[i] = csum; send_pkt_to_target(pkt, i + 1); } main(argc, argv) char **argv; { extern char *optarg; extern int optind; int c; fd_set fds; baudrate_name = "57600"; /* what C139 firmware uses */ while ((c = getopt(argc, argv, "a:B:l:s:w:")) != EOF) switch (c) { case 'a': iram_load_addr = strtoul(optarg, 0, 16); continue; case 'B': baudrate_name = optarg; continue; case 'l': logfname = optarg; continue; case 's': stack_smash_addr = strtoul(optarg, 0, 16); continue; case 'w': wakeup_after_sec = strtoul(optarg, 0, 0); continue; case '?': default: usage: fprintf(stderr, "usage: %s [options] ttyport\n", argv[0]); exit(1); } if (argc - optind != 1) goto usage; open_target_serial(argv[optind]); target_tty_port = argv[optind]; set_serial_nonblock(0); setlinebuf(stdout); if (logfname) { logF = fopen(logfname, "w"); if (!logF) { perror(logfname); exit(1); } setlinebuf(logF); fprintf(logF, "*** Log of TFC139 break-in session ***\n"); } time(&logtime); output_line("Sending IRAM payload"); send_compal_memwrite(iram_load_addr, iram_payload, sizeof iram_payload); stack_smash_payload[0] = iram_load_addr; stack_smash_payload[1] = iram_load_addr >> 8; stack_smash_payload[2] = iram_load_addr >> 16; stack_smash_payload[3] = iram_load_addr >> 24; for (;;) { FD_ZERO(&fds); FD_SET(target_fd, &fds); c = select(target_fd+1, &fds, 0, 0, 0); time(&logtime); if (c < 0) { if (errno == EINTR) continue; perror("select"); exit(1); } if (FD_ISSET(target_fd, &fds)) process_serial_rx(); } } static void handle_etm_response() { char msgbuf[80]; if (rxpkt_len != 4 || rxpkt[1] != 0x40 || rxpkt[2] || rxpkt[3] != 0x40){ output_line("ETM response differs from expected"); return; } sprintf(msgbuf, "Sending stack smash write at 0x%x", stack_smash_addr); output_line(msgbuf); send_compal_memwrite(stack_smash_addr, stack_smash_payload, 4); stack_smash_addr += 4; } handle_rx_packet() { if (rxpkt_len == 2 && rxpkt[0] == 'O' && rxpkt[1] == 'K') { output_line( "Success: target should now be in boot ROM download wait"); printf("You can now run fc-loadtool -h compal -c none %s\n", target_tty_port); exit(0); } switch (rxpkt[0]) { case RVT_RV_HEADER: if (rxpkt_len < 6) goto unknown; print_rv_trace(); return; case RVT_L1_HEADER: print_l1_trace(); return; case RVT_L23_HEADER: print_g23_trace(); return; case RVT_TM_HEADER: print_etm_output_raw(); handle_etm_response(); return; default: unknown: print_unknown_packet(); } }