2001-05-14 Till Straumann <strauman@slac.stanford.edu>

* 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.
This commit is contained in:
Joel Sherrill
2002-05-14 17:10:17 +00:00
parent 3ce2907d59
commit 69ed59f083
25 changed files with 519 additions and 565 deletions

View File

@@ -1,3 +1,26 @@
2001-05-14 Till Straumann <strauman@slac.stanford.edu>
* 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

View File

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

View File

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

View File

@@ -9,6 +9,9 @@
* (C) Copyright 1997 -
* - NavIST Group - Real-Time Distributed Systems and Industrial Automation
*
* Till Straumann, <strauman@slac.stanford.edu>, 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 <termios.h>
#include <bsp/uart.h>
#include <bsp/consoleIo.h>
#include <rtems/bspIo.h> /* 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;
}

View File

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

View File

@@ -22,12 +22,14 @@
#include <bsp.h>
#include <bsp/irq.h>
#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--;

View File

@@ -20,17 +20,34 @@
#include <libcpu/byteorder.h>
#include <libcpu/page.h>
#include <libcpu/mmu.h>
#include "keyboard.h"
#include <libcpu/io.h>
#include <string.h>
#include <stdarg.h>
#include <bsp/consoleIo.h>
#include <bsp.h>
#include <libcpu/spr.h>
#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 <strauman@slac.stanford.edu>
*/
#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();

View File

@@ -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...
*/
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 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);
}
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_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 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;
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);
}

View File

@@ -10,6 +10,8 @@
#ifndef _BSPUART_H
#define _BSPUART_H
#include <bsp/irq.h>
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
*/

View File

@@ -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 <bsp/openpic.h>
#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)

View File

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

View File

@@ -20,6 +20,7 @@
#include <libcpu/raw_exception.h>
#include <bsp/vectors.h>
#include <rtems/bspIo.h> /* 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);
}
}

View File

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

View File

@@ -8,6 +8,9 @@
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
* to make it valid for MVME2300 Motorola boards.
*
* Till Straumann <strauman@slac.stanford.edu>, 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

View File

@@ -26,15 +26,16 @@
#include <libcpu/io.h>
#include <libcpu/byteorder.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#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);
}

View File

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

View File

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

View File

@@ -14,26 +14,27 @@
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*
* Till Straumann, <strauman@slac.stanford.edu>, 1/2002
* - separated bridge detection code out of this file
*/
#include <bsp/consoleIo.h>
#include <libcpu/io.h>
#include <bsp/pci.h>
#include <bsp/residual.h>
#include <bsp/openpic.h>
#include <bsp.h>
/* 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;

View File

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

View File

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

View File

@@ -192,7 +192,7 @@ flush_tlbs:
lis r20, 0x1000
1: addic. r20, r20, -0x1000
tlbie r20
blt 1b
bgt 1b
sync
blr

View File

@@ -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 <strauman@slac.stanford.edu>) */
*((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 <strauman@slac.stanford.edu>) */
*((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

View File

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

View File

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

View File

@@ -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
* <strauman@slac.stanford.edu>, 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 && i<STACK_CLAMP; f=f->frameLink) {
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)