summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2009-11-10 06:51:52 +0000
committerTill Straumann <strauman@slac.stanford.edu>2009-11-10 06:51:52 +0000
commit4a4201cb410c4d3816fc1e0123982b90046ea19c (patch)
tree492f5a507ef61f8e138dad8e124f8ac4b8af8e59 /c
parent2009-11-09 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-4a4201cb410c4d3816fc1e0123982b90046ea19c.tar.bz2
2009-11-10 Till Straumann <strauman@slac.stanford.edu>
* pc386/make/custom/pc586-sse.cfg, pc386/start/start.S, shared/irq/irq_asm.S: Added experimental SSE support.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/i386/ChangeLog5
-rw-r--r--c/src/lib/libbsp/i386/pc386/make/custom/pc586-sse.cfg37
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.S69
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_asm.S32
4 files changed, 142 insertions, 1 deletions
diff --git a/c/src/lib/libbsp/i386/ChangeLog b/c/src/lib/libbsp/i386/ChangeLog
index bcf7664ee9..a2a52d53e8 100644
--- a/c/src/lib/libbsp/i386/ChangeLog
+++ b/c/src/lib/libbsp/i386/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-10 Till Straumann <strauman@slac.stanford.edu>
+
+ * pc386/make/custom/pc586-sse.cfg, pc386/start/start.S,
+ shared/irq/irq_asm.S: Added experimental SSE support.
+
2009-10-29 Till Straumann <strauman@slac.stanford.edu>
* shared/irq/irq_asm.S: Make sure stack is aligned to CPU_STACK_ALIGNMENT
diff --git a/c/src/lib/libbsp/i386/pc386/make/custom/pc586-sse.cfg b/c/src/lib/libbsp/i386/pc386/make/custom/pc586-sse.cfg
new file mode 100644
index 0000000000..2607b2db46
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/make/custom/pc586-sse.cfg
@@ -0,0 +1,37 @@
+#
+# Configuration file for a PC using a Pentium Class CPU
+#
+# $Id$
+#
+
+RTEMS_CPU_MODEL=pentium
+
+# This contains the compiler options necessary to select the CPU model
+# and enable architecture-specific features and extensions.
+
+# Note that the vanilla gcc multilibs for RTEMS are a joke. The
+# variants only differ by a -mtune=xxx option which merely 'optimizes'
+# for 'xxx' but does not use the full instruction set 'xxx' may implement.
+# (fully bwd compatible with i386).
+#
+# I'd recommend to roll your own set of (useful) multilibs instead...
+#
+# Useful variants would be
+# <default> (i386) (generic 386 with hard-float)
+# -msoft-float (generic 386 with soft-float)
+# -march=pentium4 (P4 with sse2)
+#
+# Note also: we give the -mtune=pentium option here only so that at least the
+# variant optimized for pentium (w/o using any pentium-specific
+# features) is used (assuming you use the vanilla RTEMS multilibs).
+#
+# And: The only sse-related feature the RTEMS support really needs is
+# fxsave/fxrstor. You can build with -msse, -msse2 or -msse3,
+# depending on your CPU.
+# There are run-time checks resulting in a 'panic' if code
+# compiled for e.g. -msse3 is executed on a CPU that only
+# supports sse2, though.
+CPU_CFLAGS = -mtune=pentium -march=pentium -msse2
+
+include $(RTEMS_ROOT)/make/custom/pc386.cfg
+
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.S b/c/src/lib/libbsp/i386/pc386/start/start.S
index b5e00101c4..904bc57fa2 100644
--- a/c/src/lib/libbsp/i386/pc386/start/start.S
+++ b/c/src/lib/libbsp/i386/pc386/start/start.S
@@ -69,6 +69,13 @@ BEGIN_CODE
EXTERN (debugPollingGetChar)
EXTERN (checkCPUtypeSetCr0)
EXTERN (BSP_console_select)
+ EXTERN (printk)
+#ifdef __SSE__
+ EXTERN (x86_capability)
+#ifdef __SSE3__
+ EXTERN (x86_capability_x)
+#endif
+#endif
/*
* In case this crashes on your machine and this is not due
@@ -142,7 +149,7 @@ speakl: jmp speakl # and SPIN!!!
/*
* try printk and a getchar in polling mode ASAP
*/
- pushl $welcome_msg
+ movl $welcome_msg, 0(esp)
call printk
addl $4, esp
@@ -207,6 +214,44 @@ SYM (zero_bss):
+---------------------------------------------------------------------*/
call SYM(BSP_console_select)
+#ifdef __SSE__
+/*--------------------------------------------------------------------+
+ | Enable SSE; we really only care about fxsave/fxrstor and leave
+ | The only feature *we* (as an OS) use is fxsave/fxrstor.
+ | But as a courtesy we make sure we don't execute on hardware
+ | that doesn't support features possibly used by the compiler.
++---------------------------------------------------------------------*/
+ movl SYM (x86_capability), eax
+ testl $0x01000000, eax
+ jne 1f
+ movl $SYM (no_fxsave_msg), 0(esp)
+ jmp SYM(_sse_panic)
+1:
+ testl $0x02000000, eax
+ jne 1f
+ movl $SYM (no_sse_msg), 0(esp)
+ jmp SYM(_sse_panic)
+1:
+#ifdef __SSE2__
+ testl $0x04000000, eax
+ jne 1f
+ movl $SYM (no_sse2_msg), 0(esp)
+ jmp SYM(_sse_panic)
+1:
+#endif
+#ifdef __SSE3__
+ movl SYM (x86_capability_x), eax
+ testl $1, eax
+ jne 1f
+ movl $SYM (no_sse3_msg), 0(esp)
+ jmp SYM(_sse_panic)
+1:
+#endif
+ mov cr4, eax # OK to enable now
+ or $0x600, eax
+ mov eax, cr4
+#endif
+
/*---------------------------------------------------------------------+
| Transfer control to User's Board Support Package
| Note: at the top we reserved space for the argument
@@ -228,6 +273,13 @@ SYM (zero_bss):
jmp SYM (_return_to_monitor)
+#ifdef __SSE__
+SYM(_sse_panic):
+ call SYM(printk)
+1: hlt
+ jmp 1b
+#endif
+
END_CODE
BEGIN_DATA
@@ -270,6 +322,21 @@ SYM (made_it_msg) :
#endif
+#ifdef __SSE__
+SYM (no_fxsave_msg) :
+ .string "PANIC: compiled for SSE but CPU seems to have no FXSAVE/FXRSTOR support (which I need)\n"
+SYM (no_sse_msg) :
+ .string "PANIC: compiled for SSE but your CPU seems to have no SSE support\n"
+#ifdef __SSE2__
+SYM (no_sse2_msg) :
+ .string "PANIC: compiled for SSE2 but your CPU seems to have no SSE2 support\n"
+#endif
+#ifdef __SSE3__
+SYM (no_sse3_msg) :
+ .string "PANIC: compiled for SSE3 but your CPU seems to have no SSE3 support\n"
+#endif
+#endif
+
END_DATA
END
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_asm.S b/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
index 1335bd749d..be0bcbb859 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_asm.S
@@ -24,7 +24,12 @@
#define MSK_OFF 4
#define EBP_OFF 8 /* code restoring ebp/esp relies on */
#define ESP_OFF 12 /* esp being on top of ebp! */
+#ifdef __SSE__
+#define FRM_SIZ (16+512)
+#define SSE_OFF 16
+#else
#define FRM_SIZ 16
+#endif
BEGIN_CODE
@@ -70,6 +75,27 @@ SYM (_ISR_Handler):
movl eax, ESP_OFF(esp)
movl ebp, EBP_OFF(esp)
+#ifdef __SSE__
+ /* NOTE: SSE only is supported if the BSP enables fxsave/fxrstor
+ * to save/restore SSE context! This is so far only implemented
+ * for pc386!.
+ */
+
+ /* We save SSE here (on the task stack) because we possibly
+ * call other C-code (besides the ISR, namely _Thread_Dispatch()
+ * or _ThreadProcessSignalsFromIrq()).
+ */
+ /* don't wait here; a possible exception condition will eventually be
+ * detected when the task resumes control and executes a FP instruction
+ fwait
+ */
+ fxsave SSE_OFF(esp)
+ fninit /* clean-slate FPU */
+ movl $0x1f80, ARG_OFF(esp) /* use ARG_OFF as scratch space */
+ ldmxcsr ARG_OFF(esp) /* clean-slate MXCSR */
+#endif
+
+
/*
* acknowledge the interrupt
*
@@ -197,6 +223,12 @@ nested:
* eip, CS, Flags).
*/
.exit:
+
+#ifdef __SSE__
+ fwait
+ fxrstor SSE_OFF(esp)
+#endif
+
/* restore ebp and original esp */
addl $EBP_OFF, esp
popl ebp