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

4.104.114.84.95
Last change on this file since a4dc7e0 was a4dc7e0, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 8, 1999 at 9:02:20 PM

Patch from Ian Lance Taylor <ian@…> to correct previous interrupt
patch.

  • Property mode set to 100644
File size: 12.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    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)) \
47    ); \
48  }
49
50#define i386_flash_interrupts( _level ) \
51  { \
52    asm volatile ( "push %0 ; \
53                    popf ; \
54                    cli" \
55                    : : "rm" ((_level)) \
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 ) \
181   { register unsigned short __port  = _port; \
182     register unsigned char  __value = _value; \
183     \
184     asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \
185                                 : "0"   (__value), "1"  (__port) \
186                  ); \
187   }
188
189#define i386_outport_word( _port, _value ) \
190   { register unsigned short __port  = _port; \
191     register unsigned short __value = _value; \
192     \
193     asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \
194                                 : "0"   (__value), "1"  (__port) \
195                  ); \
196   }
197
198#define i386_outport_long( _port, _value ) \
199   { register unsigned short __port  = _port; \
200     register unsigned int  __value = _value; \
201     \
202     asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \
203                                 : "0"   (__value), "1"  (__port) \
204                  ); \
205   }
206
207#define i386_inport_byte( _port, _value ) \
208   { register unsigned short __port  = _port; \
209     register unsigned char  __value = 0; \
210     \
211     asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \
212                                : "0"   (__value), "1"  (__port) \
213                  ); \
214     _value = __value; \
215   }
216
217#define i386_inport_word( _port, _value ) \
218   { register unsigned short __port  = _port; \
219     register unsigned short __value = 0; \
220     \
221     asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \
222                                : "0"   (__value), "1"  (__port) \
223                  ); \
224     _value = __value; \
225   }
226
227#define i386_inport_long( _port, _value ) \
228   { register unsigned short __port  = _port; \
229     register unsigned int  __value = 0; \
230     \
231     asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \
232                                : "0"   (__value), "1"  (__port) \
233                  ); \
234     _value = __value; \
235   }
236
237/*
238 * Type definition for raw interrupts.
239 */
240
241typedef unsigned char  rtems_vector_offset;
242
243struct  __rtems_raw_irq_connect_data__;
244
245typedef void (*rtems_raw_irq_hdl)               (void);
246typedef void (*rtems_raw_irq_enable)            (const struct __rtems_raw_irq_connect_data__*);
247typedef void (*rtems_raw_irq_disable)           (const struct __rtems_raw_irq_connect_data__*);
248typedef int  (*rtems_raw_irq_is_enabled)        (const struct __rtems_raw_irq_connect_data__*);
249
250typedef struct __rtems_raw_irq_connect_data__{
251 /*
252  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
253  */
254  rtems_vector_offset           idtIndex;
255  /*
256   * IDT raw handler. See comment on handler properties below in function prototype.
257   */
258  rtems_raw_irq_hdl             hdl;
259  /*
260   * function for enabling raw interrupts. In order to be consistent
261   * with the fact that the raw connexion can defined in the
262   * libcpu library, this library should have no knowledge of
263   * board specific hardware to manage interrupts and thus the
264   * "on" routine must enable the irq both at device and PIC level.
265   *
266   */
267    rtems_raw_irq_enable        on;     
268  /*
269   * function for disabling raw interrupts. In order to be consistent
270   * with the fact that the raw connexion can defined in the
271   * libcpu library, this library should have no knowledge of
272   * board specific hardware to manage interrupts and thus the
273   * "on" routine must disable the irq both at device and PIC level.
274   *
275   */
276  rtems_raw_irq_disable         off;
277  /*
278   * function enabling to know what interrupt may currently occur
279   */
280  rtems_raw_irq_is_enabled      isOn;
281}rtems_raw_irq_connect_data;
282
283typedef struct {
284  /*
285   * size of all the table fields (*Tbl) described below.
286   */
287  unsigned int                  idtSize;
288  /*
289   * Default handler used when disconnecting interrupts.
290   */
291  rtems_raw_irq_connect_data    defaultRawEntry;
292  /*
293   * Table containing initials/current value.
294   */
295  rtems_raw_irq_connect_data*   rawIrqHdlTbl;
296}rtems_raw_irq_global_settings;
297
298/*
299 * See page 14.9 Figure 14-2.
300 *
301 */
302typedef struct {
303  unsigned int low_offsets_bits : 16;
304  unsigned int segment_selector : 16;
305  unsigned int fixed_value_bits : 8;
306  unsigned int gate_type        : 5;
307  unsigned int privilege        : 2;
308  unsigned int present          : 1;
309  unsigned int high_offsets_bits: 16;
310}interrupt_gate_descriptor;
311
312
313/*
314 * C callable function enabling to create a interrupt_gate_descriptor
315 */
316void create_interrupt_gate_descriptor (interrupt_gate_descriptor*, rtems_raw_irq_hdl);
317
318/*
319 * C callable function enabling to get handler currently connected to a vector
320 *
321 */
322rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
323
324/*
325 * C callable function enabling to get easilly usable info from
326 * the actual value of IDT register.
327 */
328extern void i386_get_info_from_IDTR (interrupt_gate_descriptor** table,
329                                unsigned* limit);
330/*
331 * C callable function enabling to change the value of IDT register. Must be called
332 * with interrupts masked at processor level!!!.
333 */
334extern void i386_set_IDTR (interrupt_gate_descriptor* table,
335                      unsigned limit);
336
337/*
338 * C callable function enabling to set up one raw idt entry
339 */
340extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
341
342/*
343 * C callable function enabling to get one current raw idt entry
344 */
345extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
346
347/*
348 * C callable function enabling to remove one current raw idt entry
349 */
350extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
351
352/*
353 * C callable function enabling to init idt.
354 *
355 * CAUTION : this function assumes that the IDTR register
356 * has been already set.
357 */
358extern int i386_init_idt (rtems_raw_irq_global_settings* config);
359
360/*
361 * C callable function enabling to get actual idt configuration
362 */
363extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
364
365
366/*
367 * See page 11.12 Figure 11-8.
368 *
369 */
370
371typedef struct {
372  unsigned int limit_15_0               : 16;
373  unsigned int base_address_15_0        : 16;
374  unsigned int base_address_23_16       : 8;
375  unsigned int type                     : 4;
376  unsigned int descriptor_type          : 1;
377  unsigned int privilege                : 2;
378  unsigned int present                  : 1;
379  unsigned int limit_19_16              : 4;
380  unsigned int available                : 1;
381  unsigned int fixed_value_bits         : 1;
382  unsigned int operation_size           : 1;
383  unsigned int granularity              : 1;
384  unsigned int base_address_31_24       : 8;
385}segment_descriptors;
386
387/*
388 * C callable function enabling to get easilly usable info from
389 * the actual value of GDT register.
390 */
391extern void i386_get_info_from_GDTR (segment_descriptors** table,
392                                     unsigned* limit);
393/*
394 * C callable function enabling to change the value of GDT register. Must be called
395 * with interrupts masked at processor level!!!.
396 */
397extern void i386_set_GDTR (segment_descriptors*,
398                           unsigned limit);
399
400/*
401 * C callable function enabling to set up one raw interrupt handler
402 */
403extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
404                                             unsigned limit);
405
406/*
407 * See page 11.18 Figure 11-12.
408 *
409 */
410
411typedef struct {
412  unsigned int offset                   : 12;
413  unsigned int page                     : 10;
414  unsigned int directory                : 10;
415}la_bits;
416
417typedef union {
418  la_bits       bits;
419  unsigned int  address;
420}linear_address;
421
422
423/*
424 * See page 11.20 Figure 11-14.
425 *
426 */
427
428typedef struct {
429  unsigned int present                  : 1;
430  unsigned int writable                 : 1;
431  unsigned int user                     : 1;
432  unsigned int write_through            : 1;
433  unsigned int cache_disable            : 1;
434  unsigned int accessed                 : 1;
435  unsigned int reserved1                : 1;
436  unsigned int page_size                : 1;
437  unsigned int reserved2                : 1;
438  unsigned int available                : 3;
439  unsigned int page_frame_address       : 20;
440}page_dir_bits;
441
442typedef union {
443  page_dir_bits bits;
444  unsigned int  dir_entry;
445}page_dir_entry;
446
447typedef struct {
448  unsigned int present                  : 1;
449  unsigned int writable                 : 1;
450  unsigned int user                     : 1;
451  unsigned int write_through            : 1;
452  unsigned int cache_disable            : 1;
453  unsigned int accessed                 : 1;
454  unsigned int dirty                    : 1;
455  unsigned int reserved2                : 2;
456  unsigned int available                : 3;
457  unsigned int page_frame_address       : 20;
458}page_table_bits;
459
460typedef union {
461  page_table_bits       bits;
462  unsigned int          table_entry;
463}page_table_entry;
464 
465/*
466 * definitions related to page table entry
467 */
468#define PG_SIZE 0x1000
469#define MASK_OFFSET 0xFFF
470#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
471#define FOUR_MB       0x400000
472#define MASK_FLAGS 0x1A
473
474#define PTE_PRESENT             0x01
475#define PTE_WRITABLE            0x02
476#define PTE_USER                0x04
477#define PTE_WRITE_THROUGH       0x08
478#define PTE_CACHE_DISABLE       0x10
479
480typedef struct {
481  page_dir_entry pageDirEntry[MAX_ENTRY];
482}page_directory;
483
484typedef struct {
485  page_table_entry pageTableEntry[MAX_ENTRY];
486}page_table;
487
488static inline void flush_cache(){
489  asm volatile ("wbinvd");
490}
491
492
493/* C declaration for paging management */
494
495extern int      _CPU_is_cache_enabled();
496extern int      _CPU_is_paging_enabled();
497extern int      init_paging();
498extern void     _CPU_enable_paging();
499extern void     _CPU_disable_paging();
500extern void     _CPU_disable_cache();
501extern void     _CPU_enable_cache();
502extern int      _CPU_map_phys_address
503                      (void **mappedAddress, void *physAddress,
504                       int size, int flag); 
505extern int      _CPU_unmap_virt_address (void *mappedAddress, int size); 
506extern int      _CPU_change_memory_mapping_attribute
507                         (void **newAddress, void *mappedAddress,
508                          unsigned int size, unsigned int flag);
509extern int      _CPU_display_memory_attribute(); 
510
511# endif /* ASM */
512
513#endif
514
Note: See TracBrowser for help on using the repository browser.