Beispiel #1
0
/* write a new configuration item to config space in flash memory.
 * data will be 4-byte aligned when writing, but original length information
 * will be retained.
 *
 * @return 0 if successful, -2 when no space for storing data is available,
 *         -1 when there is not enough space for the requested length
 */
int config_write(const uint32_t type, const uint32_t length, const void* data) {
	uint32_t *dst = (uint32_t*) config_find_item(CONFIG_UNSET);
	if(dst == NULL)
		return -2;
	if(dst + length + 3 >= (uint32_t*)(CONFIG_ADDRESS + CONFIG_SIZE))
		return -1;

	flash_unlock();
	/* write header information */
	flash_program_word((uint32_t)(dst++), type);
	flash_program_word((uint32_t)(dst++), length);
	/* word-wise reading/writing */
	uint32_t p = 0;
	for(; p + 3 < length; p+=sizeof(uint32_t)) {
		uint32_t v = *((uint32_t*)(data+p));
		flash_program_word((uint32_t)(dst++), v);
	}
	/* read remainder of partial last word */
	if(p < length) {
		uint32_t v = ((uint8_t*)data)[p++];
		if(p < length)
			v = v | (((uint8_t*)data)[p++] << 8);
		if(p < length)
			v = v | (((uint8_t*)data)[p++] << 16);
		flash_program_word((uint32_t)(dst++), v);
	}
	flash_lock();
	return 0;
}
void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len)
{
	for(int i = 0; i < len; i += 4)
		flash_program_word(baseaddr + i,
			*(u32*)(buf+i),
			FLASH_PROGRAM_X32);
}
Beispiel #3
0
void storage_commit(void)
{
	int i;
	uint32_t *w;
	// backup meta
	memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN);
	flash_clear_status_flags();
	flash_unlock();
	// erase storage
	for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) {
		flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
	}
	// modify storage
	memcpy(meta_backup + FLASH_META_DESC_LEN, "stor", 4);
	memcpy(meta_backup + FLASH_META_DESC_LEN + 4, storage_uuid, sizeof(storage_uuid));
	memcpy(meta_backup + FLASH_META_DESC_LEN + 4 + sizeof(storage_uuid), &storage, sizeof(Storage));
	// copy it back
	for (i = 0; i < FLASH_META_LEN / 4; i++) {
		w = (uint32_t *)(meta_backup + i * 4);
		flash_program_word(FLASH_META_START + i * 4, *w);
	}
	flash_lock();
	// flash operation failed
	if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) {
		layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Storage failure", "detected.", NULL, "Please unplug", "the device.", NULL);
		for (;;) { }
	}
}
Beispiel #4
0
void check_bootloader(void)
{
#if MEMORY_PROTECT
	uint8_t hash[32];
	int r = memory_bootloader_hash(hash);

	if (!known_bootloader(r, hash)) {
		layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Unknown bootloader"), _("detected."), NULL, _("Unplug your TREZOR"), _("contact our support."), NULL);
		shutdown();
	}

	if (is_mode_unprivileged()) {
		return;
	}

	if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) {
		// all OK -> done
		return;
	}

	// ENABLE THIS AT YOUR OWN RISK
	// ATTEMPTING TO OVERWRITE BOOTLOADER WITH UNSIGNED FIRMWARE MAY BRICK
	// YOUR DEVICE.

	layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, _("Updating bootloader"), NULL, NULL, _("DO NOT UNPLUG"), _("YOUR TREZOR!"), NULL);

	// unlock sectors
	memory_write_unlock();

	for (int tries = 0; tries < 10; tries++) {
		// replace bootloader
		flash_unlock();
		for (int i = FLASH_BOOT_SECTOR_FIRST; i <= FLASH_BOOT_SECTOR_LAST; i++) {
			flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
		}
		for (int i = 0; i < FLASH_BOOT_LEN / 4; i++) {
			const uint32_t *w = (const uint32_t *)(bl_data + i * 4);
			flash_program_word(FLASH_BOOT_START + i * 4, *w);
		}
		flash_lock();
		// check whether the write was OK
		r = memory_bootloader_hash(hash);
		if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) {
			// OK -> show info and halt
			layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Update finished"), _("successfully."), NULL, _("Please reconnect"), _("the device."), NULL);
			shutdown();
			return;
		}
	}
	// show info and halt
	layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Bootloader update"), _("broken."), NULL, _("Unplug your TREZOR"), _("contact our support."), NULL);
	shutdown();
#endif
}
Beispiel #5
0
void platform_save_config() {
  volatile unsigned *src, *dest;
  int n_sectors, conf_bytes;
  flash_unlock();

  /* configrom is sectors 1 through 3, each 16k,
   * compute how many we need to erase */
  conf_bytes = ((char*)&_econfigdata - (char*)&_sconfigdata);
  n_sectors = (conf_bytes + 16385) / 16386;

  flash_erase_sector(n_sectors, 2);
  for (dest = &_configdata_loadaddr, src = &_sconfigdata;
      src < &_econfigdata;
      src++, dest++) {
    flash_program_word((uint32_t)dest, *src);
  }

  flash_lock();
}
static u32 flash_program_data(u32 start_address, u8 *input_data, u16 num_elements)
{
	u16 iter;
	u32 current_address = start_address;
	u32 page_address = start_address;
	u32 flash_status = 0;

	/*check if start_address is in proper range*/
	if((start_address - FLASH_BASE) >= (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM_MAX+1)))
		return 1;

	/*calculate current page address*/
	if(start_address % FLASH_PAGE_SIZE)
		page_address -= (start_address % FLASH_PAGE_SIZE);

	flash_unlock();

	/*Erasing page*/
	flash_erase_page(page_address);
	flash_status = flash_get_status_flags();
	if(flash_status != FLASH_SR_EOP)
		return flash_status;

	/*programming flash memory*/
	for(iter=0; iter<num_elements; iter += 4)
	{
		/*programming word data*/
		flash_program_word(current_address+iter, *((u32*)(input_data + iter)));
		flash_status = flash_get_status_flags();
		if(flash_status != FLASH_SR_EOP)
			return flash_status;

		/*verify if correct data is programmed*/
		if(*((u32*)(current_address+iter)) != *((u32*)(input_data + iter)))
			return FLASH_WRONG_DATA_WRITTEN;
	}

	return 0;
}
Beispiel #7
0
void
flash_func_write_word(uint32_t address, uint32_t word)
{
	flash_program_word(address + APP_LOAD_ADDRESS, word);
}
void
flash_func_write_word(uint32_t address, uint32_t word)
{
	flash_program_word(address + APP_LOAD_ADDRESS, word, FLASH_PROGRAM_X32);
}