/kernel/trunk/arch/amd64/include/thread.h |
---|
29,6 → 29,6 |
#ifndef __amd64_THREAD_H__ |
#define __amd64_THREAD_H__ |
#define ARCH_THREAD_DATA |
#define ARCH_THREAD_DATA __native tls; |
#endif |
/kernel/trunk/arch/amd64/include/cpu.h |
---|
42,6 → 42,7 |
#define AMD_MSR_STAR 0xc0000081 |
#define AMD_MSR_LSTAR 0xc0000082 |
#define AMD_MSR_SFMASK 0xc0000084 |
#define AMD_MSR_FS 0xc0000100 |
#define AMD_MSR_GS 0xc0000101 |
#ifndef __ASM__ |
/kernel/trunk/arch/amd64/src/amd64.c |
---|
32,6 → 32,7 |
#include <config.h> |
#include <proc/thread.h> |
#include <arch/ega.h> |
#include <genarch/i8042/i8042.h> |
#include <arch/i8254.h> |
47,7 → 48,9 |
#include <interrupt.h> |
#include <arch/syscall.h> |
#include <arch/debugger.h> |
#include <syscall/syscall.h> |
/** Disable I/O on non-privileged levels |
* |
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register |
159,3 → 162,18 |
i8254_calibrate_delay_loop(); |
i8254_normal_operation(); |
} |
/** Set Thread-local-storeage pointer |
* |
* TLS pointer is set in FS register. Unfortunately the 64-bit |
* part can be set only in CPL0 mode. |
* |
* The specs says, that on %fs:0 there is stored contents of %fs register, |
* we need not to go to CPL0 to read it. |
*/ |
__native sys_tls_set(__native addr) |
{ |
THREAD->tls = addr; |
write_msr(AMD_MSR_FS, addr); |
return 0; |
} |
/kernel/trunk/arch/amd64/src/proc/scheduler.c |
---|
45,6 → 45,9 |
(__u64)&THREAD->kstack); |
swapgs(); |
/* TLS support - set FS to thread local storage */ |
write_msr(AMD_MSR_FS, THREAD->tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
/kernel/trunk/arch/mips32/src/mips32.c |
---|
39,6 → 39,7 |
#include <proc/thread.h> |
#include <proc/uarg.h> |
#include <print.h> |
#include <syscall/syscall.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
141,3 → 142,13 |
void after_thread_ran_arch(void) |
{ |
} |
/** Set Thread-local-storeage pointer |
* |
* We have it currently in K1, it is |
* possible to have it separately in the future. |
*/ |
__native sys_tls_set(__native addr) |
{ |
return 0; |
} |
/kernel/trunk/arch/ia32/include/thread.h |
---|
29,6 → 29,6 |
#ifndef __ia32_THREAD_H__ |
#define __ia32_THREAD_H__ |
#define ARCH_THREAD_DATA |
#define ARCH_THREAD_DATA __native tls; |
#endif |
/kernel/trunk/arch/ia32/include/pm.h |
---|
30,7 → 30,7 |
#define __PM_H__ |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 6 |
#define GDT_ITEMS 7 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
38,6 → 38,7 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#define selector(des) ((des)<<3) |
146,6 → 147,7 |
extern void idt_setoffset(struct idescriptor *d, __address offset); |
extern void tss_initialize(struct tss *t); |
extern void set_tls_desc(__address tls); |
#endif /* __ASM__ */ |
/kernel/trunk/arch/ia32/src/ia32.c |
---|
51,6 → 51,8 |
#include <arch/mm/memory_init.h> |
#include <interrupt.h> |
#include <arch/debugger.h> |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
void arch_pre_mm_init(void) |
{ |
106,3 → 108,19 |
i8254_normal_operation(); |
} |
} |
/** Set Thread-local-storeage pointer |
* |
* TLS pointer is set in FS register. Unfortunately the 64-bit |
* part can be set only in CPL0 mode. |
* |
* The specs says, that on %fs:0 there is stored contents of %fs register, |
* we need not to go to CPL0 to read it. |
*/ |
__native sys_tls_set(__native addr) |
{ |
THREAD->tls = addr; |
set_tls_desc(addr); |
return 0; |
} |
/kernel/trunk/arch/ia32/src/pm.c |
---|
48,6 → 48,9 |
* We have no use for segmentation so we set up flat mode. In this |
* mode, we use, for each privilege level, two segments spanning the |
* whole memory. One is for code and one is for data. |
* |
* One is for GS register which holds pointer to the TLS thread |
* structure in it's base. |
*/ |
struct descriptor gdt[GDT_ITEMS] = { |
/* NULL descriptor */ |
61,7 → 64,8 |
/* UDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* TSS descriptor - set up will be completed later */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 } |
}; |
static struct idescriptor idt[IDT_ITEMS]; |
214,3 → 218,15 |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels */ |
clean_AM_flag(); /* Disable alignment check */ |
} |
void set_tls_desc(__address tls) |
{ |
struct ptr_16_32 cpugdtr; |
struct descriptor *gdt_p = (struct descriptor *) cpugdtr.base; |
__asm__ volatile ("sgdt %0\n" : : "m" (cpugdtr)); |
gdt_setbase(&gdt_p[TLS_DES], tls); |
/* Reload gdt register to update GS in CPU */ |
__asm__ volatile ("lgdt %0\n" : : "m" (cpugdtr)); |
} |
/kernel/trunk/arch/ia32/src/proc/scheduler.c |
---|
32,6 → 32,7 |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
void before_thread_runs_arch(void) |
{ |
38,6 → 39,9 |
CPU->arch.tss->esp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
set_tls_desc(THREAD->tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
/kernel/trunk/arch/ia32/src/userspace.c |
---|
55,6 → 55,9 |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
65,7 → 68,8 |
: |
: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |