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

4.11
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on Mar 20, 2014 at 9:10:47 PM

Change all references of rtems.com to rtems.org.

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