forked from Imagelibrary/rtems
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:
@@ -17,6 +17,7 @@
|
|||||||
#include <rtems/score/isr.h>
|
#include <rtems/score/isr.h>
|
||||||
#include <bspIo.h>
|
#include <bspIo.h>
|
||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
|
#include <libcpu/cpuModel.h>
|
||||||
|
|
||||||
|
|
||||||
/* _CPU_Initialize
|
/* _CPU_Initialize
|
||||||
@@ -88,6 +89,7 @@ void _CPU_Thread_Idle_body ()
|
|||||||
|
|
||||||
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
||||||
{
|
{
|
||||||
|
unsigned int faultAddr;
|
||||||
printk("----------------------------------------------------------\n");
|
printk("----------------------------------------------------------\n");
|
||||||
printk("Exception %d caught at PC %x by thread %d\n",
|
printk("Exception %d caught at PC %x by thread %d\n",
|
||||||
ctx->idtIndex,
|
ctx->idtIndex,
|
||||||
@@ -103,8 +105,14 @@ void _defaultExcHandler (CPU_Exception_frame *ctx)
|
|||||||
printk("----------------------------------------------------------\n");
|
printk("----------------------------------------------------------\n");
|
||||||
printk("Error code pushed by processor itself (if not 0) = %x\n",
|
printk("Error code pushed by processor itself (if not 0) = %x\n",
|
||||||
ctx->faultCode);
|
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");
|
printk("----------------------------------------------------------\n\n");
|
||||||
if (_ISR_Nest_level > 0) {
|
}
|
||||||
|
if (_ISR_Nest_level > 0) {
|
||||||
/*
|
/*
|
||||||
* In this case we shall not delete the task interrupted as
|
* In this case we shall not delete the task interrupted as
|
||||||
* it has nothing to do with the fault. We cannot return either
|
* it has nothing to do with the fault. We cannot return either
|
||||||
|
|||||||
@@ -60,9 +60,18 @@ extern "C" {
|
|||||||
|
|
||||||
struct rtems_bsdnet_ifconfig;
|
struct rtems_bsdnet_ifconfig;
|
||||||
extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config);
|
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_NAME "wd1"
|
||||||
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_wd_driver_attach
|
#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
|
| Constants
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
|||||||
PGM=${ARCH}/network.rel
|
PGM=${ARCH}/network.rel
|
||||||
|
|
||||||
# C source names, if any, go here -- minus the .c
|
# C source names, if any, go here -- minus the .c
|
||||||
C_PIECES=network
|
C_PIECES=network dec21140
|
||||||
C_FILES=$(C_PIECES:%=%.c)
|
C_FILES=$(C_PIECES:%=%.c)
|
||||||
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
|||||||
|
|
||||||
|
|
||||||
# C source names, if any, go here -- minus the .c
|
# 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_FILES=$(C_PIECES:%=%.c)
|
||||||
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,47 @@ static inline unsigned short i386_get_gs()
|
|||||||
return segment;
|
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
|
* 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,
|
extern int i386_set_gdt_entry (unsigned short segment_selector, unsigned base,
|
||||||
unsigned limit);
|
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 /* ASM */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,14 @@
|
|||||||
#define CR0_PAGE_LEVEL_CACHE_DISABLE 0x40000000
|
#define CR0_PAGE_LEVEL_CACHE_DISABLE 0x40000000
|
||||||
#define CR0_PAGING 0x80000000
|
#define CR0_PAGING 0x80000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* definitions related to CR3
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CR3_PAGE_CACHE_DISABLE 0x10
|
||||||
|
#define CR3_PAGE_WRITE_THROUGH 0x8
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASM
|
#ifndef ASM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -153,6 +161,23 @@ typedef union {
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
}cr0;
|
}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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <rtems/score/isr.h>
|
#include <rtems/score/isr.h>
|
||||||
#include <bspIo.h>
|
#include <bspIo.h>
|
||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
|
#include <libcpu/cpuModel.h>
|
||||||
|
|
||||||
|
|
||||||
/* _CPU_Initialize
|
/* _CPU_Initialize
|
||||||
@@ -88,6 +89,7 @@ void _CPU_Thread_Idle_body ()
|
|||||||
|
|
||||||
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
void _defaultExcHandler (CPU_Exception_frame *ctx)
|
||||||
{
|
{
|
||||||
|
unsigned int faultAddr;
|
||||||
printk("----------------------------------------------------------\n");
|
printk("----------------------------------------------------------\n");
|
||||||
printk("Exception %d caught at PC %x by thread %d\n",
|
printk("Exception %d caught at PC %x by thread %d\n",
|
||||||
ctx->idtIndex,
|
ctx->idtIndex,
|
||||||
@@ -103,8 +105,14 @@ void _defaultExcHandler (CPU_Exception_frame *ctx)
|
|||||||
printk("----------------------------------------------------------\n");
|
printk("----------------------------------------------------------\n");
|
||||||
printk("Error code pushed by processor itself (if not 0) = %x\n",
|
printk("Error code pushed by processor itself (if not 0) = %x\n",
|
||||||
ctx->faultCode);
|
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");
|
printk("----------------------------------------------------------\n\n");
|
||||||
if (_ISR_Nest_level > 0) {
|
}
|
||||||
|
if (_ISR_Nest_level > 0) {
|
||||||
/*
|
/*
|
||||||
* In this case we shall not delete the task interrupted as
|
* In this case we shall not delete the task interrupted as
|
||||||
* it has nothing to do with the fault. We cannot return either
|
* it has nothing to do with the fault. We cannot return either
|
||||||
|
|||||||
Reference in New Issue
Block a user