static int allocate_memory(void ** virt_addr, unsigned long virt_base, unsigned long size_in_bytes, unsigned long flags) { int r; l4re_ds_t ds; /* Allocate a free capability index for our data space */ ds = l4re_util_cap_alloc(); if (l4_is_invalid_cap(ds)) return -L4_ENOMEM; /* Allocate memory via a dataspace */ if ((r = l4re_ma_alloc(size_in_bytes, ds, flags))) { printf("Memory allocation failed.\n"); return r; } /* Make the dataspace visible in our address space */ *virt_addr = (void *)virt_base; if ((r = l4re_rm_attach(virt_addr, size_in_bytes, L4RE_RM_SEARCH_ADDR, ds, 0, L4_PAGESHIFT))) { printf("Memory mapping failed.\n"); return r; } /* Done, virtual address is in virt_addr */ return 0; }
static int kp_irq_func(void) { l4_cap_idx_t irq_cap = l4re_util_cap_alloc(); l4_cap_idx_t thread_cap = pthread_getl4cap(_pthread); l4_msgtag_t tag; l4_debugger_set_object_name(thread_cap, "kp-omap3.irq"); if (l4io_request_irq(7, irq_cap) < 0) return -2; // was L4_IRQ_F_LEVEL_LOW tag = l4_irq_attach(irq_cap, 0, thread_cap); if (l4_ipc_error(tag, l4_utcb())) return -3; while (1) { tag = l4_irq_receive(irq_cap, L4_IPC_NEVER); if (l4_ipc_error(tag, l4_utcb())) { printf("[KEYP] Error: Receive irq failed\n"); continue; } kp_write(REG_KEYP_IMR1, 0xf); if (kp_handler) scan_key(); l4_uint8_t value = 0; kp_read(REG_KEYP_ISR1, &value); kp_write(REG_KEYP_IMR1, 0x0); } }
static void setup_memory(void) { int ret; l4_size_t phys_size; if (fb_vaddr) return; ret = l4io_request_iomem(0x48050000, 0x1000, 0, &omap_dss_virt_base); if (ret) { printf("[LCD] Error: Could not map device memory\n"); return; } // get some frame buffer l4re_ds_t mem = l4re_util_cap_alloc(); if (l4_is_invalid_cap(mem)) return; if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED)) { printf("[LCD] Error: Could not allocate memory\n"); return; } fb_vaddr = 0; if (l4re_rm_attach(&fb_vaddr, fbmem_size(), L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP, mem, 0, L4_PAGESHIFT)) { printf("[LCD] Error: Could not attach memory\n"); return; } printf("[LCD] Info: Video memory is at virtual %p (size: 0x%x Bytes)\n", fb_vaddr, fbmem_size()); // get physical address if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size) || phys_size != fbmem_size()) { printf("[LCD] Error: Could not get physical address\n"); return; } printf("[LCD] Info: Physical video memory is at %p\n", (void *)fb_paddr); }
int main(void) { l4_msgtag_t tag; #ifdef MEASURE l4_cpu_time_t s, e; #endif l4_utcb_t *u = l4_utcb(); l4_exc_regs_t exc; l4_umword_t mr0, mr1; printf("Alien feature testing\n"); l4_debugger_set_object_name(l4re_env()->main_thread, "alientest"); /* Start alien thread */ if (l4_is_invalid_cap(alien = l4re_util_cap_alloc())) return 1; l4_touch_rw(alien_thread_stack, sizeof(alien_thread_stack)); tag = l4_factory_create_thread(l4re_env()->factory, alien); if (l4_error(tag)) return 1; l4_debugger_set_object_name(alien, "alienth"); l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); l4_thread_control_alien(1); tag = l4_thread_control_commit(alien); if (l4_error(tag)) return 2; tag = l4_thread_ex_regs(alien, (l4_umword_t)alien_thread, (l4_umword_t)alien_thread_stack + sizeof(alien_thread_stack), 0); if (l4_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, alien, &sp); if (l4_error(tag)) return 4; #ifdef MEASURE l4_calibrate_tsc(l4re_kip()); #endif /* Pager/Exception loop */ if (l4_msgtag_has_error(tag = l4_ipc_receive(alien, u, L4_IPC_NEVER))) { printf("l4_ipc_receive failed"); return 1; } memcpy(&exc, l4_utcb_exc(), sizeof(exc)); mr0 = l4_utcb_mr()->mr[0]; mr1 = l4_utcb_mr()->mr[1]; for (;;) { #ifdef MEASURE s = l4_rdtsc(); #endif if (l4_msgtag_is_exception(tag)) { #ifndef MEASURE printf("PC=%08lx SP=%08lx Err=%08lx Trap=%lx, %s syscall, SC-Nr: %lx\n", l4_utcb_exc_pc(&exc), exc.sp, exc.err, exc.trapno, (exc.err & 4) ? " after" : "before", exc.err >> 3); #endif tag = l4_msgtag((exc.err & 4) ? 0 : L4_PROTO_ALLOW_SYSCALL, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); } else printf("Umm, non-handled request (like PF): %lx %lx\n", mr0, mr1); memcpy(l4_utcb_exc(), &exc, sizeof(exc)); /* Reply and wait */ if (l4_msgtag_has_error(tag = l4_ipc_call(alien, u, tag, L4_IPC_NEVER))) { printf("l4_ipc_call failed\n"); return 1; } memcpy(&exc, l4_utcb_exc(), sizeof(exc)); mr0 = l4_utcb_mr()->mr[0]; mr1 = l4_utcb_mr()->mr[1]; #ifdef MEASURE e = l4_rdtsc(); printf("time %lld\n", l4_tsc_to_ns(e - s)); #endif }
/* Our main function */ int main(void) { /* Get a capability slot for our new thread. */ l4_cap_idx_t t1 = l4re_util_cap_alloc(); l4_utcb_t *u = l4_utcb(); l4_exc_regs_t *e = l4_utcb_exc_u(u); l4_msgtag_t tag; int err; extern char _start[], _end[], _etext[]; if (l4_is_invalid_cap(t1)) return 1; /* Prevent pagefaults of our new thread because we do not want to * implement a pager as well. */ l4_touch_ro(_start, _end - _start + 1); l4_touch_rw(_etext, _end - _etext); /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_msgtag_has_error(tag)) return 1; /* Setup the thread by setting the pager and task. */ l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); tag = l4_thread_control_commit(t1); if (l4_msgtag_has_error(tag)) return 2; /* Start the thread by finally setting instruction and stack pointer */ tag = l4_thread_ex_regs(t1, (l4_umword_t)thread, (l4_umword_t)thread_stack + sizeof(thread_stack), L4_THREAD_EX_REGS_TRIGGER_EXCEPTION); if (l4_msgtag_has_error(tag)) return 3; /* Receive initial exception from just started thread */ tag = l4_ipc_receive(t1, u, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) { printf("Umm, ipc error: %x\n", err); return 1; } /* We expect an exception IPC */ if (!l4_msgtag_is_exception(tag)) { printf("PF?: %lx %lx (not prepared to handle this) %ld\n", l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag)); return 1; } /* Fill out the complete register set of the new thread */ e->ip = (l4_umword_t)thread; e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; /* Send a complete exception */ tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); /* Send reply and start the thread with the defined CPU register set */ tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) printf("Error sending IPC: %x\n", err); /* Idle around */ while (1) l4_sleep(10000); return 0; }
static void setup_memory(void) { l4_size_t phys_size; l4io_device_handle_t dh; l4io_resource_handle_t hdl; if (fb_vaddr) return; if (l4io_lookup_device("System Control", &dh, 0, &hdl)) { printf("Could not get system controller space\n"); return; } /* System controller -- XXX Wrong Place XXX */ amba_pl110_sys_base_virt = l4io_request_resource_iomem(dh, &hdl); if (amba_pl110_sys_base_virt == 0) { printf("Could not map system controller space\n"); return; } if (l4io_lookup_device("AMBA PL110", &dh, 0, &hdl)) { printf("Could not get PL110 LCD device\n"); return; } amba_pl110_lcd_control_virt_base = l4io_request_resource_iomem(dh, &hdl); if (amba_pl110_lcd_control_virt_base == 0) { printf("Could not map controller space for '%s'\n", arm_lcd_get_info()); return; } setup_type(); if ((read_sys_reg(Reg_sys_clcd) & Sys_clcd_idmask) == 0x1000) { is_qemu = 1; // remember if we run on qemu because of the different // handling of the bpp16 mode with PL110: my hardware has // 5551 mode, qemu does 565 type = PL111; // also set the type to PL111 because qemu only // announces a PL110 but can do the 1024 resolution too printf("Running on QEmu (assuming PL111).\n"); } if (config_request_xga && type == PL111) use_xga = 1; // get some frame buffer l4re_ds_t mem = l4re_util_cap_alloc(); if (l4_is_invalid_cap(mem)) return; if (l4re_ma_alloc(fbmem_size(), mem, L4RE_MA_CONTINUOUS | L4RE_MA_PINNED)) { printf("Error allocating memory\n"); return; } fb_vaddr = 0; if (l4re_rm_attach(&fb_vaddr, fbmem_size(), L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP, mem, 0, L4_PAGESHIFT)) { printf("Error getting memory\n"); return; } printf("Video memory is at virtual %p (size: 0x%x Bytes)\n", fb_vaddr, fbmem_size()); // get physical address if (l4re_ds_phys(mem, 0, &fb_paddr, &phys_size) || phys_size != fbmem_size()) { printf("Getting the physical address failed or not contiguous\n"); return; } printf("Physical video memory is at %p\n", (void *)fb_paddr); }
/* Our main function */ int main(void) { /* Get a capability slot for our new thread. */ l4_cap_idx_t t1 = l4re_util_cap_alloc(); l4_utcb_t *u = l4_utcb(); l4_exc_regs_t *e = l4_utcb_exc_u(u); l4_msgtag_t tag; int err; printf("Example showing how to start a thread with an exception.\n"); /* We do not want to implement a pager here, take the shortcut. */ printf("Make sure to start this program with ldr-flags=eager_map\n"); if (l4_is_invalid_cap(t1)) return 1; /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_error(tag)) return 1; /* Setup the thread by setting the pager and task. */ l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); tag = l4_thread_control_commit(t1); if (l4_error(tag)) return 2; /* Start the thread by finally setting instruction and stack pointer */ tag = l4_thread_ex_regs(t1, (l4_umword_t)thread, (l4_umword_t)thread_stack + sizeof(thread_stack), L4_THREAD_EX_REGS_TRIGGER_EXCEPTION); if (l4_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp); if (l4_error(tag)) return 4; /* Receive initial exception from just started thread */ tag = l4_ipc_receive(t1, u, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) { printf("Umm, ipc error: %x\n", err); return 1; } /* We expect an exception IPC */ if (!l4_msgtag_is_exception(tag)) { printf("PF?: %lx %lx (not prepared to handle this) %ld\n", l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag)); return 1; } /* Fill out the complete register set of the new thread */ e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); #ifdef ARCH_x86 e->ip = (l4_umword_t)thread; e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; #endif #ifdef ARCH_arm e->pc = (l4_umword_t)thread; e->r[0] = 0; e->r[1] = 1; e->r[2] = 2; e->r[3] = 3; e->r[4] = 4; e->r[5] = 5; e->r[6] = 6; e->r[7] = 7; #endif /* Send a complete exception */ tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); /* Send reply and start the thread with the defined CPU register set */ tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) printf("Error sending IPC: %x\n", err); /* Idle around */ while (1) l4_sleep(10000); return 0; }