From 69ed59f083a083fd96d08b5f6d54f2c80f267f03 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 14 May 2002 17:10:17 +0000 Subject: 2001-05-14 Till Straumann * bootloader/misc.c, console/Makefile.am, console/console.c, console/consoleIo.h, console/inch.c, console/polled_io.c, console/uart.c, console/uart.h, include/bsp.h, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_init.c, openpic/openpic.c, openpic/openpic.h, pci/Makefile.am, pci/pci.c, pci/pci.h, residual/Makefile.am, start/start.S, startup/bspstart.c, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: Per PR216, "libbsp/powerpc/shared" BSP has been modified considerably with the goal to make it more flexible and reusable by other BSPs. The main strategies were: - eliminate hardcoded base addresses; devices use offsets and a BSP defined base address. - separate functionality into different files (e.g. reboot from inch.c to reboot.c) which can be overridden by a 'derived' BSP. - separate initialization code into separate files (e.g. PCI bridge detection/initialization was separated from the more generic PCI access routines), also to make it easier for 'derived' BSPs to substitute their own initialization code. There are also a couple of enhancements and fixes: - IRQ handling code now has a hook for attaching a VME bridge. - OpenPIC is now explicitely initialized (polarities, senses). Eliminated the implicit assumption on the presence of an ISA PIC. - UART and console driver now supports more than 1 port. The current maximum of 2 can easily be extended by enlarging a table (it would even be easier if the ISR API was not broken by design). - fixed polled_io.c so it correctly supports console on COM2 - fixed TLB invalidation code (start.S). - exception handler prints a stack backtrace. - added BSP_pciFindDevice() to scan the pci bus for a particular vendor/device/instance. --- c/src/lib/libbsp/powerpc/shared/ChangeLog | 23 ++ c/src/lib/libbsp/powerpc/shared/bootloader/misc.c | 17 +- .../lib/libbsp/powerpc/shared/console/Makefile.am | 6 +- c/src/lib/libbsp/powerpc/shared/console/console.c | 187 +++++----- .../lib/libbsp/powerpc/shared/console/consoleIo.h | 4 - c/src/lib/libbsp/powerpc/shared/console/inch.c | 33 +- .../lib/libbsp/powerpc/shared/console/polled_io.c | 118 ++++--- c/src/lib/libbsp/powerpc/shared/console/uart.c | 386 ++++++++------------- c/src/lib/libbsp/powerpc/shared/console/uart.h | 15 +- c/src/lib/libbsp/powerpc/shared/include/bsp.h | 26 +- c/src/lib/libbsp/powerpc/shared/irq/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/shared/irq/irq.c | 12 +- c/src/lib/libbsp/powerpc/shared/irq/irq.h | 9 +- c/src/lib/libbsp/powerpc/shared/irq/irq_init.c | 12 +- c/src/lib/libbsp/powerpc/shared/openpic/openpic.c | 18 +- c/src/lib/libbsp/powerpc/shared/openpic/openpic.h | 4 +- c/src/lib/libbsp/powerpc/shared/pci/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/shared/pci/pci.c | 118 +------ c/src/lib/libbsp/powerpc/shared/pci/pci.h | 31 +- .../lib/libbsp/powerpc/shared/residual/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/shared/start/start.S | 2 +- c/src/lib/libbsp/powerpc/shared/startup/bspstart.c | 11 +- c/src/lib/libbsp/powerpc/shared/vectors/vectors.S | 4 + c/src/lib/libbsp/powerpc/shared/vectors/vectors.h | 3 +- .../libbsp/powerpc/shared/vectors/vectors_init.c | 37 +- 25 files changed, 519 insertions(+), 565 deletions(-) (limited to 'c/src/lib/libbsp/powerpc') diff --git a/c/src/lib/libbsp/powerpc/shared/ChangeLog b/c/src/lib/libbsp/powerpc/shared/ChangeLog index ff4fb24d3a..dce1744e2e 100644 --- a/c/src/lib/libbsp/powerpc/shared/ChangeLog +++ b/c/src/lib/libbsp/powerpc/shared/ChangeLog @@ -1,3 +1,26 @@ +2001-05-14 Till Straumann + + * bootloader/misc.c, console/Makefile.am, console/console.c, + console/consoleIo.h, console/inch.c, console/polled_io.c, + console/uart.c, console/uart.h, include/bsp.h, irq/Makefile.am, + irq/irq.c, irq/irq.h, irq/irq_init.c, openpic/openpic.c, + openpic/openpic.h, pci/Makefile.am, pci/pci.c, pci/pci.h, + residual/Makefile.am, start/start.S, startup/bspstart.c, + vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: + Per PR216, "libbsp/powerpc/shared" BSP has been modified considerably + with the goal to make it more flexible and reusable by other + BSPs. The main strategies were: + - eliminate hardcoded base addresses; devices use offsets + and a BSP defined base address. + - separate functionality into different files (e.g. reboot from + inch.c to reboot.c) which can be overridden by a 'derived' BSP. + - separate initialization code into separate files (e.g. PCI + bridge detection/initialization was separated from the more + generic PCI access routines), also to make it easier for + 'derived' BSPs to substitute their own initialization code. + There are also a couple of enhancements and fixes: + - IRQ handling code now has a hook for attaching a VME bridge. + - OpenPIC is now explicitely initialized (polarities, senses). Eliminated the implicit assumption on the presence of an ISA PIC. - UART and console driver now supports more than 1 port. The current maximum of 2 can easily be extended by enlarging a table (it diff --git a/c/src/lib/libbsp/powerpc/shared/bootloader/misc.c b/c/src/lib/libbsp/powerpc/shared/bootloader/misc.c index 88b7528fca..bd9d61baa2 100644 --- a/c/src/lib/libbsp/powerpc/shared/bootloader/misc.c +++ b/c/src/lib/libbsp/powerpc/shared/bootloader/misc.c @@ -233,6 +233,21 @@ void decompress_kernel(int kernel_size, void * zimage_start, int len, codemove(bd->load_address, initrd_start, initrd_len, bd->cache_lsize); } +static int ticks_per_ms=0; + +/* this is from rtems_bsp_delay from libcpu */ +void +boot_udelay(unsigned32 _microseconds) +{ + unsigned32 start, ticks, now; + + ticks = _microseconds * ticks_per_ms / 1000; + CPU_Get_timebase_low( start ); + do { + CPU_Get_timebase_low( now ); + } while (now - start < ticks); +} + void setup_hw(void) { @@ -402,7 +417,7 @@ setup_hw(void) } break; /* Exit 'timer' loop */ } - udelay(1000); /* 1 msec */ + boot_udelay(1000); /* 1 msec */ } *cp = 0; } diff --git a/c/src/lib/libbsp/powerpc/shared/console/Makefile.am b/c/src/lib/libbsp/powerpc/shared/console/Makefile.am index 48711404c0..da98cb2a2b 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/Makefile.am +++ b/c/src/lib/libbsp/powerpc/shared/console/Makefile.am @@ -3,7 +3,7 @@ ## -C_FILES = console.c inch.c polled_io.c uart.c +C_FILES = console.c inch.c polled_io.c uart.c reboot.c H_FILES = consoleIo.h keyboard.h uart.h @@ -18,7 +18,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \ all-local: $(PREINSTALL_FILES) -EXTRA_DIST = console.c consoleIo.h inch.c keyboard.h polled_io.c uart.c \ - uart.h +EXTRA_DIST = console.c inch.c polled_io.c uart.c \ + reboot.c console.inl include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/shared/console/console.c b/c/src/lib/libbsp/powerpc/shared/console/console.c index d797108f68..a79e0a5984 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/console.c +++ b/c/src/lib/libbsp/powerpc/shared/console/console.c @@ -9,6 +9,9 @@ * (C) Copyright 1997 - * - NavIST Group - Real-Time Distributed Systems and Industrial Automation * + * Till Straumann, , 12/20/2001 + * separate BSP specific stuff from generics... + * * http://pandora.ist.utl.pt * * Instituto Superior Tecnico * Lisboa * PORTUGAL @@ -34,56 +37,24 @@ extern int close(int fd); #include #include #include +#include /* printk */ /* Definitions for BSPConsolePort */ -#define BSP_CONSOLE_PORT_CONSOLE (-1) -#define BSP_CONSOLE_PORT_COM1 (BSP_UART_COM1) -#define BSP_CONSOLE_PORT_COM2 (BSP_UART_COM2) /* * Possible value for console input/output : * BSP_CONSOLE_PORT_CONSOLE * BSP_UART_COM1 * BSP_UART_COM2 */ +int BSPConsolePort = BSP_CONSOLE_PORT; -int BSPConsolePort = BSP_UART_COM1; - -/* int BSPConsolePort = BSP_UART_COM2; */ -int BSPBaseBaud = 115200; +int BSPBaseBaud = BSP_UART_BAUD_BASE; /*-------------------------------------------------------------------------+ | External Prototypes +--------------------------------------------------------------------------*/ static int conSetAttr(int minor, const struct termios *); -static void isr_on(const rtems_irq_connect_data *); -static void isr_off(const rtems_irq_connect_data *); -static int isr_is_on(const rtems_irq_connect_data *); - - -static rtems_irq_connect_data console_isr_data = {BSP_ISA_UART_COM1_IRQ, - BSP_uart_termios_isr_com1, - isr_on, - isr_off, - isr_is_on}; - -static void -isr_on(const rtems_irq_connect_data *unused) -{ - return; -} - -static void -isr_off(const rtems_irq_connect_data *unused) -{ - return; -} - -static int -isr_is_on(const rtems_irq_connect_data *irq) -{ - return BSP_irq_enabled_at_i8259s(irq->name); -} void __assert (const char *file, int line, const char *msg) { @@ -112,6 +83,28 @@ void __assert (const char *file, int line, const char *msg) } +typedef struct TtySTblRec_ { + char *name; + void (*isr)(void); /* STUPID API doesn't pass a parameter :-( */ +} TtySTblRec, *TtySTbl; + +static TtySTblRec ttyS[]={ + { "/dev/ttyS0", +#ifdef BSP_UART_IOBASE_COM1 + BSP_uart_termios_isr_com1 +#else + 0 +#endif + }, + { "/dev/ttyS1", +#ifdef BSP_UART_IOBASE_COM2 + BSP_uart_termios_isr_com2 +#else + 0 +#endif + }, +}; + /*-------------------------------------------------------------------------+ | Console device driver INITIALIZE entry point. @@ -130,7 +123,6 @@ console_initialize(rtems_device_major_number major, * to be reinitialized. */ - /* * Set up TERMIOS */ @@ -139,57 +131,66 @@ console_initialize(rtems_device_major_number major, /* * Do device-specific initialization */ - - /* 9600-8-N-1 */ - BSP_uart_init(BSPConsolePort, 9600, 0); - - - /* Set interrupt handler */ - if(BSPConsolePort == BSP_UART_COM1) - { - console_isr_data.name = BSP_ISA_UART_COM1_IRQ; - console_isr_data.hdl = BSP_uart_termios_isr_com1; - - } - else - { - assert(BSPConsolePort == BSP_UART_COM2); - console_isr_data.name = BSP_ISA_UART_COM2_IRQ; - console_isr_data.hdl = BSP_uart_termios_isr_com2; - } - status = BSP_install_rtems_irq_handler(&console_isr_data); - - if (!status){ - printk("Error installing serial console interrupt handler!\n"); - rtems_fatal_error_occurred(status); - } - /* - * Register the device + /* RTEMS calls this routine once with 'minor'==0; loop through + * all known instances... */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - { - printk("Error registering console device!\n"); - rtems_fatal_error_occurred (status); - } + + for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) { + char *nm; + /* + * Skip ports (possibly not supported by BSP...) we have no ISR for + */ + if ( ! ttyS[minor].isr ) + continue; + /* + * Register the device + */ + status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor); + if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) + { + printk("Registering /dev/console as minor %i (==%s)\n", + minor, + ttyS[minor].name); + /* also register an alias */ + status = rtems_io_register_name ( + (nm="/dev/console"), + major, + minor); + } + if (status != RTEMS_SUCCESSFUL) + { + printk("Error registering %s!\n",nm); + rtems_fatal_error_occurred (status); + } - if(BSPConsolePort == BSP_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"); - } + } return RTEMS_SUCCESSFUL; } /* console_initialize */ +static int console_first_open(int major, int minor, void *arg) +{ + rtems_status_code status; + + /* must not open a minor device we have no ISR for */ + assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr ); + + /* 9600-8-N-1 */ + BSP_uart_init(minor, 9600, 0); + status = BSP_uart_install_isr(minor, ttyS[minor].isr); + if (!status) + { + printk("Error installing serial console interrupt handler for '%s'!\n", + ttyS[minor].name); + rtems_fatal_error_occurred(status); + } + return 0; +} + static int console_last_close(int major, int minor, void *arg) { - BSP_remove_rtems_irq_handler (&console_isr_data); - + BSP_uart_remove_isr(minor, ttyS[minor].isr); return 0; } @@ -204,21 +205,16 @@ console_open(rtems_device_major_number major, rtems_status_code status; static rtems_termios_callbacks cb = { - NULL, /* firstOpen */ - console_last_close, /* lastClose */ - NULL, /* pollRead */ - BSP_uart_termios_write_com1, /* write */ - conSetAttr, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ + NULL, /* pollRead */ + BSP_uart_termios_write_com, /* write */ + conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ }; - if(BSPConsolePort == BSP_UART_COM2) - { - cb.write = BSP_uart_termios_write_com2; - } - status = rtems_termios_open (major, minor, arg, &cb); if(status != RTEMS_SUCCESSFUL) @@ -230,10 +226,10 @@ console_open(rtems_device_major_number major, /* * Pass data area info down to driver */ - BSP_uart_termios_set(BSPConsolePort, + BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1); /* Enable interrupts on channel */ - BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS); + BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS); return RTEMS_SUCCESSFUL; } @@ -362,10 +358,7 @@ conSetAttr(int minor, const struct termios *t) return 0; } - BSP_uart_set_baud(BSPConsolePort, baud); + BSP_uart_set_baud(minor, baud); return 0; } - - - diff --git a/c/src/lib/libbsp/powerpc/shared/console/consoleIo.h b/c/src/lib/libbsp/powerpc/shared/console/consoleIo.h index c88fe3def9..50ad0428a4 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/consoleIo.h +++ b/c/src/lib/libbsp/powerpc/shared/console/consoleIo.h @@ -26,16 +26,12 @@ typedef volatile unsigned char * __io_ptr; typedef struct { __io_ptr io_base; __io_ptr isa_mem_base; - __io_ptr pci_mmio_base; - __io_ptr pci_dma_offset; } board_memory_map; extern board_memory_map *ptr_mem_map; -extern unsigned long ticks_per_ms; extern int select_console(ioType t); /* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */ -extern void udelay(int); extern void debug_putc(const unsigned char c); extern int debug_getc(void); extern int debug_tstc(void); diff --git a/c/src/lib/libbsp/powerpc/shared/console/inch.c b/c/src/lib/libbsp/powerpc/shared/console/inch.c index 5cd7148e97..eaa6224529 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/inch.c +++ b/c/src/lib/libbsp/powerpc/shared/console/inch.c @@ -22,12 +22,14 @@ #include #include +#include "console.inl" + /*-------------------------------------------------------------------------+ | Constants +--------------------------------------------------------------------------*/ -#define KBD_CTL 0x61 /* -------------------------------- */ -#define KBD_DATA 0x60 /* Ports for PC keyboard controller */ -#define KBD_STATUS 0x64 /* -------------------------------- */ +#define KBD_CTL 0x1 /* -------------------------------- */ +#define KBD_DATA 0x0 /* Port offsets for PC keyboard controller */ +#define KBD_STATUS 0x4 /* -------------------------------- */ #define KBD_BUF_SIZE 256 @@ -61,19 +63,6 @@ static rtems_unsigned16 kbd_first = 0; static rtems_unsigned16 kbd_last = 0; static rtems_unsigned16 kbd_end = KBD_BUF_SIZE - 1; -/*-------------------------------------------------------------------------+ -| Function: rtemsReboot -| Description: Reboot the PC. -| Global Variables: None. -| Arguments: None. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -void rtemsReboot(void) -{ - /* shutdown and reboot */ - outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */ -} /* rtemsReboot */ - /*-------------------------------------------------------------------------+ | Function: _IBMPC_scankey | Description: This function can be called during a poll for input, or by @@ -97,18 +86,18 @@ _IBMPC_scankey(char *outChar) *outChar = NULL; /* default value if we return FALSE */ /* Read keyboard controller, toggle enable */ - inport_byte(KBD_CTL, inChar); - outport_byte(KBD_CTL, inChar & ~0x80); - outport_byte(KBD_CTL, inChar | 0x80); - outport_byte(KBD_CTL, inChar & ~0x80); + inChar=kbd_inb(KBD_CTL); + kbd_outb(KBD_CTL, inChar & ~0x80); + kbd_outb(KBD_CTL, inChar | 0x80); + kbd_outb(KBD_CTL, inChar & ~0x80); /* See if it has data */ - inport_byte(KBD_STATUS, inChar); + inChar=kbd_inb(KBD_STATUS); if ((inChar & 0x01) == 0) return FALSE; /* Read the data. Handle nonsense with shift, control, etc. */ - inport_byte(KBD_DATA, inChar); + inChar=kbd_inb(KBD_DATA); if (extended) extended--; diff --git a/c/src/lib/libbsp/powerpc/shared/console/polled_io.c b/c/src/lib/libbsp/powerpc/shared/console/polled_io.c index 2f1a399e71..6c3e0b401e 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/polled_io.c +++ b/c/src/lib/libbsp/powerpc/shared/console/polled_io.c @@ -20,17 +20,34 @@ #include #include #include -#include "keyboard.h" #include #include #include #include +#include #include +#ifdef BSP_KBD_IOBASE +#define USE_KBD_SUPPORT +#endif +#ifdef BSP_VGA_IOBASE +#define USE_VGA_SUPPORT +#endif + +#ifdef USE_KBD_SUPPORT +#include "keyboard.h" +#endif +#include "console.inl" + +#ifdef __BOOT__ +extern void boot_udelay(); +#endif + typedef unsigned long long u64; typedef long long s64; typedef unsigned int u32; +#ifdef USE_KBD_SUPPORT unsigned short plain_map[NR_KEYS] = { 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, @@ -296,10 +313,11 @@ unsigned int accent_table_size = 68; /* These #defines have been copied from drivers/char/pc_keyb.h, by * Martin Mares (mj@ucw.cz). + * converted to offsets by Till Straumann */ -#define KBD_STATUS_REG 0x64 /* Status register (R) */ -#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ -#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ +#define KBD_STATUS_REG 0x4 /* Status register (R) */ +#define KBD_CNTL_REG 0x4 /* Controller command register (W) */ +#define KBD_DATA_REG 0x0 /* Keyboard data register (R/W) */ /* * Keyboard Controller Commands @@ -356,6 +374,8 @@ unsigned int accent_table_size = 68; SPR_RW(DEC) SPR_RO(PVR) +#endif /* USE_KBD_SUPPORT */ + /* Early messages after mm init but before console init are kept in log * buffers. @@ -377,10 +397,8 @@ static u_char log_page_pool [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE]; #endif static board_memory_map mem_map = { - (__io_ptr) 0x80000000, - (__io_ptr) 0xc0000000, - (__io_ptr) 0xc0000000, - (__io_ptr) 0x80000000 + (__io_ptr) _IO_BASE, /* from libcpu/io.h */ + (__io_ptr) _ISA_MEM_BASE, }; board_memory_map *ptr_mem_map = &mem_map; @@ -404,18 +422,6 @@ typedef struct console_io { extern console_io* curIo; -unsigned long ticks_per_ms = 1000000; /* Decrementer ticks per ms (true for 601) */ - -/* The decrementer is present on all processors and the RTC on the 601 - * has the annoying characteristic of jumping from 1e9 to 0, so we - * use the decrementer. - */ -void udelay(int us) { - us = us*ticks_per_ms/1000; - _write_DEC(us); - while((int)_read_DEC() >= 0); -} - void debug_putc(const u_char c) { curIo->putc(c); @@ -473,7 +479,6 @@ int vacuum_tstc(void) { #define LSR_TEMT 0x40 /* Xmitter empty */ #define LSR_ERR 0x80 /* Error */ -#define COM1 0x3F8 #ifdef STATIC_LOG_ALLOC static int global_index = 0; @@ -543,23 +548,28 @@ void flush_log(void) { } } +#ifndef INL_CONSOLE_INB +#error "BSP probably didn't define a console port" +#endif + void serial_putc(const u_char c) { - while ((inb(COM1+lsr) & LSR_THRE) == 0) ; - outb(c, COM1+thr); + while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ; + INL_CONSOLE_OUTB(thr, c); } int serial_getc(void) { - while ((inb(COM1+lsr) & LSR_DR) == 0) ; - return (inb(COM1+rbr)); + while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ; + return (INL_CONSOLE_INB(rbr)); } int serial_tstc(void) { - return ((inb(COM1+lsr) & LSR_DR) != 0); + return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0); } +#ifdef USE_VGA_SUPPORT static void scroll(void) { int i; @@ -579,10 +589,10 @@ static void cursor(int x, int y) { int pos = console_global_data.cols*y + x; - outb(14, 0x3D4); - outb(pos>>8, 0x3D5); - outb(15, 0x3D4); - outb(pos, 0x3D5); + vga_outb(14, 0x14); + vga_outb(0x15, pos>>8); + vga_outb(0x14, 15); + vga_outb(0x15, pos); } void @@ -620,16 +630,18 @@ vga_putc(const u_char c) console_global_data.orig_x = x; console_global_data.orig_y = y; } +#endif /* USE_VGA_SUPPORT */ +#ifdef USE_KBD_SUPPORT /* Keyboard support */ static int kbd_getc(void) { unsigned char dt, brk, val; unsigned code; loop: - while((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; + while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; - dt = inb(KBD_DATA_REG); + dt = kbd_inb(KBD_DATA_REG); brk = dt & 0x80; /* brk == 1 on key release */ dt = dt & 0x7f; /* keycode */ @@ -667,8 +679,8 @@ loop: else if (val == KVAL(K_ENTER)) { enter: /* Wait for key up */ while (1) { - while((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; - dt = inb(KBD_DATA_REG); + while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; + dt = kbd_inb(KBD_DATA_REG); if (dt & 0x80) /* key up */ break; } return 10; @@ -732,25 +744,33 @@ enter: /* Wait for key up */ static int kbd_get(int ms) { int status, data; while(1) { - status = inb(KBD_STATUS_REG); + status = kbd_inb(KBD_STATUS_REG); if (status & KBD_STAT_OBF) { - data = inb(KBD_DATA_REG); + data = kbd_inb(KBD_DATA_REG); if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) return -1; else return data; } if (--ms < 0) return -1; - udelay(1000); +#ifdef __BOOT__ + boot_udelay(1000); +#else + rtems_bsp_delay(1000); +#endif } } static void kbd_put(u_char c, int ms, int port) { - while (inb(KBD_STATUS_REG) & KBD_STAT_IBF) { + while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) { if (--ms < 0) return; - udelay(1000); +#ifdef __BOOT__ + boot_udelay(1000); +#else + rtems_bsp_delay(1000); +#endif } - outb(c, port); + kbd_outb(port, c); } int kbdreset(void) @@ -796,8 +816,9 @@ int kbdreset(void) int kbd_tstc(void) { - return ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0); + return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0); } +#endif /* USE_KBD_SUPPORT */ const struct console_io vacuum_console_functions = { @@ -811,19 +832,22 @@ log_console_functions = { log_putc, vacuum_getc, vacuum_tstc -}, - +} +, serial_console_functions = { serial_putc, serial_getc, serial_tstc -}, - +} +#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT) +, vga_console_functions = { vga_putc, kbd_getc, kbd_tstc -}; +} +#endif +; console_io* curIo = (console_io*) &vacuum_console_functions; @@ -834,7 +858,9 @@ int select_console(ioType t) { case CONSOLE_VACUUM : curIo = (console_io*)&vacuum_console_functions; break; case CONSOLE_LOG : curIo = (console_io*)&log_console_functions; break; case CONSOLE_SERIAL : curIo = (console_io*)&serial_console_functions; break; +#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT) case CONSOLE_VGA : curIo = (console_io*)&vga_console_functions; break; +#endif default : curIo = (console_io*)&vacuum_console_functions;break; } if (curType == CONSOLE_LOG) flush_log(); diff --git a/c/src/lib/libbsp/powerpc/shared/console/uart.c b/c/src/lib/libbsp/powerpc/shared/console/uart.c index da44cc2e99..8ad744d06b 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/uart.c +++ b/c/src/lib/libbsp/powerpc/shared/console/uart.c @@ -19,12 +19,42 @@ struct uart_data { + unsigned long ioBase; int hwFlow; int baud; }; -static struct uart_data uart_data[2]; +/* + * Initialization of BSP specific data. + * The constants are pulled in from a BSP + * specific file, whereas all of the code + * in this file is generic and makes no + * assumptions about addresses, irq vectors + * etc... + */ + +#define UART_UNSUPP ((unsigned long)(-1)) + +static struct uart_data uart_data[2] = { + { +#ifdef BSP_UART_IOBASE_COM1 + BSP_UART_IOBASE_COM1, +#else + UART_UNSUPP, +#endif + }, + { +#ifdef BSP_UART_IOBASE_COM2 + BSP_UART_IOBASE_COM2, +#else + UART_UNSUPP, +#endif + }, +}; +#define MAX_UARTS (sizeof(uart_data)/sizeof(uart_data[0])) +#define SANITY_CHECK(uart) \ + assert( MAX_UARTS > (unsigned)(uart) && uart_data[(uart)].ioBase != UART_UNSUPP ) /* * Macros to read/wirte register of uart, if configuration is * different just rewrite these macros @@ -33,31 +63,15 @@ static struct uart_data uart_data[2]; static inline unsigned char uread(int uart, unsigned int reg) { - register unsigned char val; - if(uart == 0) - { - inport_byte(COM1_BASE_IO+reg, val); - } - else - { - inport_byte(COM2_BASE_IO+reg, val); - } + return in_8((unsigned char*)(uart_data[uart].ioBase + reg)); - return val; } static inline void uwrite(int uart, int reg, unsigned int val) { - if(uart == 0) - { - outport_byte(COM1_BASE_IO+reg, val); - } - else - { - outport_byte(COM2_BASE_IO+reg, val); - } + out_8((unsigned char*)(uart_data[uart].ioBase + reg), val); } #ifdef UARTDEBUG @@ -103,7 +117,7 @@ BSP_uart_init(int uart, int baud, int hwFlow) unsigned char tmp; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); switch(baud) { @@ -166,7 +180,7 @@ BSP_uart_set_baud(int uart, int baud) unsigned char mcr, ier; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); /* * This function may be called whenever TERMIOS parameters @@ -197,7 +211,7 @@ void BSP_uart_intr_ctrl(int uart, int cmd) { - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); switch(cmd) { @@ -260,7 +274,7 @@ BSP_uart_throttle(int uart) { unsigned int mcr; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); if(!uart_data[uart].hwFlow) { @@ -281,7 +295,7 @@ BSP_uart_unthrottle(int uart) { unsigned int mcr; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); if(!uart_data[uart].hwFlow) { @@ -311,7 +325,7 @@ BSP_uart_polled_status(int uart) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); val = uread(uart, LSR); @@ -353,7 +367,7 @@ BSP_uart_polled_write(int uart, int val) unsigned char val1; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); for(;;) { @@ -394,7 +408,7 @@ BSP_uart_polled_read(int uart) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); for(;;) { @@ -415,20 +429,57 @@ BSP_poll_char_via_serial() return BSP_uart_polled_read(BSPConsolePort); } +static void +uart_noop(const rtems_irq_connect_data *unused) +{ + return; +} + +/* note that the IRQ names contain _ISA_ for legacy + * reasons. They can be any interrupt, depending + * on the particular BSP... + */ -/* ================ Termios support =================*/ +static int +uart_isr_is_on(const rtems_irq_connect_data *irq) +{ +int uart = (irq->name == BSP_ISA_UART_COM1_IRQ) ? + BSP_UART_COM1 : BSP_UART_COM2; + return uread(uart,IER); +} -static volatile int termios_stopped_com1 = 0; -static volatile int termios_tx_active_com1 = 0; -static void* termios_ttyp_com1 = NULL; -static char termios_tx_hold_com1 = 0; -static volatile char termios_tx_hold_valid_com1 = 0; +static int +doit(int uart, rtems_irq_hdl handler, int (*p)(const rtems_irq_connect_data*)) +{ + rtems_irq_connect_data d={0}; + d.name = (uart == BSP_UART_COM1) ? + BSP_ISA_UART_COM1_IRQ : BSP_ISA_UART_COM2_IRQ; + d.off = d.on = uart_noop; + d.isOn = uart_isr_is_on; + d.hdl = handler; + return p(&d); +} -static volatile int termios_stopped_com2 = 0; -static volatile int termios_tx_active_com2 = 0; -static void* termios_ttyp_com2 = NULL; -static char termios_tx_hold_com2 = 0; -static volatile char termios_tx_hold_valid_com2 = 0; +int +BSP_uart_install_isr(int uart, rtems_irq_hdl handler) +{ + return doit(uart, handler, BSP_install_rtems_irq_handler); +} + +int +BSP_uart_remove_isr(int uart, rtems_irq_hdl handler) +{ + return doit(uart, handler, BSP_remove_rtems_irq_handler); +} + + +/* ================ Termios support =================*/ + +static volatile int termios_stopped_com[2] = {0,0}; +static volatile int termios_tx_active_com[2] = {0,0}; +static void* termios_ttyp_com[2] = {NULL,NULL}; +static char termios_tx_hold_com[2] = {0,0}; +static volatile char termios_tx_hold_valid_com[2] = {0,0}; /* * Set channel parameters @@ -437,49 +488,30 @@ void BSP_uart_termios_set(int uart, void *ttyp) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); - if(uart == BSP_UART_COM1) + if(uart_data[uart].hwFlow) { - if(uart_data[uart].hwFlow) - { - val = uread(uart, MSR); + val = uread(uart, MSR); - termios_stopped_com1 = (val & CTS) ? 0 : 1; - } - else - { - termios_stopped_com1 = 0; - } - termios_tx_active_com1 = 0; - termios_ttyp_com1 = ttyp; - termios_tx_hold_com1 = 0; - termios_tx_hold_valid_com1 = 0; + termios_stopped_com[uart] = (val & CTS) ? 0 : 1; } else - { - if(uart_data[uart].hwFlow) - { - val = uread(uart, MSR); - - termios_stopped_com2 = (val & CTS) ? 0 : 1; - } - else - { - termios_stopped_com2 = 0; - } - termios_tx_active_com2 = 0; - termios_ttyp_com2 = ttyp; - termios_tx_hold_com2 = 0; - termios_tx_hold_valid_com2 = 0; - } + { + termios_stopped_com[uart] = 0; + } + termios_tx_active_com[uart] = 0; + termios_ttyp_com[uart] = ttyp; + termios_tx_hold_com[uart] = 0; + termios_tx_hold_valid_com[uart] = 0; return; } int -BSP_uart_termios_write_com1(int minor, const char *buf, int len) +BSP_uart_termios_write_com(int minor, const char *buf, int len) { + int uart=minor; /* could differ, theoretically */ assert(buf != NULL); if(len <= 0) @@ -491,22 +523,22 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) /* assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */ - if(termios_stopped_com1) + if(termios_stopped_com[uart]) { /* CTS low */ - termios_tx_hold_com1 = *buf; - termios_tx_hold_valid_com1 = 1; + termios_tx_hold_com[uart] = *buf; + termios_tx_hold_valid_com[uart] = 1; return 0; } /* Write character */ - uwrite(BSP_UART_COM1, THR, *buf & 0xff); + uwrite(uart, THR, *buf & 0xff); /* Enable interrupts if necessary */ - if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow) + if(!termios_tx_active_com[uart] && uart_data[uart].hwFlow) { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, (RECEIVE_ENABLE | TRANSMIT_ENABLE | RECEIVER_LINE_ST_ENABLE | @@ -514,10 +546,10 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) ) ); } - else if(!termios_tx_active_com1) + else if(!termios_tx_active_com[uart]) { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, (RECEIVE_ENABLE | TRANSMIT_ENABLE | RECEIVER_LINE_ST_ENABLE @@ -528,61 +560,8 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) return 0; } -int -BSP_uart_termios_write_com2(int minor, const char *buf, int len) -{ - assert(buf != NULL); - - if(len <= 0) - { - return 0; - } - - - /* If there TX buffer is busy - something is royally screwed up */ - assert((uread(BSP_UART_COM2, LSR) & THRE) != 0); - - if(termios_stopped_com2) - { - /* CTS low */ - termios_tx_hold_com2 = *buf; - termios_tx_hold_valid_com2 = 1; - return 0; - } - - /* Write character */ - - uwrite(BSP_UART_COM2, THR, *buf & 0xff); - - /* Enable interrupts if necessary */ - if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else if(!termios_tx_active_com2) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } - - return 0; -} - - -void -BSP_uart_termios_isr_com1(void) +static void +BSP_uart_termios_isr_com(int uart) { unsigned char buf[40]; unsigned char val; @@ -592,29 +571,29 @@ BSP_uart_termios_isr_com1(void) for(;;) { - vect = uread(BSP_UART_COM1, IIR) & 0xf; + vect = uread(uart, IIR) & 0xf; switch(vect) { case MODEM_STATUS : - val = uread(BSP_UART_COM1, MSR); - if(uart_data[BSP_UART_COM1].hwFlow) + val = uread(uart, MSR); + if(uart_data[uart].hwFlow) { if(val & CTS) { /* CTS high */ - termios_stopped_com1 = 0; - if(termios_tx_hold_valid_com1) + termios_stopped_com[uart] = 0; + if(termios_tx_hold_valid_com[uart]) { - termios_tx_hold_valid_com1 = 0; - BSP_uart_termios_write_com1(0, &termios_tx_hold_com1, + termios_tx_hold_valid_com[uart] = 0; + BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart], 1); } } else { /* CTS low */ - termios_stopped_com1 = 1; + termios_stopped_com[uart] = 1; } } break; @@ -623,7 +602,7 @@ BSP_uart_termios_isr_com1(void) if(off != 0) { /* Update rx buffer */ - rtems_termios_enqueue_raw_characters(termios_ttyp_com1, + rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], (char *)buf, off); } @@ -634,38 +613,38 @@ BSP_uart_termios_isr_com1(void) * if there is nothing more to send. */ - ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1); + ret = rtems_termios_dequeue_characters(termios_ttyp_com[uart], 1); /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow) + if(ret == 0 && uart_data[uart].hwFlow) { - uwrite(BSP_UART_COM1, IER, + uwrite(uart, IER, (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | MODEM_ENABLE ) ); - termios_tx_active_com1 = 0; + termios_tx_active_com[uart] = 0; } else if(ret == 0) { - uwrite(BSP_UART_COM1, IER, + uwrite(uart, IER, (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE ) ); - termios_tx_active_com1 = 0; + termios_tx_active_com[uart] = 0; } break; case RECEIVER_DATA_AVAIL : case CHARACTER_TIMEOUT_INDICATION: /* RX data ready */ assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM1, RBR); + buf[off++] = uread(uart, RBR); break; case RECEIVER_ERROR: /* RX error: eat character */ - uartError(BSP_UART_COM1); + uartError(uart); break; default: /* Should not happen */ @@ -676,103 +655,14 @@ BSP_uart_termios_isr_com1(void) } void -BSP_uart_termios_isr_com2() +BSP_uart_termios_isr_com1(void) { - unsigned char buf[40]; - unsigned char val; - int off, ret, vect; - - off = 0; - - for(;;) - { - vect = uread(BSP_UART_COM2, IIR) & 0xf; - - switch(vect) - { - case MODEM_STATUS : - val = uread(BSP_UART_COM2, MSR); - if(uart_data[BSP_UART_COM2].hwFlow) - { - if(val & CTS) - { - /* CTS high */ - termios_stopped_com2 = 0; - if(termios_tx_hold_valid_com2) - { - termios_tx_hold_valid_com2 = 0; - BSP_uart_termios_write_com2(0, &termios_tx_hold_com2, - 1); - } - } - else - { - /* CTS low */ - termios_stopped_com2 = 1; - } - } - break; - case NO_MORE_INTR : - /* No more interrupts */ - if(off != 0) - { - /* Update rx buffer */ - rtems_termios_enqueue_raw_characters(termios_ttyp_com2, - (char *)buf, - off); - } - return; - case TRANSMITTER_HODING_REGISTER_EMPTY : - /* - * TX holding empty: we have to disable these interrupts - * if there is nothing more to send. - */ - - ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1); - - /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } - else if(ret == 0) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } - break; - case RECEIVER_DATA_AVAIL : - case CHARACTER_TIMEOUT_INDICATION: - /* RX data ready */ - assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM2, RBR); - break; - case RECEIVER_ERROR: - /* RX error: eat character */ - uartError(BSP_UART_COM2); - break; - default: - /* Should not happen */ - assert(0); - return; - } - } + BSP_uart_termios_isr_com(BSP_UART_COM1); } - - - - - - +void +BSP_uart_termios_isr_com2(void) +{ + BSP_uart_termios_isr_com(BSP_UART_COM2); +} diff --git a/c/src/lib/libbsp/powerpc/shared/console/uart.h b/c/src/lib/libbsp/powerpc/shared/console/uart.h index e43ac9900c..6fe17d47e8 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/uart.h +++ b/c/src/lib/libbsp/powerpc/shared/console/uart.h @@ -10,6 +10,8 @@ #ifndef _BSPUART_H #define _BSPUART_H +#include + void BSP_uart_init(int uart, int baud, int hwFlow); void BSP_uart_set_baud(int aurt, int baud); void BSP_uart_intr_ctrl(int uart, int cmd); @@ -19,12 +21,14 @@ int BSP_uart_polled_status(int uart); void BSP_uart_polled_write(int uart, int val); int BSP_uart_polled_read(int uart); void BSP_uart_termios_set(int uart, void *ttyp); -int BSP_uart_termios_write_com1(int minor, const char *buf, int len); -int BSP_uart_termios_write_com2(int minor, const char *buf, int len); +int BSP_uart_termios_write_com(int minor, const char *buf, int len); void BSP_uart_termios_isr_com1(); void BSP_uart_termios_isr_com2(); void BSP_uart_dbgisr_com1(void); void BSP_uart_dbgisr_com2(void); +int BSP_uart_install_isr(int uart, rtems_irq_hdl handler); +int BSP_uart_remove_isr(int uart, rtems_irq_hdl handler); + extern unsigned BSP_poll_char_via_serial(void); extern void BSP_output_char_via_serial(int val); extern int BSPConsolePort; @@ -49,13 +53,6 @@ extern int BSPBaseBaud; #define BSP_UART_COM1 (0) #define BSP_UART_COM2 (1) -/* - * Base IO for UART - */ - -#define COM1_BASE_IO 0x3F8 -#define COM2_BASE_IO 0x2F8 - /* * Offsets from base */ diff --git a/c/src/lib/libbsp/powerpc/shared/include/bsp.h b/c/src/lib/libbsp/powerpc/shared/include/bsp.h index 1f969ce9ef..b2062c3914 100644 --- a/c/src/lib/libbsp/powerpc/shared/include/bsp.h +++ b/c/src/lib/libbsp/powerpc/shared/include/bsp.h @@ -26,9 +26,33 @@ * - Interrupt stack space is not minimum if defined. */ -/* #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 */ +#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 #define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024) + +/* fundamental addresses for this BSP (PREPxxx are from libcpu/io.h) */ +#define _IO_BASE PREP_ISA_IO_BASE +#define _ISA_MEM_BASE PREP_ISA_MEM_BASE +/* address of our ram on the PCI bus */ +#define PCI_DRAM_OFFSET PREP_PCI_DRAM_OFFSET +/* offset of pci memory as seen from the CPU */ +#define PCI_MEM_BASE PREP_ISA_MEM_BASE + +/* + * base address definitions for several devices + * + */ +#define BSP_UART_IOBASE_COM1 ((_IO_BASE)+0x3f8) +#define BSP_UART_IOBASE_COM2 ((_IO_BASE)+0x2f8) +#define BSP_KBD_IOBASE ((_IO_BASE)+0x60) +#define BSP_VGA_IOBASE ((_IO_BASE)+0x3c0) + +#define BSP_CONSOLE_PORT BSP_UART_COM1 +#define BSP_UART_BAUD_BASE 115200 +#include +#define BSP_PIC_DO_EOI openpic_eoi(0) + + #ifndef ASM #define outport_byte(port,value) outb(value,port) #define outport_word(port,value) outw(value,port) diff --git a/c/src/lib/libbsp/powerpc/shared/irq/Makefile.am b/c/src/lib/libbsp/powerpc/shared/irq/Makefile.am index 326ec19e19..b6d083eb53 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/Makefile.am +++ b/c/src/lib/libbsp/powerpc/shared/irq/Makefile.am @@ -21,6 +21,6 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \ all-local: $(PREINSTALL_FILES) -EXTRA_DIST = i8259.c irq.c irq.h irq_asm.S irq_init.c +EXTRA_DIST = i8259.c irq.c irq_asm.S irq_init.c include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq.c b/c/src/lib/libbsp/powerpc/shared/irq/irq.c index b2c97de842..939e8678dc 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq.c +++ b/c/src/lib/libbsp/powerpc/shared/irq/irq.c @@ -20,6 +20,7 @@ #include #include +#include /* for printk */ #define RAVEN_INTR_ACK_REG 0xfeff0030 /* @@ -124,6 +125,7 @@ int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) unsigned int level; if (!isValidInterrupt(irq->name)) { + printk("Invalid interrupt vector %i\n",irq->name); return 0; } /* @@ -134,6 +136,7 @@ int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) * to get the previous handler before accepting to disconnect. */ if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) { + printk("IRQ vector %i already connected\n",irq->name); return 0; } _CPU_ISR_Disable(level); @@ -372,7 +375,14 @@ void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum) outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); } else { - openpic_eoi(0); +#ifdef BSP_PCI_VME_BRIDGE_DOES_EOI + /* leave it to the VME bridge to do EOI, so + * it can re-enable the openpic while handling + * VME interrupts (-> VME priorities in software) + */ + if (BSP_PCI_VME_BRIDGE_IRQ!=irq) +#endif + openpic_eoi(0); } } diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq.h b/c/src/lib/libbsp/powerpc/shared/irq/irq.h index aaf438c8dd..a356762e4f 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq.h +++ b/c/src/lib/libbsp/powerpc/shared/irq/irq.h @@ -87,12 +87,17 @@ typedef enum { BSP_PROCESSOR_IRQ_NUMBER = 1, BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_PCI_IRQ_MAX_OFFSET + 1, BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1, + /* Misc vectors for OPENPIC irqs (IPI, timers) + */ + BSP_MISC_IRQ_NUMBER = 8, + BSP_MISC_IRQ_LOWEST_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1, + BSP_MISC_IRQ_MAX_OFFSET = BSP_MISC_IRQ_LOWEST_OFFSET + BSP_MISC_IRQ_NUMBER - 1, /* * Summary */ - BSP_IRQ_NUMBER = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1, + BSP_IRQ_NUMBER = BSP_MISC_IRQ_MAX_OFFSET + 1, BSP_LOWEST_OFFSET = BSP_ISA_IRQ_LOWEST_OFFSET, - BSP_MAX_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET, + BSP_MAX_OFFSET = BSP_MISC_IRQ_MAX_OFFSET, /* * Some ISA IRQ symbolic name definition */ diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c index 00ad78b319..d3fb5aec59 100644 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c +++ b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @@ -8,6 +8,9 @@ * Enhanced by Jay Kulpinski * to make it valid for MVME2300 Motorola boards. * + * Till Straumann , 12/20/2001: + * Use the new interface to openpic_init + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. @@ -89,6 +92,11 @@ static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={ 0 }; +static unsigned char mcp750_openpic_initpolarities[16] = { + 1, /* 8259 cascade */ + 0, /* all the rest of them */ +}; + static unsigned char mcp750_openpic_initsenses[] = { 1, /* MCP750_INT_PCB(8259) */ 0, /* MCP750_INT_FALCON_ECC_ERR */ @@ -226,12 +234,10 @@ void BSP_rtems_irq_mng_init(unsigned cpuId) /* * First initialize the Interrupt management hardware */ - OpenPIC_InitSenses = mcp750_openpic_initsenses; - OpenPIC_NumInitSenses = sizeof(mcp750_openpic_initsenses) / sizeof(char); #ifdef TRACE_IRQ_INIT printk("Going to initialize raven interrupt controller (openpic compliant)\n"); #endif - openpic_init(1); + openpic_init(1, mcp750_openpic_initsenses, mcp750_openpic_initpolarities); #ifdef TRACE_IRQ_INIT printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n"); #endif diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c index b27790a757..918ddfad10 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c @@ -26,15 +26,16 @@ #include #include #include +#include +#ifndef NULL #define NULL 0 +#endif #define REGISTER_DEBUG #undef REGISTER_DEBUG volatile struct OpenPIC *OpenPIC = NULL; -unsigned int OpenPIC_NumInitSenses = 0; -unsigned char *OpenPIC_InitSenses = NULL; static unsigned int NumProcessors; static unsigned int NumSources; @@ -157,9 +158,13 @@ static void openpic_safe_writefield(volatile unsigned int *addr, unsigned int ma * Add some kludge to use the Motorola Raven OpenPIC which does not * report vendor and device id, and gets the wrong number of interrupts. * (Motorola did a great job on that one!) + * + * T. Straumann, 12/20/2001: polarities and senses are now passed as + * parameters, eliminated global vars. + * IRQ0 is no longer treated specially. */ -void openpic_init(int main_pic) +void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses) { unsigned int t, i; unsigned int vendorid, devid, stepping, timerfreq; @@ -250,10 +255,11 @@ void openpic_init(int main_pic) openpic_initirq(0, 8, OPENPIC_VEC_SOURCE, 1, 1); /* Processor 0 */ openpic_mapirq(0, 1<<0); - for (i = 1; i < NumSources; i++) { + for (i = 0; i < NumSources; i++) { /* Enabled, Priority 8 */ - openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i, 0, - i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); + openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i, + polarities ? polarities[i] : 0, + senses ? senses[i] : 1); /* Processor 0 */ openpic_mapirq(i, 1<<0); } diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h index 97faec1e9d..152636df82 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h @@ -191,8 +191,6 @@ struct OpenPIC { }; extern volatile struct OpenPIC *OpenPIC; -extern unsigned int OpenPIC_NumInitSenses; -extern unsigned char *OpenPIC_InitSenses; /* @@ -309,7 +307,7 @@ extern unsigned char *OpenPIC_InitSenses; */ /* Global Operations */ -extern void openpic_init(int); +extern void openpic_init(int,unsigned char *, unsigned char *); extern void openpic_reset(void); extern void openpic_enable_8259_pass_through(void); extern void openpic_disable_8259_pass_through(void); diff --git a/c/src/lib/libbsp/powerpc/shared/pci/Makefile.am b/c/src/lib/libbsp/powerpc/shared/pci/Makefile.am index 4dc5a15453..e196f26c44 100644 --- a/c/src/lib/libbsp/powerpc/shared/pci/Makefile.am +++ b/c/src/lib/libbsp/powerpc/shared/pci/Makefile.am @@ -3,7 +3,7 @@ ## -C_FILES = pci.c +C_FILES = pci.c detect_raven_bridge.c pcifinddevice.c H_FILES = pci.h @@ -18,6 +18,6 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \ all-local: $(PREINSTALL_FILES) -EXTRA_DIST = pci.c pci.h +EXTRA_DIST = pci.c pci.h detect_raven_bridge.c pcifinddevice.c include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/shared/pci/pci.c b/c/src/lib/libbsp/powerpc/shared/pci/pci.c index 233a2efc00..a6d615cea6 100644 --- a/c/src/lib/libbsp/powerpc/shared/pci/pci.c +++ b/c/src/lib/libbsp/powerpc/shared/pci/pci.c @@ -14,26 +14,27 @@ * http://www.OARcorp.com/rtems/license.html. * * $Id$ + * + * Till Straumann, , 1/2002 + * - separated bridge detection code out of this file */ -#include #include #include -#include -#include -#include +/* allow for overriding these definitions */ +#ifndef PCI_CONFIG_ADDR #define PCI_CONFIG_ADDR 0xcf8 +#endif +#ifndef PCI_CONFIG_DATA #define PCI_CONFIG_DATA 0xcfc +#endif + #define PCI_INVALID_VENDORDEVICEID 0xffffffff #define PCI_MULTI_FUNCTION 0x80 -#define RAVEN_MPIC_IOSPACE_ENABLE 0x1 -#define RAVEN_MPIC_MEMSPACE_ENABLE 0x2 -#define RAVEN_MASTER_ENABLE 0x4 -#define RAVEN_PARITY_CHECK_ENABLE 0x40 -#define RAVEN_SYSTEM_ERROR_ENABLE 0x100 -#define RAVEN_CLEAR_EVENTS_MASK 0xf9000000 +/* define a shortcut */ +#define pci BSP_pci_configuration /* * Bit encode for PCI_CONFIG_HEADER_TYPE register @@ -106,7 +107,7 @@ indirect_pci_write_config_dword(unsigned char bus, unsigned char slot, return PCIBIOS_SUCCESSFUL; } -static const pci_config_access_functions indirect_functions = { +const pci_config_access_functions pci_indirect_functions = { indirect_pci_read_config_byte, indirect_pci_read_config_word, indirect_pci_read_config_dword, @@ -115,9 +116,9 @@ static const pci_config_access_functions indirect_functions = { indirect_pci_write_config_dword }; -pci_config pci = {(volatile unsigned char*)PCI_CONFIG_ADDR, +pci_config BSP_pci_configuration = {(volatile unsigned char*)PCI_CONFIG_ADDR, (volatile unsigned char*)PCI_CONFIG_DATA, - &indirect_functions}; + &pci_indirect_functions}; static int direct_pci_read_config_byte(unsigned char bus, unsigned char slot, @@ -205,7 +206,7 @@ direct_pci_write_config_dword(unsigned char bus, unsigned char slot, return PCIBIOS_SUCCESSFUL; } -static const pci_config_access_functions direct_functions = { +const pci_config_access_functions pci_direct_functions = { direct_pci_read_config_byte, direct_pci_read_config_word, direct_pci_read_config_dword, @@ -215,99 +216,12 @@ static const pci_config_access_functions direct_functions = { }; -void detect_host_bridge() -{ - PPC_DEVICE *hostbridge; - unsigned int id0; - unsigned int tmp; - - /* - * This code assumes that the host bridge is located at - * bus 0, dev 0, func 0 AND that the old pre PCI 2.1 - * standart devices detection mecahnism that was used on PC - * (still used in BSD source code) works. - */ - hostbridge=residual_find_device(&residualCopy, PROCESSORDEVICE, NULL, - BridgeController, - PCIBridge, -1, 0); - if (hostbridge) { - if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) { - pci.pci_functions=&indirect_functions; - /* Should be extracted from residual data, - * indeed MPC106 in CHRP mode is different, - * but we should not use residual data in - * this case anyway. - */ - pci.pci_config_addr = ((volatile unsigned char *) - (ptr_mem_map->io_base+0xcf8)); - pci.pci_config_data = ptr_mem_map->io_base+0xcfc; - } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) { - pci.pci_functions=&direct_functions; - pci.pci_config_data=(unsigned char *) 0x80800000; - } else { - } - } else { - /* Let us try by experimentation at our own risk! */ - pci.pci_functions = &direct_functions; - /* On all direct bridges I know the host bridge itself - * appears as device 0 function 0. - */ - pci_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &id0); - if (id0==~0U) { - pci.pci_functions = &indirect_functions; - pci.pci_config_addr = ((volatile unsigned char*) - (ptr_mem_map->io_base+0xcf8)); - pci.pci_config_data = ((volatile unsigned char*)ptr_mem_map->io_base+0xcfc); - } - /* Here we should check that the host bridge is actually - * present, but if it not, we are in such a desperate - * situation, that we probably can't even tell it. - */ - } - pci_read_config_dword(0, 0, 0, 0, &id0); - if(id0 == PCI_VENDOR_ID_MOTOROLA + - (PCI_DEVICE_ID_MOTOROLA_RAVEN<<16)) { - /* - * We have a Raven bridge. We will get information about its settings - */ - pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); -#ifdef SHOW_RAVEN_SETTING - printk("RAVEN PCI command register = %x\n",id0); -#endif - id0 |= RAVEN_CLEAR_EVENTS_MASK; - pci_write_config_dword(0, 0, 0, PCI_COMMAND, id0); - pci_read_config_dword(0, 0, 0, PCI_COMMAND, &id0); -#ifdef SHOW_RAVEN_SETTING - printk("After error clearing RAVEN PCI command register = %x\n",id0); -#endif - - if (id0 & RAVEN_MPIC_IOSPACE_ENABLE) { - pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_0, &tmp); -#ifdef SHOW_RAVEN_SETTING - printk("Raven MPIC is accessed via IO Space Access at address : %x\n",(tmp & ~0x1)); -#endif - } - if (id0 & RAVEN_MPIC_MEMSPACE_ENABLE) { - pci_read_config_dword(0, 0, 0,PCI_BASE_ADDRESS_1, &tmp); -#ifdef SHOW_RAVEN_SETTING - printk("Raven MPIC is accessed via memory Space Access at address : %x\n", tmp); -#endif - OpenPIC=(volatile struct OpenPIC *) (tmp + PREP_ISA_MEM_BASE); - printk("OpenPIC found at %p.\n", - OpenPIC); - } - } - if (OpenPIC == (volatile struct OpenPIC *)0) { - BSP_panic("OpenPic Not found\n"); - } - -} - /* * This routine determines the maximum bus number in the system */ void InitializePCI() { + extern void detect_host_bridge(); unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs; unsigned char ucHeader; unsigned char ucMaxSubordinate; diff --git a/c/src/lib/libbsp/powerpc/shared/pci/pci.h b/c/src/lib/libbsp/powerpc/shared/pci/pci.h index 2070bb434d..7327a6afbc 100644 --- a/c/src/lib/libbsp/powerpc/shared/pci/pci.h +++ b/c/src/lib/libbsp/powerpc/shared/pci/pci.h @@ -1082,7 +1082,10 @@ #define PCIBIOS_SET_FAILED 0x88 #define PCIBIOS_BUFFER_TOO_SMALL 0x89 -#define PCI_MAX_DEVICES 16 +/* T. Straumann, 7/31/2001: increased to 32 - PMC slots are not + * scanned on mvme2306 otherwise + */ +#define PCI_MAX_DEVICES 32 #define PCI_MAX_FUNCTIONS 8 typedef struct { @@ -1103,45 +1106,45 @@ typedef struct { typedef struct { volatile unsigned char* pci_config_addr; volatile unsigned char* pci_config_data; - pci_config_access_functions* pci_functions; + const pci_config_access_functions* pci_functions; } pci_config; -extern pci_config pci; +extern pci_config BSP_pci_configuration; extern inline int pci_read_config_byte(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned char * val) { - return pci.pci_functions->read_config_byte(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->read_config_byte(bus, slot, function, where, val); } extern inline int pci_read_config_word(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned short * val) { - return pci.pci_functions->read_config_word(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->read_config_word(bus, slot, function, where, val); } extern inline int pci_read_config_dword(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned int * val) { - return pci.pci_functions->read_config_dword(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->read_config_dword(bus, slot, function, where, val); } extern inline int pci_write_config_byte(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned char val) { - return pci.pci_functions->write_config_byte(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->write_config_byte(bus, slot, function, where, val); } extern inline int pci_write_config_word(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned short val) { - return pci.pci_functions->write_config_word(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->write_config_word(bus, slot, function, where, val); } extern inline int pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char function, unsigned char where, unsigned int val) { - return pci.pci_functions->write_config_dword(bus, slot, function, where, val); + return BSP_pci_configuration.pci_functions->write_config_dword(bus, slot, function, where, val); } /* @@ -1150,4 +1153,14 @@ pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char func extern unsigned char BusCountPCI(); extern void InitializePCI(); +/* scan for a specific device */ +/* find a particular PCI device + * (currently, only bus0 is scanned for device/fun0) + * + * RETURNS: zero on success, bus/dev/fun in *pbus / *pdev / *pfun + */ +int +BSP_pciFindDevice(unsigned short vendorid, unsigned short deviceid, + int instance, int *pbus, int *pdev, int *pfun); + #endif /* RTEMS_PCI_H */ diff --git a/c/src/lib/libbsp/powerpc/shared/residual/Makefile.am b/c/src/lib/libbsp/powerpc/shared/residual/Makefile.am index ad7f8f9a06..7fcb10f5ef 100644 --- a/c/src/lib/libbsp/powerpc/shared/residual/Makefile.am +++ b/c/src/lib/libbsp/powerpc/shared/residual/Makefile.am @@ -18,6 +18,6 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \ all-local: $(PREINSTALL_FILES) -EXTRA_DIST = pnp.h residual.c residual.h +EXTRA_DIST = residual.c include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/shared/start/start.S b/c/src/lib/libbsp/powerpc/shared/start/start.S index f2cedc9a6c..4746ab3a46 100644 --- a/c/src/lib/libbsp/powerpc/shared/start/start.S +++ b/c/src/lib/libbsp/powerpc/shared/start/start.S @@ -192,7 +192,7 @@ flush_tlbs: lis r20, 0x1000 1: addic. r20, r20, -0x1000 tlbie r20 - blt 1b + bgt 1b sync blr diff --git a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c index 04c6f48b8d..0c0ac29382 100644 --- a/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c @@ -200,6 +200,10 @@ void bsp_start( void ) * so that It can be printed without accessing R1. */ stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE; + + /* tag the bottom (T. Straumann 6/36/2001 ) */ + *((unsigned32 *)stack) = 0; + /* * Initialize the interrupt related settings * SPRG0 = interrupt nesting level count @@ -209,6 +213,10 @@ void bsp_start( void ) * some settings below... */ intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE; + + /* tag the bottom (T. Straumann 6/36/2001 ) */ + *((unsigned32 *)intrStack) = 0; + asm volatile ("mtspr 273, %0" : "=r" (intrStack) : "0" (intrStack)); asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel)); /* @@ -228,7 +236,8 @@ void bsp_start( void ) * PCI devices memory area. Needed to access OPENPIC features * provided by the RAVEN */ - setdbat(2, 0xc0000000, 0xc0000000, 0x08000000, IO_PAGE); + /* T. Straumann: give more PCI address space */ + setdbat(2, 0xc0000000, 0xc0000000, 0x10000000, IO_PAGE); /* * Must have acces to open pic PCI ACK registers * provided by the RAVEN diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S index d33f8549fb..692c1259c2 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.S @@ -85,6 +85,10 @@ SYM (push_normalized_frame): stw r30, EXC_CTR_OFFSET(r1) mfxer r28 stw r28, EXC_XER_OFFSET(r1) + mfmsr r28 + stw r28, EXC_MSR_OFFSET(r1) + mfdar r28 + stw r28, EXC_DAR_OFFSET(r1) /* * compute SP at exception entry */ diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h index 101f46f121..15eb7b6bfa 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors.h @@ -60,7 +60,8 @@ #define EXC_CTR_OFFSET 152 #define EXC_XER_OFFSET 156 #define EXC_LR_OFFSET 160 -#define EXC_DAR_OFFSET 164 +#define EXC_MSR_OFFSET 164 +#define EXC_DAR_OFFSET 168 /* * maintain the EABI requested 8 bytes aligment * As SVR4 ABI requires 16, make it 16 (as some diff --git a/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c b/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c index 9a339250e2..40b360e461 100644 --- a/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c +++ b/c/src/lib/libbsp/powerpc/shared/vectors/vectors_init.c @@ -23,6 +23,38 @@ static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; exception_handler_t globalExceptHdl; +/* T. Straumann: provide a stack trace + * , 6/26/2001 + */ +typedef struct LRFrameRec_ { + struct LRFrameRec_ *frameLink; + unsigned long *lr; +} LRFrameRec, *LRFrame; + +#define STACK_CLAMP 50 /* in case we have a corrupted bottom */ + +void +BSP_printStackTrace(BSP_Exception_frame* excPtr) +{ +LRFrame f; +int i; + + printk("Stack Trace: "); + printk(" IP: 0x%08x, LR: 0x%08x\n", + excPtr->EXC_SRR0, excPtr->EXC_LR); + for (f=(LRFrame)excPtr->GPR1, i=0; f->frameLink && iframeLink) { + printk("--^ 0x%08x", (long)(f->frameLink->lr)); + if (!(++i%5)) + printk("\n"); + } + if (i>=STACK_CLAMP) { + printk("Too many stack frames (stack possibly corrupted), giving up...\n"); + } else { + if (i%5) + printk("\n"); + } +} + void C_exception_handler(BSP_Exception_frame* excPtr) { int recoverable = 0; @@ -66,7 +98,10 @@ void C_exception_handler(BSP_Exception_frame* excPtr) printk("\t CTR = %x\n", excPtr->EXC_CTR); printk("\t XER = %x\n", excPtr->EXC_XER); printk("\t LR = %x\n", excPtr->EXC_LR); - printk("\t MSR = %x\n", excPtr->EXC_MSR); + printk("\t DAR = %x\n", excPtr->EXC_DAR); + + BSP_printStackTrace(excPtr); + if (excPtr->_EXC_number == ASM_DEC_VECTOR) recoverable = 1; if (excPtr->_EXC_number == ASM_SYS_VECTOR) -- cgit v1.2.3