From ddfffa06fbd6afe3a828477700bab754a51b8e13 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Sun, 24 Jul 2022 15:14:27 +0200 Subject: [PATCH] jtagdev, pif, mehfet: refactor device_class ops to be unified under jtagdev instead of using separate implementations --- drivers/jtaglib.c | 197 ++++++++++++++++++++++++++- drivers/jtaglib.h | 17 ++- drivers/jtaglib_defs.h | 5 + drivers/mehfet.c | 301 ++--------------------------------------- drivers/pif.c | 299 ++++------------------------------------ 5 files changed, 248 insertions(+), 571 deletions(-) diff --git a/drivers/jtaglib.c b/drivers/jtaglib.c index ba2b4b2..80b4490 100644 --- a/drivers/jtaglib.c +++ b/drivers/jtaglib.c @@ -35,10 +35,14 @@ */ #include + #include "jtaglib.h" -#include "output.h" #include "jtaglib_defs.h" +#include "output.h" +#include "ctrlc.h" +#include "device.h" + /* Reset target JTAG interface and perform fuse-HW check */ static void jtag_default_reset_tap(struct jtdev *p) { @@ -525,7 +529,7 @@ int jtag_is_fuse_blown (struct jtdev *p) } /*----------------------------------------------------------------------------*/ -int jtag_refresh_bps(const char *module, device_t dev, struct jtdev *p) +int jtag_refresh_bps(device_t dev, struct jtdev *p) { int i; int ret; @@ -536,9 +540,8 @@ int jtag_refresh_bps(const char *module, device_t dev, struct jtdev *p) for (i = 0; i < dev->max_breakpoints; i++) { bp = &dev->breakpoints[i]; - printc_dbg("%s: refresh breakpoint %d: type=%d " - "addr=%04x flags=%04x\n", module, - i, bp->type, bp->addr, bp->flags); + printc_dbg("jtaglib: refresh breakpoint %d: type=%d " + "addr=%04x flags=%04x\n", i, bp->type, bp->addr, bp->flags); if ( (bp->flags & DEVICE_BP_DIRTY) && (bp->type == DEVICE_BPTYPE_BREAK) ) { @@ -549,8 +552,7 @@ int jtag_refresh_bps(const char *module, device_t dev, struct jtdev *p) } if ( jtag_set_breakpoint (p, i, addr) == 0) { - printc_err("%s: failed to refresh " - "breakpoint #%d\n", module, i); + printc_err("jtaglib: failed to refresh breakpoint #%d\n", i); ret = -1; } else { bp->flags &= ~DEVICE_BP_DIRTY; @@ -561,3 +563,184 @@ int jtag_refresh_bps(const char *module, device_t dev, struct jtdev *p) return ret; } +/* ========================================================================= */ + +static int write_ram_word(struct jtdev *p, address_t addr, uint16_t value) +{ + jtag_write_mem(p, 16, addr, value); + + return p->failed ? -1 : 0; +} +static int write_flash_block(struct jtdev *p, address_t addr, + address_t len, const uint8_t *data) +{ + uint16_t* word = malloc( len / 2 * sizeof(*word) ); + if (!word) { + pr_error("jtaglib: failed to allocate memory"); + return -1; + } + + for (unsigned int i = 0; i < len/2; i++) { + word[i] = data[2*i] + (((uint16_t)data[2*i+1]) << 8); + } + jtag_write_flash(p, addr, len/2, word); + + free(word); + + return p->failed ? -1 : 0; +} + +static int read_words(device_t dev_base, const struct chipinfo_memory *m, + address_t addr, address_t len, uint8_t *data) { + struct jtdev *p = (struct jtdev*)dev_base; + + for (unsigned int index = 0; index < len; index += 2) { + unsigned int word = jtag_read_mem(p, 16, addr+index); + data[index ] = word & 0x00ff; + data[index+1] = (word >> 8) & 0x00ff; + } + + return p->failed ? -1 : len; +} +static int write_words(device_t dev_base, const struct chipinfo_memory *m, + address_t addr, address_t len, const uint8_t *data) { + struct jtdev *p = (struct jtdev*)dev_base; + int r; + + if (m->type != CHIPINFO_MEMTYPE_FLASH) { + len = 2; + r = write_ram_word(p, addr, r16le(data)); + } else { + r = write_flash_block(p, addr, len, data); + } + + if (r < 0) { + printc_err("jtaglib: write_words at address 0x%x failed\n", addr); + return -1; + } + + return len;} + +int jtag_dev_readmem(device_t dev_base, address_t addr, uint8_t *mem, address_t len) { + struct jtdev *p = (struct jtdev*)dev_base; + p->failed = 0; + return readmem(dev_base, addr, mem, len, read_words); +} +int jtag_dev_writemem(device_t dev_base, address_t addr, const uint8_t *mem, address_t len) { + struct jtdev *p = (struct jtdev*)dev_base; + p->failed = 0; + return writemem(dev_base, addr, mem, len, write_words, read_words); +} +int jtag_dev_erase(device_t dev_base, device_erase_type_t type, address_t addr) { + struct jtdev *p = (struct jtdev*)dev_base; + + p->failed = 0; + + switch (type) { + case DEVICE_ERASE_MAIN: + jtag_erase_flash(p, JTAG_ERASE_MAIN, addr); + break; + case DEVICE_ERASE_ALL: + jtag_erase_flash(p, JTAG_ERASE_MASS, addr); + break; + case DEVICE_ERASE_SEGMENT: + jtag_erase_flash(p, JTAG_ERASE_SGMT, addr); + break; + default: return -1; + } + + return p->failed ? -1 : 0; +} + +int jtag_dev_getregs(device_t dev_base, address_t *regs) { + struct jtdev *p = (struct jtdev*)dev_base; + + p->failed = 0; + + for (int i = 0; i < DEVICE_NUM_REGS; i++) { + regs[i] = jtag_read_reg(p, i); + } + + return p->failed ? -1 : 0; +} +int jtag_dev_setregs(device_t dev_base, const address_t *regs) { + struct jtdev *p = (struct jtdev*)dev_base; + + p->failed = 0; + + for (int i = 0; i < DEVICE_NUM_REGS; i++) { + jtag_write_reg(p, i, regs[i]); + } + return p->failed ? -1 : 0; +} + +int jtag_dev_ctl(device_t dev_base, device_ctl_t type) { + struct jtdev *p = (struct jtdev*)dev_base; + + p->failed = 0; + + switch (type) { + case DEVICE_CTL_RESET: + /* perform soft reset */ + jtag_execute_puc(p); + break; + + case DEVICE_CTL_RUN: + /* transfer changed breakpoints to device */ + if (jtag_refresh_bps(&p->base, p) < 0) + return -1; + + /* start program execution at current PC */ + jtag_release_device(p, 0xffff); + break; + + case DEVICE_CTL_HALT: + /* take device under JTAG control */ + jtag_get_device(p); + break; + + case DEVICE_CTL_STEP: + /* execute next instruction at current PC */ + jtag_single_step(p); + break; + + default: + printc_err("mehfet: unsupported operation %d\n", type); + return -1; + } + + return p->failed ? -1 : 0; +} +device_status_t jtag_dev_poll(device_t dev_base) { + struct jtdev *p = (struct jtdev*)dev_base; + + if (delay_ms(100) < 0 || ctrlc_check()) + return DEVICE_STATUS_INTR; + + int r = jtag_cpu_state(p); + + if (r == 1) return DEVICE_STATUS_HALTED; + + return DEVICE_STATUS_RUNNING; +} +int jtag_dev_getconfigfuses(device_t dev_base) { + struct jtdev *p = (struct jtdev*)dev_base; + + return jtag_get_config_fuses(p); +} + +int jtag_dev_init(struct jtdev *p) { + unsigned int jtagid = jtag_init(p); + if (p->failed) return -1; + + printc("JTAG ID: 0x%02x\n", jtagid); + // TODO: validate JTAG ID in a better way! + if (jtagid != 0x89 && jtagid != 0x91) { + printc_err("mehfet: unexpected JTAG ID: 0x%02x\n", jtagid); + jtag_release_device(p, 0xfffe); + return -1; + } + + return 0; +} + diff --git a/drivers/jtaglib.h b/drivers/jtaglib.h index 5514df9..a67cc7f 100644 --- a/drivers/jtaglib.h +++ b/drivers/jtaglib.h @@ -40,11 +40,6 @@ #include "jtdev.h" #include "util.h" -/* Flash erasing modes */ -#define JTAG_ERASE_MASS 0xA506 -#define JTAG_ERASE_MAIN 0xA504 -#define JTAG_ERASE_SGMT 0xA502 - /* Colleciton of functions that need different implementation for different * CPU types (that is, 16-bit vs CPUX vs Xv2) */ struct jtaglib_funcs { @@ -167,6 +162,16 @@ uint32_t jtag_default_dr_shift_20(struct jtdev *p, uint32_t dr); void jtag_default_tms_sequence(struct jtdev *p, int bits, unsigned int value); void jtag_default_init_dap(struct jtdev *p); -int jtag_refresh_bps(const char *driver, device_t dev, struct jtdev *p); +int jtag_refresh_bps(device_t dev, struct jtdev *p); + +int jtag_dev_readmem(device_t dev_base, address_t addr, uint8_t *mem, address_t len); +int jtag_dev_writemem(device_t dev_base, address_t addr, const uint8_t *mem, address_t len); +int jtag_dev_getregs(device_t dev_base, address_t *regs); +int jtag_dev_setregs(device_t dev_base, const address_t *regs); +int jtag_dev_ctl(device_t dev_base, device_ctl_t type); +device_status_t jtag_dev_poll(device_t dev_base); +int jtag_dev_erase(device_t dev_base, device_erase_type_t, address_t addr); +int jtag_dev_getconfigfuses(device_t dev_base); +int jtag_dev_init(struct jtdev *p); #endif diff --git a/drivers/jtaglib_defs.h b/drivers/jtaglib_defs.h index 47c8359..127e14d 100644 --- a/drivers/jtaglib_defs.h +++ b/drivers/jtaglib_defs.h @@ -2,6 +2,11 @@ #include "jtaglib.h" #include "eem_defs.h" +/* Flash erasing modes */ +#define JTAG_ERASE_MASS 0xA506 +#define JTAG_ERASE_MAIN 0xA504 +#define JTAG_ERASE_SGMT 0xA502 + /* JTAG identification value for all existing Flash-based MSP430 devices */ #define JTAG_ID_CPU16 0x89 diff --git a/drivers/mehfet.c b/drivers/mehfet.c index 749cbfc..b5489e1 100644 --- a/drivers/mehfet.c +++ b/drivers/mehfet.c @@ -223,257 +223,6 @@ static const struct jtdev_func jtdev_func_mehfet = { }; -/*---------------------------------------------------------------------------*/ - -// TODO: these five are kinda copied from pif.c, should be deduplicated - -static int read_words(device_t dev_base, const struct chipinfo_memory *m, - address_t addr, address_t len, uint8_t *data) -{ -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: read_words: addr=0x%04x, len=0x%x\n", addr, len); -#endif - - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - struct jtdev *p = &dev->jtag; - - for (unsigned int index = 0; index < len; index += 2) { - unsigned int word = jtag_read_mem(p, 16, addr+index); - data[index ] = word & 0x00ff; - data[index+1] = (word >> 8) & 0x00ff; - } - - return p->failed ? -1 : len; -} - -static int write_ram_word(struct jtdev *p, address_t addr, uint16_t value) -{ - jtag_write_mem(p, 16, addr, value); - - return p->failed ? -1 : 0; -} - -static int write_flash_block(struct jtdev *p, address_t addr, - address_t len, const uint8_t *data) -{ - uint16_t* word = malloc( len / 2 * sizeof(*word) ); - if (!word) { - pr_error("mehfet: failed to allocate memory"); - return -1; - } - - for (unsigned int i = 0; i < len/2; i++) { - word[i]=data[2*i] + (((uint16_t)data[2*i+1]) << 8); - } - jtag_write_flash(p, addr, len/2, word); - - free(word); - - return p->failed ? -1 : 0; -} - -/* Write a word-aligned block to any kind of memory. - * returns the number of bytes written or -1 on failure - */ -static int write_words(device_t dev_base, const struct chipinfo_memory *m, - address_t addr, address_t len, const uint8_t *data) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - struct jtdev *p = &dev->jtag; - int r; - - if (m->type != CHIPINFO_MEMTYPE_FLASH) { -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: write_words: addr=0x%04x, len=0x%x data=0x%04x\n", - addr, len, r16le(data)); - if (len != 2) { - printc_dbg("mehfet: WARN: write_words: len != 2! but 0x%04x\n", len); - __builtin_trap(); - } -#endif - len = 2; - r = write_ram_word(p, addr, r16le(data)); - } else { -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: write_flash_block: addr=0x%04x, len=0x%x\n", addr, len); -#endif - r = write_flash_block(p, addr, len, data); - } - - if (r < 0) { - printc_err("mehfet: write_words at address 0x%x failed\n", addr); - return -1; - } - - return len; -} - -/*---------------------------------------------------------------------------*/ - -static int mehfet_readmem(device_t dev_base, address_t addr, - uint8_t *mem, address_t len) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - dev->jtag.failed = 0; - return readmem(dev_base, addr, mem, len, read_words); -} - -static int mehfet_writemem(device_t dev_base, address_t addr, - const uint8_t *mem, address_t len) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - dev->jtag.failed = 0; - return writemem(dev_base, addr, mem, len, write_words, read_words); -} - -static int mehfet_setregs(device_t dev_base, const address_t *regs) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - dev->jtag.failed = 0; - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: set regs\n"); -#endif - for (int i = 0; i < DEVICE_NUM_REGS; i++) { -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: [%d] = 0x%04x\n", i, regs[i]); -#endif - jtag_write_reg(&dev->jtag, i, regs[i]); - } - return dev->jtag.failed ? -1 : 0; -} - -static int mehfet_getregs(device_t dev_base, address_t *regs) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - dev->jtag.failed = 0; - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: get regs\n"); -#endif - for (int i = 0; i < DEVICE_NUM_REGS; i++) { - regs[i] = jtag_read_reg(&dev->jtag, i); -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: [%d] = 0x%04x\n", i, regs[i]); -#endif - } - - return dev->jtag.failed ? -1 : 0; -} - -static int mehfet_ctl(device_t dev_base, device_ctl_t type) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - dev->jtag.failed = 0; - - switch (type) { - case DEVICE_CTL_RESET: - /* perform soft reset */ -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: soft reset (PUC)\n"); -#endif - jtag_execute_puc(&dev->jtag); - break; - - case DEVICE_CTL_RUN: -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: set breakpoints\n"); -#endif - /* transfer changed breakpoints to device */ - if (jtag_refresh_bps("mehfet", &dev->jtag.base, &dev->jtag) < 0) return -1; - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: run @ current PC\n"); -#endif - /* start program execution at current PC */ - jtag_release_device(&dev->jtag, 0xffff); - break; - - case DEVICE_CTL_HALT: -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: halt\n"); -#endif - /* take device under JTAG control */ - jtag_get_device(&dev->jtag); - break; - - case DEVICE_CTL_STEP: -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: single-step\n"); -#endif - /* execute next instruction at current PC */ - jtag_single_step(&dev->jtag); - break; - - default: - printc_err("mehfet: unsupported operation %d\n", type); - return -1; - } - - return dev->jtag.failed ? -1 : 0; -} - -static device_status_t mehfet_poll(device_t dev_base) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - if (delay_ms(100) < 0 || ctrlc_check()) - return DEVICE_STATUS_INTR; - - int r = jtag_cpu_state(&dev->jtag); - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: cpu state: %d\n", r); -#endif - - if (r == 1) return DEVICE_STATUS_HALTED; - - return DEVICE_STATUS_RUNNING; -} - -static int mehfet_erase(device_t dev_base, device_erase_type_t type, - address_t addr) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - dev->jtag.failed = 0; - - switch (type) { - case DEVICE_ERASE_MAIN: - jtag_erase_flash(&dev->jtag, JTAG_ERASE_MAIN, addr); - break; - case DEVICE_ERASE_ALL: - jtag_erase_flash(&dev->jtag, JTAG_ERASE_MASS, addr); - break; - case DEVICE_ERASE_SEGMENT: - jtag_erase_flash(&dev->jtag, JTAG_ERASE_SGMT, addr); - break; - default: return -1; - } - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: erase flash %d at %04x: %s\n", type, addr, dev->jtag.failed ? "failed" : "succeeded"); -#endif - - return dev->jtag.failed ? -1 : 0; -} - -static int mehfet_getconfigfuses(device_t dev_base) -{ - struct mehfet_device* dev = (struct mehfet_device*)dev_base; - - int r = jtag_get_config_fuses(&dev->jtag); - -#ifdef DEBUG_MEHFET_DRIVER - printc_dbg("mehfet: get_config_fuses: %d\n", r); -#endif - - return r; -} - /*---------------------------------------------------------------------------*/ static int check_dev_ok(struct mehfet_device* dev, const struct device_args* args, @@ -529,32 +278,6 @@ static int check_dev_ok(struct mehfet_device* dev, const struct device_args* arg return 0; } -static int init_device(struct mehfet_device* dev) { - printc_dbg("Starting JTAG\n"); - - unsigned int jtagid = jtag_init(&dev->jtag); - if (dev->jtag.failed) return -1; - - printc("JTAG ID: 0x%02x\n", jtagid); - if (jtagid != 0x89 && jtagid != 0x91) { - printc_err("mehfet: unexpected JTAG ID: 0x%02x\n", jtagid); - jtag_release_device(&dev->jtag, 0xfffe); - return -1; - } - - // JTAG fuse check has been performed, so we can now switch to a - // higher-speed physical transport suitable for ~350 kHz TCLK strobes used - // in (and required for) flash programming - int r = mehfet_cmd_set_clkspeed(dev->trans, true); - if (r < 0) { - jtag_release_device(&dev->jtag, 0xfffe); - return -1; - } - - return 0; -} - - static void mehfet_destroy(device_t dev_base) { struct mehfet_device* dev = (struct mehfet_device*)dev_base; @@ -619,7 +342,13 @@ static device_t mehfet_open(const struct device_args* args) { goto FAIL; } - r = init_device(dev); + r = jtag_dev_init(&dev->jtag); + if (r < 0) goto FAIL; + + // JTAG fuse check has been performed, so we can now switch to a + // higher-speed physical transport suitable for ~350 kHz TCLK strobes used + // in (and required for) flash programming + r = mehfet_cmd_set_clkspeed(dev->trans, true); if (r < 0) goto FAIL; #ifdef DEBUG_MEHFET_DRIVER @@ -638,13 +367,13 @@ const struct device_class device_mehfet = { .help = "MehFET USB JTAG/SBW device", .open = mehfet_open, .destroy = mehfet_destroy, - .readmem = mehfet_readmem, - .writemem = mehfet_writemem, - .getregs = mehfet_getregs, - .setregs = mehfet_setregs, - .ctl = mehfet_ctl, - .poll = mehfet_poll, - .erase = mehfet_erase, - .getconfigfuses = mehfet_getconfigfuses + .readmem = jtag_dev_readmem, + .writemem = jtag_dev_writemem, + .getregs = jtag_dev_getregs, + .setregs = jtag_dev_setregs, + .ctl = jtag_dev_ctl, + .poll = jtag_dev_poll, + .erase = jtag_dev_erase, + .getconfigfuses = jtag_dev_getconfigfuses }; diff --git a/drivers/pif.c b/drivers/pif.c index 968fa9a..61ec5a0 100644 --- a/drivers/pif.c +++ b/drivers/pif.c @@ -38,252 +38,7 @@ struct pif_device { struct jtdev jtag; }; -/*============================================================================*/ -/* pif MSP430 JTAG operations */ - /*----------------------------------------------------------------------------*/ -/* Read a word-aligned block from any kind of memory - * returns the number of bytes read or -1 on failure - */ -static int read_words(device_t dev, const struct chipinfo_memory *m, - address_t addr, address_t len, uint8_t *data) -{ - struct pif_device *pif = (struct pif_device *)dev; - struct jtdev *p = &pif->jtag; - unsigned int index; - unsigned int word; - - for ( index = 0; index < len; index += 2 ) { - word = jtag_read_mem( p, 16, addr+index ); - data[index] = word & 0x00ff; - data[index+1] = (word >> 8) & 0x00ff; - } - - return p->failed ? -1 : len; -} - -/*----------------------------------------------------------------------------*/ -/* Write a word to RAM */ -static int write_ram_word( struct jtdev *p, address_t addr, - uint16_t value ) -{ - jtag_write_mem( p, 16, addr, value ); - - return p->failed ? -1 : 0; -} - -/*----------------------------------------------------------------------------*/ -/* Write a word-aligned flash block. */ -/* The starting address must be within the flash memory range. */ - -static int write_flash_block( struct jtdev *p, address_t addr, - address_t len, - const uint8_t *data) -{ - unsigned int i; - uint16_t *word; - - word = malloc( len / 2 * sizeof(*word) ); - if (!word) { - pr_error("pif: failed to allocate memory"); - return -1; - } - - for(i = 0; i < len/2; i++) { - word[i]=data[2*i] + (((uint16_t)data[2*i+1]) << 8); - } - jtag_write_flash( p, addr, len/2, word ); - - free(word); - - return p->failed ? -1 : 0; -} - -/* Write a word-aligned block to any kind of memory. - * returns the number of bytes written or -1 on failure - */ -static int write_words(device_t dev, const struct chipinfo_memory *m, - address_t addr, address_t len, const uint8_t *data) -{ - struct pif_device *pif = (struct pif_device *)dev; - struct jtdev *p = &pif->jtag; - int r; - - if (m->type != CHIPINFO_MEMTYPE_FLASH) { - len = 2; - r = write_ram_word(p, addr, r16le(data)); - } else { - r = write_flash_block(p, addr, len, data); - } - - if (r < 0) { - printc_err("pif: write_words at address 0x%x failed\n", addr); - return -1; - } - - return len; -} - -/*----------------------------------------------------------------------------*/ -static int init_device(struct jtdev *p) -{ - unsigned int jtag_id; - - printc_dbg("Starting JTAG\n"); - jtag_id = jtag_init(p); - printc("JTAG ID: 0x%02x\n", jtag_id); - if (jtag_id != 0x89 && jtag_id != 0x91) { - printc_err("pif: unexpected JTAG ID: 0x%02x\n", jtag_id); - jtag_release_device(p, 0xfffe); - return -1; - } - - return 0; -} - -/*===== MSPDebug Device interface ============================================*/ - -/*----------------------------------------------------------------------------*/ -static int pif_readmem( device_t dev_base, - address_t addr, - uint8_t* mem, - address_t len ) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - dev->jtag.failed = 0; - return readmem(dev_base, addr, mem, len, read_words); -} - -/*----------------------------------------------------------------------------*/ -static int pif_writemem( device_t dev_base, - address_t addr, - const uint8_t* mem, - address_t len ) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - dev->jtag.failed = 0; - return writemem(dev_base, addr, mem, len, write_words, read_words); -} - -/*----------------------------------------------------------------------------*/ -static int pif_getregs(device_t dev_base, address_t *regs) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - int i; - - dev->jtag.failed = 0; - - for (i = 0; i < DEVICE_NUM_REGS; i++) - regs[i] = jtag_read_reg(&dev->jtag, i); - - return dev->jtag.failed ? -1 : 0; -} - -/*----------------------------------------------------------------------------*/ -static int pif_setregs( device_t dev_base, const address_t* regs ) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - int i; - - dev->jtag.failed = 0; - - for (i = 0; i < DEVICE_NUM_REGS; i++) { - jtag_write_reg( &dev->jtag, i, regs[i] ); - } - return dev->jtag.failed ? -1 : 0; -} - -/*----------------------------------------------------------------------------*/ -static int pif_ctl(device_t dev_base, device_ctl_t type) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - - dev->jtag.failed = 0; - - switch (type) { - case DEVICE_CTL_RESET: - /* perform soft reset */ - jtag_execute_puc(&dev->jtag); - break; - - case DEVICE_CTL_RUN: - /* transfer changed breakpoints to device */ - if (jtag_refresh_bps("pif", &dev->jtag.base, &dev->jtag) < 0) { - return -1; - } - /* start program execution at current PC */ - jtag_release_device(&dev->jtag, 0xffff); - break; - - case DEVICE_CTL_HALT: - /* take device under JTAG control */ - jtag_get_device(&dev->jtag); - break; - - case DEVICE_CTL_STEP: - /* execute next instruction at current PC */ - jtag_single_step(&dev->jtag); - break; - - default: - printc_err("pif: unsupported operation\n"); - return -1; - } - - return dev->jtag.failed ? -1 : 0; -} - -/*----------------------------------------------------------------------------*/ -static device_status_t pif_poll(device_t dev_base) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - - if (delay_ms(100) < 0 || ctrlc_check()) - return DEVICE_STATUS_INTR; - - if (jtag_cpu_state(&dev->jtag) == 1) { - return DEVICE_STATUS_HALTED; - } - - return DEVICE_STATUS_RUNNING; -} - -/*----------------------------------------------------------------------------*/ -static int pif_erase( device_t dev_base, - device_erase_type_t type, - address_t addr ) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - - dev->jtag.failed = 0; - - switch(type) { - case DEVICE_ERASE_MAIN: - jtag_erase_flash ( &dev->jtag, JTAG_ERASE_MAIN, addr ); - break; - case DEVICE_ERASE_ALL: - jtag_erase_flash ( &dev->jtag, JTAG_ERASE_MASS, addr ); - break; - case DEVICE_ERASE_SEGMENT: - jtag_erase_flash ( &dev->jtag, JTAG_ERASE_SGMT, addr ); - break; - default: - return -1; - } - - return dev->jtag.failed ? -1 : 0; -} - -/*----------------------------------------------------------------------------*/ -static int pif_getconfigfuses(device_t dev_base) -{ - struct pif_device *dev = (struct pif_device *)dev_base; - - return jtag_get_config_fuses(&dev->jtag); -} - -/*----------------------------------------------------------------------------*/ - static device_t pif_open(const struct device_args *args) { @@ -317,7 +72,7 @@ static device_t pif_open(const struct device_args *args) return NULL; } - if (init_device(&dev->jtag) < 0) { + if (jtag_dev_init(&dev->jtag) < 0) { printc_err("pif: initialization failed\n"); free(dev); return NULL; @@ -360,7 +115,7 @@ static device_t gpio_open(const struct device_args *args) return NULL; } - if (init_device(&dev->jtag) < 0) { + if (jtag_dev_init(&dev->jtag) < 0) { printc_err("gpio: initialization failed\n"); free(dev); return NULL; @@ -404,7 +159,7 @@ static device_t bp_open(const struct device_args *args) return NULL; } - if (init_device(&dev->jtag) < 0) { + if (jtag_dev_init(&dev->jtag) < 0) { printc_err("bp: initialization failed\n"); free(dev); return NULL; @@ -431,14 +186,14 @@ const struct device_class device_pif = { .help = "Parallel Port JTAG", .open = pif_open, .destroy = pif_destroy, - .readmem = pif_readmem, - .writemem = pif_writemem, - .getregs = pif_getregs, - .setregs = pif_setregs, - .ctl = pif_ctl, - .poll = pif_poll, - .erase = pif_erase, - .getconfigfuses = pif_getconfigfuses + .readmem = jtag_dev_readmem, + .writemem = jtag_dev_writemem, + .getregs = jtag_dev_getregs, + .setregs = jtag_dev_setregs, + .ctl = jtag_dev_ctl, + .poll = jtag_dev_poll, + .erase = jtag_dev_erase, + .getconfigfuses = jtag_dev_getconfigfuses }; const struct device_class device_gpio = { @@ -446,14 +201,14 @@ const struct device_class device_gpio = { .help = "/sys/class/gpio direct connect", .open = gpio_open, .destroy = pif_destroy, - .readmem = pif_readmem, - .writemem = pif_writemem, - .getregs = pif_getregs, - .setregs = pif_setregs, - .ctl = pif_ctl, - .poll = pif_poll, - .erase = pif_erase, - .getconfigfuses = pif_getconfigfuses + .readmem = jtag_dev_readmem, + .writemem = jtag_dev_writemem, + .getregs = jtag_dev_getregs, + .setregs = jtag_dev_setregs, + .ctl = jtag_dev_ctl, + .poll = jtag_dev_poll, + .erase = jtag_dev_erase, + .getconfigfuses = jtag_dev_getconfigfuses }; const struct device_class device_bp = { @@ -461,12 +216,12 @@ const struct device_class device_bp = { .help = "Bus Pirate JTAG, MISO-TDO, MOSI-TDI, CS-TMS, AUX-RESET, CLK-TCK", .open = bp_open, .destroy = pif_destroy, - .readmem = pif_readmem, - .writemem = pif_writemem, - .getregs = pif_getregs, - .setregs = pif_setregs, - .ctl = pif_ctl, - .poll = pif_poll, - .erase = pif_erase, - .getconfigfuses = pif_getconfigfuses + .readmem = jtag_dev_readmem, + .writemem = jtag_dev_writemem, + .getregs = jtag_dev_getregs, + .setregs = jtag_dev_setregs, + .ctl = jtag_dev_ctl, + .poll = jtag_dev_poll, + .erase = jtag_dev_erase, + .getconfigfuses = jtag_dev_getconfigfuses };