jtaglib xv2: memory accesses start to work now
This commit is contained in:
parent
98c434555f
commit
649d82b695
|
@ -331,15 +331,6 @@ unsigned int jtag_get_device(struct jtdev *p)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reads one byte/word from a given address */
|
|
||||||
uint16_t jtag_read_mem(struct jtdev *p, unsigned int format, address_t address)
|
|
||||||
{
|
|
||||||
// NOTE: this is one of the special functions that have to be called early
|
|
||||||
// on before chip ID stuff is done
|
|
||||||
|
|
||||||
return get_jlf(p)->jlf_read_mem(p, format, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register */
|
/* Execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register */
|
||||||
unsigned int jtag_execute_puc(struct jtdev *p)
|
unsigned int jtag_execute_puc(struct jtdev *p)
|
||||||
{
|
{
|
||||||
|
@ -349,10 +340,19 @@ unsigned int jtag_execute_puc(struct jtdev *p)
|
||||||
return get_jlf(p)->jlf_execute_puc(p);
|
return get_jlf(p)->jlf_execute_puc(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reads one byte/word from a given address */
|
||||||
|
uint16_t jtag_read_mem(struct jtdev *p, unsigned int format, address_t address)
|
||||||
|
{
|
||||||
|
return get_jlf(p)->jlf_read_mem(p, format, address);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reads an array of words from target memory */
|
/* Reads an array of words from target memory */
|
||||||
void jtag_read_mem_quick(struct jtdev *p, address_t start_address,
|
void jtag_read_mem_quick(struct jtdev *p, address_t start_address,
|
||||||
unsigned int word_count, uint16_t *data)
|
unsigned int word_count, uint16_t *data)
|
||||||
{
|
{
|
||||||
|
// NOTE: this is one of the special functions that have to be called early
|
||||||
|
// on before chip ID stuff is done
|
||||||
|
|
||||||
get_jlf(p)->jlf_read_mem_quick(p, start_address, word_count, data);
|
get_jlf(p)->jlf_read_mem_quick(p, start_address, word_count, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ static int read_words(device_t dev_base, const struct chipinfo_memory *m,
|
||||||
if (len > 2 && !(len & 1)) {
|
if (len > 2 && !(len & 1)) {
|
||||||
uint16_t* word = malloc((len>>1) * sizeof(*word));
|
uint16_t* word = malloc((len>>1) * sizeof(*word));
|
||||||
if (!word) {
|
if (!word) {
|
||||||
pr_error("jtaglib: failed to allocate memory");
|
pr_error("jtaglib: read_words: failed to allocate memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,8 +619,32 @@ static int write_words(device_t dev_base, const struct chipinfo_memory *m,
|
||||||
|
|
||||||
if (m->type != CHIPINFO_MEMTYPE_FLASH) {
|
if (m->type != CHIPINFO_MEMTYPE_FLASH) {
|
||||||
printc_dbg("jtaglib: write_words: ram: len=%d addr=%06x\n", len, addr);
|
printc_dbg("jtaglib: write_words: ram: len=%d addr=%06x\n", len, addr);
|
||||||
uint16_t value = data[0] | ((uint16_t)data[1] << 8);
|
if ((len > 2) && !(len & 1)) {
|
||||||
|
uint16_t* word = malloc((len>>1) * sizeof(*word));
|
||||||
|
if (!word) {
|
||||||
|
pr_error("jtaglib: write_words: 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_mem_quick(p, addr, (len >> 1), word);
|
||||||
|
free(word);
|
||||||
|
} else {
|
||||||
|
for (address_t i = 0; i < len; i += 2) {
|
||||||
|
uint16_t value;
|
||||||
|
if ((len & 1) && i == len - 1) {
|
||||||
|
value = data[i];
|
||||||
|
jtag_write_mem(p, 8, addr, value);
|
||||||
|
} else {
|
||||||
|
value = data[i] | ((uint16_t)data[i+1] << 8);
|
||||||
jtag_write_mem(p, 16, addr, value);
|
jtag_write_mem(p, 16, addr, value);
|
||||||
|
}
|
||||||
|
if (p->failed) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
r = p->failed ? -1 : 0;
|
r = p->failed ? -1 : 0;
|
||||||
} else {
|
} else {
|
||||||
r = write_flash_block(p, addr, len, data);
|
r = write_flash_block(p, addr, len, data);
|
||||||
|
|
|
@ -8,12 +8,10 @@
|
||||||
#define SAFE_FRAM_PC 0x0004
|
#define SAFE_FRAM_PC 0x0004
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// * read mem (broken)
|
|
||||||
// * read mem quick (consecutive ones break)
|
|
||||||
// * write mem (no effect)
|
|
||||||
// * read reg (nonsense values)
|
// * read reg (nonsense values)
|
||||||
// -> also loses FES
|
|
||||||
// * write reg?
|
// * write reg?
|
||||||
|
// * implement flash write, erase, verify stuff
|
||||||
|
// * other stuff?
|
||||||
// * single step: check if it works
|
// * single step: check if it works
|
||||||
// * breakpoints are a big TODO
|
// * breakpoints are a big TODO
|
||||||
|
|
||||||
|
@ -151,26 +149,32 @@ static unsigned int jlfxv2_get_device(struct jtdev *p)
|
||||||
return jtag_id;
|
return jtag_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
||||||
|
unsigned int length, uint16_t *data);
|
||||||
|
|
||||||
/* Reads one byte/word from a given address
|
/* Reads one byte/word from a given address
|
||||||
* format : 8-byte, 16-word
|
* format : 8-byte, 16-word
|
||||||
* address: address of memory
|
* address: address of memory
|
||||||
* return : content of memory
|
* return : content of memory
|
||||||
*/
|
*/
|
||||||
static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
|
||||||
unsigned int length, uint16_t *data);
|
|
||||||
static uint16_t jlfxv2_read_mem(struct jtdev *p, unsigned int format, address_t address)
|
static uint16_t jlfxv2_read_mem(struct jtdev *p, unsigned int format, address_t address)
|
||||||
{ // SLAU320AJ name: ReadMem
|
{ // SLAU320AJ name: ReadMem
|
||||||
uint16_t r=0;
|
uint16_t r = 0;
|
||||||
printc_dbg("read mem %d %06x\n", format, address);
|
|
||||||
jlfxv2_read_mem_quick(p, address ^ (address & 1), 1, &r);
|
|
||||||
if (format == 8) {
|
|
||||||
if (address & 1) return r >> 8;
|
|
||||||
else return r & 0xff;
|
|
||||||
} else return r;
|
|
||||||
|
|
||||||
if (!jlfxv2_check_full_emu_state(p))
|
if (!jlfxv2_check_full_emu_state(p))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// the code below (an attempt at implementing the real read_mem) doesn't
|
||||||
|
// work, so let's use read_mem_quick as a backup
|
||||||
|
jlfxv2_read_mem_quick(p, address ^ (address & 1), 1, &r);
|
||||||
|
if (format == 8) {
|
||||||
|
if (address & 1) return (r >> 8) & 0xff;
|
||||||
|
else return r & 0xff;
|
||||||
|
} else return r;
|
||||||
|
|
||||||
|
/*//jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
||||||
|
//uint16_t dr = jtag_dr_shift_16(p, 0);
|
||||||
|
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
jtag_dr_shift_16(p, (format == 16) ? 0x0501 : 0x0511);
|
jtag_dr_shift_16(p, (format == 16) ? 0x0501 : 0x0511);
|
||||||
|
@ -179,6 +183,7 @@ static uint16_t jlfxv2_read_mem(struct jtdev *p, unsigned int format, address_t
|
||||||
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);
|
||||||
|
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
||||||
|
|
||||||
r = jtag_dr_shift_16(p, 0);
|
r = jtag_dr_shift_16(p, 0);
|
||||||
|
|
||||||
|
@ -186,7 +191,7 @@ static uint16_t jlfxv2_read_mem(struct jtdev *p, unsigned int format, address_t
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
return r;
|
return r;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reads an array of words from target memory
|
/* Reads an array of words from target memory
|
||||||
|
@ -197,9 +202,12 @@ static uint16_t jlfxv2_read_mem(struct jtdev *p, unsigned int format, address_t
|
||||||
static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
||||||
unsigned int length, uint16_t *data)
|
unsigned int length, uint16_t *data)
|
||||||
{ // SLAU320AJ name: ReadMemQuick
|
{ // SLAU320AJ name: ReadMemQuick
|
||||||
|
address_t pc_bak;
|
||||||
|
|
||||||
if (!jlfxv2_check_full_emu_state(p))
|
if (!jlfxv2_check_full_emu_state(p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//pc_bak = jlfxv2_read_reg(p, 0); // FIXME
|
||||||
jlfxv2_set_pc(p, address);
|
jlfxv2_set_pc(p, address);
|
||||||
|
|
||||||
//jtag_tclk_set(p);
|
//jtag_tclk_set(p);
|
||||||
|
@ -218,12 +226,18 @@ static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
||||||
jtag_dr_shift_16(p, 0);
|
jtag_dr_shift_16(p, 0);
|
||||||
|
|
||||||
if (p->jtag_id == 0x99) {
|
|
||||||
jlfxv2_set_pc(p, SAFE_FRAM_PC);
|
jlfxv2_set_pc(p, SAFE_FRAM_PC);
|
||||||
}
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
jtag_dr_shift_16(p, 0x0501);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
|
jtag_ir_shift(p, IR_ADDR_CAPTURE);
|
||||||
|
|
||||||
|
//jlfxv2_write_reg(p, 0, pc_bak); // FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void jlfxv2_write_mem_quick(struct jtdev *p, address_t address,
|
||||||
|
unsigned int length, const uint16_t *data);
|
||||||
|
|
||||||
/* Writes one byte/word at a given address
|
/* Writes one byte/word at a given address
|
||||||
* format : 8-byte, 16-word
|
* format : 8-byte, 16-word
|
||||||
* address: address to be written
|
* address: address to be written
|
||||||
|
@ -232,10 +246,24 @@ static void jlfxv2_read_mem_quick(struct jtdev *p, address_t address,
|
||||||
static void jlfxv2_write_mem(struct jtdev *p, unsigned int format,
|
static void jlfxv2_write_mem(struct jtdev *p, unsigned int format,
|
||||||
address_t address, uint16_t data)
|
address_t address, uint16_t data)
|
||||||
{ // SLAU320AJ name: WriteMem
|
{ // SLAU320AJ name: WriteMem
|
||||||
if (!jlfxv2_check_full_emu_state(p))
|
printc_dbg("jlfxv2 write mem: %d %06x <- %04x\n", format, address, data);
|
||||||
|
|
||||||
|
if (format == 8) {
|
||||||
|
p->failed = 1;
|
||||||
|
printc_err("jlfxv2 write mem: byte access not yet implemented!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// same story as with read_mem
|
||||||
|
jlfxv2_write_mem_quick(p, address, 1, &data);
|
||||||
|
|
||||||
|
/*if (!jlfxv2_check_full_emu_state(p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printc_dbg("write mem %d: %06x<-%04x\n", format, address, data);
|
jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
||||||
|
uint16_t dr = jtag_dr_shift_16(p, 0);
|
||||||
|
|
||||||
|
printc_dbg("write mem %d: %06x<-%04x: dr=%04x\n", format, address, data, dr);
|
||||||
|
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
@ -251,7 +279,7 @@ static void jlfxv2_write_mem(struct jtdev *p, unsigned int format,
|
||||||
|
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Writes an array of words into target memory
|
/* Writes an array of words into target memory
|
||||||
|
@ -262,9 +290,41 @@ static void jlfxv2_write_mem(struct jtdev *p, unsigned int format,
|
||||||
static void jlfxv2_write_mem_quick(struct jtdev *p, address_t address,
|
static void jlfxv2_write_mem_quick(struct jtdev *p, address_t address,
|
||||||
unsigned int length, const uint16_t *data)
|
unsigned int length, const uint16_t *data)
|
||||||
{ // SLAU320AJ name: WriteMemQuick
|
{ // SLAU320AJ name: WriteMemQuick
|
||||||
for (unsigned int i = 0; i < length; ++i) {
|
uint16_t pc_bak;
|
||||||
|
|
||||||
|
/*for (unsigned int i = 0; i < length; ++i) {
|
||||||
jlfxv2_write_mem(p, 16, address + i*2, data[i]);
|
jlfxv2_write_mem(p, 16, address + i*2, data[i]);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (!jlfxv2_check_full_emu_state(p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//pc_bak = jlfxv2_read_reg(p, 0); // FIXME
|
||||||
|
jlfxv2_set_pc(p, address);
|
||||||
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
jtag_dr_shift_16(p, 0x0500);
|
||||||
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_DATA_QUICK);
|
||||||
|
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < length; ++i) {
|
||||||
|
jtag_tclk_set(p);
|
||||||
|
jtag_dr_shift_16(p, data[i]);
|
||||||
|
jtag_tclk_clr(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
jtag_dr_shift_16(p, 0x0501);
|
||||||
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
|
jlfxv2_set_pc(p, SAFE_FRAM_PC);
|
||||||
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
jtag_dr_shift_16(p, 0x0501);
|
||||||
|
jtag_tclk_set(p);
|
||||||
|
jtag_ir_shift(p, IR_ADDR_CAPTURE);
|
||||||
|
|
||||||
|
//jlfxv2_write_reg(p, 0, pc_bak);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register
|
/* Execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register
|
||||||
|
@ -392,6 +452,7 @@ static address_t jlfxv2_read_reg(struct jtdev *p, int reg)
|
||||||
{ // libmsp430 BIOS name: ReadCpuReg
|
{ // libmsp430 BIOS name: ReadCpuReg
|
||||||
uint16_t reglo, reghi;
|
uint16_t reglo, reghi;
|
||||||
uint16_t jtag_id, jmb_addr;
|
uint16_t jtag_id, jmb_addr;
|
||||||
|
const bool alt_addr = true;
|
||||||
|
|
||||||
if (reg == 3) return 0; // CG
|
if (reg == 3) return 0; // CG
|
||||||
|
|
||||||
|
@ -399,8 +460,9 @@ static address_t jlfxv2_read_reg(struct jtdev *p, int reg)
|
||||||
if (!jlfxv2_check_full_emu_state(p))
|
if (!jlfxv2_check_full_emu_state(p))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
jtag_id = jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_id = jtag_ir_shift(p, IR_DATA_16BIT);
|
jtag_ir_shift(p, IR_DATA_16BIT);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
jtag_dr_shift_16(p, reg);
|
jtag_dr_shift_16(p, reg);
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
@ -409,14 +471,22 @@ static address_t jlfxv2_read_reg(struct jtdev *p, int reg)
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
|
if (alt_addr) {
|
||||||
|
jtag_dr_shift_16(p, 0x0ff6);
|
||||||
|
} else {
|
||||||
jmb_addr = (jtag_id == 0x98) ? 0x14c : 0x18c;
|
jmb_addr = (jtag_id == 0x98) ? 0x14c : 0x18c;
|
||||||
|
|
||||||
jtag_dr_shift_16(p, jmb_addr);
|
jtag_dr_shift_16(p, jmb_addr);
|
||||||
|
}
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
jtag_dr_shift_16(p, 0x3ffd);
|
jtag_dr_shift_16(p, 0x3ffd);
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
|
|
||||||
|
if (alt_addr) {
|
||||||
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
|
jtag_dr_shift_16(p, 0x0501);
|
||||||
|
}
|
||||||
|
|
||||||
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
reglo = jtag_dr_shift_16(p, 0);
|
reglo = jtag_dr_shift_16(p, 0);
|
||||||
|
@ -430,14 +500,15 @@ static address_t jlfxv2_read_reg(struct jtdev *p, int reg)
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
|
if (!alt_addr) {
|
||||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||||
jtag_dr_shift_16(p, 0x0501);
|
jtag_dr_shift_16(p, 0x0501);
|
||||||
|
}
|
||||||
|
|
||||||
jtag_tclk_clr(p);
|
jtag_tclk_clr(p);
|
||||||
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
||||||
jtag_tclk_set(p);
|
jtag_tclk_set(p);
|
||||||
|
|
||||||
|
|
||||||
printc_dbg("read reg %d: lo=%04x hi=%04x\n", reg, reglo, reghi);
|
printc_dbg("read reg %d: lo=%04x hi=%04x\n", reg, reglo, reghi);
|
||||||
return reglo | ((address_t)reghi << 16);
|
return reglo | ((address_t)reghi << 16);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue