void init_global_data(void) { l4_threadid_t dummyid = L4_INVALID_ID; dword_t foo = L4_INV; // *** this is the booter task, and the auxpager will be thread 1 booter = l4_myself(); auxpager = booter; auxpager.id.thread = 1; // *** use ex_regs to read the ID of my pager (should be sigma0) sigma0 = L4_INVALID_ID; l4_thread_ex_regs(booter, foo, foo, &dummyid, &sigma0, &foo, &foo, &foo); // *** initialize administrative structs for (int i=0;i<MAXTASKS;i++) task[i].active=0; for (int i=0;i<MAXBLOCKS;i++) block[i].active=0; }
/* * prevent all other threads from running */ void jthread_suspendall(void) { l4_umword_t old_eflags; l4_umword_t dummy; l4_msgdope_t result; l4_threadid_t src; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t pager = L4_INVALID_ID; jthread_t current = live; l4thread_t myself = l4thread_myself(); leaflet.gc = l4_myself(); // LOG("suspendall"); /* * ex-regs all threads and save their state */ while (current) { /** * NoHeapRealtimeThreads will not be stopped */ if (current->daemon==0 && #ifdef REALTIME_EXTENSION current->threadtype != THREADTYPE_NOHEAPREAL && #endif !l4thread_equal(current->l4thread,myself)) { l4_thread_ex_regs(l4thread_l4_id(current->l4thread), (unsigned long)_l4threads_suspendall, (l4_umword_t)-1, &preempter, &pager, &old_eflags,¤t->eip,¤t->esp); } current = current -> next; } /* * Waiting for the notification IPC of the last stopped thread */ { l4_ipc_wait(&src, L4_IPC_SHORT_MSG, &dummy, &dummy, L4_IPC_NEVER,&result); }while(!l4_tasknum_equal(leaflet.gc, src) || L4_IPC_ERROR(result) == L4_IPC_RECANCELED || L4_IPC_ERROR(result) == L4_IPC_REABORTED); // LOG("suspendall-complete"); }
void launch_aux_pager(void) { l4_threadid_t pager = sigma0; l4_threadid_t dummyid = L4_NIL_ID; dword_t foo = L4_INV; // *** Launch the auxiliary pager. Its job is to forward any pagefaults // received from the memory server to sigma0. It also maps the // trampoline page to newly created threads. l4_thread_ex_regs(auxpager, (dword_t) pager_server, (dword_t)&pager_stack[THREAD_STACK_SIZE-1], &dummyid, &pager, &foo, &foo, &foo); }
/* * restore threads */ void jthread_unsuspendall(void) { volatile unsigned long int * ret_addr; l4_umword_t old_eflags,dummy; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t pager = L4_INVALID_ID; l4thread_t myself = l4thread_myself(); jthread_t current = live; while (current) { /** * NoHeapRealtimeThreads are never stopped and therefore they are not resumed */ if (current->daemon==0 && #ifdef REALTIME_EXTENSION current->threadtype != THREADTYPE_NOHEAPREAL && #endif !l4thread_equal(current->l4thread,myself)) { current->esp -= 0x04; /* stack address for the return address*/ ret_addr = (unsigned long int *)current->esp; /* replace place holder with the eip*/ *ret_addr = current->eip; l4_thread_ex_regs(l4thread_l4_id(current->l4thread), (unsigned long)_l4threads_resumepoint, current->esp-0x24, &preempter, &pager, &old_eflags, &dummy, &dummy); } current = current -> next; } sleepcount = 0; }
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; }
/* 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; }
int main(l4_threadid_t tasksvr, int taskobj) { CORBA_Environment env = idl4_default_environment; l4_threadid_t rootsvr, memsvr; int rootobj, memobj; int x,y,z; unsigned int dummyint; l4_threadid_t mypagerid, dummyid, t; char *buf; myid = l4_myself(); printf("Test client started (%X), ",myid.raw); dummyid = mypagerid = L4_INVALID_ID;dummyint=0xFFFFFFFF; l4_thread_ex_regs(myid, 0xffffffff, 0xffffffff, &dummyid, &mypagerid, &dummyint, &dummyint, &dummyint); printf("pager is %X\n\n",mypagerid.raw); dummyid = mypagerid = L4_INVALID_ID; l4_thread_ex_regs(myid, 0xffffffff, 0xffffffff, &dummyid, &mypagerid, &dummyint, &dummyint, &dummyint); printf("========================== chacmOS tester V1.00 ==========================\n"); printf(" T01 task object is <%Xh,%d>\n",tasksvr.raw,taskobj); if (generic_implements(tasksvr,taskobj,sizeof(api_task)/sizeof(int),(sdword*)&api_task,&env)!=ESUCCESS) fail("task server does not implement generic or task api"); if (task_get_root(tasksvr,taskobj,&rootsvr,&rootobj,&env)!=ESUCCESS) fail("cannot get root from task server"); printf(" T02 root is <%Xh,%d>\n",rootsvr.raw,rootobj); if (generic_implements(rootsvr,rootobj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=ESUCCESS) fail("root does not implement generic or file or directory api"); if (task_get_memory(tasksvr,taskobj,&memsvr,&memobj,&env)!=ESUCCESS) fail("cannot get memory object from task server"); printf(" T03 this task's memory object is <%Xh,%d>\n",memsvr.raw,memobj); if (generic_implements(memsvr,memobj,sizeof(api_memory)/sizeof(int),(sdword*)&api_memory,&env)!=ESUCCESS) fail("memory server does not implement generic or memory api"); if (memory_get_pagerid(memsvr,memobj,&x,&env)!=ESUCCESS) fail("memory server won't tell me my pager id"); if (x!=(int)mypagerid.raw) fail("my pager id does not match the memory server"); if (task_get_cmdline(tasksvr,taskobj,&x,&buf,&env)!=ESUCCESS) fail("cannot read my command line"); printf(" T04 my command line is '%s'\n",buf); CORBA_free(buf); if (task_get_threadid(tasksvr,taskobj,&t,&env)!=ESUCCESS) fail("task server won't tell me my thread id"); if (t != myid) fail("task server lied about my thread id"); if (file_open(rootsvr,rootobj,0,&env)!=ESUCCESS) fail("cannot open root directory"); if (file_tell(rootsvr,rootobj,&x,&env)!=ESUCCESS) fail("cannot get file pointer position"); if (x!=0) fail("file pointer is not reset upon open"); if (file_seek(rootsvr,rootobj,-1,&env)!=ESUCCESS) fail("cannot set file pointer to end of file"); if (file_tell(rootsvr,rootobj,&x,&env)!=ESUCCESS) fail("cannot get file pointer position (second time)"); if (file_seek(rootsvr,rootobj,0,&env)!=ESUCCESS) fail("cannot set file pointer to beginning of file"); printf(" N01 root directory has %d bytes\n",x); if (x>79) x=79; y=file_read(rootsvr,rootobj,x,&z,&buf,&env); if (y<=0) { printf("err code %d\n",y); fail("cannot read root directory"); } if (z!=y) fail("return value of open() and data length don't match"); if (z!=x) fail("cannot read all of root directory"); buf[z]=0; printf(" N02 files contained: ("); x=0; while (z>0) { printf("'%s'",&buf[x]); while (buf[x++]) z--; } printf(")\n"); if (file_close(rootsvr,rootobj,&env)!=ESUCCESS) fail("cannot close root directory\n"); CORBA_free(buf); printf("\n"); #ifdef TEST_FILESVR handle_t fatfs, dev, hda; if (directory_resolve(rootsvr,rootobj,3,"dev",&dev.svr,&dev.obj,&env)!=ESUCCESS) fail("cannot find /dev"); if (generic_implements(dev.svr,dev.obj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=ESUCCESS) fail("/dev does not implement directory or file or generic api"); if (directory_resolve(dev.svr,dev.obj,3,"hda",&hda.svr,&hda.obj,&env)!=ESUCCESS) fail("cannot find /dev/hda"); if (generic_implements(hda.svr,hda.obj,sizeof(api_block)/sizeof(int),(sdword*)&api_block,&env)!=ESUCCESS) fail("/dev/hda does not implement block or generic api"); printf(" F01 found /dev/hda at <%X,%d>\n",hda.svr.raw,hda.obj); if (directory_resolve(dev.svr,dev.obj,5,"fatfs",&fatfs.svr,&fatfs.obj,&env)!=ESUCCESS) fail("cannot find /dev/fatfs"); if (generic_implements(fatfs.svr,fatfs.obj,sizeof(api_filesys)/sizeof(int),(sdword*)&api_filesys,&env)!=ESUCCESS) fail("/dev/fatfs does not implement filesystem or generic api"); printf(" F02 located /dev/fatfs at <%X,%d>\n",hda.svr.raw,hda.obj); if (filesystem_mount(fatfs.svr,fatfs.obj,&hda.svr,hda.obj,&env)!=ESUCCESS) fail("cannot mount /dev/hda into /dev/fatfs"); printf(" F03 mounted filesystem\n"); x=79; y=file_read(fatfs.svr,fatfs.obj,x,&z,&buf,&env); if (y<=0) fail("cannot read root directory of /dev/fatfs"); if (z>79) z=79; buf[z]=0; printf(" N02 files contained: ("); x=0; while (z>0) { printf("'%s'",&buf[x]); while (buf[x++]) z--; } printf(")\n"); if (file_close(fatfs.svr,fatfs.obj,&env)!=ESUCCESS) fail("cannot close root directory of /dev/fatfs\n"); CORBA_free(buf); printf("\n"); #endif /*TEST_FILESVR*/ #ifdef TEST_BLOCKDEVICE int capacity, blksize, size; if (directory_resolve(rootsvr,rootobj,3,"dev",&dev.svr,&dev.obj,&env)!=ESUCCESS) fail("cannot find /dev"); if (generic_implements(dev.svr,dev.obj,sizeof(api_directory)/sizeof(int),(sdword*)&api_directory,&env)!=ESUCCESS) fail("/dev does not implement directory or file or generic api"); if (directory_resolve(dev.svr,dev.obj,3,"hda",&hda.svr,&hda.obj,&env)!=ESUCCESS) fail("cannot find /dev/hda"); if (generic_implements(hda.svr,hda.obj,sizeof(api_block)/sizeof(int),(sdword*)&api_block,&env)!=ESUCCESS) fail("/dev/hda does not implement block or generic api"); printf(" B01 found /dev/hda at <%X,%d>\n",hda.svr.raw,hda.obj); if (block_get_capacity(hda.svr,hda.obj,&capacity,&env)!=ESUCCESS) fail("/dev/hda won't tell me its capacity"); if (block_get_blocksize(hda.svr,hda.obj,&blksize,&env)!=ESUCCESS) fail("/dev/hda won't tell me its block size"); printf(" B02 device reports %d blocks of %d bytes each (%dk)\n",capacity,blksize,(capacity*blksize)/1024); if (block_read(hda.svr,hda.obj,1,1,&size,&buf,&env)!=ESUCCESS) fail("cannot read block 1 of /dev/hda"); buf[10]=0; printf(" B03 block 1 reads '%s'\n",buf); strcpy((char*)&buf[3],"Variatio delectat"); if (block_write(hda.svr,hda.obj,1,1,21,buf,&env)!=ESUCCESS) fail("cannot write block 1 of /dev/hda"); CORBA_free(buf); if (block_read(hda.svr,hda.obj,1,1,&size,&buf,&env)!=ESUCCESS) fail("cannot reread block 1 of /dev/hda"); buf[10]=0; printf(" B04 after write, it is '%s'\n",buf); CORBA_free(buf); #endif /*TEST_BLOCKDEVICE*/ printf(" X01 test completed successfully\n"); while (42); }