/* * $Id$ * * Copyright (C) 2002 ETC s.r.o. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * Written by Marcel Telka , 2002. * */ #include #include #include #include #include #include #include struct id_record { char name[20]; char fullname[100]; }; static int find_record( char *filename, tap_register *key, struct id_record *idr ) { FILE *file; tap_register *tr; int r = 0; file = fopen( filename, "r" ); if (!file) return 0; tr = register_alloc( key->len ); for (;;) { char *p; char *s; char line[1024]; if (fgets( line, 1024, file ) == NULL) break; /* remove comment and nl from the line */ p = strpbrk( line, "#\n" ); if (p) *p = '\0'; p = line; /* skip whitespace */ while (*p && isspace(*p)) p++; /* remove ending whitespace */ s = strchr( p, '\0' ); while (s != p) { if (!isspace(*--s)) break; *s = '\0'; } /* line is empty? */ if (!*p) continue; /* find end of field */ s = p; while (*s && !isspace(*s)) s++; if (*s) *s++ = '\0'; /* test field length */ if (strlen( p ) != key->len) continue; /* match */ register_init( tr, p ); if (register_compare( tr, key )) continue; /* next field */ p = s; /* skip whitespace */ while (*p && isspace(*p)) p++; /* line is empty? */ if (!*p) continue; /* find end of field */ s = p; while (*s && !isspace(*s)) s++; if (*s) *s++ = '\0'; /* test field length */ if (strlen( p ) >= sizeof idr->name) continue; /* copy name */ strcpy( idr->name, p ); /* next field */ p = s; /* skip whitespace */ while (*p && isspace(*p)) p++; /* line is empty? */ if (!*p) continue; /* test field length */ if (strlen( p ) >= sizeof idr->fullname) continue; /* copy fullname */ strcpy( idr->fullname, p ); r = 1; break; } fclose( file ); register_free( tr ); return r; } parts * detect_parts( char *db_path ) { tap_register *zeros; tap_register *id; char data_path[1024]; parts *ps = parts_alloc(); if (!ps) { printf( __FUNCTION__ ": out of memory\n" ); return NULL; } zeros = register_fill( register_alloc( 32 ), 0 ); id = register_alloc( 32 ); tap_reset(); tap_capture_dr(); for (;;) { tap_register *key; struct id_record idr; char *p; tap_shift_register( zeros, id, 0 ); if (!register_compare( id, zeros )) { tap_clock( 1, 0 ); /* Exit1-DR */ tap_clock( 1, 0 ); /* Update-DR */ break; } printf( "%s\n", register_get_string( id ) ); strcpy( data_path, db_path ); /* FIXME: Buffer overrun */ /* manufacturers */ strcat( data_path, "/MANUFACTURERS" ); key = register_alloc( 11 ); memcpy( key->data, &id->data[1], key->len ); if (!find_record( data_path, key, &idr )) { printf( " Unknown manufacturer!\n" ); register_free( key ); continue; } register_free( key ); printf( " Manufacturer: %s\n", idr.fullname ); /* parts */ p = strrchr( data_path, '/' ); if (p) p[1] = '\0'; else data_path[0] = '\0'; strcat( data_path, idr.name ); strcat( data_path, "/PARTS" ); key = register_alloc( 16 ); memcpy( key->data, &id->data[12], key->len ); if (!find_record( data_path, key, &idr )) { printf( " Unknown part!\n" ); register_free( key ); continue; } register_free( key ); printf( " Part: %s\n", idr.fullname ); /* steppings */ p = strrchr( data_path, '/' ); if (p) p[1] = '\0'; else data_path[0] = '\0'; strcat( data_path, idr.name ); strcat( data_path, "/STEPPINGS" ); key = register_alloc( 4 ); memcpy( key->data, &id->data[28], key->len ); if (!find_record( data_path, key, &idr )) { printf( " Unknown stepping!\n" ); register_free( key ); continue; } register_free( key ); printf( " Stepping: %s\n", idr.fullname ); /* part definition file */ p = strrchr( data_path, '/' ); if (p) p[1] = '\0'; else data_path[0] = '\0'; strcat( data_path, idr.name ); printf( "Reading file: %s ... ", data_path ); { FILE *f = fopen( data_path, "r" ); part *p = read_part( f ); p->active_instruction = part_find_instruction( p, "IDCODE" ); parts_add_part( ps, p ); } printf( "done\n" ); } register_free( zeros ); register_free( id ); return ps; } void setup_address( part *p, unsigned int a ) { int i; char buff[10]; for (i = 0; i < 26; i++) { sprintf( buff, "MA[%d]", i ); part_set_signal( p, buff, 1, (a >> i) & 1 ); } } void setup_data( part *p, unsigned int d ) { int i; char buff[10]; for (i = 0; i < 32; i++) { sprintf( buff, "MD[%d]", i ); part_set_signal( p, buff, 1, (d >> i) & 1 ); } } unsigned int get_data( part *p ) { int i; char buff[10]; unsigned int d = 0; for (i = 0; i < 32; i++) { sprintf( buff, "MD[%d]", i ); d |= (unsigned int) (part_get_signal( p, buff ) << i); } return d; } void set_data_in( part *p ) { int i; char buff[10]; for (i = 0; i < 32; i++) { sprintf( buff, "MD[%d]", i ); part_set_signal( p, buff, 0, 0 ); } } #define AB_READ 0 #define AB_WRITE 1 #define AB_SETUP 2 #define AB_HOLD 3 unsigned int access_bus( part *p, int type, unsigned int a, unsigned int d ) { part_set_signal( p, "nCS[0]", 1, 0 ); setup_address( p, a ); switch (type) { case AB_READ: part_set_signal( p, "nOE", 1, 0 ); part_set_signal( p, "nWE", 1, 1 ); set_data_in( p ); break; case AB_WRITE: part_set_signal( p, "nOE", 1, 1 ); part_set_signal( p, "nWE", 1, 0 ); setup_data( p, d ); break; case AB_SETUP: case AB_HOLD: part_set_signal( p, "nOE", 1, 1 ); part_set_signal( p, "nWE", 1, 1 ); setup_data( p, d ); break; default: printf( "access_bus: invalid typ\n" ); return 0; } tap_capture_dr(); tap_shift_register( p->bsr, p->prev_bsr, 1 ); return get_data( p ); } unsigned int access_rom( part *p, int type, unsigned int a, unsigned int d ) { return access_bus( p, type, a << 2, d ); } void program_flash( part *p, unsigned int a, unsigned int d ) { access_rom( p, AB_SETUP, a, 0x00400040 ); access_rom( p, AB_WRITE, a, 0x00400040 ); access_rom( p, AB_HOLD, a, 0x00400040 ); access_rom( p, AB_SETUP, a, d ); access_rom( p, AB_WRITE, a, d ); access_rom( p, AB_HOLD, a, d ); access_rom( p, AB_READ, 0, 0 ); printf( "pf: %08X\n", access_rom( p, AB_READ, 0, 0 ) ); sleep( 1 ); } void unlock( part *p, unsigned int a ) { access_rom( p, AB_SETUP, a, 0x00600060 ); access_rom( p, AB_WRITE, a, 0x00600060 ); access_rom( p, AB_HOLD, a, 0x00600060 ); access_rom( p, AB_SETUP, a, 0x00D000D0 ); access_rom( p, AB_WRITE, a, 0x00D000D0 ); access_rom( p, AB_HOLD, a, 0x00D000D0 ); } void erase( part *p, unsigned int a ) { printf( "erase\n" ); access_rom( p, AB_SETUP, a, 0x00200020 ); access_rom( p, AB_WRITE, a, 0x00200020 ); access_rom( p, AB_HOLD, a, 0x00200020 ); access_rom( p, AB_SETUP, a, 0x00D000D0 ); access_rom( p, AB_WRITE, a, 0x00D000D0 ); access_rom( p, AB_HOLD, a, 0x00D000D0 ); access_rom( p, AB_READ, 0, 0 ); printf( "pf: %08X\n", access_rom( p, AB_READ, 0, 0 ) ); sleep( 4 ); access_rom( p, AB_READ, 0, 0 ); printf( "pf: %08X\n", access_rom( p, AB_READ, 0, 0 ) ); printf( "pf: %08X\n", access_rom( p, AB_READ, 0, 0 ) ); } int main( void ) { parts *ps; part *p; unsigned int max_erase_time; unsigned int dsize; tap_init(); tap_set_trst( 0 ); tap_set_trst( 1 ); ps = detect_parts( "../data" ); if (ps->len == 0) { printf( "Not detected!!!\n" ); return 0; } p = ps->parts[0]; printf( "Setting up safe default values\n" ); parts_set_instruction( ps, "SAMPLE/PRELOAD" ); tap_capture_dr(); tap_shift_register( p->bsr, p->prev_bsr, 1 ); printf( "%s\n", register_get_string( p->bsr ) ); printf( "%s\n", register_get_string( p->prev_bsr ) ); parts_set_instruction( ps, "EXTEST" ); access_rom( p, AB_SETUP, 0x00000000, 0x00500050 ); access_rom( p, AB_WRITE, 0x00000000, 0x00500050 ); access_rom( p, AB_HOLD, 0x00000000, 0x00500050 ); access_rom( p, AB_SETUP, 0x00000000, 0x00980098 ); access_rom( p, AB_WRITE, 0x00000000, 0x00980098 ); access_rom( p, AB_HOLD, 0x00000000, 0x00980098 ); access_rom( p, AB_READ, 0x10, 0 ); printf( "read 0x10: %08X\n", access_rom( p, AB_READ, 0x11, 0 ) ); printf( "read 0x11: %08X\n", access_rom( p, AB_READ, 0x12, 0 ) ); printf( "read 0x12: %08X\n", access_rom( p, AB_READ, 0x25, 0 ) ); printf( "read max_erase_time: %08X\n", max_erase_time = access_rom( p, AB_READ, 0x27, 0 ) ); dsize = 1 << (access_rom( p, AB_READ, 0x27, 0 ) & 0xFFFF); printf( "device size: %08X\n", dsize ); unlock( p, 0 ); erase( p, 0 ); #if 0 { FILE *f = fopen( "brux.b", "r" ); unsigned int d; unsigned int a = 0; while (fread( &d, sizeof d, 1, f ) == 1) { program_flash( p, a, d ); a += 4; } } #endif program_flash( p, 0x0, 0xE1A00000 ); program_flash( p, 0x4, 0xE1A00000 ); program_flash( p, 0x8, 0xE1A00000 ); program_flash( p, 0xC, 0xE1A00000 ); program_flash( p, 0x10, 0xE1A00000 ); program_flash( p, 0x14, 0xEAFFFFF9 ); //erase( p, 0 ); access_rom( p, AB_SETUP, 0, 0x00FF00FF ); access_rom( p, AB_WRITE, 0, 0x00FF00FF ); access_rom( p, AB_HOLD, 0, 0x00FF00FF ); access_rom( p, AB_READ, 0, 0 ); printf( "read data from 0x00: %08X\n", access_rom( p, AB_READ, 0x04, 0 ) ); printf( "read data from 0x04: %08X\n", access_rom( p, AB_READ, 0x08, 0 ) ); printf( "read data from 0x08: %08X\n", access_rom( p, AB_READ, 0x0C, 0 ) ); printf( "read data from 0x0C: %08X\n", access_rom( p, AB_READ, 0x10, 0 ) ); printf( "read data from 0x10: %08X\n", access_rom( p, AB_READ, 0x14, 0 ) ); printf( "read data from 0x14: %08X\n", access_rom( p, AB_READ, 0x18, 0 ) ); printf( "read data from 0x18: %08X\n", access_rom( p, AB_READ, 0x1C, 0 ) ); #if 0 tap_capture_dr(); a: printf( "Jedna\n" ); part_set_signal( sa1110, "MA[24]", 1, 1 ); tap_shift_register( sa1110->bsr, sa1110->prev_bsr, 1 ); tap_capture_dr(); sleep(5); printf( "Nula\n" ); part_set_signal( sa1110, "MA[24]", 1, 0 ); tap_shift_register( sa1110->bsr, sa1110->prev_bsr, 1 ); tap_capture_dr(); sleep(5); goto a; printf( "%s\n", register_get_string( sa1110->bsr ) ); printf( "%s\n", register_get_string( sa1110->prev_bsr ) ); // for (i = 0; i < s1110->boundary_length; i++) { // // } #endif parts_free( ps ); tap_reset(); tap_done(); return 0; }