Ejemplo n.º 1
0
ssize_t up_progmem_erasepage(size_t page)
{
	size_t addr;
	irqstate_t irqs;

	if (page >= up_progmem_npages()) {
		return -EFAULT;
	}

	addr = up_progmem_getaddress(page);

	/* Disable IRQs while erasing sector */
	irqs = irqsave();

	s5j_sflash_disable_wp();

	/* Set sector address and then send erase command */
	putreg32(addr - S5J_FLASH_PADDR, S5J_SFLASH_ERASE_ADDRESS);
	putreg8(0xff, S5J_SFLASH_SE);

	/* Wait for the completion */
	while (s5j_sflash_read_status() & 0x1) ;

	s5j_sflash_enable_wp();

	/* Invalidate cache */
	arch_invalidate_dcache(addr, addr + up_progmem_blocksize());

	/* Restore IRQs */
	irqrestore(irqs);

	return up_progmem_blocksize();
}
Ejemplo n.º 2
0
uintptr_t sam_physpgaddr(uintptr_t vaddr)
{
  FAR uint32_t *l2table;
  uint32_t l1entry;
  uintptr_t paddr;
  int index;

  /* Check if this address is within the range of the virtualized .bss/.data,
   * heap, or stack regions.
   */

  if ((vaddr >= CONFIG_ARCH_TEXT_VBASE && vaddr < ARCH_TEXT_VEND) ||
      (vaddr >= CONFIG_ARCH_DATA_VBASE && vaddr < ARCH_DATA_VEND) ||
      (vaddr >= CONFIG_ARCH_HEAP_VBASE && vaddr < ARCH_HEAP_VEND) ||
      (vaddr >= CONFIG_ARCH_STACK_VBASE && vaddr < ARCH_STACK_VEND))
    {
      /* Yes.. Get Level 1 page table entry corresponding to this virtual
       * address.
       */

      l1entry = mmu_l1_getentry(vaddr);
      if ((l1entry & PMD_TYPE_MASK) == PMD_TYPE_PTE)
        {
          /* Get the physical address of the level 2 page table from level 1
           * page table entry.
           */

          paddr = ((uintptr_t)l1entry & PMD_PTE_PADDR_MASK);

          /* Extract the virtual address of the base of level 2 page table */

          l2table = (FAR uint32_t *)sam_virtpgaddr(paddr);
          if (l2table)
            {
              /* Invalidate D-Cache line containing this virtual address so that
               * we re-read from physical memory
               */

              index = (vaddr & SECTION_MASK) >> MM_PGSHIFT;
              arch_invalidate_dcache((uintptr_t)&l2table[index],
                                     (uintptr_t)&l2table[index] + sizeof(uint32_t));

              /* Get the Level 2 page table entry corresponding to this virtual
               * address.  Extract the physical address of the page containing
               * the mapping of the virtual address.
               */

              paddr = ((uintptr_t)l2table[index] & PTE_SMALL_PADDR_MASK);

              /* Add the correct offset and return the physical address
               * corresponding to the virtual address.
               */

              return paddr + (vaddr & MM_PGMASK);
            }
        }
Ejemplo n.º 3
0
static int up_addrenv_initdata(uintptr_t l2table)
{
  irqstate_t flags;
  FAR uint32_t *virtptr;
  uintptr_t paddr;
#ifndef CONFIG_ARCH_PGPOOL_MAPPING
  uint32_t l1save;
#endif

  DEBUGASSERT(l2table);
  flags = enter_critical_section();

#ifdef CONFIG_ARCH_PGPOOL_MAPPING
  /* Get the virtual address corresponding to the physical page table address */

  virtptr = (FAR uint32_t *)arm_pgvaddr(l2table);
#else
  /* Temporarily map the page into the virtual address space */

  l1save = mmu_l1_getentry(ARCH_SCRATCH_VBASE);
  mmu_l1_setentry(l2table & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS);
  virtptr = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (l2table & SECTION_MASK));
#endif

  /* Invalidate D-Cache so that we read from the physical memory */

  arch_invalidate_dcache((uintptr_t)virtptr,
                         (uintptr_t)virtptr + sizeof(uint32_t));

  /* Get the physical address of the first page of of .bss/.data */

  paddr = (uintptr_t)(*virtptr) & PTE_SMALL_PADDR_MASK;
  DEBUGASSERT(paddr);

#ifdef CONFIG_ARCH_PGPOOL_MAPPING
  /* Get the virtual address corresponding to the physical page address */

  virtptr = (FAR uint32_t *)arm_pgvaddr(paddr);
#else
  /* Temporarily map the page into the virtual address space */

  mmu_l1_setentry(paddr & ~SECTION_MASK, ARCH_SCRATCH_VBASE, MMU_MEMFLAGS);
  virtptr = (FAR uint32_t *)(ARCH_SCRATCH_VBASE | (paddr & SECTION_MASK));
#endif

  /* Finally, after of all of that, we can initialize the tiny region at
   * the beginning of .bss/.data by setting it to zero.
   */

  memset(virtptr, 0, ARCH_DATA_RESERVE_SIZE);

  /* Make sure that the initialized data is flushed to physical memory. */

  arch_flush_dcache((uintptr_t)virtptr,
                    (uintptr_t)virtptr + ARCH_DATA_RESERVE_SIZE);

#ifndef CONFIG_ARCH_PGPOOL_MAPPING
  /* Restore the scratch section L1 page table entry */

  mmu_l1_restore(ARCH_SCRATCH_VBASE, l1save);
#endif
  leave_critical_section(flags);
  return OK;
}
Ejemplo n.º 4
0
void
PX4IO_serial_f7::_do_interrupt()
{
	uint32_t sr = rISR;	/* get UART status register */

	if (sr & USART_ISR_RXNE) {
		(void)rRDR;	/* read DR to clear RXNE */
	}

	rICR = sr & rISR_ERR_FLAGS_MASK;	/* clear flags */

	if (sr & (USART_ISR_ORE |		/* overrun error - packet was too big for DMA or DMA was too slow */
		  USART_ISR_NF |		/* noise error - we have lost a byte due to noise */
		  USART_ISR_FE)) {		/* framing error - start/stop bit lost or line break */

		/*
		 * If we are in the process of listening for something, these are all fatal;
		 * abort the DMA with an error.
		 */
		if (_rx_dma_status == _dma_status_waiting) {
			_abort_dma();

			perf_count(_pc_uerrs);
			/* complete DMA as though in error */
			_do_rx_dma_callback(DMA_STATUS_TEIF);

			return;
		}

		/* XXX we might want to use FE / line break as an out-of-band handshake ... handle it here */

		/* don't attempt to handle IDLE if it's set - things went bad */
		return;
	}

	if (sr & USART_ISR_IDLE) {

		/* if there is DMA reception going on, this is a short packet */
		if (_rx_dma_status == _dma_status_waiting) {
			/* Invalidate _current_packet, so we get fresh data from RAM */
			arch_invalidate_dcache((uintptr_t)_current_packet,
					       (uintptr_t)_current_packet + ALIGNED_IO_BUFFER_SIZE);

			/* verify that the received packet is complete */
			size_t length = sizeof(*_current_packet) - stm32_dmaresidual(_rx_dma);

			if ((length < 1) || (length < PKT_SIZE(*_current_packet))) {
				perf_count(_pc_badidle);

				/* stop the receive DMA */
				stm32_dmastop(_rx_dma);

				/* complete the short reception */
				_do_rx_dma_callback(DMA_STATUS_TEIF);
				return;
			}

			perf_count(_pc_idle);

			/* stop the receive DMA */
			stm32_dmastop(_rx_dma);

			/* complete the short reception */
			_do_rx_dma_callback(DMA_STATUS_TCIF);
		}
	}
}