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. Eliminated the implicit assumption on the presence of an ISA PIC.
- UART and console driver now supports more than 1 port. The current - UART and console driver now supports more than 1 port. The current
maximum of 2 can easily be extended by enlarging a table (it 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); 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 void
setup_hw(void) setup_hw(void)
{ {
@@ -402,7 +417,7 @@ setup_hw(void)
} }
break; /* Exit 'timer' loop */ break; /* Exit 'timer' loop */
} }
udelay(1000); /* 1 msec */ boot_udelay(1000); /* 1 msec */
} }
*cp = 0; *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 H_FILES = consoleIo.h keyboard.h uart.h
@@ -18,7 +18,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \
all-local: $(PREINSTALL_FILES) all-local: $(PREINSTALL_FILES)
EXTRA_DIST = console.c consoleIo.h inch.c keyboard.h polled_io.c uart.c \ EXTRA_DIST = console.c inch.c polled_io.c uart.c \
uart.h reboot.c console.inl
include $(top_srcdir)/../../../../../automake/local.am include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -9,6 +9,9 @@
* (C) Copyright 1997 - * (C) Copyright 1997 -
* - NavIST Group - Real-Time Distributed Systems and Industrial Automation * - 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 * http://pandora.ist.utl.pt
* *
* Instituto Superior Tecnico * Lisboa * PORTUGAL * Instituto Superior Tecnico * Lisboa * PORTUGAL
@@ -34,56 +37,24 @@ extern int close(int fd);
#include <termios.h> #include <termios.h>
#include <bsp/uart.h> #include <bsp/uart.h>
#include <bsp/consoleIo.h> #include <bsp/consoleIo.h>
#include <rtems/bspIo.h> /* printk */
/* Definitions for BSPConsolePort */ /* 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 : * Possible value for console input/output :
* BSP_CONSOLE_PORT_CONSOLE * BSP_CONSOLE_PORT_CONSOLE
* BSP_UART_COM1 * BSP_UART_COM1
* BSP_UART_COM2 * BSP_UART_COM2
*/ */
int BSPConsolePort = BSP_CONSOLE_PORT;
int BSPConsolePort = BSP_UART_COM1; int BSPBaseBaud = BSP_UART_BAUD_BASE;
/* int BSPConsolePort = BSP_UART_COM2; */
int BSPBaseBaud = 115200;
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| External Prototypes | External Prototypes
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
static int conSetAttr(int minor, const struct termios *); 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) 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. | Console device driver INITIALIZE entry point.
@@ -130,7 +123,6 @@ console_initialize(rtems_device_major_number major,
* to be reinitialized. * to be reinitialized.
*/ */
/* /*
* Set up TERMIOS * Set up TERMIOS
*/ */
@@ -140,56 +132,65 @@ console_initialize(rtems_device_major_number major,
* Do device-specific initialization * Do device-specific initialization
*/ */
/* 9600-8-N-1 */ /* RTEMS calls this routine once with 'minor'==0; loop through
BSP_uart_init(BSPConsolePort, 9600, 0); * all known instances...
/* 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
*/ */
status = rtems_io_register_name ("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error registering console device!\n");
rtems_fatal_error_occurred (status);
}
if(BSPConsolePort == BSP_UART_COM1) for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) {
{ char *nm;
printk("Initialized console on port COM1 9600-8-N-1\n\n"); /*
} * Skip ports (possibly not supported by BSP...) we have no ISR for
else */
{ if ( ! ttyS[minor].isr )
printk("Initialized console on port COM2 9600-8-N-1\n\n"); 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);
}
}
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} /* console_initialize */ } /* 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) 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; return 0;
} }
@@ -204,21 +205,16 @@ console_open(rtems_device_major_number major,
rtems_status_code status; rtems_status_code status;
static rtems_termios_callbacks cb = static rtems_termios_callbacks cb =
{ {
NULL, /* firstOpen */ console_first_open, /* firstOpen */
console_last_close, /* lastClose */ console_last_close, /* lastClose */
NULL, /* pollRead */ NULL, /* pollRead */
BSP_uart_termios_write_com1, /* write */ BSP_uart_termios_write_com, /* write */
conSetAttr, /* setAttributes */ conSetAttr, /* setAttributes */
NULL, /* stopRemoteTx */ NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */ NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */ 1 /* outputUsesInterrupts */
}; };
if(BSPConsolePort == BSP_UART_COM2)
{
cb.write = BSP_uart_termios_write_com2;
}
status = rtems_termios_open (major, minor, arg, &cb); status = rtems_termios_open (major, minor, arg, &cb);
if(status != RTEMS_SUCCESSFUL) if(status != RTEMS_SUCCESSFUL)
@@ -230,10 +226,10 @@ console_open(rtems_device_major_number major,
/* /*
* Pass data area info down to driver * 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); ((rtems_libio_open_close_args_t *)arg)->iop->data1);
/* Enable interrupts on channel */ /* 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; return RTEMS_SUCCESSFUL;
} }
@@ -362,10 +358,7 @@ conSetAttr(int minor, const struct termios *t)
return 0; return 0;
} }
BSP_uart_set_baud(BSPConsolePort, baud); BSP_uart_set_baud(minor, baud);
return 0; return 0;
} }

View File

@@ -26,16 +26,12 @@ typedef volatile unsigned char * __io_ptr;
typedef struct { typedef struct {
__io_ptr io_base; __io_ptr io_base;
__io_ptr isa_mem_base; __io_ptr isa_mem_base;
__io_ptr pci_mmio_base;
__io_ptr pci_dma_offset;
} board_memory_map; } board_memory_map;
extern board_memory_map *ptr_mem_map; extern board_memory_map *ptr_mem_map;
extern unsigned long ticks_per_ms;
extern int select_console(ioType t); extern int select_console(ioType t);
/* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */ /* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */
extern void udelay(int);
extern void debug_putc(const unsigned char c); extern void debug_putc(const unsigned char c);
extern int debug_getc(void); extern int debug_getc(void);
extern int debug_tstc(void); extern int debug_tstc(void);

View File

@@ -22,12 +22,14 @@
#include <bsp.h> #include <bsp.h>
#include <bsp/irq.h> #include <bsp/irq.h>
#include "console.inl"
/*-------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| Constants | Constants
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
#define KBD_CTL 0x61 /* -------------------------------- */ #define KBD_CTL 0x1 /* -------------------------------- */
#define KBD_DATA 0x60 /* Ports for PC keyboard controller */ #define KBD_DATA 0x0 /* Port offsets for PC keyboard controller */
#define KBD_STATUS 0x64 /* -------------------------------- */ #define KBD_STATUS 0x4 /* -------------------------------- */
#define KBD_BUF_SIZE 256 #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_last = 0;
static rtems_unsigned16 kbd_end = KBD_BUF_SIZE - 1; 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 | Function: _IBMPC_scankey
| Description: This function can be called during a poll for input, or by | 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 */ *outChar = NULL; /* default value if we return FALSE */
/* Read keyboard controller, toggle enable */ /* Read keyboard controller, toggle enable */
inport_byte(KBD_CTL, inChar); inChar=kbd_inb(KBD_CTL);
outport_byte(KBD_CTL, inChar & ~0x80); kbd_outb(KBD_CTL, inChar & ~0x80);
outport_byte(KBD_CTL, inChar | 0x80); kbd_outb(KBD_CTL, inChar | 0x80);
outport_byte(KBD_CTL, inChar & ~0x80); kbd_outb(KBD_CTL, inChar & ~0x80);
/* See if it has data */ /* See if it has data */
inport_byte(KBD_STATUS, inChar); inChar=kbd_inb(KBD_STATUS);
if ((inChar & 0x01) == 0) if ((inChar & 0x01) == 0)
return FALSE; return FALSE;
/* Read the data. Handle nonsense with shift, control, etc. */ /* Read the data. Handle nonsense with shift, control, etc. */
inport_byte(KBD_DATA, inChar); inChar=kbd_inb(KBD_DATA);
if (extended) if (extended)
extended--; extended--;

View File

@@ -20,17 +20,34 @@
#include <libcpu/byteorder.h> #include <libcpu/byteorder.h>
#include <libcpu/page.h> #include <libcpu/page.h>
#include <libcpu/mmu.h> #include <libcpu/mmu.h>
#include "keyboard.h"
#include <libcpu/io.h> #include <libcpu/io.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <bsp/consoleIo.h> #include <bsp/consoleIo.h>
#include <bsp.h>
#include <libcpu/spr.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 unsigned long long u64;
typedef long long s64; typedef long long s64;
typedef unsigned int u32; typedef unsigned int u32;
#ifdef USE_KBD_SUPPORT
unsigned short plain_map[NR_KEYS] = { unsigned short plain_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, 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 /* These #defines have been copied from drivers/char/pc_keyb.h, by
* Martin Mares (mj@ucw.cz). * 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_STATUS_REG 0x4 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ #define KBD_CNTL_REG 0x4 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ #define KBD_DATA_REG 0x0 /* Keyboard data register (R/W) */
/* /*
* Keyboard Controller Commands * Keyboard Controller Commands
@@ -356,6 +374,8 @@ unsigned int accent_table_size = 68;
SPR_RW(DEC) SPR_RW(DEC)
SPR_RO(PVR) SPR_RO(PVR)
#endif /* USE_KBD_SUPPORT */
/* Early messages after mm init but before console init are kept in log /* Early messages after mm init but before console init are kept in log
* buffers. * buffers.
@@ -377,10 +397,8 @@ static u_char log_page_pool [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE];
#endif #endif
static board_memory_map mem_map = { static board_memory_map mem_map = {
(__io_ptr) 0x80000000, (__io_ptr) _IO_BASE, /* from libcpu/io.h */
(__io_ptr) 0xc0000000, (__io_ptr) _ISA_MEM_BASE,
(__io_ptr) 0xc0000000,
(__io_ptr) 0x80000000
}; };
board_memory_map *ptr_mem_map = &mem_map; board_memory_map *ptr_mem_map = &mem_map;
@@ -404,18 +422,6 @@ typedef struct console_io {
extern console_io* curIo; 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) void debug_putc(const u_char c)
{ {
curIo->putc(c); curIo->putc(c);
@@ -473,7 +479,6 @@ int vacuum_tstc(void) {
#define LSR_TEMT 0x40 /* Xmitter empty */ #define LSR_TEMT 0x40 /* Xmitter empty */
#define LSR_ERR 0x80 /* Error */ #define LSR_ERR 0x80 /* Error */
#define COM1 0x3F8
#ifdef STATIC_LOG_ALLOC #ifdef STATIC_LOG_ALLOC
static int global_index = 0; 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) void serial_putc(const u_char c)
{ {
while ((inb(COM1+lsr) & LSR_THRE) == 0) ; while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ;
outb(c, COM1+thr); INL_CONSOLE_OUTB(thr, c);
} }
int serial_getc(void) int serial_getc(void)
{ {
while ((inb(COM1+lsr) & LSR_DR) == 0) ; while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ;
return (inb(COM1+rbr)); return (INL_CONSOLE_INB(rbr));
} }
int serial_tstc(void) 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) static void scroll(void)
{ {
int i; int i;
@@ -579,10 +589,10 @@ static void
cursor(int x, int y) cursor(int x, int y)
{ {
int pos = console_global_data.cols*y + x; int pos = console_global_data.cols*y + x;
outb(14, 0x3D4); vga_outb(14, 0x14);
outb(pos>>8, 0x3D5); vga_outb(0x15, pos>>8);
outb(15, 0x3D4); vga_outb(0x14, 15);
outb(pos, 0x3D5); vga_outb(0x15, pos);
} }
void void
@@ -620,16 +630,18 @@ vga_putc(const u_char c)
console_global_data.orig_x = x; console_global_data.orig_x = x;
console_global_data.orig_y = y; console_global_data.orig_y = y;
} }
#endif /* USE_VGA_SUPPORT */
#ifdef USE_KBD_SUPPORT
/* Keyboard support */ /* Keyboard support */
static int kbd_getc(void) static int kbd_getc(void)
{ {
unsigned char dt, brk, val; unsigned char dt, brk, val;
unsigned code; unsigned code;
loop: 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 */ brk = dt & 0x80; /* brk == 1 on key release */
dt = dt & 0x7f; /* keycode */ dt = dt & 0x7f; /* keycode */
@@ -667,8 +679,8 @@ loop:
else if (val == KVAL(K_ENTER)) { else if (val == KVAL(K_ENTER)) {
enter: /* Wait for key up */ enter: /* Wait for key up */
while (1) { while (1) {
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);
if (dt & 0x80) /* key up */ break; if (dt & 0x80) /* key up */ break;
} }
return 10; return 10;
@@ -732,25 +744,33 @@ enter: /* Wait for key up */
static int kbd_get(int ms) { static int kbd_get(int ms) {
int status, data; int status, data;
while(1) { while(1) {
status = inb(KBD_STATUS_REG); status = kbd_inb(KBD_STATUS_REG);
if (status & KBD_STAT_OBF) { if (status & KBD_STAT_OBF) {
data = inb(KBD_DATA_REG); data = kbd_inb(KBD_DATA_REG);
if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
return -1; return -1;
else else
return data; return data;
} }
if (--ms < 0) return -1; 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) { 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; 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) int kbdreset(void)
@@ -796,8 +816,9 @@ int kbdreset(void)
int kbd_tstc(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 const struct console_io
vacuum_console_functions = { vacuum_console_functions = {
@@ -811,19 +832,22 @@ log_console_functions = {
log_putc, log_putc,
vacuum_getc, vacuum_getc,
vacuum_tstc vacuum_tstc
}, }
,
serial_console_functions = { serial_console_functions = {
serial_putc, serial_putc,
serial_getc, serial_getc,
serial_tstc serial_tstc
}, }
#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT)
,
vga_console_functions = { vga_console_functions = {
vga_putc, vga_putc,
kbd_getc, kbd_getc,
kbd_tstc kbd_tstc
}; }
#endif
;
console_io* curIo = (console_io*) &vacuum_console_functions; 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_VACUUM : curIo = (console_io*)&vacuum_console_functions; break;
case CONSOLE_LOG : curIo = (console_io*)&log_console_functions; break; case CONSOLE_LOG : curIo = (console_io*)&log_console_functions; break;
case CONSOLE_SERIAL : curIo = (console_io*)&serial_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; case CONSOLE_VGA : curIo = (console_io*)&vga_console_functions; break;
#endif
default : curIo = (console_io*)&vacuum_console_functions;break; default : curIo = (console_io*)&vacuum_console_functions;break;
} }
if (curType == CONSOLE_LOG) flush_log(); if (curType == CONSOLE_LOG) flush_log();

View File

@@ -19,12 +19,42 @@
struct uart_data struct uart_data
{ {
unsigned long ioBase;
int hwFlow; int hwFlow;
int baud; 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 * Macros to read/wirte register of uart, if configuration is
* different just rewrite these macros * different just rewrite these macros
@@ -33,31 +63,15 @@ static struct uart_data uart_data[2];
static inline unsigned char static inline unsigned char
uread(int uart, unsigned int reg) uread(int uart, unsigned int reg)
{ {
register unsigned char val;
if(uart == 0) return in_8((unsigned char*)(uart_data[uart].ioBase + reg));
{
inport_byte(COM1_BASE_IO+reg, val);
}
else
{
inport_byte(COM2_BASE_IO+reg, val);
}
return val;
} }
static inline void static inline void
uwrite(int uart, int reg, unsigned int val) uwrite(int uart, int reg, unsigned int val)
{ {
if(uart == 0) out_8((unsigned char*)(uart_data[uart].ioBase + reg), val);
{
outport_byte(COM1_BASE_IO+reg, val);
}
else
{
outport_byte(COM2_BASE_IO+reg, val);
}
} }
#ifdef UARTDEBUG #ifdef UARTDEBUG
@@ -103,7 +117,7 @@ BSP_uart_init(int uart, int baud, int hwFlow)
unsigned char tmp; unsigned char tmp;
/* Sanity check */ /* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
switch(baud) switch(baud)
{ {
@@ -166,7 +180,7 @@ BSP_uart_set_baud(int uart, int baud)
unsigned char mcr, ier; unsigned char mcr, ier;
/* Sanity check */ /* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
/* /*
* This function may be called whenever TERMIOS parameters * This function may be called whenever TERMIOS parameters
@@ -197,7 +211,7 @@ void
BSP_uart_intr_ctrl(int uart, int cmd) BSP_uart_intr_ctrl(int uart, int cmd)
{ {
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
switch(cmd) switch(cmd)
{ {
@@ -260,7 +274,7 @@ BSP_uart_throttle(int uart)
{ {
unsigned int mcr; unsigned int mcr;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
if(!uart_data[uart].hwFlow) if(!uart_data[uart].hwFlow)
{ {
@@ -281,7 +295,7 @@ BSP_uart_unthrottle(int uart)
{ {
unsigned int mcr; unsigned int mcr;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
if(!uart_data[uart].hwFlow) if(!uart_data[uart].hwFlow)
{ {
@@ -311,7 +325,7 @@ BSP_uart_polled_status(int uart)
{ {
unsigned char val; unsigned char val;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
val = uread(uart, LSR); val = uread(uart, LSR);
@@ -353,7 +367,7 @@ BSP_uart_polled_write(int uart, int val)
unsigned char val1; unsigned char val1;
/* Sanity check */ /* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
for(;;) for(;;)
{ {
@@ -394,7 +408,7 @@ BSP_uart_polled_read(int uart)
{ {
unsigned char val; unsigned char val;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); SANITY_CHECK(uart);
for(;;) for(;;)
{ {
@@ -415,20 +429,57 @@ BSP_poll_char_via_serial()
return BSP_uart_polled_read(BSPConsolePort); 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 =================*/ /* ================ Termios support =================*/
static volatile int termios_stopped_com1 = 0; static volatile int termios_stopped_com[2] = {0,0};
static volatile int termios_tx_active_com1 = 0; static volatile int termios_tx_active_com[2] = {0,0};
static void* termios_ttyp_com1 = NULL; static void* termios_ttyp_com[2] = {NULL,NULL};
static char termios_tx_hold_com1 = 0; static char termios_tx_hold_com[2] = {0,0};
static volatile char termios_tx_hold_valid_com1 = 0; static volatile char termios_tx_hold_valid_com[2] = {0,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;
/* /*
* Set channel parameters * Set channel parameters
@@ -437,49 +488,30 @@ void
BSP_uart_termios_set(int uart, void *ttyp) BSP_uart_termios_set(int uart, void *ttyp)
{ {
unsigned char val; 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; termios_stopped_com[uart] = (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;
} }
else else
{ {
if(uart_data[uart].hwFlow) termios_stopped_com[uart] = 0;
{ }
val = uread(uart, MSR); termios_tx_active_com[uart] = 0;
termios_ttyp_com[uart] = ttyp;
termios_stopped_com2 = (val & CTS) ? 0 : 1; termios_tx_hold_com[uart] = 0;
} termios_tx_hold_valid_com[uart] = 0;
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;
}
return; return;
} }
int 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); assert(buf != NULL);
if(len <= 0) 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); */ /* assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */
if(termios_stopped_com1) if(termios_stopped_com[uart])
{ {
/* CTS low */ /* CTS low */
termios_tx_hold_com1 = *buf; termios_tx_hold_com[uart] = *buf;
termios_tx_hold_valid_com1 = 1; termios_tx_hold_valid_com[uart] = 1;
return 0; return 0;
} }
/* Write character */ /* Write character */
uwrite(BSP_UART_COM1, THR, *buf & 0xff); uwrite(uart, THR, *buf & 0xff);
/* Enable interrupts if necessary */ /* 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; termios_tx_active_com[uart] = 1;
uwrite(BSP_UART_COM1, IER, uwrite(uart, IER,
(RECEIVE_ENABLE | (RECEIVE_ENABLE |
TRANSMIT_ENABLE | TRANSMIT_ENABLE |
RECEIVER_LINE_ST_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; termios_tx_active_com[uart] = 1;
uwrite(BSP_UART_COM1, IER, uwrite(uart, IER,
(RECEIVE_ENABLE | (RECEIVE_ENABLE |
TRANSMIT_ENABLE | TRANSMIT_ENABLE |
RECEIVER_LINE_ST_ENABLE RECEIVER_LINE_ST_ENABLE
@@ -528,251 +560,109 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len)
return 0; return 0;
} }
int static void
BSP_uart_termios_write_com2(int minor, const char *buf, int len) BSP_uart_termios_isr_com(int uart)
{ {
assert(buf != NULL); unsigned char buf[40];
unsigned char val;
int off, ret, vect;
if(len <= 0) off = 0;
for(;;)
{ {
return 0; vect = uread(uart, IIR) & 0xf;
switch(vect)
{
case MODEM_STATUS :
val = uread(uart, MSR);
if(uart_data[uart].hwFlow)
{
if(val & CTS)
{
/* CTS high */
termios_stopped_com[uart] = 0;
if(termios_tx_hold_valid_com[uart])
{
termios_tx_hold_valid_com[uart] = 0;
BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart],
1);
}
}
else
{
/* CTS low */
termios_stopped_com[uart] = 1;
}
}
break;
case NO_MORE_INTR :
/* No more interrupts */
if(off != 0)
{
/* Update rx buffer */
rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart],
(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_com[uart], 1);
/* If nothing else to send disable interrupts */
if(ret == 0 && uart_data[uart].hwFlow)
{
uwrite(uart, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE |
MODEM_ENABLE
)
);
termios_tx_active_com[uart] = 0;
}
else if(ret == 0)
{
uwrite(uart, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
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(uart, RBR);
break;
case RECEIVER_ERROR:
/* RX error: eat character */
uartError(uart);
break;
default:
/* Should not happen */
assert(0);
return;
}
} }
/* 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 void
BSP_uart_termios_isr_com1(void) BSP_uart_termios_isr_com1(void)
{ {
unsigned char buf[40]; BSP_uart_termios_isr_com(BSP_UART_COM1);
unsigned char val;
int off, ret, vect;
off = 0;
for(;;)
{
vect = uread(BSP_UART_COM1, IIR) & 0xf;
switch(vect)
{
case MODEM_STATUS :
val = uread(BSP_UART_COM1, MSR);
if(uart_data[BSP_UART_COM1].hwFlow)
{
if(val & CTS)
{
/* CTS high */
termios_stopped_com1 = 0;
if(termios_tx_hold_valid_com1)
{
termios_tx_hold_valid_com1 = 0;
BSP_uart_termios_write_com1(0, &termios_tx_hold_com1,
1);
}
}
else
{
/* CTS low */
termios_stopped_com1 = 1;
}
}
break;
case NO_MORE_INTR :
/* No more interrupts */
if(off != 0)
{
/* Update rx buffer */
rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
(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_com1, 1);
/* If nothing else to send disable interrupts */
if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow)
{
uwrite(BSP_UART_COM1, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE |
MODEM_ENABLE
)
);
termios_tx_active_com1 = 0;
}
else if(ret == 0)
{
uwrite(BSP_UART_COM1, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
termios_tx_active_com1 = 0;
}
break;
case RECEIVER_DATA_AVAIL :
case CHARACTER_TIMEOUT_INDICATION:
/* RX data ready */
assert(off < sizeof(buf));
buf[off++] = uread(BSP_UART_COM1, RBR);
break;
case RECEIVER_ERROR:
/* RX error: eat character */
uartError(BSP_UART_COM1);
break;
default:
/* Should not happen */
assert(0);
return;
}
}
} }
void void
BSP_uart_termios_isr_com2() BSP_uart_termios_isr_com2(void)
{ {
unsigned char buf[40]; BSP_uart_termios_isr_com(BSP_UART_COM2);
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;
}
}
} }

View File

@@ -10,6 +10,8 @@
#ifndef _BSPUART_H #ifndef _BSPUART_H
#define _BSPUART_H #define _BSPUART_H
#include <bsp/irq.h>
void BSP_uart_init(int uart, int baud, int hwFlow); void BSP_uart_init(int uart, int baud, int hwFlow);
void BSP_uart_set_baud(int aurt, int baud); void BSP_uart_set_baud(int aurt, int baud);
void BSP_uart_intr_ctrl(int uart, int cmd); void BSP_uart_intr_ctrl(int uart, int cmd);
@@ -19,12 +21,14 @@ int BSP_uart_polled_status(int uart);
void BSP_uart_polled_write(int uart, int val); void BSP_uart_polled_write(int uart, int val);
int BSP_uart_polled_read(int uart); int BSP_uart_polled_read(int uart);
void BSP_uart_termios_set(int uart, void *ttyp); 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_com(int minor, const char *buf, int len);
int BSP_uart_termios_write_com2(int minor, const char *buf, int len);
void BSP_uart_termios_isr_com1(); void BSP_uart_termios_isr_com1();
void BSP_uart_termios_isr_com2(); void BSP_uart_termios_isr_com2();
void BSP_uart_dbgisr_com1(void); void BSP_uart_dbgisr_com1(void);
void BSP_uart_dbgisr_com2(void); void BSP_uart_dbgisr_com2(void);
int BSP_uart_install_isr(int uart, rtems_irq_hdl handler);
int BSP_uart_remove_isr(int uart, rtems_irq_hdl handler);
extern unsigned BSP_poll_char_via_serial(void); extern unsigned BSP_poll_char_via_serial(void);
extern void BSP_output_char_via_serial(int val); extern void BSP_output_char_via_serial(int val);
extern int BSPConsolePort; extern int BSPConsolePort;
@@ -49,13 +53,6 @@ extern int BSPBaseBaud;
#define BSP_UART_COM1 (0) #define BSP_UART_COM1 (0)
#define BSP_UART_COM2 (1) #define BSP_UART_COM2 (1)
/*
* Base IO for UART
*/
#define COM1_BASE_IO 0x3F8
#define COM2_BASE_IO 0x2F8
/* /*
* Offsets from base * Offsets from base
*/ */

View File

@@ -26,9 +26,33 @@
* - Interrupt stack space is not minimum if defined. * - 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) #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 #ifndef ASM
#define outport_byte(port,value) outb(value,port) #define outport_byte(port,value) outb(value,port)
#define outport_word(port,value) outw(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) 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 include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -20,6 +20,7 @@
#include <libcpu/raw_exception.h> #include <libcpu/raw_exception.h>
#include <bsp/vectors.h> #include <bsp/vectors.h>
#include <rtems/bspIo.h> /* for printk */
#define RAVEN_INTR_ACK_REG 0xfeff0030 #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; unsigned int level;
if (!isValidInterrupt(irq->name)) { if (!isValidInterrupt(irq->name)) {
printk("Invalid interrupt vector %i\n",irq->name);
return 0; 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. * to get the previous handler before accepting to disconnect.
*/ */
if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) { if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
printk("IRQ vector %i already connected\n",irq->name);
return 0; return 0;
} }
_CPU_ISR_Disable(level); _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)); outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
} }
else { 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_NUMBER = 1,
BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_PCI_IRQ_MAX_OFFSET + 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, 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 * 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_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 * Some ISA IRQ symbolic name definition
*/ */

View File

@@ -8,6 +8,9 @@
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com> * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
* to make it valid for MVME2300 Motorola boards. * 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 * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html. * http://www.OARcorp.com/rtems/license.html.
@@ -89,6 +92,11 @@ static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
0 0
}; };
static unsigned char mcp750_openpic_initpolarities[16] = {
1, /* 8259 cascade */
0, /* all the rest of them */
};
static unsigned char mcp750_openpic_initsenses[] = { static unsigned char mcp750_openpic_initsenses[] = {
1, /* MCP750_INT_PCB(8259) */ 1, /* MCP750_INT_PCB(8259) */
0, /* MCP750_INT_FALCON_ECC_ERR */ 0, /* MCP750_INT_FALCON_ECC_ERR */
@@ -226,12 +234,10 @@ void BSP_rtems_irq_mng_init(unsigned cpuId)
/* /*
* First initialize the Interrupt management hardware * First initialize the Interrupt management hardware
*/ */
OpenPIC_InitSenses = mcp750_openpic_initsenses;
OpenPIC_NumInitSenses = sizeof(mcp750_openpic_initsenses) / sizeof(char);
#ifdef TRACE_IRQ_INIT #ifdef TRACE_IRQ_INIT
printk("Going to initialize raven interrupt controller (openpic compliant)\n"); printk("Going to initialize raven interrupt controller (openpic compliant)\n");
#endif #endif
openpic_init(1); openpic_init(1, mcp750_openpic_initsenses, mcp750_openpic_initpolarities);
#ifdef TRACE_IRQ_INIT #ifdef TRACE_IRQ_INIT
printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n"); printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
#endif #endif

View File

@@ -26,15 +26,16 @@
#include <libcpu/io.h> #include <libcpu/io.h>
#include <libcpu/byteorder.h> #include <libcpu/byteorder.h>
#include <bsp.h> #include <bsp.h>
#include <rtems/bspIo.h>
#ifndef NULL
#define NULL 0 #define NULL 0
#endif
#define REGISTER_DEBUG #define REGISTER_DEBUG
#undef REGISTER_DEBUG #undef REGISTER_DEBUG
volatile struct OpenPIC *OpenPIC = NULL; volatile struct OpenPIC *OpenPIC = NULL;
unsigned int OpenPIC_NumInitSenses = 0;
unsigned char *OpenPIC_InitSenses = NULL;
static unsigned int NumProcessors; static unsigned int NumProcessors;
static unsigned int NumSources; 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 * Add some kludge to use the Motorola Raven OpenPIC which does not
* report vendor and device id, and gets the wrong number of interrupts. * report vendor and device id, and gets the wrong number of interrupts.
* (Motorola did a great job on that one!) * (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 t, i;
unsigned int vendorid, devid, stepping, timerfreq; 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); openpic_initirq(0, 8, OPENPIC_VEC_SOURCE, 1, 1);
/* Processor 0 */ /* Processor 0 */
openpic_mapirq(0, 1<<0); openpic_mapirq(0, 1<<0);
for (i = 1; i < NumSources; i++) { for (i = 0; i < NumSources; i++) {
/* Enabled, Priority 8 */ /* Enabled, Priority 8 */
openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i, 0, openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i,
i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); polarities ? polarities[i] : 0,
senses ? senses[i] : 1);
/* Processor 0 */ /* Processor 0 */
openpic_mapirq(i, 1<<0); openpic_mapirq(i, 1<<0);
} }

View File

@@ -191,8 +191,6 @@ struct OpenPIC {
}; };
extern volatile struct OpenPIC *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 */ /* Global Operations */
extern void openpic_init(int); extern void openpic_init(int,unsigned char *, unsigned char *);
extern void openpic_reset(void); extern void openpic_reset(void);
extern void openpic_enable_8259_pass_through(void); extern void openpic_enable_8259_pass_through(void);
extern void openpic_disable_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 H_FILES = pci.h
@@ -18,6 +18,6 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \
all-local: $(PREINSTALL_FILES) 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 include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -14,26 +14,27 @@
* http://www.OARcorp.com/rtems/license.html. * http://www.OARcorp.com/rtems/license.html.
* *
* $Id$ * $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 <libcpu/io.h>
#include <bsp/pci.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 #define PCI_CONFIG_ADDR 0xcf8
#endif
#ifndef PCI_CONFIG_DATA
#define PCI_CONFIG_DATA 0xcfc #define PCI_CONFIG_DATA 0xcfc
#endif
#define PCI_INVALID_VENDORDEVICEID 0xffffffff #define PCI_INVALID_VENDORDEVICEID 0xffffffff
#define PCI_MULTI_FUNCTION 0x80 #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 * 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; 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_byte,
indirect_pci_read_config_word, indirect_pci_read_config_word,
indirect_pci_read_config_dword, indirect_pci_read_config_dword,
@@ -115,9 +116,9 @@ static const pci_config_access_functions indirect_functions = {
indirect_pci_write_config_dword 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, (volatile unsigned char*)PCI_CONFIG_DATA,
&indirect_functions}; &pci_indirect_functions};
static int static int
direct_pci_read_config_byte(unsigned char bus, unsigned char slot, 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; 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_byte,
direct_pci_read_config_word, direct_pci_read_config_word,
direct_pci_read_config_dword, 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 * This routine determines the maximum bus number in the system
*/ */
void InitializePCI() void InitializePCI()
{ {
extern void detect_host_bridge();
unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs; unsigned char ucSlotNumber, ucFnNumber, ucNumFuncs;
unsigned char ucHeader; unsigned char ucHeader;
unsigned char ucMaxSubordinate; unsigned char ucMaxSubordinate;

View File

@@ -1082,7 +1082,10 @@
#define PCIBIOS_SET_FAILED 0x88 #define PCIBIOS_SET_FAILED 0x88
#define PCIBIOS_BUFFER_TOO_SMALL 0x89 #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 #define PCI_MAX_FUNCTIONS 8
typedef struct { typedef struct {
@@ -1103,45 +1106,45 @@ typedef struct {
typedef struct { typedef struct {
volatile unsigned char* pci_config_addr; volatile unsigned char* pci_config_addr;
volatile unsigned char* pci_config_data; volatile unsigned char* pci_config_data;
pci_config_access_functions* pci_functions; const pci_config_access_functions* pci_functions;
} pci_config; } pci_config;
extern pci_config pci; extern pci_config BSP_pci_configuration;
extern inline int extern inline int
pci_read_config_byte(unsigned char bus, unsigned char slot, unsigned char function, pci_read_config_byte(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned char * val) { 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 extern inline int
pci_read_config_word(unsigned char bus, unsigned char slot, unsigned char function, pci_read_config_word(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned short * val) { 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 extern inline int
pci_read_config_dword(unsigned char bus, unsigned char slot, unsigned char function, pci_read_config_dword(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned int * val) { 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 extern inline int
pci_write_config_byte(unsigned char bus, unsigned char slot, unsigned char function, pci_write_config_byte(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned char val) { 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 extern inline int
pci_write_config_word(unsigned char bus, unsigned char slot, unsigned char function, pci_write_config_word(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned short val) { 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 extern inline int
pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char function, pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char function,
unsigned char where, unsigned int val) { 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 unsigned char BusCountPCI();
extern void InitializePCI(); 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 */ #endif /* RTEMS_PCI_H */

View File

@@ -18,6 +18,6 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE)/bsp \
all-local: $(PREINSTALL_FILES) all-local: $(PREINSTALL_FILES)
EXTRA_DIST = pnp.h residual.c residual.h EXTRA_DIST = residual.c
include $(top_srcdir)/../../../../../automake/local.am include $(top_srcdir)/../../../../../automake/local.am

View File

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

View File

@@ -200,6 +200,10 @@ void bsp_start( void )
* so that It can be printed without accessing R1. * so that It can be printed without accessing R1.
*/ */
stack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE; 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 * Initialize the interrupt related settings
* SPRG0 = interrupt nesting level count * SPRG0 = interrupt nesting level count
@@ -209,6 +213,10 @@ void bsp_start( void )
* some settings below... * some settings below...
*/ */
intrStack = ((unsigned char*) &__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE - CPU_MINIMUM_STACK_FRAME_SIZE; 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 273, %0" : "=r" (intrStack) : "0" (intrStack));
asm volatile ("mtspr 272, %0" : "=r" (intrNestingLevel) : "0" (intrNestingLevel)); 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 * PCI devices memory area. Needed to access OPENPIC features
* provided by the RAVEN * 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 * Must have acces to open pic PCI ACK registers
* provided by the RAVEN * provided by the RAVEN

View File

@@ -85,6 +85,10 @@ SYM (push_normalized_frame):
stw r30, EXC_CTR_OFFSET(r1) stw r30, EXC_CTR_OFFSET(r1)
mfxer r28 mfxer r28
stw r28, EXC_XER_OFFSET(r1) 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 * compute SP at exception entry
*/ */

View File

@@ -60,7 +60,8 @@
#define EXC_CTR_OFFSET 152 #define EXC_CTR_OFFSET 152
#define EXC_XER_OFFSET 156 #define EXC_XER_OFFSET 156
#define EXC_LR_OFFSET 160 #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 * maintain the EABI requested 8 bytes aligment
* As SVR4 ABI requires 16, make it 16 (as some * 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; 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) void C_exception_handler(BSP_Exception_frame* excPtr)
{ {
int recoverable = 0; 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 CTR = %x\n", excPtr->EXC_CTR);
printk("\t XER = %x\n", excPtr->EXC_XER); printk("\t XER = %x\n", excPtr->EXC_XER);
printk("\t LR = %x\n", excPtr->EXC_LR); 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) if (excPtr->_EXC_number == ASM_DEC_VECTOR)
recoverable = 1; recoverable = 1;
if (excPtr->_EXC_number == ASM_SYS_VECTOR) if (excPtr->_EXC_number == ASM_SYS_VECTOR)