On Mon, Feb 23, 2015 at 1:52 PM, Matthijs van Duin <matthijsvanduin@xxxxxxxxx> wrote: > At least on the am335x, the trick actually works! I have a working > demo which configures ICEPick registers and even performs transactions > on the debug interconnect. Nice! > I've been lazy and imported a bunch of files from my baremetal > projects so I could easily mess with the hardware, rudely bypassing > the kernel. The whole implementation is hideous in all sorts of ways, > but it gets the job done: https://github.com/dutchanddutch/jbang > > The key part, how to bitbang JTAG, is reasonably isolated from all > this in src/jbang.cc and glues onto the device-specific part via > hw-subarctic.h. You could probably also turn jbang.cc into plain C > without too much effort and discard the rest... I accept that my code > style is probably a bit of an acquired taste ;-) > > For the omap3, apart from the differences in padconf details, you'll > want to change icepick_init_regs[] to just { 0x23002100 } I think and > hopefully you can then write the DAPCTL regs using ap_write(). I've finally got rid of nTRST pulldown (haven't connected TDO though), created hw-omap3.{h,cc}, but couldn't get it to do anything, until it came to my mind that you may be running ARM on your BBB slower that 1GHz that I'm using on my DM3730. So lowered the clock to 500MHz and voila, it worked! I guess I'll still connect TDO as it's not so much fun without it, going to try connecting to EMU0 too, hopefully it doesn't mess up the boot modes. Before I could get it all to work a coworker lent me an Altera USB Blaster, which I've connected to a pandora prototype board I still have from a long time ago and wasn't that afraid to kill with bad soldering job. And hey, it worked too with your code modified to use USB Blaster in it's bitbang mode over libftdi. This setup also works with openocd, but somewhat unreliably (only occasionally gets through init, often gets register values it doesn't like). My main goal is to have hardware watchpoints on the cased production unit without extra hardware, and it looks like I can finally have that, thanks! > I hope this example is of any help. It sure is! The only thing I do not understand is why are you using that process_vm_readv() call, mmap() already makes unprivileged user mode writable mappings. Anyway I'm attaching my code too, feel free to incorporate it too and/or ultra-modernize to your c++ dialect. Gražvydas
#include "defs.h" #include "map-phys.h" #include "hw-omap3.h" static u16 *padconf_regs; //-------------- JTAG pin i/o ------------------------------------------------// // JTAG inputs controlled by toggling receiver-enable (pins must be pulled high // externally or left floating to allow internal pull-up to work). // let static sim_input( uint offset, bool level ) { padconf_regs[offset >> 1] = 0x0018 | (level ? 0x0100 : 0x0000); } // JTAG inputs controlled via padconf let trst( bool level ) -> void { sim_input( 0x0a1c, level ); } let tck( bool level ) -> void { sim_input( 0x0a1e, level ); } let tms( bool level ) -> void { sim_input( 0x0a20, level ); } let tdi( bool level ) -> void { sim_input( 0x0a22, level ); } // JTAG output (TDO) monitored via gpio let tdo() -> bool { return 0; } // TDO unavailable let static tdo_init() { } // RTCK unavailable let rtck() -> bool { return false; } let hw_init() -> void { padconf_regs = (u16 *)map_phys( 0x4800'2000, 0x1000 ); if( has_tdo ) tdo_init(); }
#pragma once #include "defs.h" let hw_init() -> void; //-------------- JTAG pin i/o ------------------------------------------------// // control JTAG inputs let trst( bool out ) -> void; let tck( bool out ) -> void; let tms( bool out ) -> void; let tdi( bool out ) -> void; // monitor JTAG output let tdo() -> bool; let rtck() -> bool; let constexpr has_tdo = false; let constexpr has_rtck = false; //-------------- Debug hw config ---------------------------------------------// constexpr u32 idcode_mask = 0x0'ffff'fff; constexpr u32 idcode_match = 0x0'b7ae'02f; // initialization of icepick registers constexpr u32 icepick_init_regs[] = { 0x23'002100, // assert cortex-a8 DBGEN }; // address of cortex-a8 debug regs on debug APB constexpr u32 a8_debug = 0x54011'000;
#include "defs.h" #include "hw-omap3.h" #include "die.h" #include <ftdi.h> /* see usb-blaster-protocol.txt */ #define BLASTER_TCK (1 << 0) #define BLASTER_TMS (1 << 1) #define BLASTER_NCE (1 << 2) #define BLASTER_TDI (1 << 4) #define BLASTER_LED (1 << 5) #define BLASTER_READ (1 << 6) static struct ftdi_context ftdic; static u8 blaster_byte; //-------------- JTAG pin i/o ------------------------------------------------// let static sim_input( u8 mask, bool level ) { int ret; if (level) blaster_byte |= mask; else blaster_byte &= ~mask; ret = ftdi_write_data(&ftdic, &blaster_byte, 1); if (ret != 1) die("ftdi_write_data %d\n", ret); } // JTAG inputs let trst( bool level ) -> void { sim_input( BLASTER_NCE, level ); } let tck( bool level ) -> void { sim_input( BLASTER_TCK, level ); } let tms( bool level ) -> void { sim_input( BLASTER_TMS, level ); } let tdi( bool level ) -> void { sim_input( BLASTER_TDI, level ); } // JTAG output (TDO) let tdo() -> bool { static u8 byte; int ret; do { ret = ftdi_read_data(&ftdic, &byte, 1); } while (ret == 1); if (ret != 0 && ret != 1) die("ftdi_read_data %d\n", ret); return byte & 1; } // RTCK unavailable let rtck() -> bool { return false; } let hw_init() -> void { if (ftdi_init(&ftdic) < 0) die("ftdi_init\n"); if (ftdi_usb_open(&ftdic, 0x09fb, 0x6001) < 0) die("ftdi_usb_open\n"); if (ftdi_usb_reset(&ftdic) < 0) die("ftdi_usb_reset\n"); if (ftdi_set_latency_timer(&ftdic, 2) < 0) die("ftdi_set_latency_timer\n"); ftdi_disable_bitbang(&ftdic); blaster_byte = BLASTER_LED | BLASTER_READ; }