summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2004-02-21 05:29:17 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2004-02-21 05:29:17 +0000
commit0abd808663db59e4c1bbf75fa0f6948cccce36d2 (patch)
treef455df3071b90c579df75e4acc80612e6ffb5f9e
parent1569606112ffbf75e6542d0b661984a49d86c229 (diff)
Implement the arm pthreads pieces, only two regress fails, preemption_float
and sigmask.
-rw-r--r--lib/libpthread/arch/arm/uthread_machdep.c60
-rw-r--r--lib/libpthread/arch/arm/uthread_machdep_asm.S193
2 files changed, 95 insertions, 158 deletions
diff --git a/lib/libpthread/arch/arm/uthread_machdep.c b/lib/libpthread/arch/arm/uthread_machdep.c
index 12996411b75..3309f895fb5 100644
--- a/lib/libpthread/arch/arm/uthread_machdep.c
+++ b/lib/libpthread/arch/arm/uthread_machdep.c
@@ -1,23 +1,25 @@
-/* $OpenBSD: uthread_machdep.c,v 1.1 2004/02/09 13:14:34 drahn Exp $ */
+/* $OpenBSD: uthread_machdep.c,v 1.2 2004/02/21 05:29:16 drahn Exp $ */
/* David Leonard, <d@csee.uq.edu.au>. Public domain */
#include <pthread.h>
#include "pthread_private.h"
-#if 0
-#define ALIGNBYTES 0xf
+#define ALIGNBYTES 0x7
/* Register save frame as it appears on the stack */
struct frame {
- int r1;
- int reserved;
- int gp[32-14];
- int lr, cr, ctr, xer;
- double fp[32];
- double fs;
+ int r[12-4];
+ int fp; /* r12 */
+ int ip; /* r13 */
+ int lr; /* r14 */
+ int cpsr;
+ double fpr[6]; /* sizeof(fp)+sizeof(fs) == 52 */
+ int fs;
/* The rest are only valid in the initial frame */
- int next_r1;
+ int next_fp;
+ int next_ip;
int next_lr;
+ int oldpc;
};
/*
@@ -32,42 +34,32 @@ _thread_machdep_init(statep, base, len, entry)
void (*entry)(void);
{
struct frame *f;
+ int scratch;
/* Locate the initial frame, aligned at the top of the stack */
f = (struct frame *)(((int)base + len - sizeof *f) & ~ALIGNBYTES);
- f->r1 = (int)&f->next_r1;
- f->reserved = 0;
+ f->fp = (int)&f->next_fp;
+ f->ip = (int)0;
f->lr = (int)entry;
- f->next_r1 = 0; /* for gdb */
+ f->next_fp = 0; /* for gdb */
f->next_lr = 0; /* for gdb */
/* Initialise the new thread with all the state from this thread. */
-#define copyreg(x) __asm__ volatile ("stw " #x ", %0" : "=m"(f->gp[x-14]))
- copyreg(14); copyreg(15); copyreg(16); copyreg(17); copyreg(18);
- copyreg(19); copyreg(20); copyreg(21); copyreg(22); copyreg(23);
- copyreg(24); copyreg(25); copyreg(26); copyreg(27); copyreg(28);
- copyreg(29); copyreg(30); copyreg(31);
+ __asm__ volatile ("mrs %0, cpsr_all; str %0, [%2, #0]"
+ : "=r"(scratch) : "0"(scratch), "r" (&f->cpsr));
-#define copysreg(nm) __asm__ volatile ("mf" #nm " %0" : "=r"(f->nm))
- copysreg(cr); copysreg(ctr); copysreg(xer);
+ __asm__ volatile ("stmia %0, {r4-r12}":: "r"(&f->r[0]));
-#define copyfreg(x) __asm__ volatile ("stfd " #x ", %0" : "=m"(f->fp[x]))
- copyfreg(0); copyfreg(1); copyfreg(2); copyfreg(3);
- copyfreg(4); copyfreg(5); copyfreg(6); copyfreg(7);
- copyfreg(8); copyfreg(9); copyfreg(10); copyfreg(11);
- copyfreg(12); copyfreg(13); copyfreg(14); copyfreg(15);
- copyfreg(16); copyfreg(17); copyfreg(18); copyfreg(19);
- copyfreg(20); copyfreg(21); copyfreg(22); copyfreg(23);
- copyfreg(24); copyfreg(25); copyfreg(26); copyfreg(27);
- copyfreg(28); copyfreg(29); copyfreg(30); copyfreg(31);
+#ifndef __VFP_FP__
+ __asm__ volatile ("sfm f4, 4, [%0], #0":: "r"(&f->fpr[0]));
- __asm__ volatile ("mffs 0; stfd 0, %0" : "=m"(f->fs));
+ __asm__ volatile ("rfs 0; stfd 0, %0" : "=m"(f->fs));
+#endif
statep->frame = (int)f;
}
-#endif
/*
@@ -79,10 +71,16 @@ void
_thread_machdep_save_float_state(statep)
struct _machdep_state* statep;
{
+#ifndef __VFP_FP__
+#error finish FP save
+#endif
}
void
_thread_machdep_restore_float_state(statep)
struct _machdep_state* statep;
{
+#ifndef __VFP_FP__
+#error finish FP save
+#endif
}
diff --git a/lib/libpthread/arch/arm/uthread_machdep_asm.S b/lib/libpthread/arch/arm/uthread_machdep_asm.S
index 7781d633fe5..272f8c3bf39 100644
--- a/lib/libpthread/arch/arm/uthread_machdep_asm.S
+++ b/lib/libpthread/arch/arm/uthread_machdep_asm.S
@@ -1,137 +1,76 @@
-/* $OpenBSD: uthread_machdep_asm.S,v 1.1 2004/02/09 13:14:34 drahn Exp $ */
-/* David Leonard, <d@csee.uq.edu.au>. Public domain. */
+/* $OpenBSD: uthread_machdep_asm.S,v 1.2 2004/02/21 05:29:16 drahn Exp $ */
+
+/*
+ * Copyright (c) 2004 Dale Rahn. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * 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.
+ */
-#if 0
#include <machine/asm.h>
-/* These need to be kept in sync with uthread_machdep.c */
-#define REGOFF(n) (2*4 + (n-14)*4)
-#define FPOFF(n) (REGOFF(36) + (n)*8)
-#define FRAMESIZE FPOFF(33)
+/* THESE MUST BE IN SYNC WITH uthread_machdep.c:struct frame */
+#define OFFSET_R 0 /* offsetof(struct frame, r) */
+#define OFFSET_FP ((12-4)*4)
+#define OFFSET_LR (OFFSET_FP+4)
+#define OFFSET_CPSR (OFFSET_LR+4)
+#define OFFSET_FPR (OFFSET_CPSR+4)
+#define OFFSET_FS (OFFSET_FPR+(6*8))
+#define FRAME_SIZE (OFFSET_FS+4)
-#define SA(x) (((x)+0xf)&~0xf)
+/*
+ * r0 is pointer to new save area - restore from here
+ * r1 is pointer to old save area - put pointer to stack save area here
+ */
ENTRY(_thread_machdep_switch)
- stwu 1, -SA(FRAMESIZE)(1)
-
- /* Save context into frame */
- stw 14, REGOFF(14)(1)
- stw 15, REGOFF(15)(1)
- stw 16, REGOFF(16)(1)
- stw 17, REGOFF(17)(1)
- stw 18, REGOFF(18)(1)
- stw 19, REGOFF(19)(1)
- stw 20, REGOFF(20)(1)
- stw 21, REGOFF(21)(1)
- stw 22, REGOFF(22)(1)
- stw 23, REGOFF(23)(1)
- stw 24, REGOFF(24)(1)
- stw 25, REGOFF(25)(1)
- stw 26, REGOFF(26)(1)
- stw 27, REGOFF(27)(1)
- stw 28, REGOFF(28)(1)
- stw 29, REGOFF(29)(1)
- stw 30, REGOFF(30)(1)
- stw 31, REGOFF(31)(1)
- mflr 0; stw 0, REGOFF(32)(1)
- mfcr 0; stw 0, REGOFF(33)(1)
- mfctr 0; stw 0, REGOFF(34)(1)
- mfxer 0; stw 0, REGOFF(35)(1)
- stfd 0, FPOFF(0)(1)
- stfd 1, FPOFF(1)(1)
- stfd 2, FPOFF(2)(1)
- stfd 3, FPOFF(3)(1)
- stfd 4, FPOFF(4)(1)
- stfd 5, FPOFF(5)(1)
- stfd 6, FPOFF(6)(1)
- stfd 7, FPOFF(7)(1)
- stfd 8, FPOFF(8)(1)
- stfd 9, FPOFF(9)(1)
- stfd 10, FPOFF(10)(1)
- stfd 11, FPOFF(11)(1)
- stfd 12, FPOFF(12)(1)
- stfd 13, FPOFF(13)(1)
- stfd 14, FPOFF(14)(1)
- stfd 15, FPOFF(15)(1)
- stfd 16, FPOFF(16)(1)
- stfd 17, FPOFF(17)(1)
- stfd 18, FPOFF(18)(1)
- stfd 19, FPOFF(19)(1)
- stfd 20, FPOFF(20)(1)
- stfd 21, FPOFF(21)(1)
- stfd 22, FPOFF(22)(1)
- stfd 23, FPOFF(23)(1)
- stfd 24, FPOFF(24)(1)
- stfd 25, FPOFF(25)(1)
- stfd 26, FPOFF(26)(1)
- stfd 27, FPOFF(27)(1)
- stfd 28, FPOFF(28)(1)
- stfd 29, FPOFF(29)(1)
- stfd 30, FPOFF(30)(1)
- stfd 31, FPOFF(31)(1)
- mffs 0; stfd 0, FPOFF(32)(1)
+ mov ip, sp
+ sub sp, sp, #FRAME_SIZE+4
+ add r2, sp, #4
+ stmia r2, {r4-r11}
+ str fp, [r2, #OFFSET_FP]
+ str lr, [r2, #OFFSET_LR]
- /* Switch stacks */
- stw 1, 0(4)
- lwz 1, 0(3)
+ mrs r3, cpsr_all
+ str r3, [r2, #OFFSET_CPSR]
+#ifndef __VFP_FP__
+ sfm f4, 4, [r2, #OFFSET_FPR]
+ rfs r3
+ str r3, [r2, #OFFSET_FS]
+#endif
- /* Restore context from the frame */
- lfd 0, FPOFF(32)(1); mtfsf 0xff, 0
- lfd 31, FPOFF(31)(1)
- lfd 30, FPOFF(30)(1)
- lfd 29, FPOFF(29)(1)
- lfd 28, FPOFF(28)(1)
- lfd 27, FPOFF(27)(1)
- lfd 26, FPOFF(26)(1)
- lfd 25, FPOFF(25)(1)
- lfd 24, FPOFF(24)(1)
- lfd 23, FPOFF(23)(1)
- lfd 22, FPOFF(22)(1)
- lfd 21, FPOFF(21)(1)
- lfd 20, FPOFF(20)(1)
- lfd 19, FPOFF(19)(1)
- lfd 18, FPOFF(18)(1)
- lfd 17, FPOFF(17)(1)
- lfd 16, FPOFF(16)(1)
- lfd 15, FPOFF(15)(1)
- lfd 14, FPOFF(14)(1)
- lfd 13, FPOFF(13)(1)
- lfd 12, FPOFF(12)(1)
- lfd 11, FPOFF(11)(1)
- lfd 10, FPOFF(10)(1)
- lfd 9, FPOFF(9)(1)
- lfd 8, FPOFF(8)(1)
- lfd 7, FPOFF(7)(1)
- lfd 6, FPOFF(6)(1)
- lfd 5, FPOFF(5)(1)
- lfd 4, FPOFF(4)(1)
- lfd 3, FPOFF(3)(1)
- lfd 2, FPOFF(2)(1)
- lfd 1, FPOFF(1)(1)
- lfd 0, FPOFF(0)(1)
+ str sp, [r1, #0]
+ ldr sp, [r0, #0]
+ add r2, sp, #4
+
+ ldmfd r2, {r4-r11}
+ ldr fp, [r2, #OFFSET_FP]
+ ldr lr, [r2, #OFFSET_LR]
- lwz 0, REGOFF(35)(1); mtxer 0
- lwz 0, REGOFF(34)(1); mtctr 0
- lwz 0, REGOFF(33)(1); mtcr 0
- lwz 0, REGOFF(32)(1); mtlr 0
- lwz 31, REGOFF(31)(1)
- lwz 30, REGOFF(30)(1)
- lwz 29, REGOFF(29)(1)
- lwz 28, REGOFF(28)(1)
- lwz 27, REGOFF(27)(1)
- lwz 26, REGOFF(26)(1)
- lwz 25, REGOFF(25)(1)
- lwz 24, REGOFF(24)(1)
- lwz 23, REGOFF(23)(1)
- lwz 22, REGOFF(22)(1)
- lwz 21, REGOFF(21)(1)
- lwz 20, REGOFF(20)(1)
- lwz 19, REGOFF(19)(1)
- lwz 18, REGOFF(18)(1)
- lwz 17, REGOFF(17)(1)
- lwz 16, REGOFF(16)(1)
- lwz 15, REGOFF(15)(1)
- lwz 14, REGOFF(14)(1)
- la 1, SA(FRAMESIZE)(1)
- blr
+ ldr r3, [r2, #OFFSET_CPSR]
+ msr cpsr_f, r3
+#ifndef __VFP_FP__
+ lfm f4, 4, [r2, #OFFSET_FPR]
+ ldr r3, [r2, #OFFSET_FS]
+ wfs r3
#endif
+
+ add sp, sp, #FRAME_SIZE+4
+ mov pc, lr