Skip to content

Commit

Permalink
Merge pull request #540 from jpcornil-git/pr_sram
Browse files Browse the repository at this point in the history
Add support for 8 & 16 bits sram traces
  • Loading branch information
gatk555 authored Dec 1, 2024
2 parents 8d8e833 + 71c616d commit bcff83e
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 13 deletions.
12 changes: 12 additions & 0 deletions simavr/sim/avr/avr_mcu_section.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ enum {
AVR_MMCU_TAG_VCD_TRACE,
AVR_MMCU_TAG_VCD_PORTPIN,
AVR_MMCU_TAG_VCD_IRQ,
AVR_MMCU_TAG_VCD_SRAM_8,
AVR_MMCU_TAG_VCD_SRAM_16,
AVR_MMCU_TAG_PORT_EXTERNAL_PULL,
};

Expand Down Expand Up @@ -149,6 +151,16 @@ struct avr_mmcu_vcd_trace_t {
.len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\
.name = _name

#define AVR_MCU_VCD_SRAM_8(_name) \
.tag = AVR_MMCU_TAG_VCD_SRAM_8, \
.len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\
.name = _name

#define AVR_MCU_VCD_SRAM_16(_name) \
.tag = AVR_MMCU_TAG_VCD_SRAM_16, \
.len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\
.name = _name

/*!
* Specifies the name and wanted period (in usec) for a VCD file
* this is not mandatory for the VCD output to work, if this tag
Expand Down
11 changes: 5 additions & 6 deletions simavr/sim/avr_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,16 @@ avr_adc_int_raise(
{
avr_adc_t * p = (avr_adc_t *)param;
if (avr_regbit_get(avr, p->aden)) {
if (!p->read_status) {
/* Update I/O registers. */
avr_core_watch_write(avr, p->r_adcl, p->result & 0xff);
avr_core_watch_write(avr, p->r_adch, p->result >> 8);
}
// if the interrupts are not used, still raised the UDRE and TXC flag
avr_raise_interrupt(avr, &p->adc);
avr_regbit_clear(avr, p->adsc);
if( p->adts_mode == avr_adts_free_running )
avr_raise_irq(p->io.irq + ADC_IRQ_IN_TRIGGER, 1);
if (!p->read_status) {
/* Update I/O registers. */

avr->data[p->r_adcl] = p->result & 0xff;
avr->data[p->r_adch] = p->result >> 8;
}
}
return 0;
}
Expand Down
15 changes: 12 additions & 3 deletions simavr/sim/run_avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ display_usage(
" [-ti <vector>] Add traces for IRQ vector <vector>\n"
" [--input|-i <file>] A VCD file to use as input signals\n"
" [--output|-o <file>] A VCD file to save the traced signals\n"
" [--add-trace|-at <name=kind@addr/mask>]\n"
" [--add-trace|-at <name=[portpin|irq|trace]@addr/mask>] or \n"
" <name=[sram8|sram16]@addr>]\n"
" Add signal to be included in VCD output\n"
" [-ff <.hex file>] Load next .hex file as flash\n"
" [-ee <.hex file>] Load next .hex file as eeprom\n"
Expand Down Expand Up @@ -174,9 +175,11 @@ main(
&trace.addr,
&trace.mask
);
if (n_args != 4) {

if ((n_args != 4) &&
((n_args != 3) || (strcmp(trace.kind, "sram8") && strcmp(trace.kind, "sram16")))) {
--pi;
fprintf(stderr, "%s: format for %s is name=kind@addr/mask.\n", argv[0], argv[pi]);
fprintf(stderr, "%s: format for %s is name=kind@addr</mask>.\n", argv[0], argv[pi]);
exit(1);
}

Expand All @@ -186,6 +189,10 @@ main(
f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_IRQ;
} else if (!strcmp(trace.kind, "trace")) {
f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_TRACE;
} else if (!strcmp(trace.kind, "sram8")) {
f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_SRAM_8;
} else if (!strcmp(trace.kind, "sram16")) {
f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_SRAM_16;
} else {
fprintf(
stderr,
Expand All @@ -204,6 +211,8 @@ main(
f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_PORTPIN ? "portpin"
: f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_IRQ ? "irq"
: f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_TRACE ? "trace"
: f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_SRAM_8 ? "sram8"
: f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_SRAM_16 ? "sram16"
: "unknown",
f.trace[f.tracecount].addr,
f.trace[f.tracecount].mask,
Expand Down
9 changes: 9 additions & 0 deletions simavr/sim/sim_avr.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ typedef struct avr_t {
} io[4];
} io_shared_io[4];

// SRAM tracepoint
#define SRAM_TRACEPOINT_SIZE 16
int sram_tracepoint_count;
struct {
struct avr_irq_t * irq;
int width;
uint16_t addr;
} sram_tracepoint[SRAM_TRACEPOINT_SIZE];

// flash memory (initialized to 0xff, and code loaded into it)
uint8_t * flash;
// this is the general purpose registers, IO registers, and SRAM
Expand Down
25 changes: 25 additions & 0 deletions simavr/sim/sim_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,28 @@ static inline void _call_register_irqs(avr_t * avr, uint16_t addr)
}
}

void _call_sram_irqs(avr_t *avr, uint16_t addr) {
for(int tracepoint=0; tracepoint < avr->sram_tracepoint_count; tracepoint++) {

if (avr->sram_tracepoint[tracepoint].width == 16) {
// 16 bits trace (LSB/addr or MSB/addr+1 may be accessed)
if (avr->sram_tracepoint[tracepoint].addr == addr) {
uint16_t v = (avr->data[addr+1] << 8) | avr->data[addr]; // LSB
avr_raise_irq(avr->sram_tracepoint[tracepoint].irq, v);
} else if (avr->sram_tracepoint[tracepoint].addr == addr - 1) {
uint16_t v = (avr->data[addr] << 8) | avr->data[addr-1]; // MSB
avr_raise_irq(avr->sram_tracepoint[tracepoint].irq, v);
}
} else {
// 8 bits trace
if (avr->sram_tracepoint[tracepoint].addr == addr) {
uint8_t v = avr->data[addr];
avr_raise_irq(avr->sram_tracepoint[tracepoint].irq, v);
}
}
}
}

void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)
{
if (addr > avr->ramend) {
Expand Down Expand Up @@ -220,6 +242,7 @@ void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v)

avr->data[addr] = v;
_call_register_irqs(avr, addr);
_call_sram_irqs(avr, addr);
}

uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr)
Expand Down Expand Up @@ -269,6 +292,8 @@ static inline void _avr_set_r(avr_t * avr, uint16_t r, uint8_t v)
avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1);
}
}
// _call_register_irqs(avr, r); // else section above could then be removed ?
_call_sram_irqs(avr, r); // Only for io region
} else
avr->data[r] = v;
}
Expand Down
34 changes: 30 additions & 4 deletions simavr/sim/sim_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ avr_load_firmware(
avr->vcd,
firmware->traceperiod >= 1000 ? firmware->traceperiod : 1000);

AVR_LOG(avr, LOG_TRACE, "Creating VCD trace file '%s'\n",
AVR_LOG(avr, LOG_TRACE, "ELF: Creating VCD trace file '%s'\n",
avr->vcd->filename);

for (int ti = 0; ti < firmware->tracecount; ti++) {
Expand All @@ -228,8 +228,32 @@ avr_load_firmware(
&bit[firmware->trace[ti].addr],
firmware->trace[ti].mask == 0xff ? 8 : 1,
firmware->trace[ti].name);
} else if ( (firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_SRAM_8) ||
(firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_SRAM_16) ) {
if ((firmware->trace[ti].addr <= 31) || (firmware->trace[ti].addr > avr->ramend)) {
AVR_LOG(avr, LOG_ERROR, "ELF: *** Invalid SRAM trace address (0x20 < 0x%04x < 0x%04x )\n", firmware->trace[ti].addr, avr->ramend);
} else if (avr->sram_tracepoint_count >= ARRAY_SIZE(avr->sram_tracepoint)) {
AVR_LOG(avr, LOG_ERROR, "ELF: *** Too many SRAM traces (limit = %d)\n", ARRAY_SIZE(avr->sram_tracepoint));
} else {
char name[20];
sprintf(name, "sram_tracepoint_%d", avr->sram_tracepoint_count);
const char *names[1] = {name};
avr_irq_t *irq = avr_alloc_irq(&avr->irq_pool, 0, 1, names);
if (irq) {
AVR_LOG(avr, LOG_OUTPUT, "ELF: SRAM tracepoint added at '0x%04x' (%s, %d bits)\n", firmware->trace[ti].addr, firmware->trace[ti].name, firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_SRAM_8 ? 8 : 16);
avr->sram_tracepoint[avr->sram_tracepoint_count].irq = irq;
avr->sram_tracepoint[avr->sram_tracepoint_count].width = firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_SRAM_8 ? 8 : 16;
avr->sram_tracepoint[avr->sram_tracepoint_count].addr = firmware->trace[ti].addr;
avr_vcd_add_signal(avr->vcd,
irq,
avr->sram_tracepoint[avr->sram_tracepoint_count].width,
firmware->trace[ti].name[0] ? firmware->trace[ti].name : names[0]
);
avr->sram_tracepoint_count++;
}
}
} else if (firmware->trace[ti].mask == 0xff ||
firmware->trace[ti].mask == 0) {
firmware->trace[ti].mask == 0) {
// easy one
avr_irq_t * all = avr_iomem_getirq(avr,
firmware->trace[ti].addr,
Expand Down Expand Up @@ -330,7 +354,9 @@ elf_parse_mmcu_section(
} break;
case AVR_MMCU_TAG_VCD_PORTPIN:
case AVR_MMCU_TAG_VCD_IRQ:
case AVR_MMCU_TAG_VCD_TRACE: {
case AVR_MMCU_TAG_VCD_TRACE:
case AVR_MMCU_TAG_VCD_SRAM_8:
case AVR_MMCU_TAG_VCD_SRAM_16: {
uint8_t mask = src[0];
uint16_t addr = src[1] | (src[2] << 8);
char * name = (char*)src + 3;
Expand Down Expand Up @@ -385,7 +411,7 @@ elf_copy_segment(int fd, Elf32_Phdr *php, uint8_t **dest)
rv, php->p_filesz, php->p_vaddr, php->p_offset);
return -1;
}
AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at %x\n",
AVR_LOG(NULL, LOG_DEBUG, "ELF: Loaded %d bytes at %x\n",
php->p_filesz, php->p_vaddr);
return 0;
}
Expand Down

0 comments on commit bcff83e

Please sign in to comment.