summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/i386/rtems/score/i386.h
blob: ca1af66fff7f0f6f8487ed206bf799b6698710be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/*  i386.h
 *
 *  This include file contains information pertaining to the Intel
 *  i386 processor.
 *
 *  COPYRIGHT (c) 1989-1999.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 */

#ifndef __i386_h
#define __i386_h

#ifdef __cplusplus
extern "C" {
#endif

/*
 *  This section contains the information required to build
 *  RTEMS for a particular member of the Intel i386
 *  family when executing in protected mode.  It does
 *  this by setting variables to indicate which implementation
 *  dependent features are present in a particular member
 *  of the family.
 *
 *  Currently recognized:
 *    i386_fp    (i386 DX or SX w/i387)
 *    i386_nofp  (i386 DX or SX w/o i387)
 *    i486dx
 *    i486sx
 *    pentium
 *    pentiumpro
 *
 *  CPU Model Feature Flags:
 *
 *  I386_HAS_BSWAP:  Defined to "1" if the instruction for endian swapping 
 *                   (bswap) should be used.  This instruction appears to
 *                   be present in all i486's and above.
 *
 *  I386_HAS_FPU:    Defined to "1" if the CPU has an FPU.
 *
 */

#if defined(rtems_multilib)
/*
 *  Figure out all CPU Model Feature Flags based upon compiler 
 *  predefines. 
 */

#define CPU_MODEL_NAME  "rtems_multilib"
#define I386_HAS_FPU   0
#define I386_HAS_BSWAP 0

#elif defined(i386_fp)

#define CPU_MODEL_NAME  "i386 with i387"
#define I386_HAS_BSWAP 0

#elif defined(i386_nofp)

#define CPU_MODEL_NAME  "i386 w/o i387"
#define I386_HAS_FPU   0
#define I386_HAS_BSWAP 0

#elif defined(i486dx)

#define CPU_MODEL_NAME  "i486dx"

#elif defined(i486sx)

#define CPU_MODEL_NAME  "i486sx"
#define I386_HAS_FPU 0

#elif defined(pentium)

#define CPU_MODEL_NAME  "Pentium"

#elif defined(pentiumpro)

#define CPU_MODEL_NAME  "Pentium Pro"

#else

#error "Unsupported CPU Model"

#endif

/*
 *  Set default values for CPU model feature flags
 *
 *  NOTE: These settings are chosen to reflect most of the family members.
 */

#ifndef I386_HAS_FPU
#define I386_HAS_FPU 1
#endif

#ifndef I386_HAS_BSWAP
#define I386_HAS_BSWAP 1
#endif

/*
 *  Define the name of the CPU family.
 */

#define CPU_NAME "Intel i386"

#ifndef ASM

/*
 *  The following routine swaps the endian format of an unsigned int.
 *  It must be static so it can be referenced indirectly.
 */

static inline unsigned int i386_swap_U32(
  unsigned int value
)
{
  unsigned long lout;

#if (I386_HAS_BSWAP == 0)
  asm volatile( "rorw  $8,%%ax;"
                "rorl  $16,%0;"
                "rorw  $8,%%ax" : "=a" (lout) : "0" (value) );
#else
    __asm__ volatile( "bswap %0" : "=r"  (lout) : "0"   (value));
#endif
  return( lout );
}

static inline unsigned int i386_swap_U16(
  unsigned int value
)
{
    unsigned short      sout;

    __asm__ volatile( "rorw $8,%0" : "=r"  (sout) : "0"   (value));
    return (sout);
}


/*
 * Added for pagination management
 */
 
static inline unsigned int i386_get_cr0()
{
  register unsigned int segment = 0;

  asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );

  return segment;
}

static inline void i386_set_cr0(unsigned int segment)
{
  asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
}

static inline unsigned int i386_get_cr2()
{
  register unsigned int segment = 0;

  asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );

  return segment;
}

static inline unsigned int i386_get_cr3()
{
  register unsigned int segment = 0;

  asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );

  return segment;
}

static inline void i386_set_cr3(unsigned int segment)
{
  asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
}

/*
 * Disable the entire cache
 */
void _CPU_disable_cache() {
  cr0 regCr0;

  regCr0.i = i386_get_cr0();
  regCr0.cr0.page_level_cache_disable = 1;
  regCr0.cr0.no_write_through = 1;
  i386_set_cr0( regCr0.i );
  rtems_flush_entire_data_cache();
}

/*
 * Enable the entire cache
 */
static inline void _CPU_enable_cache() {
  cr0 regCr0;

  regCr0.i = i386_get_cr0();
  regCr0.cr0.page_level_cache_disable = 0;
  regCr0.cr0.no_write_through = 0;
  i386_set_cr0( regCr0.i );
  /*rtems_flush_entire_data_cache();*/
}

/*
 * CACHE MANAGER: The following functions are CPU-specific.
 * They provide the basic implementation for the rtems_* cache
 * management routines. If a given function has no meaning for the CPU,
 * it does nothing by default.
 * 
 * FIXME: Definitions for I386_CACHE_ALIGNMENT are missing above for
 *        each CPU. The routines below should be implemented per CPU,
 *        to accomodate the capabilities of each.
 */

/* FIXME: I don't belong here. */
#define I386_CACHE_ALIGNMENT 16

#if defined(I386_CACHE_ALIGNMENT)
#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT

static inline void _CPU_flush_1_data_cache_line (const void * d_addr) {}
static inline void _CPU_invalidate_1_data_cache_line (const void * d_addr) {}
static inline void _CPU_freeze_data_cache (void) {}
static inline void _CPU_unfreeze_data_cache (void) {}
static inline void _CPU_invalidate_1_inst_cache_line const void * d_addr() {}
static inline void _CPU_freeze_inst_cache (void) {}
static inline void _CPU_unfreeze_inst_cache (void) {}

static inline void _CPU_flush_entire_data_cache (
  const void * d_addr )
{
  asm ("wbinvd");
}
static inline void _CPU_invalidate_entire_data_cache (
  const void * d_addr )
{
  asm ("invd");
}

static inline void _CPU_enable_data_cache (
	void )
{
	_CPU_enable_cache();
}

static inline void _CPU_disable_data_cache (
	void )
{
	_CPU_disable_cache();
}

static inline void _CPU_invalidate_entire_inst_cache (
  const void * i_addr )
{
  asm ("invd");
}

static inline void _CPU_enable_inst_cache (
	void )
{
	_CPU_enable_cache();
}

static inline void _CPU_disable_inst_cache (
	void )
{
	_CPU_disable_cache();
}
#endif


/* routines */

/*
 *  i386_Logical_to_physical
 *
 *  Converts logical address to physical address.
 */

void *i386_Logical_to_physical(
  unsigned short  segment,
  void           *address
);

/*
 *  i386_Physical_to_logical
 *
 *  Converts physical address to logical address.
 */

void *i386_Physical_to_logical(
  unsigned short  segment,
  void           *address
);


/*
 *  "Simpler" names for a lot of the things defined in this file
 */

/* segment access routines */
 
#define get_cs()   i386_get_cs()
#define get_ds()   i386_get_ds()
#define get_es()   i386_get_es()
#define get_ss()   i386_get_ss()
#define get_fs()   i386_get_fs()
#define get_gs()   i386_get_gs()
 
#define CPU_swap_u32( _value )  i386_swap_U32( _value )
#define CPU_swap_u16( _value )  i386_swap_U16( _value )
 
/* i80x86 I/O instructions */
 
#define outport_byte( _port, _value ) i386_outport_byte( _port, _value )
#define outport_word( _port, _value ) i386_outport_word( _port, _value )
#define outport_long( _port, _value ) i386_outport_long( _port, _value )
#define inport_byte( _port, _value )  i386_inport_byte( _port, _value )
#define inport_word( _port, _value )  i386_inport_word( _port, _value )
#define inport_long( _port, _value )  i386_inport_long( _port, _value )
 

#ifdef __cplusplus
}
#endif

#endif /* !ASM */

#endif
/* end of include file */