/** * \brief Map init user-space memory. * * This function maps pages of the init user-space module. It expects * the virtual base address 'vbase' of a program segment of the init executable, * its size 'size' and its ELF64 access control flags. It maps pages * into physical memory that is allocated on the fly and puts * corresponding frame caps into init's segcn. * * \param vbase Virtual base address of program segment. * \param size Size of program segment in bytes. * \param flags ELF64 access control flags of program segment. * \param ret Used to return base region pointer */ errval_t startup_alloc_init(void *state, genvaddr_t gvbase, size_t size, uint32_t flags, void **ret) { errval_t err; struct spawn_state *spawn_state = state; lvaddr_t vbase = (lvaddr_t)gvbase; /* XXX */ lvaddr_t offset = BASE_PAGE_OFFSET(vbase); /* Page align the parameters */ paging_align(&vbase, NULL, &size, BASE_PAGE_SIZE); lpaddr_t pbase = 0, paddr = 0; for(lvaddr_t i = vbase; i < vbase + size; i += BASE_PAGE_SIZE) { if (apic_is_bsp()) { paddr = bsp_alloc_phys(BASE_PAGE_SIZE); } else { paddr = app_alloc_phys(BASE_PAGE_SIZE); } if(pbase == 0) { pbase = paddr; } err = startup_map_init(i, paddr, BASE_PAGE_SIZE, flags); assert(err_is_ok(err)); } if (apic_is_bsp()) { // Create frame caps for segcn paddr += BASE_PAGE_SIZE; debug(SUBSYS_STARTUP, "Allocated physical memory [0x%"PRIxLPADDR", 0x%"PRIxLPADDR"]\n", pbase, paddr - pbase); err = create_caps_to_cnode(pbase, paddr - pbase, RegionType_RootTask, spawn_state, bootinfo); if (err_is_fail(err)) { return err; } } assert(ret != NULL); *ret = (void *)(vbase + offset); return SYS_ERR_OK; }
static lpaddr_t app_alloc_phys_aligned(size_t size, size_t align) { app_alloc_phys_start = round_up(app_alloc_phys_start, align); return app_alloc_phys(size); }