Add a function to the device struct to handle config fuses.

Also provide a getconfigfuses implementation for the pif based drivers (pif
and gpio).
This commit is contained in:
Alex Orange 2017-06-14 13:28:07 -06:00
parent 33cd9ba4cd
commit 8a1afe6c91
15 changed files with 176 additions and 109 deletions

View File

@ -411,5 +411,6 @@ const struct device_class device_bsl = {
.getregs = bsl_getregs, .getregs = bsl_getregs,
.setregs = bsl_setregs, .setregs = bsl_setregs,
.ctl = bsl_ctl, .ctl = bsl_ctl,
.poll = bsl_poll .poll = bsl_poll,
.getconfigfuses = NULL
}; };

View File

@ -212,6 +212,9 @@ int device_probe_id(device_t dev, const char *force_id)
id.fab = data[3]; id.fab = data[3];
id.self = r16le(data + 8); id.self = r16le(data + 8);
id.config = data[13] & 0x7f; id.config = data[13] & 0x7f;
if(dev->type->getconfigfuses != NULL) {
id.fuses = dev->type->getconfigfuses(dev);
}
} }
printc_dbg("Chip ID data:\n"); printc_dbg("Chip ID data:\n");
@ -221,7 +224,7 @@ int device_probe_id(device_t dev, const char *force_id)
printc_dbg(" fab: %02x\n", id.fab); printc_dbg(" fab: %02x\n", id.fab);
printc_dbg(" self: %04x\n", id.self); printc_dbg(" self: %04x\n", id.self);
printc_dbg(" config: %02x\n", id.config); printc_dbg(" config: %02x\n", id.config);
//printc_dbg(" fuses: %02x\n", id.fuses); printc_dbg(" fuses: %02x\n", id.fuses);
//printc_dbg(" activation_key: %08x\n", id.activation_key); //printc_dbg(" activation_key: %08x\n", id.activation_key);
dev->chip = chipinfo_find_by_id(&id); dev->chip = chipinfo_find_by_id(&id);

View File

@ -117,6 +117,9 @@ struct device_class {
/* Wait a little while for the CPU to change state */ /* Wait a little while for the CPU to change state */
device_status_t (*poll)(device_t dev); device_status_t (*poll)(device_t dev);
/* Get the configuration fuse values */
int (*getconfigfuses)(device_t dev);
}; };
struct device { struct device {

View File

@ -63,7 +63,8 @@ const struct device_class device_rf2500 = {
.getregs = fet_getregs, .getregs = fet_getregs,
.setregs = fet_setregs, .setregs = fet_setregs,
.ctl = fet_ctl, .ctl = fet_ctl,
.poll = fet_poll .poll = fet_poll,
.getconfigfuses = NULL
}; };
static device_t fet_open_olimex_iso_mk2(const struct device_args *args) static device_t fet_open_olimex_iso_mk2(const struct device_args *args)
@ -125,7 +126,8 @@ const struct device_class device_olimex_iso_mk2 = {
.getregs = fet_getregs, .getregs = fet_getregs,
.setregs = fet_setregs, .setregs = fet_setregs,
.ctl = fet_ctl, .ctl = fet_ctl,
.poll = fet_poll .poll = fet_poll,
.getconfigfuses = NULL
}; };
static device_t fet_open_olimex(const struct device_args *args) static device_t fet_open_olimex(const struct device_args *args)
@ -160,7 +162,8 @@ const struct device_class device_olimex = {
.getregs = fet_getregs, .getregs = fet_getregs,
.setregs = fet_setregs, .setregs = fet_setregs,
.ctl = fet_ctl, .ctl = fet_ctl,
.poll = fet_poll .poll = fet_poll,
.getconfigfuses = NULL
}; };
static device_t fet_open_olimex_v1(const struct device_args *args) static device_t fet_open_olimex_v1(const struct device_args *args)
@ -230,7 +233,8 @@ const struct device_class device_olimex_iso = {
.getregs = fet_getregs, .getregs = fet_getregs,
.setregs = fet_setregs, .setregs = fet_setregs,
.ctl = fet_ctl, .ctl = fet_ctl,
.poll = fet_poll .poll = fet_poll,
.getconfigfuses = NULL
}; };
static device_t fet_open_uif(const struct device_args *args) static device_t fet_open_uif(const struct device_args *args)
@ -260,5 +264,6 @@ const struct device_class device_uif = {
.getregs = fet_getregs, .getregs = fet_getregs,
.setregs = fet_setregs, .setregs = fet_setregs,
.ctl = fet_ctl, .ctl = fet_ctl,
.poll = fet_poll .poll = fet_poll,
.getconfigfuses = NULL
}; };

View File

@ -309,5 +309,6 @@ const struct device_class device_ezfet = {
.setregs = fet3_setregs, .setregs = fet3_setregs,
.ctl = fet3_ctl, .ctl = fet3_ctl,
.poll = fet3_poll, .poll = fet3_poll,
.erase = fet3_erase .erase = fet3_erase,
.getconfigfuses = NULL
}; };

View File

@ -665,5 +665,6 @@ const struct device_class device_flash_bsl = {
.setregs = flash_bsl_setregs, .setregs = flash_bsl_setregs,
.ctl = flash_bsl_ctl, .ctl = flash_bsl_ctl,
.poll = flash_bsl_poll, .poll = flash_bsl_poll,
.erase = flash_bsl_erase .erase = flash_bsl_erase,
.getconfigfuses = NULL
}; };

View File

@ -472,5 +472,6 @@ const struct device_class device_gdbc = {
.getregs = gdbc_getregs, .getregs = gdbc_getregs,
.setregs = gdbc_setregs, .setregs = gdbc_setregs,
.ctl = gdbc_ctl, .ctl = gdbc_ctl,
.poll = gdbc_poll .poll = gdbc_poll,
.getconfigfuses = NULL
}; };

View File

@ -580,5 +580,6 @@ const struct device_class device_goodfet = {
.setregs = goodfet_setregs, .setregs = goodfet_setregs,
.ctl = goodfet_ctl, .ctl = goodfet_ctl,
.poll = goodfet_poll, .poll = goodfet_poll,
.erase = goodfet_erase .erase = goodfet_erase,
.getconfigfuses = NULL
}; };

View File

@ -60,6 +60,8 @@
/* Instructions for the JTAG Fuse */ /* Instructions for the JTAG Fuse */
#define IR_PREPARE_BLOW 0x44 /* 0x22 */ #define IR_PREPARE_BLOW 0x44 /* 0x22 */
#define IR_EX_BLOW 0x24 /* 0x24 */ #define IR_EX_BLOW 0x24 /* 0x24 */
/* Instructions for the Configuration Fuse */
#define IR_CONFIG_FUSES 0x94
/* Bypass instruction */ /* Bypass instruction */
#define IR_BYPASS 0xFF /* 0xFF */ #define IR_BYPASS 0xFF /* 0xFF */
/* Instructions for the EEM */ /* Instructions for the EEM */
@ -203,11 +205,37 @@ static unsigned int jtag_ir_shift(struct jtdev *p, unsigned int instruction)
/* JTAG state = Run-Test/Idle */ /* JTAG state = Run-Test/Idle */
} }
/* Shifts a given 8-bit byte into the JTAG data register through TDI.
* data : 8 bit data
* return: scanned TDO value
*/
static unsigned int jtag_dr_shift_8(struct jtdev *p, unsigned int data)
{
/* JTAG state = Run-Test/Idle */
jtag_tms_set(p);
jtag_tck_clr(p);
jtag_tck_set(p);
/* JTAG state = Select DR-Scan */
jtag_tms_clr(p);
jtag_tck_clr(p);
jtag_tck_set(p);
/* JTAG state = Capture-DR */
jtag_tck_clr(p);
jtag_tck_set(p);
/* JTAG state = Shift-DR, Shift in TDI (16-bit) */
return jtag_shift(p, 8, data);
/* JTAG state = Run-Test/Idle */
}
/* Shifts a given 16-bit word into the JTAG data register through TDI. /* Shifts a given 16-bit word into the JTAG data register through TDI.
* data : 16 bit data * data : 16 bit data
* return: scanned TDO value * return: scanned TDO value
*/ */
static unsigned int jtag_dr_shift(struct jtdev *p, unsigned int data) static unsigned int jtag_dr_shift_16(struct jtdev *p, unsigned int data)
{ {
/* JTAG state = Run-Test/Idle */ /* JTAG state = Run-Test/Idle */
jtag_tms_set(p); jtag_tms_set(p);
@ -242,10 +270,10 @@ static int jtag_set_instruction_fetch(struct jtdev *p)
* timeout after limited attempts * timeout after limited attempts
*/ */
for (loop_counter = 50; loop_counter > 0; loop_counter--) { for (loop_counter = 50; loop_counter > 0; loop_counter--) {
if ((jtag_dr_shift(p, 0x0000) & 0x0080) == 0x0080) if ((jtag_dr_shift_16(p, 0x0000) & 0x0080) == 0x0080)
return 1; return 1;
jtag_tclk_clr(p); /* The TCLK pulse befor jtag_dr_shift leads to */ jtag_tclk_clr(p); /* The TCLK pulse befor jtag_dr_shift_16 leads to */
jtag_tclk_set(p); /* problems at MEM_QUICK_READ, it's from SLAU265 */ jtag_tclk_set(p); /* problems at MEM_QUICK_READ, it's from SLAU265 */
} }
@ -263,17 +291,17 @@ static void jtag_halt_cpu(struct jtdev *p)
/* Set device into JTAG mode + read */ /* Set device into JTAG mode + read */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
/* Send JMP $ instruction to keep CPU from changing the state */ /* Send JMP $ instruction to keep CPU from changing the state */
jtag_ir_shift(p, IR_DATA_16BIT); jtag_ir_shift(p, IR_DATA_16BIT);
jtag_dr_shift(p, 0x3FFF); jtag_dr_shift_16(p, 0x3FFF);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* Set JTAG_HALT bit */ /* Set JTAG_HALT bit */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2409); jtag_dr_shift_16(p, 0x2409);
jtag_tclk_set(p); jtag_tclk_set(p);
} }
@ -284,7 +312,7 @@ static void jtag_release_cpu(struct jtdev *p)
/* clear the HALT_JTAG bit */ /* clear the HALT_JTAG bit */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_ir_shift(p, IR_ADDR_CAPTURE); jtag_ir_shift(p, IR_ADDR_CAPTURE);
jtag_tclk_set(p); jtag_tclk_set(p);
} }
@ -313,13 +341,13 @@ static int jtag_verify_psa(struct jtdev *p,
jtag_execute_puc(p); jtag_execute_puc(p);
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_set_instruction_fetch(p); jtag_set_instruction_fetch(p);
jtag_ir_shift(p, IR_DATA_16BIT); jtag_ir_shift(p, IR_DATA_16BIT);
jtag_dr_shift(p, 0x4030); jtag_dr_shift_16(p, 0x4030);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_dr_shift(p, start_address-2); jtag_dr_shift_16(p, start_address-2);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
@ -327,7 +355,7 @@ static int jtag_verify_psa(struct jtdev *p,
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_ir_shift(p, IR_ADDR_CAPTURE); jtag_ir_shift(p, IR_ADDR_CAPTURE);
jtag_dr_shift(p, 0x0000); jtag_dr_shift_16(p, 0x0000);
jtag_ir_shift(p, IR_DATA_PSA); jtag_ir_shift(p, IR_DATA_PSA);
for (index = 0; index < length; index++) { for (index = 0; index < length; index++) {
@ -369,7 +397,7 @@ static int jtag_verify_psa(struct jtdev *p,
/* Read out the PSA value */ /* Read out the PSA value */
jtag_ir_shift(p, IR_SHIFT_OUT_PSA); jtag_ir_shift(p, IR_SHIFT_OUT_PSA);
psa_value = jtag_dr_shift(p, 0x0000); psa_value = jtag_dr_shift_16(p, 0x0000);
jtag_tclk_set(p); jtag_tclk_set(p);
return (psa_value == psa_crc) ? 1 : 0; return (psa_value == psa_crc) ? 1 : 0;
@ -436,14 +464,14 @@ unsigned int jtag_get_device(struct jtdev *p)
/* Set device into JTAG mode + read */ /* Set device into JTAG mode + read */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
/* Wait until CPU is synchronized, /* Wait until CPU is synchronized,
* timeout after a limited number of attempts * timeout after a limited number of attempts
*/ */
jtag_id = jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE); jtag_id = jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
for ( loop_counter = 50; loop_counter > 0; loop_counter--) { for ( loop_counter = 50; loop_counter > 0; loop_counter--) {
if ( (jtag_dr_shift(p, 0x0000) & 0x0200) == 0x0200 ) { if ( (jtag_dr_shift_16(p, 0x0000) & 0x0200) == 0x0200 ) {
break; break;
} }
} }
@ -491,20 +519,20 @@ uint16_t jtag_read_mem(struct jtdev *p,
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
if (format == 16) { if (format == 16) {
/* set word read */ /* set word read */
jtag_dr_shift(p, 0x2409); jtag_dr_shift_16(p, 0x2409);
} else { } else {
/* set byte read */ /* set byte read */
jtag_dr_shift(p, 0x2419); jtag_dr_shift_16(p, 0x2419);
} }
/* set address */ /* set address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, address); jtag_dr_shift_16(p, address);
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* shift out 16 bits */ /* shift out 16 bits */
content = jtag_dr_shift(p, 0x0000); content = jtag_dr_shift_16(p, 0x0000);
jtag_tclk_set(p); /* is also the first instruction in jtag_release_cpu() */ jtag_tclk_set(p); /* is also the first instruction in jtag_release_cpu() */
jtag_release_cpu(p); jtag_release_cpu(p);
if (format == 8) if (format == 8)
@ -532,14 +560,14 @@ void jtag_read_mem_quick(struct jtdev *p,
/* set RW to read */ /* set RW to read */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2409); jtag_dr_shift_16(p, 0x2409);
jtag_ir_shift(p, IR_DATA_QUICK); jtag_ir_shift(p, IR_DATA_QUICK);
for (index = 0; index < length; index++) { for (index = 0; index < length; index++) {
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* shift out the data from the target */ /* shift out the data from the target */
data[index] = jtag_dr_shift(p, 0x0000); data[index] = jtag_dr_shift_16(p, 0x0000);
} }
jtag_tclk_set(p); jtag_tclk_set(p);
@ -562,19 +590,19 @@ void jtag_write_mem(struct jtdev *p,
if (format == 16) if (format == 16)
/* Set word write */ /* Set word write */
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
else else
/* Set byte write */ /* Set byte write */
jtag_dr_shift(p, 0x2418); jtag_dr_shift_16(p, 0x2418);
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
/* Set addr */ /* Set addr */
jtag_dr_shift(p, address); jtag_dr_shift_16(p, address);
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
/* Shift in 16 bits */ /* Shift in 16 bits */
jtag_dr_shift(p, data); jtag_dr_shift_16(p, data);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_release_cpu(p); jtag_release_cpu(p);
} }
@ -598,12 +626,12 @@ void jtag_write_mem_quick(struct jtdev *p,
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
/* Set RW to write */ /* Set RW to write */
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
jtag_ir_shift(p, IR_DATA_QUICK); jtag_ir_shift(p, IR_DATA_QUICK);
for (index = 0; index < length; index++) { for (index = 0; index < length; index++) {
/* Write data */ /* Write data */
jtag_dr_shift(p, data[index]); jtag_dr_shift_16(p, data[index]);
/* Increment PC by 2 */ /* Increment PC by 2 */
jtag_tclk_set(p); jtag_tclk_set(p);
@ -625,7 +653,7 @@ int jtag_is_fuse_blown (struct jtdev *p)
/* First trial could be wrong */ /* First trial could be wrong */
for (loop_counter = 3; loop_counter > 0; loop_counter--) { for (loop_counter = 3; loop_counter > 0; loop_counter--) {
jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE); jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
if (jtag_dr_shift(p, 0xAAAA) == 0x5555) if (jtag_dr_shift_16(p, 0xAAAA) == 0x5555)
/* Fuse is blown */ /* Fuse is blown */
return 1; return 1;
} }
@ -644,8 +672,8 @@ unsigned int jtag_execute_puc(struct jtdev *p)
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
/* Apply and remove reset */ /* Apply and remove reset */
jtag_dr_shift(p, 0x2C01); jtag_dr_shift_16(p, 0x2C01);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
@ -681,8 +709,8 @@ void jtag_release_device(struct jtdev *p, address_t address)
jtag_set_breakpoint(p,-1,0); jtag_set_breakpoint(p,-1,0);
/* issue reset */ /* issue reset */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2C01); jtag_dr_shift_16(p, 0x2C01);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
break; break;
default: /* Set target CPU's PC */ default: /* Set target CPU's PC */
jtag_write_reg(p, 0, address); jtag_write_reg(p, 0, address);
@ -692,11 +720,11 @@ void jtag_release_device(struct jtdev *p, address_t address)
jtag_set_instruction_fetch(p); jtag_set_instruction_fetch(p);
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
jtag_dr_shift(p, BREAKREACT + READ); jtag_dr_shift_16(p, BREAKREACT + READ);
jtag_dr_shift(p, 0x0000); jtag_dr_shift_16(p, 0x0000);
jtag_ir_shift(p, IR_EMEX_WRITE_CONTROL); jtag_ir_shift(p, IR_EMEX_WRITE_CONTROL);
jtag_dr_shift(p, 0x000f); jtag_dr_shift_16(p, 0x000f);
jtag_ir_shift(p, IR_CNTRL_SIG_RELEASE); jtag_ir_shift(p, IR_CNTRL_SIG_RELEASE);
} }
@ -746,56 +774,56 @@ void jtag_write_flash(struct jtdev *p,
/* Set RW to write */ /* Set RW to write */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
/* FCTL1 register */ /* FCTL1 register */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x0128); jtag_dr_shift_16(p, 0x0128);
/* Enable FLASH write */ /* Enable FLASH write */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA540); jtag_dr_shift_16(p, 0xA540);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* FCTL2 register */ /* FCTL2 register */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x012A); jtag_dr_shift_16(p, 0x012A);
/* Select MCLK as source, DIV=1 */ /* Select MCLK as source, DIV=1 */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA540); jtag_dr_shift_16(p, 0xA540);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* FCTL3 register */ /* FCTL3 register */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x012C); jtag_dr_shift_16(p, 0x012C);
/* Clear FCTL3 register */ /* Clear FCTL3 register */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA500); jtag_dr_shift_16(p, 0xA500);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
for (index = 0; index < length; index++) { for (index = 0; index < length; index++) {
/* Set RW to write */ /* Set RW to write */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
/* Set address */ /* Set address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, address); jtag_dr_shift_16(p, address);
/* Set data */ /* Set data */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, data[index]); jtag_dr_shift_16(p, data[index]);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* Set RW to read */ /* Set RW to read */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2409); jtag_dr_shift_16(p, 0x2409);
/* provide TCLKs /* provide TCLKs
* min. 33 for F149 and F449 * min. 33 for F149 and F449
@ -809,15 +837,15 @@ void jtag_write_flash(struct jtdev *p,
/* Set RW to write */ /* Set RW to write */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
/* FCTL1 register */ /* FCTL1 register */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x0128); jtag_dr_shift_16(p, 0x0128);
/* Disable FLASH write */ /* Disable FLASH write */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA500); jtag_dr_shift_16(p, 0xA500);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_release_cpu(p); jtag_release_cpu(p);
@ -853,66 +881,66 @@ void jtag_erase_flash(struct jtdev *p,
/* Set RW to write */ /* Set RW to write */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
/* FCTL1 address */ /* FCTL1 address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x0128); jtag_dr_shift_16(p, 0x0128);
/* Enable erase mode */ /* Enable erase mode */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, erase_mode); jtag_dr_shift_16(p, erase_mode);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* FCTL2 address */ /* FCTL2 address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x012A); jtag_dr_shift_16(p, 0x012A);
/* MCLK is source, DIV=1 */ /* MCLK is source, DIV=1 */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA540); jtag_dr_shift_16(p, 0xA540);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* FCTL3 address */ /* FCTL3 address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x012C); jtag_dr_shift_16(p, 0x012C);
/* Clear FCTL3 */ /* Clear FCTL3 */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA500); jtag_dr_shift_16(p, 0xA500);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* Set erase address */ /* Set erase address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, erase_address); jtag_dr_shift_16(p, erase_address);
/* Dummy write to start erase */ /* Dummy write to start erase */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0x55AA); jtag_dr_shift_16(p, 0x55AA);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* Set RW to read */ /* Set RW to read */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2409); jtag_dr_shift_16(p, 0x2409);
/* provide TCLKs */ /* provide TCLKs */
p->f->jtdev_tclk_strobe(p, number_of_strobes); p->f->jtdev_tclk_strobe(p, number_of_strobes);
/* Set RW to write */ /* Set RW to write */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2408); jtag_dr_shift_16(p, 0x2408);
/* FCTL1 address */ /* FCTL1 address */
jtag_ir_shift(p, IR_ADDR_16BIT); jtag_ir_shift(p, IR_ADDR_16BIT);
jtag_dr_shift(p, 0x0128); jtag_dr_shift_16(p, 0x0128);
/* Disable erase */ /* Disable erase */
jtag_ir_shift(p, IR_DATA_TO_ADDR); jtag_ir_shift(p, IR_DATA_TO_ADDR);
jtag_dr_shift(p, 0xA500); jtag_dr_shift_16(p, 0xA500);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_release_cpu(p); jtag_release_cpu(p);
} }
@ -927,7 +955,7 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
/* CPU controls RW & BYTE */ /* CPU controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x3401); jtag_dr_shift_16(p, 0x3401);
/* Set CPU into instruction fetch mode */ /* Set CPU into instruction fetch mode */
jtag_set_instruction_fetch(p); jtag_set_instruction_fetch(p);
@ -937,7 +965,7 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
/* "jmp $-4" instruction */ /* "jmp $-4" instruction */
/* PC - 4 -> PC */ /* PC - 4 -> PC */
/* needs 2 clock cycles */ /* needs 2 clock cycles */
jtag_dr_shift(p, 0x3ffd); jtag_dr_shift_16(p, 0x3ffd);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
@ -950,10 +978,10 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
* it's a ROM address, write has no effect, but * it's a ROM address, write has no effect, but
* the registers value is placed on the databus * the registers value is placed on the databus
*/ */
jtag_dr_shift(p, 0x4082 | (((unsigned int)reg << 8) & 0x0f00) ); jtag_dr_shift_16(p, 0x4082 | (((unsigned int)reg << 8) & 0x0f00) );
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_dr_shift(p, 0x01fe); jtag_dr_shift_16(p, 0x01fe);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
@ -963,11 +991,11 @@ address_t jtag_read_reg(struct jtdev *p, int reg)
/* Read databus which contains the registers value */ /* Read databus which contains the registers value */
jtag_ir_shift(p, IR_DATA_CAPTURE); jtag_ir_shift(p, IR_DATA_CAPTURE);
value = jtag_dr_shift(p, 0x0000); value = jtag_dr_shift_16(p, 0x0000);
/* JTAG controls RW & BYTE */ /* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_tclk_set(p); jtag_tclk_set(p);
@ -980,7 +1008,7 @@ void jtag_write_reg(struct jtdev *p, int reg, address_t value)
{ {
/* CPU controls RW & BYTE */ /* CPU controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x3401); jtag_dr_shift_16(p, 0x3401);
/* Set CPU into instruction fetch mode */ /* Set CPU into instruction fetch mode */
jtag_set_instruction_fetch(p); jtag_set_instruction_fetch(p);
@ -990,7 +1018,7 @@ void jtag_write_reg(struct jtdev *p, int reg, address_t value)
/* "jmp $-4" instruction */ /* "jmp $-4" instruction */
/* PC - 4 -> PC */ /* PC - 4 -> PC */
/* needs 4 clock cycles */ /* needs 4 clock cycles */
jtag_dr_shift(p, 0x3ffd); jtag_dr_shift_16(p, 0x3ffd);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
@ -1001,16 +1029,16 @@ void jtag_write_reg(struct jtdev *p, int reg, address_t value)
* PC is advanced 4 bytes by this instruction * PC is advanced 4 bytes by this instruction
* needs 2 clock cycles * needs 2 clock cycles
*/ */
jtag_dr_shift(p, 0x4030 | (reg & 0x000f) ); jtag_dr_shift_16(p, 0x4030 | (reg & 0x000f) );
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_dr_shift(p, value); jtag_dr_shift_16(p, value);
jtag_tclk_set(p); jtag_tclk_set(p);
jtag_tclk_clr(p); jtag_tclk_clr(p);
/* JTAG controls RW & BYTE */ /* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
jtag_tclk_set(p); jtag_tclk_set(p);
} }
@ -1022,7 +1050,7 @@ void jtag_single_step( struct jtdev *p )
/* CPU controls RW & BYTE */ /* CPU controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x3401); jtag_dr_shift_16(p, 0x3401);
/* clock CPU until next instruction fetch cycle */ /* clock CPU until next instruction fetch cycle */
/* failure after 10 clock cycles */ /* failure after 10 clock cycles */
@ -1031,14 +1059,14 @@ void jtag_single_step( struct jtdev *p )
for (loop_counter = 10; loop_counter > 0; loop_counter--) { for (loop_counter = 10; loop_counter > 0; loop_counter--) {
jtag_tclk_clr(p); jtag_tclk_clr(p);
jtag_tclk_set(p); jtag_tclk_set(p);
if ((jtag_dr_shift(p, 0x0000) & 0x0080) == 0x0080) { if ((jtag_dr_shift_16(p, 0x0000) & 0x0080) == 0x0080) {
break; break;
} }
} }
/* JTAG controls RW & BYTE */ /* JTAG controls RW & BYTE */
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT); jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
jtag_dr_shift(p, 0x2401); jtag_dr_shift_16(p, 0x2401);
if (loop_counter == 0) { if (loop_counter == 0) {
/* timeout reached */ /* timeout reached */
@ -1071,42 +1099,42 @@ unsigned int jtag_set_breakpoint( struct jtdev *p,int bp_num, address_t bp_addr
/* disable all breakpoints by deleting the BREAKREACT /* disable all breakpoints by deleting the BREAKREACT
* register */ * register */
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
jtag_dr_shift(p, BREAKREACT + WRITE); jtag_dr_shift_16(p, BREAKREACT + WRITE);
jtag_dr_shift(p, 0x0000); jtag_dr_shift_16(p, 0x0000);
return 1; return 1;
} }
/* set breakpoint */ /* set breakpoint */
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE);
jtag_dr_shift(p, GENCTRL + WRITE); jtag_dr_shift_16(p, GENCTRL + WRITE);
jtag_dr_shift(p, EEM_EN + CLEAR_STOP + EMU_CLK_EN + EMU_FEAT_EN); jtag_dr_shift_16(p, EEM_EN + CLEAR_STOP + EMU_CLK_EN + EMU_FEAT_EN);
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
jtag_dr_shift(p, 8*bp_num + MBTRIGxVAL + WRITE); jtag_dr_shift_16(p, 8*bp_num + MBTRIGxVAL + WRITE);
jtag_dr_shift(p, bp_addr); jtag_dr_shift_16(p, bp_addr);
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
jtag_dr_shift(p, 8*bp_num + MBTRIGxCTL + WRITE); jtag_dr_shift_16(p, 8*bp_num + MBTRIGxCTL + WRITE);
jtag_dr_shift(p, MAB + TRIG_0 + CMP_EQUAL); jtag_dr_shift_16(p, MAB + TRIG_0 + CMP_EQUAL);
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
jtag_dr_shift(p, 8*bp_num + MBTRIGxMSK + WRITE); jtag_dr_shift_16(p, 8*bp_num + MBTRIGxMSK + WRITE);
jtag_dr_shift(p, NO_MASK); jtag_dr_shift_16(p, NO_MASK);
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
jtag_dr_shift(p, 8*bp_num + MBTRIGxCMB + WRITE); jtag_dr_shift_16(p, 8*bp_num + MBTRIGxCMB + WRITE);
jtag_dr_shift(p, 1<<bp_num); jtag_dr_shift_16(p, 1<<bp_num);
/* read the actual setting of the BREAKREACT register */ /* read the actual setting of the BREAKREACT register */
/* while reading a 1 is automatically shifted into LSB */ /* while reading a 1 is automatically shifted into LSB */
/* this will be undone and the bit for the new breakpoint set */ /* this will be undone and the bit for the new breakpoint set */
/* then the updated value is stored back */ /* then the updated value is stored back */
jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed jtag_ir_shift(p, IR_EMEX_DATA_EXCHANGE); //repeating may not needed
breakreact = jtag_dr_shift(p, BREAKREACT + READ); breakreact = jtag_dr_shift_16(p, BREAKREACT + READ);
breakreact += jtag_dr_shift(p, 0x000); breakreact += jtag_dr_shift_16(p, 0x000);
breakreact = (breakreact >> 1) | (1 << bp_num); breakreact = (breakreact >> 1) | (1 << bp_num);
jtag_dr_shift(p, BREAKREACT + WRITE); jtag_dr_shift_16(p, BREAKREACT + WRITE);
jtag_dr_shift(p, breakreact); jtag_dr_shift_16(p, breakreact);
return 1; return 1;
} }
@ -1115,9 +1143,17 @@ unsigned int jtag_cpu_state( struct jtdev *p )
{ {
jtag_ir_shift(p, IR_EMEX_READ_CONTROL); jtag_ir_shift(p, IR_EMEX_READ_CONTROL);
if ((jtag_dr_shift(p, 0x0000) & 0x0080) == 0x0080) { if ((jtag_dr_shift_16(p, 0x0000) & 0x0080) == 0x0080) {
return 1; /* halted */ return 1; /* halted */
} else { } else {
return 0; /* running */ return 0; /* running */
} }
} }
/*----------------------------------------------------------------------------*/
int jtag_get_config_fuses( struct jtdev *p )
{
jtag_ir_shift(p, IR_CONFIG_FUSES);
return jtag_dr_shift_8(p, 0);
}

View File

@ -115,5 +115,6 @@ void jtag_single_step(struct jtdev *p);
unsigned int jtag_set_breakpoint(struct jtdev *p, unsigned int jtag_set_breakpoint(struct jtdev *p,
int bp_num, address_t bp_addr); int bp_num, address_t bp_addr);
unsigned int jtag_cpu_state(struct jtdev *p); unsigned int jtag_cpu_state(struct jtdev *p);
int jtag_get_config_fuses(struct jtdev *p);
#endif #endif

View File

@ -472,5 +472,6 @@ const struct device_class device_loadbsl = {
.getregs = loadbsl_getregs, .getregs = loadbsl_getregs,
.setregs = loadbsl_setregs, .setregs = loadbsl_setregs,
.ctl = loadbsl_ctl, .ctl = loadbsl_ctl,
.poll = loadbsl_poll .poll = loadbsl_poll,
.getconfigfuses = NULL
}; };

View File

@ -312,6 +312,14 @@ static int pif_erase( device_t dev_base,
return dev->jtag.failed ? -1 : 0; 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);
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -423,7 +431,8 @@ const struct device_class device_pif = {
.setregs = pif_setregs, .setregs = pif_setregs,
.ctl = pif_ctl, .ctl = pif_ctl,
.poll = pif_poll, .poll = pif_poll,
.erase = pif_erase .erase = pif_erase,
.getconfigfuses = pif_getconfigfuses
}; };
const struct device_class device_gpio = { const struct device_class device_gpio = {
@ -437,5 +446,6 @@ const struct device_class device_gpio = {
.setregs = pif_setregs, .setregs = pif_setregs,
.ctl = pif_ctl, .ctl = pif_ctl,
.poll = pif_poll, .poll = pif_poll,
.erase = pif_erase .erase = pif_erase,
.getconfigfuses = pif_getconfigfuses
}; };

View File

@ -512,5 +512,6 @@ const struct device_class device_rom_bsl = {
.getregs = rom_bsl_getregs, .getregs = rom_bsl_getregs,
.setregs = rom_bsl_setregs, .setregs = rom_bsl_setregs,
.ctl = rom_bsl_ctl, .ctl = rom_bsl_ctl,
.poll = rom_bsl_poll .poll = rom_bsl_poll,
.getconfigfuses = NULL
}; };

View File

@ -817,5 +817,6 @@ const struct device_class device_sim = {
.getregs = sim_getregs, .getregs = sim_getregs,
.setregs = sim_setregs, .setregs = sim_setregs,
.ctl = sim_ctl, .ctl = sim_ctl,
.poll = sim_poll .poll = sim_poll,
.getconfigfuses = NULL
}; };

View File

@ -642,5 +642,6 @@ const struct device_class device_tilib = {
.getregs = tilib_getregs, .getregs = tilib_getregs,
.setregs = tilib_setregs, .setregs = tilib_setregs,
.ctl = tilib_ctl, .ctl = tilib_ctl,
.poll = tilib_poll .poll = tilib_poll,
.getconfigfuses = NULL
}; };