Index: libc/arch/amd64/Makefile.inc
===================================================================
--- libc/arch/amd64/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/amd64/Makefile.inc	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -34,5 +34,6 @@
 
 ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
-		arch/$(ARCH)/src/psthread.S
+		arch/$(ARCH)/src/psthread.S \
+		arch/$(ARCH)/src/thread.c
 
 LFLAGS += -N
Index: libc/arch/amd64/_link.ld.in
===================================================================
--- libc/arch/amd64/_link.ld.in	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/amd64/_link.ld.in	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -21,4 +21,15 @@
 		*(.data);
 	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	
 	.bss : {
 		*(COMMON);
Index: libc/arch/amd64/include/thread.h
===================================================================
--- libc/arch/amd64/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/amd64/include/thread.h	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -32,10 +32,15 @@
 #include <libc.h>
 
-static inline void __tls_set(void *tls)
+typedef struct {
+	void *self;
+	void *pst_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
 {
-	__SYSCALL1(SYS_TLS_SET, (sysarg_t) tls);
+	__SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb);
 }
 
-static inline void * __tls_get(void)
+static inline tcb_t * __tcb_get(void)
 {
 	void * retval;
Index: libc/arch/amd64/src/thread.c
===================================================================
--- libc/arch/amd64/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
+++ libc/arch/amd64/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <thread.h>
+#include <malloc.h>
+
+/** Allocate TLS & TCB for initial module threads
+ *
+ * @param data Start of data section
+ * @return pointer to tcb_t structure
+ */
+tcb_t * __alloc_tls(void **data, size_t size)
+{
+	tcb_t *tcb;
+	
+	*data = malloc(sizeof(tcb_t) + size);
+
+	tcb = (tcb_t *) (*data + size);
+	tcb->self = tcb;
+
+	return tcb;
+}
+
+void __free_tls_arch(tcb_t *tcb, size_t size)
+{
+	void *start = ((void *)tcb) - size;
+	free(start);
+}
Index: libc/arch/ia32/Makefile.inc
===================================================================
--- libc/arch/ia32/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia32/Makefile.inc	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -34,5 +34,6 @@
 
 ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
-		arch/$(ARCH)/src/psthread.S
+		arch/$(ARCH)/src/psthread.S \
+		arch/$(ARCH)/src/thread.c
 
 LFLAGS += -N
Index: libc/arch/ia32/_link.ld.in
===================================================================
--- libc/arch/ia32/_link.ld.in	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia32/_link.ld.in	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -21,4 +21,14 @@
 		*(.data);
 	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
 	.bss : {
                 *(COMMON);
Index: libc/arch/ia32/include/thread.h
===================================================================
--- libc/arch/ia32/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia32/include/thread.h	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -32,10 +32,15 @@
 #include <libc.h>
 
-static inline void __tls_set(void *tls)
+typedef struct {
+	void *self;
+	void *pst_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
 {
-	__SYSCALL1(SYS_TLS_SET, (sysarg_t) tls);
+	__SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb);
 }
 
-static inline void * __tls_get(void)
+static inline tcb_t * __tcb_get(void)
 {
 	void * retval;
Index: libc/arch/ia32/src/thread.c
===================================================================
--- libc/arch/ia32/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
+++ libc/arch/ia32/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -0,0 +1,1 @@
+../../amd64/src/thread.c
Index: libc/arch/ia64/Makefile.inc
===================================================================
--- libc/arch/ia64/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/Makefile.inc	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -37,3 +37,4 @@
 
 ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
-		arch/$(ARCH)/src/psthread.S
+		arch/$(ARCH)/src/psthread.S \
+		arch/$(ARCH)/src/thread.c
Index: libc/arch/ia64/_link.ld.in
===================================================================
--- libc/arch/ia64/_link.ld.in	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/_link.ld.in	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -27,4 +27,14 @@
 		*(.sdata);
 	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
 	.bss : {
 		*(.sbss);
Index: libc/arch/ia64/include/thread.h
===================================================================
--- libc/arch/ia64/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/include/thread.h	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -30,10 +30,16 @@
 #define __LIBC__ia64THREAD_H__
 
-static inline void __tls_set(void *tls)
+/* This structure must be exactly 16 bytes long */
+typedef struct {
+	void *dtv; /* unused in static linking*/
+	void *pst_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
 {
-	__asm__ volatile ("mov r13 = %0\n" : : "r" (tls) : "r13");
+	__asm__ volatile ("mov r13 = %0\n" : : "r" (tcb) : "r13");
 }
 
-static inline void *__tls_get(void)
+static inline tcb_t *__tcb_get(void)
 {
 	void *retval;
Index: libc/arch/ia64/src/thread.c
===================================================================
--- libc/arch/ia64/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
+++ libc/arch/ia64/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <thread.h>
+#include <malloc.h>
+
+/** Allocate TLS & TCB for initial module threads
+ *
+ * @param data Start of data section
+ * @return pointer to tcb_t structure
+ */
+extern char _tdata_start;
+extern char _tbss_end;
+tcb_t * __alloc_tls(void **data, size_t size)
+{
+	tcb_t *tcb;
+	
+/*	ASSERT(sizeof(tcb_t) == 16); */
+
+	tcb = malloc(sizeof(tcb_t) + size);
+	*data = ((void *) tcb) + 16;
+
+	return tcb;
+}
+
+void __free_tls_arch(tcb_t *tcb, size_t size)
+{
+	free(tcb);
+}
Index: libc/arch/mips32/Makefile.inc
===================================================================
--- libc/arch/mips32/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/mips32/Makefile.inc	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -35,5 +35,6 @@
 
 ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
-	arch/$(ARCH)/src/psthread.S
+	arch/$(ARCH)/src/psthread.S \
+	arch/$(ARCH)/src/thread.c
 
 
Index: libc/arch/mips32/_link.ld.in
===================================================================
--- libc/arch/mips32/_link.ld.in	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/mips32/_link.ld.in	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -22,8 +22,21 @@
 		*(.data.rel*);
 	} :data
+
 	.got : {
 		_gp = .;
 		*(.got);
 	} :data
+
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+
 	.sbss : {
 		*(.scommon);
Index: libc/arch/mips32/include/psthread.h
===================================================================
--- libc/arch/mips32/include/psthread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/mips32/include/psthread.h	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -32,4 +32,15 @@
 #include <types.h>
 
+/* We define our own context_set, because we need to set
+ * the TLS pointer to the tcb+0x7000
+ *
+ * See tls_set in thread.h
+ */
+#define context_set(c, _pc, stack, size, ptls) 			\
+	(c)->pc = (sysarg_t) (_pc);				\
+	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; 	\
+        (c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
+
+
 /* +16 is just for sure that the called function
  * have space to store it's arguments
Index: libc/arch/mips32/include/thread.h
===================================================================
--- libc/arch/mips32/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/mips32/include/thread.h	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -32,15 +32,37 @@
 #define __LIBC__mips32THREAD_H__
 
-static inline void __tls_set(void *tls)
+/* I did not find any specification (neither MIPS nor PowerPC), but
+ * as I found it
+ * - it uses Variant II
+ * - TCB is at Address(First TLS Block)+0x7000.
+ * - DTV is at Address(First TLS Block)+0x8000
+ * - What would happen if the TLS data was larger then 0x7000?
+ * - The linker never accesses DTV directly, has the second definition any
+ *   sense?
+ * We will make it this way:
+ * - TCB is at TP-0x7000-sizeof(tcb)
+ * - No assumption about DTV etc., but it will not have a fixed address
+ */
+#define MIPS_TP_OFFSET 0x7000
+
+typedef struct {
+	void *pst_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
 {
-	__asm__ volatile ("add $27, %0, $0" : : "r"(tls)); /* Move tls to K1 */
+	void *tp = tcb;
+	tp += MIPS_TP_OFFSET + sizeof(tcb_t);
+
+	__asm__ volatile ("add $27, %0, $0" : : "r"(tp)); /* Move tls to K1 */
 }
 
-static inline void * __tls_get(void)
+static inline tcb_t * __tcb_get(void)
 {
 	void * retval;
 
 	__asm__ volatile("add %0, $27, $0" : "=r"(retval));
-	return retval;
+
+	return (tcb_t *)(retval - MIPS_TP_OFFSET - sizeof(tcb_t));
 }
 
Index: libc/arch/mips32/src/thread.c
===================================================================
--- libc/arch/mips32/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
+++ libc/arch/mips32/src/thread.c	(revision c4c5de59abd6442cc66d82b804875450e089da68)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <thread.h>
+#include <malloc.h>
+
+/** Allocate TLS & TCB for initial module threads
+ *
+ * @param data (out) Start of TLS section
+ * @param size Size of tdata+tbss section
+ * @return pointer to tcb_t structure
+ */
+tcb_t * __alloc_tls(void **data, size_t size)
+{
+	tcb_t *result;
+
+	result = malloc(sizeof(tcb_t) + size);
+	*data = ((void *)result) + sizeof(tcb_t);
+	return result;
+}
+
+void __free_tls_arch(tcb_t *tcb, size_t size)
+{
+	free(tcb);
+}
