Index: libc/generic/libc.c
===================================================================
--- libc/generic/libc.c	(revision 520492a919fe1fbbbca2ba14c75775dab9c6f60a)
+++ libc/generic/libc.c	(revision 8fe1cdb01b8894ae130c2960e9b330b65a22e88f)
@@ -37,11 +37,19 @@
 }
 
+#include <stdio.h>
 void __main(void) {
-	__tls_set(__make_tls());
+	tcb_t *tcb;
+	
+	tcb = __make_tls();
+	__tcb_set(tcb);
+	psthread_setup(tcb);
 }
 
 void __exit(void) {
-	free(__tls_get());
-	
+	tcb_t *tcb;
+
+	tcb = __tcb_get();
+	psthread_teardown(tcb->pst_data);
+	__free_tls(tcb);
 	_exit(0);
 }
Index: libc/generic/psthread.c
===================================================================
--- libc/generic/psthread.c	(revision 520492a919fe1fbbbca2ba14c75775dab9c6f60a)
+++ libc/generic/psthread.c	(revision 8fe1cdb01b8894ae130c2960e9b330b65a22e88f)
@@ -40,4 +40,25 @@
 static void psthread_main(void);
 
+/** Setup PSthread information into TCB structure */
+psthread_data_t * psthread_setup(tcb_t *tcb)
+{
+	psthread_data_t *pt;
+
+	pt = malloc(sizeof(*pt));
+	if (!pt) {
+		return NULL;
+	}
+
+	tcb->pst_data = pt;
+	pt->tcb = tcb;
+
+	return pt;
+}
+
+void psthread_teardown(psthread_data_t *pt)
+{
+	free(pt);
+}
+
 /** Function to preempt to other pseudo thread without adding
  * currently running pseudo thread to ready_list.
@@ -60,5 +81,6 @@
 void psthread_main(void)
 {
-	psthread_data_t *pt = __tls_get();
+	psthread_data_t *pt = __tcb_get()->pst_data;
+
 	pt->retval = pt->func(pt->arg);
 
@@ -81,5 +103,5 @@
 		return 0;
 
-	pt = __tls_get();
+	pt = __tcb_get()->pst_data;
 	if (!context_save(&pt->ctx))
 		return 1;
@@ -104,9 +126,8 @@
 
 	/* Handle psthrid = Kernel address -> it is wait for call */
-
 	pt = (psthread_data_t *) psthrid;
 
 	if (!pt->finished) {
-		mypt = __tls_get();
+		mypt = __tcb_get()->pst_data;
 		if (context_save(&((psthread_data_t *) mypt)->ctx)) {
 			pt->waiter = (psthread_data_t *) mypt;
@@ -117,5 +138,6 @@
 
 	free(pt->stack);
-	__free_tls((psthread_data_t *) pt);
+	__free_tls(pt->tcb);
+	psthread_teardown((void *)pt);
 
 	return retval;
@@ -133,9 +155,20 @@
 {
 	psthread_data_t *pt;
+	tcb_t *tcb;
 
-	pt = __make_tls();
+	tcb = __make_tls();
+	if (!tcb)
+		return 0;
+
+	pt = psthread_setup(tcb);
+	if (!pt) {
+		__free_tls(tcb);
+		return 0;
+	}
 	pt->stack = (char *) malloc(getpagesize());
 
 	if (!pt->stack) {
+		__free_tls(tcb);
+		psthread_teardown(pt);
 		return 0;
 	}
@@ -147,5 +180,6 @@
 
 	context_save(&pt->ctx);
-	context_set(&pt->ctx, FADDR(psthread_main), pt->stack, getpagesize(), pt);
+	context_set(&pt->ctx, FADDR(psthread_main), pt->stack, getpagesize(),
+		    tcb);
 
 	list_append(&pt->link, &ready_list);
Index: libc/generic/thread.c
===================================================================
--- libc/generic/thread.c	(revision 520492a919fe1fbbbca2ba14c75775dab9c6f60a)
+++ libc/generic/thread.c	(revision 8fe1cdb01b8894ae130c2960e9b330b65a22e88f)
@@ -33,19 +33,36 @@
 #include <kernel/proc/uarg.h>
 #include <psthread.h>
+#include <string.h>
 
 #include <stdio.h>
-void * __make_tls(void)
+
+extern char _tdata_start;
+extern char _tdata_end;
+extern char _tbss_start;
+extern char _tbss_end;
+
+/** Create Thread Local storage area, return pointer to TCB(ThreadControlBlock)
+ *
+ * !! The code requires, that sections .tdata and .tbss are adjacent.
+ *    It may be changed in the future.
+ */
+tcb_t * __make_tls(void)
 {
-	psthread_data_t *pt;
+	void *data;
+	tcb_t *tcb;
+	size_t tls_size = &_tbss_end - &_tdata_start;
+	
+	tcb = __alloc_tls(&data, tls_size);
+	
+	memcpy(data, &_tdata_start, &_tdata_end - &_tdata_start);
+	memset(data + (&_tbss_start-&_tdata_start), &_tbss_end-&_tbss_start, 0);
 
-	pt = malloc(sizeof(psthread_data_t));
-	pt->self = pt;
-
-	return pt;
+	return tcb;
 }
 
-void __free_tls(void *tls)
+void __free_tls(tcb_t *tcb)
 {
-	free(tls);
+	size_t tls_size = &_tbss_end - &_tdata_start;
+	__free_tls_arch(tcb, tls_size);
 }
 
@@ -61,6 +78,9 @@
 void __thread_main(uspace_arg_t *uarg)
 {
+	tcb_t *tcb;
 	/* This should initialize the area according to TLS specicification */
-	__tls_set(__make_tls());
+	tcb = __make_tls();
+	__tcb_set(tcb);
+	psthread_setup(tcb);
 
 	uarg->uspace_thread_function(uarg->uspace_thread_arg);
@@ -68,5 +88,6 @@
 	free(uarg);
 
-	__free_tls(__tls_get());
+	psthread_teardown(tcb->pst_data);
+	__free_tls(tcb);
 
 	thread_exit(0);
