int Syscall::kcall_threadregs(CoreData& core_data, Thread *currt) { /* * Read or write some thread data * * KPARM1 : pid * KPARM2 : tid * KPARM3 : *wr * KPARM4 : *rd * * KRETVAL : 0 or -ERRNO */ Thread *target_thr; regpack64_t *regpack_wr; regpack64_t *regpack_rd; struct _Anvil_tls *pptls_wr; struct _Anvil_tls *pptls_rd; if ((target_thr = get_thread_ref(KPARM1, KPARM2)) == NULL) { kdebug("kcall_threadregs got no thread %d %d\n", KPARM1, KPARM2); return -ESRCH; } kdebug("kcall_threadregs %d %d %016lx\n", KPARM1, KPARM2, target_thr); regpack_wr = (regpack64_t *)KPARM3; regpack_rd = (regpack64_t *)KPARM4; pptls_wr = (struct _Anvil_tls *)KPARM5; pptls_rd = (struct _Anvil_tls *)KPARM6; mm_ctx_set(target_thr->ctx); kdebug("kcall_threadregs 1\n"); if (regpack_rd) { *regpack_rd = target_thr->reg; } kdebug("kcall_threadregs 2\n"); if (regpack_wr) { target_thr->reg = *regpack_wr; } if (pptls_rd) { kdebug("kcall_threadregs 3 %016lx\n", target_thr->pptls); memcpy(pptls_rd, *(target_thr->pptls), sizeof(struct _Anvil_tls)); } if (pptls_wr) { kdebug("kcall_threadregs 4 %016lx\n", target_thr->pptls); memcpy(*(target_thr->pptls), pptls_wr, sizeof(struct _Anvil_tls) - sizeof(void *)); } kdebug("kcall_threadregs done !!\n"); target_thr->unref(); return 0; }
void Thread::init_tls(void (*return_func)()) { mm_ctx_set(ctx); struct _Anvil_tls *ptls = (struct _Anvil_tls *)reg.oldrsp; ptls->return_func = return_func; //kdebug("kcall_threadcreate - return func = %016lx\n", return_func); ptls->id = get_id() | ((get_pid() & 0x7fff) << 15); //kdebug("ID=%016lx id=%d pid=%d\n", ptls->id, get_id(), get_pid()); ptls->stackaddr = stackaddr; ptls->stacksize = stacksize; ptls->pself = ptls; pptls = &ptls->pself; }
void mm_ctx_destroy(mm_context *ctx) { /* * We need to make sure that if this is the current context that we * shift to another one. */ if (mm_ctx_get() == ctx) { /* Set it to context one which is always valid */ mm_ctx_set(ctx1); } mm_ctx_clean(ctx); kfree(ctx); }
int kthread_init() { Process *proc1; Thread *tnew; int err; int i; //struct _Anvil_tls *ptls; //kobj_thread_type = kobj_register_type(sizeof(kobj_thread_t), (void (*)(void *))thread_delete_callback); /* All these threads are going to be part of process 1 */ proc1 = proctable.getref(1); kdebug("proc1=%016lx pid=%d\n", proc1, proc1->get_id()); /* Create an idle thread for each core in ring 1 */ for (i=0; i<ksysinfo->num_cores; ++i) { /* TODO: allocate a proper stack */ void *stackaddr = kmm_page_alloc();//mm_mmap(k_ctx, 0, IDLESTACK_SIZE, //PROT_READ | PROT_WRITE, MAP_ANON | MAP_GUARD, -1, 0, NULL); memset(tnew->stackaddr, 0, IDLESTACK_SIZE); /* Seems okay so let's create a new thread */ tnew = new Thread((uint64_t)idle, (uint64_t)i, stackaddr, IDLESTACK_SIZE); // if ((err = proc1->thread_add(tnew)) != 0) // { // kprintf("kcall_threadcreate (kobj_create) - err %d\n", -err); // return -err; // } /* Initialise the thread context */ /* Now check whether we need to create a stack */ tnew->reg.cs = RING1_CS; tnew->reg.oldss = RING1_SS; tnew->set_state(THR_ST_RUNNING); tnew->priority = 0; tnew->max_addr = (char *)KERN_TOP; tnew->ctx = proc1->ctx; kdebug("pid=%d tid=%d\n", tnew->get_pid(), tnew->get_id()); sys.core_data[i].curr_thread = tnew; tnew->affinity = i; tnew->activate(); } void *stk_addr; err = mm_mmap(proc1->ctx, 0, 4 * __PAGESIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_GUARD, -1, 0, &stk_addr); /* Create the main thread in the init - runs in ring 3 */ tnew = new Thread(ksysinfo->init_program_info.ventry, 0, stk_addr, 4 * __PAGESIZE); if ((err = proc1->thread_add(tnew)) != 0) { kprintf("kcall_threadcreate (kobj_create) - err %d\n", -err); return -err; } tnew->ctx = proc1->ctx; mm_ctx_set(tnew->ctx); memset(tnew->stackaddr, 0, 4 * __PAGESIZE); tnew->max_addr = (char *)proc1->ctx->hi_addr; /* We've got a stack so put the TLS stuff on it */ // mm_ctx_set(tnew->ctx); // ptls = (struct _Anvil_tls *)tnew->reg.oldrsp; // ptls->return_func = NULL; // // ptls->id = tnew->get_id() | ((tnew->get_pid() & 0x7fff) << 15); // kdebug("ID=%d id=%d pid=%d tnew=%016lx\n", ptls->id, tnew->get_id(), tnew->get_pid(), tnew); // ptls->stackaddr = tnew->stackaddr; // ptls->stacksize = tnew->stacksize; // ptls->pself = ptls; // tnew->pptls = &ptls->pself; proc1->unref(); tnew->init_tls(NULL); /* 24 bytes for argc, argv and envp */ tnew->reg.oldrsp -= 24; sys.m_sched.add(tnew, 0); tnew->activate(); return 0; }