forked from Imagelibrary/rtems
2003-02-20 Till Straumann <strauman@slac.stanford.edu>
PR 349/bsps * console/console.c, console/uart.c, console/uart.h: implement IOCTLs for the serial (UART) console to install/retrieve a BREAK-IRQ callback. The callback routine (if installed) is invoked from the UART ISR when a BREAK interrupt is detected. This can be used e.g. to enforce a "hotkey" reboot a la vxWorks Ctrl-X (although we use the serial line break condition) NOTE: The callback runs in ISR context.
This commit is contained in:
@@ -1,3 +1,14 @@
|
|||||||
|
2003-02-20 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
|
PR 349/bsps
|
||||||
|
* console/console.c, console/uart.c, console/uart.h: implement
|
||||||
|
IOCTLs for the serial (UART) console to install/retrieve a BREAK-IRQ
|
||||||
|
callback. The callback routine (if installed) is invoked from the
|
||||||
|
UART ISR when a BREAK interrupt is detected. This can be used
|
||||||
|
e.g. to enforce a "hotkey" reboot a la vxWorks Ctrl-X (although we
|
||||||
|
use the serial line break condition) NOTE: The callback runs in
|
||||||
|
ISR context.
|
||||||
|
|
||||||
2003-01-20 Joel Sherrill <joel@OARcorp.com>
|
2003-01-20 Joel Sherrill <joel@OARcorp.com>
|
||||||
|
|
||||||
* startup/linkcmds*: Add FreeBSD sysctl() sections.
|
* startup/linkcmds*: Add FreeBSD sysctl() sections.
|
||||||
|
|||||||
@@ -257,11 +257,24 @@ console_write(rtems_device_major_number major,
|
|||||||
* Handle ioctl request.
|
* Handle ioctl request.
|
||||||
*/
|
*/
|
||||||
rtems_device_driver
|
rtems_device_driver
|
||||||
console_control(rtems_device_major_number major,
|
console_control(rtems_device_major_number major,
|
||||||
rtems_device_minor_number minor,
|
rtems_device_minor_number minor,
|
||||||
void * arg
|
void *arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
/* does the BSP support break callbacks ? */
|
||||||
|
#if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB)
|
||||||
|
rtems_libio_ioctl_args_t *ioa=arg;
|
||||||
|
switch (ioa->command) {
|
||||||
|
case BIOCSETBREAKCB:
|
||||||
|
return BSP_uart_set_break_cb(minor, ioa);
|
||||||
|
case BIOCGETBREAKCB:
|
||||||
|
return BSP_uart_get_break_cb(minor, ioa);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return rtems_termios_ioctl (arg);
|
return rtems_termios_ioctl (arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ static int skip_atoi(const char **s)
|
|||||||
* bloat has been limited since we basically only need %u, %x, %s and %c.
|
* bloat has been limited since we basically only need %u, %x, %s and %c.
|
||||||
* But we need 64 bit values !
|
* But we need 64 bit values !
|
||||||
*/
|
*/
|
||||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
int k_vsprintf(char *buf, const char *fmt, va_list args);
|
||||||
|
|
||||||
int printk(const char *fmt, ...) {
|
int printk(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -897,7 +897,7 @@ int printk(const char *fmt, ...) {
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
i = vsprintf(buf, fmt, args);
|
i = k_vsprintf(buf, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
puts(buf);
|
puts(buf);
|
||||||
return i;
|
return i;
|
||||||
@@ -988,7 +988,7 @@ static char * number(char * str, int size, int type, u64 num)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
int k_vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
u64 num;
|
u64 num;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "console.inl"
|
#include "console.inl"
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
#include <libcpu/stackTrace.h>
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------+
|
/*-------------------------------------------------------------------------+
|
||||||
| Function: rtemsReboot
|
| Function: rtemsReboot
|
||||||
@@ -11,6 +13,8 @@
|
|||||||
+--------------------------------------------------------------------------*/
|
+--------------------------------------------------------------------------*/
|
||||||
void rtemsReboot(void)
|
void rtemsReboot(void)
|
||||||
{
|
{
|
||||||
|
printk("Printing a stack trace for your convenience :-)\n");
|
||||||
|
CPU_print_stack();
|
||||||
/* shutdown and reboot */
|
/* shutdown and reboot */
|
||||||
kbd_outb(0x4, 0xFE); /* use keyboard controler to do the job... */
|
kbd_outb(0x4, 0xFE); /* use keyboard controler to do the job... */
|
||||||
} /* rtemsReboot */
|
} /* rtemsReboot */
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
#include <bsp/uart.h>
|
#include <bsp/uart.h>
|
||||||
#include <rtems/libio.h>
|
#include <rtems/libio.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -19,9 +20,10 @@
|
|||||||
|
|
||||||
struct uart_data
|
struct uart_data
|
||||||
{
|
{
|
||||||
unsigned long ioBase;
|
unsigned long ioBase;
|
||||||
int hwFlow;
|
int hwFlow;
|
||||||
int baud;
|
int baud;
|
||||||
|
BSP_UartBreakCbRec breakCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -74,11 +76,13 @@ uwrite(int uart, int reg, unsigned int val)
|
|||||||
out_8((unsigned char*)(uart_data[uart].ioBase + reg), val);
|
out_8((unsigned char*)(uart_data[uart].ioBase + reg), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define UARTDEBUG
|
||||||
#ifdef UARTDEBUG
|
#ifdef UARTDEBUG
|
||||||
static void
|
static void
|
||||||
uartError(int uart)
|
uartError(int uart, void *termiosPrivate)
|
||||||
{
|
{
|
||||||
unsigned char uartStatus, dummy;
|
unsigned char uartStatus, dummy;
|
||||||
|
BSP_UartBreakCbProc h;
|
||||||
|
|
||||||
uartStatus = uread(uart, LSR);
|
uartStatus = uread(uart, LSR);
|
||||||
dummy = uread(uart, RBR);
|
dummy = uread(uart, RBR);
|
||||||
@@ -89,19 +93,32 @@ uartError(int uart)
|
|||||||
printk("********* Parity Error **********\n");
|
printk("********* Parity Error **********\n");
|
||||||
if (uartStatus & FE)
|
if (uartStatus & FE)
|
||||||
printk("********* Framing Error **********\n");
|
printk("********* Framing Error **********\n");
|
||||||
if (uartStatus & BI)
|
if (uartStatus & BI) {
|
||||||
printk("********* Parity Error **********\n");
|
printk("********* BREAK INTERRUPT *********\n");
|
||||||
|
if ((h=uart_data[uart].breakCallback.handler))
|
||||||
|
h(uart,
|
||||||
|
(dummy<<8)|uartStatus,
|
||||||
|
termiosPrivate,
|
||||||
|
uart_data[uart].breakCallback.private);
|
||||||
|
|
||||||
|
}
|
||||||
if (uartStatus & ERFIFO)
|
if (uartStatus & ERFIFO)
|
||||||
printk("********* Error receive Fifo **********\n");
|
printk("********* Error receive Fifo **********\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline void uartError(int uart)
|
inline void uartError(int uart, void *termiosPrivate)
|
||||||
{
|
{
|
||||||
unsigned char uartStatus;
|
unsigned char uartStatus,dummy;
|
||||||
|
BSP_UartBreakCbProc h;
|
||||||
|
|
||||||
uartStatus = uread(uart, LSR);
|
uartStatus = uread(uart, LSR);
|
||||||
uartStatus = uread(uart, RBR);
|
dummy = uread(uart, RBR);
|
||||||
|
if ((uartStatus & BI) && (h=uart_data[uart].breakCallback.handler))
|
||||||
|
h(uart,
|
||||||
|
(dummy<<8)|uartStatus,
|
||||||
|
termiosPrivate,
|
||||||
|
uart_data[uart].breakCallback.private);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -644,7 +661,7 @@ BSP_uart_termios_isr_com(int uart)
|
|||||||
break;
|
break;
|
||||||
case RECEIVER_ERROR:
|
case RECEIVER_ERROR:
|
||||||
/* RX error: eat character */
|
/* RX error: eat character */
|
||||||
uartError(uart);
|
uartError(uart, termios_ttyp_com[uart]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Should not happen */
|
/* Should not happen */
|
||||||
@@ -666,3 +683,30 @@ BSP_uart_termios_isr_com2(void)
|
|||||||
BSP_uart_termios_isr_com(BSP_UART_COM2);
|
BSP_uart_termios_isr_com(BSP_UART_COM2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* retrieve 'break' handler info */
|
||||||
|
int
|
||||||
|
BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
|
||||||
|
{
|
||||||
|
BSP_UartBreakCb cb=arg->buffer;
|
||||||
|
unsigned long flags;
|
||||||
|
SANITY_CHECK(uart);
|
||||||
|
rtems_interrupt_disable(flags);
|
||||||
|
*cb = uart_data[uart].breakCallback;
|
||||||
|
rtems_interrupt_enable(flags);
|
||||||
|
arg->ioctl_return=0;
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* install 'break' handler */
|
||||||
|
int
|
||||||
|
BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
|
||||||
|
{
|
||||||
|
BSP_UartBreakCb cb=arg->buffer;
|
||||||
|
unsigned long flags;
|
||||||
|
SANITY_CHECK(uart);
|
||||||
|
rtems_interrupt_disable(flags);
|
||||||
|
uart_data[uart].breakCallback = *cb;
|
||||||
|
rtems_interrupt_enable(flags);
|
||||||
|
arg->ioctl_return=0;
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
|
||||||
void BSP_uart_init(int uart, int baud, int hwFlow);
|
void BSP_uart_init(int uart, int baud, int hwFlow);
|
||||||
void BSP_uart_set_baud(int aurt, int baud);
|
void BSP_uart_set_baud(int aurt, int baud);
|
||||||
void BSP_uart_intr_ctrl(int uart, int cmd);
|
void BSP_uart_intr_ctrl(int uart, int cmd);
|
||||||
@@ -28,11 +31,32 @@ void BSP_uart_dbgisr_com1(void);
|
|||||||
void BSP_uart_dbgisr_com2(void);
|
void BSP_uart_dbgisr_com2(void);
|
||||||
int BSP_uart_install_isr(int uart, rtems_irq_hdl handler);
|
int BSP_uart_install_isr(int uart, rtems_irq_hdl handler);
|
||||||
int BSP_uart_remove_isr(int uart, rtems_irq_hdl handler);
|
int BSP_uart_remove_isr(int uart, rtems_irq_hdl handler);
|
||||||
|
int BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg);
|
||||||
|
int BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg);
|
||||||
|
|
||||||
extern unsigned BSP_poll_char_via_serial(void);
|
extern unsigned BSP_poll_char_via_serial(void);
|
||||||
extern void BSP_output_char_via_serial(int val);
|
extern void BSP_output_char_via_serial(int val);
|
||||||
extern int BSPConsolePort;
|
extern int BSPConsolePort;
|
||||||
extern int BSPBaseBaud;
|
extern int BSPBaseBaud;
|
||||||
|
|
||||||
|
/* Special IOCTLS to install a lowlevel 'BREAK' handler */
|
||||||
|
|
||||||
|
/* pass a BSP_UartBreakCb pointer to ioctl when retrieving
|
||||||
|
* or installing break callback
|
||||||
|
*/
|
||||||
|
typedef void (*BSP_UartBreakCbProc)(int uartMinor,
|
||||||
|
unsigned uartRBRLSRStatus,
|
||||||
|
void *termiosPrivatePtr,
|
||||||
|
void *private);
|
||||||
|
|
||||||
|
typedef struct BSP_UartBreakCbRec_ {
|
||||||
|
BSP_UartBreakCbProc handler; /* NOTE NOTE this handler runs in INTERRUPT CONTEXT */
|
||||||
|
void *private; /* closure pointer which is passed to the callback */
|
||||||
|
} BSP_UartBreakCbRec, *BSP_UartBreakCb;
|
||||||
|
|
||||||
|
#define BIOCGETBREAKCB _IOR('b',1,sizeof(BSP_UartBreakCbRec))
|
||||||
|
#define BIOCSETBREAKCB _IOW('b',2,sizeof(BSP_UartBreakCbRec))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command values for BSP_uart_intr_ctrl(),
|
* Command values for BSP_uart_intr_ctrl(),
|
||||||
* values are strange in order to catch errors
|
* values are strange in order to catch errors
|
||||||
|
|||||||
Reference in New Issue
Block a user