From 5d18fb057a9158336a79953b88d481c74c6eb0ae Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sat, 27 Jun 1998 18:51:49 +0000 Subject: PC386 BSP enhancements from Aleksey Romanov (Quality Quorum ). Unfortunately after merging these, the pc386 will not boot using grub for for. It still does not work using netboot for me. Here is his summary of changes: rtems/c/src/lib/libbsp/i386/pc386/Makefile.in Added support for new sub-directory rtems/c/src/lib/libbsp/i386/pc386/bsp_specs Made possible to build COFF image rtems/c/src/lib/libbsp/i386/pc386/console/console.c Added support for serial consoles, selectable by patching binary image, added __assert(), use _IBMPC_inch_sleep() instaed of _IMBPC_inch() rtems/c/src/lib/libbsp/i386/pc386/console/inch.c Added _IMBPC_inch_sleep() rtems/c/src/lib/libbsp/i386/pc386/console/outch.c Oops - just formatting rtems/c/src/lib/libbsp/i386/pc386/include/Makefile.in Added support for new files rtems/c/src/lib/libbsp/i386/pc386/include/bsp.h Added support for new features rtems/c/src/lib/libbsp/i386/pc386/include/pc386uart.h New file: definitions for serial ports rtems/c/src/lib/libbsp/i386/pc386/include/pcibios.h New file: definitions for PCI BIOS rtems/c/src/lib/libbsp/i386/pc386/pc386dev/Makefile.in New file: makefile in new directory rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub-glue.c New file: i386-stub interface rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub.c New file: i386-stub itself rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pc386uart.c New file: serial ports rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pcibios.c New file: PCI BIOS support rtems/c/src/lib/libbsp/i386/pc386/start/start.s Commented out DEBUG_EARLY stuff, everything is working fine rtems/c/src/lib/libbsp/i386/pc386/start/start16.s Cleaned up rtems/c/src/lib/libbsp/i386/pc386/startup/bspstart.c Added call to console_resereve_resources rtems/c/src/lib/libbsp/i386/pc386/startup/exit.c Added support for serial console rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s Fixed typo in comments rtems/c/src/lib/libbsp/i386/pc386/tools/Makefile.in Changed to reflect cnages in code rtems/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c Trivialized, problem - I do not know how to make patch remove obsolete files - there are a lot of them there rtems/c/src/lib/libbsp/i386/pc386/tools/binpatch.c New file: utility to do binary patches rtems/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in Added support for new directory rtems/make/custom/pc386.cfg Add COFF image building --- c/src/lib/libbsp/i386/pc386/console/console.c | 346 +++++++++++++++++++------- c/src/lib/libbsp/i386/pc386/console/inch.c | 44 +++- c/src/lib/libbsp/i386/pc386/console/outch.c | 14 +- 3 files changed, 298 insertions(+), 106 deletions(-) (limited to 'c/src/lib/libbsp/i386/pc386/console') diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c index 1689f5c546..8698ea8136 100644 --- a/c/src/lib/libbsp/i386/pc386/console/console.c +++ b/c/src/lib/libbsp/i386/pc386/console/console.c @@ -33,10 +33,17 @@ #include +#include #include #include #include +#include +#include + +int PC386ConsolePort = PC386_CONSOLE_PORT_CONSOLE; + +static int conSetAttr(int minor, const struct termios *); /*-------------------------------------------------------------------------+ | Constants @@ -51,74 +58,25 @@ extern rtems_isr _IBMPC_keyboard_isr(rtems_vector_number); /* keyboard (IRQ 0x01) Interrupt Service Routine (defined in 'inch.c') */ -/*-------------------------------------------------------------------------+ -| Functions -+--------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------+ -| Function: console_cleanup -| Description: This routine is called at exit to clean up the console -| hardware. -| Global Variables: None. -| Arguments: None. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -void -console_cleanup(void) +void console_reserve_resources(rtems_configuration_table *conf) { - /* nothing */ -} /* console_cleanup */ - - -/*-------------------------------------------------------------------------+ -| Function: is_character_ready -| Description: Check if a character is available for input, and if so -| return it. -| Global Variables: None. -| Arguments: c - character read if available, otherwise unchanged. -| Returns: TRUE if there was a character available for input, -| FALSE otherwise. -+--------------------------------------------------------------------------*/ -rtems_boolean -is_character_ready(char *c) -{ - return (_IBMPC_chrdy(c) ? TRUE : FALSE); -} /* is_character_ready */ - + if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE) + { + rtems_termios_reserve_resources(conf, 1); + } + return; +} -/*-------------------------------------------------------------------------+ -| Function: inbyte -| Description: Read a character from the console (keyboard). -| Global Variables: None. -| Arguments: None. -| Returns: Caracter read from the console. -+--------------------------------------------------------------------------*/ -unsigned char -inbyte(void) +void __assert(const char *file, int line, const char *msg) { - char c = _IBMPC_inch(); - - /* Echo character to screen */ - _IBMPC_outch(c); - if (c == '\r') - _IBMPC_outch('\n'); /* CR = CR + LF */ + printk("assert failed: %s: ", file); + printk("%d: ", line); + printk("%s\n", msg); - return c; -} /* inbyte */ - - -/*-------------------------------------------------------------------------+ -| Function: outbyte -| Description: Write a character to the console (display). -| Global Variables: None. -| Arguments: Character to be written. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -void -outbyte(char c) -{ - _IBMPC_outch(c); -} /* outbyte */ + exit(1); + return; +} /*-------------------------------------------------------------------------+ | Console device driver INITIALIZE entry point. @@ -135,26 +93,74 @@ console_initialize(rtems_device_major_number major, /* Initialize video */ _IBMPC_initVideo(); - /* Install keyboard interrupt handler */ - status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr); - - if (status != RTEMS_SUCCESSFUL) - { - printk("Error installing keyboard interrupt handler!\n"); - rtems_fatal_error_occurred(status); - } + if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE) + { - status = - rtems_io_register_name("/dev/console", major, (rtems_device_minor_number)0); - - if (status != RTEMS_SUCCESSFUL) - { - printk("Error registering console device!\n"); - rtems_fatal_error_occurred(status); - } + /* Install keyboard interrupt handler */ + status = PC386_installRtemsIrqHandler(KEYBOARD_IRQ, _IBMPC_keyboard_isr); + + if (status != RTEMS_SUCCESSFUL) + { + printk("Error installing keyboard interrupt handler!\n"); + rtems_fatal_error_occurred(status); + } + + status = rtems_io_register_name("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + { + printk("Error registering console device!\n"); + rtems_fatal_error_occurred(status); + } + printk("Initialized console on port CONSOLE\n\n"); + } + else + { + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + + /* 9600-8-N-1 */ + PC386_uart_init(PC386ConsolePort, 9600, 0); + + + /* Set interrupt handler */ + if(PC386ConsolePort == PC386_UART_COM1) + { + status = PC386_installRtemsIrqHandler(PC386_UART_COM1_IRQ, + PC386_uart_termios_isr_com1); + } + else + { + assert(PC386ConsolePort == PC386_UART_COM2); + + status = PC386_installRtemsIrqHandler(PC386_UART_COM2_IRQ, + PC386_uart_termios_isr_com2); + } + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + { + printk("Error registering console device!\n"); + rtems_fatal_error_occurred (status); + } + + if(PC386ConsolePort == PC386_UART_COM1) + { + printk("Initialized console on port COM1 9600-8-N-1\n\n"); + } + else + { + printk("Initialized console on port COM2 9600-8-N-1\n\n"); + } + } - atexit(console_cleanup); - return RTEMS_SUCCESSFUL; } /* console_initialize */ @@ -164,12 +170,51 @@ console_initialize(rtems_device_major_number major, +--------------------------------------------------------------------------*/ rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) + rtems_device_minor_number minor, + void *arg) { - return RTEMS_SUCCESSFUL; -} /* console_open */ + rtems_status_code status; + static rtems_termios_callbacks cb = + { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + PC386_uart_termios_write_com1, /* write */ + conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + + if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE) + { + return RTEMS_SUCCESSFUL; + } + if(PC386ConsolePort == PC386_UART_COM2) + { + cb.write = PC386_uart_termios_write_com2; + } + + status = rtems_termios_open (major, minor, arg, &cb); + + if(status != RTEMS_SUCCESSFUL) + { + printk("Error openning console device\n"); + return status; + } + + /* + * Pass data area info down to driver + */ + PC386_uart_termios_set(PC386ConsolePort, + ((rtems_libio_open_close_args_t *)arg)->iop->data1); + + /* Enable interrupts on channel */ + PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_TERMIOS); + + return RTEMS_SUCCESSFUL; +} /*-------------------------------------------------------------------------+ | Console device driver CLOSE entry point @@ -179,6 +224,11 @@ console_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) { + if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE) + { + return rtems_termios_close (arg); + } + return RTEMS_SUCCESSFUL; } /* console_close */ @@ -196,10 +246,24 @@ console_read(rtems_device_major_number major, rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; char *buffer = rw_args->buffer; int count, maximum = rw_args->count; + + if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE) + { + return rtems_termios_read (arg); + } for (count = 0; count < maximum; count++) { - buffer[count] = inbyte(); + /* Get character */ + buffer[count] = _IBMPC_inch_sleep(); + + /* Echo character to screen */ + _IBMPC_outch(buffer[count]); + if (buffer[count] == '\r') + { + _IBMPC_outch('\n'); /* CR = CR + LF */ + } + if (buffer[count] == '\n' || buffer[count] == '\r') { /* What if this goes past the end of the buffer? We're hosed. [bhc] */ @@ -227,12 +291,17 @@ console_write(rtems_device_major_number major, rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; char *buffer = rw_args->buffer; int count, maximum = rw_args->count; + + if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE) + { + return rtems_termios_write (arg); + } for (count = 0; count < maximum; count++) { - outbyte(buffer[count]); + _IBMPC_outch(buffer[count]); if (buffer[count] == '\n') - outbyte('\r'); /* LF = LF + CR */ + _IBMPC_outch('\r'); /* LF = LF + CR */ } rw_args->bytes_moved = maximum; @@ -240,13 +309,98 @@ console_write(rtems_device_major_number major, } /* console_write */ -/*-------------------------------------------------------------------------+ -| Console device driver CONTROL entry point -+--------------------------------------------------------------------------*/ -rtems_device_driver + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ + rtems_device_minor_number minor, + void * arg +) +{ + if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE) + { + return rtems_termios_ioctl (arg); + } + return RTEMS_SUCCESSFUL; -} /* console_control */ +} + +static int +conSetAttr(int minor, const struct termios *t) +{ + int baud; + + switch (t->c_cflag & CBAUD) + { + case B50: + baud = 50; + break; + case B75: + baud = 75; + break; + case B110: + baud = 110; + break; + case B134: + baud = 134; + break; + case B150: + baud = 150; + break; + case B200: + baud = 200; + break; + case B300: + baud = 300; + break; + case B600: + baud = 600; + break; + case B1200: + baud = 1200; + break; + case B1800: + baud = 1800; + break; + case B2400: + baud = 2400; + break; + case B4800: + baud = 4800; + break; + case B9600: + baud = 9600; + break; + case B19200: + baud = 19200; + break; + case B38400: + baud = 38400; + break; + case B57600: + baud = 57600; + break; + case B115200: + baud = 115200; + break; + default: + baud = 0; + rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); + return 0; + } + + PC386_uart_set_baud(PC386ConsolePort, baud); + + return 0; +} + + + + + + + + + diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c index bcb9a17312..f29f6124c8 100644 --- a/c/src/lib/libbsp/i386/pc386/console/inch.c +++ b/c/src/lib/libbsp/i386/pc386/console/inch.c @@ -70,6 +70,7 @@ static char shift_map[] = static char kbd_buffer[KBD_BUF_SIZE]; static rtems_unsigned16 kbd_first = 0; static rtems_unsigned16 kbd_last = 0; +static rtems_unsigned16 kbd_end = KBD_BUF_SIZE - 1; /*-------------------------------------------------------------------------+ | Function: rtemsReboot @@ -81,7 +82,7 @@ static rtems_unsigned16 kbd_last = 0; void rtemsReboot(void) { /* shutdown and reboot */ - outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */ + outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */ } /* rtemsReboot */ /*-------------------------------------------------------------------------+ @@ -223,10 +224,12 @@ _IBMPC_keyboard_isr(rtems_vector_number vector) 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; + unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1; if (next != kbd_first) - kbd_last = next; + { + kbd_last = next; + } } PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */ @@ -277,3 +280,38 @@ _IBMPC_inch(void) return c; } /* _IBMPC_inch */ + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_inch_sleep +| Description: If charcter is ready return it, otherwise sleep until +| it is ready +| Global Variables: None. +| Arguments: None. +| Returns: character read from keyboard. ++--------------------------------------------------------------------------*/ +char +_IBMPC_inch_sleep(void) +{ + char c; + extern rtems_interval _TOD_Ticks_per_second; /* XXX should not do this */ + rtems_interval ticks_to_delay; + + ticks_to_delay = (_TOD_Ticks_per_second + 24) / 25; + + for(;;) + { + if(_IBMPC_chrdy(&c)) + { + return c; + } + rtems_task_wake_after(ticks_to_delay); + } + + return c; +} /* _IBMPC_inch */ + + + + + + diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c index e4c45c2166..1d5c1f9c38 100644 --- a/c/src/lib/libbsp/i386/pc386/console/outch.c +++ b/c/src/lib/libbsp/i386/pc386/console/outch.c @@ -33,8 +33,8 @@ static unsigned char column; static unsigned short attribute; static unsigned int nLines; - static void -scroll() +static void +scroll(void) { int i, j; /* Counters */ unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ @@ -55,8 +55,8 @@ scroll() } } - static void -endColumn() +static void +endColumn(void) { if (++row == maxRow) { scroll(); /* Scroll the screen now */ @@ -70,7 +70,7 @@ endColumn() - static void +static void videoPutChar(char car) { unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol; @@ -117,8 +117,8 @@ videoPutChar(char car) } } - void -clear_screen() +void +clear_screen(void) { int i,j; -- cgit v1.2.3