.ioend = RAMSTART - 1, \
.ramend = RAMEND, \
.flashend = FLASHEND, \
+ .spm_pagesize = SPM_PAGESIZE, \
.e2end = E2END, \
.vector_size = _vector_size, \
.fuse = _FUSE_HELPER, \
.extrf = AVR_IO_REGBIT(MCU_STATUS_REG, EXTRF),\
.borf = AVR_IO_REGBIT(MCU_STATUS_REG, BORF),\
.wdrf = AVR_IO_REGBIT(MCU_STATUS_REG, WDRF)\
- }
+ }, \
+ .fuse_value = DEFAULT_avr_fuse_value, \
+ .lock_value = DEFAULT_avr_lock_value
#else
// Disable signature when using an old avr toolchain
#define DEFAULT_CORE(_vector_size) \
// atmega32 has different name for Watchdog Turn-off Enable register
#define WDCE WDTOE
#include "sim_avr.h"
+#include <string.h>
#define SIM_VECTOR_SIZE 4
#define SIM_MMCU "atmega16"
// instantiate the new core
#include "sim_megax.h"
+static void init_fuse_lock(struct avr_t * avr)
+{
+ avr->fuse_value.lfuse = avr->fuse[0];
+ avr->fuse_value.hfuse = avr->fuse[1];
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t lfuse = avr->fuse_value.lfuse;
+ avr->fuse_value.cksel =
+ (((lfuse & ~FUSE_CKSEL3) != 0) << 3) | (((lfuse & ~FUSE_CKSEL2) != 0) << 2) |
+ (((lfuse & ~FUSE_CKSEL1) != 0) << 1) | (((lfuse & ~FUSE_CKSEL0) != 0) << 0);
+ avr->fuse_value.sut = (((lfuse & ~FUSE_SUT1) != 0) << 1) | (((lfuse & ~FUSE_SUT0) != 0) << 0);
+ avr->fuse_value.boden_disabled = (lfuse & ~FUSE_BODEN) != 0;
+ avr->fuse_value.bodlevel = (lfuse & ~FUSE_BODLEVEL) != 0;
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t hfuse = avr->fuse_value.hfuse;
+ avr->fuse_value.bootrst_disabled = (hfuse & ~FUSE_BOOTRST) != 0;
+ avr->fuse_value.bootsz = (((hfuse & ~FUSE_BOOTSZ0) != 0) << 1) | ((hfuse & ~FUSE_BOOTSZ1) != 0);
+ avr->fuse_value.eesave_disabled = (hfuse & ~FUSE_EESAVE) != 0;
+ avr->fuse_value.ckopt_disabled = (hfuse & ~FUSE_CKOPT) != 0;
+ avr->fuse_value.spien_disabled = (hfuse & ~FUSE_SPIEN) != 0;
+ avr->fuse_value.jtagen_disabled = (hfuse & ~FUSE_JTAGEN) != 0;
+ avr->fuse_value.ocden_disabled = (hfuse & ~FUSE_OCDEN) != 0;
+
+ memset(&avr->lock_value, 0x00, sizeof(avr_lock_value_t));
+ uint8_t lock = avr->lockbits;
+ avr->lock_value.lock = lock;
+ switch (lock & 0x03) {
+ case 0: avr->lock_value.mode3_dis_prg_ver = 1; break;
+ case 1: break;
+ case 2: avr->lock_value.mode2_dis_prg = 1; break;
+ case 3: avr->lock_value.mode1_nolock = 1; break;
+ }
+ switch ((lock >> 2)& 0x03) {
+ case 0: avr->lock_value.app_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.app_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.app_mode2_nospm = 1; break;
+ case 3: avr->lock_value.app_mode1_nolock = 1; break;
+ }
+ switch ((lock >> 4)& 0x03) {
+ case 0: avr->lock_value.boot_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.boot_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.boot_mode2_nospm = 1; break;
+ case 3: avr->lock_value.boot_mode1_nolock = 1; break;
+ }
+
+ if (FLASHEND == 0x3fff) {
+ switch (avr->fuse_value.bootsz) {
+ case 0: avr->fuse_value.bootloader_pages = 16; break;
+ case 1: avr->fuse_value.bootloader_pages = 8; break;
+ case 2: avr->fuse_value.bootloader_pages = 4; break;
+ case 3: avr->fuse_value.bootloader_pages = 2; break;
+ }
+ uint32_t appEnd = avr->flashend - avr->fuse_value.bootloader_pages * avr->spm_pagesize;
+ AVR_LOG(avr, LOG_DEBUG, "HFUSE=0x%02x -> application 0..0x%04x, bootloader: 0x%04x..0x%04x\n", hfuse, appEnd, appEnd + 1, avr->flashend);
+ if (!avr->fuse_value.bootrst_disabled) {
+ avr->reset_pc = appEnd + 1;
+ avr->pc = avr->reset_pc;
+ AVR_LOG(avr, LOG_OUTPUT, "HFUSE=0x%02x -> bootloader reset at 0x%04x\n", hfuse, avr->reset_pc);
+ }
+
+ } else {
+ AVR_LOG(avr, LOG_WARNING, "init_fuse_bit() fails, invalid flash size\n");
+ }
+}
+
static avr_t * make()
{
- return avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr_t *avr = avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr->init_fuse_lock = init_fuse_lock;
+ avr->init_fuse_lock(avr);
+ return avr;
}
avr_kind_t mega16 = {
*/
#include "sim_avr.h"
+#include <string.h>
#define SIM_MMCU "atmega324"
#define SIM_CORENAME mcu_mega324
#define EFUSE_DEFAULT (0xFF)
#endif
+// #define HFUSE_DEFAULT 0
+
// instantiate the new core
#include "sim_megax4.h"
+#define _BVX(v) (1 << v)
+#define BIT6 (unsigned char)~_BVX(6)
+#define BIT7 (unsigned char)~_BVX(7)
+#define VALUE_DEFAULT (BIT6 & BIT7)
+
+static void init_fuse_lock(struct avr_t * avr)
+{
+ avr->fuse_value.lfuse = avr->fuse[0];
+ avr->fuse_value.hfuse = avr->fuse[1];
+ avr->fuse_value.efuse = avr->fuse[2];
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t lfuse = avr->fuse_value.lfuse;
+ avr->fuse_value.cksel =
+ (((lfuse & ~FUSE_CKSEL3) != 0) << 3) | (((lfuse & ~FUSE_CKSEL2) != 0) << 2) |
+ (((lfuse & ~FUSE_CKSEL1) != 0) << 1) | (((lfuse & ~FUSE_CKSEL0) != 0) << 0);
+ avr->fuse_value.sut = (((lfuse & ~FUSE_SUT1) != 0) << 1) | (((lfuse & ~FUSE_SUT0) != 0) << 0);
+ avr->fuse_value.ckout_disabled = (lfuse & ~FUSE_CKOUT) != 0;
+ avr->fuse_value.ckdiv8_disabled = (lfuse & ~FUSE_CKDIV8) != 0;
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t hfuse = avr->fuse_value.hfuse;
+ avr->fuse_value.bootrst_disabled = (hfuse & ~FUSE_BOOTRST) != 0;
+ avr->fuse_value.bootsz = (((hfuse & ~FUSE_BOOTSZ0) != 0) << 1) | ((hfuse & ~FUSE_BOOTSZ1) != 0);
+ avr->fuse_value.eesave_disabled = (hfuse & ~FUSE_EESAVE) != 0;
+ avr->fuse_value.wdton_disabled = (hfuse & ~FUSE_WDTON) != 0;
+ avr->fuse_value.spien_disabled = (hfuse & ~FUSE_SPIEN) != 0;
+ avr->fuse_value.jtagen_disabled = (hfuse & ~FUSE_JTAGEN) != 0;
+ avr->fuse_value.ocden_disabled = (hfuse & ~FUSE_OCDEN) != 0;
+
+ uint8_t efuse = avr->fuse_value.efuse;
+ avr->fuse_value.bodlevel = (((efuse & ~FUSE_BODLEVEL2) != 0) << 2) |
+ (((efuse & ~FUSE_BODLEVEL1) != 0) << 1) | (((efuse & ~FUSE_BODLEVEL0) != 0) << 0);
+
+ memset(&avr->lock_value, 0x00, sizeof(avr_lock_value_t));
+ uint8_t lock = avr->lockbits;
+ avr->lock_value.lock = lock;
+ switch (lock & 0x03) {
+ case 0: avr->lock_value.mode3_dis_prg_ver = 1; break;
+ case 1: break;
+ case 2: avr->lock_value.mode2_dis_prg = 1; break;
+ case 3: avr->lock_value.mode1_nolock = 1; break;
+ }
+ switch ((lock >> 2)& 0x03) {
+ case 0: avr->lock_value.app_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.app_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.app_mode2_nospm = 1; break;
+ case 3: avr->lock_value.app_mode1_nolock = 1; break;
+ }
+ switch ((lock >> 4)& 0x03) {
+ case 0: avr->lock_value.boot_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.boot_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.boot_mode2_nospm = 1; break;
+ case 3: avr->lock_value.boot_mode1_nolock = 1; break;
+ }
+
+ if (FLASHEND == 0x7fff) {
+ switch (avr->fuse_value.bootsz) {
+ case 0: avr->fuse_value.bootloader_pages = 32; break;
+ case 1: avr->fuse_value.bootloader_pages = 16; break;
+ case 2: avr->fuse_value.bootloader_pages = 8; break;
+ case 3: avr->fuse_value.bootloader_pages = 4; break;
+ }
+ uint32_t appEnd = avr->flashend - avr->fuse_value.bootloader_pages * avr->spm_pagesize;
+ AVR_LOG(avr, LOG_DEBUG, "HFUSE=0x%02x -> application 0..0x%04x, bootloader: 0x%04x..0x%04x\n", hfuse, appEnd, appEnd + 1, avr->flashend);
+ if (!avr->fuse_value.bootrst_disabled) {
+ avr->reset_pc = appEnd + 1;
+ avr->pc = avr->reset_pc;
+ AVR_LOG(avr, LOG_OUTPUT, "HFUSE=0x%02x -> bootloader reset at 0x%04x\n", hfuse, avr->reset_pc);
+ }
+
+ } else {
+ AVR_LOG(avr, LOG_WARNING, "init_fuse_bit() fails, invalid flash size\n");
+ }
+}
+
static avr_t * make()
{
- return avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr_t *avr = avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr->init_fuse_lock = init_fuse_lock;
+ avr->init_fuse_lock(avr);
+ return avr;
}
avr_kind_t mega324 = {
.make = make
};
+
*/
#include "sim_avr.h"
+#include <string.h>
#define SIM_VECTOR_SIZE 4
#define SIM_MMCU "atmega328"
// instantiate the new core
#include "sim_megax8.h"
+static void init_fuse_lock(struct avr_t * avr)
+{
+ avr->fuse_value.lfuse = avr->fuse[0];
+ avr->fuse_value.hfuse = avr->fuse[1];
+ avr->fuse_value.efuse = avr->fuse[2];
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t lfuse = avr->fuse_value.lfuse;
+ avr->fuse_value.cksel =
+ (((lfuse & ~FUSE_CKSEL3) != 0) << 3) | (((lfuse & ~FUSE_CKSEL2) != 0) << 2) |
+ (((lfuse & ~FUSE_CKSEL1) != 0) << 1) | (((lfuse & ~FUSE_CKSEL0) != 0) << 0);
+ avr->fuse_value.sut = (((lfuse & ~FUSE_SUT1) != 0) << 1) | (((lfuse & ~FUSE_SUT0) != 0) << 0);
+ avr->fuse_value.ckout_disabled = (lfuse & ~FUSE_CKOUT) != 0;
+ avr->fuse_value.ckdiv8_disabled = (lfuse & ~FUSE_CKDIV8) != 0;
+
+ // 0= programmed (function active), 1=not programmed (function not active)
+ uint8_t hfuse = avr->fuse_value.hfuse;
+ avr->fuse_value.bootrst_disabled = (hfuse & ~FUSE_BOOTRST) != 0;
+ avr->fuse_value.bootsz = (((hfuse & ~FUSE_BOOTSZ0) != 0) << 1) | ((hfuse & ~FUSE_BOOTSZ1) != 0);
+ avr->fuse_value.eesave_disabled = (hfuse & ~FUSE_EESAVE) != 0;
+ avr->fuse_value.wdton_disabled = (hfuse & ~FUSE_WDTON) != 0;
+ avr->fuse_value.spien_disabled = (hfuse & ~FUSE_SPIEN) != 0;
+ avr->fuse_value.dwen_disabled = (hfuse & ~FUSE_DWEN) != 0;
+ avr->fuse_value.rstdisbl_disabled = (hfuse & ~FUSE_RSTDISBL) != 0;
+
+ uint8_t efuse = avr->fuse_value.efuse;
+ avr->fuse_value.bodlevel = (((efuse & ~FUSE_BODLEVEL2) != 0) << 2) |
+ (((efuse & ~FUSE_BODLEVEL1) != 0) << 1) | (((efuse & ~FUSE_BODLEVEL0) != 0) << 0);
+
+ memset(&avr->lock_value, 0x00, sizeof(avr_lock_value_t));
+ uint8_t lock = avr->lockbits;
+ avr->lock_value.lock = lock;
+ switch (lock & 0x03) {
+ case 0: avr->lock_value.mode3_dis_prg_ver = 1; break;
+ case 1: break;
+ case 2: avr->lock_value.mode2_dis_prg = 1; break;
+ case 3: avr->lock_value.mode1_nolock = 1; break;
+ }
+ switch ((lock >> 2)& 0x03) {
+ case 0: avr->lock_value.app_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.app_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.app_mode2_nospm = 1; break;
+ case 3: avr->lock_value.app_mode1_nolock = 1; break;
+ }
+ switch ((lock >> 4)& 0x03) {
+ case 0: avr->lock_value.boot_mode4_nolpm = 1; break;
+ case 1: avr->lock_value.boot_mode3_nospmlpm = 1; break;
+ case 2: avr->lock_value.boot_mode2_nospm = 1; break;
+ case 3: avr->lock_value.boot_mode1_nolock = 1; break;
+ }
+
+ if (FLASHEND == 0x7fff) {
+ switch (avr->fuse_value.bootsz) {
+ case 0: avr->fuse_value.bootloader_pages = 32; break;
+ case 1: avr->fuse_value.bootloader_pages = 16; break;
+ case 2: avr->fuse_value.bootloader_pages = 8; break;
+ case 3: avr->fuse_value.bootloader_pages = 4; break;
+ }
+ uint32_t appEnd = avr->flashend - avr->fuse_value.bootloader_pages * avr->spm_pagesize;
+ AVR_LOG(avr, LOG_DEBUG, "HFUSE=0x%02x -> application 0..0x%04x, bootloader: 0x%04x..0x%04x\n", hfuse, appEnd, appEnd + 1, avr->flashend);
+ if (!avr->fuse_value.bootrst_disabled) {
+ avr->reset_pc = appEnd + 1;
+ avr->pc = avr->reset_pc;
+ AVR_LOG(avr, LOG_OUTPUT, "HFUSE=0x%02x -> bootloader reset at 0x%04x\n", hfuse, avr->reset_pc);
+ }
+
+ } else {
+ AVR_LOG(avr, LOG_WARNING, "init_fuse_bit() fails, invalid flash size\n");
+ }
+}
+
static avr_t * make()
{
- return avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr_t *avr = avr_core_allocate(&SIM_CORENAME.core, sizeof(struct mcu_t));
+ avr->init_fuse_lock = init_fuse_lock;
+ avr->init_fuse_lock(avr);
+ return avr;
}
avr_kind_t mega328 = {
avr->sleep = avr_callback_sleep_raw;
// number of address bytes to push/pull on/off the stack
avr->address_size = avr->eind ? 3 : 2;
- avr->log = 1;
+ avr->log = LOG_WARNING;
avr_reset(avr);
avr_regbit_set(avr, avr->reset_flags.porf); // by default set to power-on reset
return 0;
avr_reset(
avr_t * avr)
{
- AVR_LOG(avr, LOG_TRACE, "%s reset\n", avr->mmcu);
-
+ if (avr->cycle > 0) {
+ AVR_LOG(avr, LOG_OUTPUT, "%s reset (PC set to 0x%04x)\n", avr->mmcu, avr->reset_pc);
+ }
avr->state = cpu_Running;
for(int i = 0x20; i <= avr->ioend; i++)
avr->data[i] = 0;
typedef uint32_t avr_flashaddr_t;
+// fuse values are initialized with -1 and set by device specific init_fuse_lock()
+// Attention: fuse unprogrammed -> bit=1 (function disabled)
+// fuse programmed -> bit=0 (function enabled)
+#define DEFAULT_avr_fuse_value { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
+typedef struct avr_fuse_value_t {
+ int lfuse; // LFUSE
+ int hfuse; // HFUSE
+ int efuse; // EFUSE
+ int cksel; // FUSE_CKSEL3, FUSE_CKSEL2, FUSE_CKSEL1, FUSE_CKSEL0
+ int sut; // FUSE_SUT1, FUSE_SUT0
+ int ckout_disabled; // FUSE_CKOUT
+ int ckdiv8_disabled; // FUSE_CKDIV8
+ int bootrst_disabled; // FUSE_BOOTRST
+ int bootsz; // FUSE_BOOTSZ1, FUSE_BOOTSZ0
+ int bootloader_pages; // bootloader size in number of flash pages
+ int eesave_disabled; // FUSE_EESAVE
+ int wdton_disabled; // FUSE_WDTON
+ int ckopt_disabled; // FUSE_CKOPT
+ int spien_disabled; // FUSE_SPIEN
+ int jtagen_disabled; // FUSE_JTAGEN
+ int ocden_disabled; // FUSE_OCDEN
+ int dwen_disabled; // FUSE FUSE_DWEN
+ int rstdisbl_disabled; // FUSE_RSTDISBL
+ int boden_disabled; // FUSE BODEN
+ int bodlevel; // FUSE_BODLEVEL2, FUSE_BODLEVEL1, FUSE_BODLEVEL0
+} avr_fuse_value_t;
+
+// lock values are initialized with -1 and set by device specific init_fuse_lock()
+#define DEFAULT_avr_lock_value { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
+typedef struct avr_lock_value_t {
+ int lock; // LOCK value
+ int mode1_nolock; // Mode 1: No memory lock features enabled
+ int mode2_dis_prg; // Mode 2: Further programming disabled
+ int mode3_dis_prg_ver; // Mode 3: Further programming and verification disabled
+ int app_mode1_nolock; // Application Mode 1, no lock on SPM and LPM
+ int app_mode2_nospm; // Application Mode 2, SPM prohibited
+ int app_mode3_nospmlpm; // Application Mode 3, SPM and LPM prohibited
+ int app_mode4_nolpm; // Application Mode 4, LPM prohibited
+ int boot_mode1_nolock; // Bootloader Mode 1, no lock on SPM and LPM
+ int boot_mode2_nospm; // Bootloader Mode 2, SPM prohibited
+ int boot_mode3_nospmlpm; // Bootloader Mode 3, SPM and LPM prohibited
+ int boot_mode4_nolpm; // Bootloader Mode 4, LPM prohibited
+} avr_lock_value_t;
+
+
struct avr_t;
typedef uint8_t (*avr_io_read_t)(
struct avr_t * avr,
uint16_t ioend;
uint16_t ramend;
uint32_t flashend;
+ uint16_t spm_pagesize;
uint32_t e2end;
uint8_t vector_size;
uint8_t signature[3];
uint32_t size;
uint32_t len;
} io_console_buffer;
+
+ // fuse and lock bits (function called in avr_load_firmware())
+ void (*init_fuse_lock)(struct avr_t * avr);
+ struct avr_fuse_value_t fuse_value;
+ struct avr_lock_value_t lock_value;
+
} avr_t;
};
avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &d);
}
- if (firmware->fuse)
+ if (firmware->fuse) {
memcpy(avr->fuse, firmware->fuse, firmware->fusesize);
+ AVR_LOG(avr, LOG_DEBUG, "fuses available, checking bootloader settings\n");
+ if (avr->init_fuse_lock) {
+ avr->init_fuse_lock(avr);
+ } else {
+ AVR_LOG(avr, LOG_WARNING, "WARNING: fuse and lock values ignored (no init_fuse_lock() found)\n");
+ }
+ }
if (firmware->lockbits)
avr->lockbits = firmware->lockbits[0];
// load the default pull up/down values for ports
name, php->p_filesz, php->p_vaddr);
return -1;
}
- AVR_LOG(NULL, LOG_DEBUG, " Loaded %d (0x%0x) bytes (section offset 0x%04x)\n",
- php->p_filesz, php->p_filesz, php->p_vaddr);
return 0;
}
if (php->p_vaddr < 0x810000) { // .text or .data section
if (firmware->flash == NULL) {
avr_t *avr = avr_make_mcu_by_name(firmware->mmcu);
+ if (avr == NULL) {
+ AVR_LOG(NULL, LOG_ERROR, " ERROR: cannot initialize flash, unknown mmcu name %s!\n", firmware->mmcu);
+ return -1;
+ }
firmware->flashbase = 0;
firmware->flashsize = avr->flashend + 1;
+ free(avr);
+ avr = NULL;
if (firmware->flashsize <= 0) {
- AVR_LOG(NULL, LOG_ERROR, "cannot initialize flash, unknown size!\n");
+ AVR_LOG(NULL, LOG_ERROR, " ERROR: cannot initialize flash, unknown size!\n");
return -1;
}
firmware->flash = (uint8_t *)malloc(firmware->flashsize);
if (firmware->flash == NULL) {
- AVR_LOG(NULL, LOG_ERROR, "malloc flash memory fails!\n");
+ AVR_LOG(NULL, LOG_ERROR, " ERROR: malloc flash memory fails!\n");
return -1;
}
memset(firmware->flash, 0xff, firmware->flashsize);
- AVR_LOG(NULL, LOG_DEBUG, "flash initialization with 0xff (%d bytes)\n", firmware->flashsize);
+ AVR_LOG(NULL, LOG_DEBUG, " Flash (%d bytes = %dKiB) initialized with 0xff\n", firmware->flashsize, firmware->flashsize / 1024);
}
if (php->p_vaddr < 0x800000) {
isTextSectionLoaded = 0;
} else if (!isTextSectionLoaded) {
AVR_LOG(NULL, LOG_ERROR,
- "Initialialised data but no flash (%d bytes at %x in file \"%s\")!\n",
+ " ERROR: .data without .text (%d bytes at %x in file \"%s\")!\n",
php->p_filesz, php->p_vaddr, file);
return -1;
}
uint8_t *section = NULL;
if (elf_copy_segment(fd, php, §ion) || section == NULL) {
AVR_LOG(NULL, LOG_ERROR,
- "cannot read section (%d bytes at %x in file \"%s\")!\n",
+ " ERROR: cannot read section (%d bytes at %x in file \"%s\")!\n",
php->p_filesz, php->p_vaddr, file);
if (section != NULL) {
free(section);
}
return -1;
} else {
- AVR_LOG(NULL, LOG_DEBUG, " Loading %d (0x%0x) bytes (section offset 0x%04x) to flash address 0x%04x\n",
- php->p_filesz, php->p_filesz, php->p_vaddr, offset);
+ AVR_LOG(NULL, LOG_OUTPUT, " Loading section %s (%d=0x%0x bytes at 0x%04x) to flash 0x%04x\n",
+ isTextSectionLoaded ? ".text" : ".data", php->p_filesz, php->p_filesz, php->p_vaddr, offset);
}
uint32_t overlapping_start = UINT32_MAX;
for (uint32_t addr = offset; addr < (offset + php->p_filesz); addr++) {
if (addr >= firmware->flashsize) {
AVR_LOG(NULL, LOG_ERROR,
- "section out of flash address range (%d bytes at %x in file \"%s\")!\n",
+ " ERROR: section out of flash address range (%d bytes at %x in file \"%s\")!\n",
php->p_filesz, php->p_vaddr, file);
return -1;
}
if (overlapping_start <= overlapping_end) {
if (overlapping_error) {
AVR_LOG(NULL, LOG_OUTPUT,
- "WARNING: overlapping section with different content (0x%04x..0x%04x)!\n",
+ " WARNING: overlapping section with different content (0x%04x..0x%04x)!\n",
overlapping_start, overlapping_end);
} else {
AVR_LOG(NULL, LOG_OUTPUT,
- "overlapping section with same content (0x%04x..0x%04x)!\n",
+ " overlapping section with same content (0x%04x..0x%04x)!\n",
overlapping_start, overlapping_end);
}
}
} else if (php->p_vaddr < 0x820000) {
/* EEPROM. */
- if (elf_handle_segment(fd, php, &firmware->eeprom, "EEPROM"))
+ if (elf_handle_segment(fd, php, &firmware->eeprom, "EEPROM")) {
+ AVR_LOG(NULL, LOG_WARNING,
+ " WARNING: Loading section .eeprom (%d bytes at 0x%04x) fails!\n",
+ php->p_filesz, php->p_vaddr);
continue;
+ }
firmware->eesize = php->p_filesz;
+ AVR_LOG(NULL, LOG_OUTPUT,
+ " Loading eeprom data from section .eeprom (%d bytes at 0x%04x)\n",
+ php->p_filesz, php->p_vaddr);
+
} else if (php->p_vaddr < 0x830000) {
/* Fuses. */
- if (elf_handle_segment(fd, php, &firmware->fuse, "Fuses"))
+ if (elf_handle_segment(fd, php, &firmware->fuse, "Fuses")) {
+ AVR_LOG(NULL, LOG_WARNING,
+ "WARNING: Loading section .fuse (%d bytes at 0x%04x) fails!\n",
+ php->p_filesz, php->p_vaddr);
continue;
+ }
firmware->fusesize = php->p_filesz;
+ char lfuse[16], hfuse[16], efuse[16];
+ snprintf(lfuse, firmware->fusesize >= 1 ? sizeof(lfuse) : 1, " LFUSE=0x%02x", firmware->fusesize >= 1 ? firmware->fuse[0] : 0);
+ snprintf(hfuse, firmware->fusesize >= 2 ? sizeof(lfuse) : 1, " HFUSE=0x%02x", firmware->fusesize >= 2 ? firmware->fuse[1] : 0);
+ snprintf(efuse, firmware->fusesize >= 3 ? sizeof(lfuse) : 1, " EFUSE=0x%02x", firmware->fusesize >= 3 ? firmware->fuse[2] : 0);
+ AVR_LOG(NULL, LOG_OUTPUT, " Loading%s%s%s from section .fuse (%d bytes at 0x%04x)\n",
+ lfuse, hfuse, efuse, php->p_filesz, php->p_vaddr);
+
} else if (php->p_vaddr < 0x840000) {
/* Lock bits. */
-
- elf_handle_segment(fd, php, &firmware->lockbits, "Lock bits");
+ if (elf_handle_segment(fd, php, &firmware->lockbits, "Lock bits")) {
+ AVR_LOG(NULL, LOG_WARNING,
+ " WARNING: Loading section .lock (%d bytes at 0x%04x) fails!\n",
+ php->p_filesz, php->p_vaddr);
+ continue;
+ }
+ AVR_LOG(NULL, LOG_OUTPUT,
+ " Loading LOCK=0x%02x from section .lock (%d bytes at 0x%04x)\n",
+ *firmware->lockbits, php->p_filesz, php->p_vaddr);
}
}