forked from Imagelibrary/rtems
committed by
Gedare Bloom
parent
dda25b19df
commit
328bd350aa
@@ -57,7 +57,7 @@
|
|||||||
#include <rtems/iosupp.h>
|
#include <rtems/iosupp.h>
|
||||||
#include <rtems/console.h>
|
#include <rtems/console.h>
|
||||||
#include <rtems/clockdrv.h>
|
#include <rtems/clockdrv.h>
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
|
||||||
static rtems_raw_irq_connect_data* raw_irq_table;
|
static rtems_raw_irq_connect_data* raw_irq_table;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef _REALMODE_INT_H
|
#ifndef _REALMODE_INT_H
|
||||||
#define _REALMODE_INT_H
|
#define _REALMODE_INT_H
|
||||||
|
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef ASM /* ASM */
|
#ifndef ASM /* ASM */
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
extern void _pc386_delay(void);
|
extern void _pc386_delay(void);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ include $(top_srcdir)/../../../automake/compile.am
|
|||||||
|
|
||||||
include_libcpudir = $(includedir)/libcpu
|
include_libcpudir = $(includedir)/libcpu
|
||||||
|
|
||||||
include_libcpu_HEADERS = cpu.h cpuModel.h
|
include_libcpu_HEADERS = page.h cpuModel.h
|
||||||
include_libcpu_HEADERS += ../shared/include/cache.h
|
include_libcpu_HEADERS += ../shared/include/cache.h
|
||||||
include_libcpu_HEADERS += byteorder.h
|
include_libcpu_HEADERS += byteorder.h
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ score_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
|||||||
score_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
score_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
noinst_PROGRAMS += page.rel
|
noinst_PROGRAMS += page.rel
|
||||||
page_rel_SOURCES = page.c cpu.h
|
page_rel_SOURCES = page.c page.h
|
||||||
page_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
page_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
page_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
page_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <rtems/score/registers.h>
|
|
||||||
#include "cache_.h"
|
#include "cache_.h"
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
|
#include <libcpu/page.h>
|
||||||
|
|
||||||
void _CPU_disable_cache(void)
|
void _CPU_disable_cache(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,475 +0,0 @@
|
|||||||
/*
|
|
||||||
* @file cpu.h
|
|
||||||
*
|
|
||||||
* This file contains definitions for data structure related
|
|
||||||
* to Intel system programming. More information can be found
|
|
||||||
* on Intel site and more precisely in the following book :
|
|
||||||
*
|
|
||||||
* Pentium Processor familly
|
|
||||||
* Developper's Manual
|
|
||||||
*
|
|
||||||
* Volume 3 : Architecture and Programming Manual
|
|
||||||
*
|
|
||||||
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
|
|
||||||
* Canon Centre Recherche France.
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rtems.org/license/LICENSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBCPU_i386_CPU_H
|
|
||||||
#define _LIBCPU_i386_CPU_H
|
|
||||||
|
|
||||||
#include <rtems/score/registers.h>
|
|
||||||
|
|
||||||
#ifndef ASM
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt Level Macros
|
|
||||||
*/
|
|
||||||
#include <rtems/score/interrupts.h>
|
|
||||||
|
|
||||||
#include <rtems/score/basedefs.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Segment Access Routines
|
|
||||||
*
|
|
||||||
* NOTE: Unfortunately, these are still static inlines even when the
|
|
||||||
* "macro" implementation of the generic code is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_cs(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_ds(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_es(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_ss(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_fs(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ unsigned short i386_get_gs(void)
|
|
||||||
{
|
|
||||||
register unsigned short segment = 0;
|
|
||||||
|
|
||||||
__asm__ volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
|
|
||||||
|
|
||||||
return segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IO Port Access Routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define i386_outport_byte( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned char __value = _value; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define i386_outport_word( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned short __value = _value; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define i386_outport_long( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned int __value = _value; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define i386_inport_byte( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned char __value = 0; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "inb %1,%0" : "=a" (__value) \
|
|
||||||
: "d" (__port) \
|
|
||||||
); \
|
|
||||||
_value = __value; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define i386_inport_word( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned short __value = 0; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "inw %1,%0" : "=a" (__value) \
|
|
||||||
: "d" (__port) \
|
|
||||||
); \
|
|
||||||
_value = __value; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define i386_inport_long( _port, _value ) \
|
|
||||||
do { register unsigned short __port = _port; \
|
|
||||||
register unsigned int __value = 0; \
|
|
||||||
\
|
|
||||||
__asm__ volatile ( "inl %1,%0" : "=a" (__value) \
|
|
||||||
: "d" (__port) \
|
|
||||||
); \
|
|
||||||
_value = __value; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type definition for raw interrupts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned char rtems_vector_offset;
|
|
||||||
|
|
||||||
typedef struct __rtems_raw_irq_connect_data__{
|
|
||||||
/*
|
|
||||||
* IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
|
|
||||||
*/
|
|
||||||
rtems_vector_offset idtIndex;
|
|
||||||
/*
|
|
||||||
* IDT raw handler. See comment on handler properties below in function prototype.
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_hdl hdl;
|
|
||||||
/*
|
|
||||||
* function for enabling raw interrupts. In order to be consistent
|
|
||||||
* with the fact that the raw connexion can defined in the
|
|
||||||
* libcpu library, this library should have no knowledge of
|
|
||||||
* board specific hardware to manage interrupts and thus the
|
|
||||||
* "on" routine must enable the irq both at device and PIC level.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_enable on;
|
|
||||||
/*
|
|
||||||
* function for disabling raw interrupts. In order to be consistent
|
|
||||||
* with the fact that the raw connexion can defined in the
|
|
||||||
* libcpu library, this library should have no knowledge of
|
|
||||||
* board specific hardware to manage interrupts and thus the
|
|
||||||
* "on" routine must disable the irq both at device and PIC level.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_disable off;
|
|
||||||
/*
|
|
||||||
* function enabling to know what interrupt may currently occur
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_is_enabled isOn;
|
|
||||||
}rtems_raw_irq_connect_data;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/*
|
|
||||||
* size of all the table fields (*Tbl) described below.
|
|
||||||
*/
|
|
||||||
unsigned int idtSize;
|
|
||||||
/*
|
|
||||||
* Default handler used when disconnecting interrupts.
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_connect_data defaultRawEntry;
|
|
||||||
/*
|
|
||||||
* Table containing initials/current value.
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_connect_data* rawIrqHdlTbl;
|
|
||||||
}rtems_raw_irq_global_settings;
|
|
||||||
|
|
||||||
#include <rtems/score/idtr.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to get handler currently connected to a vector
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to set up one raw idt entry
|
|
||||||
*/
|
|
||||||
extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to get one current raw idt entry
|
|
||||||
*/
|
|
||||||
extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to remove one current raw idt entry
|
|
||||||
*/
|
|
||||||
extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to init idt.
|
|
||||||
*
|
|
||||||
* CAUTION : this function assumes that the IDTR register
|
|
||||||
* has been already set.
|
|
||||||
*/
|
|
||||||
extern int i386_init_idt (rtems_raw_irq_global_settings* config);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to get actual idt configuration
|
|
||||||
*/
|
|
||||||
extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See page 11.12 Figure 11-8.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief describes one entry of Global/Local Descriptor Table
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
unsigned int limit_15_0 : 16;
|
|
||||||
unsigned int base_address_15_0 : 16;
|
|
||||||
unsigned int base_address_23_16 : 8;
|
|
||||||
unsigned int type : 4;
|
|
||||||
unsigned int descriptor_type : 1;
|
|
||||||
unsigned int privilege : 2;
|
|
||||||
unsigned int present : 1;
|
|
||||||
unsigned int limit_19_16 : 4;
|
|
||||||
unsigned int available : 1;
|
|
||||||
unsigned int fixed_value_bits : 1;
|
|
||||||
unsigned int operation_size : 1;
|
|
||||||
unsigned int granularity : 1;
|
|
||||||
unsigned int base_address_31_24 : 8;
|
|
||||||
} RTEMS_PACKED segment_descriptors;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to get easilly usable info from
|
|
||||||
* the actual value of GDT register.
|
|
||||||
*/
|
|
||||||
extern void i386_get_info_from_GDTR (segment_descriptors** table,
|
|
||||||
uint16_t* limit);
|
|
||||||
/*
|
|
||||||
* C callable function enabling to change the value of GDT register. Must be called
|
|
||||||
* with interrupts masked at processor level!!!.
|
|
||||||
*/
|
|
||||||
extern void i386_set_GDTR (segment_descriptors*,
|
|
||||||
uint16_t limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Allows to set a GDT entry.
|
|
||||||
*
|
|
||||||
* Puts global descriptor \p sd to the global descriptor table on index
|
|
||||||
* \p segment_selector_index
|
|
||||||
*
|
|
||||||
* @param[in] segment_selector_index index to GDT entry
|
|
||||||
* @param[in] sd structure to be coppied to given \p segment_selector in GDT
|
|
||||||
* @retval 0 FAILED out of GDT range or index is 0, which is not valid
|
|
||||||
* index in GDT
|
|
||||||
* @retval 1 SUCCESS
|
|
||||||
*/
|
|
||||||
extern uint32_t i386_raw_gdt_entry (uint16_t segment_selector_index,
|
|
||||||
segment_descriptors* sd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief fills \p sd with provided \p base in appropriate fields of \p sd
|
|
||||||
*
|
|
||||||
* @param[in] base 32-bit address to be set as descriptor's base
|
|
||||||
* @param[out] sd descriptor being filled with \p base
|
|
||||||
*/
|
|
||||||
extern void i386_fill_segment_desc_base (uint32_t base,
|
|
||||||
segment_descriptors* sd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief fills \p sd with provided \p limit in appropriate fields of \p sd
|
|
||||||
*
|
|
||||||
* sets granularity bit if necessary
|
|
||||||
*
|
|
||||||
* @param[in] limit 32-bit value representing number of limit bytes
|
|
||||||
* @param[out] sd descriptor being filled with \p limit
|
|
||||||
*/
|
|
||||||
extern void i386_fill_segment_desc_limit (uint32_t limit,
|
|
||||||
segment_descriptors* sd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C callable function enabling to set up one raw interrupt handler
|
|
||||||
*/
|
|
||||||
extern uint32_t i386_set_gdt_entry (uint16_t segment_selector,
|
|
||||||
uint32_t base,
|
|
||||||
uint32_t limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns next empty descriptor in GDT.
|
|
||||||
*
|
|
||||||
* Number of descriptors that can be returned depends on \a GDT_SIZE
|
|
||||||
*
|
|
||||||
* @retval 0 FAILED GDT is full
|
|
||||||
* @retval <1;65535> segment_selector number as index to GDT
|
|
||||||
*/
|
|
||||||
extern uint16_t i386_next_empty_gdt_entry (void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Copies GDT entry at index \p segment_selector to structure
|
|
||||||
* pointed to by \p struct_to_fill
|
|
||||||
*
|
|
||||||
* @param[in] segment_selector index to GDT table specifying descriptor to copy
|
|
||||||
* @param[out] struct_to_fill pointer to memory where will be descriptor coppied
|
|
||||||
* @retval 0 FAILED segment_selector out of GDT range
|
|
||||||
* @retval <1;65535> retrieved segment_selector
|
|
||||||
*/
|
|
||||||
extern uint16_t i386_cpy_gdt_entry (uint16_t segment_selector,
|
|
||||||
segment_descriptors* struct_to_fill);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns pointer to GDT table at index given by \p segment_selector
|
|
||||||
*
|
|
||||||
* @param[in] sgmnt_selector index to GDT table for specifying descriptor to get
|
|
||||||
* @retval NULL FAILED segment_selector out of GDT range
|
|
||||||
* @retval pointer to GDT table at \p segment_selector
|
|
||||||
*/
|
|
||||||
extern segment_descriptors* i386_get_gdt_entry (uint16_t sgmnt_selector);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Extracts base address from GDT entry pointed to by \p gdt_entry
|
|
||||||
*
|
|
||||||
* @param[in] gdt_entry pointer to entry from which base should be retrieved
|
|
||||||
* @retval base address from GDT entry
|
|
||||||
*/
|
|
||||||
RTEMS_INLINE_ROUTINE void* i386_base_gdt_entry (segment_descriptors* gdt_entry)
|
|
||||||
{
|
|
||||||
return (void*)(gdt_entry->base_address_15_0 |
|
|
||||||
(gdt_entry->base_address_23_16<<16) |
|
|
||||||
(gdt_entry->base_address_31_24<<24));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Extracts limit in bytes from GDT entry pointed to by \p gdt_entry
|
|
||||||
*
|
|
||||||
* @param[in] gdt_entry pointer to entry from which limit should be retrieved
|
|
||||||
* @retval limit value in bytes from GDT entry
|
|
||||||
*/
|
|
||||||
extern uint32_t i386_limit_gdt_entry (segment_descriptors* gdt_entry);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See page 11.18 Figure 11-12.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int offset : 12;
|
|
||||||
unsigned int page : 10;
|
|
||||||
unsigned int directory : 10;
|
|
||||||
}la_bits;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
la_bits bits;
|
|
||||||
unsigned int address;
|
|
||||||
}linear_address;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See page 11.20 Figure 11-14.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int present : 1;
|
|
||||||
unsigned int writable : 1;
|
|
||||||
unsigned int user : 1;
|
|
||||||
unsigned int write_through : 1;
|
|
||||||
unsigned int cache_disable : 1;
|
|
||||||
unsigned int accessed : 1;
|
|
||||||
unsigned int reserved1 : 1;
|
|
||||||
unsigned int page_size : 1;
|
|
||||||
unsigned int reserved2 : 1;
|
|
||||||
unsigned int available : 3;
|
|
||||||
unsigned int page_frame_address : 20;
|
|
||||||
}page_dir_bits;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
page_dir_bits bits;
|
|
||||||
unsigned int dir_entry;
|
|
||||||
}page_dir_entry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int present : 1;
|
|
||||||
unsigned int writable : 1;
|
|
||||||
unsigned int user : 1;
|
|
||||||
unsigned int write_through : 1;
|
|
||||||
unsigned int cache_disable : 1;
|
|
||||||
unsigned int accessed : 1;
|
|
||||||
unsigned int dirty : 1;
|
|
||||||
unsigned int reserved2 : 2;
|
|
||||||
unsigned int available : 3;
|
|
||||||
unsigned int page_frame_address : 20;
|
|
||||||
}page_table_bits;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
page_table_bits bits;
|
|
||||||
unsigned int table_entry;
|
|
||||||
} page_table_entry;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* definitions related to page table entry
|
|
||||||
*/
|
|
||||||
#define PG_SIZE 0x1000
|
|
||||||
#define MASK_OFFSET 0xFFF
|
|
||||||
#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
|
|
||||||
#define FOUR_MB 0x400000
|
|
||||||
#define MASK_FLAGS 0x1A
|
|
||||||
|
|
||||||
#define PTE_PRESENT 0x01
|
|
||||||
#define PTE_WRITABLE 0x02
|
|
||||||
#define PTE_USER 0x04
|
|
||||||
#define PTE_WRITE_THROUGH 0x08
|
|
||||||
#define PTE_CACHE_DISABLE 0x10
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
page_dir_entry pageDirEntry[MAX_ENTRY];
|
|
||||||
} page_directory;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
page_table_entry pageTableEntry[MAX_ENTRY];
|
|
||||||
} page_table;
|
|
||||||
|
|
||||||
|
|
||||||
/* C declaration for paging management */
|
|
||||||
|
|
||||||
extern int _CPU_is_cache_enabled(void);
|
|
||||||
extern int _CPU_is_paging_enabled(void);
|
|
||||||
extern int init_paging(void);
|
|
||||||
extern void _CPU_enable_paging(void);
|
|
||||||
extern void _CPU_disable_paging(void);
|
|
||||||
extern void _CPU_disable_cache(void);
|
|
||||||
extern void _CPU_enable_cache(void);
|
|
||||||
extern int _CPU_map_phys_address
|
|
||||||
(void **mappedAddress, void *physAddress,
|
|
||||||
int size, int flag);
|
|
||||||
extern int _CPU_unmap_virt_address (void *mappedAddress, int size);
|
|
||||||
extern int _CPU_change_memory_mapping_attribute
|
|
||||||
(void **newAddress, void *mappedAddress,
|
|
||||||
unsigned int size, unsigned int flag);
|
|
||||||
extern int _CPU_display_memory_attribute(void);
|
|
||||||
|
|
||||||
# endif /* ASM */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
* Tell us the machine setup..
|
* Tell us the machine setup..
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libcpu/cpuModel.h>
|
#include <libcpu/cpuModel.h>
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <libcpu/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
|
#include <libcpu/page.h>
|
||||||
|
|
||||||
#define MEMORY_SIZE 0x4000000 /* 64Mo */
|
#define MEMORY_SIZE 0x4000000 /* 64Mo */
|
||||||
|
|
||||||
|
|||||||
39
c/src/lib/libcpu/i386/page.h
Normal file
39
c/src/lib/libcpu/i386/page.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* @file page.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
|
||||||
|
* Canon Centre Recherche France.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.org/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBCPU_i386_PAGE_H
|
||||||
|
#define _LIBCPU_i386_PAGE_H
|
||||||
|
|
||||||
|
#ifndef ASM
|
||||||
|
|
||||||
|
#include <rtems/score/cpu.h>
|
||||||
|
|
||||||
|
/* C declaration for paging management */
|
||||||
|
|
||||||
|
extern int _CPU_is_cache_enabled(void);
|
||||||
|
extern int _CPU_is_paging_enabled(void);
|
||||||
|
extern int init_paging(void);
|
||||||
|
extern void _CPU_enable_paging(void);
|
||||||
|
extern void _CPU_disable_paging(void);
|
||||||
|
extern void _CPU_disable_cache(void);
|
||||||
|
extern void _CPU_enable_cache(void);
|
||||||
|
extern int _CPU_map_phys_address
|
||||||
|
(void **mappedAddress, void *physAddress,
|
||||||
|
int size, int flag);
|
||||||
|
extern int _CPU_unmap_virt_address (void *mappedAddress, int size);
|
||||||
|
extern int _CPU_change_memory_mapping_attribute
|
||||||
|
(void **newAddress, void *mappedAddress,
|
||||||
|
unsigned int size, unsigned int flag);
|
||||||
|
extern int _CPU_display_memory_attribute(void);
|
||||||
|
|
||||||
|
# endif /* ASM */
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,9 +18,9 @@ $(PROJECT_INCLUDE)/libcpu/$(dirstamp):
|
|||||||
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
||||||
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/libcpu/cpu.h: cpu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
$(PROJECT_INCLUDE)/libcpu/page.h: page.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cpu.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/page.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cpu.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/page.h
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/libcpu/cpuModel.h: cpuModel.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
$(PROJECT_INCLUDE)/libcpu/cpuModel.h: cpuModel.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cpuModel.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cpuModel.h
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ extern "C" {
|
|||||||
#include <rtems/score/types.h>
|
#include <rtems/score/types.h>
|
||||||
#include <rtems/score/i386.h>
|
#include <rtems/score/i386.h>
|
||||||
|
|
||||||
#ifndef ASM
|
|
||||||
#include <rtems/score/interrupts.h> /* formerly in libcpu/cpu.h> */
|
|
||||||
#include <rtems/score/registers.h> /* formerly part of libcpu */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* conditional compilation parameters */
|
/* conditional compilation parameters */
|
||||||
|
|
||||||
#define CPU_INLINE_ENABLE_DISPATCH TRUE
|
#define CPU_INLINE_ENABLE_DISPATCH TRUE
|
||||||
|
|||||||
@@ -8,9 +8,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT (c) 1989-2013.
|
* COPYRIGHT (c) 1989-2016.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
*
|
*
|
||||||
|
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
|
||||||
|
* Canon Centre Recherche France.
|
||||||
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
@@ -23,6 +26,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <rtems/score/interrupts.h>
|
||||||
|
#include <rtems/score/registers.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This section contains the information required to build
|
* This section contains the information required to build
|
||||||
* RTEMS for a particular member of the Intel i386
|
* RTEMS for a particular member of the Intel i386
|
||||||
@@ -112,6 +118,7 @@ static inline uint32_t i386_swap_u32(
|
|||||||
#endif
|
#endif
|
||||||
return( lout );
|
return( lout );
|
||||||
}
|
}
|
||||||
|
#define CPU_swap_u32( _value ) i386_swap_u32( _value )
|
||||||
|
|
||||||
static inline uint16_t i386_swap_u16(
|
static inline uint16_t i386_swap_u16(
|
||||||
uint16_t value
|
uint16_t value
|
||||||
@@ -122,6 +129,7 @@ static inline uint16_t i386_swap_u16(
|
|||||||
__asm__ volatile( "rorw $8,%0" : "=r" (sout) : "0" (value));
|
__asm__ volatile( "rorw $8,%0" : "=r" (sout) : "0" (value));
|
||||||
return (sout);
|
return (sout);
|
||||||
}
|
}
|
||||||
|
#define CPU_swap_u16( _value ) i386_swap_u16( _value )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Added for pagination management
|
* Added for pagination management
|
||||||
@@ -202,7 +210,7 @@ RTEMS_INLINE_ROUTINE void *i386_Real_to_physical(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retreives real mode pointer elements {segmnet, offset} from
|
* @brief Retrieves real mode pointer elements {segmnet, offset} from
|
||||||
* physical address.
|
* physical address.
|
||||||
*
|
*
|
||||||
* i386_Physical_to_real
|
* i386_Physical_to_real
|
||||||
@@ -227,23 +235,425 @@ int i386_Physical_to_real(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Simpler" names for a lot of the things defined in this file
|
* Segment Access Routines
|
||||||
|
*
|
||||||
|
* NOTE: Unfortunately, these are still static inlines even when the
|
||||||
|
* "macro" implementation of the generic code is used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* segment access routines */
|
static __inline__ unsigned short i386_get_cs(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
#define get_cs() i386_get_cs()
|
__asm__ volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) );
|
||||||
#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 )
|
return segment;
|
||||||
#define CPU_swap_u16( _value ) i386_swap_u16( _value )
|
}
|
||||||
|
|
||||||
/* i80x86 I/O instructions */
|
static __inline__ unsigned short i386_get_ds(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
|
__asm__ volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ unsigned short i386_get_es(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
|
__asm__ volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ unsigned short i386_get_ss(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
|
__asm__ volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ unsigned short i386_get_fs(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
|
__asm__ volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ unsigned short i386_get_gs(void)
|
||||||
|
{
|
||||||
|
register unsigned short segment = 0;
|
||||||
|
|
||||||
|
__asm__ volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) );
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IO Port Access Routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define i386_outport_byte( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned char __value = _value; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "outb %0,%1" : : "a" (__value), "d" (__port) ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define i386_outport_word( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned short __value = _value; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "outw %0,%1" : : "a" (__value), "d" (__port) ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define i386_outport_long( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned int __value = _value; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "outl %0,%1" : : "a" (__value), "d" (__port) ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define i386_inport_byte( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned char __value = 0; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "inb %1,%0" : "=a" (__value) \
|
||||||
|
: "d" (__port) \
|
||||||
|
); \
|
||||||
|
_value = __value; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define i386_inport_word( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned short __value = 0; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "inw %1,%0" : "=a" (__value) \
|
||||||
|
: "d" (__port) \
|
||||||
|
); \
|
||||||
|
_value = __value; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define i386_inport_long( _port, _value ) \
|
||||||
|
do { register unsigned short __port = _port; \
|
||||||
|
register unsigned int __value = 0; \
|
||||||
|
\
|
||||||
|
__asm__ volatile ( "inl %1,%0" : "=a" (__value) \
|
||||||
|
: "d" (__port) \
|
||||||
|
); \
|
||||||
|
_value = __value; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type definition for raw interrupts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef unsigned char rtems_vector_offset;
|
||||||
|
|
||||||
|
typedef struct __rtems_raw_irq_connect_data__{
|
||||||
|
/*
|
||||||
|
* IDT vector offset (IRQ line + PC386_IRQ_VECTOR_BASE)
|
||||||
|
*/
|
||||||
|
rtems_vector_offset idtIndex;
|
||||||
|
/*
|
||||||
|
* IDT raw handler. See comment on handler properties below in function prototype.
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_hdl hdl;
|
||||||
|
/*
|
||||||
|
* function for enabling raw interrupts. In order to be consistent
|
||||||
|
* with the fact that the raw connexion can defined in the
|
||||||
|
* libcpu library, this library should have no knowledge of
|
||||||
|
* board specific hardware to manage interrupts and thus the
|
||||||
|
* "on" routine must enable the irq both at device and PIC level.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_enable on;
|
||||||
|
/*
|
||||||
|
* function for disabling raw interrupts. In order to be consistent
|
||||||
|
* with the fact that the raw connexion can defined in the
|
||||||
|
* libcpu library, this library should have no knowledge of
|
||||||
|
* board specific hardware to manage interrupts and thus the
|
||||||
|
* "on" routine must disable the irq both at device and PIC level.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_disable off;
|
||||||
|
/*
|
||||||
|
* function enabling to know what interrupt may currently occur
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_is_enabled isOn;
|
||||||
|
}rtems_raw_irq_connect_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* size of all the table fields (*Tbl) described below.
|
||||||
|
*/
|
||||||
|
unsigned int idtSize;
|
||||||
|
/*
|
||||||
|
* Default handler used when disconnecting interrupts.
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_connect_data defaultRawEntry;
|
||||||
|
/*
|
||||||
|
* Table containing initials/current value.
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_connect_data* rawIrqHdlTbl;
|
||||||
|
}rtems_raw_irq_global_settings;
|
||||||
|
|
||||||
|
#include <rtems/score/idtr.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to get handler currently connected to a vector
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_raw_irq_hdl get_hdl_from_vector(rtems_vector_offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to set up one raw idt entry
|
||||||
|
*/
|
||||||
|
extern int i386_set_idt_entry (const rtems_raw_irq_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to get one current raw idt entry
|
||||||
|
*/
|
||||||
|
extern int i386_get_current_idt_entry (rtems_raw_irq_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to remove one current raw idt entry
|
||||||
|
*/
|
||||||
|
extern int i386_delete_idt_entry (const rtems_raw_irq_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to init idt.
|
||||||
|
*
|
||||||
|
* CAUTION : this function assumes that the IDTR register
|
||||||
|
* has been already set.
|
||||||
|
*/
|
||||||
|
extern int i386_init_idt (rtems_raw_irq_global_settings* config);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to get actual idt configuration
|
||||||
|
*/
|
||||||
|
extern int i386_get_idt_config (rtems_raw_irq_global_settings** config);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See page 11.12 Figure 11-8.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief describes one entry of Global/Local Descriptor Table
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int limit_15_0 : 16;
|
||||||
|
unsigned int base_address_15_0 : 16;
|
||||||
|
unsigned int base_address_23_16 : 8;
|
||||||
|
unsigned int type : 4;
|
||||||
|
unsigned int descriptor_type : 1;
|
||||||
|
unsigned int privilege : 2;
|
||||||
|
unsigned int present : 1;
|
||||||
|
unsigned int limit_19_16 : 4;
|
||||||
|
unsigned int available : 1;
|
||||||
|
unsigned int fixed_value_bits : 1;
|
||||||
|
unsigned int operation_size : 1;
|
||||||
|
unsigned int granularity : 1;
|
||||||
|
unsigned int base_address_31_24 : 8;
|
||||||
|
} RTEMS_PACKED segment_descriptors;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to get easilly usable info from
|
||||||
|
* the actual value of GDT register.
|
||||||
|
*/
|
||||||
|
extern void i386_get_info_from_GDTR (segment_descriptors** table,
|
||||||
|
uint16_t* limit);
|
||||||
|
/*
|
||||||
|
* C callable function enabling to change the value of GDT register. Must be called
|
||||||
|
* with interrupts masked at processor level!!!.
|
||||||
|
*/
|
||||||
|
extern void i386_set_GDTR (segment_descriptors*,
|
||||||
|
uint16_t limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allows to set a GDT entry.
|
||||||
|
*
|
||||||
|
* Puts global descriptor \p sd to the global descriptor table on index
|
||||||
|
* \p segment_selector_index
|
||||||
|
*
|
||||||
|
* @param[in] segment_selector_index index to GDT entry
|
||||||
|
* @param[in] sd structure to be coppied to given \p segment_selector in GDT
|
||||||
|
* @retval 0 FAILED out of GDT range or index is 0, which is not valid
|
||||||
|
* index in GDT
|
||||||
|
* @retval 1 SUCCESS
|
||||||
|
*/
|
||||||
|
extern uint32_t i386_raw_gdt_entry (uint16_t segment_selector_index,
|
||||||
|
segment_descriptors* sd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fills \p sd with provided \p base in appropriate fields of \p sd
|
||||||
|
*
|
||||||
|
* @param[in] base 32-bit address to be set as descriptor's base
|
||||||
|
* @param[out] sd descriptor being filled with \p base
|
||||||
|
*/
|
||||||
|
extern void i386_fill_segment_desc_base (uint32_t base,
|
||||||
|
segment_descriptors* sd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fills \p sd with provided \p limit in appropriate fields of \p sd
|
||||||
|
*
|
||||||
|
* sets granularity bit if necessary
|
||||||
|
*
|
||||||
|
* @param[in] limit 32-bit value representing number of limit bytes
|
||||||
|
* @param[out] sd descriptor being filled with \p limit
|
||||||
|
*/
|
||||||
|
extern void i386_fill_segment_desc_limit (uint32_t limit,
|
||||||
|
segment_descriptors* sd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to set up one raw interrupt handler
|
||||||
|
*/
|
||||||
|
extern uint32_t i386_set_gdt_entry (uint16_t segment_selector,
|
||||||
|
uint32_t base,
|
||||||
|
uint32_t limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns next empty descriptor in GDT.
|
||||||
|
*
|
||||||
|
* Number of descriptors that can be returned depends on \a GDT_SIZE
|
||||||
|
*
|
||||||
|
* @retval 0 FAILED GDT is full
|
||||||
|
* @retval <1;65535> segment_selector number as index to GDT
|
||||||
|
*/
|
||||||
|
extern uint16_t i386_next_empty_gdt_entry (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copies GDT entry at index \p segment_selector to structure
|
||||||
|
* pointed to by \p struct_to_fill
|
||||||
|
*
|
||||||
|
* @param[in] segment_selector index to GDT table specifying descriptor to copy
|
||||||
|
* @param[out] struct_to_fill pointer to memory where will be descriptor coppied
|
||||||
|
* @retval 0 FAILED segment_selector out of GDT range
|
||||||
|
* @retval <1;65535> retrieved segment_selector
|
||||||
|
*/
|
||||||
|
extern uint16_t i386_cpy_gdt_entry (uint16_t segment_selector,
|
||||||
|
segment_descriptors* struct_to_fill);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns pointer to GDT table at index given by \p segment_selector
|
||||||
|
*
|
||||||
|
* @param[in] sgmnt_selector index to GDT table for specifying descriptor to get
|
||||||
|
* @retval NULL FAILED segment_selector out of GDT range
|
||||||
|
* @retval pointer to GDT table at \p segment_selector
|
||||||
|
*/
|
||||||
|
extern segment_descriptors* i386_get_gdt_entry (uint16_t sgmnt_selector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extracts base address from GDT entry pointed to by \p gdt_entry
|
||||||
|
*
|
||||||
|
* @param[in] gdt_entry pointer to entry from which base should be retrieved
|
||||||
|
* @retval base address from GDT entry
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void* i386_base_gdt_entry (segment_descriptors* gdt_entry)
|
||||||
|
{
|
||||||
|
return (void*)(gdt_entry->base_address_15_0 |
|
||||||
|
(gdt_entry->base_address_23_16<<16) |
|
||||||
|
(gdt_entry->base_address_31_24<<24));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extracts limit in bytes from GDT entry pointed to by \p gdt_entry
|
||||||
|
*
|
||||||
|
* @param[in] gdt_entry pointer to entry from which limit should be retrieved
|
||||||
|
* @retval limit value in bytes from GDT entry
|
||||||
|
*/
|
||||||
|
extern uint32_t i386_limit_gdt_entry (segment_descriptors* gdt_entry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See page 11.18 Figure 11-12.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int offset : 12;
|
||||||
|
unsigned int page : 10;
|
||||||
|
unsigned int directory : 10;
|
||||||
|
}la_bits;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
la_bits bits;
|
||||||
|
unsigned int address;
|
||||||
|
}linear_address;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See page 11.20 Figure 11-14.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int present : 1;
|
||||||
|
unsigned int writable : 1;
|
||||||
|
unsigned int user : 1;
|
||||||
|
unsigned int write_through : 1;
|
||||||
|
unsigned int cache_disable : 1;
|
||||||
|
unsigned int accessed : 1;
|
||||||
|
unsigned int reserved1 : 1;
|
||||||
|
unsigned int page_size : 1;
|
||||||
|
unsigned int reserved2 : 1;
|
||||||
|
unsigned int available : 3;
|
||||||
|
unsigned int page_frame_address : 20;
|
||||||
|
}page_dir_bits;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
page_dir_bits bits;
|
||||||
|
unsigned int dir_entry;
|
||||||
|
}page_dir_entry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int present : 1;
|
||||||
|
unsigned int writable : 1;
|
||||||
|
unsigned int user : 1;
|
||||||
|
unsigned int write_through : 1;
|
||||||
|
unsigned int cache_disable : 1;
|
||||||
|
unsigned int accessed : 1;
|
||||||
|
unsigned int dirty : 1;
|
||||||
|
unsigned int reserved2 : 2;
|
||||||
|
unsigned int available : 3;
|
||||||
|
unsigned int page_frame_address : 20;
|
||||||
|
}page_table_bits;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
page_table_bits bits;
|
||||||
|
unsigned int table_entry;
|
||||||
|
} page_table_entry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* definitions related to page table entry
|
||||||
|
*/
|
||||||
|
#define PG_SIZE 0x1000
|
||||||
|
#define MASK_OFFSET 0xFFF
|
||||||
|
#define MAX_ENTRY (PG_SIZE/sizeof(page_dir_entry))
|
||||||
|
#define FOUR_MB 0x400000
|
||||||
|
#define MASK_FLAGS 0x1A
|
||||||
|
|
||||||
|
#define PTE_PRESENT 0x01
|
||||||
|
#define PTE_WRITABLE 0x02
|
||||||
|
#define PTE_USER 0x04
|
||||||
|
#define PTE_WRITE_THROUGH 0x08
|
||||||
|
#define PTE_CACHE_DISABLE 0x10
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
page_dir_entry pageDirEntry[MAX_ENTRY];
|
||||||
|
} page_directory;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
page_table_entry pageTableEntry[MAX_ENTRY];
|
||||||
|
} page_table;
|
||||||
|
|
||||||
|
/* Simpler names for the i80x86 I/O instructions */
|
||||||
#define outport_byte( _port, _value ) i386_outport_byte( _port, _value )
|
#define outport_byte( _port, _value ) i386_outport_byte( _port, _value )
|
||||||
#define outport_word( _port, _value ) i386_outport_word( _port, _value )
|
#define outport_word( _port, _value ) i386_outport_word( _port, _value )
|
||||||
#define outport_long( _port, _value ) i386_outport_long( _port, _value )
|
#define outport_long( _port, _value ) i386_outport_long( _port, _value )
|
||||||
@@ -251,7 +661,6 @@ int i386_Physical_to_real(
|
|||||||
#define inport_word( _port, _value ) i386_inport_word( _port, _value )
|
#define inport_word( _port, _value ) i386_inport_word( _port, _value )
|
||||||
#define inport_long( _port, _value ) i386_inport_long( _port, _value )
|
#define inport_long( _port, _value ) i386_inport_long( _port, _value )
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user