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.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
if need_shared
|
if need_shared
|
||||||
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
SUBDIRS = clock console include pci residual openpic irq vectors start \
|
||||||
startup motorola bootloader
|
startup motorola bootloader vme
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include $(top_srcdir)/../../../../../automake/subdirs.am
|
include $(top_srcdir)/../../../../../automake/subdirs.am
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <rtems/system.h>
|
#include <rtems/system.h>
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/VME.h>
|
||||||
#include <bsp/openpic.h>
|
#include <bsp/openpic.h>
|
||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
#include <rtems/score/apiext.h>
|
#include <rtems/score/apiext.h>
|
||||||
@@ -86,14 +87,14 @@ static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
|
|||||||
*/
|
*/
|
||||||
static void compute_i8259_masks_from_prio ()
|
static void compute_i8259_masks_from_prio ()
|
||||||
{
|
{
|
||||||
unsigned int i;
|
int i;
|
||||||
unsigned int j;
|
int j;
|
||||||
/*
|
/*
|
||||||
* Always mask at least current interrupt to prevent re-entrance
|
* Always mask at least current interrupt to prevent re-entrance
|
||||||
*/
|
*/
|
||||||
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_NUMBER; i++) {
|
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
|
||||||
* ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
|
* ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
|
||||||
for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_NUMBER; j++) {
|
for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
|
||||||
/*
|
/*
|
||||||
* Mask interrupts at i8259 level that have a lower priority
|
* Mask interrupts at i8259 level that have a lower priority
|
||||||
*/
|
*/
|
||||||
@@ -261,7 +262,7 @@ int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
|
|||||||
*/
|
*/
|
||||||
compute_i8259_masks_from_prio ();
|
compute_i8259_masks_from_prio ();
|
||||||
|
|
||||||
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_NUMBER; i++) {
|
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
|
||||||
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||||
BSP_irq_enable_at_i8259s (i);
|
BSP_irq_enable_at_i8259s (i);
|
||||||
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
|
rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
|
||||||
@@ -375,10 +376,10 @@ void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
|
|||||||
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
|
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef BSP_PCI_VME_BRIDGE_DOES_EOI
|
#ifdef BSP_PCI_VME_DRIVER_DOES_EOI
|
||||||
/* leave it to the VME bridge to do EOI, so
|
/* leave it to the VME bridge driver to do EOI, so
|
||||||
* it can re-enable the openpic while handling
|
* it can re-enable the openpic while handling
|
||||||
* VME interrupts (-> VME priorities in software)
|
* VME interrupts (-> VME priorities in software)
|
||||||
*/
|
*/
|
||||||
if (BSP_PCI_VME_BRIDGE_IRQ!=irq)
|
if (BSP_PCI_VME_BRIDGE_IRQ!=irq)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,15 +73,19 @@ SYM (shared_raw_irq_code_entry):
|
|||||||
* to reenable exception processing
|
* to reenable exception processing
|
||||||
*/
|
*/
|
||||||
stw r0, GPR0_OFFSET(r1)
|
stw r0, GPR0_OFFSET(r1)
|
||||||
|
/* PPC EABI: R2 is reserved (pointer to short data .sdata2) - we won't touch it
|
||||||
|
* but we still save/restore it, just in case...
|
||||||
|
*/
|
||||||
stw r2, GPR2_OFFSET(r1)
|
stw r2, GPR2_OFFSET(r1)
|
||||||
stw r3, GPR3_OFFSET(r1)
|
stw r3, GPR3_OFFSET(r1)
|
||||||
|
|
||||||
mfsrr0 r0
|
mfsrr0 r0
|
||||||
mfsrr1 r2
|
mfsrr1 r3
|
||||||
mfmsr r3
|
|
||||||
|
|
||||||
stw r0, SRR0_FRAME_OFFSET(r1)
|
stw r0, SRR0_FRAME_OFFSET(r1)
|
||||||
stw r2, SRR1_FRAME_OFFSET(r1)
|
stw r3, SRR1_FRAME_OFFSET(r1)
|
||||||
|
|
||||||
|
mfmsr r3
|
||||||
/*
|
/*
|
||||||
* Enable data and instruction address translation, exception recovery
|
* Enable data and instruction address translation, exception recovery
|
||||||
*
|
*
|
||||||
@@ -137,21 +141,21 @@ SYM (shared_raw_irq_code_entry):
|
|||||||
*/
|
*/
|
||||||
addis r15,0, _Thread_Dispatch_disable_level@ha
|
addis r15,0, _Thread_Dispatch_disable_level@ha
|
||||||
/*
|
/*
|
||||||
* Get current nesting level in R2
|
* Get current nesting level in R3
|
||||||
*/
|
*/
|
||||||
mfspr r2, SPRG0
|
mfspr r3, SPRG0
|
||||||
/*
|
/*
|
||||||
* Check if stack switch is necessary
|
* Check if stack switch is necessary
|
||||||
*/
|
*/
|
||||||
cmpwi r2,0
|
cmpwi r3,0
|
||||||
bne nested
|
bne nested
|
||||||
mfspr r1, SPRG1
|
mfspr r1, SPRG1
|
||||||
|
|
||||||
nested:
|
nested:
|
||||||
/*
|
/*
|
||||||
* Start Incrementing nesting level in R2
|
* Start Incrementing nesting level in R3
|
||||||
*/
|
*/
|
||||||
addi r2,r2,1
|
addi r3,r3,1
|
||||||
/*
|
/*
|
||||||
* Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
|
* Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
|
||||||
*/
|
*/
|
||||||
@@ -159,7 +163,7 @@ nested:
|
|||||||
/*
|
/*
|
||||||
* store new nesting level in SPRG0
|
* store new nesting level in SPRG0
|
||||||
*/
|
*/
|
||||||
mtspr SPRG0, r2
|
mtspr SPRG0, r3
|
||||||
|
|
||||||
addi r6, r6, 1
|
addi r6, r6, 1
|
||||||
mfmsr r5
|
mfmsr r5
|
||||||
@@ -183,14 +187,14 @@ nested:
|
|||||||
* value as an easy exit condition because if interrupt nesting level > 1
|
* value as an easy exit condition because if interrupt nesting level > 1
|
||||||
* then _Thread_Dispatch_disable_level > 1
|
* then _Thread_Dispatch_disable_level > 1
|
||||||
*/
|
*/
|
||||||
mfspr r2, SPRG0
|
mfspr r4, SPRG0
|
||||||
/*
|
/*
|
||||||
* start decrementing _Thread_Dispatch_disable_level
|
* start decrementing _Thread_Dispatch_disable_level
|
||||||
*/
|
*/
|
||||||
lwz r3,_Thread_Dispatch_disable_level@l(r15)
|
lwz r3,_Thread_Dispatch_disable_level@l(r15)
|
||||||
addi r2, r2, -1 /* Continue decrementing nesting level */
|
addi r4, r4, -1 /* Continue decrementing nesting level */
|
||||||
addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
|
addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
|
||||||
mtspr SPRG0, r2 /* End decrementing nesting level */
|
mtspr SPRG0, r4 /* End decrementing nesting level */
|
||||||
stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
|
stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
|
||||||
cmpwi r3, 0
|
cmpwi r3, 0
|
||||||
/*
|
/*
|
||||||
@@ -222,14 +226,14 @@ nested:
|
|||||||
*/
|
*/
|
||||||
stmw r16, GPR16_OFFSET(r1)
|
stmw r16, GPR16_OFFSET(r1)
|
||||||
addi r3, r1, 0x8
|
addi r3, r1, 0x8
|
||||||
/*
|
/*
|
||||||
* compute SP at exception entry
|
* compute SP at exception entry
|
||||||
*/
|
*/
|
||||||
addi r2, r1, EXCEPTION_FRAME_END
|
addi r4, r1, EXCEPTION_FRAME_END
|
||||||
/*
|
/*
|
||||||
* store it at the right place
|
* store it at the right place
|
||||||
*/
|
*/
|
||||||
stw r2, GPR1_OFFSET(r1)
|
stw r4, GPR1_OFFSET(r1)
|
||||||
/*
|
/*
|
||||||
* Call High Level signal handling code
|
* Call High Level signal handling code
|
||||||
*/
|
*/
|
||||||
@@ -314,14 +318,14 @@ easy_exit:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
lwz r4, SRR1_FRAME_OFFSET(r1)
|
lwz r4, SRR1_FRAME_OFFSET(r1)
|
||||||
lwz r2, SRR0_FRAME_OFFSET(r1)
|
lwz r3, SRR0_FRAME_OFFSET(r1)
|
||||||
lwz r3, GPR3_OFFSET(r1)
|
lwz r2, GPR2_OFFSET(r1)
|
||||||
lwz r0, GPR0_OFFSET(r1)
|
lwz r0, GPR0_OFFSET(r1)
|
||||||
|
|
||||||
mtsrr1 r4
|
mtsrr1 r4
|
||||||
mtsrr0 r2
|
mtsrr0 r3
|
||||||
lwz r4, GPR4_OFFSET(r1)
|
lwz r4, GPR4_OFFSET(r1)
|
||||||
lwz r2, GPR2_OFFSET(r1)
|
lwz r3, GPR3_OFFSET(r1)
|
||||||
addi r1,r1, EXCEPTION_FRAME_END
|
addi r1,r1, EXCEPTION_FRAME_END
|
||||||
SYNC
|
SYNC
|
||||||
rfi
|
rfi
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)
|
|||||||
#ifdef TRACE_IRQ_INIT
|
#ifdef TRACE_IRQ_INIT
|
||||||
printk("Going to initialize raven interrupt controller (openpic compliant)\n");
|
printk("Going to initialize raven interrupt controller (openpic compliant)\n");
|
||||||
#endif
|
#endif
|
||||||
openpic_init(1, mcp750_openpic_initsenses, mcp750_openpic_initpolarities);
|
openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses);
|
||||||
#ifdef TRACE_IRQ_INIT
|
#ifdef TRACE_IRQ_INIT
|
||||||
printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
|
printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
|
|
||||||
C_FILES = openpic.c
|
C_FILES = openpic.c
|
||||||
|
|
||||||
include_bspdir = $(includedir)/bsp
|
H_FILES = openpic.h
|
||||||
include_bsp_HEADERS = openpic.h
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/bsp:
|
$(PROJECT_INCLUDE)/bsp:
|
||||||
$(mkinstalldirs) $@
|
$(mkinstalldirs) $@
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
##
|
##
|
||||||
|
|
||||||
|
|
||||||
C_FILES = bspstart.c
|
C_FILES = bspstart.c pgtbl_setup.c pgtbl_activate.c
|
||||||
|
|
||||||
noinst_DATA = linkcmds
|
noinst_DATA = linkcmds
|
||||||
|
|
||||||
EXTRA_DIST = bspstart.c linkcmds
|
EXTRA_DIST = bspstart.c linkcmds pgtbl_setup.c pgtbl_activate.c
|
||||||
|
|
||||||
include $(top_srcdir)/../../../../../automake/local.am
|
include $(top_srcdir)/../../../../../automake/local.am
|
||||||
|
|||||||
@@ -27,8 +27,10 @@
|
|||||||
#include <bsp/pci.h>
|
#include <bsp/pci.h>
|
||||||
#include <bsp/openpic.h>
|
#include <bsp/openpic.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/VME.h>
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <libcpu/bat.h>
|
#include <libcpu/bat.h>
|
||||||
|
#include <libcpu/pte121.h>
|
||||||
#include <libcpu/cpuIdent.h>
|
#include <libcpu/cpuIdent.h>
|
||||||
#include <bsp/vectors.h>
|
#include <bsp/vectors.h>
|
||||||
#include <bsp/motorola.h>
|
#include <bsp/motorola.h>
|
||||||
@@ -41,6 +43,13 @@ extern void L1_caches_enables();
|
|||||||
extern unsigned get_L2CR();
|
extern unsigned get_L2CR();
|
||||||
extern void set_L2CR(unsigned);
|
extern void set_L2CR(unsigned);
|
||||||
extern void bsp_cleanup(void);
|
extern void bsp_cleanup(void);
|
||||||
|
extern Triv121PgTbl BSP_pgtbl_setup();
|
||||||
|
extern void BSP_pgtbl_activate();
|
||||||
|
extern void BSP_vme_config();
|
||||||
|
|
||||||
|
SPR_RW(SPR0)
|
||||||
|
SPR_RW(SPR1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy of residuals passed by firmware
|
* Copy of residuals passed by firmware
|
||||||
*/
|
*/
|
||||||
@@ -173,6 +182,7 @@ void bsp_start( void )
|
|||||||
ppc_cpu_revision_t myCpuRevision;
|
ppc_cpu_revision_t myCpuRevision;
|
||||||
prep_t boardManufacturer;
|
prep_t boardManufacturer;
|
||||||
motorolaBoard myBoard;
|
motorolaBoard myBoard;
|
||||||
|
Triv121PgTbl pt=0;
|
||||||
/*
|
/*
|
||||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
||||||
* store the result in global variables so that it can be used latter...
|
* store the result in global variables so that it can be used latter...
|
||||||
@@ -217,8 +227,8 @@ void bsp_start( void )
|
|||||||
/* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
|
/* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
|
||||||
*((unsigned32 *)intrStack) = 0;
|
*((unsigned32 *)intrStack) = 0;
|
||||||
|
|
||||||
asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack));
|
_write_SPR1((unsigned int)intrStack);
|
||||||
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel));
|
_write_SPR0(intrNestingLevel);
|
||||||
/*
|
/*
|
||||||
* Initialize default raw exception hanlders. See vectors/vectors_init.c
|
* Initialize default raw exception hanlders. See vectors/vectors_init.c
|
||||||
*/
|
*/
|
||||||
@@ -231,18 +241,20 @@ void bsp_start( void )
|
|||||||
* PC legacy IO space used for inb/outb and all PC
|
* PC legacy IO space used for inb/outb and all PC
|
||||||
* compatible hardware
|
* compatible hardware
|
||||||
*/
|
*/
|
||||||
setdbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
|
setdbat(1, _IO_BASE, _IO_BASE, 0x10000000, IO_PAGE);
|
||||||
/*
|
/*
|
||||||
* PCI devices memory area. Needed to access OPENPIC features
|
* PCI devices memory area. Needed to access OPENPIC features
|
||||||
* provided by the RAVEN
|
* provided by the RAVEN
|
||||||
*/
|
*/
|
||||||
/* T. Straumann: give more PCI address space */
|
/* T. Straumann: give more PCI address space */
|
||||||
setdbat(2, 0xc0000000, 0xc0000000, 0x10000000, IO_PAGE);
|
setdbat(2, PCI_MEM_BASE, PCI_MEM_BASE, 0x10000000, IO_PAGE);
|
||||||
/*
|
/*
|
||||||
* Must have acces to open pic PCI ACK registers
|
* Must have acces to open pic PCI ACK registers
|
||||||
* provided by the RAVEN
|
* provided by the RAVEN
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
|
setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
|
||||||
|
|
||||||
select_console(CONSOLE_LOG);
|
select_console(CONSOLE_LOG);
|
||||||
|
|
||||||
/* We check that the keyboard is present and immediately
|
/* We check that the keyboard is present and immediately
|
||||||
@@ -305,6 +317,27 @@ void bsp_start( void )
|
|||||||
BSP_time_base_divisor = (residualCopy.VitalProductData.TimeBaseDivisor?
|
BSP_time_base_divisor = (residualCopy.VitalProductData.TimeBaseDivisor?
|
||||||
residualCopy.VitalProductData.TimeBaseDivisor : 4000);
|
residualCopy.VitalProductData.TimeBaseDivisor : 4000);
|
||||||
|
|
||||||
|
/* Allocate and set up the page table mappings
|
||||||
|
* This is only available on >604 CPUs.
|
||||||
|
*
|
||||||
|
* NOTE: This setup routine may modify the available memory
|
||||||
|
* size. It is essential to call it before
|
||||||
|
* calculating the workspace etc.
|
||||||
|
*/
|
||||||
|
pt = BSP_pgtbl_setup(&BSP_mem_size);
|
||||||
|
|
||||||
|
if (!pt ||
|
||||||
|
TRIV121_MAP_SUCCESS != triv121PgTblMap(
|
||||||
|
pt,
|
||||||
|
TRIV121_121_VSID,
|
||||||
|
0xfeff0000,
|
||||||
|
1,
|
||||||
|
TRIV121_ATTR_IO_PAGE,
|
||||||
|
TRIV121_PP_RW_PAGE
|
||||||
|
)) {
|
||||||
|
printk("WARNING: unable to setup page tables VME bridge must share PCI space\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up our hooks
|
* Set up our hooks
|
||||||
* Make sure libc_init is done before drivers initialized so that
|
* Make sure libc_init is done before drivers initialized so that
|
||||||
@@ -335,6 +368,34 @@ void bsp_start( void )
|
|||||||
* Initalize RTEMS IRQ system
|
* Initalize RTEMS IRQ system
|
||||||
*/
|
*/
|
||||||
BSP_rtems_irq_mng_init(0);
|
BSP_rtems_irq_mng_init(0);
|
||||||
|
|
||||||
|
|
||||||
|
/* Activate the page table mappings only after
|
||||||
|
* initializing interrupts because the irq_mng_init()
|
||||||
|
* routine needs to modify the text
|
||||||
|
*/
|
||||||
|
if (pt) {
|
||||||
|
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||||
|
printk("Page table setup finished; will activate it NOW...\n");
|
||||||
|
#endif
|
||||||
|
BSP_pgtbl_activate(pt);
|
||||||
|
/* finally, switch off DBAT3 */
|
||||||
|
setdbat(3, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize VME bridge - needs working PCI
|
||||||
|
* and IRQ subsystems...
|
||||||
|
*/
|
||||||
|
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||||
|
printk("Going to initialize VME bridge\n");
|
||||||
|
#endif
|
||||||
|
/* VME initialization is in a separate file so apps which don't use
|
||||||
|
* VME or want a different configuration may link against a customized
|
||||||
|
* routine.
|
||||||
|
*/
|
||||||
|
BSP_vme_config();
|
||||||
|
|
||||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||||
printk("Exit from bspstart\n");
|
printk("Exit from bspstart\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ ENTRY(_start)
|
|||||||
PROVIDE (__stack = 0);
|
PROVIDE (__stack = 0);
|
||||||
MEMORY {
|
MEMORY {
|
||||||
VECTORS : ORIGIN = 0x0 , LENGTH = 0x3000
|
VECTORS : ORIGIN = 0x0 , LENGTH = 0x3000
|
||||||
CODE : ORIGIN = 0x3000 , LENGTH = 0x100000
|
CODE : ORIGIN = 0x3000 , LENGTH = 0x400000
|
||||||
}
|
}
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
@@ -75,10 +75,10 @@ SECTIONS
|
|||||||
.rodata : { *(.rodata*) *(.gnu.linkonce.r*) } > CODE
|
.rodata : { *(.rodata*) *(.gnu.linkonce.r*) } > CODE
|
||||||
.rodata1 : { *(.rodata1) } > CODE
|
.rodata1 : { *(.rodata1) } > CODE
|
||||||
.eh_frame : { *.(eh_frame) } >CODE
|
.eh_frame : { *.(eh_frame) } >CODE
|
||||||
_etext = .;
|
|
||||||
PROVIDE (etext = .);
|
|
||||||
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >CODE
|
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >CODE
|
||||||
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >CODE
|
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >CODE
|
||||||
|
_etext = .;
|
||||||
|
PROVIDE (etext = .);
|
||||||
/* Adjust the address for the data segment. We want to adjust up to
|
/* Adjust the address for the data segment. We want to adjust up to
|
||||||
the same address within the page on the next page up. It would
|
the same address within the page on the next page up. It would
|
||||||
be more correct to do this:
|
be more correct to do this:
|
||||||
|
|||||||
@@ -40,9 +40,12 @@ SYM (default_exception_vector_code_prolog):
|
|||||||
*/
|
*/
|
||||||
stwu r1, - (EXCEPTION_FRAME_END)(r1)
|
stwu r1, - (EXCEPTION_FRAME_END)(r1)
|
||||||
stw r3, GPR3_OFFSET(r1)
|
stw r3, GPR3_OFFSET(r1)
|
||||||
|
/* R2 should never change (EABI: pointer to .sdata2) - we
|
||||||
|
* save it nevertheless..
|
||||||
|
*/
|
||||||
stw r2, GPR2_OFFSET(r1)
|
stw r2, GPR2_OFFSET(r1)
|
||||||
mflr r2
|
mflr r3
|
||||||
stw r2, EXC_LR_OFFSET(r1)
|
stw r3, EXC_LR_OFFSET(r1)
|
||||||
bl 0f
|
bl 0f
|
||||||
0: /*
|
0: /*
|
||||||
* r3 = exception vector entry point
|
* r3 = exception vector entry point
|
||||||
@@ -64,8 +67,8 @@ PUBLIC_VAR (push_normalized_frame)
|
|||||||
SYM (push_normalized_frame):
|
SYM (push_normalized_frame):
|
||||||
stw r3, EXCEPTION_NUMBER_OFFSET(r1)
|
stw r3, EXCEPTION_NUMBER_OFFSET(r1)
|
||||||
stw r0, GPR0_OFFSET(r1)
|
stw r0, GPR0_OFFSET(r1)
|
||||||
mfsrr0 r2
|
mfsrr0 r3
|
||||||
stw r2, SRR0_FRAME_OFFSET(r1)
|
stw r3, SRR0_FRAME_OFFSET(r1)
|
||||||
mfsrr1 r3
|
mfsrr1 r3
|
||||||
stw r3, SRR1_FRAME_OFFSET(r1)
|
stw r3, SRR1_FRAME_OFFSET(r1)
|
||||||
/*
|
/*
|
||||||
@@ -89,14 +92,14 @@ SYM (push_normalized_frame):
|
|||||||
stw r28, EXC_MSR_OFFSET(r1)
|
stw r28, EXC_MSR_OFFSET(r1)
|
||||||
mfdar r28
|
mfdar r28
|
||||||
stw r28, EXC_DAR_OFFSET(r1)
|
stw r28, EXC_DAR_OFFSET(r1)
|
||||||
/*
|
/*
|
||||||
* compute SP at exception entry
|
* compute SP at exception entry
|
||||||
*/
|
*/
|
||||||
addi r2, r1, EXCEPTION_FRAME_END
|
addi r3, r1, EXCEPTION_FRAME_END
|
||||||
/*
|
/*
|
||||||
* store it at the right place
|
* store it at the right place
|
||||||
*/
|
*/
|
||||||
stw r2, GPR1_OFFSET(r1)
|
stw r3, GPR1_OFFSET(r1)
|
||||||
/*
|
/*
|
||||||
* Enable data and instruction address translation, exception nesting
|
* Enable data and instruction address translation, exception nesting
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <bsp/vectors.h>
|
#include <bsp/vectors.h>
|
||||||
#include <libcpu/raw_exception.h>
|
#include <libcpu/raw_exception.h>
|
||||||
|
#include <libcpu/spr.h>
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
|
|
||||||
static rtems_raw_except_global_settings exception_config;
|
static rtems_raw_except_global_settings exception_config;
|
||||||
@@ -33,16 +34,28 @@ typedef struct LRFrameRec_ {
|
|||||||
|
|
||||||
#define STACK_CLAMP 50 /* in case we have a corrupted bottom */
|
#define STACK_CLAMP 50 /* in case we have a corrupted bottom */
|
||||||
|
|
||||||
|
SPR_RO(LR)
|
||||||
|
|
||||||
void
|
void
|
||||||
BSP_printStackTrace(BSP_Exception_frame* excPtr)
|
BSP_printStackTrace(BSP_Exception_frame* excPtr)
|
||||||
{
|
{
|
||||||
LRFrame f;
|
LRFrame f;
|
||||||
int i;
|
int i;
|
||||||
|
LRFrame sp;
|
||||||
|
void *lr;
|
||||||
|
|
||||||
printk("Stack Trace: ");
|
printk("Stack Trace: \n ");
|
||||||
printk(" IP: 0x%08x, LR: 0x%08x\n",
|
if (excPtr) {
|
||||||
excPtr->EXC_SRR0, excPtr->EXC_LR);
|
printk("IP: 0x%08x, ",excPtr->EXC_SRR0);
|
||||||
for (f=(LRFrame)excPtr->GPR1, i=0; f->frameLink && i<STACK_CLAMP; f=f->frameLink) {
|
sp=(LRFrame)excPtr->GPR1;
|
||||||
|
lr=(void*)excPtr->EXC_LR;
|
||||||
|
} else {
|
||||||
|
/* there's no macro for this */
|
||||||
|
__asm__ __volatile__("mr %0, 1":"=r"(sp));
|
||||||
|
lr=(LRFrame)_read_LR();
|
||||||
|
}
|
||||||
|
printk("LR: 0x%08x\n",lr);
|
||||||
|
for (f=(LRFrame)sp, i=0; f->frameLink && i<STACK_CLAMP; f=f->frameLink) {
|
||||||
printk("--^ 0x%08x", (long)(f->frameLink->lr));
|
printk("--^ 0x%08x", (long)(f->frameLink->lr));
|
||||||
if (!(++i%5))
|
if (!(++i%5))
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user