Index: libc/arch/ppc32/include/context_offset.h
===================================================================
--- libc/arch/ppc32/include/context_offset.h	(revision 432c648cd952eb152b9ab227ed8dce288cc3e360)
+++ libc/arch/ppc32/include/context_offset.h	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -0,0 +1,25 @@
+/* struct context */
+#define OFFSET_SP    0x0
+#define OFFSET_PC    0x4
+#define OFFSET_R2    0x8
+#define OFFSET_R13   0xc
+#define OFFSET_R14   0x10
+#define OFFSET_R15   0x14
+#define OFFSET_R16   0x18
+#define OFFSET_R17   0x1c
+#define OFFSET_R18   0x20
+#define OFFSET_R19   0x24
+#define OFFSET_R20   0x28
+#define OFFSET_R21   0x2c
+#define OFFSET_R22   0x30
+#define OFFSET_R23   0x34
+#define OFFSET_R24   0x38
+#define OFFSET_R25   0x3c
+#define OFFSET_R26   0x40
+#define OFFSET_R27   0x44
+#define OFFSET_R28   0x48
+#define OFFSET_R29   0x4c
+#define OFFSET_R30   0x50
+#define OFFSET_R31   0x54
+#define OFFSET_CR    0x58
+#define OFFSET_CR    0x58
Index: libc/arch/ppc32/include/psthread.h
===================================================================
--- libc/arch/ppc32/include/psthread.h	(revision 432c648cd952eb152b9ab227ed8dce288cc3e360)
+++ libc/arch/ppc32/include/psthread.h	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -32,17 +32,43 @@
 #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);
+	(c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t);
 
-#define SP_DELTA	(8+16)
+#define SP_DELTA	16
 
-typedef struct  {
+typedef struct {
 	uint32_t sp;
 	uint32_t pc;
 	
 	uint32_t tls;
-} context_t;
+	uint32_t r13;
+	uint32_t r14;
+	uint32_t r15;
+	uint32_t r16;
+	uint32_t r17;
+	uint32_t r18;
+	uint32_t r19;
+	uint32_t r20;
+	uint32_t r21;
+	uint32_t r22;
+	uint32_t r23;
+	uint32_t r24;
+	uint32_t r25;
+	uint32_t r26;
+	uint32_t r27;
+	uint32_t r28;
+	uint32_t r29;
+	uint32_t r30;
+	uint32_t r31;
+	
+	uint32_t cr;
+} __attribute__ ((packed)) context_t;
 
 #endif
Index: libc/arch/ppc32/include/regname.h
===================================================================
--- libc/arch/ppc32/include/regname.h	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
+++ libc/arch/ppc32/include/regname.h	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2006 Martin Decky
+ * 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.
+ */
+
+#ifndef __ppc32_REGNAME_H__
+#define __ppc32_REGNAME_H__
+
+/* Condition Register Bit Fields */
+#define	cr0	0
+#define	cr1	1
+#define	cr2	2
+#define	cr3	3
+#define	cr4	4
+#define	cr5	5
+#define	cr6	6
+#define	cr7	7
+
+/* General Purpose Registers (GPRs) */
+#define	r0	0
+#define	r1	1
+#define	r2	2
+#define	r3	3
+#define	r4	4
+#define	r5	5
+#define	r6	6
+#define	r7	7
+#define	r8	8
+#define	r9	9
+#define	r10	10
+#define	r11	11
+#define	r12	12
+#define	r13	13
+#define	r14	14
+#define	r15	15
+#define	r16	16
+#define	r17	17
+#define	r18	18
+#define	r19	19
+#define	r20	20
+#define	r21	21
+#define	r22	22
+#define	r23	23
+#define	r24	24
+#define	r25	25
+#define	r26	26
+#define	r27	27
+#define	r28	28
+#define	r29	29
+#define	r30	30
+#define	r31	31
+
+/* GPR Aliases */
+#define	sp	1
+
+/* Floating Point Registers (FPRs) */
+#define	fr0		0
+#define	fr1		1
+#define	fr2		2
+#define	fr3		3
+#define	fr4		4
+#define	fr5		5
+#define	fr6		6
+#define	fr7		7
+#define	fr8		8
+#define	fr9		9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31
+
+#define	vr0		0
+#define	vr1		1
+#define	vr2		2
+#define	vr3		3
+#define	vr4		4
+#define	vr5		5
+#define	vr6		6
+#define	vr7		7
+#define	vr8		8
+#define	vr9		9
+#define	vr10	10
+#define	vr11	11
+#define	vr12	12
+#define	vr13	13
+#define	vr14	14
+#define	vr15	15
+#define	vr16	16
+#define	vr17	17
+#define	vr18	18
+#define	vr19	19
+#define	vr20	20
+#define	vr21	21
+#define	vr22	22
+#define	vr23	23
+#define	vr24	24
+#define	vr25	25
+#define	vr26	26
+#define	vr27	27
+#define	vr28	28
+#define	vr29	29
+#define	vr30	30
+#define	vr31	31
+
+#define	evr0	0
+#define	evr1	1
+#define	evr2	2
+#define	evr3	3
+#define	evr4	4
+#define	evr5	5
+#define	evr6	6
+#define	evr7	7
+#define	evr8	8
+#define	evr9	9
+#define	evr10	10
+#define	evr11	11
+#define	evr12	12
+#define	evr13	13
+#define	evr14	14
+#define	evr15	15
+#define	evr16	16
+#define	evr17	17
+#define	evr18	18
+#define	evr19	19
+#define	evr20	20
+#define	evr21	21
+#define	evr22	22
+#define	evr23	23
+#define	evr24	24
+#define	evr25	25
+#define	evr26	26
+#define	evr27	27
+#define	evr28	28
+#define	evr29	29
+#define	evr30	30
+#define	evr31	31
+
+#endif
Index: libc/arch/ppc32/include/thread.h
===================================================================
--- libc/arch/ppc32/include/thread.h	(revision 432c648cd952eb152b9ab227ed8dce288cc3e360)
+++ libc/arch/ppc32/include/thread.h	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -30,4 +30,18 @@
 #define __LIBC__ppc32__THREAD_H__
 
+/* 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 PPC_TP_OFFSET 0x7000
+
 typedef struct {
 	void *pst_data;
@@ -36,8 +50,24 @@
 static inline void __tcb_set(tcb_t *tcb)
 {
+	void *tp = tcb;
+	tp += PPC_TP_OFFSET + sizeof(tcb_t);
+	
+	asm volatile (
+		"mr %%r2, %0\n"
+		:
+		: "r" (tp)
+	);
 }
 
 static inline tcb_t * __tcb_get(void)
 {
+	void * retval;
+	
+	asm volatile (
+		"mr %0, %%r2\n"
+		: "=r" (retval)
+	);
+
+	return (tcb_t *)(retval - PPC_TP_OFFSET - sizeof(tcb_t));
 }
 
Index: libc/arch/ppc32/src/psthread.S
===================================================================
--- libc/arch/ppc32/src/psthread.S	(revision 432c648cd952eb152b9ab227ed8dce288cc3e360)
+++ libc/arch/ppc32/src/psthread.S	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -32,10 +32,79 @@
 .global context_restore
 
+#include <libarch/regname.h>
 #include <libarch/context_offset.h>
 
+.macro CONTEXT_STORE r
+	stw sp, OFFSET_SP(\r)
+	stw r2, OFFSET_R2(\r)
+	stw r13, OFFSET_R13(\r)
+	stw r14, OFFSET_R14(\r)
+	stw r15, OFFSET_R15(\r)
+	stw r16, OFFSET_R16(\r)
+	stw r17, OFFSET_R17(\r)
+	stw r18, OFFSET_R18(\r)
+	stw r19, OFFSET_R19(\r)
+	stw r20, OFFSET_R20(\r)
+	stw r21, OFFSET_R21(\r)
+	stw r22, OFFSET_R22(\r)
+	stw r23, OFFSET_R23(\r)
+	stw r24, OFFSET_R24(\r)
+	stw r25, OFFSET_R25(\r)
+	stw r26, OFFSET_R26(\r)
+	stw r27, OFFSET_R27(\r)
+	stw r28, OFFSET_R28(\r)
+	stw r29, OFFSET_R29(\r)
+	stw r30, OFFSET_R30(\r)
+	stw r31, OFFSET_R31(\r)
+.endm
+
+.macro CONTEXT_LOAD r
+	lwz sp, OFFSET_SP(\r)
+	lwz r2, OFFSET_R2(\r)
+	lwz r13, OFFSET_R13(\r)
+	lwz r14, OFFSET_R14(\r)
+	lwz r15, OFFSET_R15(\r)
+	lwz r16, OFFSET_R16(\r)
+	lwz r17, OFFSET_R17(\r)
+	lwz r18, OFFSET_R18(\r)
+	lwz r19, OFFSET_R19(\r)
+	lwz r20, OFFSET_R20(\r)
+	lwz r21, OFFSET_R21(\r)
+	lwz r22, OFFSET_R22(\r)
+	lwz r23, OFFSET_R23(\r)
+	lwz r24, OFFSET_R24(\r)
+	lwz r25, OFFSET_R25(\r)
+	lwz r26, OFFSET_R26(\r)
+	lwz r27, OFFSET_R27(\r)
+	lwz r28, OFFSET_R28(\r)
+	lwz r29, OFFSET_R29(\r)
+	lwz r30, OFFSET_R30(\r)
+	lwz r31, OFFSET_R31(\r)
+.endm
+
 context_save:
+	CONTEXT_STORE r3
+	
+	mflr r4
+	stw r4, OFFSET_PC(r3)
+	
+	mfcr r4
+	stw r4, OFFSET_CR(r3)
+	
+	# context_save returns 1
+	li r3, 1
 	blr
 
 
 context_restore:
+	CONTEXT_LOAD r3
+	
+	lwz r4, OFFSET_CR(r3)
+	mtcr r4
+	
+	lwz r4, OFFSET_PC(r3)
+	mtlr r4
+	
+	# context_restore returns 0
+	li r3, 0
 	blr
Index: libc/arch/ppc32/src/thread.c
===================================================================
--- libc/arch/ppc32/src/thread.c	(revision 432c648cd952eb152b9ab227ed8dce288cc3e360)
+++ libc/arch/ppc32/src/thread.c	(revision 20a9b85953864efe36abda6ed2c4e3c4ab28c4f5)
@@ -34,4 +34,5 @@
  * @param data Start of data section
  * @return pointer to tcb_t structure
+ *
  */
 tcb_t * __alloc_tls(void **data, size_t size)
@@ -40,7 +41,5 @@
 	
 	*data = malloc(sizeof(tcb_t) + size);
-
 	tcb = (tcb_t *) (*data + size);
-
 	return tcb;
 }
