static int _dma_morecore(size_t min_size, int cached, struct dma_mem_descriptor* dma_desc) { static uint32_t _vaddr = DMA_VSTART; struct seL4_ARM_Page_GetAddress getaddr_ret; seL4_CPtr frame; seL4_CPtr pd; vka_t* vka; int err; pd = simple_get_pd(&_simple); vka = &_vka; /* Create a frame */ frame = vka_alloc_frame_leaky(vka, 12); assert(frame); if (!frame) { return -1; } /* Try to map the page */ err = seL4_ARM_Page_Map(frame, pd, _vaddr, seL4_AllRights, 0); if (err) { seL4_CPtr pt; /* Allocate a page table */ pt = vka_alloc_page_table_leaky(vka); if (!pt) { printf("Failed to create page table\n"); return -1; } /* Map the page table */ err = seL4_ARM_PageTable_Map(pt, pd, _vaddr, 0); if (err) { printf("Failed to map page table\n"); return -1; } /* Try to map the page again */ err = seL4_ARM_Page_Map(frame, pd, _vaddr, seL4_AllRights, 0); if (err) { printf("Failed to map page\n"); return -1; } } /* Find the physical address of the page */ getaddr_ret = seL4_ARM_Page_GetAddress(frame); assert(!getaddr_ret.error); /* Setup dma memory description */ dma_desc->vaddr = _vaddr; dma_desc->paddr = getaddr_ret.paddr; dma_desc->cached = 0; dma_desc->size_bits = 12; dma_desc->alloc_cookie = (void*)frame; dma_desc->cookie = NULL; /* Advance the virtual address marker */ _vaddr += BIT(12); return 0; }
static int _map_sel4_page(addrspace_t *as, seL4_CPtr frame_cap, seL4_Word vpage, seL4_CapRights rights, seL4_ARM_VMAttributes attr) { seL4_ARM_PageDirectory pd = as->as_sel4_pd; int err; /* Attempt the mapping */ err = seL4_ARM_Page_Map(frame_cap, pd, vpage, rights, attr); if(err == seL4_FailedLookup) { /* Assume the error was because we have no page table */ err = _map_page_table(as, pd, vpage); if(!err) { /* Try the mapping again */ err = seL4_ARM_Page_Map(frame_cap, pd, vpage, rights, attr); } } return err ? EFAULT : 0; }
static int _set_page_reference(addrspace_t *as, seL4_Word vaddr, uint32_t rights) { int err; seL4_CPtr kframe_cap, frame_cap; seL4_Word vpage = PAGE_ALIGN(vaddr); int x = PT_L1_INDEX(vpage); int y = PT_L2_INDEX(vpage); if (as->as_pd_regs[x] == NULL) { return EINVAL; } seL4_Word kvaddr = (as->as_pd_regs[x][y] & PTE_KVADDR_MASK); dprintf(3, "mapping back into kvaddr -> 0x%08x, vaddr = 0x%08x\n", kvaddr, vaddr); err = frame_get_cap(kvaddr, &kframe_cap); //assert(!err); // This kvaddr is ready to use, there should be no error /* Copy the frame cap as we need to map it into 2 address spaces */ frame_cap = cspace_copy_cap(cur_cspace, cur_cspace, kframe_cap, rights); if (frame_cap == CSPACE_NULL) { dprintf(3, "vmf: failed copying frame cap\n"); return EFAULT; } err = seL4_ARM_Page_Map(frame_cap, as->as_sel4_pd, vpage, rights, seL4_ARM_Default_VMAttributes); if(err == seL4_FailedLookup){ dprintf(3, "vmf: failed mapping application frame to sel4\n"); return EFAULT; } as->as_pd_caps[x][y] = frame_cap; err = frame_set_referenced(kvaddr); if(err){ dprintf(3, "vmf: setting frame referenced error\n"); return err; } return 0; }