diff --git a/hermit/arch/x86/kernel/tasks.c b/hermit/arch/x86/kernel/tasks.c index fd1e9d534..824db8d1c 100644 --- a/hermit/arch/x86/kernel/tasks.c +++ b/hermit/arch/x86/kernel/tasks.c @@ -67,6 +67,7 @@ static inline void enter_user_task(size_t ep, size_t stack) static int thread_entry(void* arg, size_t ep) { task_t* curr_task = per_core(current_task); +#if 0 size_t addr, stack = 0; size_t flags; int64_t npages; @@ -99,27 +100,29 @@ static int thread_entry(void* arg, size_t ep) // create vma regions for the user-level stack flags = VMA_CACHEABLE|VMA_USER|VMA_READ|VMA_WRITE; vma_add(stack, stack+npages*PAGE_SIZE-1, flags); +#endif //vma_dump(); // do we have to create a TLS segement? - if (curr_task->tls_addr && curr_task->tls_mem_size) { - // set fs register to the TLS segment - writefs(stack+offset); - kprintf("Task %d set fs to 0x%llx\n", curr_task->id, stack+offset); + if (curr_task->tls_addr && curr_task->tls_size) { + char* tls_addr = NULL; + tls_addr = kmalloc(curr_task->tls_size); // copy default TLS segment to stack - offset -= curr_task->tls_mem_size; - if (curr_task->tls_file_size) - memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size); + memcpy((void*) (tls_addr), (void*) curr_task->tls_addr, curr_task->tls_size); - // align stack to 16 byte boundary - offset = offset & ~0xFULL; + // set fs register to the TLS segment + writefs((size_t) tls_addr); + kprintf("Task %d set fs to %p\n", curr_task->id, tls_addr); } else writefs(0); // no TLS => clear fs register // set first argument - asm volatile ("mov %0, %%rdi" :: "r"(arg)); - enter_user_task(ep, stack+offset); + //asm volatile ("mov %0, %%rdi" :: "r"(arg)); + //enter_user_task(ep, stack+offset); + + entry_point_t call_ep = (entry_point_t) ep; + call_ep(arg); return 0; } @@ -182,12 +185,12 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor /* The instruction pointer shall be set on the first function to be called after IRETing */ - if ((size_t) ep < KERNEL_SPACE) { - stptr->rip = (size_t)ep; - } else { + //if ((size_t) ep < KERNEL_SPACE) { + // stptr->rip = (size_t)ep; + //} else { stptr->rip = (size_t)thread_entry; stptr->rsi = (size_t)ep; // use second argument to transfer the entry point - } + //} stptr->cs = 0x08; stptr->ss = 0x10; stptr->gs = core_id * ((size_t) &percore_end0 - (size_t) &percore_start); @@ -359,9 +362,11 @@ static int load_task(load_args_t* largs) break; case ELF_PT_TLS: kprintf("Found TLS segment. addr 0x%llx, mem size 0x%llx, file size 0x%llx\n", prog_header.virt_addr, prog_header.mem_size, prog_header.file_size); +#if 0 curr_task->tls_addr = prog_header.virt_addr; curr_task->tls_mem_size = prog_header.mem_size; curr_task->tls_file_size = prog_header.file_size; +#endif break; case ELF_PT_NOTE: //kprintf("Found note segment: %s\n", (char*)prog_header.virt_addr + 12); @@ -401,6 +406,7 @@ static int load_task(load_args_t* largs) offset = DEFAULT_STACK_SIZE-16; +#if 0 // do we have to create a TLS segement? if (curr_task->tls_addr && curr_task->tls_mem_size) { if (curr_task->tls_mem_size >= DEFAULT_STACK_SIZE-128) { @@ -418,6 +424,7 @@ static int load_task(load_args_t* largs) if (curr_task->tls_file_size) memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size); } +#endif // push strings on the stack memset((void*) (stack+offset), 0, 4); diff --git a/hermit/include/hermit/tasks_types.h b/hermit/include/hermit/tasks_types.h index 0239b15b5..ef2823a33 100644 --- a/hermit/include/hermit/tasks_types.h +++ b/hermit/include/hermit/tasks_types.h @@ -108,10 +108,8 @@ typedef struct task { struct task* prev; /// TLS address size_t tls_addr; - /// TLS mem size - size_t tls_mem_size; /// TLS file size - size_t tls_file_size; + size_t tls_size; /// LwIP error code int lwip_err; /// FPU state diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index 588251ae0..b6c226b37 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -68,6 +68,8 @@ extern const void kernel_start; extern const void kernel_end; extern const void kbss_start; extern const void kbss_end; +extern const void tls_start; +extern const void tls_end; extern const void percore_start; extern const void percore_end0; extern const void percore_end; @@ -270,6 +272,28 @@ static int initd(void* arg) init_netifs(); + // do we have a thread local storage? + if (((size_t) &tls_end - (size_t) &tls_start) > 0) { + char* tls_addr = NULL; + + curr_task->tls_addr = (size_t) &tls_start; + curr_task->tls_size = (size_t) &tls_end - (size_t) &tls_start; + + // TODO: free TLS after termination + tls_addr = kmalloc(curr_task->tls_size); + if (BUILTIN_EXPECT(!tls_addr, 0)) { + kprintf("load_task: heap is missing!\n"); + kfree(curr_task->heap); + return -ENOMEM; + } + + memcpy((void*) tls_addr, (void*) curr_task->tls_addr, curr_task->tls_size); + + // set fs register to the TLS segment + writefs((size_t) tls_addr); + kprintf("Task %d set fs to 0x%zx\n", curr_task->id, tls_addr); + } else writefs(0); // no TLS => clear fs register + //init_rcce(); s = socket(PF_INET , SOCK_STREAM , 0); @@ -386,6 +410,7 @@ int hermit_main(void) kprintf("This is Hermit %s, build date %u\n", VERSION, &__DATE__); kprintf("Isle %d of %d possible isles\n", isle, possible_isles); kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end); + kprintf("TLS image starts at %p and ends at %p\n", &tls_start, &tls_end); kprintf("Per core data starts at %p and ends at %p\n", &percore_start, &percore_end); kprintf("Per core size 0x%zd\n", (size_t) &percore_end0 - (size_t) &percore_start); kprintf("Processor frequency: %u MHz\n", get_cpu_frequency()); diff --git a/hermit/kernel/syscall.c b/hermit/kernel/syscall.c index ef08bf14c..41f37df38 100644 --- a/hermit/kernel/syscall.c +++ b/hermit/kernel/syscall.c @@ -61,6 +61,11 @@ int sys_getprio(void) return task->prio; } +int sys_setprio(tid_t* id, int prio) +{ + return -ENOSYS; +} + static void sys_yield(void) { reschedule(); @@ -357,6 +362,11 @@ int sys_sem_timedwait(sem_t *sem, unsigned int ms) return sem_wait(sem, ms); } +int sys_sem_cancelablewait(sem_t* sem, unsigned int ms) +{ + return -ENOSYS; +} + int sys_clone(tid_t* id, void* ep, void* argv) { return clone_task(id, ep, argv, per_core(current_task)->prio); diff --git a/hermit/kernel/tasks.c b/hermit/kernel/tasks.c index 1feafb3c6..53cf60717 100644 --- a/hermit/kernel/tasks.c +++ b/hermit/kernel/tasks.c @@ -42,8 +42,8 @@ * A task's id will be its position in this array. */ static task_t task_table[MAX_TASKS] = { \ - [0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}, \ - [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}}; + [0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0}, \ + [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0}}; static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT; @@ -294,8 +294,6 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) return -EINVAL; if (BUILTIN_EXPECT(prio > MAX_PRIO, 0)) return -EINVAL; - if (BUILTIN_EXPECT((size_t)ep < KERNEL_SPACE, 0)) - return -EINVAL; curr_task = per_core(current_task); @@ -324,8 +322,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) task_table[i].start_tick = get_clock_tick(); task_table[i].parent = curr_task->id; task_table[i].tls_addr = curr_task->tls_addr; - task_table[i].tls_mem_size = curr_task->tls_mem_size; - task_table[i].tls_file_size = curr_task->tls_file_size; + task_table[i].tls_size = curr_task->tls_size; task_table[i].lwip_err = 0; task_table[i].user_usage = curr_task->user_usage; task_table[i].page_map = curr_task->page_map; @@ -411,8 +408,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c task_table[i].start_tick = get_clock_tick(); task_table[i].parent = 0; task_table[i].tls_addr = 0; - task_table[i].tls_mem_size = 0; - task_table[i].tls_file_size = 0; + task_table[i].tls_size = 0; task_table[i].lwip_err = 0; spinlock_irqsave_init(&task_table[i].page_lock); diff --git a/hermit/usr/binutils b/hermit/usr/binutils index 72df72547..8931334f7 160000 --- a/hermit/usr/binutils +++ b/hermit/usr/binutils @@ -1 +1 @@ -Subproject commit 72df72547e5f46d4413f101abd8979d03e8e44d3 +Subproject commit 8931334f7f4e24b40c0973753e410421f0733a80 diff --git a/hermit/usr/pte b/hermit/usr/pte index 53835aebf..a7188dcfd 160000 --- a/hermit/usr/pte +++ b/hermit/usr/pte @@ -1 +1 @@ -Subproject commit 53835aebf4adb9b9582a3fa0665d5340568208c8 +Subproject commit a7188dcfd4e33dc2a1b4902c58c44574cebf5fe4 diff --git a/hermit/usr/tests/Makefile b/hermit/usr/tests/Makefile index 8d8d8572b..f356af36c 100644 --- a/hermit/usr/tests/Makefile +++ b/hermit/usr/tests/Makefile @@ -3,7 +3,7 @@ TARGET=x86_64-hermit MAKE = make override STRIP_DEBUG = --strip-debug #--strip-unneeded KEEP_DEBUG = --only-keep-debug -OBJCOPY_FLAGS = -j .mboot -j .ktext -j .kdata -j .kbss -j .fini -j .init -j .ctors -j .dtors -j .text -j .data -j .rodata -j .bss -j .percore -O binary +OBJCOPY_FLAGS = -j .mboot -j .ktext -j .kdata -j .kbss -j .tbss -j .tdata -j .fini -j .init -j .ctors -j .dtors -j .text -j .data -j .rodata -j .bss -j .percore -O binary # Set your own cross compiler tool chain prefix here CROSSCOMPREFIX = x86_64-hermit- @@ -44,7 +44,7 @@ endif default: all -all: hello.bin hello++.bin #hellof.bin thr_hello.bin #jacobi RCCE_minimum +all: hello.bin hello++.bin thr_hello.bin #hellof.bin #jacobi RCCE_minimum hello++: hello++.o @echo [LD] $@