Example #1
0
static size_t memwrite_flash(void *dest, void *src, size_t len) {
#if USE_BLOCKWRITING
	return rom_pwrite(src, len, (off_t)(uintptr_t)dest);
	// The compiler will remove everything from this point on.
	// -> No #elsif needed
#endif /* USE_BLOCKWRITING */
	size_t written = 0;
	unsigned short *lcldest = dest;
	char *lclsrc = src;
	unsigned short ow;
	char *owptr = (char*) (&ow);

#if DEBUG
	if ((uintptr_t) dest & 1) {
		puts("Alignment FAIL");
	}
#endif
	//DPRINTF("Flash: %x\n", ow);
	//watchdog_periodic();

#if 1 != FBENCHMARK
	flash_setup();
#endif
	while ((len & ~0x1) > written) {
		owptr[0] = *lclsrc++;
		owptr[1] = *lclsrc++;
#if 1 !=FBENCHMARK
		flash_write(lcldest, ow);
#if DEBUG
		printf("WRT: %p, %d, %d\n", lcldest, ow, *lcldest);
		watchdog_periodic();
		if (ow != *lcldest) {
			printf("PANIC!");
			while (1)
				;
		}
#endif
		lcldest++;
#endif
		written += 2;
	}
#if 1 != FBENCHMARK
	flash_done();
	IFG1 |= UTXIFG0;
#endif
	return written;
}
Example #2
0
/*---------------------------------------------------------------------------*/
int
elfloader_load(off_t eepromaddr)
{
  struct cle_info h;
  int ret;

  void (*elfloader_init)(void);

  elfloader_unknown[0] = 0;

  /* The ELF header is located at the start of the buffer. */
  ret = cle_read_info(&h, xmem_pread, eepromaddr);

  if(ret != ELFLOADER_OK) {
    memcpy(elfloader_unknown, h.name, sizeof(elfloader_unknown));
    elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
    return ret;
  }

  if(datamemory != NULL) {
    free(datamemory);
  }

  /* We are making semi-permanent allocations, first compact heap! */
  /* malloc_compact(); */
  datamemory = malloc(IMAX(h.textsize, h.datasize + h.bsssize));
  if(datamemory == NULL) {
    return ELFLOADER_DATA_TO_LARGE; /* XXX or text to large */
  }

  h.data = datamemory;
  h.bss = datamemory + h.datasize;
  h.text = TEXTMEMORY;

  PRINTF("elfloader: copy text segment to RAM %p %p\n",
	 h.data, h.data + h.textsize);
  ret = xmem_pread(datamemory, h.textsize, eepromaddr + h.textoff); 
  assert(ret > 0);
  if(h.textrelasize > 0) {
    PRINTF("elfloader: relocate text in RAM\n");
    ret = cle_relocate(&h,
		       xmem_pread,
		       eepromaddr,
		       datamemory,
		       h.textrelaoff, h.textrelasize);
    if(ret != ELFLOADER_OK) {
      memcpy(elfloader_unknown, h.name, sizeof(elfloader_unknown));
      elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
      return ret;
    }
  }
  PRINTF("elfloader: copy text segment to ROM 0x%lx 0x%lx\n",
	 (unsigned long)h.text,
	 (unsigned long)h.text + h.textsize);

  ret = rom_erase((h.textsize+ROM_ERASE_UNIT_SIZE) & ~(ROM_ERASE_UNIT_SIZE-1),
		  h.text);
  assert(ret > 0);
  ret = rom_pwrite(datamemory, h.textsize, h.text);
  assert(ret > 0);

  PRINTF("elfloader: copy data segment to RAM %p %p\n",
	 h.data, h.data + h.datasize);
  ret = xmem_pread(datamemory, h.datasize, eepromaddr + h.dataoff); 
  assert(ret >= h.datasize);
  if(h.datarelasize > 0) {
    PRINTF("elfloader: relocate data segment\n");
    ret = cle_relocate(&h,
		       xmem_pread,
		       eepromaddr,
		       datamemory,
		       h.datarelaoff, h.datarelasize);
    if(ret != ELFLOADER_OK) {
      memcpy(elfloader_unknown, h.name, sizeof(elfloader_unknown));
      elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
      return ret;
    }
  }

  PRINTF("elfloader: zero bss %p %p\n", h.bss, h.bss + h.bsssize);
  memset(h.bss, 0, h.bsssize);

  /* Find _init, _fini, and loaded_process. */
  elfloader_loaded_process = cle_lookup(&h, xmem_pread, eepromaddr,
					"autostart_processes");
  elfloader_fini = cle_lookup(&h, xmem_pread, eepromaddr, "_fini");
  elfloader_init = cle_lookup(&h, xmem_pread, eepromaddr, "_init");

  if(elfloader_init != NULL) {
    PRINTF("init=%p fini=%p\n", elfloader_init, elfloader_fini);
    (*elfloader_init)();
    elfloader_loaded_process = NULL;
    return ELFLOADER_OK;
  }

  if(elfloader_loaded_process != NULL) {
    PRINTF("elfloader: launch program\n");
    process_start(elfloader_loaded_process, NULL);
    elfloader_fini = NULL;
    return ELFLOADER_OK;
  } else {
    return ELFLOADER_NO_STARTPOINT;
  }
}