int thread_alloc(struct thread *thread) { unsigned int thread_no; int r; thread_no = rfl_alloc(thread_list); if (thread_no == -1U) { /* Run out of threads */ return 1; } assert(thread_no > 0); thread->id = L4_GlobalId((unsigned long)thread_no, 1); assert(hash_lookup(l4tid_to_thread, thread->id.raw) == NULL); r = hash_insert(l4tid_to_thread, thread->id.raw, thread); if (r == -1) { r = rfl_free(thread_list, (unsigned long)thread_no); /* We just removed it before, so it should be possible to reinsert */ assert(r == RFL_SUCCESS); return -1; } return 0; }
L4_ThreadId_t vmctrl_get_root_tid( void ) { void *kip = L4_GetKernelInterface(); // sigma0 = 0 + L4_ThreadIdUserBase(kip) // sigma1 = 1 + L4_ThreadIdUserBase(kip) // root task = 2 + L4_ThreadIdUserBase(kip) return L4_GlobalId( 2+L4_ThreadIdUserBase(kip), 1 ); }
L4_ThreadId_t thread_new(AddrSpace_t *space) { assert (space != NULL); L4_Word_t tno; L4_ThreadId_t tid; L4_ThreadId_t space_spec; L4_Word_t utcb_location; slab_t *sb; list_t *li; thread_t *this; mutex_lock(&thrlock); tno = threadno_find_free(bitmap, MAX_TASKS); if (!tno) { mutex_unlock(&thrlock); return L4_nilthread; } tid = L4_GlobalId(tno, 1); utcb_location = UTCB_AREA_LOCATION; space_spec = space->tid; tno = threadno_find_free(space->threads, MAX_THREADS_PER_TASK); if (!tno) { mutex_unlock(&thrlock); return L4_nilthread; } utcb_location += tno * UTCB_SIZE; sb = slab_alloc(&thrpool); if (!sb) { mutex_unlock(&thrlock); return L4_nilthread; } if (FALSE == (L4_ThreadControl(tid, space_spec, tid, space->pager, (void *) utcb_location))) { slab_free(&thrpool, sb); mutex_unlock(&thrlock); return L4_nilthread; } li = LIST_TYPE(sb->data); this = (thread_t *) li->data; list_push(&thread_list, li); this->tid = tid; this->space = space; this->index = tno; this->creation = L4_SystemClock(); threadno_alloc(bitmap, L4_ThreadNo(tid)); threadno_alloc(space->threads, tno); mutex_unlock(&thrlock); return tid; }
/** * Starts the clock driver. This will map the memory region where the * registers are in uncached mode, start the time stamp timer register * and enable the interrupts for our time stamp timer and the general * purpose timer 0. * * @return CLOCK_R_OK if the timer is started successfully * CLOCK_R_FAIL if the memory region could not be mapped */ int start_timer(void) { assert(!driver_initialized); // initialize variables timestamp_irq_tid = L4_GlobalId(NSLU2_TIMESTAMP_IRQ, 1); timer0_irq_tid = L4_GlobalId(NSLU2_TIMER0_IRQ, 1); registers_fpage = L4_FpageLog2(NSLU2_OSTS_PHYS_BASE, 12); // Set up uncached memory mapping for registers L4_Set_Rights(®isters_fpage, L4_FullyAccessible); L4_PhysDesc_t phys = L4_PhysDesc(NSLU2_OSTS_PHYS_BASE, L4_UncachedMemory); if(L4_MapFpage(L4_Pager(), registers_fpage, phys)) { // enable timer0 interrupts TIMER0_ONE_SHOT(0); TIMER0_STOP(); (*(L4_Word_t*)OST_STATUS) |= (0x1 << 0); int res = L4_AssociateInterrupt(timer0_irq_tid, root_thread_g); assert(res); // start timestamp timer *((L4_Word_t*)OST_TS) = 0x00000000; // reset counter // enable timestamp interrupts (*(L4_Word_t*)OST_STATUS) |= (0x1 << 2); res = L4_AssociateInterrupt(timestamp_irq_tid, root_thread_g); assert(res); driver_initialized = TRUE; return CLOCK_R_OK; } else { return CLOCK_R_FAIL; } }
int main( int argc, char *argv[] ) { L4_ThreadId_t earmmgr, locator; L4_MsgTag_t tag; L4_Msg_t msg; L4_Word_t logid = 0; L4_Word_t guid = 0; L4_Word_t budget = 0; CORBA_Environment ipc_env; if( argc < 3 ) usage(argv[0]); guid = strtoul(argv[1], NULL, 0); logid = strtoul(argv[2], NULL, 0); budget = strtoul(argv[3], NULL, 0); locator = L4_GlobalId( 2+L4_ThreadIdUserBase(L4_GetKernelInterface()), 1 ); printf("locator %p\n", locator.raw); ipc_env = idl4_default_environment; IResourcemon_query_interface( locator, UUID_IEarm_Manager, &earmmgr, &ipc_env ); if( ipc_env._major == CORBA_USER_EXCEPTION ) { CORBA_exception_free(&ipc_env); return -ENODEV; } else if( ipc_env._major != CORBA_NO_EXCEPTION ) { CORBA_exception_free(&ipc_env); return -EIO; } printf("earm mgr %p\n", earmmgr.raw); printf("Setting guid %d logid %d budget %d\n", guid, logid, budget); ipc_env = idl4_default_environment; IEarm_Manager_budget_resource( earmmgr, guid, logid, budget, &ipc_env ); }
static L4_ThreadId_t create_local_thread(char *desc, L4_KernelInterfacePage_t *kip, int idx, threadfunc_t func, L4_Word_t stack_size) { L4_Word_t utcb_size = L4_UtcbSize(kip); L4_Word_t my_utcb = L4_MyLocalId().raw; my_utcb = (my_utcb & ~(utcb_size - 1)); L4_ThreadId_t tid = L4_GlobalId(L4_ThreadNo(L4_Myself()) + idx, 1); L4_Word_t utcb_location = my_utcb + idx * utcb_size; if (FALSE == L4_ThreadControl(tid, L4_Myself(), L4_Myself(), L4_Pager(), (void *) utcb_location)) { printf("panic: can't execute %s: error code %d\n", desc, (int) L4_ErrorCode()); return L4_nilthread; } void *stack = kmalloc(stack_size); L4_Start_SpIp(tid, (L4_Word_t) stack + stack_size - 32, (L4_Word_t) func); return tid; }
static L4_ThreadId_t thread_offset(int i) { L4_ThreadId_t t = main_thread; return L4_GlobalId(L4_ThreadNo(t) + (i+16), 1); }
L4_ThreadId_t vpager(void) { L4_Word_t id = ipc_send_simple_0(L4_rootserver, SOS_VPAGER, YES_REPLY); return L4_GlobalId(id, 1); }
void freevms_main(void) { char *command_line; # define ROOT_DEVICE_LENGTH 80 char root_device[ROOT_DEVICE_LENGTH]; # define CONSOLE_DEVICE_LENGTH 80 char console_device[CONSOLE_DEVICE_LENGTH]; L4_BootRec_t *boot_record; L4_KernelInterfacePage_t *kip; L4_ProcDesc_t *main_proc_desc; L4_ThreadId_t root_tid; L4_ThreadId_t s0_tid; L4_Word_t api_flags; L4_Word_t boot_info; L4_Word_t i; L4_Word_t kernel_id; L4_Word_t kernel_interface; L4_Word_t num_boot_info_entries; L4_Word_t num_processors; L4_Word_t page_bits; L4_Word_t pagesize; struct vms$meminfo mem_info; vms$pd_initialized = 0; notice("\n"); notice(">>> FreeVMS %s (R)\n", FREEVMS_VERSION); notice("\n"); kip = (L4_KernelInterfacePage_t *) L4_KernelInterface(&kernel_interface, &api_flags, &kernel_id); notice(SYSBOOT_I_SYSBOOT "leaving kernel privileges\n"); notice(SYSBOOT_I_SYSBOOT "launching FreeVMS kernel with executive " "privileges\n"); root_tid = L4_Myself(); s0_tid = L4_GlobalId(kip->ThreadInfo.X.UserBase, 1); notice(SYSBOOT_I_SYSBOOT "booting main processor\n"); for(page_bits = 0; !((1 << page_bits) & L4_PageSizeMask(kip)); page_bits++); pagesize = (((vms$pointer) 1) << page_bits); notice(SYSBOOT_I_SYSBOOT "computing page size: %d bytes\n", (int) pagesize); num_processors = L4_NumProcessors((void *) kip); switch(num_processors - 1) { case 0: break; case 1: notice(SYSBOOT_I_SYSBOOT "booting %d secondary processor\n", (int) (num_processors - 1)); break; default: notice(SYSBOOT_I_SYSBOOT "booting %d secondary processors\n", (int) (num_processors - 1)); break; } for(i = 0; i < num_processors; i++) { main_proc_desc = L4_ProcDesc((void *) kip, i); notice(SYSBOOT_I_SYSBOOT "CPU%d EXTFREQ=%d MHz, INTFREQ=%d MHz\n", (int) i, (int) (main_proc_desc->X.ExternalFreq / 1000), (int) (main_proc_desc->X.InternalFreq / 1000)); } L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(L4_BootInfo(kip), pagesize)); boot_info = L4_BootInfo((void *) kip); num_boot_info_entries = L4_BootInfo_Entries((void *) boot_info); boot_record = L4_BootInfo_FirstEntry((void *) boot_info); for(i = 2; i < num_boot_info_entries; i++) { PANIC(L4_BootRec_Type(boot_record) != L4_BootInfo_SimpleExec); command_line = L4_SimpleExec_Cmdline(boot_record); if ((strstr(command_line, "vmskernel.sys") != NULL) && (i == 3)) { break; } boot_record = L4_BootRec_Next(boot_record); } PANIC(L4_BootRec_Type(boot_record) != L4_BootInfo_SimpleExec); command_line = L4_SimpleExec_Cmdline(boot_record); notice(SYSBOOT_I_SYSBOOT "parsing command line: %s\n", command_line); sys$parsing(command_line, (char *) "root", root_device, ROOT_DEVICE_LENGTH); notice(SYSBOOT_I_SYSBOOT "selecting root device: %s\n", root_device); sys$parsing(command_line, (char *) "console", console_device, CONSOLE_DEVICE_LENGTH); notice(SYSBOOT_I_SYSBOOT "selecting console device: %s\n", console_device); dbg$virtual_memory = (strstr(command_line, " dbg$virtual_memory") != NULL) ? 1 : 0; dbg$sys_pagefault = (strstr(command_line, " dbg$sys_pagefault") != NULL) ? 1 : 0; dbg$vms_pagefault = (strstr(command_line, " dbg$vms_pagefault") != NULL) ? 1 : 0; // Starting virtual memory subsystem sys$mem_init(kip, &mem_info, pagesize); sys$bootstrap(&mem_info, pagesize); sys$objtable_init(); sys$utcb_init(kip); sys$pd_init(&mem_info); sys$thread_init(kip); sys$populate_init_objects(&mem_info, pagesize); dev$init(); names$init(); sys$pager(kip, &mem_info, pagesize, root_device); sys$init(kip, &mem_info, pagesize, root_device); sys$loop(); notice(">>> System halted\n"); return; }
AddrSpace_t *task_new(L4_ThreadId_t pager) { L4_Word_t tno; L4_ThreadId_t tid; L4_ThreadId_t space_spec; L4_Word_t utcb_location; AddrSpace_t *space = NULL; slab_t *sb; list_t *li; thread_t *this; mutex_lock(&thrlock); tno = threadno_find_free(bitmap, MAX_TASKS); if (!tno) { mutex_unlock(&thrlock); return NULL; } tid = L4_GlobalId(tno, 1); utcb_location = UTCB_AREA_LOCATION; space_spec = tid; sb = slab_alloc(&thrpool); if (!sb) { mutex_unlock(&thrlock); return NULL; } if (FALSE == (L4_ThreadControl(tid, space_spec, L4_Myself(), L4_nilthread, (void *) utcb_location))) { slab_free(&thrpool, sb); mutex_unlock(&thrlock); return NULL; } space = address_space_new(tid, pager); if (!space) { L4_ThreadControl(tid, L4_nilthread, L4_nilthread, L4_nilthread, (void *) -1); slab_free(&thrpool, sb); mutex_unlock(&thrlock); return NULL; } else { /* set self space, and the specified pager * FIXME - using myself as the scheduler */ L4_ThreadControl(tid, tid, L4_Myself(), pager, (void *) -1); } li = LIST_TYPE(sb->data); this = (thread_t *) li->data; list_push(&thread_list, li); this->tid = tid; this->space = space; this->index = 0; this->creation = L4_SystemClock(); threadno_alloc(bitmap, L4_ThreadNo(tid)); threadno_alloc(space->threads, 0); mutex_unlock(&thrlock); return space; }
static void ipc_irq_setup(struct new_bench_test *test, int args[]) { int r; L4_Word_t utcb; L4_Word_t utcb_size; // L4_Word_t dummy; num_iterations = args[0]; handler_space = L4_nilspace; /* We need a maximum of two threads per task */ utcb_size = L4_GetUtcbSize(); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb =(L4_Word_t)L4_GetUtcbBase() + utcb_size; #endif /* Create pager */ master_tid = KBENCH_SERVER; pager_tid.raw = KBENCH_SERVER.raw + 1; handler_tid.raw = KBENCH_SERVER.raw + 2; interrupt = PMU_IRQ; #if SPINNER spinner_tid = L4_GlobalId (L4_ThreadNo (master_tid) + 3, 2); #endif r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); if (r == 0 && (L4_ErrorCode() == 2)) { r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert(r == 1); r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); assert(r == 1); } L4_KDB_SetThreadName(pager_tid, "pager"); //L4_Schedule(pager_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); L4_Set_Priority(pager_tid, 254); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); L4_Receive(pager_tid); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl(handler_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void *) utcb); assert(r == 1); L4_KDB_SetThreadName(handler_tid, "handler"); L4_Set_Priority(handler_tid, 100); // Startup notification, start handler thread //printf("register irq %ld, to %lx\n", interrupt, handler_tid.raw); L4_Word_t control = 0 | (0 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot register interrupt %lu\n", interrupt); } L4_Start_SpIp (handler_tid, (L4_Word_t) handler_stack + sizeof(handler_stack) - 32, START_ADDR(handler)); L4_Receive(handler_tid); #if SPINNER //Create spinner thread #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl (spinner_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void*) utcb); if (r == 0) printf("create spinner failed %ld\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(spinner_tid, "spinner"); //L4_Schedule(spinner_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); //Set priority to the lowest. L4_Set_Priority(spinner_tid, 1); L4_Start_SpIp (spinner_tid, (L4_Word_t) spinner_stack + sizeof(spinner_stack) - 32, START_ADDR (spinner)); #endif }
void __lib_iguana_init_pager(void) { __iguana_pager = L4_GlobalId(0, 0); }