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

4.115
Last change on this file since 038e1dba was 038e1dba, checked in by Jan Dolezal <dolezj21@…>, on Dec 3, 2014 at 11:56:39 PM

i386: doxygen and comments related to VESA real mode framebuffer

  • Property mode set to 100644
File size: 13.0 KB
Line 
1/*
2 * @file cpu.h
3 *
4 *          This file contains definitions for data structure related
5 *          to Intel system programming. More information can be found
6 *          on Intel site and more precisely in the following book :
7 *
8 *              Pentium Processor familly
9 *              Developper's Manual
10 *
11 *              Volume 3 : Architecture and Programming Manual
12 *
13 * Copyright (C) 1998  Eric Valette (valette@crf.canon.fr)
14 *                     Canon Centre Recherche France.
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#ifndef _LIBCPU_i386_CPU_H
22#define _LIBCPU_i386_CPU_H
23
24#include <rtems/score/registers.h>
25
26#ifndef ASM
27
28/*
29 *  Interrupt Level Macros
30 */
31#include <rtems/score/interrupts.h>
32
33#include <rtems/score/basedefs.h>
34
35/*
36 *  Segment Access Routines
37 *
38 *  NOTE:  Unfortunately, these are still static inlines even when the
39 *         "macro" implementation of the generic code is used.
40 */
41
42static __inline__ unsigned short i386_get_cs(void)
43{
44  register unsigned short segment = 0;
45
46  __asm__ volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
47
48  return segment;
49}
50
51static __inline__ unsigned short i386_get_ds(void)
52{
53  register unsigned short segment = 0;
54
55  __asm__ volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
56
57  return segment;
58}
59
60static __inline__ unsigned short i386_get_es(void)
61{
62  register unsigned short segment = 0;
63
64  __asm__ volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
65
66  return segment;
67}
68
69static __inline__ unsigned short i386_get_ss(void)
70{
71  register unsigned short segment = 0;
72
73  __asm__ volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
74
75  return segment;
76}
77
78static __inline__ unsigned short i386_get_fs(void)
79{
80  register unsigned short segment = 0;
81
82  __asm__ volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
83
84  return segment;
85}
86
87static __inline__ unsigned short i386_get_gs(void)
88{
89  register unsigned short segment = 0;
90
91  __asm__ volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
92
93  return segment;
94}
95
96/*
97 *  IO Port Access Routines
98 */
99
100#define i386_outport_byte( _port, _value ) \
101do { register unsigned short __port  = _port; \
102     register unsigned char  __value = _value; \
103     \
104     __asm__ volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
105   } while (0)
106
107#define i386_outport_word( _port, _value ) \
108do { register unsigned short __port  = _port; \
109     register unsigned short __value = _value; \
110     \
111     __asm__ volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
112   } while (0)
113
114#define i386_outport_long( _port, _value ) \
115do { register unsigned short __port  = _port; \
116     register unsigned int  __value = _value; \
117     \
118     __asm__ volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
119   } while (0)
120
121#define i386_inport_byte( _port, _value ) \
122do { register unsigned short __port  = _port; \
123     register unsigned char  __value = 0; \
124     \
125     __asm__ volatile ( "inb %1,%0" : "=a" (__value) \
126                                : "d"  (__port) \
127                  ); \
128     _value = __value; \
129   } while (0)
130
131#define i386_inport_word( _port, _value ) \
132do { register unsigned short __port  = _port; \
133     register unsigned short __value = 0; \
134     \
135     __asm__ volatile ( "inw %1,%0" : "=a" (__value) \
136                                : "d"  (__port) \
137                  ); \
138     _value = __value; \
139   } while (0)
140
141#define i386_inport_long( _port, _value ) \
142do { register unsigned short __port  = _port; \
143     register unsigned int  __value = 0; \
144     \
145     __asm__ volatile ( "inl %1,%0" : "=a" (__value) \
146                                : "d"  (__port) \
147                  ); \
148     _value = __value; \
149   } while (0)
150
151/*
152 * Type definition for raw interrupts.
153 */
154
155typedef unsigned char  rtems_vector_offset;
156
157typedef struct __rtems_raw_irq_connect_data__{
158 /*
159  * IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
160  */
161  rtems_vector_offset           idtIndex;
162  /*
163   * IDT raw handler. See comment on handler properties below in function prototype.
164   */
165  rtems_raw_irq_hdl             hdl;
166  /*
167   * function for enabling raw interrupts. In order to be consistent
168   * with the fact that the raw connexion can defined in the
169   * libcpu library, this library should have no knowledge of
170   * board specific hardware to manage interrupts and thus the
171   * "on" routine must enable the irq both at device and PIC level.
172   *
173   */
174    rtems_raw_irq_enable        on;
175  /*
176   * function for disabling raw interrupts. In order to be consistent
177   * with the fact that the raw connexion can defined in the
178   * libcpu library, this library should have no knowledge of
179   * board specific hardware to manage interrupts and thus the
180   * "on" routine must disable the irq both at device and PIC level.
181   *
182   */
183  rtems_raw_irq_disable         off;
184  /*
185   * function enabling to know what interrupt may currently occur
186   */
187  rtems_raw_irq_is_enabled      isOn;
188}rtems_raw_irq_connect_data;
189
190typedef struct {
191  /*
192   * size of all the table fields (*Tbl) described below.
193   */
194  unsigned int                  idtSize;
195  /*
196   * Default handler used when disconnecting interrupts.
197   */
198  rtems_raw_irq_connect_data    defaultRawEntry;
199  /*
200   * Table containing initials/current value.
201   */
202  rtems_raw_irq_connect_data*   rawIrqHdlTbl;
203}rtems_raw_irq_global_settings;
204
205#include <rtems/score/idtr.h>
206
207/*
208 * C callable function enabling to get handler currently connected to a vector
209 *
210 */
211rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
212
213/*
214 * C callable function enabling to set up one raw idt entry
215 */
216extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
217
218/*
219 * C callable function enabling to get one current raw idt entry
220 */
221extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
222
223/*
224 * C callable function enabling to remove one current raw idt entry
225 */
226extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
227
228/*
229 * C callable function enabling to init idt.
230 *
231 * CAUTION : this function assumes that the IDTR register
232 * has been already set.
233 */
234extern int i386_init_idt (rtems_raw_irq_global_settings* config);
235
236/*
237 * C callable function enabling to get actual idt configuration
238 */
239extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
240
241
242/*
243 * See page 11.12 Figure 11-8.
244 *
245 */
246/**
247 * @brief describes one entry of Global/Local Descriptor Table
248 */
249typedef struct {
250  unsigned int limit_15_0               : 16;
251  unsigned int base_address_15_0        : 16;
252  unsigned int base_address_23_16       : 8;
253  unsigned int type                     : 4;
254  unsigned int descriptor_type          : 1;
255  unsigned int privilege                : 2;
256  unsigned int present                  : 1;
257  unsigned int limit_19_16              : 4;
258  unsigned int available                : 1;
259  unsigned int fixed_value_bits         : 1;
260  unsigned int operation_size           : 1;
261  unsigned int granularity              : 1;
262  unsigned int base_address_31_24       : 8;
263} RTEMS_COMPILER_PACKED_ATTRIBUTE segment_descriptors;
264
265/*
266 * C callable function enabling to get easilly usable info from
267 * the actual value of GDT register.
268 */
269extern void i386_get_info_from_GDTR (segment_descriptors** table,
270                                     uint16_t* limit);
271/*
272 * C callable function enabling to change the value of GDT register. Must be called
273 * with interrupts masked at processor level!!!.
274 */
275extern void i386_set_GDTR (segment_descriptors*,
276                           uint16_t limit);
277
278/**
279 * @brief Allows to set a GDT entry.
280 *
281 * Puts global descriptor \p sd to the global descriptor table on index
282 * \p segment_selector_index
283 *
284 * @param[in] segment_selector_index index to GDT entry
285 * @param[in] sd structure to be coppied to given \p segment_selector in GDT
286 * @retval  0 FAILED out of GDT range or index is 0, which is not valid
287 *                   index in GDT
288 * @retval  1 SUCCESS
289 */
290extern uint32_t i386_raw_gdt_entry (uint16_t segment_selector_index,
291                               segment_descriptors* sd);
292
293/**
294 * @brief fills \p sd with provided \p base in appropriate fields of \p sd
295 *
296 * @param[in] base 32-bit address to be set as descriptor's base
297 * @param[out] sd descriptor being filled with \p base
298 */
299extern void i386_fill_segment_desc_base (uint32_t base,
300                                         segment_descriptors* sd);
301
302/**
303 * @brief fills \p sd with provided \p limit in appropriate fields of \p sd
304 *
305 * sets granularity bit if necessary
306 *
307 * @param[in] limit 32-bit value representing number of limit bytes
308 * @param[out] sd descriptor being filled with \p limit
309 */
310extern void i386_fill_segment_desc_limit (uint32_t limit,
311                                          segment_descriptors* sd);
312
313/*
314 * C callable function enabling to set up one raw interrupt handler
315 */
316extern uint32_t i386_set_gdt_entry (uint16_t segment_selector,
317                                    uint32_t base,
318                                    uint32_t limit);
319
320/**
321 * @brief Returns next empty descriptor in GDT.
322 *
323 * Number of descriptors that can be returned depends on \a GDT_SIZE
324 *
325 * @retval  0 FAILED GDT is full
326 * @retval  <1;65535> segment_selector number as index to GDT
327 */
328extern uint16_t i386_next_empty_gdt_entry (void);
329
330/**
331 * @brief Copies GDT entry at index \p segment_selector to structure
332 * pointed to by \p struct_to_fill
333 *
334 * @param[in] segment_selector index to GDT table specifying descriptor to copy
335 * @param[out] struct_to_fill pointer to memory where will be descriptor coppied
336 * @retval  0 FAILED segment_selector out of GDT range
337 * @retval  <1;65535> retrieved segment_selector
338 */
339extern uint16_t i386_cpy_gdt_entry (uint16_t segment_selector,
340                                    segment_descriptors* struct_to_fill);
341
342/**
343 * @brief Returns pointer to GDT table at index given by \p segment_selector
344 *
345 * @param[in] sgmnt_selector index to GDT table for specifying descriptor to get
346 * @retval  NULL FAILED segment_selector out of GDT range
347 * @retval  pointer to GDT table at \p segment_selector
348 */
349extern segment_descriptors* i386_get_gdt_entry (uint16_t sgmnt_selector);
350
351/**
352 * @brief Extracts base address from GDT entry pointed to by \p gdt_entry
353 *
354 * @param[in]  gdt_entry pointer to entry from which base should be retrieved
355 * @retval base address from GDT entry
356*/
357RTEMS_INLINE_ROUTINE void* i386_base_gdt_entry (segment_descriptors* gdt_entry)
358{
359    return (void*)(gdt_entry->base_address_15_0 |
360            (gdt_entry->base_address_23_16<<16) |
361            (gdt_entry->base_address_31_24<<24));
362}
363
364/**
365 * @brief Extracts limit in bytes from GDT entry pointed to by \p gdt_entry
366 *
367 * @param[in]  gdt_entry pointer to entry from which limit should be retrieved
368 * @retval limit value in bytes from GDT entry
369 */
370extern uint32_t i386_limit_gdt_entry (segment_descriptors* gdt_entry);
371
372/*
373 * See page 11.18 Figure 11-12.
374 *
375 */
376
377typedef struct {
378  unsigned int offset                   : 12;
379  unsigned int page                     : 10;
380  unsigned int directory                : 10;
381}la_bits;
382
383typedef union {
384  la_bits       bits;
385  unsigned int  address;
386}linear_address;
387
388
389/*
390 * See page 11.20 Figure 11-14.
391 *
392 */
393
394typedef struct {
395  unsigned int present                  : 1;
396  unsigned int writable                 : 1;
397  unsigned int user                     : 1;
398  unsigned int write_through            : 1;
399  unsigned int cache_disable            : 1;
400  unsigned int accessed                 : 1;
401  unsigned int reserved1                : 1;
402  unsigned int page_size                : 1;
403  unsigned int reserved2                : 1;
404  unsigned int available                : 3;
405  unsigned int page_frame_address       : 20;
406}page_dir_bits;
407
408typedef union {
409  page_dir_bits bits;
410  unsigned int  dir_entry;
411}page_dir_entry;
412
413typedef struct {
414  unsigned int present                  : 1;
415  unsigned int writable                 : 1;
416  unsigned int user                     : 1;
417  unsigned int write_through            : 1;
418  unsigned int cache_disable            : 1;
419  unsigned int accessed                 : 1;
420  unsigned int dirty                    : 1;
421  unsigned int reserved2                : 2;
422  unsigned int available                : 3;
423  unsigned int page_frame_address       : 20;
424}page_table_bits;
425
426typedef union {
427  page_table_bits       bits;
428  unsigned int          table_entry;
429} page_table_entry;
430
431/*
432 * definitions related to page table entry
433 */
434#define PG_SIZE 0x1000
435#define MASK_OFFSET 0xFFF
436#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
437#define FOUR_MB       0x400000
438#define MASK_FLAGS 0x1A
439
440#define PTE_PRESENT             0x01
441#define PTE_WRITABLE            0x02
442#define PTE_USER                0x04
443#define PTE_WRITE_THROUGH       0x08
444#define PTE_CACHE_DISABLE       0x10
445
446typedef struct {
447  page_dir_entry pageDirEntry[MAX_ENTRY];
448} page_directory;
449
450typedef struct {
451  page_table_entry pageTableEntry[MAX_ENTRY];
452} page_table;
453
454
455/* C declaration for paging management */
456
457extern int      _CPU_is_cache_enabled(void);
458extern int      _CPU_is_paging_enabled(void);
459extern int      init_paging(void);
460extern void     _CPU_enable_paging(void);
461extern void     _CPU_disable_paging(void);
462extern void     _CPU_disable_cache(void);
463extern void     _CPU_enable_cache(void);
464extern int      _CPU_map_phys_address
465                      (void **mappedAddress, void *physAddress,
466                       int size, int flag);
467extern int      _CPU_unmap_virt_address (void *mappedAddress, int size);
468extern int      _CPU_change_memory_mapping_attribute
469                         (void **newAddress, void *mappedAddress,
470                          unsigned int size, unsigned int flag);
471extern int      _CPU_display_memory_attribute(void);
472
473# endif /* ASM */
474
475#endif
Note: See TracBrowser for help on using the repository browser.