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.
|
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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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--;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user