summaryrefslogtreecommitdiff
path: root/include/rtems/score/i386.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/rtems/score/i386.h')
-rw-r--r--include/rtems/score/i386.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/include/rtems/score/i386.h b/include/rtems/score/i386.h
new file mode 100644
index 0000000000..875526ad62
--- /dev/null
+++ b/include/rtems/score/i386.h
@@ -0,0 +1,261 @@
+/**
+ * @file
+ *
+ * @brief Intel I386 CPU Dependent Source
+ *
+ * This include file contains information pertaining to the Intel
+ * i386 processor.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_I386_H
+#define _RTEMS_SCORE_I386_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This section contains the information required to build
+ * RTEMS for a particular member of the Intel i386
+ * family when executing in protected mode. It does
+ * this by setting variables to indicate which implementation
+ * dependent features are present in a particular member
+ * of the family.
+ *
+ * Currently recognized:
+ * i386_fp (i386 DX or SX w/i387)
+ * i486dx
+ * pentium
+ * pentiumpro
+ *
+ * CPU Model Feature Flags:
+ *
+ * I386_HAS_BSWAP: Defined to "1" if the instruction for endian swapping
+ * (bswap) should be used. This instruction appears to
+ * be present in all i486's and above.
+ *
+ * I386_HAS_FPU: Defined to "1" if the CPU has an FPU.
+ * As of at least gcc 4.7, i386 soft-float was obsoleted.
+ * Thus this is always set to "1".
+ */
+#define I386_HAS_FPU 1
+
+#if defined(__pentiumpro__)
+
+ #define CPU_MODEL_NAME "Pentium Pro"
+
+#elif defined(__i586__)
+
+ #if defined(__pentium__)
+ #define CPU_MODEL_NAME "Pentium"
+ #elif defined(__k6__)
+ #define CPU_MODEL_NAME "K6"
+ #else
+ #define CPU_MODEL_NAME "i586"
+ #endif
+
+#elif defined(__i486__)
+
+ #define CPU_MODEL_NAME "i486dx"
+
+#elif defined(__i386__)
+
+ #define I386_HAS_BSWAP 0
+ #define CPU_MODEL_NAME "i386 with i387"
+
+#else
+ #error "Unknown CPU Model"
+#endif
+
+/*
+ * Set default values for CPU model feature flags
+ *
+ * NOTE: These settings are chosen to reflect most of the family members.
+ */
+#ifndef I386_HAS_BSWAP
+#define I386_HAS_BSWAP 1
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+#define CPU_NAME "Intel i386"
+
+#ifndef ASM
+
+/*
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static so it can be referenced indirectly.
+ */
+
+static inline uint32_t i386_swap_u32(
+ uint32_t value
+)
+{
+ uint32_t lout;
+
+#if (I386_HAS_BSWAP == 0)
+ __asm__ volatile( "rorw $8,%%ax;"
+ "rorl $16,%0;"
+ "rorw $8,%%ax" : "=a" (lout) : "0" (value) );
+#else
+ __asm__ volatile( "bswap %0" : "=r" (lout) : "0" (value));
+#endif
+ return( lout );
+}
+
+static inline uint16_t i386_swap_u16(
+ uint16_t value
+)
+{
+ unsigned short sout;
+
+ __asm__ volatile( "rorw $8,%0" : "=r" (sout) : "0" (value));
+ return (sout);
+}
+
+/*
+ * Added for pagination management
+ */
+static inline unsigned int i386_get_cr0(void)
+{
+ register unsigned int segment = 0;
+
+ __asm__ volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr0(unsigned int segment)
+{
+ __asm__ volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
+}
+
+static inline unsigned int i386_get_cr2(void)
+{
+ register unsigned int segment = 0;
+
+ __asm__ volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned int i386_get_cr3(void)
+{
+ register unsigned int segment = 0;
+
+ __asm__ volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline void i386_set_cr3(unsigned int segment)
+{
+ __asm__ volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
+}
+
+/* routines */
+
+/*
+ * i386_Logical_to_physical
+ *
+ * Converts logical address to physical address.
+ */
+void *i386_Logical_to_physical(
+ unsigned short segment,
+ void *address
+);
+
+/*
+ * i386_Physical_to_logical
+ *
+ * Converts physical address to logical address.
+ */
+void *i386_Physical_to_logical(
+ unsigned short segment,
+ void *address
+);
+
+/**
+ * @brief Converts real mode pointer {segment, offset} to physical address.
+ *
+ * i386_Real_to_physical
+ *
+ * @param[in] segment used with \p offset to compute physical address
+ * @param[in] offset used with \p segment to compute physical address
+ * @retval physical address
+ */
+RTEMS_INLINE_ROUTINE void *i386_Real_to_physical(
+ uint16_t segment,
+ uint16_t offset)
+{
+ return (void *)(((uint32_t)segment<<4)+offset);
+}
+
+/**
+ * @brief Retreives real mode pointer elements {segmnet, offset} from
+ * physical address.
+ *
+ * i386_Physical_to_real
+ * Function returns the highest segment (base) address possible.
+ * Example: input address - 0x4B3A2
+ * output segment - 0x4B3A
+ * offset - 0x2
+ * input address - 0x10F12E
+ * output segment - 0xFFFF
+ * offset - 0xF13E
+ *
+ * @param[in] address address to be converted, must be less than 0x10FFEF
+ * @param[out] segment segment computed from \p address
+ * @param[out] offset offset computed from \p address
+ * @retval 0 address not convertible
+ * @retval 1 segment and offset extracted
+ */
+int i386_Physical_to_real(
+ void *address,
+ uint16_t *segment,
+ uint16_t *offset
+);
+
+/*
+ * "Simpler" names for a lot of the things defined in this file
+ */
+
+/* segment access routines */
+
+#define get_cs() i386_get_cs()
+#define get_ds() i386_get_ds()
+#define get_es() i386_get_es()
+#define get_ss() i386_get_ss()
+#define get_fs() i386_get_fs()
+#define get_gs() i386_get_gs()
+
+#define CPU_swap_u32( _value ) i386_swap_u32( _value )
+#define CPU_swap_u16( _value ) i386_swap_u16( _value )
+
+/* i80x86 I/O instructions */
+
+#define outport_byte( _port, _value ) i386_outport_byte( _port, _value )
+#define outport_word( _port, _value ) i386_outport_word( _port, _value )
+#define outport_long( _port, _value ) i386_outport_long( _port, _value )
+#define inport_byte( _port, _value ) i386_inport_byte( _port, _value )
+#define inport_word( _port, _value ) i386_inport_word( _port, _value )
+#define inport_long( _port, _value ) i386_inport_long( _port, _value )
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif