Beispiel #1
0
static int erase_sector(sector_descriptor_t *sm, flash_entry_header_t *pf)
{
	int rv = 0;
	ssize_t page = up_progmem_getpage((size_t)pf);

	if (page > 0 && page == sm->page) {
		last_erased = sm->page;
		ssize_t size = up_progmem_erasepage(page);

		if (size < 0 || size != sm->size) {
			rv = size;
		}
	}

	return rv;
}
Beispiel #2
0
ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
{
	int page;
	int pagesize;
	size_t remain = count;

	page = up_progmem_getpage(addr + count);
	if (page < 0) {
		return -EINVAL;
	}

	pagesize = up_progmem_pagesize(page);

	while (remain) {
		int tmp = remain;
		irqstate_t irqs;

		if (tmp > pagesize) {
			tmp = pagesize;
		}

		/* Disable IRQs */
		irqs = irqsave();

		s5j_sflash_disable_wp();

		/* Load and write data */
		memcpy((void *)addr, buf, tmp);

		/* Flush cache */
		arch_flush_dcache(addr, addr + tmp);

		s5j_sflash_enable_wp();

		/* Restore IRQs */
		irqrestore(irqs);

		buf += tmp;
		addr += tmp;
		remain -= tmp;
	}

	return count;
}
Beispiel #3
0
static int install_remove(const char *scriptname)
{
  FILE    *fp;
  int      progsize, addr, freedsize;
  uint16_t page;
  int      status = 0;

  /* Parse script */

  if ((fp = fopen(scriptname, "r")))
    {
      progsize  = install_getlasthexvalue(fp,'=');
      addr      = install_getlasthexvalue(fp,' ');
      freedsize = progsize;
    }
  else
    {
      return -errno;
    }

  fclose(fp);

  /* Remove pages */

  if (progsize <= 0 || addr <= 0)
    {
      return -EIO;
    }

  do
    {
      if ((page = up_progmem_getpage(addr)) < 0)
        {
          status = -page;
          break;
        }

      if (up_progmem_erasepage(page) < 0)
        {
          status = -page;
          break;
        }

      addr += up_progmem_pagesize(page);
      progsize -= up_progmem_pagesize(page);

    }
  while (progsize > 0);

  if (status < 0)
    {
      return status;
    }

  /* Remove script file */

  if (unlink(scriptname) < 0)
    {
      return -errno;
    }

  return freedsize;
}
Beispiel #4
0
ssize_t __ramfunc__ up_progmem_write(size_t addr, const void *buf, size_t size)
{
  int       ret = 0;
  int       word_count;
  int       num_words;
  int       page_words;
  uint32_t *p_data;
  uint32_t *address = (uint32_t *)addr;
  uint32_t  num_bytes = size;

  /* EFM32 requires word access */

  if (addr & 3)
    {
      return -EINVAL;
    }

  /* EFM32 requires word access */

  if (num_bytes & 3)
    {
      return -EINVAL;
    }

  efm32_flash_unlock();

  /* enable writing to the flash */

  bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 1);

  /* Convert bytes to words */

  num_words = num_bytes >> 2;

  /* The following loop splits the data into chunks corresponding to flash pages.
   * The address is loaded only once per page, because the hardware automatically
   * increments the address internally for each data load inside a page.
   */

  for (word_count = 0, p_data = (uint32_t *)buf; word_count < num_words; )
    {
      int page_bytes;
      ssize_t page_idx;
      irqstate_t flags;

      /* Compute the number of words to write to the current page. */

      page_idx = up_progmem_getpage((size_t)address+(word_count << 2));
      if (page_idx < 0)
        {
          ret = -EINVAL;
          break;
        }

      page_bytes = up_progmem_pagesize(page_idx);
      if (page_bytes < 0)
        {
          ret = -EINVAL;
          break;
        }

      page_words = (page_bytes - (((uint32_t) (address + word_count)) & \
                    (page_bytes-1))) / sizeof(uint32_t);

      if (page_words > num_words - word_count)
        {
          page_words = num_words - word_count;
        }

      flags = enter_critical_section();

      /* First we load address. The address is auto-incremented within a page.
       * Therefore the address phase is only needed once for each page.
       */

      ret = msc_load_verify_address(address + word_count);

      /* Now write the data in the current page. */

      if (ret == 0)
        {
          ret = msc_load_write_data(p_data, page_words, true);
        }

      leave_critical_section(flags);

      if (ret != 0)
        {
          break;
        }

      word_count += page_words;
      p_data += page_words;
    }

  /* Disable writing to the MSC */

  bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WREN_SHIFT, 0);

#if (defined(CONFIG_EFM32_EFM32GG) || defined(CONFIG_EFM32_EFM32WG)) && (2==WORDS_PER_DATA_PHASE)

  /* Turn off double word write cycle support. */

  bitband_set_peripheral(EFM32_MSC_WRITECTRL, _MSC_WRITECTRL_WDOUBLE_SHIFT, 0);

#endif

  if (ret < 0)
    {
      return ret;
    }

  return word_count;
}