Ada95, gnat, go32

This commit is contained in:
Joel Sherrill
1995-07-12 19:47:25 +00:00
parent 68931b5dc1
commit 637df35f96
64 changed files with 4086 additions and 788 deletions

View File

@@ -0,0 +1,135 @@
/* Clock_initialize
*
* This routine initializes the 8254 timer under GO32.
* The tick frequency is 1 millisecond.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* $Id$
*/
#include <bsp.h>
#include <clockdrv.h>
#include <stdlib.h>
volatile rtems_unsigned32 Clock_driver_ticks;
rtems_unsigned32 Clock_isrs_per_tick; /* ISRs per tick */
rtems_unsigned32 Clock_isrs; /* ISRs until next tick */
rtems_isr_entry Old_ticker;
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp,
rtems_id tid,
rtems_unsigned32 *rval
)
{
Install_clock( Clock_isr );
}
void ReInstall_clock(
rtems_isr_entry clock_isr
)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable( isrlevel );
(void) set_vector( clock_isr, 0x8, 1 );
rtems_interrupt_enable( isrlevel );
}
void Install_clock(
rtems_isr_entry clock_isr
)
{
unsigned int microseconds_per_isr;
#if 0
/* Initialize clock from on-board real time clock. This breaks the */
/* test code which assumes which assumes the application will do it. */
{
rtems_time_of_day Now;
extern void init_rtc( void );
extern long rtc_read( rtems_time_of_day * tod );
init_rtc();
if ( rtc_read( &Now ) >= 0 )
clock_set( &Now );
}
#endif
/* Start by assuming hardware counter is large enough, then */
/* scale it until it actually fits. */
Clock_driver_ticks = 0;
Clock_isrs_per_tick = 1;
if ( BSP_Configuration.microseconds_per_tick == 0 )
microseconds_per_isr = 10000; /* default 10 ms */
else
microseconds_per_isr = BSP_Configuration.microseconds_per_tick;
while ( US_TO_TICK(microseconds_per_isr) > 65535 ) {
Clock_isrs_per_tick *= 10;
microseconds_per_isr /= 10;
}
/* Initialize count in ckisr.c */
Clock_isrs = Clock_isrs_per_tick;
#if 0
/* This was dropped in the last revision. Its a nice thing to know. */
TICKS_PER_SECOND = 1000000 / (Clock_isrs_per_tick * microseconds_per_isr);
#endif
if ( BSP_Configuration.ticks_per_timeslice ) {
/* 105/88 approximates TIMER_TICK*1e-6 */
unsigned int count = US_TO_TICK( microseconds_per_isr );
Old_ticker = (rtems_isr_entry) set_vector( clock_isr, 0x8, 1 );
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
outport_byte( TIMER_CNTR0, count >> 0 & 0xff );
outport_byte( TIMER_CNTR0, count >> 8 & 0xff );
}
atexit( Clock_exit );
}
void Clock_exit( void )
{
if ( BSP_Configuration.ticks_per_timeslice ) {
extern void rtc_set_dos_date( void );
/* reset to DOS value: */
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
outport_byte( TIMER_CNTR0, 0 );
outport_byte( TIMER_CNTR0, 0 );
/* reset time-of-day */
rtc_set_dos_date();
/* re-enable old handler: assume it was one of ours */
set_vector( (rtems_isr_entry)Old_ticker, 0x8, 1 );
}
}
#if 0 && defined(pentium)
/* This can be used to get extremely accurate timing on a pentium. */
/* It isn't supported. [bryce] */
#define HZ 90.0
volatile long long Last_RDTSC;
#define RDTSC()\
({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })
long long Kernel_Time_ns( void )
{
extern rtems_unsigned32 _TOD_Ticks_per_second;
unsigned isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second;
long long now;
int flags;
disable_intr( flags );
now = 1e9 * Clock_driver_ticks / isrs_per_second
+ (RDTSC() - Last_RDTSC) * (1000.0/HZ);
enable_intr( flags );
return now;
}
#endif

View File

@@ -0,0 +1,213 @@
/*
* $Id$
*/
#define IO_RTC 0x70 /* RTC */
#define RTC_SEC 0x00 /* seconds */
#define RTC_SECALRM 0x01 /* seconds alarm */
#define RTC_MIN 0x02 /* minutes */
#define RTC_MINALRM 0x03 /* minutes alarm */
#define RTC_HRS 0x04 /* hours */
#define RTC_HRSALRM 0x05 /* hours alarm */
#define RTC_WDAY 0x06 /* week day */
#define RTC_DAY 0x07 /* day of month */
#define RTC_MONTH 0x08 /* month of year */
#define RTC_YEAR 0x09 /* month of year */
#define RTC_STATUSA 0x0a /* status register A */
#define RTCSA_TUP 0x80 /* time update, don't look now */
#define RTC_STATUSB 0x0b /* status register B */
#define RTC_INTR 0x0c /* status register C (R) interrupt source */
#define RTCIR_UPDATE 0x10 /* update intr */
#define RTCIR_ALARM 0x20 /* alarm intr */
#define RTCIR_PERIOD 0x40 /* periodic intr */
#define RTCIR_INT 0x80 /* interrupt output signal */
#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */
#define RTCSD_PWR 0x80 /* clock lost power */
#define RTC_DIAG 0x0e /* status register E - bios diagnostic */
#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
#define RTC_CENTURY 0x32 /* current century - increment in Dec99 */
#include <rtems.h>
#include <cpu.h>
#include <memory.h>
void init_rtc( void )
{
int s;
/* initialize brain-dead battery powered clock */
outport_byte( IO_RTC, RTC_STATUSA );
outport_byte( IO_RTC+1, 0x26 );
outport_byte( IO_RTC, RTC_STATUSB );
outport_byte( IO_RTC+1, 2 );
outport_byte( IO_RTC, RTC_DIAG );
inport_byte( IO_RTC+1, s );
#if 0
if (s) printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
#endif
}
/* convert 2 digit BCD number */
static int bcd( unsigned int i )
{
return ((i/16)*10 + (i%16));
}
/* convert years to seconds (from 1970) */
static unsigned long ytos( int y )
{
int i;
unsigned long ret;
ret = 0;
for(i = 1970; i < y; i++) {
if (i % 4) ret += 365*24*60*60;
else ret += 366*24*60*60;
}
return ret;
}
/* convert months to seconds */
static unsigned long mtos( int m, int leap )
{
int i;
unsigned long ret;
ret = 0;
for(i=1;i<m;i++) {
switch(i){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
ret += 31*24*60*60;
break;
case 4: case 6: case 9: case 11:
ret += 30*24*60*60;
break;
case 2:
if (leap)
ret += 29*24*60*60;
else
ret += 28*24*60*60;
}
}
return ret;
}
static inline unsigned int rtcin( unsigned int what )
{
unsigned int r;
outport_byte( IO_RTC, what );
inport_byte( IO_RTC+1, r );
return r;
}
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
*/
long rtc_read( rtems_time_of_day * tod )
{
int sa;
unsigned long sec = 0;
memset( tod, 0, sizeof *tod );
/* do we have a realtime clock present? (otherwise we loop below) */
sa = rtcin(RTC_STATUSA);
if (sa == 0xff || sa == 0)
return -1;
/* ready for a read? */
while ((sa&RTCSA_TUP) == RTCSA_TUP)
sa = rtcin(RTC_STATUSA);
tod->year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */
if (tod->year < 1970) tod->year += 100;
tod->month = bcd(rtcin(RTC_MONTH)); /* month */
tod->day = bcd(rtcin(RTC_DAY)); /* day */
(void) bcd(rtcin(RTC_WDAY)); /* weekday */
tod->hour = bcd(rtcin(RTC_HRS)); /* hour */
tod->minute = bcd(rtcin(RTC_MIN)); /* minutes */
tod->second = bcd(rtcin(RTC_SEC)); /* seconds */
tod->ticks = 0;
#if 0
sec = ytos( tod->year );
sec += mtos( tod->month, tod->year % 4 == 0 );
sec += tod->day * 24*60*60;
sec += tod->hour * 60*60; /* hour */
sec += tod->minute * 60; /* minutes */
sec += tod->second; /* seconds */
#else
sec = 0;
#endif
return sec;
}
/* from djgpp: include before rtems.h to avoid conflicts */
#undef delay
#include <dos.h>
void rtc_set_dos_date( void )
{
int s;
struct date date;
struct time time;
/* initialize brain-dead battery powered clock */
outport_byte( IO_RTC, RTC_STATUSA );
outport_byte( IO_RTC+1, 0x26 );
outport_byte( IO_RTC, RTC_STATUSB );
outport_byte( IO_RTC+1, 2 );
outport_byte( IO_RTC, RTC_DIAG );
inport_byte( IO_RTC+1, s );
if (s) {
#if 0
printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS);
#else
return;
#endif
}
/* check for presence of clock */
s = rtcin(RTC_STATUSA);
if ( s == 0xff || s == 0 ) {
#if 0
printf( "Real-time clock not found\n" );
#endif
return;
}
/* ready for a read? */
while ((s & RTCSA_TUP) == RTCSA_TUP)
s = rtcin(RTC_STATUSA);
date.da_year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */
if ( date.da_year < 1970) date.da_year += 100;
date.da_year -= 1980;
date.da_mon = bcd(rtcin(RTC_MONTH)); /* month */
date.da_day = bcd(rtcin(RTC_DAY)); /* day */
(void)bcd(rtcin(RTC_WDAY)); /* weekday */
time.ti_hour = bcd(rtcin(RTC_HRS)); /* hour */
time.ti_min = bcd(rtcin(RTC_MIN)); /* minutes */
time.ti_sec = bcd(rtcin(RTC_SEC)); /* seconds */
time.ti_hund = 0;
setdate( & date );
settime( & time );
}

View File

@@ -0,0 +1,186 @@
/*
* This file contains the go32 console IO package.
*
* $Id$
*/
#define IBMPC_INIT
#include <stdlib.h>
#include <rtems.h>
#include "console.h"
#include "bsp.h"
#include <dpmi.h>
#include <go32.h>
/* console_cleanup
*
* This routine is called at exit to clean up the console hardware.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/
void console_cleanup( void )
{
/* nothing */
}
/* console_initialize
*
* This routine initializes the console IO driver.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/
/* Set this if console I/O should use go32 (DOS) read/write calls. */
/* Otherwise, direct hardware accesses will be used. */
int _IBMPC_Use_Go32_IO = 0;
static rtems_isr_entry old_keyboard_isr = NULL;
extern void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt );
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg,
rtems_id self,
rtems_unsigned32 *status
)
{
if ( _IBMPC_Use_Go32_IO ) {
/* Nothing. We let DOS and go32 do all the work. */
} else {
/* Grap the keyboard interrupt so DOS doesn't steal our */
/* keystrokes. */
rtems_status_code status;
status = rtems_interrupt_catch( _IBMPC_keyboard_isr, 9,
&old_keyboard_isr );
if ( status ) {
int write( int, void *, int );
void exit( int );
char msg[] = "error initializing keyboard\n";
write( 2, msg, sizeof msg - 1 );
exit( 1 );
}
}
atexit( console_cleanup );
}
/* is_character_ready
*
* This routine returns TRUE if a character is available.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/
rtems_boolean is_character_ready(
char *ch
)
{
return _IBMPC_chrdy( ch ) ? TRUE : FALSE;
}
/* inbyte
*
* This routine reads a character from the UART.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
* character read from UART
*/
char inbyte( void )
{
char ch = _IBMPC_inch();
#if 1
/* Echo character to screen */
void outbyte( char ch );
outbyte( ch );
if ( ch == '\r' )
outbyte( '\n' );
#endif
return ch;
}
/* outbyte
*
* This routine transmits a character out the port.
*
* Input parameters:
* ch - character to be transmitted
*
* Output parameters: NONE
*/
void outbyte( char ch )
{
_IBMPC_outch( ch );
}
/*
* __read -- read bytes from the console. Ignore fd, since
* we only have stdin.
*/
int __read(
int fd,
char *buf,
int nbytes
)
{
int i = 0;
for ( i = 0; i < nbytes; i++ ) {
buf[i] = inbyte();
if ( buf[i] == '\r' ) {
/* What if this goes past the end of the buffer? We're hosed. [bhc] */
buf[i++] = '\n';
buf[i] = '\0';
break;
}
}
return i;
}
/*
* __write -- write bytes to the console. Ignore fd, since
* stdout and stderr are the same. Since we have no filesystem,
* open will only return an error.
*/
int __write(
int fd,
char *buf,
int nbytes
)
{
int i;
for (i = 0; i < nbytes; i++) {
if (*(buf + i) == '\n') {
outbyte ('\r');
}
outbyte (*(buf + i));
}
return (nbytes);
}

View File

@@ -0,0 +1,163 @@
/*
* $Id$
*/
#include <pc.h>
#include <go32.h>
#include <bsp.h>
#include <cpu.h>
/*
* Ports for PC keyboard
*/
#define KBD_CTL 0x61
#define KBD_DATA 0x60
#define KBD_STATUS 0x64
static char key_map[] = {
0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
0134,'z','x','c','v','b','n','m',',','.','/',0x80,
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,'0',0177
};
static char shift_map[] = {
0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
'|','Z','X','C','V','B','N','M','<','>','?',0x80,
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
'1','2','3','0',177
};
extern int _IBMPC_Use_Go32_IO;
#define KBD_BUF_SIZE 256
static char kbd_buffer[ KBD_BUF_SIZE ];
static unsigned int kbd_first = 0;
static unsigned int kbd_last = 0;
/* This function can be called during a poll for input, or by an ISR. */
/* Basically any time you want to process a keypress. */
int _IBMPC_scankey( char * ch )
{
unsigned char c;
unsigned char outch;
static int shift_pressed = 0;
static int ctrl_pressed = 0;
static int caps_pressed = 0;
/* Read keyboard controller, toggle enable */
inport_byte( KBD_CTL, c );
outport_byte( KBD_CTL, c & ~0x80 );
outport_byte( KBD_CTL, c | 0x80 );
outport_byte( KBD_CTL, c & ~0x80 );
/* See if it has data */
inport_byte( KBD_STATUS, c );
if ( ( c & 0x01 ) == 0 )
return 0;
/* Read the data. Handle nonsense with shift, control, etc. */
inport_byte( KBD_DATA, c );
switch ( c ) {
case 0x36:
case 0x2a:
shift_pressed = 1;
return 0;
case 0x3a:
caps_pressed = 1;
return 0;
case 0x1d:
ctrl_pressed = 1;
return 0;
case 0xb6:
case 0xaa:
shift_pressed = 0;
return 0;
case 0xba:
caps_pressed = 0;
return 0;
case 0x9d:
ctrl_pressed = 0;
return 0;
/*
* Ignore unrecognized keys--usually arrow and such
*/
default:
if ( c & 0x80 )
/* High-bit on means key is being released, not pressed */
return 0;
if ( c == 88 )
/* F12 - abort */
exit( 1 );
if ( c > 0x39 ) {
return 0;
}
}
/* Strip high bit, look up in our map */
c &= 127;
if ( ctrl_pressed ) {
outch = key_map[c];
outch &= 037;
} else {
outch = shift_pressed ? shift_map[c] : key_map[c];
if ( caps_pressed ) {
if ( outch >= 'A' && outch <= 'Z' ) outch += 'a' - 'A';
else if ( outch >= 'a' && outch <= 'z' ) outch -= 'a' - 'A';
}
}
*ch = outch;
return 1;
}
void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt )
{
if ( _IBMPC_scankey( & kbd_buffer[ kbd_last ] ) ) {
/* Got one; save it if there is enough room in buffer. */
unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
if ( next != kbd_first )
kbd_last = next;
}
/* Mark interrupt as handled */
outport_byte( 0x20, 0x20 );
}
int _IBMPC_chrdy( char * ch )
{
if ( _IBMPC_Use_Go32_IO ) {
/* Read keyboard via BIOS: raw mode. */
if ( kbhit() ) {
*ch = getkey();
return 1;
} else {
return 0;
}
} else {
/* Check buffer our ISR builds */
if ( kbd_first != kbd_last ) {
*ch = kbd_buffer[ kbd_first ];
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return 1;
} else {
return 0;
}
}
}
int _IBMPC_inch( void )
{
char Ch;
while ( ! _IBMPC_chrdy( & Ch ) )
continue;
return Ch;
}

View File

@@ -0,0 +1,151 @@
/*
* $Id$
*/
#include <go32.h>
#include <bsp.h>
#include <cpu.h>
#include <memory.h>
#define MAX_COL 80
#define MAX_ROW 50
static unsigned nrow = 25;
static unsigned ncol = 80;
static unsigned short * tvram = TVRAM;
static unsigned char current_col = 0;
static unsigned char current_row = 0;
static unsigned short screen_copy[ MAX_ROW*MAX_COL ];
static void init_cons( void );
/*
* set_cursor_pos()
* Set cursor position based on current absolute screen offset
*/
static void
set_cursor_pos(void)
{
register unsigned short gdc_pos = current_row * ncol + current_col;
outport_byte( GDC_REG_PORT, 0xe );
outport_byte( GDC_VAL_PORT, (gdc_pos >> 8) & 0xff );
outport_byte( GDC_REG_PORT, 0xf );
outport_byte( GDC_VAL_PORT, gdc_pos & 0xff );
}
/*
* scroll_up()
* Scroll screen up one line
*/
static void
scroll_up( unsigned short * tv, unsigned short * copy, unsigned int lines )
{
if ( lines > nrow )
lines = nrow;
/* move everything up */
memmove( copy, copy+ncol*lines, (nrow-lines)*ncol*sizeof copy[0] );
/* fill bottom with blanks */
{
int loop = ncol*lines;
unsigned short * ptr = copy + ncol*(nrow-lines);
while ( --loop >= 0 )
*ptr++ = (WHITE<<8) | ' ';
}
/* copy new screen to video buffer */
dosmemput( copy, nrow*ncol*sizeof copy[0], (int)tv );
}
/*
* PUT()
* Write character at current screen location
*/
inline static void PUT( char c )
{
unsigned short loc = current_row*ncol+current_col;
unsigned short val = (WHITE<<8) | c;
screen_copy[loc] = val;
dosmemput( &screen_copy[loc], sizeof screen_copy[0], (int)(tvram+loc) );
}
/*
* cons_putc()
* Place a character on next screen position
*/
static void
cons_putc( unsigned char c )
{
static int first = 1;
if ( first ) {
init_cons();
first = 0;
}
switch (c) {
case '\t':
while ( current_row % 8 )
cons_putc(' ');
break;
case '\r':
current_col = 0;
break;
case '\n':
if ( ++current_row >= nrow ) {
scroll_up( tvram, screen_copy, 1 );
current_row -= 1;
}
break;
case '\b':
if ( current_col > 0 ) {
--current_col;
PUT(' ');
}
break;
default:
PUT(c);
current_col += 1;
if ( current_col >= ncol ) {
current_col = 0;
current_row += 1;
if ( current_row >= nrow ) {
scroll_up( tvram, screen_copy, 1 );
current_row -= 1;
}
}
};
set_cursor_pos();
}
/*
* init_cons()
* Hook for any early setup
*/
static void
init_cons( void )
{
#if 0
/* Get a copy of original screen */
dosmemget( (int)tvram, nrow*ncol*sizeof *tvram, screen_copy );
#else
/* Clear entire screen */
scroll_up( tvram, screen_copy, nrow );
#endif
}
void _IBMPC_outch( unsigned char ch )
{
extern int _IBMPC_Use_Go32_IO;
if ( _IBMPC_Use_Go32_IO ) {
write( 1, &ch, 1 );
} else {
cons_putc( ch );
}
}

View File

@@ -0,0 +1,157 @@
/* bsp.h
*
* This include file definitions related to the ibm386 (go32) board.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __IBMPC_h
#define __IBMPC_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <cpu.h>
#include <iosupp.h>
/*
* Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These
* values are in seconds and need to be converted to ticks for the
* application.
*
*/
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/*
* Define the interrupt mechanism for Time Test 27
*
* NOTE: Use a software interrupt for the i386.
*/
#define MUST_WAIT_FOR_INTERRUTPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 )
#define Cause_tm27_intr() asm volatile( "int $0x90" : : );
#define Clear_tm27_intr()
#define Lower_tm27_intr()
/*
* Simple spin delay in microsecond units for device drivers.
* This is very dependent on the clock speed of the target.
*/
#define delay( _microseconds ) { \
rtems_unsigned32 _cnt = (_microseconds); \
asm volatile ("0: nop; mov %0,%0; loop 0b" : "=c"(_cnt) : "0"(_cnt) ); \
}
/* Constants */
/* Assume color console */
#define COLOR 1
#if COLOR
# define GDC_REG_PORT 0x3d4
# define GDC_VAL_PORT 0x3d5
# define TVRAM ((unsigned short *)0xb8000L)
#else
# define GDC_REG_PORT 0x3b4
# define GDC_VAL_PORT 0x3b5
# define TVRAM ((unsigned short *)0xb0000L)
#endif
/* White character attribute--works for MGA and CGA */
#define WHITE 0x07
/* Ports for PC keyboard */
#define KBD_CTL 0x61
#define KBD_DATA 0x60
#define KBD_STATUS 0x64
/* Constants relating to the 8254 (or 8253) programmable interval timers */
/* Port address of the control port and timer channels */
/*
* Macros for specifying values to be written into a mode register.
*/
#define IO_TIMER1 0x40
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
#define TIMER_LATCH 0x00 /* latch counter for reading */
#define TIMER_LSB 0x10 /* r/w counter LSB */
#define TIMER_MSB 0x20 /* r/w counter MSB */
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
#define TIMER_BCD 0x01 /* count in BCD */
/* The internal tick rate in ticks per second */
#define TIMER_TICK 1193182
#define US_TO_TICK(us) (((us)*105+44)/88)
#define TICK_TO_US(tk) (((tk)*88+52)/105)
/* Structures */
#ifdef IBMPC_INIT
#undef BSP_EXTERN
#define BSP_EXTERN
#else
#undef BSP_EXTERN
#define BSP_EXTERN extern
#endif
/* functions */
int _IBMPC_chrdy( char * ch );
int _IBMPC_inch( void );
void _IBMPC_outch( unsigned char );
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration;
#if 0
extern i386_IDT_slot Interrupt_descriptor_table[ 256 ];
extern i386_GDT_slot Global_descriptor_table[ 8192 ];
BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */
BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */
BSP_EXTERN unsigned int Idt_base;
BSP_EXTERN unsigned int Gdt_base;
#endif
/* routines */
i386_isr set_vector(
rtems_isr_entry handler,
rtems_vector_number vector,
int type
);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,104 @@
/* coverhd.h
*
* This include file has defines to represent the overhead associated
* with calling a particular directive from C on this target.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#ifdef __cplusplus
extern "C" {
#endif
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 0
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 0
#define CALLING_OVERHEAD_CLOCK_SET 0
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 0
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 0
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,134 @@
/* bsp_start()
*
* This routine starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before this routine is invoked.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <cpu.h>
#include <libcsupport.h>
#include <stackchk.h>
/*
* The original table from the application and our copy of it with
* some changes.
*/
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
/* Initialize whatever libc we are using
* called from postdriver hook
*/
void bsp_libc_init()
{
rtems_unsigned32 heap_start;
#if 0
extern int end;
heap_start = (rtems_unsigned32) &end;
#else
void * sbrk( int );
heap_start = (rtems_unsigned32) sbrk( 64 * 1024 + CPU_ALIGNMENT );
#endif
if (heap_start & (CPU_ALIGNMENT-1))
heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
/*
* Set up for the libc handling.
*/
if (BSP_Configuration.ticks_per_timeslice > 0)
libc_init(1); /* reentrant if possible */
else
libc_init(0); /* non-reentrant */
/*
* Initialize the stack bounds checker
*/
#ifdef STACK_CHECKER_ON
Stack_check_Initialize();
#endif
}
void bsp_start()
{
extern void * sbrk( int );
Cpu_table.pretasking_hook = NULL;
Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */
Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_table_segment = 0;/* get_ds(); */
Cpu_table.interrupt_table_offset = (void *)0;
Cpu_table.interrupt_stack_size = 4096;
Cpu_table.extra_system_initialization_stack = 0;
/*
* Copy the table
*/
BSP_Configuration = Configuration;
BSP_Configuration.work_space_start = sbrk( Configuration.work_space_size );
if ( BSP_Configuration.work_space_start == 0 ) {
/* Big trouble */
int write( int, void *, int );
void _exit( int );
char msg[] = "bsp_start() couldn't sbrk() RTEMS work space\n";
write( 2, msg, sizeof msg - 1 );
_exit( 1 );
}
/*
* Add 1 region for Malloc in libc_low
*/
BSP_Configuration.maximum_regions++;
/*
* Add 1 extension for newlib libc
*/
#ifdef RTEMS_NEWLIB
BSP_Configuration.maximum_extensions++;
#endif
/*
* Add another extension if using the stack checker
*/
#ifdef STACK_CHECKER_ON
BSP_Configuration.maximum_extensions++;
#endif
rtems_initialize_executive( &BSP_Configuration, &Cpu_table );
/* does not return */
/* no cleanup necessary for GO32 */
}

View File

@@ -0,0 +1,30 @@
/*
* exit
*
* This routine returns control to DOS.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <clockdrv.h>
#include <iodrv.h>
#if 0
/* Prefer to pick up _exit() in djgcc */
void _exit( )
{
Io_cleanup();
bsp_cleanup();
}
#endif

View File

@@ -0,0 +1,67 @@
/* set_vector
*
* This routine installs an interrupt vector under go32.
*
* INPUT:
* handler - interrupt handler entry point
* vector - vector number
* type - 0 indicates raw hardware connect
* 1 indicates RTEMS interrupt connect
*
* RETURNS:
* address of previous interrupt handler
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <dpmi.h>
#include <go32.h>
i386_isr set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
)
{
i386_isr previous_isr;
if ( type ) {
rtems_interrupt_catch( handler, vector,
(rtems_isr_entry *) &previous_isr );
} else {
/* Interrupt goes straight to the supplied ISR. This code is */
/* slightly different than that in _CPU_ISR_install_vector */
/* (which is eventually called by the above) in that this code */
/* returns the raw entry point as the old handler, while the */
/* other version returns the old entry point pointed at by the */
/* rtems ISR table. */
_go32_dpmi_seginfo handler_info;
/* get the address of the old handler */
_go32_dpmi_get_protected_mode_interrupt_vector( vector, &handler_info);
/* Notice how we're failing to save the pm_segment portion of the */
/* structure here? That means we might crash the system if we */
/* try to restore the ISR. Can't fix this until i386_isr is */
/* redefined. XXX [BHC]. */
previous_isr = (i386_isr) handler_info.pm_offset;
/* install the IDT entry */
handler_info.pm_offset = (int)handler;
handler_info.pm_selector = _go32_my_cs();
_go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info);
}
return previous_isr;
}

View File

@@ -0,0 +1,107 @@
/* Timer_init()
*
* This routine initializes the timer on the IBM 386.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <cpu.h>
#include <bsp.h>
volatile rtems_unsigned32 Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead;
#if defined(pentium)
static inline unsigned long long rdtsc( void )
{
/* Return the value of the on-chip cycle counter. */
unsigned long long result;
__asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) );
return result;
}
#else /* pentium */
rtems_isr timerisr();
#endif /* pentium */
void Timer_initialize()
{
#if defined(pentium)
Ttimer_val = rdtsc();
#else /* pentium */
static int First = 1;
if ( First ) {
/* install ISR */
set_vector( timerisr, 0x8, 0 );
/* Wait for ISR to be called at least once */
Ttimer_val = 0;
while ( Ttimer_val == 0 )
continue;
/* load timer for 250 microsecond period */
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN );
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff);
outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff);
First = 0;
}
Ttimer_val = 0; /* clear timer ISR count */
#endif /* PENTIUM */
}
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
#define LEAST_VALID 1 /* Don't trust a value lower than this */
int Read_timer()
{
register rtems_unsigned32 total;
#if defined(pentium)
total = rdtsc() - Ttimer_val;
#else /* pentium */
register rtems_unsigned8 lsb, msb;
register rtems_unsigned32 clicks;
outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH );
inport_byte( TIMER_CNTR0, lsb );
inport_byte( TIMER_CNTR0, msb );
clicks = msb << 8 | lsb;
total = Ttimer_val + 250 - TICK_TO_US( clicks );
#endif /* pentium */
if ( Timer_driver_Find_average_overhead == 1 )
return total;
else if ( total < LEAST_VALID )
return 0; /* below timer resolution */
else
return total - AVG_OVERHEAD;
}
rtems_status_code Empty_function( void )
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(
rtems_boolean find_flag
)
{
Timer_driver_Find_average_overhead = find_flag;
}

View File

@@ -0,0 +1,39 @@
# timer_isr()
#
# This routine provides the ISR for the timer. The timer is set up
# to generate an interrupt at maximum intervals.
#
# Input parameters: NONE
#
# Output parameters: NONE
#
# COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
# On-Line Applications Research Corporation (OAR).
# All rights assigned to U.S. Government, 1994.
#
# This material may be reproduced by or for the U.S. Government pursuant
# to the copyright license under the clause at DFARS 252.227-7013. This
# notice must appear in all copies of this file and its derivatives.
#
# $Id$
#
#include "asm.h"
BEGIN_CODE
EXTERN(_Ttimer_val)
SYM (_timerisr):
addl $250,_Ttimer_val # another 250 microseconds
push edx
push eax
movw $0x20,dx
mov edx,eax
outb al,(dx) # touch interrupt controller
pop eax
pop edx
iret
END_CODE
END

View File

@@ -0,0 +1,122 @@
/* Clock
*
* This routine initializes the interval timer on the
* PA-RISC CPU. The tick frequency is specified by the bsp.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
extern rtems_configuration_table Configuration;
extern sigset_t UNIX_SIGNAL_MASK;
/*
* Function prototypes
*/
void Install_clock();
void Clock_isr();
void Clock_exit();
/*
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
* allocated and set by bsp_start()
*/
#ifndef CPU_HPPA_CLICKS_PER_TICK
extern rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK;
#endif
volatile rtems_unsigned32 Clock_driver_ticks;
struct itimerval new;
rtems_device_driver
Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp,
rtems_id tid,
rtems_unsigned32 *rval
)
{
Install_clock(Clock_isr);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
(void)set_vector(new_clock_isr, SIGALRM, 1);
rtems_interrupt_enable(isrlevel);
}
void
Install_clock(rtems_isr_entry clock_isr)
{
Clock_driver_ticks = 0;
new.it_value.tv_sec = 0;
new.it_value.tv_usec = Configuration.microseconds_per_tick;
new.it_interval.tv_sec = 0;
new.it_interval.tv_usec = Configuration.microseconds_per_tick;
(void)set_vector(clock_isr, SIGALRM, 1);
setitimer(ITIMER_REAL, &new, 0);
atexit(Clock_exit);
}
void
Clock_isr(int vector)
{
Clock_driver_ticks++;
rtems_clock_tick();
}
/*
* Called via atexit()
* Remove the clock signal
*/
void
Clock_exit(void)
{
struct sigaction act;
/*
* Set the SIGALRM signal to ignore any last
* signals that might come in while we are
* disarming the timer and removing the interrupt
* vector.
*/
act.sa_handler = SIG_IGN;
sigaction(SIGALRM, &act, 0);
new.it_value.tv_sec = 0;
new.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &new, 0);
(void)set_vector(0, SIGALRM, 1);
}

View File

@@ -0,0 +1,37 @@
/*
* Console IO Support Routines
*
* These provide UNIX-like read and write calls for the C library.
*
* COPYRIGHT (c) 1994 by Division Incorporated
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of Division Incorporated not be
* used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission.
* Division Incorporated makes no representations about the
* suitability of this software for any purpose.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <unistd.h>
#include <errno.h>
rtems_device_driver
console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg,
rtems_id self,
rtems_unsigned32 * status)
{
*status = RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,88 @@
/* bsp.h
*
* This include file contains all Solaris 2.3 UNIX definitions.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __SOLARIS23_h
#define __SOLARIS23_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <iosupp.h>
/*
* Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These
* values are in seconds and need to be converted to ticks for the
* application.
*
*/
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 1
#define Install_tm27_vector( handler ) \
set_vector( (handler), 16, 1 )
#define Cause_tm27_intr() \
raise( 16 )
#define Clear_tm27_intr()
#define Lower_tm27_intr() \
_ISR_Set_level( 0 );
#define RAM_START 0
#define RAM_END 0x100000
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration;
#define INTERRUPT_EXTERNAL_MPCI 0
/* functions */
void bsp_start( void );
void bsp_cleanup( void );
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
extern rtems_cpu_table Cpu_table; /* owned by BSP */
extern int rtems_argc;
extern char **rtems_argv;
extern char **rtems_envp;
extern rtems_unsigned32 bsp_isr_level;
extern char *rtems_progname; /* UNIX executable name */
extern int cpu_number;
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,111 @@
/* coverhd.h
*
* This include file has defines to represent the overhead associated
* with calling a particular directive from C. These are used in the
* Timing Test Suite to ignore the overhead required to pass arguments
* to directives. On some CPUs and/or target boards, this overhead
* is significant and makes it difficult to distinguish internal
* RTEMS execution time from that used to call the directive.
*
* NOTE: If these are all zero, then the times reported include all
* all calling overhead including passing of arguments.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#ifdef __cplusplus
extern "C" {
#endif
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 0
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 0
#define CALLING_OVERHEAD_CLOCK_SET 0
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 0
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 0
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,9 @@
#
# $Id$
#
This directory contains the SHM driver support files for
System V/POSIX derived UNIX flavors.
WARNING: The interrupt support in this directory currently will
only work in a homogeneous system.

View File

@@ -0,0 +1,32 @@
/* rtems_unsigned32 *Shm_Convert_address( addr )
*
* No address range conversion is required.
*
* Input parameters:
* addr - address to convert
*
* Output parameters:
* returns - converted address
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
void *Shm_Convert_address(
void *addr
)
{
return ( addr );
}

View File

@@ -0,0 +1,136 @@
/* void Shm_get_config( localnode, &shmcfg )
*
* This routine initializes, if necessary, and returns a pointer
* to the Shared Memory Configuration Table for the UNIX
* simulator.
*
* INPUT PARAMETERS:
* localnode - local node number
* shmcfg - address of pointer to SHM Config Table
*
* OUTPUT PARAMETERS:
* *shmcfg - pointer to SHM Config Table
*
* NOTES: The MP interrupt used is the Runway bus' ability to directly
* address the control registers of up to four CPUs and cause
* interrupts on them.
*
* The following table illustrates the configuration limitations:
*
* BUS MAX
* MODE ENDIAN NODES
* ========= ====== =======
* POLLED BIG 2+
* INTERRUPT BIG 2..4
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <shm.h>
#include <bsp.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define INTERRUPT 0 /* can be interrupt or polling */
#define POLLING 1
shm_config_table BSP_shm_cfgtbl;
int semid;
void Shm_Cause_interrupt_unix(
rtems_unsigned32 node
);
void Shm_Get_configuration(
rtems_unsigned32 localnode,
shm_config_table **shmcfg
)
{
rtems_unsigned32 maximum_nodes;
int i;
int shmid;
char *shm_addr;
key_t shm_key;
key_t sem_key;
struct sembuf sb;
int status;
shm_key = 0xa000;
shmid = shmget(shm_key, 16 * KILOBYTE, IPC_CREAT | 0660);
if ( shmid == -1 ) {
perror( "shmget" );
exit( 0 );
}
shm_addr = shmat(shmid, (char *)0, SHM_RND);
if ( shm_addr == (void *)-1 ) {
perror( "shmat" );
exit( 0 );
}
sem_key = 0xa001;
maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
semid = semget(sem_key, maximum_nodes + 1, IPC_CREAT | 0660);
if ( semid == -1 ) {
perror( "semget" );
exit( 0 );
}
if ( Shm_Is_master_node() ) {
for ( i=0 ; i <= maximum_nodes ; i++ ) {
sb.sem_op = 1;
sb.sem_num = i;
sb.sem_flg = 0;
status = semop( semid, &sb, 1 );
if ( status == -1 ) {
fprintf( stderr, "Sem init failed %d\n", errno ); fflush( stderr );
exit( 0 );
}
}
}
BSP_shm_cfgtbl.base = (vol_u32 *)shm_addr;
BSP_shm_cfgtbl.length = 16 * KILOBYTE;
BSP_shm_cfgtbl.format = SHM_BIG;
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt_unix;
#ifdef NEUTRAL_BIG
BSP_shm_cfgtbl.convert = NULL_CONVERT;
#else
BSP_shm_cfgtbl.convert = CPU_swap_u32;
#endif
#if ( POLLING == 1 )
BSP_shm_cfgtbl.poll_intr = POLLED_MODE;
BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT;
#else
BSP_shm_cfgtbl.poll_intr = INTR_MODE;
BSP_shm_cfgtbl.Intr.address = 0; /* process id? */
BSP_shm_cfgtbl.Intr.value = 0; /* signal to send? */
BSP_shm_cfgtbl.Intr.length = LONG;
#endif
*shmcfg = &BSP_shm_cfgtbl;
}

View File

@@ -0,0 +1,31 @@
/* void Shm_interrupt_unix( node )
*
* This routine is the shared memory driver routine which
* generates interrupts to other CPUs.
*
* Input parameters:
* node - destination of this packet (0 = broadcast)
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <shm.h>
#include <stdio.h>
void Shm_Cause_interrupt_unix(
rtems_unsigned32 node
)
{
}

View File

@@ -0,0 +1,117 @@
/* Shared Memory Lock Routines
*
* This shared memory locked queue support routine need to be
* able to lock the specified locked queue. Interrupts are
* disabled while the queue is locked to prevent preemption
* and deadlock when two tasks poll for the same lock.
* previous level.
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
extern int semid;
/*
* Shm_Initialize_lock
*
* Initialize the lock for the specified locked queue.
*/
void Shm_Initialize_lock(
Shm_Locked_queue_Control *lq_cb
)
{
lq_cb->lock =
( lq_cb - Shm_Locked_queues ) / sizeof( Shm_Locked_queue_Control );
}
/* Shm_Lock( &lq_cb )
*
* This shared memory locked queue support routine locks the
* specified locked queue. It disables interrupts to prevent
* a deadlock condition.
*/
void Shm_Lock(
Shm_Locked_queue_Control *lq_cb
)
{
rtems_unsigned32 isr_level;
struct sembuf sb;
int status;
isr_level = 0;
sb.sem_num = lq_cb->lock;
sb.sem_op = -1;
sb.sem_flg = 0;
rtems_interrupt_disable( isr_level );
Shm_isrstat = isr_level;
while (1) {
status = semop(semid, &sb, 1);
if ( status == 0 )
break;
if ( status == -1 && errno == EINTR )
continue;
fprintf( stderr, "shm lock (%d %d)\n", status, errno );
exit( 0 );
}
}
/*
* Shm_Unlock
*
* Unlock the lock for the specified locked queue.
*/
void Shm_Unlock(
Shm_Locked_queue_Control *lq_cb
)
{
rtems_unsigned32 isr_level;
struct sembuf sb;
int status;
isr_level = 0;
sb.sem_num = lq_cb->lock;
sb.sem_op = 1;
sb.sem_flg = 0;
while (1) {
status = semop(semid, &sb, 1);
if ( status == 0 )
break;
if ( status == -1 && errno == EINTR )
continue;
fprintf( stderr, "shm lock (%d %d)\n", status, errno ); fflush( stderr );
exit( 0 );
}
isr_level = Shm_isrstat;
rtems_interrupt_enable( isr_level );
}

View File

@@ -0,0 +1,29 @@
/* Shm_setvec
*
* This driver routine sets the SHM interrupt vector to point to the
* driver's SHM interrupt service routine.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
void Shm_setvec( void )
{
set_vector( Shm_isr, INTERRUPT_EXTERNAL_MPCI, 1 );
}

View File

@@ -0,0 +1,37 @@
/* bsp_cleanup()
*
* This routine normally is part of start.s and returns
* control to a monitor but on the UNIX simulator
* we do that directly from main.c.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
/*
* The app has "exited" (called rtems_shutdown_executive)
*/
void bsp_cleanup( void )
{
/*
* Invoke any fatal error extension and "halt"
* By definition, rtems_fatal_error_occurred does not return.
*/
rtems_fatal_error_occurred(0);
}

View File

@@ -0,0 +1,314 @@
/*
* @(#)bspstart.c 1.7 - 95/04/07
*
*/
/* bsp_start()
*
* This routine starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before this routine is invoked.
*
* Called by RTEMS::RTEMS constructor in startup-ctor.cc
*
* INPUT: NONE
*
* OUTPUT: NONE
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <bsp.h>
#include <libcsupport.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
#endif
extern rtems_configuration_table Configuration;
/*
* A copy of the configuration table from the application
* with some changes applied to it.
*/
rtems_configuration_table BSP_Configuration;
rtems_multiprocessing_table BSP_Multiprocessing;
rtems_cpu_table Cpu_table;
rtems_unsigned32 bsp_isr_level;
rtems_unsigned32 Heap_size;
int rtems_argc;
char **rtems_argv;
char **rtems_envp;
#define WORKSPACE_SIZE (WORKSPACE_MB * (1024 * 1024))
#define HEAPSPACE_SIZE (HEAPSPACE_MB * (1024 * 1024))
rtems_unsigned8 MY_WORK_SPACE[ WORKSPACE_SIZE ] CPU_STRUCTURE_ALIGNMENT;
/*
* Amount to increment itimer by each pass
* It is a variable instead of a #define to allow the 'looptest'
* script to bump it without recompiling rtems
*/
rtems_unsigned32 CPU_CLICKS_PER_TICK;
/*
* Function: bsp_libc_init
* Created: 94/12/6
*
* Description:
* Initialize whatever libc we are using
* called from bsp_postdriver_hook
*
*
* Parameters:
* none
*
* Returns:
* none.
*
* Side Effects:
*
*
* Notes:
*
* Deficiencies/ToDo:
*
*
*/
void
bsp_libc_init(void)
{
void *heap_start;
Heap_size = HEAPSPACE_SIZE;
heap_start = 0;
RTEMS_Malloc_Initialize((void *)heap_start, Heap_size, 1024 * 1024);
libc_init(1);
}
/*
* Function: bsp_pretasking_hook
* Created: 95/03/10
*
* Description:
* BSP pretasking hook. Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*
* Parameters:
* none
*
* Returns:
* nada
*
* Side Effects:
* installs a few extensions
*
* Notes:
* Must not use libc (to do io) from here, since drivers are
* not yet initialized.
*
* Deficiencies/ToDo:
*
*
*/
void
bsp_pretasking_hook(void)
{
bsp_libc_init();
#ifdef STACK_CHECKER_ON
/*
* Initialize the stack bounds checker
* We can either turn it on here or from the app.
*/
Stack_check_Initialize();
#endif
#ifdef RTEMS_DEBUG
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif
}
/*
* Function: bsp_start
* Created: 94/12/6
*
* Description:
* called by crt0 as our "main" equivalent
*
*
*
* Parameters:
*
*
* Returns:
*
*
* Side Effects:
*
*
* Notes:
*
*
* Deficiencies/ToDo:
*
*
*/
void
bsp_start(void)
{
struct stat stat_buf;
char buf[256];
char node[6];
char *home;
int fd;
/*
* Copy the table
*/
BSP_Configuration = Configuration;
/*
* If the node number is -1 then the application better provide
* it through the file $HOME/rtems_node
*/
BSP_Multiprocessing.node = -1;
if (BSP_Configuration.User_multiprocessing_table) {
if (BSP_Configuration.User_multiprocessing_table->node == -1) {
home = getenv("HOME");
sprintf(buf, "%s/%s", home, "rtems_node");
if ((stat(buf, &stat_buf)) == 0) {
fd = open(buf, O_RDONLY);
read(fd, node, 5);
close(fd);
unlink(buf);
BSP_Multiprocessing = *BSP_Configuration.User_multiprocessing_table;
BSP_Multiprocessing.node = atoi(node);
BSP_Configuration.User_multiprocessing_table = &BSP_Multiprocessing;
}
if (BSP_Configuration.User_multiprocessing_table->maximum_nodes == -1) {
home = getenv("HOME");
sprintf(buf, "%s/%s", home, "rtems_max_node");
if ((stat(buf, &stat_buf)) == 0) {
fd = open(buf, O_RDONLY);
read(fd, node, 5);
close(fd);
BSP_Multiprocessing.maximum_nodes = atoi(node);
}
}
}
}
/*
* Set cpu_number to accurately reflect our cpu number
*/
if (BSP_Configuration.User_multiprocessing_table)
cpu_number = BSP_Configuration.User_multiprocessing_table->node - 1;
else
cpu_number = 0;
BSP_Configuration.work_space_start = (void *)MY_WORK_SPACE;
if (BSP_Configuration.work_space_size)
BSP_Configuration.work_space_size = WORKSPACE_SIZE;
/*
* Set up our hooks
* Make sure libc_init is done before drivers init'd so that
* they can use atexit()
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.predriver_hook = NULL;
Cpu_table.postdriver_hook = NULL;
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
/*
* Don't zero out the workspace since it is in the BSS under UNIX.
*/
Cpu_table.do_zero_of_workspace = FALSE;
/*
* XXX; interrupt stack not currently used, so this doesn't matter
*/
Cpu_table.interrupt_stack_size = (12 * 1024);
Cpu_table.extra_system_initialization_stack = 0;
/*
* Add 1 region for RTEMS Malloc
*/
BSP_Configuration.maximum_regions++;
#ifdef RTEMS_NEWLIB
/*
* Add 1 extension for newlib libc
*/
BSP_Configuration.maximum_extensions++;
#endif
#ifdef STACK_CHECKER_ON
/*
* Add 1 extension for stack checker
*/
BSP_Configuration.maximum_extensions++;
#endif
/*
* Add 1 extension for MPCI_fatal
*/
if (BSP_Configuration.User_multiprocessing_table)
BSP_Configuration.maximum_extensions++;
CPU_CLICKS_PER_TICK = 1;
/*
* Start most of RTEMS
* main() will start the rest
*/
bsp_isr_level = rtems_initialize_executive_early(
&BSP_Configuration,
&Cpu_table
);
}

View File

@@ -0,0 +1,28 @@
/*
* exit
*
* This routine returns control to "the pre-RTEMS environment".
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <clockdrv.h>
void _exit( void )
{
/* Clock or Timer cleanup is run by at_exit() */
Io_cleanup();
bsp_cleanup();
}

View File

@@ -0,0 +1,108 @@
// @(#)rtems-ctor.cc 1.6 - 95/04/25
//
//
/*
* rtems-ctor.cc
*
* Description:
* This file exists solely to (try to) ensure RTEMS is initialized
* before any global constructors are run.
*
* The problem:
* Global constructors might reasonably expect that new() will
* work, but since new() uses malloc() which uses RTEMS regions,
* it can not be called until after initialize_executive().
*
* Global constructors are called in GNU systems one of 2 ways:
*
* an "invisible" call to __main() inserted by compiler
* This __main() calls __do_global_ctors() which
* walks thru the table and calls all global
* constructors.
*
* or -
* A special section is put into the linked binary. The
* system startup code knows to run the constructors in
* this special section before calling main().
*
* By making RTEMS initialization a constructor, we avoid having
* too much about all this. All we have to guarantee is that
* this constructor is the first one run.
*
*
* So for the first case above, this is what happens
*
* host crt0
* main()
* __main()
* __do_global_ctors()
* bsp_start()
* init_executive_early()
* <<any other constructors>>
*
* init_executive_late()
* bsp_cleanup()
*
* TODO:
*
*/
#include <bsp.h>
/*
* RTEMS program name
* Probably not used by anyone, but it is nice to have it.
* Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably
* need to use it
*/
char *rtems_progname;
class RTEMS {
public:
RTEMS();
~RTEMS();
};
RTEMS rtems_constructor;
RTEMS::RTEMS()
{
bsp_start();
}
RTEMS::~RTEMS()
{
bsp_cleanup();
}
extern "C" {
int
main(int argc,
char **argv,
char **environp)
{
rtems_argc = argc;
rtems_argv = argv;
rtems_envp = environp;
if ((argc > 0) && argv && argv[0])
rtems_progname = argv[0];
else
rtems_progname = "RTEMS";
/*
* Start multitasking
*/
rtems_initialize_executive_late( bsp_isr_level );
/*
* Returns when multitasking is stopped
* This allows our destructors to get run normally
*/
return 0;
}
}

View File

@@ -0,0 +1,60 @@
/* set_vector
*
* This routine installs an interrupt vector on UNIX.
*
* INPUT:
* handler - interrupt handler entry point
* vector - vector number
* type - 0 indicates raw hardware connect
* 1 indicates RTEMS interrupt connect
*
* NOTE 'type' is ignored on hppa; all interrupts are owned by RTEMS
*
* RETURNS:
* address of previous interrupt handler
*
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* This material may be reproduced by or for the U.S. Government pursuant
* to the copyright license under the clause at DFARS 252.227-7013. This
* notice must appear in all copies of this file and its derivatives.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
/*
* Install an interrupt handler in the right place
* given its vector number from cpu/hppa.h
* There are 2 places an interrupt can be installed
* _ISR_Vector_table
* bsp interrupt XXX: nyi
*
* We decide which based on the vector number
*/
unix_isr_entry
set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
)
{
rtems_isr_entry rtems_isr_ptr;
proc_ptr raw_isr_ptr;
if ( type ) {
rtems_interrupt_catch( handler, vector, &rtems_isr_ptr );
return (unix_isr_entry) rtems_isr_ptr;
} else {
_CPU_ISR_install_vector( vector, (proc_ptr) handler, &raw_isr_ptr );
return (unix_isr_entry) raw_isr_ptr;
}
}

View File

@@ -282,7 +282,7 @@ exit(int status)
*
*/
#ifndef RTEMS_UNIX
#if !defined(RTEMS_UNIX) && !defined(__GO32__)
void _exit(int status)
{
rtems_shutdown_executive(status);

View File

@@ -16,10 +16,10 @@
* TODO:
*/
#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems.h>
#include "symbols.h"