From 278a9487e60fdcf3e96236580f9542c218a8c1f1 Mon Sep 17 00:00:00 2001 From: dwhuseby Date: Mon, 10 Jan 2011 21:13:14 +0000 Subject: [PATCH 1/1] hooking up the goodfet.xscale code. it is minimal for now. it should be able to pull down the cpu id. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@829 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFETMSP430.py | 2 +- client/GoodFETXSCALE.py | 70 +++++++++++++ client/goodfet.xscale | 33 ++++++ firmware/apps/jtag/jtagxscale.c | 178 +++++++++++++++++++++++++++++++- firmware/goodfet.c | 9 +- firmware/include/apps.h | 1 + firmware/include/command.h | 5 +- firmware/include/jtagxscale.h | 81 ++++++++++++++- 8 files changed, 365 insertions(+), 14 deletions(-) create mode 100644 client/GoodFETXSCALE.py create mode 100755 client/goodfet.xscale diff --git a/client/GoodFETMSP430.py b/client/GoodFETMSP430.py index adbfd15..ac9ab74 100644 --- a/client/GoodFETMSP430.py +++ b/client/GoodFETMSP430.py @@ -66,7 +66,7 @@ class GoodFETMSP430(GoodFET): self.writecmd(self.MSP430APP,0x03,6,self.data); written=ord(self.data[0])+(ord(self.data[1])<<8); if(written!=val): - print "Failed to write 0x%04x to 0x$04x" % (val,adr); + print "Failed to write 0x%04x to 0x%04x" % (val,adr); return written; def MSP430pokeflash(self,adr,val): """Write the contents of flash memory at an address.""" diff --git a/client/GoodFETXSCALE.py b/client/GoodFETXSCALE.py new file mode 100644 index 0000000..6e0aed5 --- /dev/null +++ b/client/GoodFETXSCALE.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# GoodFET Client Library +# +# +# Good luck with alpha / beta code. +# Contributions and bug reports welcome. +# +# NOTE: this is just a hacked up copy of the GoodFETARM.py file + +import sys, binascii, struct + +# Standard verbs +READ = 0x00 +WRITE = 0x01 +PEEK = 0x02 +POKE = 0x03 +SETUP = 0x10 +START = 0x20 +STOP = 0x21 +CALL = 0x30 +EXEC = 0x31 +NOK = 0x7E +OK = 0x7F + +# XSCALE JTAG verbs +GET_CHIP_ID = 0xF1 + +from GoodFET import GoodFET +from intelhex import IntelHex + +class GoodFETXSCALE(GoodFET): + + """A GoodFET variant for use with XScale processors.""" + + XSCALEAPP=0x13; + APP=XSCALEAPP; + + def setup(self): + """Move the FET into the JTAG ARM application.""" + print "Initializing XScale..." + self.writecmd(self.APP, SETUP, 0, self.data) + + def start(self): + """Start debugging.""" + print "Staring debug..." + self.writecmd(self.APP, START, 0, self.data) + + def stop(self): + """Stop debugging.""" + print "Stopping debug..." + self.writecmd(self.APP, STOP, 0, self.data) + + def get_id(self): + """Get the Chip ID.""" + + # send the get chip ID command + self.writecmd(self.APP, GET_CHIP_ID, 0, []) + + # get the response + ident = struct.unpack("> 28 + part_number = (ident >> 12) & 0x10 + manufacturer = ident & 0xFFF + + print "XScale ID --\n\tmfg: %x\n\tpart: %x\n\tver: %x\n\t(%x)" % (version, part_number, manufacturer, ident) + + return ident + + diff --git a/client/goodfet.xscale b/client/goodfet.xscale new file mode 100755 index 0000000..7c6e95b --- /dev/null +++ b/client/goodfet.xscale @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# GoodFET Intel XScale +# +# (C) 2009 Travis Goodspeed +# (C) 2010 Dave Huseby +# +# This code is being rewritten and refactored. You've been warned! + +import sys; +import binascii; + +from GoodFETXSCALE import GoodFETXSCALE +from intelhex import IntelHex + +#if(len(sys.argv) == 1): +# print "Usage: %s verb [objects]\n" % sys.argv[0] +# print "%s chipid" % sys.argv[0] +# sys.exit(); + +#Initailize FET and set baud rate +client = GoodFETXSCALE() +client.serInit() + +#Connect to target +client.setup() +client.start() + +print 'arg: %s' % sys.argv[1] +if(sys.argv[1] == 'chipid'): + print 'Getting XScale Chip ID...' + client.get_id() + +client.stop(); diff --git a/firmware/apps/jtag/jtagxscale.c b/firmware/apps/jtag/jtagxscale.c index ffe169c..93cba9e 100644 --- a/firmware/apps/jtag/jtagxscale.c +++ b/firmware/apps/jtag/jtagxscale.c @@ -1,24 +1,194 @@ -/*! \file jtagxscale.c +/*! + \file jtagxscale.c \author Dave Huseby - \brief Intel XScale JTAG (32-bit) + \brief Intel XScale JTAG */ #include "platform.h" #include "command.h" #include "jtag.h" +#include "jtagxscale.h" -//! Handles XScale JTAG commands. Forwards others to JTAG. +/* From the Intel XScale Core Developer's Manual: + * + * The Intel XScale® core provides test features compatible with IEEE Standard + * Test Access Port and Boundary Scan Architecture (IEEE Std. 1149.1). These + * features include a TAP controller, a 5 or 7 bit instruction register, and + * test data registers to support software debug. The size of the instruction + * register depends on which variant of the Intel XScale® core is being used. + * This can be found out by examining the CoreGen field of Coprocessor 15, ID + * Register (bits 15:13). (See Table 7-4, "ID Register" on page 7-81 for more + * details.) A CoreGen value of 0x1 means the JTAG instruction register size + * is 5 bits and a CoreGen value of 0x2 means the JTAG instruction register + * size is 7 bits. + * + */ + +/* NOTE: I heavily cribbed from the ARM7TDMI jtag implementation. Credit where + * credit is due. */ + +/* this handles shifting arbitrary length bit strings into the instruction + * register and clocking out bits while leaving the JTAG state machine in a + * known state. it also handle bit swapping. */ +unsigned long jtag_xscale_shift_n(unsigned long word, + unsigned char nbits, + unsigned char flags) +{ + unsigned int bit; + unsigned long high = 1; + unsigned long mask; + + for (bit = (nbits - 1) / 8; bit > 0; bit--) + high <<= 8; + + high <<= ((nbits - 1) % 8); + + mask = high - 1; + + if (flags & LSB) + { + /* clock the bits into the IR from LSB to MSB order */ + for (bit = nbits; bit > 0; bit--) + { + /* write MOSI on trailing edge of previous clock */ + if (word & 1) + { + SETMOSI; + } + else + { + CLRMOSI; + } + word >>= 1; + + if (bit == 1 && !(flags & NOEND)) + SETTMS; /* TMS high on last bit to exit. */ + + /* tick tock the clock line */ + XTT; + + /* read MISO on trailing edge */ + if (READMISO) + { + word += (high); + } + } + } + else + { + /* clock the bits into the IR from MSB to LSB order */ + for (bit = nbits; bit > 0; bit--) + { + /* write MOSI on trailing edge of previous clock */ + if (word & high) + { + SETMOSI; + } + else + { + CLRMOSI; + } + word = (word & mask) << 1; + + if (bit == 1 && !(flags & NOEND)) + SETTMS;//TMS high on last bit to exit. + + /* tick tock the clock line */ + XTT; + + /* read MISO on trailing edge */ + word |= (READMISO); + } + } + + SETMOSI; + + if (!(flags & NOEND)) + { + /* exit state */ + XTT; + + /* update state */ + if (!(flags & NORETIDLE)) + { + CLRTMS; + XTT; + } + } + + return word; +} + + +/* this handles shifting in the IDCODE instruction and shifting the result + * out the TDO and return it. */ +unsigned long jtag_xscale_idcode() +{ + /* NOTE: this assumes that we're in the run-test-idle state */ + + /* get into the shift-ir state */ + SHIFT_IR; + + /* shift the ID code instruction into the IR and return to run-test-idle */ + jtag_xscale_shift_n(XSCALE_IR_IDCODE, 5, LSB); + + /* get into the shift-dr state */ + SHIFT_DR; + + /* now clock out the 32 bit ID code and return back to run-test-idle */ + return jtag_xscale_shift_n(0, 32, LSB); +} + +/* Handles XScale JTAG commands. Forwards others to JTAG. */ void xscalehandle(unsigned char app, unsigned char verb, unsigned long len) { switch(verb) { + /* + * Standard Commands + */ + case SETUP: + + /* set up the pin I/O for JTAG */ + jtagsetup(); + + /* reset to run-test-idle state */ + RUN_TEST_IDLE; + + /* send back OK */ + txdata(app, OK, 0); + + break; + case START: case STOP: case PEEK: case POKE: + case READ: + case WRITE: default: - jtaghandle(app,verb,len); + + /* send back OK */ + txdata(app, OK, 0); + + break; + + /* + * XScale Commands + */ + case XSCALE_GET_CHIP_ID: + + /* reset to run-test-idle state */ + RUN_TEST_IDLE; + + /* put the ID code in the data buffer */ + cmddatalong[0] = jtag_xscale_idcode(); + + /* send it back to the client */ + txdata(app,verb,4); + + break; } } diff --git a/firmware/goodfet.c b/firmware/goodfet.c index a6ccae4..8be9a74 100644 --- a/firmware/goodfet.c +++ b/firmware/goodfet.c @@ -112,9 +112,9 @@ void handle(unsigned char app, case PIC: pichandle(app,verb,len); break; - case ADC10: - adchandle(app,verb,len); - break; + case ADC10: + adchandle(app,verb,len); + break; case I2CAPP: i2chandle(app,verb,len); break; @@ -127,6 +127,9 @@ void handle(unsigned char app, case EJTAG: ejtaghandle(app,verb,len); break; + case JTAGXSCALE: + xscalehandle(app,verb,len); + break; case JTAG430: //Also JTAG430X, JTAG430X2 //Revert this when X2 support returns. jtag430x2handle(app,verb,len); diff --git a/firmware/include/apps.h b/firmware/include/apps.h index 19c5eea..47a9167 100644 --- a/firmware/include/apps.h +++ b/firmware/include/apps.h @@ -14,6 +14,7 @@ #define EJTAG 0x12 #define JTAGARM7TDMI 0x13 #define ADIv5 0x14 +#define JTAGXSCALE 0x15 //Manufacturer-specific protocols go in 0x30 and 0x40. #define CHIPCON 0x30 diff --git a/firmware/include/command.h b/firmware/include/command.h index 29f406f..567d810 100644 --- a/firmware/include/command.h +++ b/firmware/include/command.h @@ -135,9 +135,10 @@ WEAKDEF void cchandle(unsigned char, unsigned char, unsigned long); WEAKDEF void jtaghandle(unsigned char, unsigned char, unsigned long); WEAKDEF void jtag430handle(unsigned char, unsigned char, unsigned long); WEAKDEF void ejtaghandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len); +WEAKDEF void jtagarm7tdmihandle(unsigned char, unsigned char, unsigned long); +WEAKDEF void xscalehandle(unsigned char, unsigned char, unsigned long); -WEAKDEF void jtag430x2handle(unsigned char app, unsigned char verb, unsigned long len); +WEAKDEF void jtag430x2handle(unsigned char, unsigned char, unsigned long); WEAKDEF void nrfhandle(unsigned char, unsigned char, diff --git a/firmware/include/jtagxscale.h b/firmware/include/jtagxscale.h index 05d497b..f1f17fa 100644 --- a/firmware/include/jtagxscale.h +++ b/firmware/include/jtagxscale.h @@ -1,11 +1,84 @@ -/*! \file jtagxscale.h +/*! + \file jtagxscale.h \author Dave Huseby - \brief Intel XScale JTAG command verbs + \brief Intel XScale JTAG */ +/* NOTE: I heavily cribbed from the ARM7TDMI jtag implementation. Credit where + * credit is due. */ + +/* + * Utility Macros + */ + +/* XTT (LED TCK TOCK) toggles the CLK line while turning on/off the LED */ +#define XTT CLRTCK;PLEDOUT^=PLEDPIN;SETTCK;PLEDOUT^=PLEDPIN; + +/* RUN_TEST_IDLE gets us into run-test-idle from anywhere in the TAP FSM */ +#define RUN_TEST_IDLE SETTMS;XTT;XTT;XTT;XTT;XTT;XTT;XTT;XTT;CLRTMS;XTT; + +/* SHIFT_IR gets us into the "Shift IR" state from the run-test-idle state */ +#define SHIFT_IR SETTMS;XTT;XTT;CLRTMS;XTT;XTT; + +/* SHIFT_DIR gets us into the "Shift DR" state from the run-test-idle state */ +#define SHIFT_DR SETTMS;XTT;CLRTMS;XTT;XTT; + + +/* + * XScale 5-bit JTAG Commands + */ + +/* On the XScale chip, the TDI pin is connected to the MSB of the IR and the + * TDO is connected to the LSB. That means we have to shift these commands + * in from LSB to MSB order. */ + +/* 01000 - High Z + * The highz instruction floats all three-stateable output and in/out pins. + * Also, when this instruction is active, the Bypass register is connected + * between TDI and TDO. This register can be accessed via the JTAG Test-Access + * Port throughout the device operation. Access to the Bypass register can also + * be obtained with the bypass instruction. */ +#define XSCALE_IR_HIGHZ 0x08 + +/* 11110 - Get ID Code + * The idcode instruction is used in conjunction with the device identification + * register. It connects the identification register between TDI and TDO in the + * Shift_DR state. When selected, idcode parallel-loads the hard-wired + * identification code (32 bits) on TDO into the identification register on the + * rising edge of TCK in the Capture_DR state. Note: The device identification + * register is not altered by data being shifted in on TDI.*/ +#define XSCALE_IR_IDCODE 0x1E + +/* 11111 - Bypass + * The bypass instruction selects the Bypass register between TDI and TDO pins + * while in SHIFT_DR state, effectively bypassing the processor’s test logic. + * 02 is captured in the CAPTURE_DR state. While this instruction is in effect, + * all other test data registers have no effect on the operation of the system. + * Test data registers with both test and system functionality perform their + * system functions when this instruction is selected. */ +#define XSCALE_IR_BYPASS 0x1F /* - * TODO: specify the standard Intel XScale IR, TCB control and device specific - * values. + * GoodFET Commands from the Client */ +/* Get CHIP ID */ +#define XSCALE_GET_CHIP_ID 0xF1 + + +/* + * Public Interface + */ + +/* this handles shifting arbitrary length bit strings into the instruction + * register and clocking out bits while leaving the JTAG state machine in a + * known state. it also handle bit swapping. */ +unsigned long jtag_xscale_shift_n(unsigned long word, + unsigned char nbits, + unsigned char flags); + +/* this handles shifting in the IDCODE instruction and shifting the result + * out the TDO and return it. */ +unsigned long jtag_xscale_idcode(); + + -- 2.20.1