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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
void jtag_read_mem_quick(struct jtdev *p, address_t start_address,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -589,7 +589,7 @@ static int read_words(device_t dev_base, const struct chipinfo_memory *m,
|
|||
if (len > 2 && !(len & 1)) {
|
||||
uint16_t* word = malloc((len>>1) * sizeof(*word));
|
||||
if (!word) {
|
||||
pr_error("jtaglib: failed to allocate memory");
|
||||
pr_error("jtaglib: read_words: failed to allocate memory");
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
if (p->failed) break;
|
||||
}
|
||||
}
|
||||
r = p->failed ? -1 : 0;
|
||||
} else {
|
||||
r = write_flash_block(p, addr, len, data);
|
||||
|
|
|
@ -8,12 +8,10 @@
|
|||
#define SAFE_FRAM_PC 0x0004
|
||||
|
||||
// FIXME:
|
||||
// * read mem (broken)
|
||||
// * read mem quick (consecutive ones break)
|
||||
// * write mem (no effect)
|
||||
// * read reg (nonsense values)
|
||||
// -> also loses FES
|
||||
// * write reg?
|
||||
// * implement flash write, erase, verify stuff
|
||||
// * other stuff?
|
||||
// * single step: check if it works
|
||||
// * breakpoints are a big TODO
|
||||
|
||||
|
@ -151,26 +149,32 @@ static unsigned int jlfxv2_get_device(struct jtdev *p)
|
|||
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
|
||||
* format : 8-byte, 16-word
|
||||
* address: address 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)
|
||||
{ // SLAU320AJ name: ReadMem
|
||||
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))
|
||||
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_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||
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_tclk_set(p);
|
||||
jtag_tclk_clr(p);
|
||||
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
||||
|
||||
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_set(p);
|
||||
|
||||
return r;
|
||||
return r;*/
|
||||
}
|
||||
|
||||
/* 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,
|
||||
unsigned int length, uint16_t *data)
|
||||
{ // SLAU320AJ name: ReadMemQuick
|
||||
address_t pc_bak;
|
||||
|
||||
if (!jlfxv2_check_full_emu_state(p))
|
||||
return;
|
||||
|
||||
//pc_bak = jlfxv2_read_reg(p, 0); // FIXME
|
||||
jlfxv2_set_pc(p, address);
|
||||
|
||||
//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_dr_shift_16(p, 0);
|
||||
|
||||
if (p->jtag_id == 0x99) {
|
||||
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); // 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
|
||||
* format : 8-byte, 16-word
|
||||
* 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,
|
||||
address_t address, uint16_t data)
|
||||
{ // 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;
|
||||
|
||||
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_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_clr(p);
|
||||
jtag_tclk_set(p);
|
||||
jtag_tclk_set(p);*/
|
||||
}
|
||||
|
||||
/* 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,
|
||||
unsigned int length, const uint16_t *data)
|
||||
{ // 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]);
|
||||
}*/
|
||||
|
||||
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
|
||||
|
@ -392,6 +452,7 @@ static address_t jlfxv2_read_reg(struct jtdev *p, int reg)
|
|||
{ // libmsp430 BIOS name: ReadCpuReg
|
||||
uint16_t reglo, reghi;
|
||||
uint16_t jtag_id, jmb_addr;
|
||||
const bool alt_addr = true;
|
||||
|
||||
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))
|
||||
return 0;
|
||||
|
||||
jtag_id = jtag_ir_shift(p, IR_CNTRL_SIG_CAPTURE);
|
||||
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_dr_shift_16(p, reg);
|
||||
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_set(p);
|
||||
|
||||
if (alt_addr) {
|
||||
jtag_dr_shift_16(p, 0x0ff6);
|
||||
} else {
|
||||
jmb_addr = (jtag_id == 0x98) ? 0x14c : 0x18c;
|
||||
|
||||
jtag_dr_shift_16(p, jmb_addr);
|
||||
}
|
||||
jtag_tclk_clr(p);
|
||||
jtag_tclk_set(p);
|
||||
jtag_dr_shift_16(p, 0x3ffd);
|
||||
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_tclk_set(p);
|
||||
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_set(p);
|
||||
|
||||
if (!alt_addr) {
|
||||
jtag_ir_shift(p, IR_CNTRL_SIG_16BIT);
|
||||
jtag_dr_shift_16(p, 0x0501);
|
||||
}
|
||||
|
||||
jtag_tclk_clr(p);
|
||||
jtag_ir_shift(p, IR_DATA_CAPTURE);
|
||||
jtag_tclk_set(p);
|
||||
|
||||
|
||||
printc_dbg("read reg %d: lo=%04x hi=%04x\n", reg, reglo, reghi);
|
||||
return reglo | ((address_t)reghi << 16);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue