source: rtems/c/src/lib/libcpu/i386/cpu.h @ 67a2288

4.104.114.84.95
Last change on this file since 67a2288 was 67a2288, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 23, 1998 at 10:02:34 PM

Patch from Eric VALETTE <valette@…>:

Here is a enhanced version of my previous patch. This patch enables
to potentially share the new interrupt management code for all Intel targets
(pc386, go32 and force386) bsp.

Note : this patch is complete only for pc386. It still needs to

be completed for go32 and force386. I carrefully checked
that anything needed is in for force386 (only some function
name changes for IDT manipulation and GDT segment
manipulation). But anyway I will not be able to test any
of theses targets...

  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*
2 * cpu.h  - This file contains definitions for data structure related
3 *          to Intel system programming. More information can be found
4 *          on Intel site and more precisely in the following book :
5 *
6 *              Pentium Processor familly
7 *              Developper's Manual
8 *
9 *              Volume 3 : Architecture and Programming Manual
10 *
11 * Copyright (C) 1998  Eric Valette (valette@crf.canon.fr)
12 *                     Canon Centre Recherche France.
13 *
14 *  The license and distribution terms for this file may be
15 *  found in found in the file LICENSE in this distribution or at
16 *  http://www.OARcorp.com/rtems/license.html.
17 *
18 * $Id$
19 */
20
21#ifndef _i386_CPU_H
22#define _i386_CPU_H
23
24#ifndef ASM
25
26/*
27 *  Interrupt Level Macros
28 */
29
30#define i386_disable_interrupts( _level ) \
31  { \
32    _level = 0;   /* avoids warnings */ \
33    asm volatile ( "pushf ; \
34                    cli ; \
35                    pop %0" \
36                    : "=r" ((_level)) : "0" ((_level)) \
37    ); \
38  }
39
40#define i386_enable_interrupts( _level )  \
41  { \
42    asm volatile ( "push %0 ; \
43                    popf" \
44                    : "=r" ((_level)) : "0" ((_level)) \
45    ); \
46  }
47
48#define i386_flash_interrupts( _level ) \
49  { \
50    asm volatile ( "push %0 ; \
51                    popf ; \
52                    cli" \
53                    : "=r" ((_level)) : "0" ((_level)) \
54    ); \
55  }
56
57#define i386_get_interrupt_level( _level ) \
58  do { \
59    register unsigned32 _eflags = 0; \
60    \
61    asm volatile ( "pushf ; \
62                    pop %0" \
63                    : "=r" ((_eflags)) : "0" ((_eflags)) \
64    ); \
65    \
66    _level = (_eflags & 0x0200) ? 0 : 1; \
67  } while (0)
68
69#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
70#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
71     
72/*
73 *  Segment Access Routines
74 *
75 *  NOTE:  Unfortunately, these are still static inlines even when the
76 *         "macro" implementation of the generic code is used.
77 */
78
79static inline unsigned short i386_get_cs()
80{
81  register unsigned short segment = 0;
82
83  asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
84
85  return segment;
86}
87
88static inline unsigned short i386_get_ds()
89{
90  register unsigned short segment = 0;
91
92  asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
93
94  return segment;
95}
96
97static inline unsigned short i386_get_es()
98{
99  register unsigned short segment = 0;
100
101  asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
102
103  return segment;
104}
105
106static inline unsigned short i386_get_ss()
107{
108  register unsigned short segment = 0;
109
110  asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
111
112  return segment;
113}
114
115static inline unsigned short i386_get_fs()
116{
117  register unsigned short segment = 0;
118
119  asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
120
121  return segment;
122}
123
124static inline unsigned short i386_get_gs()
125{
126  register unsigned short segment = 0;
127
128  asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
129
130  return segment;
131}
132
133/*
134 *  IO Port Access Routines
135 */
136
137#define i386_outport_byte( _port, _value ) \
138   { register unsigned short __port  = _port; \
139     register unsigned char  __value = _value; \
140     \
141     asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \
142                                 : "0"   (__value), "1"  (__port) \
143                  ); \
144   }
145
146#define i386_outport_word( _port, _value ) \
147   { register unsigned short __port  = _port; \
148     register unsigned short __value = _value; \
149     \
150     asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \
151                                 : "0"   (__value), "1"  (__port) \
152                  ); \
153   }
154
155#define i386_outport_long( _port, _value ) \
156   { register unsigned short __port  = _port; \
157     register unsigned int  __value = _value; \
158     \
159     asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \
160                                 : "0"   (__value), "1"  (__port) \
161                  ); \
162   }
163
164#define i386_inport_byte( _port, _value ) \
165   { register unsigned short __port  = _port; \
166     register unsigned char  __value = 0; \
167     \
168     asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \
169                                : "0"   (__value), "1"  (__port) \
170                  ); \
171     _value = __value; \
172   }
173
174#define i386_inport_word( _port, _value ) \
175   { register unsigned short __port  = _port; \
176     register unsigned short __value = 0; \
177     \
178     asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \
179                                : "0"   (__value), "1"  (__port) \
180                  ); \
181     _value = __value; \
182   }
183
184#define i386_inport_long( _port, _value ) \
185   { register unsigned short __port  = _port; \
186     register unsigned int  __value = 0; \
187     \
188     asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \
189                                : "0"   (__value), "1"  (__port) \
190                  ); \
191     _value = __value; \
192   }
193
194/*
195 * Type definition for raw interrupts.
196 */
197
198typedef unsigned char  rtems_vector_offset;
199
200struct  __rtems_raw_irq_connect_data__;
201
202typedef void (*rtems_raw_irq_hdl)               (void);
203typedef void (*rtems_raw_irq_enable)            (const struct __rtems_raw_irq_connect_data__*);
204typedef void (*rtems_raw_irq_disable)           (const struct __rtems_raw_irq_connect_data__*);
205typedef int  (*rtems_raw_irq_is_enabled)        (const struct __rtems_raw_irq_connect_data__*);
206
207typedef struct __rtems_raw_irq_connect_data__{
208 /*
209  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
210  */
211  rtems_vector_offset           idtIndex;
212  /*
213   * IDT raw handler. See comment on handler properties below in function prototype.
214   */
215  rtems_raw_irq_hdl             hdl;
216  /*
217   * function for enabling raw interrupts. In order to be consistent
218   * with the fact that the raw connexion can defined in the
219   * libcpu library, this library should have no knowledge of
220   * board specific hardware to manage interrupts and thus the
221   * "on" routine must enable the irq both at device and PIC level.
222   *
223   */
224    rtems_raw_irq_enable        on;     
225  /*
226   * function for disabling raw interrupts. In order to be consistent
227   * with the fact that the raw connexion can defined in the
228   * libcpu library, this library should have no knowledge of
229   * board specific hardware to manage interrupts and thus the
230   * "on" routine must disable the irq both at device and PIC level.
231   *
232   */
233  rtems_raw_irq_disable         off;
234  /*
235   * function enabling to know what interrupt may currently occur
236   */
237  rtems_raw_irq_is_enabled      isOn;
238}rtems_raw_irq_connect_data;
239
240typedef struct {
241  /*
242   * size of all the table fields (*Tbl) described below.
243   */
244  unsigned int                  idtSize;
245  /*
246   * Default handler used when disconnecting interrupts.
247   */
248  rtems_raw_irq_connect_data    defaultRawEntry;
249  /*
250   * Table containing initials/current value.
251   */
252  rtems_raw_irq_connect_data*   rawIrqHdlTbl;
253}rtems_raw_irq_global_settings;
254
255/*
256 * See page 14.9 Figure 14-2.
257 *
258 */
259typedef struct {
260  unsigned int low_offsets_bits : 16;
261  unsigned int segment_selector : 16;
262  unsigned int fixed_value_bits : 8;
263  unsigned int gate_type        : 5;
264  unsigned int privilege        : 2;
265  unsigned int present          : 1;
266  unsigned int high_offsets_bits: 16;
267}interrupt_gate_descriptor;
268
269
270/*
271 * C callable function enabling to create a interrupt_gate_descriptor
272 */
273void create_interrupt_gate_descriptor (interrupt_gate_descriptor*, rtems_raw_irq_hdl);
274
275/*
276 * C callable function enabling to get handler currently connected to a vector
277 *
278 */
279rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
280
281/*
282 * C callable function enabling to get easilly usable info from
283 * the actual value of IDT register.
284 */
285extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
286                                unsigned* limit);
287/*
288 * C callable function enabling to change the value of IDT register. Must be called
289 * with interrupts masked at processor level!!!.
290 */
291extern void i386_set_IDTR (interrupt_gate_descriptor* table,
292                      unsigned limit);
293
294/*
295 * C callable function enabling to set up one raw idt entry
296 */
297extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
298
299/*
300 * C callable function enabling to get one current raw idt entry
301 */
302extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
303
304/*
305 * C callable function enabling to remove one current raw idt entry
306 */
307extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
308
309/*
310 * C callable function enabling to init idt.
311 *
312 * CAUTION : this function assumes that the IDTR register
313 * has been already set.
314 */
315extern int i386_init_idt (rtems_raw_irq_global_settings* config);
316
317/*
318 * C callable function enabling to get actual idt configuration
319 */
320extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
321
322
323/*
324 * See page 11.12 Figure 11-8.
325 *
326 */
327
328typedef struct {
329  unsigned int limit_15_0               : 16;
330  unsigned int base_address_15_0        : 16;
331  unsigned int base_address_23_16       : 8;
332  unsigned int type                     : 4;
333  unsigned int descriptor_type          : 1;
334  unsigned int privilege                : 2;
335  unsigned int present                  : 1;
336  unsigned int limit_19_16              : 4;
337  unsigned int available                : 1;
338  unsigned int fixed_value_bits         : 1;
339  unsigned int operation_size           : 1;
340  unsigned int granularity              : 1;
341  unsigned int base_address_31_24       : 8;
342}segment_descriptors;
343
344/*
345 * C callable function enabling to get easilly usable info from
346 * the actual value of GDT register.
347 */
348extern void i386_get_info_from_GDTR (segment_descriptors** table,
349                                     unsigned* limit);
350/*
351 * C callable function enabling to change the value of GDT register. Must be called
352 * with interrupts masked at processor level!!!.
353 */
354extern void i386_set_GDTR (segment_descriptors*,
355                           unsigned limit);
356
357/*
358 * C callable function enabling to set up one raw interrupt handler
359 */
360extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
361                                             unsigned limit);
362
363# endif /* ASM */
364
365#endif
Note: See TracBrowser for help on using the repository browser.