OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [i386/] [cpu.h] - Blame information for rev 607

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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: cpu.h,v 1.2 2001-09-27 12:01:22 chris Exp $
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
 
81
static 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
 
90
static 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
 
99
static 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
 
108
static 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
 
117
static 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
 
126
static 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
 
139
static 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
 
148
static inline void i386_set_cr0(unsigned int segment)
149
{
150
  asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
151
}
152
 
153
static 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
 
162
static 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
 
171
static 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
do { 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 ) \
188
do { 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 ) \
195
do { 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 ) \
202
do { 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 ) \
212
do { 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 ) \
222
do { 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
 
235
typedef unsigned char  rtems_vector_offset;
236
 
237
struct  __rtems_raw_irq_connect_data__;
238
 
239
typedef void (*rtems_raw_irq_hdl)               (void);
240
typedef void (*rtems_raw_irq_enable)            (const struct __rtems_raw_irq_connect_data__*);
241
typedef void (*rtems_raw_irq_disable)           (const struct __rtems_raw_irq_connect_data__*);
242
typedef int  (*rtems_raw_irq_is_enabled)        (const struct __rtems_raw_irq_connect_data__*);
243
 
244
typedef 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
 
277
typedef 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
 */
296
typedef 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
 */
310
void 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
 */
316
rtems_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
 */
322
extern 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
 */
328
extern 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
 */
334
extern 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
 */
339
extern 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
 */
344
extern 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
 */
352
extern int i386_init_idt (rtems_raw_irq_global_settings* config);
353
 
354
/*
355
 * C callable function enabling to get actual idt configuration
356
 */
357
extern 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
 
365
typedef 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
 */
385
extern 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
 */
391
extern void i386_set_GDTR (segment_descriptors*,
392
                           unsigned limit);
393
 
394
/*
395
 * C callable function enabling to set up one raw interrupt handler
396
 */
397
extern 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
 
405
typedef struct {
406
  unsigned int offset                   : 12;
407
  unsigned int page                     : 10;
408
  unsigned int directory                : 10;
409
}la_bits;
410
 
411
typedef 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
 
422
typedef 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
 
436
typedef union {
437
  page_dir_bits bits;
438
  unsigned int  dir_entry;
439
}page_dir_entry;
440
 
441
typedef 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
 
454
typedef 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
 
474
typedef struct {
475
  page_dir_entry pageDirEntry[MAX_ENTRY];
476
} page_directory;
477
 
478
typedef struct {
479
  page_table_entry pageTableEntry[MAX_ENTRY];
480
} page_table;
481
 
482
static 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
 
491
extern int      _CPU_is_cache_enabled();
492
extern int      _CPU_is_paging_enabled();
493
extern int      init_paging();
494
extern void     _CPU_enable_paging();
495
extern void     _CPU_disable_paging();
496
extern void     _CPU_disable_cache();
497
extern void     _CPU_enable_cache();
498
extern int      _CPU_map_phys_address
499
                      (void **mappedAddress, void *physAddress,
500
                       int size, int flag);
501
extern int      _CPU_unmap_virt_address (void *mappedAddress, int size);
502
extern int      _CPU_change_memory_mapping_attribute
503
                         (void **newAddress, void *mappedAddress,
504
                          unsigned int size, unsigned int flag);
505
extern int      _CPU_display_memory_attribute();
506
 
507
# endif /* ASM */
508
 
509
#endif
510
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.