static void init_timer_caps(env_t env) { /* get the timer irq cap */ seL4_CPtr cap; UNUSED int error = vka_cspace_alloc(&env->vka, &cap); assert(error == 0); vka_cspace_make_path(&env->vka, cap, &env->irq_path); error = simple_get_IRQ_control(&env->simple, DEFAULT_TIMER_INTERRUPT, env->irq_path); assert(error == 0); #ifdef CONFIG_ARCH_ARM /* get the timer frame cap */ error = vka_cspace_alloc(&env->vka, &cap); assert(error == 0); vka_cspace_make_path(&env->vka, cap, &env->frame_path); error = simple_get_frame_cap(&env->simple, (void *) DEFAULT_TIMER_PADDR, PAGE_BITS_4K, &env->frame_path); assert(error == 0); #elif CONFIG_ARCH_IA32 env->io_port_cap = simple_get_IOPort_cap(&env->simple, PIT_IO_PORT_MIN, PIT_IO_PORT_MAX); assert(env->io_port_cap != 0); #else #error "Unknown architecture" #endif }
/* Binds and IRQ to an endpoint */ static seL4_CPtr irq_bind(irq_t irq, seL4_CPtr notification_cap, int idx, vka_t* vka, simple_t *simple) { seL4_CPtr irq_cap, bnotification_cap; cspacepath_t irq_path, notification_path, bnotification_path; seL4_CapData_t badge; int err; /* Create an IRQ cap */ err = vka_cspace_alloc(vka, &irq_cap); if (err != 0) { ZF_LOGE("Failed to allocate cslot for irq\n"); return seL4_CapNull; } vka_cspace_make_path(vka, irq_cap, &irq_path); err = simple_get_IRQ_control(simple, irq, irq_path); if (err != seL4_NoError) { ZF_LOGE("Failed to get cap to irq_number %d\n", irq); vka_cspace_free(vka, irq_cap); return seL4_CapNull; } /* Badge the provided endpoint. The bit position of the badge tells us the array * index of the associated IRQ data. */ err = vka_cspace_alloc(vka, &bnotification_cap); if (err != 0) { ZF_LOGE("Failed to allocate cslot for irq\n"); vka_cspace_free(vka, irq_cap); return seL4_CapNull; } vka_cspace_make_path(vka, notification_cap, ¬ification_path); vka_cspace_make_path(vka, bnotification_cap, &bnotification_path); badge = seL4_CapData_Badge_new(BIT(idx)); err = vka_cnode_mint(&bnotification_path, ¬ification_path, seL4_AllRights, badge); if (err != seL4_NoError) { ZF_LOGE("Failed to badge IRQ notification endpoint\n"); vka_cspace_free(vka, irq_cap); vka_cspace_free(vka, bnotification_cap); return seL4_CapNull; } /* bind the IRQ cap to our badged endpoint */ err = seL4_IRQHandler_SetNotification(irq_cap, bnotification_cap); if (err != seL4_NoError) { ZF_LOGE("Failed to bind IRQ handler to notification\n"); vka_cspace_free(vka, irq_cap); vka_cspace_free(vka, bnotification_cap); return seL4_CapNull; } /* Finally ACK any pending IRQ and enable the IRQ */ seL4_IRQHandler_Ack(irq_cap); DIRQSERVER("Registered IRQ %d with badge 0x%lx\n", irq, BIT(idx)); return irq_cap; }
seL4_Word get_free_slot(env_t env) { seL4_CPtr slot; UNUSED int error = vka_cspace_alloc(&env->vka, &slot); assert(!error); return slot; }
// creates IRQHandler cap "handler" for IRQ "irq" static void get_irqhandler_cap(int irq, cspacepath_t* handler) { seL4_CPtr cap; // get a cspace slot UNUSED int err = vka_cspace_alloc(&vka, &cap); assert(err == 0); // convert allocated cptr to a cspacepath, for use in // operations such as Untyped_Retype vka_cspace_make_path(&vka, cap, handler); // exec seL4_IRQControl_Get(seL4_CapIRQControl, irq, ...) // to get an IRQHandler cap for IRQ "irq" err = simple_get_IRQ_control(&simple, irq, *handler); assert(err == 0); }
static int map_iopt_set(env_t env, seL4_CPtr *iospace, iopt_cptrs_t *pts, seL4_CPtr *frame) { int error; cspacepath_t master_path, iospace_path; /* Allocate a random device ID that hopefully doesn't exist have any * RMRR regions */ error = vka_cspace_alloc(&env->vka, iospace); test_assert(!error); vka_cspace_make_path(&env->vka, *iospace, &iospace_path); vka_cspace_make_path(&env->vka, env->io_space, &master_path); error = vka_cnode_mint(&iospace_path, &master_path, seL4_AllRights,(DOMAIN_ID << 16) | FAKE_PCI_DEVICE); test_eq(error, seL4_NoError); error = map_iopt_from_iospace(env, *iospace, pts, frame); return error; }
printf("=========\n"); printf("\n"); /* allocate lots of untyped memory for tests to use */ num_untypeds = populate_untypeds(untypeds); /* create a frame that will act as the init data, we can then map that * in to target processes */ env.init = (test_init_data_t *) vspace_new_pages(&env.vspace, seL4_AllRights, 1, PAGE_BITS_4K); assert(env.init != NULL); /* copy the cap to map into the remote process */ cspacepath_t src, dest; vka_cspace_make_path(&env.vka, vspace_get_cap(&env.vspace, env.init), &src); UNUSED int error = vka_cspace_alloc(&env.vka, &env.init_frame_cap_copy); assert(error == 0); vka_cspace_make_path(&env.vka, env.init_frame_cap_copy, &dest); error = vka_cnode_copy(&dest, &src, seL4_AllRights); assert(error == 0); /* copy the untyped size bits list across to the init frame */ memcpy(env.init->untyped_size_bits_list, untyped_size_bits_list, sizeof(uint8_t) * num_untypeds); /* parse elf region data about the test image to pass to the tests app */ num_elf_regions = sel4utils_elf_num_regions(TESTS_APP); assert(num_elf_regions < MAX_REGIONS); sel4utils_elf_reserve(NULL, TESTS_APP, elf_regions); /* copy the region list for the process to clone itself */ memcpy(env.init->elf_regions, elf_regions, sizeof(sel4utils_elf_region_t) * num_elf_regions);
int proxy_vka_cspace_alloc(void *data, seL4_CPtr *res) { proxy_vka_t *vka = (proxy_vka_t*)data; return vka_cspace_alloc(&vka->regular_vka, res); }