Patch from Emmanuel Raguet <raguet@crf.canon.fr>:

You will find enclosed a patch which contains, for Intel PC386 target :

      - an Ethernet driver for DEC21140 device based boards.
      - a simple cache management with paging mechanism.
This commit is contained in:
Joel Sherrill
1999-02-18 15:16:37 +00:00
parent edfb0eba88
commit e029467dac
7 changed files with 201 additions and 4 deletions

View File

@@ -17,6 +17,7 @@
#include <rtems/score/isr.h>
#include <bspIo.h>
#include <rtems/score/thread.h>
#include <libcpu/cpuModel.h>
/* _CPU_Initialize
@@ -88,6 +89,7 @@ void _CPU_Thread_Idle_body ()
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
unsigned int faultAddr;
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
@@ -103,7 +105,13 @@ void _defaultExcHandler (CPU_Exception_frame *ctx)
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n");
if (ctx->idtIndex == PAGE_FAULT){
faultAddr = i386_get_cr2();
printk("Page fault linear address (CR2) = %x\n",
faultAddr);
printk("----------------------------------------------------------\n\n");
}
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as

View File

@@ -60,9 +60,18 @@ extern "C" {
struct rtems_bsdnet_ifconfig;
extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config);
extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config);
#if 0
#define RTEMS_BSP_NETWORK_DRIVER_NAME "wd1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_wd_driver_attach
#endif
#if 1
#define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach
#endif
/*-------------------------------------------------------------------------+
| Constants

View File

@@ -11,7 +11,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
PGM=${ARCH}/network.rel
# C source names, if any, go here -- minus the .c
C_PIECES=network
C_PIECES=network dec21140
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)

View File

@@ -10,7 +10,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
# C source names, if any, go here -- minus the .c
C_PIECES=cpu displayCpu
C_PIECES=cpu displayCpu page
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)

View File

@@ -133,6 +133,47 @@ static inline unsigned short i386_get_gs()
return segment;
}
/*
* 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) );
}
/*
* IO Port Access Routines
*/
@@ -363,6 +404,112 @@ extern void i386_set_GDTR (segment_descriptors*,
extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
unsigned limit);
/*
* 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;
static inline void flush_cache(){
asm volatile ("wbinvd");
}
/* C declaration for paging management */
extern int _CPU_is_cache_enabled();
extern int _CPU_is_paging_enabled();
extern int init_paging();
extern void _CPU_enable_paging();
extern void _CPU_disable_paging();
extern void _CPU_disable_cache();
extern void _CPU_enable_cache();
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();
# endif /* ASM */
#endif

View File

@@ -58,6 +58,14 @@
#define CR0_PAGE_LEVEL_CACHE_DISABLE 0x40000000
#define CR0_PAGING 0x80000000
/*
* definitions related to CR3
*/
#define CR3_PAGE_CACHE_DISABLE 0x10
#define CR3_PAGE_WRITE_THROUGH 0x8
#ifndef ASM
/*
@@ -153,6 +161,23 @@ typedef union {
unsigned int i;
}cr0;
/*
* definition of cr3 registers has a bit field structure
*/
typedef struct {
unsigned int : 3;
unsigned int page_write_transparent : 1;
unsigned int page_cache_disable : 1;
unsigned int : 7;
unsigned int page_directory_base :20;
}cr3_bits;
typedef union {
cr3_bits cr3;
unsigned int i;
}cr3;
#endif
#endif

View File

@@ -17,6 +17,7 @@
#include <rtems/score/isr.h>
#include <bspIo.h>
#include <rtems/score/thread.h>
#include <libcpu/cpuModel.h>
/* _CPU_Initialize
@@ -88,6 +89,7 @@ void _CPU_Thread_Idle_body ()
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
unsigned int faultAddr;
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->idtIndex,
@@ -103,7 +105,13 @@ void _defaultExcHandler (CPU_Exception_frame *ctx)
printk("----------------------------------------------------------\n");
printk("Error code pushed by processor itself (if not 0) = %x\n",
ctx->faultCode);
printk("----------------------------------------------------------\n");
if (ctx->idtIndex == PAGE_FAULT){
faultAddr = i386_get_cr2();
printk("Page fault linear address (CR2) = %x\n",
faultAddr);
printk("----------------------------------------------------------\n\n");
}
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as