summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/i386/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/lib/libcpu/i386/cpu.h365
1 files changed, 365 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/i386/cpu.h b/c/src/lib/libcpu/i386/cpu.h
new file mode 100644
index 0000000000..cded552740
--- /dev/null
+++ b/c/src/lib/libcpu/i386/cpu.h
@@ -0,0 +1,365 @@
+/*
+ * 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@crf.canon.fr)
+ * Canon Centre Recherche France.
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#ifndef _i386_CPU_H
+#define _i386_CPU_H
+
+#ifndef ASM
+
+/*
+ * Interrupt Level Macros
+ */
+
+#define i386_disable_interrupts( _level ) \
+ { \
+ _level = 0; /* avoids warnings */ \
+ asm volatile ( "pushf ; \
+ cli ; \
+ pop %0" \
+ : "=r" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+
+#define i386_enable_interrupts( _level ) \
+ { \
+ asm volatile ( "push %0 ; \
+ popf" \
+ : "=r" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+
+#define i386_flash_interrupts( _level ) \
+ { \
+ asm volatile ( "push %0 ; \
+ popf ; \
+ cli" \
+ : "=r" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+
+#define i386_get_interrupt_level( _level ) \
+ do { \
+ register unsigned32 _eflags = 0; \
+ \
+ asm volatile ( "pushf ; \
+ pop %0" \
+ : "=r" ((_eflags)) : "0" ((_eflags)) \
+ ); \
+ \
+ _level = (_eflags & 0x0200) ? 0 : 1; \
+ } while (0)
+
+#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
+#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
+
+/*
+ * 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()
+{
+ register unsigned short segment = 0;
+
+ asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned short i386_get_ds()
+{
+ register unsigned short segment = 0;
+
+ asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned short i386_get_es()
+{
+ register unsigned short segment = 0;
+
+ asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned short i386_get_ss()
+{
+ register unsigned short segment = 0;
+
+ asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned short i386_get_fs()
+{
+ register unsigned short segment = 0;
+
+ asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
+
+ return segment;
+}
+
+static inline unsigned short i386_get_gs()
+{
+ 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 ) \
+ { register unsigned short __port = _port; \
+ register unsigned char __value = _value; \
+ \
+ asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ }
+
+#define i386_outport_word( _port, _value ) \
+ { register unsigned short __port = _port; \
+ register unsigned short __value = _value; \
+ \
+ asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ }
+
+#define i386_outport_long( _port, _value ) \
+ { register unsigned short __port = _port; \
+ register unsigned int __value = _value; \
+ \
+ asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ }
+
+#define i386_inport_byte( _port, _value ) \
+ { register unsigned short __port = _port; \
+ register unsigned char __value = 0; \
+ \
+ asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ _value = __value; \
+ }
+
+#define i386_inport_word( _port, _value ) \
+ { register unsigned short __port = _port; \
+ register unsigned short __value = 0; \
+ \
+ asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ _value = __value; \
+ }
+
+#define i386_inport_long( _port, _value ) \
+ { register unsigned short __port = _port; \
+ register unsigned int __value = 0; \
+ \
+ asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \
+ : "0" (__value), "1" (__port) \
+ ); \
+ _value = __value; \
+ }
+
+/*
+ * Type definition for raw interrupts.
+ */
+
+typedef unsigned char rtems_vector_offset;
+
+struct __rtems_raw_irq_connect_data__;
+
+typedef void (*rtems_raw_irq_hdl) (void);
+typedef void (*rtems_raw_irq_enable) (const struct __rtems_raw_irq_connect_data__*);
+typedef void (*rtems_raw_irq_disable) (const struct __rtems_raw_irq_connect_data__*);
+typedef int (*rtems_raw_irq_is_enabled) (const struct __rtems_raw_irq_connect_data__*);
+
+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;
+
+/*
+ * See page 14.9 Figure 14-2.
+ *
+ */
+typedef struct {
+ unsigned int low_offsets_bits : 16;
+ unsigned int segment_selector : 16;
+ unsigned int fixed_value_bits : 8;
+ unsigned int gate_type : 5;
+ unsigned int privilege : 2;
+ unsigned int present : 1;
+ unsigned int high_offsets_bits: 16;
+}interrupt_gate_descriptor;
+
+
+/*
+ * C callable function enabling to create a interrupt_gate_descriptor
+ */
+void create_interrupt_gate_descriptor (interrupt_gate_descriptor*, rtems_raw_irq_hdl);
+
+/*
+ * 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 get easilly usable info from
+ * the actual value of IDT register.
+ */
+extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
+ unsigned* limit);
+/*
+ * C callable function enabling to change the value of IDT register. Must be called
+ * with interrupts masked at processor level!!!.
+ */
+extern void i386_set_IDTR (interrupt_gate_descriptor* table,
+ unsigned limit);
+
+/*
+ * 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.
+ *
+ */
+
+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;
+}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,
+ unsigned* 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*,
+ unsigned limit);
+
+/*
+ * C callable function enabling to set up one raw interrupt handler
+ */
+extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
+ unsigned limit);
+
+# endif /* ASM */
+
+#endif