void malloc_panic(void) { printf("testbench: %s called in %lu:%lu, returns %p, %p, %p!\n", __func__, L4_ThreadNo(L4_Myself()), L4_Version(L4_Myself()), __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); abort(); }
/* * This function loads the entire elf file into the phsical frames and * maps fpages corresponding to virtual address in elf file to the process */ int load_code_segment_virtual(char *elfFile,L4_ThreadId_t new_tid) { uint32_t min[2]; uint32_t max[2]; elf_getMemoryBounds(elfFile, 0, (uint64_t*)min, (uint64_t*)max); //Now we need to reserve memory between min and max L4_Word_t lower_address = ((L4_Word_t) min[1] / PAGESIZE) * PAGESIZE; L4_Word_t upper_address = ((L4_Word_t) max[1] / PAGESIZE) * PAGESIZE; while(lower_address <= upper_address) { L4_Word_t frame = frame_alloc(); if(!frame) { //Oops out of frames unmap_process(new_tid); return -1; } else { L4_Fpage_t targetpage = L4_FpageLog2(lower_address,12); lower_address += PAGESIZE; //Now map fpage L4_Set_Rights(&targetpage,L4_FullyAccessible); L4_PhysDesc_t phys = L4_PhysDesc(frame, L4_DefaultMemory); //Map the frame to root task but enter entries in pagetable with tid since we will update the mappings once elf loading is done if (L4_MapFpage(L4_Myself(), targetpage, phys) ) { page_table[(frame-new_low)/PAGESIZE].tid = new_tid; page_table[(frame-new_low)/PAGESIZE].pinned = 1; page_table[(frame-new_low)/PAGESIZE].pageNo = targetpage; } else { unmap_process(new_tid); } } } //Now we have mapped the pages, now load elf_file should work with the virtual addresses if(elf_loadFile(elfFile,0) == 1) { //Elffile was successfully loaded //Map the fpages which were previously mapped to Myself to the tid for(int i=0;i<numPTE;i++) { if(L4_ThreadNo(new_tid) == L4_ThreadNo(page_table[i].tid)) { //Now remap the pages which were mapped to root task to the new tid L4_UnmapFpage(L4_Myself(),page_table[i].pageNo); L4_PhysDesc_t phys = L4_PhysDesc(new_low + i * PAGESIZE, L4_DefaultMemory); if(!L4_MapFpage(new_tid, page_table[i].pageNo, phys)) { unmap_process(new_tid); return -1; } } } } else { unmap_process(new_tid); } //Remove later L4_CacheFlushAll(); return 0; }
/* * The Philosopher thread tries to take the 2 chopsticks closest to him * (according to its number and the number of each chopstick) in order to eat. */ void philosopher(int argc, char **argv) { int left, right, first, second, mynum = 0; L4_Word_t me = L4_Myself().raw; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { mynum = atoi(argv[0]); } else { printf("(Philosopher 0x%lx) Error: Argument(s) missing!\n", me); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(dp_main); } // Have to take chopsticks according to "my number" left = mynum; if (chopstick[mynum + 1]) { right = mynum + 1; } else { right = 0; } // This should allow to avoid deadlock when trying to grab the chopsticks. first = left < right ? left : right; second = first == left ? right : left; //printf("Philosopher %d: %lx, managed by %lx\n", mynum, me, dp_main.raw); //printf("Philosopher %d: chopsticks %d and %d\n", mynum, left, right); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); while (meal_served == 0) ; okl4_libmutex_count_lock(chopstick[first]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, first, chopstick[first]); okl4_libmutex_count_lock(chopstick[second]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, second, chopstick[second]); //printf("Philosopher %d/%lx is eating\n", mynum, me); okl4_libmutex_count_unlock(chopstick[second]); okl4_libmutex_count_unlock(chopstick[first]); //printf("Philosopher %d: %lx/%lx finished eating\n", mynum, me, dp_main.raw); L4_Set_Label(&tag, 0xfed); L4_Set_MsgTag(tag); L4_Send(dp_main); L4_Send(L4_Myself()); }
static void mutex0403_worker_thread(void) { int i; for (i = 0; i < 100; i++) { L4_Lock(m); mutex0403_lock_holder = L4_Myself(); L4_Yield(); fail_unless(mutex0403_lock_holder.raw == L4_Myself().raw, "Protected counter changed while we held the lock."); L4_Unlock(m); L4_Yield(); } L4_Send(main_thread); L4_WaitForever(); }
END_TEST START_TEST(test_mutex_count_lock) { struct mutex m; mutex_t mtx = &m; L4_Word_t me = L4_Myself().raw; mutex_init(mtx); mutex_count_lock(mtx); fail_if(mtx->holder != me, "Mutex is not held by me"); fail_if(mtx->count != 1, "Mutex count is wrong"); mutex_count_lock(mtx); fail_if(mtx->count != 2, "Mutex count is wrong"); mutex_count_lock(mtx); fail_if(mtx->count != 3, "Mutex count is wrong"); mutex_count_unlock(mtx); fail_if(mtx->holder != me, "Mutex is not held by me"); fail_if(mtx->count != 2, "Mutex count is wrong"); mutex_count_unlock(mtx); fail_if(mtx->holder != me, "Mutex is not held by me"); fail_if(mtx->count != 1, "Mutex count is wrong"); mutex_count_unlock(mtx); fail_if(mtx->holder != 0, "Mutex has not been unlocked properly"); fail_if(mtx->count != 0, "Mutex count is wrong"); }
int init_transport(struct ip_addr server) { struct pbuf *pbuf; udp_cnx = udp_new(); udp_recv(udp_cnx, time_recv, (void*) L4_Myself().raw); udp_bind(udp_cnx, IP_ADDR_ANY, NFS_LOCAL_PORT); udp_connect(udp_cnx, &server, 37 /* Time port */); do { pbuf = pbuf_alloc(PBUF_TRANSPORT, UDP_PAYLOAD, PBUF_RAM); udp_send(udp_cnx, pbuf); sos_usleep(100); pbuf_free(pbuf); } while (time_of_day == 0); udp_remove(udp_cnx); cur_xid = time_of_day * 10000; /* Generate a randomish xid */ udp_cnx = udp_new(); udp_recv(udp_cnx, my_recv, NULL); udp_connect(udp_cnx, &server, 0); udp_bind(udp_cnx, IP_ADDR_ANY, NFS_LOCAL_PORT); return 0; }
int okl4_mutex_trylock(okl4_mutex_t m) { L4_Word_t me = L4_Myself().raw; return !try_lock(m, me); }
// FIXME: Pass a list of 'resources' rather than a single address+irq number, which may // not always be sufficient. static void scan_devices(void) { CORBA_Environment env; L4_ThreadId_t me = L4_Myself(); thread_ref_t server_; cap_t device; /* timer device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTIMER_SERVER")), &server_); timer_server = thread_l4tid(server_); device_add_resource(timer_server, 0x40a00000,0, MEMORY_RESOURCE, &env); device_add_resource(timer_server, 27,0, INTERRUPT_RESOURCE, &env); device_add_resource(timer_server, 28,0, INTERRUPT_RESOURCE, &env); device = device_create(timer_server, &me, TIMER, &env); timer_device = device.ref.obj; /* rtc device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); device_add_resource(rtc_server, RTC_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(rtc_server, INT_RTC, 0, INTERRUPT_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; /* serial device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VSERIAL_SERVER")), &server_); serial_server = thread_l4tid(server_); device_add_resource(serial_server, 0x40100000,0, MEMORY_RESOURCE, &env); device_add_resource(serial_server, 22,0, INTERRUPT_RESOURCE, &env); device = device_create(serial_server, &me, UART1, &env); serial_device = device.ref.obj; #if 0 /* serial device */ memsection_lookup(iguana_getenv(IGUANA_GETENV_VBUS_SERVER), &server_); bus_server = thread_l4tid(server_); device_add_resource(bus_server, 101,0, INTERRUPT_RESOURCE, &env); device = device_create(bus_server, &me, BUS, &env); bus_device = device.ref.obj; DEBUG_TRACE(2, "looking for LCD device\n"); cap_t virtual_bus = virtual_bus_factory_create(bus_server, bus_device, &lcd_server, 0, NULL); /* LCD device */ memsection_lookup(iguana_getenv(IGUANA_GETENV_VLCD_SERVER), &server_); lcd_server = thread_l4tid(server_); device_add_resource(lcd_server, bus_server.raw, virtual_bus.ref.obj, BUS_RESOURCE, &env); device_add_resource(lcd_server, bus_server.raw, virtual_bus.ref.obj, BUS_RESOURCE, &env); device_add_resource(lcd_server, 101,0, INTERRUPT_RESOURCE, &env); device = device_create(lcd_server, &me, LCD, &env); lcd_device = device.ref.obj; #endif // And any other devices you care to add ... }
static void thread_simple_spinner_main (void) { int thrd_num = get_thread_num(L4_Myself()); clear_counters(5); thread_simple_spinner_start = 1; while(thread_simple_spinner_cleanup == 0) { if(counter[thrd_num]++ % 50000 == 0) { VERBOSE_HIGH("### %d %d\n", (int)thrd_num, (int)counter[thrd_num]); } if (counter[thrd_num] > 0x00100000) thread_simple_spinner_cleanup = 1; // done } L4_Call(L4_Myself()); }
void mutex_lock(mutex_t *m) { L4_Word_t me = L4_Myself().raw; while (!try_lock(m, me)) { L4_ThreadSwitch(L4_nilthread); } }
static void thread_simple_spinner (void *arg) { int thrd_num = get_thread_num(L4_Myself()); int dummy; while(thread_simple_spinner_start == 0) ; while(thread_simple_spinner_cleanup == 0) { if(counter[thrd_num]++ % 50000 == 0) { VERBOSE_HIGH("### %d %d\n", (int)thrd_num, (int)counter[thrd_num]); } if (counter[thrd_num] > 0x00100000) dummy = 1; // done } L4_Call(L4_Myself()); }
void __assert_failure( const char *condition, const char *file, unsigned int line, const char *function) { if(in_test()) { printf("Bail out! %s:%d assert failure `%s'\n", file, line, condition); exit_on_fail(); } else { printf("testbench %lu:%lu %s(`%s', `%s', %u, `%s')\n", L4_ThreadNo(L4_Myself()), L4_Version(L4_Myself()), __func__, condition, file, line, function); abort(); for(;;) { asm volatile("int $1"); } } }
void thread_block(void) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgTag_t tag = L4_Receive(L4_Myself()); if (L4_IpcFailed(tag)) { printf("!!! thread_block: failed, tag=%lx\n", tag.raw); } }
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; }
void okl4_mutex_lock(okl4_mutex_t m) { L4_Word_t me = L4_Myself().raw; L4_ThreadId_t holder; holder.raw = m->holder; while (!try_lock(m, me)) { L4_ThreadSwitch(holder); } }
// Block a thread forever static void thread_block(void) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgTag_t tag = L4_Receive(L4_Myself()); if (L4_IpcFailed(tag)) { printf("blocking thread failed: %lx\n", tag.raw); *(char *) 0 = 0; } }
void thread_get_capability(HpfCapability *cap, L4_ThreadId_t tid, L4_Word_t flags) { list_t *li; assert(cap != NULL); memset(cap, 0, sizeof(HpfCapability)); li = list_find(thread_list, &tid, sizeof(L4_ThreadId_t)); if (!li) return; hpf_capability_new(cap, L4_Myself(), (L4_Word_t) tid.raw, flags, (L4_Word_t) THREAD_TYPE(li->data)->creation.raw); }
struct pbuf * rpc_call(struct pbuf *pbuf, int port) { L4_ThreadId_t from; opaque_auth_t auth; reply_stat r; /* Send the thing */ rpc_send(pbuf, port, signal, NULL, L4_Myself().raw); /* We wait for a reply */ L4_Wait(&from); pbuf_adv_arg(call_pbuf, 0, 8); /* check if it was an accepted reply */ getfrombuf(call_pbuf, (char*) &r, sizeof(r)); if(r != MSG_ACCEPTED) { debug( "Message NOT accepted (%d)\n", r ); /* extract error code */ getfrombuf(call_pbuf, (char*) &r, sizeof(r)); debug( "Error code %d\n", r ); if(r == 1) { /* get the auth problem */ getfrombuf(call_pbuf, (char*) &r, sizeof(r)); debug( "auth_stat %d\n", r ); } return 0; } /* and the auth data!*/ getfrombuf(call_pbuf, (char*) &auth, sizeof(auth)); debug("Got auth data. size is %d\n", auth.size); /* check its accept stat */ getfrombuf(call_pbuf, (char*) &r, sizeof(r)); if( r == SUCCESS ) return call_pbuf; else { debug( "reply stat was %d\n", r ); return NULL; } }
static void synch_pong (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; VERBOSE_HIGH("Pong running\n"); while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; L4_LoadMR (0, 0); L4_Send(caller); } L4_Call(L4_Myself()); }
/* * Init function to initialise the page table entries */ L4_Word_t pager_init(L4_Word_t low, L4_Word_t high) { //The frames have been used to set up page table entries as well page_table = (sos_PTE*) low; // Use a simple algaebric formula to calculate optimum size of page table for the // amount of memory available //new_low points to the memory to be used now, memory low -> new_low is the pagetable new_low = ((double)high*sizeof(sos_PTE)+PAGESIZE*(double)low)/ (double)(PAGESIZE+sizeof(sos_PTE)); // align it new_low = (new_low/PAGESIZE)*PAGESIZE + PAGESIZE; numPTE = (high-new_low)/PAGESIZE; printf("low: %lx new_low: %lx high: %lx numPTE: %d \n", low, new_low, high, numPTE); //printf("value of swap memory %p \n",swap_table); // initialize the empty page table. for (int i = 0; i < numPTE; i++) { page_table[i].tid = L4_nilthread; page_table[i].referenced = 0; page_table[i].dirty = 0; page_table[i].being_updated = 0; page_table[i].error_in_transfer = 0; page_table[i].pinned = 0; } for(int i=0;i<MAX_SWAP_ENTRIES;i++) { swap_table[i].tid = L4_nilthread; swap_table[i].offset = PTE_SENTINEL; //Initially all entries are free so each points to the next one in the table swap_table[i].next_free = i+1; } // add a guard page against stack overflows and let it map to 0 L4_Word_t guardPage = 0x7000000; L4_PhysDesc_t phys = L4_PhysDesc(0, L4_DefaultMemory); L4_Fpage_t targetFpage = L4_FpageLog2(guardPage, 12); L4_Set_Rights(&targetFpage, L4_Readable); if ( !L4_MapFpage(L4_Myself(), targetFpage, phys) ) { sos_print_error(L4_ErrorCode()); printf(" Can't map guard page\n"); } return new_low; }
static void synch_ping (void *arg) { L4_ThreadId_t partner; L4_MsgTag_t tag; VERBOSE_HIGH("Ping running\n"); /* XXX partner always thread 0 (created before us) */ partner = get_thread_id(0); while(pingpong_cleanup == 0) { L4_LoadMR (0, 0); L4_Send(partner); tag = L4_Wait(&partner); } L4_Call(L4_Myself()); }
/** * DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked. * If the semaphore is 'full', it is taken and control is returned * to the caller. If the time indicated in 'timeout' is reached, * the thread will unblock and return an error indication. If the * timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block; * if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until * the semaphore is available. * * */ static IX_STATUS ixOsalSemaphoreWaitInternal(struct semaphore *sem, bool wait) { IX_STATUS ixStatus = IX_SUCCESS; // Get the lock, decrement the count, add to queue, get out with count ixOsalFastMutexLock(&sem->fInterlockP); // Will need to block eventually int mycount = sem->fCount--; if (mycount <= 0) { if (!wait) { sem->fCount++; ixStatus = IX_FAIL; } else { // we are going to wait so add to queue struct tid_list entry, **add; // Find end of tid_list XXX why not use a STAIL list? for (add = &(sem->fQueue); *add; add = &((*add)->fNext)) ; entry.fTid = L4_Myself(); entry.fNext = NULL; *add = &entry; } } ixOsalFastMutexUnlock(&sem->fInterlockP); if (mycount <= 0 && ixStatus != IX_FAIL) { // We are going to wait, but anything can wake us up // This is a bad assumption we could wake on anything FIXME L4_ThreadId_t partner; L4_Wait(&partner); } return ixStatus; }
static void synch_recv (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; int i; int j=1000; while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; for (i=0; i < j; i++) ; j+=1000; if ((pingpong_counter % 50) == 0) { printf(" %d: %d\n", pingpong_counter, j); } } L4_Call(L4_Myself()); }
int main(void) { /* initialise communication */ ttyout_init(); // invalid access: //*(char *) 0x30000000 = 123; //*(char *) NULL = 123; pt_test(); L4_ThreadId_t myid; /*assert( ((int)&stack_space) > 0x2000000); stack_space[0] = 'a'; stack_space[1025] = 'b'; //L4_Word_t utcb_location = (L4_Word_t) L4_GetUtcbBase(); //printf("utcb is at: %ud", utcb_location); printf("stack addr: %X\n", (int)&stack_space);*/ myid = L4_Myself(); do { printf("task:\tHello world, I'm\t0x%lx!\n", L4_ThreadNo(myid)); sos_write("123456789012345\n", 0, 16, NULL); sos_write("1234567890123456789\n", 0, 20, NULL); sos_write("abcdefghijklmnop\n", 0, 17, NULL); sos_write("abc\n", 0, 4, NULL); thread_block(); // sleep(1); // Implement this as a syscall } while(1); return 0; }
/* * Function to initialise swapfile, create it if not present */ void initialise_swap() { nfs_lookup(&mnt_point,SWAPFILE,initialise_swap_callback,L4_Myself().raw); }
// FIXME: Pass a list of 'resources' rather than a single address+irq number, which may // not always be sufficient. static void scan_devices(void) { CORBA_Environment env; L4_ThreadId_t me = L4_Myself(); thread_ref_t server_; cap_t device; /* timer device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTIMER_SERVER")), &server_); timer_server = thread_l4tid(server_); device_add_resource(timer_server, TIMER2_PHYS, 0, MEMORY_RESOURCE, &env); /* XXX only use timer2 */ device_add_resource(timer_server, INT_TIMER2, 0, INTERRUPT_RESOURCE, &env); device = device_create(timer_server, &me, TIMER, &env); timer_device = device.ref.obj; #if 0 // andy - 4 /* rtc device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); device_add_resource(rtc_server, RTC_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(rtc_server, INT_RTC, 0, INTERRUPT_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; #endif // andy - 4 /* This is an example of how to setup a software rtc. */ #if 0 memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VRTC_SERVER")), &server_); rtc_server = thread_l4tid(server_); /* Create virtual timer and pass to rtc_device as a resource.*/ cap_t virtual_timer = virtual_timer_factory_create(timer_server, timer_device, &rtc_server, 0x3, NULL); device_add_resource(rtc_server, timer_server.raw, virtual_timer.ref.obj, TIMER_RESOURCE, &env); device = device_create(rtc_server, &me, RTC, &env); rtc_device = device.ref.obj; #endif /* serial device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VSERIAL_SERVER")), &server_); serial_server = thread_l4tid(server_); device_add_resource(serial_server, UART1_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(serial_server, INT_UART1, 0, INTERRUPT_RESOURCE, &env); device = device_create(serial_server, &me, UART, &env); serial_device = device.ref.obj; #if 0 // andy - 5 /* touchscreen device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VTOUCH_SERVER")), &server_); ts_server = thread_l4tid(server_); device_add_resource(ts_server, TS_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(ts_server, INT_TC, 0, INTERRUPT_RESOURCE, &env); device_add_resource(ts_server, INT_ADC, 0, INTERRUPT_RESOURCE, &env); device = device_create(ts_server, &me, VTOUCH, &env); ts_device = device.ref.obj; /* spi device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VBUS_SERVER")), &server_); spi_server = thread_l4tid(server_); device_add_resource(spi_server, SPI_PHYS, 0, MEMORY_RESOURCE, &env); device_add_resource(spi_server, INT_SPI1, 0, INTERRUPT_RESOURCE, &env); device = device_create(spi_server, &me, SPI1, &env); spi_device = device.ref.obj; /* nand device */ memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VMTD_SERVER")), &server_); mtd_server = thread_l4tid(server_); device_add_resource(mtd_server, MTD_PHYS, 0, MEMORY_RESOURCE, &env); device = device_create(mtd_server, &me, NAND, &env); mtd_device = device.ref.obj; /* get a bus handle to provide to the lcd driver */ cap_t virtual_spi = virtual_bus_factory_create(spi_server, spi_device, &lcd_server, 0, NULL); #endif // andy - 5 /* lcd device */ // TEMP: REMOVED (jmatthews): causes NPE /* memsection_lookup((objref_t) env_memsection_base(iguana_getenv("OKL4_VLCD_SERVER")), */ /* &server_); */ /* lcd_server = thread_l4tid(server_); */ /* device_add_resource(lcd_server, LCD_PHYS, 0, MEMORY_RESOURCE, &env); */ /* //device_add_resource(lcd_server, spi_server.raw, virtual_spi.ref.obj, BUS_RESOURCE, &env); */ /* device_add_resource(lcd_server, spi_server.raw, 0, BUS_RESOURCE, &env); */ /* device_add_resource(lcd_server, INT_LCD, 0, INTERRUPT_RESOURCE, &env); */ /* device = device_create(lcd_server, &me, LCD, &env); */ /* lcd_device = device.ref.obj; */ // And any other devices you care to add ... 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; }
void service_init(HpfCapability *cap) { my_secret = rand(); hpf_capability_new(&file_cap, L4_Myself(), 0, HPF_CAP_PERM_FULL, my_secret); *cap = file_cap; }
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; }