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

4.104.114.84.95
Last change on this file since ab0df696 was ab0df696, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 5, 1998 at 3:15:46 PM

Automatic CPU type detection code from Eric Valette <valette@…>.
Enabled on the pc386.

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