Commit ad5381e3f9a0f1a048eefce812a7a4e254ed8034
authorMichel Pollet <michel.pollet@bp.renesas.com>
Wed, 19 Oct 2016 09:04:54 +0000 (10:04 +0100)
committerMichel Pollet <michel.pollet@bp.renesas.com>
Wed, 19 Oct 2016 09:04:54 +0000 (10:04 +0100)
Support reading fuses and lock bits from ELF files and loading them into
the simavr internals for later use.

2 files changed:
simavr/sim/sim_elf.c
simavr/sim/sim_elf.h

index 33a60ae4ae703395e78c3b912d50b54ed2b9d5fb..d73f27788f022b324a010591f180c297f1195b46 100644 (file)
@@ -76,6 +76,10 @@ void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware)
                avr_eeprom_desc_t d = { .ee = firmware->eeprom, .offset = 0, .size = firmware->eesize };
                avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &d);
        }
+       if (firmware->fuse)
+               memcpy(avr->fuse, firmware->fuse, firmware->fusesize);
+       if (firmware->lockbits)
+               avr->lockbits = firmware->lockbits[0];
        // load the default pull up/down values for ports
        for (int i = 0; i < 8; i++)
                if (firmware->external_state[i].port == 0)
@@ -219,6 +223,23 @@ static void elf_parse_mmcu_section(elf_firmware_t * firmware, uint8_t * src, uin
        }
 }
 
+static int
+elf_copy_section(
+       const char *name,
+       Elf_Data *data,
+       uint8_t **dest)
+{
+       *dest = malloc(data->d_size);
+       if (!*dest)
+               return -1;
+
+       memcpy(*dest, data->d_buf, data->d_size);
+       AVR_LOG(NULL, LOG_TRACE, "Loaded %zu .%s\n", name, data->d_size);
+
+       return 0;
+}
+
+
 int elf_read_firmware(const char * file, elf_firmware_t * firmware)
 {
        Elf32_Ehdr elf_header;                  /* ELF header */
@@ -236,6 +257,8 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware)
        Elf_Data *data_data = NULL,
                *data_text = NULL,
                *data_ee = NULL;                /* Data Descriptor */
+       Elf_Data *data_fuse = NULL;
+       Elf_Data *data_lockbits = NULL;
 
        memset(firmware, 0, sizeof(*firmware));
 #if ELF_SYMBOLS
@@ -265,6 +288,10 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware)
                        data_data = elf_getdata(scn, NULL);
                else if (!strcmp(name, ".eeprom"))
                        data_ee = elf_getdata(scn, NULL);
+               else if (!strcmp(name, ".fuse"))
+                       data_fuse = elf_getdata(scn, NULL);
+               else if (!strcmp(name, ".lock"))
+                       data_lockbits = elf_getdata(scn, NULL);
                else if (!strcmp(name, ".bss")) {
                        Elf_Data *s = elf_getdata(scn, NULL);
                        firmware->bsssize = s->d_size;
@@ -353,6 +380,13 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware)
                AVR_LOG(NULL, LOG_TRACE, "Loaded %u .eeprom\n", (unsigned int)data_ee->d_size);
                firmware->eesize = data_ee->d_size;
        }
+       if (data_fuse) {
+               elf_copy_section(".fuse", data_fuse, &firmware->fuse);
+               firmware->fusesize = data_fuse->d_size;
+       }
+       if (data_lockbits)
+               elf_copy_section(".lock", data_fuse, &firmware->lockbits);
+
 //     hdump("flash", avr->flash, offset);
        elf_end(elf);
        close(fd);
index 30b399c24724c401b376025e099c7e7ccbedd2c2..9d6bc71397e3b4ad6906a328942e8b5fa6cdf33d 100644 (file)
@@ -71,6 +71,9 @@ typedef struct elf_firmware_t {
        // read the .eeprom section of the elf, too
        uint8_t *       eeprom;
        uint32_t        eesize;
+       uint8_t *       fuse;
+       uint32_t        fusesize;
+       uint8_t *       lockbits;
 
 #if ELF_SYMBOLS
        avr_symbol_t **  symbol;