[PATCH 7/7] i386: refactor libcpu/cpu.h into rtems/score/i386.h

Gedare Bloom gedare at rtems.org
Mon Feb 15 19:05:44 UTC 2016


From: Joel Sherrill <joel at rtems.org>

Fixes #2515.
---
 c/src/lib/libbsp/i386/pc386/include/bsp.h          |   2 +-
 c/src/lib/libbsp/i386/shared/irq/idt.c             |   2 +-
 c/src/lib/libbsp/i386/shared/irq/irq_init.c        |   2 +-
 .../libbsp/i386/shared/realmode_int/realmode_int.h |   2 +-
 c/src/lib/libbsp/i386/shared/smp/smp-imps.c        |   2 +-
 c/src/lib/libcpu/i386/Makefile.am                  |   4 +-
 c/src/lib/libcpu/i386/cache.c                      |   4 +-
 c/src/lib/libcpu/i386/cpu.h                        | 475 ---------------------
 c/src/lib/libcpu/i386/displayCpu.c                 |   2 +-
 c/src/lib/libcpu/i386/page.c                       |   3 +-
 c/src/lib/libcpu/i386/page.h                       |  39 ++
 c/src/lib/libcpu/i386/preinstall.am                |   6 +-
 cpukit/score/cpu/i386/rtems/score/cpu.h            |   5 -
 cpukit/score/cpu/i386/rtems/score/i386.h           | 437 ++++++++++++++++++-
 14 files changed, 477 insertions(+), 508 deletions(-)
 delete mode 100644 c/src/lib/libcpu/i386/cpu.h
 create mode 100644 c/src/lib/libcpu/i386/page.h

diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index cee5566..3d29e3e 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -57,7 +57,7 @@
 #include <rtems/iosupp.h>
 #include <rtems/console.h>
 #include <rtems/clockdrv.h>
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 #include <rtems/bspIo.h>
 
 #ifdef __cplusplus
diff --git a/c/src/lib/libbsp/i386/shared/irq/idt.c b/c/src/lib/libbsp/i386/shared/irq/idt.c
index fc9364e..ee6f8e0 100644
--- a/c/src/lib/libbsp/i386/shared/irq/idt.c
+++ b/c/src/lib/libbsp/i386/shared/irq/idt.c
@@ -16,7 +16,7 @@
  *  http://www.rtems.org/license/LICENSE.
  */
 
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 #include <bsp/irq.h>
 
 static rtems_raw_irq_connect_data* 	raw_irq_table;
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_init.c b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
index 9bf9bc5..fe8d7e7 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_init.c
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
@@ -16,7 +16,7 @@
 
 #include <rtems/bspIo.h>
 
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 
 #include <bsp.h>
 #include <bsp/irq.h>
diff --git a/c/src/lib/libbsp/i386/shared/realmode_int/realmode_int.h b/c/src/lib/libbsp/i386/shared/realmode_int/realmode_int.h
index a6b067d..e8a1e36 100644
--- a/c/src/lib/libbsp/i386/shared/realmode_int/realmode_int.h
+++ b/c/src/lib/libbsp/i386/shared/realmode_int/realmode_int.h
@@ -23,7 +23,7 @@
 #ifndef _REALMODE_INT_H
 #define _REALMODE_INT_H
 
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 #include <stdint.h>
 
 #ifndef ASM /* ASM */
diff --git a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
index 158a45d..ca1a0f1 100644
--- a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
+++ b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
@@ -79,7 +79,7 @@
 #include <unistd.h>
 #include <rtems.h>
 #include <rtems/bspIo.h>
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 #include <assert.h>
 
 extern void _pc386_delay(void);
diff --git a/c/src/lib/libcpu/i386/Makefile.am b/c/src/lib/libcpu/i386/Makefile.am
index 0869435..79797b5 100644
--- a/c/src/lib/libcpu/i386/Makefile.am
+++ b/c/src/lib/libcpu/i386/Makefile.am
@@ -6,7 +6,7 @@ include $(top_srcdir)/../../../automake/compile.am
 
 include_libcpudir = $(includedir)/libcpu
 
-include_libcpu_HEADERS = cpu.h cpuModel.h
+include_libcpu_HEADERS = page.h cpuModel.h
 include_libcpu_HEADERS += ../shared/include/cache.h
 include_libcpu_HEADERS += byteorder.h
 
@@ -22,7 +22,7 @@ score_rel_CPPFLAGS = $(AM_CPPFLAGS)
 score_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
 
 noinst_PROGRAMS += page.rel
-page_rel_SOURCES = page.c cpu.h
+page_rel_SOURCES = page.c page.h
 page_rel_CPPFLAGS = $(AM_CPPFLAGS)
 page_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
 
diff --git a/c/src/lib/libcpu/i386/cache.c b/c/src/lib/libcpu/i386/cache.c
index 66657ab..da31a38 100644
--- a/c/src/lib/libcpu/i386/cache.c
+++ b/c/src/lib/libcpu/i386/cache.c
@@ -3,9 +3,9 @@
  */
 
 #include <rtems.h>
-#include <rtems/score/registers.h>
 #include "cache_.h"
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/page.h>
 
 void _CPU_disable_cache(void)
 {
diff --git a/c/src/lib/libcpu/i386/cpu.h b/c/src/lib/libcpu/i386/cpu.h
deleted file mode 100644
index c0c4756..0000000
--- a/c/src/lib/libcpu/i386/cpu.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * @file cpu.h
- *
- *          This file contains definitions for data structure related
- *          to Intel system programming. More information can be found
- *	    on Intel site and more precisely in the following book :
- *
- *		Pentium Processor familly
- *		Developper's Manual
- *
- *		Volume 3 : Architecture and Programming Manual
- *
- * Copyright (C) 1998  Eric Valette (valette at crf.canon.fr)
- *                     Canon Centre Recherche France.
- *
- *  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 _LIBCPU_i386_CPU_H
-#define _LIBCPU_i386_CPU_H
-
-#include <rtems/score/registers.h>
-
-#ifndef ASM
-
-/*
- *  Interrupt Level Macros
- */
-#include <rtems/score/interrupts.h>
-
-#include <rtems/score/basedefs.h>
-
-/*
- *  Segment Access Routines
- *
- *  NOTE:  Unfortunately, these are still static inlines even when the
- *         "macro" implementation of the generic code is used.
- */
-
-static __inline__ unsigned short i386_get_cs(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-static __inline__ unsigned short i386_get_ds(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-static __inline__ unsigned short i386_get_es(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-static __inline__ unsigned short i386_get_ss(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-static __inline__ unsigned short i386_get_fs(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-static __inline__ unsigned short i386_get_gs(void)
-{
-  register unsigned short segment = 0;
-
-  __asm__ volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
-
-  return segment;
-}
-
-/*
- *  IO Port Access Routines
- */
-
-#define i386_outport_byte( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned char  __value = _value; \
-     \
-     __asm__ volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
-   } while (0)
-
-#define i386_outport_word( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned short __value = _value; \
-     \
-     __asm__ volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
-   } while (0)
-
-#define i386_outport_long( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned int  __value = _value; \
-     \
-     __asm__ volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
-   } while (0)
-
-#define i386_inport_byte( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned char  __value = 0; \
-     \
-     __asm__ volatile ( "inb %1,%0" : "=a" (__value) \
-                                : "d"  (__port) \
-                  ); \
-     _value = __value; \
-   } while (0)
-
-#define i386_inport_word( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned short __value = 0; \
-     \
-     __asm__ volatile ( "inw %1,%0" : "=a" (__value) \
-                                : "d"  (__port) \
-                  ); \
-     _value = __value; \
-   } while (0)
-
-#define i386_inport_long( _port, _value ) \
-do { register unsigned short __port  = _port; \
-     register unsigned int  __value = 0; \
-     \
-     __asm__ volatile ( "inl %1,%0" : "=a" (__value) \
-                                : "d"  (__port) \
-                  ); \
-     _value = __value; \
-   } while (0)
-
-/*
- * Type definition for raw interrupts.
- */
-
-typedef unsigned char  rtems_vector_offset;
-
-typedef struct __rtems_raw_irq_connect_data__{
- /*
-  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
-  */
-  rtems_vector_offset		idtIndex;
-  /*
-   * IDT raw handler. See comment on handler properties below in function prototype.
-   */
-  rtems_raw_irq_hdl	   	hdl;
-  /*
-   * function for enabling raw interrupts. In order to be consistent
-   * with the fact that the raw connexion can defined in the
-   * libcpu library, this library should have no knowledge of
-   * board specific hardware to manage interrupts and thus the
-   * "on" routine must enable the irq both at device and PIC level.
-   *
-   */
-    rtems_raw_irq_enable	on;
-  /*
-   * function for disabling raw interrupts. In order to be consistent
-   * with the fact that the raw connexion can defined in the
-   * libcpu library, this library should have no knowledge of
-   * board specific hardware to manage interrupts and thus the
-   * "on" routine must disable the irq both at device and PIC level.
-   *
-   */
-  rtems_raw_irq_disable		off;
-  /*
-   * function enabling to know what interrupt may currently occur
-   */
-  rtems_raw_irq_is_enabled	isOn;
-}rtems_raw_irq_connect_data;
-
-typedef struct {
-  /*
-   * size of all the table fields (*Tbl) described below.
-   */
-  unsigned int	 		idtSize;
-  /*
-   * Default handler used when disconnecting interrupts.
-   */
-  rtems_raw_irq_connect_data	defaultRawEntry;
-  /*
-   * Table containing initials/current value.
-   */
-  rtems_raw_irq_connect_data*	rawIrqHdlTbl;
-}rtems_raw_irq_global_settings;
-
-#include <rtems/score/idtr.h>
-
-/*
- * C callable function enabling to get handler currently connected to a vector
- *
- */
-rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
-
-/*
- * C callable function enabling to set up one raw idt entry
- */
-extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
-
-/*
- * C callable function enabling to get one current raw idt entry
- */
-extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
-
-/*
- * C callable function enabling to remove one current raw idt entry
- */
-extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
-
-/*
- * C callable function enabling to init idt.
- *
- * CAUTION : this function assumes that the IDTR register
- * has been already set.
- */
-extern int i386_init_idt (rtems_raw_irq_global_settings* config);
-
-/*
- * C callable function enabling to get actual idt configuration
- */
-extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
-
-
-/*
- * See page 11.12 Figure 11-8.
- *
- */
-/**
- * @brief describes one entry of Global/Local Descriptor Table
- */
-typedef struct {
-  unsigned int limit_15_0 		: 16;
-  unsigned int base_address_15_0	: 16;
-  unsigned int base_address_23_16	: 8;
-  unsigned int type			: 4;
-  unsigned int descriptor_type		: 1;
-  unsigned int privilege		: 2;
-  unsigned int present			: 1;
-  unsigned int limit_19_16		: 4;
-  unsigned int available		: 1;
-  unsigned int fixed_value_bits		: 1;
-  unsigned int operation_size		: 1;
-  unsigned int granularity		: 1;
-  unsigned int base_address_31_24	: 8;
-} RTEMS_PACKED segment_descriptors;
-
-/*
- * C callable function enabling to get easilly usable info from
- * the actual value of GDT register.
- */
-extern void i386_get_info_from_GDTR (segment_descriptors** table,
-                                     uint16_t* limit);
-/*
- * C callable function enabling to change the value of GDT register. Must be called
- * with interrupts masked at processor level!!!.
- */
-extern void i386_set_GDTR (segment_descriptors*,
-                           uint16_t limit);
-
-/**
- * @brief Allows to set a GDT entry.
- *
- * Puts global descriptor \p sd to the global descriptor table on index
- * \p segment_selector_index
- *
- * @param[in] segment_selector_index index to GDT entry
- * @param[in] sd structure to be coppied to given \p segment_selector in GDT
- * @retval  0 FAILED out of GDT range or index is 0, which is not valid
- *                   index in GDT
- * @retval  1 SUCCESS
- */
-extern uint32_t i386_raw_gdt_entry (uint16_t segment_selector_index,
-                               segment_descriptors* sd);
-
-/**
- * @brief fills \p sd with provided \p base in appropriate fields of \p sd
- *
- * @param[in] base 32-bit address to be set as descriptor's base
- * @param[out] sd descriptor being filled with \p base
- */
-extern void i386_fill_segment_desc_base (uint32_t base,
-                                         segment_descriptors* sd);
-
-/**
- * @brief fills \p sd with provided \p limit in appropriate fields of \p sd
- *
- * sets granularity bit if necessary
- *
- * @param[in] limit 32-bit value representing number of limit bytes
- * @param[out] sd descriptor being filled with \p limit
- */
-extern void i386_fill_segment_desc_limit (uint32_t limit,
-                                          segment_descriptors* sd);
-
-/*
- * C callable function enabling to set up one raw interrupt handler
- */
-extern uint32_t i386_set_gdt_entry (uint16_t segment_selector,
-                                    uint32_t base,
-                                    uint32_t limit);
-
-/**
- * @brief Returns next empty descriptor in GDT.
- *
- * Number of descriptors that can be returned depends on \a GDT_SIZE
- *
- * @retval  0 FAILED GDT is full
- * @retval  <1;65535> segment_selector number as index to GDT
- */
-extern uint16_t i386_next_empty_gdt_entry (void);
-
-/**
- * @brief Copies GDT entry at index \p segment_selector to structure
- * pointed to by \p struct_to_fill
- *
- * @param[in] segment_selector index to GDT table specifying descriptor to copy
- * @param[out] struct_to_fill pointer to memory where will be descriptor coppied
- * @retval  0 FAILED segment_selector out of GDT range
- * @retval  <1;65535> retrieved segment_selector
- */
-extern uint16_t i386_cpy_gdt_entry (uint16_t segment_selector,
-                                    segment_descriptors* struct_to_fill);
-
-/**
- * @brief Returns pointer to GDT table at index given by \p segment_selector
- *
- * @param[in] sgmnt_selector index to GDT table for specifying descriptor to get
- * @retval  NULL FAILED segment_selector out of GDT range
- * @retval  pointer to GDT table at \p segment_selector
- */
-extern segment_descriptors* i386_get_gdt_entry (uint16_t sgmnt_selector);
-
-/**
- * @brief Extracts base address from GDT entry pointed to by \p gdt_entry
- *
- * @param[in]  gdt_entry pointer to entry from which base should be retrieved
- * @retval base address from GDT entry
-*/
-RTEMS_INLINE_ROUTINE void* i386_base_gdt_entry (segment_descriptors* gdt_entry)
-{
-    return (void*)(gdt_entry->base_address_15_0 |
-            (gdt_entry->base_address_23_16<<16) |
-            (gdt_entry->base_address_31_24<<24));
-}
-
-/**
- * @brief Extracts limit in bytes from GDT entry pointed to by \p gdt_entry
- *
- * @param[in]  gdt_entry pointer to entry from which limit should be retrieved
- * @retval limit value in bytes from GDT entry
- */
-extern uint32_t i386_limit_gdt_entry (segment_descriptors* gdt_entry);
-
-/*
- * See page 11.18 Figure 11-12.
- *
- */
-
-typedef struct {
-  unsigned int offset			: 12;
-  unsigned int page			: 10;
-  unsigned int directory 		: 10;
-}la_bits;
-
-typedef union {
-  la_bits	bits;
-  unsigned int	address;
-}linear_address;
-
-
-/*
- * See page 11.20 Figure 11-14.
- *
- */
-
-typedef struct {
-  unsigned int present	 		: 1;
-  unsigned int writable			: 1;
-  unsigned int user			: 1;
-  unsigned int write_through		: 1;
-  unsigned int cache_disable		: 1;
-  unsigned int accessed			: 1;
-  unsigned int reserved1		: 1;
-  unsigned int page_size		: 1;
-  unsigned int reserved2		: 1;
-  unsigned int available		: 3;
-  unsigned int page_frame_address	: 20;
-}page_dir_bits;
-
-typedef union {
-  page_dir_bits	bits;
-  unsigned int	dir_entry;
-}page_dir_entry;
-
-typedef struct {
-  unsigned int present	 		: 1;
-  unsigned int writable			: 1;
-  unsigned int user			: 1;
-  unsigned int write_through		: 1;
-  unsigned int cache_disable		: 1;
-  unsigned int accessed			: 1;
-  unsigned int dirty			: 1;
-  unsigned int reserved2		: 2;
-  unsigned int available		: 3;
-  unsigned int page_frame_address	: 20;
-}page_table_bits;
-
-typedef union {
-  page_table_bits	bits;
-  unsigned int		table_entry;
-} page_table_entry;
-
-/*
- * definitions related to page table entry
- */
-#define PG_SIZE 0x1000
-#define MASK_OFFSET 0xFFF
-#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
-#define FOUR_MB       0x400000
-#define MASK_FLAGS 0x1A
-
-#define PTE_PRESENT  		0x01
-#define PTE_WRITABLE 		0x02
-#define PTE_USER		0x04
-#define PTE_WRITE_THROUGH	0x08
-#define PTE_CACHE_DISABLE	0x10
-
-typedef struct {
-  page_dir_entry pageDirEntry[MAX_ENTRY];
-} page_directory;
-
-typedef struct {
-  page_table_entry pageTableEntry[MAX_ENTRY];
-} page_table;
-
-
-/* C declaration for paging management */
-
-extern int  	_CPU_is_cache_enabled(void);
-extern int  	_CPU_is_paging_enabled(void);
-extern int 	init_paging(void);
-extern void 	_CPU_enable_paging(void);
-extern void 	_CPU_disable_paging(void);
-extern void 	_CPU_disable_cache(void);
-extern void 	_CPU_enable_cache(void);
-extern int 	_CPU_map_phys_address
-                      (void **mappedAddress, void *physAddress,
-		       int size, int flag);
-extern int 	_CPU_unmap_virt_address (void *mappedAddress, int size);
-extern int 	_CPU_change_memory_mapping_attribute
-                         (void **newAddress, void *mappedAddress,
-			  unsigned int size, unsigned int flag);
-extern int  	_CPU_display_memory_attribute(void);
-
-# endif /* ASM */
-
-#endif
diff --git a/c/src/lib/libcpu/i386/displayCpu.c b/c/src/lib/libcpu/i386/displayCpu.c
index f8ab3b3..f451194 100644
--- a/c/src/lib/libcpu/i386/displayCpu.c
+++ b/c/src/lib/libcpu/i386/displayCpu.c
@@ -20,7 +20,7 @@
  * Tell us the machine setup..
  */
 #include <stdio.h>
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
 #include <string.h>
 #include <libcpu/cpuModel.h>
 #include <rtems/bspIo.h>
diff --git a/c/src/lib/libcpu/i386/page.c b/c/src/lib/libcpu/i386/page.c
index b35d72b..f05e145 100644
--- a/c/src/lib/libcpu/i386/page.c
+++ b/c/src/lib/libcpu/i386/page.c
@@ -21,7 +21,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <rtems.h>
-#include <libcpu/cpu.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/page.h>
 
 #define MEMORY_SIZE 0x4000000 		/* 64Mo */
 
diff --git a/c/src/lib/libcpu/i386/page.h b/c/src/lib/libcpu/i386/page.h
new file mode 100644
index 0000000..5e9cec2
--- /dev/null
+++ b/c/src/lib/libcpu/i386/page.h
@@ -0,0 +1,39 @@
+/*
+ * @file page.h
+ *
+ * Copyright (C) 1998  Eric Valette (valette at crf.canon.fr)
+ *                     Canon Centre Recherche France.
+ *
+ *  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 _LIBCPU_i386_PAGE_H
+#define _LIBCPU_i386_PAGE_H
+
+#ifndef ASM
+
+#include <rtems/score/cpu.h>
+
+/* C declaration for paging management */
+
+extern int  	_CPU_is_cache_enabled(void);
+extern int  	_CPU_is_paging_enabled(void);
+extern int 	init_paging(void);
+extern void 	_CPU_enable_paging(void);
+extern void 	_CPU_disable_paging(void);
+extern void 	_CPU_disable_cache(void);
+extern void 	_CPU_enable_cache(void);
+extern int 	_CPU_map_phys_address
+                      (void **mappedAddress, void *physAddress,
+		       int size, int flag);
+extern int 	_CPU_unmap_virt_address (void *mappedAddress, int size);
+extern int 	_CPU_change_memory_mapping_attribute
+                         (void **newAddress, void *mappedAddress,
+			  unsigned int size, unsigned int flag);
+extern int  	_CPU_display_memory_attribute(void);
+
+# endif /* ASM */
+
+#endif
diff --git a/c/src/lib/libcpu/i386/preinstall.am b/c/src/lib/libcpu/i386/preinstall.am
index 6f4af52..dab3862 100644
--- a/c/src/lib/libcpu/i386/preinstall.am
+++ b/c/src/lib/libcpu/i386/preinstall.am
@@ -18,9 +18,9 @@ $(PROJECT_INCLUDE)/libcpu/$(dirstamp):
 	@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 
-$(PROJECT_INCLUDE)/libcpu/cpu.h: cpu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
-	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cpu.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cpu.h
+$(PROJECT_INCLUDE)/libcpu/page.h: page.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/page.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/page.h
 
 $(PROJECT_INCLUDE)/libcpu/cpuModel.h: cpuModel.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cpuModel.h
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index 18b63af..6abbdf8 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -30,11 +30,6 @@ extern "C" {
 #include <rtems/score/types.h>
 #include <rtems/score/i386.h>
 
-#ifndef ASM
-#include <rtems/score/interrupts.h>	/* formerly in libcpu/cpu.h> */
-#include <rtems/score/registers.h>	/* formerly part of libcpu */
-#endif
-
 /* conditional compilation parameters */
 
 #define CPU_INLINE_ENABLE_DISPATCH       TRUE
diff --git a/cpukit/score/cpu/i386/rtems/score/i386.h b/cpukit/score/cpu/i386/rtems/score/i386.h
index 875526a..2555d13 100644
--- a/cpukit/score/cpu/i386/rtems/score/i386.h
+++ b/cpukit/score/cpu/i386/rtems/score/i386.h
@@ -8,9 +8,12 @@
  */
 
 /*
- *  COPYRIGHT (c) 1989-2013.
+ *  COPYRIGHT (c) 1989-2016.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (C) 1998  Eric Valette (valette at crf.canon.fr)
+ *                     Canon Centre Recherche France.
+ *
  *  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.
@@ -23,6 +26,9 @@
 extern "C" {
 #endif
 
+#include <rtems/score/interrupts.h>
+#include <rtems/score/registers.h>
+
 /*
  *  This section contains the information required to build
  *  RTEMS for a particular member of the Intel i386
@@ -112,6 +118,7 @@ static inline uint32_t i386_swap_u32(
 #endif
   return( lout );
 }
+#define CPU_swap_u32( _value )  i386_swap_u32( _value )
 
 static inline uint16_t i386_swap_u16(
   uint16_t value
@@ -122,6 +129,7 @@ static inline uint16_t i386_swap_u16(
   __asm__ volatile( "rorw $8,%0" : "=r"  (sout) : "0"   (value));
   return (sout);
 }
+#define CPU_swap_u16( _value )  i386_swap_u16( _value )
 
 /*
  * Added for pagination management
@@ -202,7 +210,7 @@ RTEMS_INLINE_ROUTINE void *i386_Real_to_physical(
 }
 
 /**
- * @brief Retreives real mode pointer elements {segmnet, offset} from
+ * @brief Retrieves real mode pointer elements {segmnet, offset} from
  * physical address.
  *
  * i386_Physical_to_real
@@ -227,23 +235,425 @@ int i386_Physical_to_real(
 );
 
 /*
- *  "Simpler" names for a lot of the things defined in this file
+ *  Segment Access Routines
+ *
+ *  NOTE:  Unfortunately, these are still static inlines even when the
+ *         "macro" implementation of the generic code is used.
  */
 
-/* segment access routines */
+static __inline__ unsigned short i386_get_cs(void)
+{
+  register unsigned short segment = 0;
 
-#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()
+  __asm__ volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
 
-#define CPU_swap_u32( _value )  i386_swap_u32( _value )
-#define CPU_swap_u16( _value )  i386_swap_u16( _value )
+  return segment;
+}
+
+static __inline__ unsigned short i386_get_ds(void)
+{
+  register unsigned short segment = 0;
+
+  __asm__ volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
+
+  return segment;
+}
+
+static __inline__ unsigned short i386_get_es(void)
+{
+  register unsigned short segment = 0;
+
+  __asm__ volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
+
+  return segment;
+}
+
+static __inline__ unsigned short i386_get_ss(void)
+{
+  register unsigned short segment = 0;
+
+  __asm__ volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
+
+  return segment;
+}
+
+static __inline__ unsigned short i386_get_fs(void)
+{
+  register unsigned short segment = 0;
+
+  __asm__ volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
+
+  return segment;
+}
 
-/* i80x86 I/O instructions */
+static __inline__ unsigned short i386_get_gs(void)
+{
+  register unsigned short segment = 0;
+
+  __asm__ volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
+
+  return segment;
+}
+
+/*
+ *  IO Port Access Routines
+ */
+
+#define i386_outport_byte( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned char  __value = _value; \
+     \
+     __asm__ volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
+   } while (0)
+
+#define i386_outport_word( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned short __value = _value; \
+     \
+     __asm__ volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
+   } while (0)
+
+#define i386_outport_long( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned int  __value = _value; \
+     \
+     __asm__ volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
+   } while (0)
+
+#define i386_inport_byte( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned char  __value = 0; \
+     \
+     __asm__ volatile ( "inb %1,%0" : "=a" (__value) \
+                                : "d"  (__port) \
+                  ); \
+     _value = __value; \
+   } while (0)
+
+#define i386_inport_word( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned short __value = 0; \
+     \
+     __asm__ volatile ( "inw %1,%0" : "=a" (__value) \
+                                : "d"  (__port) \
+                  ); \
+     _value = __value; \
+   } while (0)
+
+#define i386_inport_long( _port, _value ) \
+do { register unsigned short __port  = _port; \
+     register unsigned int  __value = 0; \
+     \
+     __asm__ volatile ( "inl %1,%0" : "=a" (__value) \
+                                : "d"  (__port) \
+                  ); \
+     _value = __value; \
+   } while (0)
+
+/*
+ * Type definition for raw interrupts.
+ */
+
+typedef unsigned char  rtems_vector_offset;
+
+typedef struct __rtems_raw_irq_connect_data__{
+ /*
+  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
+  */
+  rtems_vector_offset		idtIndex;
+  /*
+   * IDT raw handler. See comment on handler properties below in function prototype.
+   */
+  rtems_raw_irq_hdl	   	hdl;
+  /*
+   * function for enabling raw interrupts. In order to be consistent
+   * with the fact that the raw connexion can defined in the
+   * libcpu library, this library should have no knowledge of
+   * board specific hardware to manage interrupts and thus the
+   * "on" routine must enable the irq both at device and PIC level.
+   *
+   */
+    rtems_raw_irq_enable	on;
+  /*
+   * function for disabling raw interrupts. In order to be consistent
+   * with the fact that the raw connexion can defined in the
+   * libcpu library, this library should have no knowledge of
+   * board specific hardware to manage interrupts and thus the
+   * "on" routine must disable the irq both at device and PIC level.
+   *
+   */
+  rtems_raw_irq_disable		off;
+  /*
+   * function enabling to know what interrupt may currently occur
+   */
+  rtems_raw_irq_is_enabled	isOn;
+}rtems_raw_irq_connect_data;
+
+typedef struct {
+  /*
+   * size of all the table fields (*Tbl) described below.
+   */
+  unsigned int	 		idtSize;
+  /*
+   * Default handler used when disconnecting interrupts.
+   */
+  rtems_raw_irq_connect_data	defaultRawEntry;
+  /*
+   * Table containing initials/current value.
+   */
+  rtems_raw_irq_connect_data*	rawIrqHdlTbl;
+}rtems_raw_irq_global_settings;
+
+#include <rtems/score/idtr.h>
+
+/*
+ * C callable function enabling to get handler currently connected to a vector
+ *
+ */
+rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
+
+/*
+ * C callable function enabling to set up one raw idt entry
+ */
+extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
+
+/*
+ * C callable function enabling to get one current raw idt entry
+ */
+extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
+
+/*
+ * C callable function enabling to remove one current raw idt entry
+ */
+extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
+
+/*
+ * C callable function enabling to init idt.
+ *
+ * CAUTION : this function assumes that the IDTR register
+ * has been already set.
+ */
+extern int i386_init_idt (rtems_raw_irq_global_settings* config);
+
+/*
+ * C callable function enabling to get actual idt configuration
+ */
+extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
 
+
+/*
+ * See page 11.12 Figure 11-8.
+ *
+ */
+/**
+ * @brief describes one entry of Global/Local Descriptor Table
+ */
+typedef struct {
+  unsigned int limit_15_0 		: 16;
+  unsigned int base_address_15_0	: 16;
+  unsigned int base_address_23_16	: 8;
+  unsigned int type			: 4;
+  unsigned int descriptor_type		: 1;
+  unsigned int privilege		: 2;
+  unsigned int present			: 1;
+  unsigned int limit_19_16		: 4;
+  unsigned int available		: 1;
+  unsigned int fixed_value_bits		: 1;
+  unsigned int operation_size		: 1;
+  unsigned int granularity		: 1;
+  unsigned int base_address_31_24	: 8;
+} RTEMS_PACKED segment_descriptors;
+
+/*
+ * C callable function enabling to get easilly usable info from
+ * the actual value of GDT register.
+ */
+extern void i386_get_info_from_GDTR (segment_descriptors** table,
+                                     uint16_t* limit);
+/*
+ * C callable function enabling to change the value of GDT register. Must be called
+ * with interrupts masked at processor level!!!.
+ */
+extern void i386_set_GDTR (segment_descriptors*,
+                           uint16_t limit);
+
+/**
+ * @brief Allows to set a GDT entry.
+ *
+ * Puts global descriptor \p sd to the global descriptor table on index
+ * \p segment_selector_index
+ *
+ * @param[in] segment_selector_index index to GDT entry
+ * @param[in] sd structure to be coppied to given \p segment_selector in GDT
+ * @retval  0 FAILED out of GDT range or index is 0, which is not valid
+ *                   index in GDT
+ * @retval  1 SUCCESS
+ */
+extern uint32_t i386_raw_gdt_entry (uint16_t segment_selector_index,
+                               segment_descriptors* sd);
+
+/**
+ * @brief fills \p sd with provided \p base in appropriate fields of \p sd
+ *
+ * @param[in] base 32-bit address to be set as descriptor's base
+ * @param[out] sd descriptor being filled with \p base
+ */
+extern void i386_fill_segment_desc_base (uint32_t base,
+                                         segment_descriptors* sd);
+
+/**
+ * @brief fills \p sd with provided \p limit in appropriate fields of \p sd
+ *
+ * sets granularity bit if necessary
+ *
+ * @param[in] limit 32-bit value representing number of limit bytes
+ * @param[out] sd descriptor being filled with \p limit
+ */
+extern void i386_fill_segment_desc_limit (uint32_t limit,
+                                          segment_descriptors* sd);
+
+/*
+ * C callable function enabling to set up one raw interrupt handler
+ */
+extern uint32_t i386_set_gdt_entry (uint16_t segment_selector,
+                                    uint32_t base,
+                                    uint32_t limit);
+
+/**
+ * @brief Returns next empty descriptor in GDT.
+ *
+ * Number of descriptors that can be returned depends on \a GDT_SIZE
+ *
+ * @retval  0 FAILED GDT is full
+ * @retval  <1;65535> segment_selector number as index to GDT
+ */
+extern uint16_t i386_next_empty_gdt_entry (void);
+
+/**
+ * @brief Copies GDT entry at index \p segment_selector to structure
+ * pointed to by \p struct_to_fill
+ *
+ * @param[in] segment_selector index to GDT table specifying descriptor to copy
+ * @param[out] struct_to_fill pointer to memory where will be descriptor coppied
+ * @retval  0 FAILED segment_selector out of GDT range
+ * @retval  <1;65535> retrieved segment_selector
+ */
+extern uint16_t i386_cpy_gdt_entry (uint16_t segment_selector,
+                                    segment_descriptors* struct_to_fill);
+
+/**
+ * @brief Returns pointer to GDT table at index given by \p segment_selector
+ *
+ * @param[in] sgmnt_selector index to GDT table for specifying descriptor to get
+ * @retval  NULL FAILED segment_selector out of GDT range
+ * @retval  pointer to GDT table at \p segment_selector
+ */
+extern segment_descriptors* i386_get_gdt_entry (uint16_t sgmnt_selector);
+
+/**
+ * @brief Extracts base address from GDT entry pointed to by \p gdt_entry
+ *
+ * @param[in]  gdt_entry pointer to entry from which base should be retrieved
+ * @retval base address from GDT entry
+*/
+RTEMS_INLINE_ROUTINE void* i386_base_gdt_entry (segment_descriptors* gdt_entry)
+{
+    return (void*)(gdt_entry->base_address_15_0 |
+            (gdt_entry->base_address_23_16<<16) |
+            (gdt_entry->base_address_31_24<<24));
+}
+
+/**
+ * @brief Extracts limit in bytes from GDT entry pointed to by \p gdt_entry
+ *
+ * @param[in]  gdt_entry pointer to entry from which limit should be retrieved
+ * @retval limit value in bytes from GDT entry
+ */
+extern uint32_t i386_limit_gdt_entry (segment_descriptors* gdt_entry);
+
+/*
+ * See page 11.18 Figure 11-12.
+ *
+ */
+
+typedef struct {
+  unsigned int offset			: 12;
+  unsigned int page			: 10;
+  unsigned int directory 		: 10;
+}la_bits;
+
+typedef union {
+  la_bits	bits;
+  unsigned int	address;
+}linear_address;
+
+
+/*
+ * See page 11.20 Figure 11-14.
+ *
+ */
+
+typedef struct {
+  unsigned int present	 		: 1;
+  unsigned int writable			: 1;
+  unsigned int user			: 1;
+  unsigned int write_through		: 1;
+  unsigned int cache_disable		: 1;
+  unsigned int accessed			: 1;
+  unsigned int reserved1		: 1;
+  unsigned int page_size		: 1;
+  unsigned int reserved2		: 1;
+  unsigned int available		: 3;
+  unsigned int page_frame_address	: 20;
+}page_dir_bits;
+
+typedef union {
+  page_dir_bits	bits;
+  unsigned int	dir_entry;
+}page_dir_entry;
+
+typedef struct {
+  unsigned int present	 		: 1;
+  unsigned int writable			: 1;
+  unsigned int user			: 1;
+  unsigned int write_through		: 1;
+  unsigned int cache_disable		: 1;
+  unsigned int accessed			: 1;
+  unsigned int dirty			: 1;
+  unsigned int reserved2		: 2;
+  unsigned int available		: 3;
+  unsigned int page_frame_address	: 20;
+}page_table_bits;
+
+typedef union {
+  page_table_bits	bits;
+  unsigned int		table_entry;
+} page_table_entry;
+
+/*
+ * definitions related to page table entry
+ */
+#define PG_SIZE 0x1000
+#define MASK_OFFSET 0xFFF
+#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
+#define FOUR_MB       0x400000
+#define MASK_FLAGS 0x1A
+
+#define PTE_PRESENT  		0x01
+#define PTE_WRITABLE 		0x02
+#define PTE_USER		0x04
+#define PTE_WRITE_THROUGH	0x08
+#define PTE_CACHE_DISABLE	0x10
+
+typedef struct {
+  page_dir_entry pageDirEntry[MAX_ENTRY];
+} page_directory;
+
+typedef struct {
+  page_table_entry pageTableEntry[MAX_ENTRY];
+} page_table;
+
+/* Simpler names for the 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 )
@@ -251,7 +661,6 @@ int i386_Physical_to_real(
 #define inport_word( _port, _value )  i386_inport_word( _port, _value )
 #define inport_long( _port, _value )  i386_inport_long( _port, _value )
 
-
 #ifdef __cplusplus
 }
 #endif
-- 
1.9.1



More information about the devel mailing list