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:
Joel Sherrill
2003-02-20 21:32:07 +00:00
parent d19443c71a
commit 4f3e4f33db
16 changed files with 257 additions and 80 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) $@

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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
*/ */

View File

@@ -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");