forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -192,7 +192,7 @@ flush_tlbs:
|
||||
lis r20, 0x1000
|
||||
1: addic. r20, r20, -0x1000
|
||||
tlbie r20
|
||||
blt 1b
|
||||
bgt 1b
|
||||
sync
|
||||
blr
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user