diff options
Diffstat (limited to 'c/src/lib/libbsp/i386')
-rw-r--r-- | c/src/lib/libbsp/i386/force386/clock/ckinit.c | 108 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/force386/console/console.c | 149 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/force386/include/bsp.h | 20 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/force386/startup/bspstart.c | 59 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/clock/ckinit.c | 182 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/console/console.c | 189 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/include/bsp.h | 29 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/startup/bspstart.c | 165 |
8 files changed, 666 insertions, 235 deletions
diff --git a/c/src/lib/libbsp/i386/force386/clock/ckinit.c b/c/src/lib/libbsp/i386/force386/clock/ckinit.c index 45400dbd49..45a64f6f14 100644 --- a/c/src/lib/libbsp/i386/force386/clock/ckinit.c +++ b/c/src/lib/libbsp/i386/force386/clock/ckinit.c @@ -19,33 +19,44 @@ */ #include <bsp.h> -#include <clockdrv.h> + +#include <rtems/libio.h> + #include <stdlib.h> -volatile rtems_unsigned32 Clock_driver_ticks; +#define CLOCK_VECTOR 0x38 + rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ + +volatile rtems_unsigned32 Clock_driver_ticks; + 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 Clock_exit( void ); + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_major_number rtems_clock_minor = 0; -void ReInstall_clock( - rtems_isr_entry clock_isr +/* + * This is the ISR handler. + */ + +rtems_isr Clock_isr( + rtems_vector_number vector ) { - rtems_unsigned32 isrlevel = 0; - - rtems_interrupt_disable( isrlevel ); - (void) set_vector( clock_isr, 0x38, 1 ); - rtems_interrupt_enable( isrlevel ); + /* enable_tracing(); */ + Clock_driver_ticks += 1; + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + } + else + Clock_isrs -= 1; } void Install_clock( @@ -56,7 +67,7 @@ void Install_clock( Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; if ( BSP_Configuration.ticks_per_timeslice ) { - Old_ticker = ( rtems_isr_entry ) set_vector( clock_isr, 0x38, 1 ); + Old_ticker = ( rtems_isr_entry ) set_vector( clock_isr, CLOCK_VECTOR, 1 ); outport_byte( TBCR, 0x14 ); /* reset it, delay mode, 50X */ outport_byte( TBDR, 0x50 ); /* 1 millisecond */ outport_byte( IERA, 0x41 ); /* enable interrupt for B */ @@ -64,6 +75,17 @@ void Install_clock( atexit( Clock_exit ); } +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + void Clock_exit( void ) { if ( BSP_Configuration.ticks_per_timeslice ) { @@ -73,3 +95,49 @@ void Clock_exit( void ) } } +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Install_clock( Clock_isr ); + + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver Clock_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr(CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + ReInstall_clock(args->buffer); + } + +done: + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/i386/force386/console/console.c b/c/src/lib/libbsp/i386/force386/console/console.c index f1f019c487..2b68f329c0 100644 --- a/c/src/lib/libbsp/i386/force386/console/console.c +++ b/c/src/lib/libbsp/i386/force386/console/console.c @@ -14,11 +14,10 @@ #define F386_INIT -#include <stdlib.h> +#include <bsp.h> +#include <rtems/libio.h> -#include <rtems.h> -#include "console.h" -#include "bsp.h" +#include <stdlib.h> /* console_cleanup * @@ -61,18 +60,29 @@ void console_cleanup( void ) rtems_device_driver console_initialize( rtems_device_major_number major, rtems_device_minor_number minor, - void *arg, - rtems_id self, - rtems_unsigned32 *status + void *arg ) { - /* - * flush the console now and at exit. Just in case. - */ + rtems_status_code status; + + /* + * flush the console now and at exit. Just in case. + */ + + console_cleanup(); + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); - console_cleanup(); + atexit( console_cleanup ); - atexit( console_cleanup ); + return RTEMS_SUCCESSFUL; } @@ -172,48 +182,103 @@ void outbyte( } /* - * __read -- read bytes from the serial port. Ignore fd, since - * we only have stdin. + * Open entry point */ - -int __read( - int fd, - char *buf, - int nbytes + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) { - int i = 0; + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} - for (i = 0; i < nbytes; i++) { - *(buf + i) = inbyte(); - if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { - (*(buf + i++)) = '\n'; - (*(buf + i)) = 0; +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + buffer[ count ] = 0; break; } } - return (i); + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; } - + /* - * __write -- write bytes to the serial port. Ignore fd, since - * stdout and stderr are the same. Since we have no filesystem, - * open will only return an error. + * write bytes to the serial port. Stdout and stderr are the same. */ - -int __write( - int fd, - char *buf, - int nbytes + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) { - int i; - - for (i = 0; i < nbytes; i++) { - if (*(buf + i) == '\n') { - outbyte ('\r'); + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); } - outbyte (*(buf + i)); + outbyte( buffer[ count ] ); } - return (nbytes); + return maximum; } + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + diff --git a/c/src/lib/libbsp/i386/force386/include/bsp.h b/c/src/lib/libbsp/i386/force386/include/bsp.h index cc8fb2d3ba..c6c553e454 100644 --- a/c/src/lib/libbsp/i386/force386/include/bsp.h +++ b/c/src/lib/libbsp/i386/force386/include/bsp.h @@ -22,6 +22,8 @@ extern "C" { #include <rtems.h> #include <iosupp.h> +#include <console.h> +#include <clockdrv.h> /* * Define the time limits for RTEMS Test Suite test durations. @@ -128,6 +130,24 @@ extern "C" { #define BSP_EXTERN extern #endif +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + /* miscellaneous stuff assumed to exist */ extern rtems_configuration_table BSP_Configuration; diff --git a/c/src/lib/libbsp/i386/force386/startup/bspstart.c b/c/src/lib/libbsp/i386/force386/startup/bspstart.c index 78def6375c..19cb28e450 100644 --- a/c/src/lib/libbsp/i386/force386/startup/bspstart.c +++ b/c/src/lib/libbsp/i386/force386/startup/bspstart.c @@ -20,11 +20,16 @@ * $Id$ */ -#include <rtems.h> #include <bsp.h> +#include <rtems/libio.h> + #include <libcsupport.h> +#include <fcntl.h> + +#ifdef STACK_CHECKER_ON #include <stackchk.h> +#endif /* * The original table from the application and our copy of it with @@ -36,6 +41,8 @@ rtems_configuration_table BSP_Configuration; rtems_cpu_table Cpu_table; +char *rtems_progname; + /* Initialize whatever libc we are using * called from postdriver hook */ @@ -52,6 +59,14 @@ void bsp_libc_init() RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); /* + * Init the RTEMS libio facility to provide UNIX-like system + * calls for use by newlib (ie: provide __open, __close, etc) + * Uses malloc() to get area for the iops, so must be after malloc init + */ + + rtems_libio_init(); + + /* * Set up for the libc handling. */ @@ -70,12 +85,44 @@ void bsp_libc_init() } -int bsp_start( +/* + * After drivers are setup, register some "filenames" + * and open stdin, stdout, stderr files + * + * Newlib will automatically associate the files with these + * (it hardcodes the numbers) + */ + +void +bsp_postdriver_hook(void) +{ + int stdin_fd, stdout_fd, stderr_fd; + + if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1) + rtems_fatal_error_occurred('STD0'); + + if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD1'); + + if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD2'); + + if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2)) + rtems_fatal_error_occurred('STIO'); +} + +int main( int argc, char **argv, char **environp ) { + + if ((argc > 0) && argv && argv[0]) + rtems_progname = argv[0]; + else + rtems_progname = "RTEMS"; + /* * FORCE documentation incorrectly states that the bus request * level is initialized to 3. It is actually initialized by @@ -92,7 +139,7 @@ int bsp_start( Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ - Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; Cpu_table.idle_task = NULL; /* do not override system IDLE task */ @@ -137,6 +184,12 @@ int bsp_start( BSP_Configuration.maximum_extensions++; #endif + /* + * Tell libio how many fd's we want and allow it to tweak config + */ + + rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS); + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); /* does not return */ /* no cleanup necessary for Force CPU-386 */ diff --git a/c/src/lib/libbsp/i386/go32/clock/ckinit.c b/c/src/lib/libbsp/i386/go32/clock/ckinit.c index 5ac1c10d98..fa6a8bf057 100644 --- a/c/src/lib/libbsp/i386/go32/clock/ckinit.c +++ b/c/src/lib/libbsp/i386/go32/clock/ckinit.c @@ -11,67 +11,81 @@ */ #include <bsp.h> -#include <clockdrv.h> +#include <rtems/libio.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_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 ); -} +#define CLOCK_VECTOR 0x8 -void ReInstall_clock( - rtems_isr_entry clock_isr +void Clock_exit( void ); + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +rtems_isr Clock_isr( + rtems_vector_number vector ) { - rtems_unsigned32 isrlevel = 0; + /* touch interrupt controller for irq0 (0x20+0) */ + outport_byte( 0x20, 0x20 ); - rtems_interrupt_disable( isrlevel ); - (void) set_vector( clock_isr, 0x8, 1 ); - rtems_interrupt_enable( isrlevel ); + Clock_driver_ticks += 1; + +#if 0 && defined(pentium) + { + extern long long Last_RDTSC; + __asm __volatile( ".byte 0x0F, 0x31" : "=A" (Last_RDTSC) ); + } +#endif + + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = Clock_isrs_per_tick; + } else { + Clock_isrs -= 1; + } } void Install_clock( rtems_isr_entry clock_isr ) { - unsigned int microseconds_per_isr; + unsigned int microseconds_per_isr; #if 0 - /* Initialize clock from on-board real time clock. This breaks the */ + /* 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 ); - } + 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. */ + /* 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 */ + microseconds_per_isr = 10000; /* default 10 ms */ else - microseconds_per_isr = BSP_Configuration.microseconds_per_tick; + 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; + Clock_isrs_per_tick *= 10; + microseconds_per_isr /= 10; } /* Initialize count in ckisr.c */ @@ -83,43 +97,101 @@ void Install_clock( #endif if ( BSP_Configuration.ticks_per_timeslice ) { - /* 105/88 approximates TIMER_TICK*1e-6 */ - unsigned int count = US_TO_TICK( microseconds_per_isr ); + /* 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 ); + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 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 ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + 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 ); + 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, CLOCK_VECTOR, 1 ); } } +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Install_clock( Clock_isr ); + + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver Clock_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr(CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + ReInstall_clock(args->buffer); + } + +done: + return RTEMS_SUCCESSFUL; +} #if 0 && defined(pentium) -/* This can be used to get extremely accurate timing on a pentium. */ -/* It isn't supported. [bryce] */ +/* 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; @@ -128,7 +200,7 @@ long long Kernel_Time_ns( void ) int flags; disable_intr( flags ); now = 1e9 * Clock_driver_ticks / isrs_per_second - + (RDTSC() - Last_RDTSC) * (1000.0/HZ); + + (RDTSC() - Last_RDTSC) * (1000.0/HZ); enable_intr( flags ); return now; } diff --git a/c/src/lib/libbsp/i386/go32/console/console.c b/c/src/lib/libbsp/i386/go32/console/console.c index d7e5641e22..3265f46de0 100644 --- a/c/src/lib/libbsp/i386/go32/console/console.c +++ b/c/src/lib/libbsp/i386/go32/console/console.c @@ -8,9 +8,8 @@ #include <stdlib.h> -#include <rtems.h> -#include "console.h" -#include "bsp.h" +#include <bsp.h> +#include <rtems/libio.h> #include <dpmi.h> #include <go32.h> @@ -42,40 +41,55 @@ void console_cleanup( void ) * 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; +/* Set this if console I/O should use go32 (DOS) read/write calls. */ +/* Otherwise, direct hardware accesses will be used. */ -static rtems_isr_entry old_keyboard_isr = NULL; -extern void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt ); +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 + void *arg ) { - 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 ); - } + rtems_status_code 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 ); + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + atexit( console_cleanup ); + + return RTEMS_SUCCESSFUL; } @@ -117,7 +131,7 @@ char inbyte( void ) void outbyte( char ch ); outbyte( ch ); if ( ch == '\r' ) - outbyte( '\n' ); + outbyte( '\n' ); #endif return ch; } @@ -138,49 +152,104 @@ void outbyte( char ch ) } /* - * __read -- read bytes from the console. Ignore fd, since - * we only have stdin. + * Open entry point */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} -int __read( - int fd, - char *buf, - int nbytes +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) { - 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 RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + /* What if this goes past the end of the buffer? We're hosed. [bhc] */ + buffer[ count++ ] = '\n'; + buffer[ count ] = 0; + break; } } - return i; + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; } - + /* - * __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. + * write bytes to the serial port. Stdout and stderr are the same. */ - -int __write( - int fd, - char *buf, - int nbytes + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) { - int i; - - for (i = 0; i < nbytes; i++) { - if (*(buf + i) == '\n') { - outbyte ('\r'); + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); } - outbyte (*(buf + i)); + outbyte( buffer[ count ] ); } - return (nbytes); + return maximum; } + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + diff --git a/c/src/lib/libbsp/i386/go32/include/bsp.h b/c/src/lib/libbsp/i386/go32/include/bsp.h index a41d57dc77..5bafd27bd4 100644 --- a/c/src/lib/libbsp/i386/go32/include/bsp.h +++ b/c/src/lib/libbsp/i386/go32/include/bsp.h @@ -22,6 +22,8 @@ extern "C" { #include <rtems.h> #include <iosupp.h> +#include <console.h> +#include <clockdrv.h> /* * Define the time limits for RTEMS Test Suite test durations. @@ -124,6 +126,24 @@ extern "C" { #define BSP_EXTERN extern #endif +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + /* functions */ int _IBMPC_chrdy( char * ch ); @@ -134,15 +154,6 @@ void _IBMPC_outch( unsigned char ); 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_entry set_vector( diff --git a/c/src/lib/libbsp/i386/go32/startup/bspstart.c b/c/src/lib/libbsp/i386/go32/startup/bspstart.c index 21594766ad..940c04270a 100644 --- a/c/src/lib/libbsp/i386/go32/startup/bspstart.c +++ b/c/src/lib/libbsp/i386/go32/startup/bspstart.c @@ -20,11 +20,18 @@ * $Id$ */ -#include <rtems.h> #include <bsp.h> +#include <rtems/libio.h> + #include <libcsupport.h> - +#include <z8036.h> + +#include <string.h> +#include <fcntl.h> + +#ifdef STACK_CHECKER_ON #include <stackchk.h> +#endif /* * The original table from the application and our copy of it with @@ -36,6 +43,8 @@ rtems_configuration_table BSP_Configuration; rtems_cpu_table Cpu_table; +char *rtems_progname; + /* Initialize whatever libc we are using * called from postdriver hook */ @@ -57,6 +66,14 @@ void bsp_libc_init() RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); /* + * Init the RTEMS libio facility to provide UNIX-like system + * calls for use by newlib (ie: provide __open, __close, etc) + * Uses malloc() to get area for the iops, so must be after malloc init + */ + + rtems_libio_init(); + + /* * Set up for the libc handling. */ @@ -74,60 +91,116 @@ void bsp_libc_init() #endif } - -void bsp_start() + +/* + * After drivers are setup, register some "filenames" + * and open stdin, stdout, stderr files + * + * Newlib will automatically associate the files with these + * (it hardcodes the numbers) + */ + +void +bsp_postdriver_hook(void) { - 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 - */ + int stdin_fd, stdout_fd, stderr_fd; + + if ((stdin_fd = __open("/dev/console", O_RDONLY, 0)) == -1) + rtems_fatal_error_occurred('STD0'); + + if ((stdout_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD1'); + + if ((stderr_fd = __open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred('STD2'); + + if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2)) + rtems_fatal_error_occurred('STIO'); +} - BSP_Configuration.maximum_regions++; +/* This is the original command line passed from DOS */ +char ** Go32_Argv; - /* - * Add 1 extension for newlib libc - */ +int main( + int argc, + char **argv, + char **environp +) +{ + extern void * sbrk( int ); + extern volatile void _exit( int ); + + /* Set up arguments that we can access later */ + Go32_Argv = argv; + + if ((argc > 0) && argv && argv[0]) + rtems_progname = argv[0]; + else + rtems_progname = "RTEMS"; + + Cpu_table.pretasking_hook = NULL; + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; + 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 ); + 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++; + BSP_Configuration.maximum_extensions++; #endif - /* - * Add another extension if using the stack checker - */ + /* + * Add another extension if using the stack checker + */ #ifdef STACK_CHECKER_ON - BSP_Configuration.maximum_extensions++; + BSP_Configuration.maximum_extensions++; #endif - rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); - /* does not return */ + /* + * Tell libio how many fd's we want and allow it to tweak config + */ + + rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS); + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + /* We only return here if the executive has finished. This happens */ + /* when the task has called exit(). */ + /* At this point we call _exit() which resides in djgcc. */ + + for (;;) + _exit( 0 ); + + /* no cleanup necessary for GO32 */ - /* no cleanup necessary for GO32 */ + return 0; } |