int up_addrenv_ustackalloc(FAR struct tcb_s *tcb, size_t stacksize)
{
  int ret;

  bvdbg("tcb=%p stacksize=%lu\n", tcb, (unsigned long)stacksize);

  DEBUGASSERT(tcb);

  /* Initialize the address environment list to all zeroes */

  memset(tcb->xcp.ustack, 0, ARCH_STACK_NSECTS * sizeof(uintptr_t *));

  /* Back the allocation up with physical pages and set up the level 2 mapping
   * (which of course does nothing until the L2 page table is hooked into
   * the L1 page table).
   */

  /* Allocate .text space pages */

  ret = arm_addrenv_create_region(tcb->xcp.ustack, ARCH_STACK_NSECTS,
                                  CONFIG_ARCH_STACK_VBASE, stacksize,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to create stack region: %d\n", ret);
      up_addrenv_ustackfree(tcb);
      return ret;
    }

  return OK;
}
Ejemplo n.º 2
0
int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
                      FAR group_addrenv_t *addrenv)
{
  int ret;

  binfo("addrenv=%p textsize=%lu datasize=%lu\n",
        addrenv, (unsigned long)textsize, (unsigned long)datasize);

  DEBUGASSERT(addrenv);

  /* Initialize the address environment structure to all zeroes */

  memset(addrenv, 0, sizeof(group_addrenv_t));

  /* Back the allocation up with physical pages and set up the level 2 mapping
   * (which of course does nothing until the L2 page table is hooked into
   * the L1 page table).
   */

  /* Allocate .text space pages */

  ret = arm_addrenv_create_region(addrenv->text, ARCH_TEXT_NSECTS,
                                  CONFIG_ARCH_TEXT_VBASE, textsize,
                                  MMU_L2_UTEXTFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create .text region: %d\n", ret);
      goto errout;
    }

  /* Allocate .bss/.data space pages.  NOTE that a configurable offset is
   * added to the allocted size.  This is matched by the offset that is
   * used when reporting the virtual data address in up_addrenv_vdata().
   */

  ret = arm_addrenv_create_region(addrenv->data, ARCH_DATA_NSECTS,
                                  CONFIG_ARCH_DATA_VBASE,
                                  datasize + ARCH_DATA_RESERVE_SIZE,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create .bss/.data region: %d\n", ret);
      goto errout;
    }

#ifdef CONFIG_BUILD_KERNEL
  /* Initialize the shared data are at the beginning of the .bss/.data
   * region.
   */

  ret = up_addrenv_initdata((uintptr_t)addrenv->data[0] & PMD_PTE_PADDR_MASK);
  if (ret < 0)
    {
      berr("ERROR: Failed to initialize .bss/.data region: %d\n", ret);
      goto errout;
    }
#endif

#ifdef CONFIG_BUILD_KERNEL
  /* Allocate heap space pages */

  ret = arm_addrenv_create_region(addrenv->heap, ARCH_HEAP_NSECTS,
                                  CONFIG_ARCH_HEAP_VBASE, heapsize,
                                  MMU_L2_UDATAFLAGS);
  if (ret < 0)
    {
      berr("ERROR: Failed to create heap region: %d\n", ret);
      goto errout;
    }

  /* Save the initial heap size allocated.  This will be needed when
   * the heap data structures are initialized.
   */

  addrenv->heapsize = (size_t)ret << MM_PGSHIFT;
#endif
  return OK;

errout:
  up_addrenv_destroy(addrenv);
  return ret;
}