static void _sos_ipc_init(seL4_CPtr* ipc_ep, seL4_CPtr* async_ep){ seL4_Word ep_addr, aep_addr; int err; /* Create an Async endpoint for interrupts */ aep_addr = ut_alloc(seL4_EndpointBits); conditional_panic(!aep_addr, "No memory for async endpoint"); err = cspace_ut_retype_addr(aep_addr, seL4_AsyncEndpointObject, seL4_EndpointBits, cur_cspace, async_ep); conditional_panic(err, "Failed to allocate c-slot for Interrupt endpoint"); /* Bind the Async endpoint to our TCB */ err = seL4_TCB_BindAEP(seL4_CapInitThreadTCB, *async_ep); conditional_panic(err, "Failed to bind ASync EP to TCB"); /* Create an endpoint for user application IPC */ ep_addr = ut_alloc(seL4_EndpointBits); conditional_panic(!ep_addr, "No memory for endpoint"); err = cspace_ut_retype_addr(ep_addr, seL4_EndpointObject, seL4_EndpointBits, cur_cspace, ipc_ep); conditional_panic(err, "Failed to allocate c-slot for IPC endpoint"); }
/* * Inject data into the given vspace. * TODO: Don't keep these pages mapped in */ static int load_segment_into_vspace(seL4_RISCV_PageDirectory dest_as, char *src, unsigned long segment_size, unsigned long file_size, unsigned long dst, unsigned long permissions) { assert(file_size <= segment_size); unsigned long pos; /* We work a page at a time in the destination vspace. */ pos = 0; while(pos < segment_size) { seL4_Word paddr; seL4_CPtr sos_cap, tty_cap; seL4_Word vpage, kvpage; unsigned long kdst; int nbytes; int err; kdst = dst + PROCESS_SCRATCH; vpage = PAGE_ALIGN(dst); kvpage = PAGE_ALIGN(kdst); /* First we need to create a frame */ paddr = ut_alloc(seL4_PageBits); conditional_panic(!paddr, "Out of memory - could not allocate frame"); err = cspace_ut_retype_addr(paddr, seL4_RISCV_4K, seL4_PageBits, cur_cspace, &tty_cap); conditional_panic(err, "Failed to retype to a frame object"); /* Copy the frame cap as we need to map it into 2 address spaces */ sos_cap = cspace_copy_cap(cur_cspace, cur_cspace, tty_cap, seL4_AllRights); conditional_panic(sos_cap == 0, "Failed to copy frame cap"); /* Map the frame into tty_test address spaces */ err = map_page(tty_cap, dest_as, vpage, permissions, seL4_RISCV_Default_VMAttributes); conditional_panic(err, "Failed to map to tty address space"); /* Map the frame into sos address spaces */ err = map_page(sos_cap, seL4_CapInitThreadPD, kvpage, seL4_AllRights, seL4_RISCV_Default_VMAttributes); conditional_panic(err, "Failed to map sos address space"); /* Now copy our data into the destination vspace. */ nbytes = PAGESIZE - (dst & PAGEMASK); if (pos < file_size){ memcpy((void*)kdst, (void*)src, MIN(nbytes, file_size - pos)); } /* Not observable to I-cache yet so flush the frame */ // seL4_ARM_Page_Unify_Instruction(sos_cap, 0, PAGESIZE); pos += nbytes; dst += nbytes; src += nbytes; } return 0; }
static int _create_tcb(sos_pcb *pcb, seL4_Word priority) { int err; pcb->tcb_addr = ut_alloc(seL4_TCBBits); // Create a new seL4 TCB object if (pcb->tcb_addr == 0) return SOS_PROCESS_OOM; err = cspace_ut_retype_addr(pcb->tcb_addr, seL4_TCBObject, seL4_TCBBits, cur_cspace, &pcb->tcb_cap); if (err) { dprintf(6, "procreatE: Failed to retype TCB!\n"); return err; } // Configure it err = seL4_TCB_Configure(pcb->tcb_cap, pcb->ep_cap, priority, pcb->cspace->root_cnode, seL4_NilData, pcb->seL4_pd, seL4_NilData, SOS_PROCESS_IPC_BUFFER, pcb->ipc_cap); if (err) { dprintf(6, "procreate: unable to configure new TCB!\n"); return err; } return SOS_PROCESS_SUCCESS; }
/** * Maps a page table into the root servers page directory * @param vaddr The virtual address of the mapping * @return 0 on success */ static int _map_page_table(addrspace_t *as, seL4_ARM_PageDirectory pd, seL4_Word vpage) { seL4_Word pt_addr; seL4_ARM_PageTable pt_cap; int err; /* Allocate a PT object */ pt_addr = ut_alloc(seL4_PageTableBits); if(pt_addr == 0) { return ENOMEM; } /* Create the frame cap */ err = cspace_ut_retype_addr(pt_addr, seL4_ARM_PageTableObject, seL4_PageTableBits, cur_cspace, &pt_cap); if(err) { ut_free(pt_addr, seL4_PageTableBits); return EFAULT; } /* Tell seL4 to map the PT in for us */ err = seL4_ARM_PageTable_Map(pt_cap, pd, vpage, seL4_ARM_Default_VMAttributes); if (err) { ut_free(pt_addr, seL4_PageTableBits); cspace_delete_cap(cur_cspace, pt_cap); return EFAULT; } _insert_pt(as, pt_cap, pt_addr); return 0; }
/* We defer to ut for kernel objects, for now. * SOS kernel objects will never be swappable, so this is OK. */ static int _create_vspace(sos_pcb *pcb) { int err; pcb->seL4_pd_addr = ut_alloc(seL4_PageDirBits); // 14 bits = 16K if (pcb->seL4_pd_addr == 0) { dprintf(6, "No memory for new Page Directory\n"); return SOS_PROCESS_OOM; } dprintf(7, "create_vspace: got paddr %p for sel4PD\n", pcb->seL4_pd_addr); err = cspace_ut_retype_addr(pcb->seL4_pd_addr, seL4_ARM_PageDirectoryObject, seL4_PageDirBits, cur_cspace, &(pcb->seL4_pd)); if (err) dprintf(6, "Failed to retype memory for PD"); return err; }
extern void *bdiff_malloc( size_t size ) { return( ut_alloc( size ) ); }
extern void *GUIAlloc( unsigned size ) { return( ut_alloc( size ) ); }