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

4.104.114.84.95
Last change on this file since 3772e2c was 3772e2c, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 23, 1999 at 2:54:42 PM

* empty log message *

  • Property mode set to 100644
File size: 12.6 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    asm volatile ( "pushf ; \
36                    cli ; \
37                    pop %0" \
38                   : "=rm" ((_level)) \
39    ); \
40  }
41
42#define i386_enable_interrupts( _level )  \
43  { \
44    asm volatile ( "push %0 ; \
45                    popf" \
46                    : : "rm" ((_level)) : "cc" \
47    ); \
48  }
49
50#define i386_flash_interrupts( _level ) \
51  { \
52    asm volatile ( "push %0 ; \
53                    popf ; \
54                    cli" \
55                    : : "rm" ((_level)) : "cc" \
56    ); \
57  }
58
59#define i386_get_interrupt_level( _level ) \
60  do { \
61    register unsigned32 _eflags; \
62    \
63    asm volatile ( "pushf ; \
64                    pop %0" \
65                    : "=rm" ((_eflags)) \
66    ); \
67    \
68    _level = (_eflags & EFLAGS_INTR_ENABLE) ? 0 : 1; \
69  } while (0)
70
71#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
72#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level )
73     
74/*
75 *  Segment Access Routines
76 *
77 *  NOTE:  Unfortunately, these are still static inlines even when the
78 *         "macro" implementation of the generic code is used.
79 */
80
81static inline unsigned short i386_get_cs()
82{
83  register unsigned short segment = 0;
84
85  asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
86
87  return segment;
88}
89
90static inline unsigned short i386_get_ds()
91{
92  register unsigned short segment = 0;
93
94  asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
95
96  return segment;
97}
98
99static inline unsigned short i386_get_es()
100{
101  register unsigned short segment = 0;
102
103  asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
104
105  return segment;
106}
107
108static inline unsigned short i386_get_ss()
109{
110  register unsigned short segment = 0;
111
112  asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
113
114  return segment;
115}
116
117static inline unsigned short i386_get_fs()
118{
119  register unsigned short segment = 0;
120
121  asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
122
123  return segment;
124}
125
126static inline unsigned short i386_get_gs()
127{
128  register unsigned short segment = 0;
129
130  asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
131
132  return segment;
133}
134
135/*
136 * Added for pagination management
137 */
138
139static inline unsigned int i386_get_cr0()
140{
141  register unsigned int segment = 0;
142
143  asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
144
145  return segment;
146}
147
148static inline void i386_set_cr0(unsigned int segment)
149{
150  asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
151}
152
153static inline unsigned int i386_get_cr2()
154{
155  register unsigned int segment = 0;
156
157  asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
158
159  return segment;
160}
161
162static inline unsigned int i386_get_cr3()
163{
164  register unsigned int segment = 0;
165
166  asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
167
168  return segment;
169}
170
171static inline void i386_set_cr3(unsigned int segment)
172{
173  asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
174}
175
176/*
177 *  IO Port Access Routines
178 */
179
180#define i386_outport_byte( _port, _value ) \
181do { register unsigned short __port  = _port; \
182     register unsigned char  __value = _value; \
183     \
184     asm volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
185   } while (0)
186
187#define i386_outport_word( _port, _value ) \
188do { register unsigned short __port  = _port; \
189     register unsigned short __value = _value; \
190     \
191     asm volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
192   } while (0)
193
194#define i386_outport_long( _port, _value ) \
195do { register unsigned short __port  = _port; \
196     register unsigned int  __value = _value; \
197     \
198     asm volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
199   } while (0)
200
201#define i386_inport_byte( _port, _value ) \
202do { register unsigned short __port  = _port; \
203     register unsigned char  __value = 0; \
204     \
205     asm volatile ( "inb %1,%0" : "=a" (__value) \
206                                : "d"  (__port) \
207                  ); \
208     _value = __value; \
209   } while (0)
210
211#define i386_inport_word( _port, _value ) \
212do { register unsigned short __port  = _port; \
213     register unsigned short __value = 0; \
214     \
215     asm volatile ( "inw %1,%0" : "=a" (__value) \
216                                : "d"  (__port) \
217                  ); \
218     _value = __value; \
219   } while (0)
220
221#define i386_inport_long( _port, _value ) \
222do { register unsigned short __port  = _port; \
223     register unsigned int  __value = 0; \
224     \
225     asm volatile ( "inl %1,%0" : "=a" (__value) \
226                                : "d"  (__port) \
227                  ); \
228     _value = __value; \
229   } while (0)
230
231/*
232 * Type definition for raw interrupts.
233 */
234
235typedef unsigned char  rtems_vector_offset;
236
237struct  __rtems_raw_irq_connect_data__;
238
239typedef void (*rtems_raw_irq_hdl)               (void);
240typedef void (*rtems_raw_irq_enable)            (const struct __rtems_raw_irq_connect_data__*);
241typedef void (*rtems_raw_irq_disable)           (const struct __rtems_raw_irq_connect_data__*);
242typedef int  (*rtems_raw_irq_is_enabled)        (const struct __rtems_raw_irq_connect_data__*);
243
244typedef struct __rtems_raw_irq_connect_data__{
245 /*
246  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
247  */
248  rtems_vector_offset           idtIndex;
249  /*
250   * IDT raw handler. See comment on handler properties below in function prototype.
251   */
252  rtems_raw_irq_hdl             hdl;
253  /*
254   * function for enabling raw interrupts. In order to be consistent
255   * with the fact that the raw connexion can defined in the
256   * libcpu library, this library should have no knowledge of
257   * board specific hardware to manage interrupts and thus the
258   * "on" routine must enable the irq both at device and PIC level.
259   *
260   */
261    rtems_raw_irq_enable        on;     
262  /*
263   * function for disabling raw interrupts. In order to be consistent
264   * with the fact that the raw connexion can defined in the
265   * libcpu library, this library should have no knowledge of
266   * board specific hardware to manage interrupts and thus the
267   * "on" routine must disable the irq both at device and PIC level.
268   *
269   */
270  rtems_raw_irq_disable         off;
271  /*
272   * function enabling to know what interrupt may currently occur
273   */
274  rtems_raw_irq_is_enabled      isOn;
275}rtems_raw_irq_connect_data;
276
277typedef struct {
278  /*
279   * size of all the table fields (*Tbl) described below.
280   */
281  unsigned int                  idtSize;
282  /*
283   * Default handler used when disconnecting interrupts.
284   */
285  rtems_raw_irq_connect_data    defaultRawEntry;
286  /*
287   * Table containing initials/current value.
288   */
289  rtems_raw_irq_connect_data*   rawIrqHdlTbl;
290}rtems_raw_irq_global_settings;
291
292/*
293 * See page 14.9 Figure 14-2.
294 *
295 */
296typedef struct {
297  unsigned int low_offsets_bits : 16;
298  unsigned int segment_selector : 16;
299  unsigned int fixed_value_bits : 8;
300  unsigned int gate_type        : 5;
301  unsigned int privilege        : 2;
302  unsigned int present          : 1;
303  unsigned int high_offsets_bits: 16;
304}interrupt_gate_descriptor;
305
306
307/*
308 * C callable function enabling to create a interrupt_gate_descriptor
309 */
310void create_interrupt_gate_descriptor (interrupt_gate_descriptor*, rtems_raw_irq_hdl);
311
312/*
313 * C callable function enabling to get handler currently connected to a vector
314 *
315 */
316rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
317
318/*
319 * C callable function enabling to get easilly usable info from
320 * the actual value of IDT register.
321 */
322extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
323                                unsigned* limit);
324/*
325 * C callable function enabling to change the value of IDT register. Must be called
326 * with interrupts masked at processor level!!!.
327 */
328extern void i386_set_IDTR (interrupt_gate_descriptor* table,
329                      unsigned limit);
330
331/*
332 * C callable function enabling to set up one raw idt entry
333 */
334extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
335
336/*
337 * C callable function enabling to get one current raw idt entry
338 */
339extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
340
341/*
342 * C callable function enabling to remove one current raw idt entry
343 */
344extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
345
346/*
347 * C callable function enabling to init idt.
348 *
349 * CAUTION : this function assumes that the IDTR register
350 * has been already set.
351 */
352extern int i386_init_idt (rtems_raw_irq_global_settings* config);
353
354/*
355 * C callable function enabling to get actual idt configuration
356 */
357extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
358
359
360/*
361 * See page 11.12 Figure 11-8.
362 *
363 */
364
365typedef struct {
366  unsigned int limit_15_0               : 16;
367  unsigned int base_address_15_0        : 16;
368  unsigned int base_address_23_16       : 8;
369  unsigned int type                     : 4;
370  unsigned int descriptor_type          : 1;
371  unsigned int privilege                : 2;
372  unsigned int present                  : 1;
373  unsigned int limit_19_16              : 4;
374  unsigned int available                : 1;
375  unsigned int fixed_value_bits         : 1;
376  unsigned int operation_size           : 1;
377  unsigned int granularity              : 1;
378  unsigned int base_address_31_24       : 8;
379}segment_descriptors;
380
381/*
382 * C callable function enabling to get easilly usable info from
383 * the actual value of GDT register.
384 */
385extern void i386_get_info_from_GDTR (segment_descriptors** table,
386                                     unsigned* limit);
387/*
388 * C callable function enabling to change the value of GDT register. Must be called
389 * with interrupts masked at processor level!!!.
390 */
391extern void i386_set_GDTR (segment_descriptors*,
392                           unsigned limit);
393
394/*
395 * C callable function enabling to set up one raw interrupt handler
396 */
397extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
398                                             unsigned limit);
399
400/*
401 * See page 11.18 Figure 11-12.
402 *
403 */
404
405typedef struct {
406  unsigned int offset                   : 12;
407  unsigned int page                     : 10;
408  unsigned int directory                : 10;
409}la_bits;
410
411typedef union {
412  la_bits       bits;
413  unsigned int  address;
414}linear_address;
415
416
417/*
418 * See page 11.20 Figure 11-14.
419 *
420 */
421
422typedef struct {
423  unsigned int present                  : 1;
424  unsigned int writable                 : 1;
425  unsigned int user                     : 1;
426  unsigned int write_through            : 1;
427  unsigned int cache_disable            : 1;
428  unsigned int accessed                 : 1;
429  unsigned int reserved1                : 1;
430  unsigned int page_size                : 1;
431  unsigned int reserved2                : 1;
432  unsigned int available                : 3;
433  unsigned int page_frame_address       : 20;
434}page_dir_bits;
435
436typedef union {
437  page_dir_bits bits;
438  unsigned int  dir_entry;
439}page_dir_entry;
440
441typedef struct {
442  unsigned int present                  : 1;
443  unsigned int writable                 : 1;
444  unsigned int user                     : 1;
445  unsigned int write_through            : 1;
446  unsigned int cache_disable            : 1;
447  unsigned int accessed                 : 1;
448  unsigned int dirty                    : 1;
449  unsigned int reserved2                : 2;
450  unsigned int available                : 3;
451  unsigned int page_frame_address       : 20;
452}page_table_bits;
453
454typedef union {
455  page_table_bits       bits;
456  unsigned int          table_entry;
457} page_table_entry;
458 
459/*
460 * definitions related to page table entry
461 */
462#define PG_SIZE 0x1000
463#define MASK_OFFSET 0xFFF
464#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
465#define FOUR_MB       0x400000
466#define MASK_FLAGS 0x1A
467
468#define PTE_PRESENT             0x01
469#define PTE_WRITABLE            0x02
470#define PTE_USER                0x04
471#define PTE_WRITE_THROUGH       0x08
472#define PTE_CACHE_DISABLE       0x10
473
474typedef struct {
475  page_dir_entry pageDirEntry[MAX_ENTRY];
476} page_directory;
477
478typedef struct {
479  page_table_entry pageTableEntry[MAX_ENTRY];
480} page_table;
481
482static inline void flush_cache()
483{
484  /* Would this be better as a macro? */
485  asm ("wbinvd");  /* gcc did not like a volatile being on this */
486}
487
488
489/* C declaration for paging management */
490
491extern int      _CPU_is_cache_enabled();
492extern int      _CPU_is_paging_enabled();
493extern int      init_paging();
494extern void     _CPU_enable_paging();
495extern void     _CPU_disable_paging();
496extern void     _CPU_disable_cache();
497extern void     _CPU_enable_cache();
498extern int      _CPU_map_phys_address
499                      (void **mappedAddress, void *physAddress,
500                       int size, int flag); 
501extern int      _CPU_unmap_virt_address (void *mappedAddress, int size); 
502extern int      _CPU_change_memory_mapping_attribute
503                         (void **newAddress, void *mappedAddress,
504                          unsigned int size, unsigned int flag);
505extern int      _CPU_display_memory_attribute(); 
506
507# endif /* ASM */
508
509#endif
510
Note: See TracBrowser for help on using the repository browser.