console: Implement debug console register
authorMichel Pollet <buserror@gmail.com>
Tue, 12 Oct 2010 09:02:03 +0000 (10:02 +0100)
committerMichel Pollet <buserror@gmail.com>
Tue, 12 Oct 2010 09:02:03 +0000 (10:02 +0100)
Used in pair with the console register declaration, just
prints what's sent to that debug register.

Signed-off-by: Michel Pollet <buserror@gmail.com>
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h
simavr/sim/sim_elf.c
simavr/sim/sim_elf.h

index 73883d4..7add414 100644 (file)
@@ -121,6 +121,28 @@ void avr_set_command_register(avr_t * avr, avr_io_addr_t addr)
                avr_register_io_write(avr, addr, _avr_io_command_write, NULL);
 }
 
+static void _avr_io_console_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
+{
+       static char * buf = NULL;
+       static int size = 0, len = 0;
+
+       if (v == '\r') {
+               printf("O:" "%s" "" "\n", buf);
+               fflush(stdout);
+       }
+       if (len + 1 >= size) {
+               size += 128;
+               buf = (char*)realloc(buf, size);
+       }
+       buf[len++] = v;
+}
+
+void avr_set_console_register(avr_t * avr, avr_io_addr_t addr)
+{
+       if (addr)
+               avr_register_io_write(avr, addr, _avr_io_console_write, NULL);
+}
+
 void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address)
 {
        memcpy(avr->flash + address, code, size);
index 5b20178..dc1430c 100644 (file)
@@ -241,6 +241,11 @@ void avr_terminate(avr_t * avr);
 // set an IO register to receive commands from the AVR firmware
 // it's optional, and uses the ELF tags
 void avr_set_command_register(avr_t * avr, avr_io_addr_t addr);
+
+// specify the "console register" -- output sent to this register
+// is printed on the simulator console, without using a UART
+void avr_set_console_register(avr_t * avr, avr_io_addr_t addr);
+
 // load code in the "flash"
 void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, uint32_t address);
 
index 8c17f00..ab34c28 100644 (file)
@@ -45,6 +45,7 @@ void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware)
 #if CONFIG_SIMAVR_TRACE
        avr->codeline = firmware->codeline;
 #endif
+
        avr_loadcode(avr, firmware->flash, firmware->flashsize, firmware->flashbase);
        avr->codeend = firmware->flashsize + firmware->flashbase - firmware->datasize;
        if (firmware->eeprom && firmware->eesize) {
@@ -53,6 +54,10 @@ void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware)
        }
 
        avr_set_command_register(avr, firmware->command_register_addr);
+       avr_set_console_register(avr, firmware->console_register_addr);
+
+       // rest is initialization of the VCD file
+
        if (firmware->tracecount == 0)
                return;
        avr->vcd = malloc(sizeof(*avr->vcd));
@@ -151,6 +156,9 @@ static void elf_parse_mmcu_section(elf_firmware_t * firmware, uint8_t * src, uin
                        case AVR_MMCU_TAG_SIMAVR_COMMAND: {
                                firmware->command_register_addr = src[0] | (src[1] << 8);
                        }       break;
+                       case AVR_MMCU_TAG_SIMAVR_CONSOLE: {
+                               firmware->console_register_addr = src[0] | (src[1] << 8);
+                       }       break;
                }
                size -= next;
                src += next - 2; // already incremented
index cd70f4d..cd3cb9c 100644 (file)
@@ -56,6 +56,7 @@ typedef struct elf_firmware_t {
        
        // register to listen to for commands from the firmware
        uint16_t        command_register_addr;
+       uint16_t        console_register_addr;
 
        uint32_t        flashbase;      // base address
        uint8_t *       flash;