hooking up the goodfet.xscale code. it is minimal for now. it should be able to...
authordwhuseby <dwhuseby@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 10 Jan 2011 21:13:14 +0000 (21:13 +0000)
committerdwhuseby <dwhuseby@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 10 Jan 2011 21:13:14 +0000 (21:13 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@829 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETMSP430.py
client/GoodFETXSCALE.py [new file with mode: 0644]
client/goodfet.xscale [new file with mode: 0755]
firmware/apps/jtag/jtagxscale.c
firmware/goodfet.c
firmware/include/apps.h
firmware/include/command.h
firmware/include/jtagxscale.h

index adbfd15..ac9ab74 100644 (file)
@@ -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):
         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."""
         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 (file)
index 0000000..6e0aed5
--- /dev/null
@@ -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("<L", "".join(self.data[0:4]))[0]
+
+        version = ident >> 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 (executable)
index 0000000..7c6e95b
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# GoodFET Intel XScale
+# 
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+# (C) 2010 Dave Huseby <dave at linuxprogrammer.org>
+#
+# 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();
index ffe169c..93cba9e 100644 (file)
-/*! \file jtagxscale.c
+/*! 
+  \file jtagxscale.c
   \author Dave Huseby <dave@linuxprogrammer.org>
   \author Dave Huseby <dave@linuxprogrammer.org>
-  \brief Intel XScale JTAG (32-bit)
+  \brief Intel XScale JTAG
 */
 
 #include "platform.h"
 #include "command.h"
 #include "jtag.h"
 */
 
 #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) 
     {
 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 START:
         case STOP:
         case PEEK:
         case POKE:
+        case READ:
+        case WRITE:
         default:
         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;
     }
 }
     }
 }
index a6ccae4..8be9a74 100644 (file)
@@ -112,9 +112,9 @@ void handle(unsigned char app,
   case PIC:
     pichandle(app,verb,len);
     break;
   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;
   case I2CAPP:
     i2chandle(app,verb,len);
     break;
@@ -127,6 +127,9 @@ void handle(unsigned char app,
   case EJTAG:
     ejtaghandle(app,verb,len);
     break;
   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);
   case JTAG430: //Also JTAG430X, JTAG430X2
     //Revert this when X2 support returns.
     jtag430x2handle(app,verb,len);
index 19c5eea..47a9167 100644 (file)
@@ -14,6 +14,7 @@
 #define EJTAG 0x12
 #define JTAGARM7TDMI 0x13
 #define ADIv5 0x14
 #define EJTAG 0x12
 #define JTAGARM7TDMI 0x13
 #define ADIv5 0x14
+#define JTAGXSCALE 0x15
 
 //Manufacturer-specific protocols go in 0x30 and 0x40.
 #define CHIPCON 0x30
 
 //Manufacturer-specific protocols go in 0x30 and 0x40.
 #define CHIPCON 0x30
index 29f406f..567d810 100644 (file)
@@ -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 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,
 
 WEAKDEF void nrfhandle(unsigned char,
                       unsigned char,
index 05d497b..f1f17fa 100644 (file)
@@ -1,11 +1,84 @@
-/*! \file jtagxscale.h
+/*! 
+  \file jtagxscale.h
   \author Dave Huseby <huseby at linuxprogrammer.org>
   \author Dave Huseby <huseby at linuxprogrammer.org>
-  \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();
+
+