forked from Imagelibrary/rtems
added virtex BSP support and some missing files for common PPC
exception handling
This commit is contained in:
13
c/src/lib/libbsp/powerpc/virtex/ChangeLog
Normal file
13
c/src/lib/libbsp/powerpc/virtex/ChangeLog
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
2007-04-1 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
||||||
|
|
||||||
|
* bsp_specs, bsp_specs.dl, ChangeLog, configure.ac,
|
||||||
|
* console/consolelite.c, dlentry/dlentry.S, include/bsp.h,
|
||||||
|
* include/coverhd.h, include/opbintctrl.h, include/tm27.h,
|
||||||
|
* include/xparameters_dflt.h, irq/irq.h, irq/irq_init.c,
|
||||||
|
* Makefile.am, network/xiltemac.c, network/xiltemac.h,
|
||||||
|
* opbintctrl/opbintctrl.c, preinstall.am, README,
|
||||||
|
* startup/bspclean.c, startup/bspstart.c, startup/linkcmds,
|
||||||
|
* startup/linkcmds.dl, startup/setvec.c;
|
||||||
|
|
||||||
|
integration of virtex BSP into RTEMS source tree
|
||||||
|
|
||||||
99
c/src/lib/libbsp/powerpc/virtex/Makefile.am
Normal file
99
c/src/lib/libbsp/powerpc/virtex/Makefile.am
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
##
|
||||||
|
## $Id$
|
||||||
|
##
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I ../../../../aclocal
|
||||||
|
|
||||||
|
include $(top_srcdir)/../../../../automake/compile.am
|
||||||
|
include $(top_srcdir)/../../bsp.am
|
||||||
|
|
||||||
|
dist_project_lib_DATA = bsp_specs
|
||||||
|
|
||||||
|
include_HEADERS = include/bsp.h
|
||||||
|
include_HEADERS += include/tm27.h
|
||||||
|
|
||||||
|
nodist_include_HEADERS = include/bspopts.h
|
||||||
|
DISTCLEANFILES = include/bspopts.h
|
||||||
|
|
||||||
|
noinst_PROGRAMS =
|
||||||
|
|
||||||
|
include_bspdir = $(includedir)/bsp
|
||||||
|
|
||||||
|
include_HEADERS += include/coverhd.h
|
||||||
|
|
||||||
|
dist_project_lib_DATA += startup/linkcmds startup/linkcmds.dl
|
||||||
|
|
||||||
|
noinst_PROGRAMS += startup.rel
|
||||||
|
startup_rel_SOURCES = startup/bspclean.c ../../shared/bsplibc.c \
|
||||||
|
../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
|
||||||
|
../../shared/sbrk.c startup/setvec.c \
|
||||||
|
../../shared/gnatinstallhandler.c
|
||||||
|
startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
noinst_PROGRAMS += dlentry.rel
|
||||||
|
dlentry_rel_SOURCES = dlentry/dlentry.S
|
||||||
|
dlentry_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
dlentry_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
noinst_PROGRAMS += bspconsole.rel
|
||||||
|
bspconsole_rel_SOURCES = console/consolelite.c ../../shared/console.c
|
||||||
|
bspconsole_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
bspconsole_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
include_bsp_HEADERS = include/opbintctrl.h
|
||||||
|
noinst_PROGRAMS += opbintctrl.rel
|
||||||
|
opbintctrl_rel_SOURCES = opbintctrl/opbintctrl.c
|
||||||
|
opbintctrl_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
opbintctrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
include_bsp_HEADERS += irq/irq.h
|
||||||
|
noinst_PROGRAMS += irq.rel
|
||||||
|
irq_rel_SOURCES = irq/irq_init.c ../shared/irq/irq_asm.S
|
||||||
|
irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
include_bsp_HEADERS += ../../powerpc/shared/vectors/vectors.h
|
||||||
|
noinst_PROGRAMS += vectors.rel
|
||||||
|
vectors_rel_SOURCES = ../../powerpc/shared/vectors/vectors.h \
|
||||||
|
../../powerpc/shared/vectors/vectors_init.c \
|
||||||
|
../../powerpc/shared/vectors/vectors.S
|
||||||
|
vectors_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
if HAS_NETWORKING
|
||||||
|
network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
|
||||||
|
network_CPPFLAGS += -D__BSD_VISIBLE
|
||||||
|
noinst_PROGRAMS += network.rel
|
||||||
|
network_rel_SOURCES = network/xiltemac.c
|
||||||
|
network_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
##RSG Start
|
||||||
|
## include_HEADERS += include/xiltemac.h
|
||||||
|
#noinst_PROGRAMS += xiltemac.rel
|
||||||
|
#xiltemac_rel_SOURCES = network/xiltemac.c
|
||||||
|
#xiltemac_rel_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ $(AM_CPPFLAGS) -O0 -g
|
||||||
|
#xiltemac_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
##RSG End
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_LIBRARIES = libbsp.a
|
||||||
|
libbsp_a_SOURCES =
|
||||||
|
|
||||||
|
libbsp_a_LIBADD = startup.rel dlentry.rel bspconsole.rel opbintctrl.rel \
|
||||||
|
vectors.rel irq.rel network.rel
|
||||||
|
|
||||||
|
libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/@exceptions@/raw_exception.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/ppc403/clock.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/ppc403/timer.rel \
|
||||||
|
../../../libcpu/@RTEMS_CPU@/ppc403/tty_drv.rel
|
||||||
|
|
||||||
|
EXTRA_DIST = times
|
||||||
|
|
||||||
|
include $(srcdir)/preinstall.am
|
||||||
|
include $(top_srcdir)/../../../../automake/local.am
|
||||||
91
c/src/lib/libbsp/powerpc/virtex/README
Normal file
91
c/src/lib/libbsp/powerpc/virtex/README
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
# Adapted from vitex BSP
|
||||||
|
|
||||||
|
BSP NAME: Virtex
|
||||||
|
BOARD: Xilinx ML-403 and (hopefully) any vitex/PPC based board
|
||||||
|
BUS: N/A
|
||||||
|
CPU FAMILY: ppc
|
||||||
|
CPU: PowerPC 405GP
|
||||||
|
COPROCESSORS: N/A
|
||||||
|
MODE: 32 bit mode
|
||||||
|
|
||||||
|
DEBUG MONITOR:
|
||||||
|
|
||||||
|
PERIPHERALS
|
||||||
|
===========
|
||||||
|
TIMERS: 405GP internal
|
||||||
|
SERIAL PORTS: Xilinx consolelite
|
||||||
|
REAL-TIME CLOCK: none
|
||||||
|
DMA: Xilinx vitex internal
|
||||||
|
VIDEO: none
|
||||||
|
SCSI: none
|
||||||
|
NETWORKING: Xilinx TEMAC
|
||||||
|
|
||||||
|
DRIVER INFORMATION
|
||||||
|
==================
|
||||||
|
CLOCK DRIVER: PPC Decrementer
|
||||||
|
IOSUPP DRIVER: N/A
|
||||||
|
SHMSUPP: N/A
|
||||||
|
TIMER DRIVER: N/A
|
||||||
|
TTY DRIVER: consoleelite
|
||||||
|
|
||||||
|
STDIO
|
||||||
|
=====
|
||||||
|
PORT: Console port 0
|
||||||
|
ELECTRICAL: RS-232
|
||||||
|
BAUD: as defined in FPGA design
|
||||||
|
BITS PER CHARACTER: 8
|
||||||
|
PARITY: None
|
||||||
|
STOP BITS: 1
|
||||||
|
|
||||||
|
Notes
|
||||||
|
=====
|
||||||
|
|
||||||
|
Board description
|
||||||
|
-----------------
|
||||||
|
clock rate: 234 MHz
|
||||||
|
ROM: 16MByte FLASH
|
||||||
|
RAM: 64MByte DRAM
|
||||||
|
|
||||||
|
virtex only supports single processor operations.
|
||||||
|
|
||||||
|
Porting
|
||||||
|
-------
|
||||||
|
This board support package is written for a typical virtex/PPC FPGA
|
||||||
|
system. The rough features of such a board are described above.
|
||||||
|
|
||||||
|
When a new virtex FPGA system is created (using the Xilinx design
|
||||||
|
software), a parameter file "xparameters.h" is also created, which
|
||||||
|
describes the basic features of the hardware (like peripherals
|
||||||
|
inculded, interrupt routing etc).
|
||||||
|
|
||||||
|
This BSP normally takes its basic HW description for the file
|
||||||
|
"xparameters_dflt.h", which describes my FPGA system. When this BSP
|
||||||
|
should run on a different hardware, a path to the proper
|
||||||
|
"xparameters.h" can be provided on the "configure" command line.
|
||||||
|
|
||||||
|
For adapting this BSP to other boards,
|
||||||
|
|
||||||
|
the following files should be
|
||||||
|
modified:
|
||||||
|
|
||||||
|
- c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
|
||||||
|
for the memory layout required
|
||||||
|
|
||||||
|
- c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
|
||||||
|
for adaption of BSP_Configuration. here you can select
|
||||||
|
the clock source for the timers and the serial interface
|
||||||
|
(system clock or external clock pin), the clock rates, initial
|
||||||
|
baud rate and other stuff
|
||||||
|
|
||||||
|
- c/src/lib/libbsp/powerpc/virtex/include/bsp.h
|
||||||
|
some BSP-related constants
|
||||||
|
|
||||||
|
- c/src/lib/libbsp/powerpc/virtex/*
|
||||||
|
well, they should be generic, so there _should_ be no reason
|
||||||
|
to mess around there (but who knows...)
|
||||||
|
|
||||||
|
|
||||||
15
c/src/lib/libbsp/powerpc/virtex/bsp_specs
Normal file
15
c/src/lib/libbsp/powerpc/virtex/bsp_specs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%rename endfile old_endfile
|
||||||
|
%rename startfile old_startfile
|
||||||
|
%rename link old_link
|
||||||
|
|
||||||
|
*startfile:
|
||||||
|
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
|
||||||
|
%{!qrtems_debug: } \
|
||||||
|
%{qrtems_debug: }ecrti%O%s}}
|
||||||
|
|
||||||
|
*endfile:
|
||||||
|
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
|
||||||
|
|
||||||
|
*link:
|
||||||
|
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -u download_entry -N }
|
||||||
|
|
||||||
23
c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl
Normal file
23
c/src/lib/libbsp/powerpc/virtex/bsp_specs.dl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
%rename cpp old_cpp
|
||||||
|
%rename lib old_lib
|
||||||
|
%rename endfile old_endfile
|
||||||
|
%rename startfile old_startfile
|
||||||
|
%rename link old_link
|
||||||
|
|
||||||
|
*cpp:
|
||||||
|
%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
|
||||||
|
|
||||||
|
*lib:
|
||||||
|
%{!qrtems: %(old_lib)} %{qrtems: ecrti%O%s --start-group \
|
||||||
|
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
|
||||||
|
-lc -lgcc --end-group \
|
||||||
|
%{!qnolinkcmds: -T linkcmds%s}}
|
||||||
|
|
||||||
|
*startfile:
|
||||||
|
%{!qrtems: %(old_startfile)} %{qrtems: \
|
||||||
|
%{!qrtems_debug: } \
|
||||||
|
%{qrtems_debug: }}
|
||||||
|
|
||||||
|
*link:
|
||||||
|
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -u download_entry -N }
|
||||||
|
|
||||||
366
c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
Normal file
366
c/src/lib/libbsp/powerpc/virtex/console/consolelite.c
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
* This file contains the console driver for the xilinx uart lite.
|
||||||
|
*
|
||||||
|
* Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
|
||||||
|
* COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland.
|
||||||
|
*
|
||||||
|
* Derived from libbsp/no_cpu/no_bsp/console.c and therefore also:
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1999.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <libchip/serial.h>
|
||||||
|
#include <libchip/sersupp.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Status Register Masks */
|
||||||
|
#define PARITY_ERROR 0x80 /* Parity Error */
|
||||||
|
#define FRAME_ERROR 0x40 /* Frame Error */
|
||||||
|
#define OVERRUN_ERROR 0x20 /* Overrun Error */
|
||||||
|
#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR )
|
||||||
|
|
||||||
|
#define INTR_ENABLED 0x10 /* Interrupts are enabled */
|
||||||
|
#define TX_FIFO_FULL 0x08 /* Transmit FIFO is full */
|
||||||
|
#define TX_FIFO_EMPTY 0x04 /* Transmit FIFO is empty */
|
||||||
|
#define RX_FIFO_FULL 0x02 /* Receive FIFO is full */
|
||||||
|
#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */
|
||||||
|
/* Control Register Masks*/
|
||||||
|
#define ENABLE_INTR 0x10 /* Enable interrupts */
|
||||||
|
#define RST_RX_FIFO 0x02 /* Reset and clear RX FIFO */
|
||||||
|
#define RST_TX_FIFO 0x01 /* Reset and clear TX FIFO */
|
||||||
|
|
||||||
|
/* General Defines */
|
||||||
|
#define TX_FIFO_SIZE 16
|
||||||
|
#define RX_FIFO_SIZE 16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define RECV_REG 0
|
||||||
|
#define TRAN_REG 4
|
||||||
|
#define STAT_REG 8
|
||||||
|
#define CTRL_REG 12
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base)
|
||||||
|
{
|
||||||
|
uint32_t c = *((volatile uint32_t*)(base+CTRL_REG));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base)
|
||||||
|
{
|
||||||
|
uint32_t c = *((volatile uint32_t*)(base+STAT_REG));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base)
|
||||||
|
{
|
||||||
|
uint32_t c = *((volatile uint32_t*)(base+RECV_REG));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch)
|
||||||
|
{
|
||||||
|
*(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_write_char(uint32_t base, char ch)
|
||||||
|
{
|
||||||
|
uint32_t retrycount= 0, idler, status;
|
||||||
|
|
||||||
|
while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 )
|
||||||
|
{
|
||||||
|
++retrycount;
|
||||||
|
|
||||||
|
/* uart tx is busy */
|
||||||
|
if( retrycount == 0x4000 )
|
||||||
|
{
|
||||||
|
/* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* spin for a bit so we can sample the register rather than
|
||||||
|
* continually reading it */
|
||||||
|
for( idler= 0; idler < 0x2000; idler++);
|
||||||
|
}
|
||||||
|
|
||||||
|
xlite_uart_write(base, ch);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void xlite_init (int minor )
|
||||||
|
{
|
||||||
|
uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
|
||||||
|
|
||||||
|
/* clear status register */
|
||||||
|
*((volatile uint32_t*)(base+STAT_REG)) = 0;
|
||||||
|
|
||||||
|
/* clear control register; reset fifos & interrupt enable */
|
||||||
|
*((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_open(
|
||||||
|
int major,
|
||||||
|
int minor,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
|
||||||
|
|
||||||
|
/* the lite uarts have hardcoded baud & serial parms so no port
|
||||||
|
* conditioning is needed. We're running polled so no interrupt
|
||||||
|
* enables either */
|
||||||
|
|
||||||
|
/* clear status register */
|
||||||
|
*((volatile uint32_t*)(base+STAT_REG)) = 0;
|
||||||
|
|
||||||
|
/* clear control register; reset fifos & disable interrupts */
|
||||||
|
*((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO;
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_close(
|
||||||
|
int major,
|
||||||
|
int minor,
|
||||||
|
void *arg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* no shutdown protocol necessary */
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_read_polled (int minor )
|
||||||
|
{
|
||||||
|
uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
|
||||||
|
|
||||||
|
unsigned int status = xlite_uart_status(base);
|
||||||
|
|
||||||
|
if(status & RX_FIFO_VALID_DATA)
|
||||||
|
return (int)xlite_uart_read(base);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_write_buffer_polled(
|
||||||
|
int minor,
|
||||||
|
const char *buf,
|
||||||
|
int len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
|
||||||
|
int nwrite = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* poll each byte in the string out of the port.
|
||||||
|
*/
|
||||||
|
while (nwrite < len)
|
||||||
|
{
|
||||||
|
if( xlite_write_char(base, *buf++) < 0 ) break;
|
||||||
|
nwrite++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return the number of bytes written.
|
||||||
|
*/
|
||||||
|
return nwrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xlite_write_char_polled(
|
||||||
|
int minor,
|
||||||
|
char c
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t base = Console_Port_Tbl[minor].ulCtrlPort1;
|
||||||
|
xlite_write_char(base, c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int xlite_set_attributes(int minor, const struct termios *t)
|
||||||
|
{
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console_fns xlite_fns_polled =
|
||||||
|
{
|
||||||
|
libchip_serial_default_probe, /* deviceProbe */
|
||||||
|
xlite_open, /* deviceFirstOpen */
|
||||||
|
xlite_close, /* deviceLastClose */
|
||||||
|
xlite_read_polled, /* deviceRead */
|
||||||
|
xlite_write_buffer_polled, /* deviceWrite */
|
||||||
|
xlite_init, /* deviceInitialize */
|
||||||
|
xlite_write_char_polled, /* deviceWritePolled */
|
||||||
|
xlite_set_attributes, /* deviceSetAttributes */
|
||||||
|
FALSE, /* deviceOutputUsesInterrupts */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set ulCtrlPort1 to the base address of each UART Lite instance. Set in vhdl model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
console_tbl Console_Port_Tbl[] = {
|
||||||
|
{
|
||||||
|
"/dev/ttyS0", /* sDeviceName */
|
||||||
|
SERIAL_CUSTOM, /* deviceType */
|
||||||
|
&xlite_fns_polled, /* pDeviceFns */
|
||||||
|
NULL, /* deviceProbe, assume it is there */
|
||||||
|
NULL, /* pDeviceFlow */
|
||||||
|
16, /* ulMargin */
|
||||||
|
8, /* ulHysteresis */
|
||||||
|
(void *) NULL, /* NULL */ /* pDeviceParams */
|
||||||
|
0x40600000, /* ulCtrlPort1 */
|
||||||
|
0, /* ulCtrlPort2 */
|
||||||
|
0, /* ulDataPort */
|
||||||
|
NULL, /* getRegister */
|
||||||
|
NULL, /* setRegister */
|
||||||
|
NULL, /* unused */ /* getData */
|
||||||
|
NULL, /* unused */ /* setData */
|
||||||
|
0, /* ulClock */
|
||||||
|
0 /* ulIntVector -- base for port */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/dev/ttyS1", /* sDeviceName */
|
||||||
|
SERIAL_CUSTOM, /* deviceType */
|
||||||
|
&xlite_fns_polled, /* pDeviceFns */
|
||||||
|
NULL, /* deviceProbe, assume it is there */
|
||||||
|
NULL, /* pDeviceFlow */
|
||||||
|
16, /* ulMargin */
|
||||||
|
8, /* ulHysteresis */
|
||||||
|
(void *) NULL, /* NULL */ /* pDeviceParams */
|
||||||
|
0x40610000, /* ulCtrlPort1 */
|
||||||
|
0, /* ulCtrlPort2 */
|
||||||
|
0, /* ulDataPort */
|
||||||
|
NULL, /* getRegister */
|
||||||
|
NULL, /* setRegister */
|
||||||
|
NULL, /* unused */ /* getData */
|
||||||
|
NULL, /* unused */ /* setData */
|
||||||
|
0, /* ulClock */
|
||||||
|
0 /* ulIntVector -- base for port */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/dev/ttyS2", /* sDeviceName */
|
||||||
|
SERIAL_CUSTOM, /* deviceType */
|
||||||
|
&xlite_fns_polled, /* pDeviceFns */
|
||||||
|
NULL, /* deviceProbe, assume it is there */
|
||||||
|
NULL, /* pDeviceFlow */
|
||||||
|
16, /* ulMargin */
|
||||||
|
8, /* ulHysteresis */
|
||||||
|
(void *) NULL, /* NULL */ /* pDeviceParams */
|
||||||
|
0x40620000, /* ulCtrlPort1 */
|
||||||
|
0, /* ulCtrlPort2 */
|
||||||
|
0, /* ulDataPort */
|
||||||
|
NULL, /* getRegister */
|
||||||
|
NULL, /* setRegister */
|
||||||
|
NULL, /* unused */ /* getData */
|
||||||
|
NULL, /* unused */ /* setData */
|
||||||
|
0, /* ulClock */
|
||||||
|
0 /* ulIntVector -- base for port */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/dev/ttyS3", /* sDeviceName */
|
||||||
|
SERIAL_CUSTOM, /* deviceType */
|
||||||
|
&xlite_fns_polled, /* pDeviceFns */
|
||||||
|
NULL, /* deviceProbe, assume it is there */
|
||||||
|
NULL, /* pDeviceFlow */
|
||||||
|
16, /* ulMargin */
|
||||||
|
8, /* ulHysteresis */
|
||||||
|
(void *) NULL, /* NULL */ /* pDeviceParams */
|
||||||
|
0x40630000, /* ulCtrlPort1 */
|
||||||
|
0, /* ulCtrlPort2 */
|
||||||
|
0, /* ulDataPort */
|
||||||
|
NULL, /* getRegister */
|
||||||
|
NULL, /* setRegister */
|
||||||
|
NULL, /* unused */ /* getData */
|
||||||
|
NULL, /* unused */ /* setData */
|
||||||
|
0, /* ulClock */
|
||||||
|
0 /* ulIntVector -- base for port */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
|
||||||
|
|
||||||
|
unsigned long Console_Port_Count = NUM_CONSOLE_PORTS;
|
||||||
|
console_data Console_Port_Data[NUM_CONSOLE_PORTS];
|
||||||
|
rtems_device_minor_number Console_Port_Minor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
|
void outputChar(char ch)
|
||||||
|
{
|
||||||
|
if (ch == '\n') {
|
||||||
|
xlite_write_char_polled( 0, '\r' );
|
||||||
|
}
|
||||||
|
xlite_write_char_polled( 0, ch );
|
||||||
|
}
|
||||||
|
|
||||||
|
char inputChar()
|
||||||
|
{
|
||||||
|
return (char)xlite_read_polled(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BSP_output_char_function_type BSP_output_char = outputChar;
|
||||||
|
BSP_polling_getchar_function_type BSP_poll_char = inputChar;
|
||||||
|
|
||||||
|
|
||||||
156
c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S
Normal file
156
c/src/lib/libbsp/powerpc/virtex/dlentry/dlentry.S
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/* dlentry.s
|
||||||
|
*
|
||||||
|
* This file contains the entry code for RTEMS programs starting
|
||||||
|
* after download to RAM
|
||||||
|
*
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD
|
||||||
|
*
|
||||||
|
* Changes from IMD are covered by the original distributions terms.
|
||||||
|
* This file has been derived from the papyrus BSP:
|
||||||
|
*
|
||||||
|
* This file contains the entry veneer for RTEMS programs
|
||||||
|
* downloaded to Papyrus.
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* derived from "helas403/dlentry.S":
|
||||||
|
* Id: dlentry.S,v 1.2 2000/08/02 16:30:57 joel Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems/asm.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The virtex ELF link scripts support three special sections:
|
||||||
|
* .entry The actual entry point
|
||||||
|
* .vectors The section containing the interrupt entry veneers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Downloaded code loads the vectors separately to 0x00000100,
|
||||||
|
* so .entry can be over 256 bytes.
|
||||||
|
*
|
||||||
|
* The other sections are linked in the following order:
|
||||||
|
* .entry
|
||||||
|
* .text
|
||||||
|
* .data
|
||||||
|
* .bss
|
||||||
|
* see linker command file for section placement
|
||||||
|
*
|
||||||
|
* The initial stack is set to stack.end
|
||||||
|
*
|
||||||
|
* All the entry veneer has to do is to clear the BSS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GDB likes to have debugging information for the entry veneer.
|
||||||
|
* Here was some DWARF information. IMD removed it, because we
|
||||||
|
* could not check, whether it was still correct. Sorry.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .entry
|
||||||
|
|
||||||
|
PUBLIC_VAR (start)
|
||||||
|
PUBLIC_VAR (download_entry)
|
||||||
|
PUBLIC_VAR (__rtems_entry_point)
|
||||||
|
SYM(start):
|
||||||
|
SYM(download_entry):
|
||||||
|
SYM(__rtems_entry_point):
|
||||||
|
bl .startup
|
||||||
|
base_addr:
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Parameters from linker
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
toc_pointer:
|
||||||
|
.long s.got
|
||||||
|
bss_length:
|
||||||
|
.long bss.size
|
||||||
|
bss_addr:
|
||||||
|
.long bss.start
|
||||||
|
stack_top:
|
||||||
|
.long stack.end
|
||||||
|
PUBLIC_VAR (text_addr)
|
||||||
|
text_addr:
|
||||||
|
.long text.start
|
||||||
|
|
||||||
|
PUBLIC_VAR (text_length)
|
||||||
|
text_length:
|
||||||
|
.long text.size
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Reset_entry.
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
.startup:
|
||||||
|
/* Get start address, stack grows down from here... */
|
||||||
|
mflr r1
|
||||||
|
|
||||||
|
/* Assume Bank regs set up..., cache etc. */
|
||||||
|
bl bssclr
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
.extern SYM(__vectors)
|
||||||
|
|
||||||
|
lis r2,__vectors@h /* set EVPR exc. vector prefix */
|
||||||
|
#else
|
||||||
|
lis r2,0
|
||||||
|
#endif
|
||||||
|
mtspr evpr,r2
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
* C_setup.
|
||||||
|
*------------------------------------------------------------------*/
|
||||||
|
lwz r2,toc_pointer-base_addr(r1) /* set r2 to toc */
|
||||||
|
lwz r1,stack_top-base_addr(r1) /* set r1 to stack_top */
|
||||||
|
|
||||||
|
addi r1,r1,-56-4 /* start stack at text_addr - 56 */
|
||||||
|
addi r3,r0,0x0 /* clear r3 */
|
||||||
|
stw r3, 0(r1) /* Clear stack chain */
|
||||||
|
stw r3, 4(r1)
|
||||||
|
stw r3, 8(r1)
|
||||||
|
stw r3, 12(r1)
|
||||||
|
lis r5,environ@ha
|
||||||
|
la r5,environ@l(r5) /* environp */
|
||||||
|
li r4, 0 /* argv */
|
||||||
|
li r3, 0 /* argc */
|
||||||
|
.extern SYM (boot_card)
|
||||||
|
b SYM (boot_card) /* call the first C routine */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* bssclr.
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
bssclr:
|
||||||
|
/*-------------------------------------------------------------------
|
||||||
|
* Data move finished, zero out bss.
|
||||||
|
*------------------------------------------------------------------*/
|
||||||
|
lwz r2,bss_addr-base_addr(r1) /* start of bss set by loader */
|
||||||
|
lwz r3,bss_length-base_addr(r1) /* bss length */
|
||||||
|
rlwinm. r3,r3,30,0x3FFFFFFF /* form length/4 */
|
||||||
|
beqlr /* no bss */
|
||||||
|
mtctr r3 /* set ctr reg */
|
||||||
|
xor r6,r6,r6 /* r6 = 0 */
|
||||||
|
clear_bss:
|
||||||
|
stswi r6,r2,0x4 /* store r6 */
|
||||||
|
addi r2,r2,0x4 /* update r2 */
|
||||||
|
bdnz clear_bss /* decrement counter and loop */
|
||||||
|
blr /* return */
|
||||||
|
.L_text_e:
|
||||||
|
|
||||||
|
.comm environ,4,4
|
||||||
123
c/src/lib/libbsp/powerpc/virtex/include/bsp.h
Normal file
123
c/src/lib/libbsp/powerpc/virtex/include/bsp.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* bsp.h
|
||||||
|
*
|
||||||
|
* This include file contains all GEN405 board IO definitions.
|
||||||
|
*
|
||||||
|
* derived from helas403/include/bsp.h:
|
||||||
|
* Id: bsp.h,v 1.4 2001/06/18 17:01:48 joel Exp
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD
|
||||||
|
*
|
||||||
|
* Changes from IMD are covered by the original distributions terms.
|
||||||
|
* This file has been derived from the papyrus BSP.
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1999.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BSP_H
|
||||||
|
#define _BSP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <bspopts.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* confdefs.h overrides for this BSP:
|
||||||
|
* - number of termios serial ports (defaults to 1)
|
||||||
|
* - Interrupt stack space is not minimum if defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 */
|
||||||
|
#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024)
|
||||||
|
|
||||||
|
#ifdef ASM
|
||||||
|
/* Definition of where to store registers in alignment handler */
|
||||||
|
#define ALIGN_REGS 0x0140
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/console.h>
|
||||||
|
#include <rtems/clockdrv.h>
|
||||||
|
#include <rtems/console.h>
|
||||||
|
#include <rtems/iosupp.h>
|
||||||
|
#include <rtems/rtems_bsdnet.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Constants */
|
||||||
|
|
||||||
|
extern uint32_t _HeapSize;
|
||||||
|
extern uint32_t _heap_start;
|
||||||
|
extern uint32_t _heap_end;
|
||||||
|
extern uint32_t _top_of_ram;
|
||||||
|
|
||||||
|
/* miscellaneous stuff assumed to exist */
|
||||||
|
|
||||||
|
extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
|
||||||
|
extern rtems_cpu_table Cpu_table; /* owned by BSP */
|
||||||
|
|
||||||
|
|
||||||
|
/* Network Defines */
|
||||||
|
#if 1 /* EB/doe changes */
|
||||||
|
#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0"
|
||||||
|
#else
|
||||||
|
#include "xiltemac.h"
|
||||||
|
#define RTEMS_BSP_NETWORK_DRIVER_NAME XILTEMAC_DRIVER_PREFIX
|
||||||
|
#endif
|
||||||
|
extern xilTemac_driver_attach(struct rtems_bsdnet_ifconfig*, int );
|
||||||
|
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH xilTemac_driver_attach
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device Driver Table Entries
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Use the standard Console driver entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Use the standard Clock driver entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
|
||||||
|
rtems_isr_entry set_vector( /* returns old vector */
|
||||||
|
rtems_isr_entry handler, /* isr routine */
|
||||||
|
rtems_vector_number vector, /* vector number */
|
||||||
|
int type /* RTEMS or RAW intr */
|
||||||
|
);
|
||||||
|
#endif /* ASM */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
33
c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in
Normal file
33
c/src/lib/libbsp/powerpc/virtex/include/bspopts.h.in
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/* include/bspopts.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* If defined, then the PowerPC specific code in RTEMS will use some of the
|
||||||
|
special purpose registers to slightly optimize interrupt response time. The
|
||||||
|
use of these registers can conflict with other tools like debuggers. */
|
||||||
|
#undef PPC_USE_SPRG
|
||||||
|
|
||||||
|
/* This defines the base address of the exception table. NOTE: Vectors are
|
||||||
|
actually at 0xFFF00000 but file starts at offset. */
|
||||||
|
#undef PPC_VECTOR_FILE_BASE
|
||||||
|
|
||||||
|
/* This defines the location of the hardware specific "xparameters.h" file. in
|
||||||
|
the file system. Specify an absolute path. Don't forget the double quotes
|
||||||
|
*/
|
||||||
|
#undef RTEMS_XPARAMETERS_H
|
||||||
|
|
||||||
|
/* Defines path to Xilinx XPS PPC libraries. */
|
||||||
|
#undef RTEMS_XPPC_BASE
|
||||||
133
c/src/lib/libbsp/powerpc/virtex/include/coverhd.h
Normal file
133
c/src/lib/libbsp/powerpc/virtex/include/coverhd.h
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/* coverhd.h
|
||||||
|
*
|
||||||
|
* This include file has defines to represent the overhead associated
|
||||||
|
* with calling a particular directive from C. These are used in the
|
||||||
|
* Timing Test Suite to ignore the overhead required to pass arguments
|
||||||
|
* to directives. On some CPUs and/or target boards, this overhead
|
||||||
|
* is significant and makes it difficult to distinguish internal
|
||||||
|
* RTEMS execution time from that used to call the directive.
|
||||||
|
* This file should be updated after running the C overhead timing
|
||||||
|
* test. Once this update has been performed, the RTEMS Time Test
|
||||||
|
* Suite should be rebuilt to account for these overhead times in the
|
||||||
|
* timing results.
|
||||||
|
*
|
||||||
|
* NOTE: If these are all zero, then the times reported include
|
||||||
|
* all calling overhead including passing of arguments.
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1999.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Updated for a 25MHz Papyrus by Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* Units are 100ns.
|
||||||
|
*
|
||||||
|
* These numbers are of questionable use, as they are developed by calling
|
||||||
|
* the routine many times, thus getting its entry veneer into the (small)
|
||||||
|
* cache on the 403GA. This in general is not true of the RTEMS timing
|
||||||
|
* tests, which usually call a routine only once, thus having no cache loaded
|
||||||
|
* advantage.
|
||||||
|
*
|
||||||
|
* Whether the directive times are useful after deducting the function call
|
||||||
|
* overhead is also questionable. The user is more interested generally
|
||||||
|
* in the total cost of a directive, not the cost if the procedure call
|
||||||
|
* is inlined! (In general this is not true).
|
||||||
|
*
|
||||||
|
* Andrew Bray 18/08/1995
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COVERHD_h
|
||||||
|
#define __COVERHD_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 1
|
||||||
|
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_CREATE 3
|
||||||
|
#define CALLING_OVERHEAD_TASK_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_START 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_RESTART 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_SUSPEND 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_RESUME 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_MODE 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_GET_NOTE 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_SET_NOTE 1
|
||||||
|
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 4
|
||||||
|
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 1
|
||||||
|
#define CALLING_OVERHEAD_INTERRUPT_CATCH 1
|
||||||
|
#define CALLING_OVERHEAD_CLOCK_GET 4
|
||||||
|
#define CALLING_OVERHEAD_CLOCK_SET 3
|
||||||
|
#define CALLING_OVERHEAD_CLOCK_TICK 1
|
||||||
|
|
||||||
|
#define CALLING_OVERHEAD_TIMER_CREATE 1
|
||||||
|
#define CALLING_OVERHEAD_TIMER_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_TIMER_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 2
|
||||||
|
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 5
|
||||||
|
#define CALLING_OVERHEAD_TIMER_RESET 1
|
||||||
|
#define CALLING_OVERHEAD_TIMER_CANCEL 1
|
||||||
|
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 2
|
||||||
|
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 1
|
||||||
|
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 2
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 1
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 2
|
||||||
|
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 1
|
||||||
|
|
||||||
|
#define CALLING_OVERHEAD_EVENT_SEND 1
|
||||||
|
#define CALLING_OVERHEAD_EVENT_RECEIVE 2
|
||||||
|
#define CALLING_OVERHEAD_SIGNAL_CATCH 1
|
||||||
|
#define CALLING_OVERHEAD_SIGNAL_SEND 1
|
||||||
|
#define CALLING_OVERHEAD_PARTITION_CREATE 3
|
||||||
|
#define CALLING_OVERHEAD_PARTITION_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_PARTITION_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 1
|
||||||
|
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 1
|
||||||
|
#define CALLING_OVERHEAD_REGION_CREATE 3
|
||||||
|
#define CALLING_OVERHEAD_REGION_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_REGION_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 2
|
||||||
|
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 1
|
||||||
|
#define CALLING_OVERHEAD_PORT_CREATE 2
|
||||||
|
#define CALLING_OVERHEAD_PORT_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_PORT_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 1
|
||||||
|
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 2
|
||||||
|
|
||||||
|
#define CALLING_OVERHEAD_IO_INITIALIZE 2
|
||||||
|
#define CALLING_OVERHEAD_IO_OPEN 2
|
||||||
|
#define CALLING_OVERHEAD_IO_CLOSE 2
|
||||||
|
#define CALLING_OVERHEAD_IO_READ 2
|
||||||
|
#define CALLING_OVERHEAD_IO_WRITE 2
|
||||||
|
#define CALLING_OVERHEAD_IO_CONTROL 2
|
||||||
|
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 1
|
||||||
|
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 1
|
||||||
|
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 1
|
||||||
|
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 1
|
||||||
|
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 1
|
||||||
|
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 1
|
||||||
|
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
90
c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h
Normal file
90
c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/* opbintctrl.h
|
||||||
|
*
|
||||||
|
* This file contains definitions and declarations for the
|
||||||
|
* Xilinx Off Processor Bus (OPB) Interrupt Controller
|
||||||
|
*
|
||||||
|
* Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
|
||||||
|
* COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_OPBINTCTRL_H
|
||||||
|
#define _INCLUDE_OPBINTCTRL_H
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/isr.h>
|
||||||
|
#include <rtems/irq.h>
|
||||||
|
#include <bspopts.h>
|
||||||
|
#include RTEMS_XPARAMETERS_H
|
||||||
|
|
||||||
|
#define USE_GREG_INTERRUPTS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* extern XIntc InterruptController;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum number of IRQs. Defined in vhdl model */
|
||||||
|
#define OPB_INTC_IRQ_MAX XPAR_INTC_MAX_NUM_INTR_INPUTS
|
||||||
|
|
||||||
|
/* Width of INTC registers. Defined in vhdl model */
|
||||||
|
#define OPB_INTC_REGISTER_WIDTH 32
|
||||||
|
|
||||||
|
/* Base Register address and register offsets. Defined in vhdl model */
|
||||||
|
#define OPB_INTC_BASE XPAR_INTC_BASEADDR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Interrupt Status Register */
|
||||||
|
#define OPB_INTC_ISR 0x0
|
||||||
|
/* Interrupt Pending Register (ISR && IER) */
|
||||||
|
#define OPB_INTC_IPR 0x4
|
||||||
|
/* Interrupt Enable Register */
|
||||||
|
#define OPB_INTC_IER 0x8
|
||||||
|
/* Interrupt Acknowledge Register */
|
||||||
|
#define OPB_INTC_IAR 0xC
|
||||||
|
/* Set Interrupt Enable (same as read/mask/write to IER) */
|
||||||
|
#define OPB_INTC_SIE 0x10
|
||||||
|
/* Clear Interrupt Enable (same as read/mask/write to IER) */
|
||||||
|
#define OPB_INTC_CIE 0x14
|
||||||
|
/* Interrupt Vector Address (highest priority vector number from IPR) */
|
||||||
|
#define OPB_INTC_IVR 0x18
|
||||||
|
/* Master Enable Register */
|
||||||
|
#define OPB_INTC_MER 0x1C
|
||||||
|
|
||||||
|
/* Master Enable Register: Hardware Interrupt Enable */
|
||||||
|
#define OPB_INTC_MER_HIE 0x2
|
||||||
|
|
||||||
|
/* Master Enable Register: Master IRQ Enable */
|
||||||
|
#define OPB_INTC_MER_ME 0x1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make this fast: is this a opbintc interrupt?
|
||||||
|
*/
|
||||||
|
void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum);
|
||||||
|
|
||||||
|
void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum);
|
||||||
|
/*
|
||||||
|
* IRQ Handler: this is called from the primary exception dispatcher
|
||||||
|
*/
|
||||||
|
void BSP_irq_handle_at_opbintc(void);
|
||||||
|
/*
|
||||||
|
* activate the interrupt controller
|
||||||
|
*/
|
||||||
|
rtems_status_code opb_intc_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _INCLUDE_OPBINTCTRL_H */
|
||||||
32
c/src/lib/libbsp/powerpc/virtex/include/tm27.h
Normal file
32
c/src/lib/libbsp/powerpc/virtex/include/tm27.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* tm27.h
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RTEMS_TMTEST27
|
||||||
|
#error "This is an RTEMS internal file you must not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __tm27_h
|
||||||
|
#define __tm27_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stuff for Time Test 27
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MUST_WAIT_FOR_INTERRUPT 0
|
||||||
|
|
||||||
|
#define Install_tm27_vector( handler ) set_vector( (handler), PPC_IRQ_SCALL, 1 )
|
||||||
|
|
||||||
|
#define Cause_tm27_intr() asm volatile ("sc")
|
||||||
|
|
||||||
|
#define Clear_tm27_intr() /* empty */
|
||||||
|
|
||||||
|
#define Lower_tm27_intr() /* empty */
|
||||||
|
|
||||||
|
#endif
|
||||||
193
c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h
Normal file
193
c/src/lib/libbsp/powerpc/virtex/include/xparameters_dflt.h
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* CAUTION: This file is automatically generated by libgen.
|
||||||
|
* Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4
|
||||||
|
* DO NOT EDIT.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Xilinx, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Description: Driver parameters
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
#define STDIN_BASEADDRESS 0x40600000
|
||||||
|
#define STDOUT_BASEADDRESS 0x40600000
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver PLBARB */
|
||||||
|
#define XPAR_XPLBARB_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral PLB */
|
||||||
|
#define XPAR_PLB_BASEADDR 0x00000000
|
||||||
|
#define XPAR_PLB_HIGHADDR 0x00000000
|
||||||
|
#define XPAR_PLB_DEVICE_ID 0
|
||||||
|
#define XPAR_PLB_PLB_NUM_MASTERS 3
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver OPBARB */
|
||||||
|
#define XPAR_XOPBARB_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral OPB */
|
||||||
|
#define XPAR_OPB_BASEADDR 0xFFFFFFFF
|
||||||
|
#define XPAR_OPB_HIGHADDR 0x00000000
|
||||||
|
#define XPAR_OPB_DEVICE_ID 0
|
||||||
|
#define XPAR_OPB_NUM_MASTERS 1
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver UARTLITE */
|
||||||
|
#define XPAR_XUARTLITE_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral CONSOLE */
|
||||||
|
#define XPAR_CONSOLE_BASEADDR 0x40600000
|
||||||
|
#define XPAR_CONSOLE_HIGHADDR 0x4060FFFF
|
||||||
|
#define XPAR_CONSOLE_DEVICE_ID 0
|
||||||
|
#define XPAR_CONSOLE_BAUDRATE 115200
|
||||||
|
#define XPAR_CONSOLE_USE_PARITY 0
|
||||||
|
#define XPAR_CONSOLE_ODD_PARITY 0
|
||||||
|
#define XPAR_CONSOLE_DATA_BITS 8
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver GPIO */
|
||||||
|
#define XPAR_XGPIO_NUM_INSTANCES 3
|
||||||
|
|
||||||
|
/* Definitions for peripheral LEDS */
|
||||||
|
#define XPAR_LEDS_BASEADDR 0x40000000
|
||||||
|
#define XPAR_LEDS_HIGHADDR 0x4000FFFF
|
||||||
|
#define XPAR_LEDS_DEVICE_ID 0
|
||||||
|
#define XPAR_LEDS_INTERRUPT_PRESENT 0
|
||||||
|
#define XPAR_LEDS_IS_DUAL 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions for peripheral PBLEDS */
|
||||||
|
#define XPAR_PBLEDS_BASEADDR 0x40020000
|
||||||
|
#define XPAR_PBLEDS_HIGHADDR 0x4002FFFF
|
||||||
|
#define XPAR_PBLEDS_DEVICE_ID 1
|
||||||
|
#define XPAR_PBLEDS_INTERRUPT_PRESENT 0
|
||||||
|
#define XPAR_PBLEDS_IS_DUAL 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions for peripheral PUSHBUTTONS */
|
||||||
|
#define XPAR_PUSHBUTTONS_BASEADDR 0x40040000
|
||||||
|
#define XPAR_PUSHBUTTONS_HIGHADDR 0x4004FFFF
|
||||||
|
#define XPAR_PUSHBUTTONS_DEVICE_ID 2
|
||||||
|
#define XPAR_PUSHBUTTONS_INTERRUPT_PRESENT 1
|
||||||
|
#define XPAR_PUSHBUTTONS_IS_DUAL 0
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver TMRCTR */
|
||||||
|
#define XPAR_XTMRCTR_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral OPBTIMER */
|
||||||
|
#define XPAR_OPBTIMER_BASEADDR 0x41C00000
|
||||||
|
#define XPAR_OPBTIMER_HIGHADDR 0x41C0FFFF
|
||||||
|
#define XPAR_OPBTIMER_DEVICE_ID 0
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 3
|
||||||
|
#define XPAR_XINTC_HAS_IPR 1
|
||||||
|
#define XPAR_XINTC_USE_DCR 0
|
||||||
|
/* Definitions for driver INTC */
|
||||||
|
#define XPAR_XINTC_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral INTC */
|
||||||
|
#define XPAR_INTC_BASEADDR 0x41200000
|
||||||
|
#define XPAR_INTC_HIGHADDR 0x4120FFFF
|
||||||
|
#define XPAR_INTC_DEVICE_ID 0
|
||||||
|
#define XPAR_INTC_KIND_OF_INTR 0x00000000
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define XPAR_INTC_SINGLE_BASEADDR 0x41200000
|
||||||
|
#define XPAR_INTC_SINGLE_HIGHADDR 0x4120FFFF
|
||||||
|
#define XPAR_INTC_SINGLE_DEVICE_ID XPAR_INTC_DEVICE_ID
|
||||||
|
#define XPAR_OPBTIMER_INTERRUPT_MASK 0X000001
|
||||||
|
#define XPAR_INTC_OPBTIMER_INTERRUPT_INTR 0
|
||||||
|
#define XPAR_ETHERNET_IP2INTC_IRPT_MASK 0X000002
|
||||||
|
#define XPAR_INTC_ETHERNET_IP2INTC_IRPT_INTR 1
|
||||||
|
#define XPAR_PUSHBUTTONS_IP2INTC_IRPT_MASK 0X000004
|
||||||
|
#define XPAR_INTC_PUSHBUTTONS_IP2INTC_IRPT_INTR 2
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver DDR */
|
||||||
|
#define XPAR_XDDR_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral DDR_SDRAM_64MX32 */
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_ECC_BASEADDR 0xFFFFFFFF
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_ECC_HIGHADDR 0x00000000
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_DEVICE_ID 0
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_INCLUDE_ECC_INTR 0
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for peripheral DDR_SDRAM_64MX32 */
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_MEM0_BASEADDR 0x00000000
|
||||||
|
#define XPAR_DDR_SDRAM_64MX32_MEM0_HIGHADDR 0x03FFFFFF
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions for peripheral HARD_TEMAC_0 */
|
||||||
|
#define XPAR_HARD_TEMAC_0_PHY_TYPE 1
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for driver TEMAC */
|
||||||
|
#define XPAR_XTEMAC_NUM_INSTANCES 1
|
||||||
|
|
||||||
|
/* Definitions for peripheral ETHERNET */
|
||||||
|
#define XPAR_ETHERNET_DEVICE_ID 0
|
||||||
|
#define XPAR_ETHERNET_BASEADDR 0x81200000
|
||||||
|
#define XPAR_ETHERNET_HIGHADDR 0x8120FFFF
|
||||||
|
#define XPAR_ETHERNET_RXFIFO_DEPTH 32768
|
||||||
|
#define XPAR_ETHERNET_TXFIFO_DEPTH 32768
|
||||||
|
#define XPAR_ETHERNET_MAC_FIFO_DEPTH 64
|
||||||
|
#define XPAR_ETHERNET_DMA_TYPE 1
|
||||||
|
#define XPAR_ETHERNET_TX_DRE_TYPE 0
|
||||||
|
#define XPAR_ETHERNET_RX_DRE_TYPE 0
|
||||||
|
#define XPAR_ETHERNET_INCLUDE_TX_CSUM 0
|
||||||
|
#define XPAR_ETHERNET_INCLUDE_RX_CSUM 0
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions for peripheral FLASH */
|
||||||
|
#define XPAR_FLASH_NUM_BANKS_MEM 1
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* Definitions for peripheral FLASH */
|
||||||
|
#define XPAR_FLASH_MEM0_BASEADDR 0x06000000
|
||||||
|
#define XPAR_FLASH_MEM0_HIGHADDR 0x067FFFFF
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions for peripheral PLB_BRAM_IF_CNTLR_1 */
|
||||||
|
#define XPAR_PLB_BRAM_IF_CNTLR_1_BASEADDR 0xffff8000
|
||||||
|
#define XPAR_PLB_BRAM_IF_CNTLR_1_HIGHADDR 0xffffffff
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
99
c/src/lib/libbsp/powerpc/virtex/irq/irq.h
Normal file
99
c/src/lib/libbsp/powerpc/virtex/irq/irq.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*===============================================================*\
|
||||||
|
| Project: RTEMS virtex BSP |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| Copyright (c) 2007 |
|
||||||
|
| Embedded Brains GmbH |
|
||||||
|
| Obere Lagerstr. 30 |
|
||||||
|
| D-82178 Puchheim |
|
||||||
|
| Germany |
|
||||||
|
| rtems@embedded-brains.de |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| The license and distribution terms for this file may be |
|
||||||
|
| found in the file LICENSE in this distribution or at |
|
||||||
|
| |
|
||||||
|
| http://www.rtems.com/license/LICENSE. |
|
||||||
|
| |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| this file declares constants of the interrupt controller |
|
||||||
|
\*===============================================================*/
|
||||||
|
#ifndef VIRTEX_IRQ_IRQ_H
|
||||||
|
#define VIRTEX_IRQ_IRQ_H
|
||||||
|
|
||||||
|
#include <rtems/irq.h>
|
||||||
|
#include <bsp/opbintctrl.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the following definitions specify the indices used
|
||||||
|
* to interface the interrupt handler API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base index for the module specific irq handlers
|
||||||
|
*/
|
||||||
|
#define BSP_ASM_IRQ_VECTOR_BASE 0x0
|
||||||
|
#define BSP_OPBINTC_VECTOR_BASE BSP_ASM_IRQ_VECTOR_BASE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Peripheral IRQ handlers related definitions
|
||||||
|
*/
|
||||||
|
#define BSP_OPBINTC_PER_IRQ_NUMBER XPAR_INTC_MAX_NUM_INTR_INPUTS
|
||||||
|
#define BSP_OPBINTC_IRQ_LOWEST_OFFSET BSP_OPBINTC_VECTOR_BASE /* 0 */
|
||||||
|
#define BSP_OPBINTC_IRQ_MAX_OFFSET (BSP_OPBINTC_IRQ_LOWEST_OFFSET\
|
||||||
|
+BSP_OPBINTC_PER_IRQ_NUMBER-1)
|
||||||
|
|
||||||
|
#define BSP_IS_OPBINTC_IRQ(irqnum) \
|
||||||
|
(((irqnum) >= BSP_OPBINTC_IRQ_LOWEST_OFFSET) && \
|
||||||
|
((irqnum) <= BSP_OPBINTC_IRQ_MAX_OFFSET))
|
||||||
|
/*
|
||||||
|
* Processor IRQ handlers related definitions
|
||||||
|
*/
|
||||||
|
#define BSP_PROCESSOR_IRQ_NUMBER 3
|
||||||
|
#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_OPBINTC_IRQ_MAX_OFFSET+1)
|
||||||
|
#define BSP_PROCESSOR_IRQ_MAX_OFFSET (BSP_PROCESSOR_IRQ_LOWEST_OFFSET\
|
||||||
|
+BSP_PROCESSOR_IRQ_NUMBER-1)
|
||||||
|
|
||||||
|
#define BSP_IS_PROCESSOR_IRQ(irqnum) \
|
||||||
|
(((irqnum) >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) && \
|
||||||
|
((irqnum) <= BSP_PROCESSOR_IRQ_MAX_OFFSET))
|
||||||
|
/*
|
||||||
|
* Summary
|
||||||
|
*/
|
||||||
|
#define BSP_IRQ_NUMBER (BSP_PROCESSOR_IRQ_MAX_OFFSET+1)
|
||||||
|
#define BSP_LOWEST_OFFSET BSP_OPBINTC_IRQ_LOWEST_OFFSET
|
||||||
|
#define BSP_MAX_OFFSET BSP_PROCESSOR_IRQ_MAX_OFFSET
|
||||||
|
|
||||||
|
#define BSP_IS_VALID_IRQ(irqnum) \
|
||||||
|
(BSP_IS_PROCESSOR_IRQ(irqnum) \
|
||||||
|
|| BSP_IS_OPBINTC_IRQ(irqnum))
|
||||||
|
|
||||||
|
#ifndef ASM
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* index table for the module specific handlers, a few entries are only placeholders
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
BSP_OPBINTC_IRQ_FIRST = BSP_OPBINTC_IRQ_LOWEST_OFFSET,
|
||||||
|
/*
|
||||||
|
* Note: for this BSP, the peripheral names are derived
|
||||||
|
* from the Xilinx parameter file
|
||||||
|
*/
|
||||||
|
BSP_OPBINTC_IRQ_LAST = BSP_OPBINTC_IRQ_MAX_OFFSET,
|
||||||
|
BSP_EXT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0,
|
||||||
|
BSP_PIT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1,
|
||||||
|
BSP_CRIT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 2
|
||||||
|
} rtems_irq_symbolic_name;
|
||||||
|
|
||||||
|
#define BSP_OPBINTC_XPAR(xname) (BSP_OPBINTC_IRQ_LOWEST_OFFSET+xname)
|
||||||
|
|
||||||
|
extern rtems_irq_connect_data *BSP_rtems_irq_tbl;
|
||||||
|
void BSP_rtems_irq_mng_init(unsigned cpuId);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* ASM */
|
||||||
|
|
||||||
|
#endif /* VIRTEX_IRQ_IRQ_H */
|
||||||
421
c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c
Normal file
421
c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c
Normal file
@@ -0,0 +1,421 @@
|
|||||||
|
/*===============================================================*\
|
||||||
|
| Project: RTEMS virtex BSP |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| Partially based on the code references which are named below. |
|
||||||
|
| Adaptions, modifications, enhancements and any recent parts of |
|
||||||
|
| the code are: |
|
||||||
|
| Copyright (c) 2007 |
|
||||||
|
| Embedded Brains GmbH |
|
||||||
|
| Obere Lagerstr. 30 |
|
||||||
|
| D-82178 Puchheim |
|
||||||
|
| Germany |
|
||||||
|
| rtems@embedded-brains.de |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| The license and distribution terms for this file may be |
|
||||||
|
| found in the file LICENSE in this distribution or at |
|
||||||
|
| |
|
||||||
|
| http://www.rtems.com/license/LICENSE. |
|
||||||
|
| |
|
||||||
|
+-----------------------------------------------------------------+
|
||||||
|
| this file contains the irq controller handler |
|
||||||
|
\*===============================================================*/
|
||||||
|
#include <libcpu/spr.h>
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <libcpu/raw_exception.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
#include <rtems/powerpc/powerpc.h>
|
||||||
|
#include <bsp/vectors.h>
|
||||||
|
|
||||||
|
static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
|
||||||
|
rtems_irq_connect_data *BSP_rtems_irq_tbl;
|
||||||
|
rtems_irq_global_settings* BSP_rtems_irq_config;
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* dummy functions for on/off/isOn calls
|
||||||
|
* these functions just do nothing fulfill the semantic
|
||||||
|
* requirements to enable/disable a certain interrupt or exception
|
||||||
|
*/
|
||||||
|
void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* nothing to do
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_irq_nop_hdl(void *hdl)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* nothing to do
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
int BSP_irq_true_func(const rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* nothing to do
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* interrupt handler and its enable/disable functions
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* functions to enable/disable/query external/critical interrupts
|
||||||
|
*/
|
||||||
|
void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
|
||||||
|
{
|
||||||
|
uint32_t msr_value;
|
||||||
|
/*
|
||||||
|
* get current MSR value
|
||||||
|
*/
|
||||||
|
_CPU_MSR_GET(msr_value);
|
||||||
|
|
||||||
|
|
||||||
|
msr_value |= PPC_MSR_EE;
|
||||||
|
_CPU_MSR_SET(msr_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* nothing to do
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* High level IRQ handler called from shared_raw_irq_code_entry
|
||||||
|
*/
|
||||||
|
void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle interrupt
|
||||||
|
*/
|
||||||
|
switch(excNum) {
|
||||||
|
#if 0
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
_CPU_MSR_GET(msr);
|
||||||
|
new_msr = msr | MSR_EE;
|
||||||
|
_CPU_MSR_SET(new_msr);
|
||||||
|
|
||||||
|
BSP_rtems_irq_tbl[BSP_DECREMENTER].hdl
|
||||||
|
(BSP_rtems_irq_tbl[BSP_DECREMENTER].handle);
|
||||||
|
|
||||||
|
_CPU_MSR_SET(msr);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
BSP_irq_handle_at_opbintc();
|
||||||
|
break;
|
||||||
|
case ASM_PIT_VECTOR:
|
||||||
|
BSP_rtems_irq_tbl[BSP_PIT].hdl
|
||||||
|
(BSP_rtems_irq_tbl[BSP_PIT].handle);
|
||||||
|
break;
|
||||||
|
#if 0 /* Critical interrupts not yet supported */
|
||||||
|
case ASM_CRIT_VECTOR:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Process pending signals that have not already been
|
||||||
|
* processed by _Thread_Displatch. This happens quite
|
||||||
|
* unfrequently : the ISR must have posted an action
|
||||||
|
* to the current running thread.
|
||||||
|
*/
|
||||||
|
if ( _Thread_Do_post_task_switch_extension ||
|
||||||
|
_Thread_Executing->do_post_task_switch_extension ) {
|
||||||
|
_Thread_Executing->do_post_task_switch_extension = FALSE;
|
||||||
|
_API_extensions_Run_postswitch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* functions to set/get/remove interrupt handlers
|
||||||
|
***********************************************************/
|
||||||
|
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
/*
|
||||||
|
* check for valid irq name
|
||||||
|
* if invalid, print error and return 0
|
||||||
|
*/
|
||||||
|
if (!BSP_IS_VALID_IRQ(irq->name)) {
|
||||||
|
printk("Invalid interrupt vector %d\n",irq->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disable interrupts
|
||||||
|
*/
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
/*
|
||||||
|
* check, that default handler is installed now
|
||||||
|
*/
|
||||||
|
if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
printk("IRQ vector %d already connected\n",irq->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* store new handler data
|
||||||
|
*/
|
||||||
|
rtemsIrqTbl[irq->name] = *irq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enable irq at interrupt controller
|
||||||
|
*/
|
||||||
|
if (BSP_IS_OPBINTC_IRQ(irq->name)) {
|
||||||
|
BSP_irq_enable_at_opbintc(irq->name);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* call "on" function to enable interrupt at device
|
||||||
|
*/
|
||||||
|
irq->on(irq);
|
||||||
|
/*
|
||||||
|
* reenable interrupts
|
||||||
|
*/
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for valid IRQ name
|
||||||
|
*/
|
||||||
|
if (!BSP_IS_VALID_IRQ(irq->name)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
/*
|
||||||
|
* return current IRQ entry
|
||||||
|
*/
|
||||||
|
*irq = rtemsIrqTbl[irq->name];
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for valid IRQ name
|
||||||
|
*/
|
||||||
|
if (!BSP_IS_VALID_IRQ(irq->name)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
/*
|
||||||
|
* check, that specified handler is really connected now
|
||||||
|
*/
|
||||||
|
if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* disable interrupt at interrupt controller
|
||||||
|
*/
|
||||||
|
if (BSP_IS_OPBINTC_IRQ(irq->name)) {
|
||||||
|
BSP_irq_disable_at_opbintc(irq->name);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* disable interrupt at source
|
||||||
|
*/
|
||||||
|
irq->off(irq);
|
||||||
|
/*
|
||||||
|
* restore default interrupt handler
|
||||||
|
*/
|
||||||
|
rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reenable interrupts
|
||||||
|
*/
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* functions to set/get the basic interrupt management setup
|
||||||
|
***********************************************************/
|
||||||
|
/*
|
||||||
|
* (Re) get info on current RTEMS interrupt management.
|
||||||
|
*/
|
||||||
|
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
|
||||||
|
{
|
||||||
|
*ret_ptr = BSP_rtems_irq_config;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set management stuff
|
||||||
|
*/
|
||||||
|
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
/*
|
||||||
|
* store given configuration
|
||||||
|
*/
|
||||||
|
BSP_rtems_irq_config = config;
|
||||||
|
BSP_rtems_irq_tbl = BSP_rtems_irq_config->irqHdlTbl;
|
||||||
|
/*
|
||||||
|
* enable any non-empty IRQ entries at OPBINTC
|
||||||
|
*/
|
||||||
|
for (i = BSP_OPBINTC_IRQ_LOWEST_OFFSET;
|
||||||
|
i <= BSP_OPBINTC_IRQ_MAX_OFFSET;
|
||||||
|
i++) {
|
||||||
|
if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
|
||||||
|
BSP_irq_enable_at_opbintc(i);
|
||||||
|
BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
|
||||||
|
BSP_irq_disable_at_opbintc(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* store any irq-like processor exceptions
|
||||||
|
*/
|
||||||
|
for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
|
||||||
|
i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
|
||||||
|
i++) {
|
||||||
|
if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
|
||||||
|
if (BSP_rtems_irq_tbl[i].on != NULL) {
|
||||||
|
BSP_rtems_irq_tbl[i].on
|
||||||
|
(&(BSP_rtems_irq_tbl[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (BSP_rtems_irq_tbl[i].off != NULL) {
|
||||||
|
BSP_rtems_irq_tbl[i].off
|
||||||
|
(&(BSP_rtems_irq_tbl[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/**********************************************
|
||||||
|
* list of exception vectors to tap for interrupt handlers
|
||||||
|
*/
|
||||||
|
static rtems_raw_except_connect_data BSP_vec_desc[] = {
|
||||||
|
#if 0 /* ppc405 has no decrementer */
|
||||||
|
{ASM_DEC_VECTOR,
|
||||||
|
{ASM_DEC_VECTOR,
|
||||||
|
decrementer_exception_vector_prolog_code,
|
||||||
|
(size_t)decrementer_exception_vector_prolog_code_size
|
||||||
|
},
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_always_enabled
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
{ASM_EXT_VECTOR,
|
||||||
|
{ASM_EXT_VECTOR,
|
||||||
|
external_exception_vector_prolog_code,
|
||||||
|
(size_t)&external_exception_vector_prolog_code_size
|
||||||
|
},
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_always_enabled
|
||||||
|
},
|
||||||
|
{ASM_PIT_VECTOR,
|
||||||
|
{ASM_PIT_VECTOR,
|
||||||
|
pit_exception_vector_prolog_code,
|
||||||
|
(size_t)&pit_exception_vector_prolog_code_size
|
||||||
|
},
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_nop_enable,
|
||||||
|
exception_always_enabled
|
||||||
|
}
|
||||||
|
#if 0 /* Critical interrupts not yet supported */
|
||||||
|
,{ASM_CRIT_VECTOR,
|
||||||
|
{ASM_CRIT_VECTOR,
|
||||||
|
critical_exception_vector_prolog_code,
|
||||||
|
critical_exception_vector_prolog_code_size
|
||||||
|
}
|
||||||
|
BSP_irq_nop_func,
|
||||||
|
BSP_irq_nop_func,
|
||||||
|
BSP_irq_true_func
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dummy for an empty IRQ handler entry
|
||||||
|
*/
|
||||||
|
static rtems_irq_connect_data emptyIrq = {
|
||||||
|
0, /* Irq Name */
|
||||||
|
BSP_irq_nop_hdl, /* handler function */
|
||||||
|
NULL, /* handle passed to handler */
|
||||||
|
BSP_irq_nop_func, /* on function */
|
||||||
|
BSP_irq_nop_func, /* off function */
|
||||||
|
BSP_irq_true_func /* isOn function */
|
||||||
|
};
|
||||||
|
|
||||||
|
static rtems_irq_global_settings initialConfig = {
|
||||||
|
BSP_IRQ_NUMBER, /* irqNb */
|
||||||
|
{ 0, /* Irq Name */
|
||||||
|
BSP_irq_nop_hdl, /* handler function */
|
||||||
|
NULL, /* handle passed to handler */
|
||||||
|
BSP_irq_nop_func, /* on function */
|
||||||
|
BSP_irq_nop_func, /* off function */
|
||||||
|
BSP_irq_true_func /* isOn function */
|
||||||
|
}, /* emptyIrq */
|
||||||
|
rtemsIrqTbl, /* irqHdlTbl */
|
||||||
|
0, /* irqBase */
|
||||||
|
NULL /* irqPrioTbl */
|
||||||
|
};
|
||||||
|
|
||||||
|
void BSP_rtems_irq_mng_init(unsigned cpuId)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
* connect all exception vectors needed
|
||||||
|
*/
|
||||||
|
for (i = 0;
|
||||||
|
i < (sizeof(BSP_vec_desc) /
|
||||||
|
sizeof(BSP_vec_desc[0]));
|
||||||
|
i++) {
|
||||||
|
if (!ppc_set_exception (&BSP_vec_desc[i])) {
|
||||||
|
BSP_panic("Unable to initialize RTEMS raw exception\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* setup interrupt handlers table
|
||||||
|
*/
|
||||||
|
for (i = 0;
|
||||||
|
i < BSP_IRQ_NUMBER;
|
||||||
|
i++) {
|
||||||
|
rtemsIrqTbl[i] = emptyIrq;
|
||||||
|
rtemsIrqTbl[i].name = i;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* init interrupt controller
|
||||||
|
*/
|
||||||
|
opb_intc_init();
|
||||||
|
/*
|
||||||
|
* initialize interrupt management
|
||||||
|
*/
|
||||||
|
if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
|
||||||
|
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
966
c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c
Normal file
966
c/src/lib/libbsp/powerpc/virtex/network/xiltemac.c
Normal file
@@ -0,0 +1,966 @@
|
|||||||
|
/*
|
||||||
|
* Driver for Xilinx plb temac v3.00a
|
||||||
|
*
|
||||||
|
* Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
|
||||||
|
* Copyright (c) 2007 Linn Products Ltd, Scotland.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define PPC_HAS_CLASSIC_EXCEPTIONS FALSE
|
||||||
|
|
||||||
|
#ifndef __INSIDE_RTEMS_BSD_TCPIP_STACK__
|
||||||
|
#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __BSD_VISIBLE
|
||||||
|
#define __BSD_VISIBLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/rtems_bsdnet.h>
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/mbuf.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <xiltemac.h>
|
||||||
|
#include <rtems/irq.h>
|
||||||
|
|
||||||
|
/* Reading/Writing memory mapped i/o */
|
||||||
|
#define IN32(aPtr) ((uint32_t)( *((volatile uint32_t *)(aPtr))) )
|
||||||
|
#define OUT32(aPtr, aValue) (*((volatile uint32_t *)(aPtr)) = (uint32_t)aValue)
|
||||||
|
#define NUM_XILTEMAC_UNITS 2
|
||||||
|
|
||||||
|
extern void printk(char*, ...);
|
||||||
|
|
||||||
|
/* Why isn't this defined in stdio.h like it's supposed to be? */
|
||||||
|
extern int snprintf(char*, size_t, const char*, ...);
|
||||||
|
|
||||||
|
void xilTemacInit( void *voidptr );
|
||||||
|
void xilTemacReset(struct ifnet *ifp);
|
||||||
|
void xilTemacStop(struct ifnet *ifp);
|
||||||
|
void xilTemacSend(struct ifnet *ifp);
|
||||||
|
void xilTemacStart(struct ifnet *ifp);
|
||||||
|
void xilTemacSetMacAddress(struct ifnet *ifp, unsigned char* aAddr);
|
||||||
|
void xilTemacPrintStats(struct ifnet *ifp);
|
||||||
|
|
||||||
|
void xilTemacRxThread( void *ignore );
|
||||||
|
void xilTemacTxThread( void *ignore );
|
||||||
|
|
||||||
|
static struct XilTemac gXilTemac[ NUM_XILTEMAC_UNITS ];
|
||||||
|
|
||||||
|
static rtems_id gXilRxThread = 0;
|
||||||
|
static rtems_id gXilTxThread = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Events, one per unit. The event is sent to the rx task from the isr
|
||||||
|
** or from the stack to the tx task whenever a unit needs service. The
|
||||||
|
** rx/tx tasks identify the requesting unit(s) by their particular
|
||||||
|
** events so only requesting units are serviced.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static rtems_event_set gUnitSignals[ NUM_XILTEMAC_UNITS ]= { RTEMS_EVENT_1,
|
||||||
|
RTEMS_EVENT_2 };
|
||||||
|
|
||||||
|
uint32_t xilTemacTxFifoVacancyBytes(uint32_t aBaseAddr)
|
||||||
|
{
|
||||||
|
uint32_t ipisr = IN32(aBaseAddr + XTE_IPISR_OFFSET);
|
||||||
|
uint32_t bytes = 0;
|
||||||
|
if(ipisr & XTE_IPXR_XMIT_LFIFO_FULL_MASK) {
|
||||||
|
/* If there's no room in the transmit length fifo, then any room in the
|
||||||
|
* data fifo is irrelevant, return 0 */
|
||||||
|
} else {
|
||||||
|
bytes = IN32(aBaseAddr + XTE_PFIFO_TX_VACANCY_OFFSET);
|
||||||
|
bytes &= XTE_PFIFO_COUNT_MASK;
|
||||||
|
bytes *= 8;
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacFifoRead64(uint32_t aBaseAddr, uint32_t* aBuf, uint32_t aBytes)
|
||||||
|
{
|
||||||
|
uint32_t numqwords = aBytes / 8;
|
||||||
|
uint32_t xtrabytes = aBytes % 8;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < numqwords; i++)
|
||||||
|
{
|
||||||
|
aBuf[ (i*2) ] = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET);
|
||||||
|
aBuf[ (i*2)+1 ] = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there was a non qword sized read */
|
||||||
|
if( xtrabytes != 0 )
|
||||||
|
{
|
||||||
|
uint32_t lastdwordMS = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET);
|
||||||
|
uint32_t lastdwordLS = IN32(aBaseAddr + XTE_PFIFO_RX_DATA_OFFSET + 4);
|
||||||
|
uint8_t* finalbytes = (uint8_t *)&aBuf[ (numqwords*2) ];
|
||||||
|
uint8_t* ptr8;
|
||||||
|
int32_t offset = 0;
|
||||||
|
|
||||||
|
ptr8 = (uint8_t *)&lastdwordMS;
|
||||||
|
if( xtrabytes >= 4 )
|
||||||
|
{
|
||||||
|
finalbytes[ offset++ ] = ptr8[0];
|
||||||
|
finalbytes[ offset++ ] = ptr8[1];
|
||||||
|
finalbytes[ offset++ ] = ptr8[2];
|
||||||
|
finalbytes[ offset++ ] = ptr8[3];
|
||||||
|
|
||||||
|
xtrabytes -= 4;
|
||||||
|
ptr8 = (uint8_t *)&lastdwordLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xtrabytes == 1 )
|
||||||
|
{
|
||||||
|
finalbytes[ offset++ ] = ptr8[0];
|
||||||
|
}
|
||||||
|
else if ( xtrabytes == 2 )
|
||||||
|
{
|
||||||
|
finalbytes[ offset++ ] = ptr8[0];
|
||||||
|
finalbytes[ offset++ ] = ptr8[1];
|
||||||
|
}
|
||||||
|
else if ( xtrabytes == 3 )
|
||||||
|
{
|
||||||
|
finalbytes[ offset++ ] = ptr8[0];
|
||||||
|
finalbytes[ offset++ ] = ptr8[1];
|
||||||
|
finalbytes[ offset++ ] = ptr8[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacFifoWrite64(uint32_t aBaseAddr, uint32_t* aBuf, uint32_t aBytes)
|
||||||
|
{
|
||||||
|
uint32_t numqwords = aBytes / 8;
|
||||||
|
uint32_t xtrabytes = aBytes % 8;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < numqwords; i++ ) {
|
||||||
|
OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET , aBuf[ (i*2) ]);
|
||||||
|
OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET + 4, aBuf[ (i*2)+1 ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there was a non word sized write */
|
||||||
|
if( xtrabytes != 0 ) {
|
||||||
|
uint32_t lastdwordMS = 0;
|
||||||
|
uint32_t lastdwordLS = 0;
|
||||||
|
uint8_t* finalbytes = (uint8_t *)&aBuf[ (numqwords*2) ];
|
||||||
|
uint8_t* ptr8;
|
||||||
|
int32_t offset = 0;
|
||||||
|
|
||||||
|
ptr8 = (uint8_t *)&lastdwordMS;
|
||||||
|
|
||||||
|
if( xtrabytes >= 4 ) {
|
||||||
|
ptr8[0] = finalbytes[ offset++ ];
|
||||||
|
ptr8[1] = finalbytes[ offset++ ];
|
||||||
|
ptr8[2] = finalbytes[ offset++ ];
|
||||||
|
ptr8[3] = finalbytes[ offset++ ];
|
||||||
|
|
||||||
|
xtrabytes -= 4;
|
||||||
|
|
||||||
|
ptr8 = (uint8_t *)&lastdwordLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xtrabytes == 1 ) {
|
||||||
|
ptr8[0] = finalbytes[ offset++ ];
|
||||||
|
}
|
||||||
|
else if ( xtrabytes == 2 ) {
|
||||||
|
ptr8[0] = finalbytes[ offset++ ];
|
||||||
|
ptr8[1] = finalbytes[ offset++ ];
|
||||||
|
}
|
||||||
|
else if ( xtrabytes == 3 ) {
|
||||||
|
ptr8[0] = finalbytes[ offset++ ];
|
||||||
|
ptr8[1] = finalbytes[ offset++ ];
|
||||||
|
ptr8[2] = finalbytes[ offset++ ];
|
||||||
|
}
|
||||||
|
|
||||||
|
OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET, lastdwordMS);
|
||||||
|
OUT32(aBaseAddr + XTE_PFIFO_TX_DATA_OFFSET + 4, lastdwordLS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacStop(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
|
||||||
|
/* Disable ipif interrupts */
|
||||||
|
OUT32(base + XTE_DGIE_OFFSET, 0);
|
||||||
|
|
||||||
|
/* Disable the receiver */
|
||||||
|
uint32_t rxc1 = IN32(base + XTE_ERXC1_OFFSET);
|
||||||
|
rxc1 &= ~XTE_ERXC1_RXEN_MASK;
|
||||||
|
OUT32(base + XTE_ERXC1_OFFSET, rxc1);
|
||||||
|
|
||||||
|
/* If receiver was receiving a packet when we disabled it, it will be
|
||||||
|
* rejected, clear appropriate status bit */
|
||||||
|
uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
|
||||||
|
if( ipisr & XTE_IPXR_RECV_REJECT_MASK ) {
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PPC_HAS_CLASSIC_EXCEPTIONS
|
||||||
|
if( xilTemac->iOldHandler )
|
||||||
|
{
|
||||||
|
opb_intc_set_vector( xilTemac->iOldHandler, xilTemac->iIsrVector, NULL );
|
||||||
|
xilTemac->iOldHandler = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if( xilTemac->iOldHandler.name != 0)
|
||||||
|
{
|
||||||
|
BSP_install_rtems_irq_handler (&xilTemac->iOldHandler);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ifp->if_flags &= ~IFF_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacStart(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
if( (ifp->if_flags & IFF_RUNNING) == 0 )
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
|
||||||
|
/* Reset plb temac */
|
||||||
|
OUT32(base + XTE_DSR_OFFSET, XTE_DSR_RESET_MASK);
|
||||||
|
/* Don't have usleep on rtems 4.6
|
||||||
|
usleep(1);
|
||||||
|
*/
|
||||||
|
/* @ fastest ppc clock of 500 MHz = 2ns clk */
|
||||||
|
uint32_t i = 0;
|
||||||
|
for( i = 0; i < 1 * 500; i++) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset hard temac */
|
||||||
|
OUT32(base + XTE_CR_OFFSET, XTE_CR_HTRST_MASK);
|
||||||
|
/* Don't have usleep on rtems 4.6
|
||||||
|
usleep(4);
|
||||||
|
*/
|
||||||
|
for( i = 0; i < 4 * 500; i++) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the receiver -- no need to disable xmit as we control that ;) */
|
||||||
|
uint32_t rxc1 = IN32(base + XTE_ERXC1_OFFSET);
|
||||||
|
rxc1 &= ~XTE_ERXC1_RXEN_MASK;
|
||||||
|
OUT32(base + XTE_ERXC1_OFFSET, rxc1);
|
||||||
|
|
||||||
|
/* If receiver was receiving a packet when we disabled it, it will be
|
||||||
|
* rejected, clear appropriate status bit */
|
||||||
|
uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
|
||||||
|
if( ipisr & XTE_IPXR_RECV_REJECT_MASK ) {
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup IPIF interrupt enables */
|
||||||
|
uint32_t dier = XTE_DXR_CORE_MASK | XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK;
|
||||||
|
dier |= XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK;
|
||||||
|
OUT32(base + XTE_DIER_OFFSET, dier);
|
||||||
|
|
||||||
|
/* Set the mac address */
|
||||||
|
xilTemacSetMacAddress( ifp, xilTemac->iArpcom.ac_enaddr);
|
||||||
|
|
||||||
|
/* Set the link speed */
|
||||||
|
uint32_t emcfg = IN32(base + XTE_ECFG_OFFSET);
|
||||||
|
printk("xiltemacStart, default linkspeed: %08x\n", emcfg);
|
||||||
|
emcfg |= XTE_ECFG_LINKSPD_100;
|
||||||
|
OUT32(base + XTE_ECFG_OFFSET, emcfg);
|
||||||
|
|
||||||
|
/* Set phy divisor and enable mdio. For a plb bus freq of 150MHz (the
|
||||||
|
maximum as of Virtex4 Fx), a divisor of 29 gives a mdio clk freq of
|
||||||
|
2.5MHz (see Xilinx docs for equation), the maximum in the phy standard.
|
||||||
|
For slower plb frequencies, slower mkdio clks will result. They may not
|
||||||
|
be optimal, but they should work. */
|
||||||
|
uint32_t divisor = 29;
|
||||||
|
OUT32(base + XTE_EMC_OFFSET, divisor | XTE_EMC_MDIO_MASK);
|
||||||
|
|
||||||
|
#if PPC_HAS_CLASSIC_EXCEPTIONS /* old connect code */
|
||||||
|
/* Connect isr vector */
|
||||||
|
rtems_status_code sc;
|
||||||
|
extern rtems_isr xilTemacIsr( rtems_vector_number aVector );
|
||||||
|
sc = opb_intc_set_vector( xilTemacIsr, xilTemac->iIsrVector, &xilTemac->iOldHandler );
|
||||||
|
if( sc != RTEMS_SUCCESSFUL )
|
||||||
|
{
|
||||||
|
xilTemac->iOldHandler = 0;
|
||||||
|
printk("%s: Could not set interrupt vector for interface '%s' opb_intc_set_vector ret: %d\n", DRIVER_PREFIX, xilTemac->iUnitName, sc );
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
extern rtems_isr xilTemacIsr( void *handle );
|
||||||
|
extern void xilTemacIsrOn(const rtems_irq_connect_data *);
|
||||||
|
extern void xilTemacIsrOff(const rtems_irq_connect_data *);
|
||||||
|
extern int xilTemacIsrIsOn(const rtems_irq_connect_data *);
|
||||||
|
rtems_irq_connect_data IrqConnData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*get old irq handler
|
||||||
|
*/
|
||||||
|
xilTemac->iOldHandler.name = xilTemac->iIsrVector;
|
||||||
|
if (!BSP_get_current_rtems_irq_handler (&xilTemac->iOldHandler)) {
|
||||||
|
xilTemac->iOldHandler.name = 0;
|
||||||
|
printk("%s: Unable to detect previous Irq handler\n",DRIVER_PREFIX);
|
||||||
|
rtems_fatal_error_occurred(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
IrqConnData.on = xilTemacIsrOn;
|
||||||
|
IrqConnData.off = xilTemacIsrOff;
|
||||||
|
IrqConnData.isOn = xilTemacIsrIsOn;
|
||||||
|
IrqConnData.name = xilTemac->iIsrVector;
|
||||||
|
IrqConnData.hdl = xilTemacIsr;
|
||||||
|
IrqConnData.handle = xilTemac;
|
||||||
|
|
||||||
|
if (!BSP_install_rtems_irq_handler (&IrqConnData)) {
|
||||||
|
printk("%s: Unable to connect Irq handler\n",DRIVER_PREFIX);
|
||||||
|
rtems_fatal_error_occurred(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Enable promiscuous mode -- The temac only supports full duplex, which
|
||||||
|
means we're plugged into a switch. Thus promiscuous mode simply means
|
||||||
|
we get all multicast addresses*/
|
||||||
|
OUT32(base + XTE_EAFM_OFFSET, XTE_EAFM_EPPRM_MASK);
|
||||||
|
|
||||||
|
/* Setup and enable receiver */
|
||||||
|
rxc1 = XTE_ERXC1_RXFCS_MASK | XTE_ERXC1_RXEN_MASK | XTE_ERXC1_RXVLAN_MASK;
|
||||||
|
OUT32(base + XTE_ERXC1_OFFSET, rxc1);
|
||||||
|
|
||||||
|
/* Setup and enable transmitter */
|
||||||
|
uint32_t txc = XTE_ETXC_TXEN_MASK | XTE_ETXC_TXVLAN_MASK;
|
||||||
|
OUT32(base + XTE_ETXC_OFFSET, txc);
|
||||||
|
|
||||||
|
/* Enable interrupts for temac */
|
||||||
|
uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
|
||||||
|
ipier |= (XTE_IPXR_XMIT_ERROR_MASK);
|
||||||
|
ipier |= (XTE_IPXR_RECV_ERROR_MASK | XTE_IPXR_RECV_DONE_MASK);
|
||||||
|
ipier |= (XTE_IPXR_AUTO_NEG_MASK);
|
||||||
|
OUT32(base + XTE_IPIER_OFFSET, ipier);
|
||||||
|
|
||||||
|
printk("%s: xiltemacStart, ipier: %08x\n",DRIVER_PREFIX, ipier);
|
||||||
|
|
||||||
|
/* Enable device global interrutps */
|
||||||
|
OUT32(base + XTE_DGIE_OFFSET, XTE_DGIE_ENABLE_MASK);
|
||||||
|
ifp->if_flags |= IFF_RUNNING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacInit( void *voidptr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacReset(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
xilTemacStop( ifp );
|
||||||
|
xilTemacStart( ifp );
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacSetMacAddress(struct ifnet *ifp, unsigned char* aAddr)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
|
||||||
|
/* You can't change the mac address while the card is in operation */
|
||||||
|
if( (ifp->if_flags & IFF_RUNNING) != 0 ) {
|
||||||
|
printk("%s: attempted to change MAC while up, interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
uint32_t mac;
|
||||||
|
mac = aAddr[0] & 0x000000FF;
|
||||||
|
mac |= aAddr[1] << 8;
|
||||||
|
mac |= aAddr[2] << 16;
|
||||||
|
mac |= aAddr[3] << 24;
|
||||||
|
OUT32(base + XTE_EUAW0_OFFSET, mac);
|
||||||
|
|
||||||
|
mac = IN32(base + XTE_EUAW1_OFFSET);
|
||||||
|
mac &= ~XTE_EUAW1_MASK;
|
||||||
|
mac |= aAddr[4] & 0x000000FF;
|
||||||
|
mac |= aAddr[5] << 8;
|
||||||
|
OUT32(base + XTE_EUAW1_OFFSET, mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacPrintStats( struct ifnet *ifp )
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("%s: Statistics for interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
|
||||||
|
printf("%s: Ipif Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iInterrupts);
|
||||||
|
printf("%s: Rx Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxInterrupts);
|
||||||
|
printf("%s: Rx Rejected Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedInterrupts);
|
||||||
|
printf("%s: Rx Rej Invalid Frame: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedInvalidFrame);
|
||||||
|
printf("%s: Rx Rej Data Fifo Full: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedDataFifoFull);
|
||||||
|
printf("%s:Rx Rej Length Fifo Full: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxRejectedLengthFifoFull);
|
||||||
|
printf("%s: Rx Stray Events: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxStrayEvents);
|
||||||
|
printf("%s: Rx Max Drained: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iRxMaxDrained);
|
||||||
|
printf("%s: Tx Interrupts: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iTxInterrupts);
|
||||||
|
printf("%s: Tx Max Drained: %lu\n", DRIVER_PREFIX, xilTemac->iStats.iTxMaxDrained);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacIsrSingle(struct XilTemac* xilTemac)
|
||||||
|
{
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
uint32_t disr = IN32( base + XTE_DISR_OFFSET );
|
||||||
|
struct ifnet* ifp = xilTemac->iIfp;
|
||||||
|
|
||||||
|
if( disr && (ifp->if_flags & IFF_RUNNING) == 0 ) {
|
||||||
|
/* some interrupt status bits are asserted but card is down */
|
||||||
|
printk("%s: Fatal error, disr 0 or this emac not running\n", DRIVER_PREFIX);
|
||||||
|
/*assert(0);*/
|
||||||
|
} else {
|
||||||
|
/* Handle all error conditions first */
|
||||||
|
if( disr & (XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK |
|
||||||
|
XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK) ) {
|
||||||
|
printk("%s: Fatal Bus error, disr: %08x\n", DRIVER_PREFIX, disr);
|
||||||
|
/*assert(0);*/
|
||||||
|
}
|
||||||
|
if( disr & XTE_DXR_CORE_MASK ) {
|
||||||
|
/* Normal case, temac interrupt */
|
||||||
|
uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
|
||||||
|
uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
|
||||||
|
uint32_t newipier = ipier;
|
||||||
|
uint32_t pending = ipisr & ipier;
|
||||||
|
xilTemac->iStats.iInterrupts++;
|
||||||
|
|
||||||
|
/* Check for all fatal errors, even if that error is not enabled in ipier */
|
||||||
|
if(ipisr & XTE_IPXR_FIFO_FATAL_ERROR_MASK) {
|
||||||
|
printk("%s: Fatal Fifo Error ipisr: %08x\n", DRIVER_PREFIX, ipisr);
|
||||||
|
/*assert(0);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pending & XTE_IPXR_RECV_DONE_MASK) {
|
||||||
|
/* We've received a packet
|
||||||
|
- inc stats
|
||||||
|
- disable rx interrupt
|
||||||
|
- signal rx thread to empty out fifo
|
||||||
|
(rx thread must renable interrupt)
|
||||||
|
*/
|
||||||
|
xilTemac->iStats.iRxInterrupts++;
|
||||||
|
|
||||||
|
newipier &= ~XTE_IPXR_RECV_DONE_MASK;
|
||||||
|
|
||||||
|
rtems_event_send(gXilRxThread, xilTemac->iIoEvent);
|
||||||
|
}
|
||||||
|
if(pending & XTE_IPXR_XMIT_DONE_MASK) {
|
||||||
|
/* We've transmitted a packet. This interrupt is only ever enabled in
|
||||||
|
the ipier if the tx thread didn't have enough space in the data fifo
|
||||||
|
or the tplr fifo. If that's the case, we:
|
||||||
|
- inc stats
|
||||||
|
- disable tx interrupt
|
||||||
|
- signal tx thread that a transmit has completed and thus there is now
|
||||||
|
room to send again.
|
||||||
|
*/
|
||||||
|
xilTemac->iStats.iTxInterrupts++;
|
||||||
|
|
||||||
|
newipier &= ~XTE_IPXR_XMIT_DONE_MASK;
|
||||||
|
|
||||||
|
rtems_event_send(gXilTxThread, xilTemac->iIoEvent);
|
||||||
|
}
|
||||||
|
if(pending & XTE_IPXR_RECV_DROPPED_MASK) {
|
||||||
|
/* A packet was dropped (because it was invalid, or receiving it
|
||||||
|
have overflowed one of the rx fifo's).
|
||||||
|
- Increment stats.
|
||||||
|
- Clear interrupt condition.
|
||||||
|
*/
|
||||||
|
uint32_t toggle = 0;
|
||||||
|
if(pending & XTE_IPXR_RECV_REJECT_MASK) {
|
||||||
|
xilTemac->iStats.iRxRejectedInvalidFrame++;
|
||||||
|
toggle |= XTE_IPXR_RECV_REJECT_MASK;
|
||||||
|
}
|
||||||
|
if(pending & XTE_IPXR_RECV_PFIFO_ABORT_MASK) {
|
||||||
|
xilTemac->iStats.iRxRejectedDataFifoFull++;
|
||||||
|
toggle |= XTE_IPXR_RECV_PFIFO_ABORT_MASK;
|
||||||
|
}
|
||||||
|
if(pending & XTE_IPXR_RECV_LFIFO_ABORT_MASK) {
|
||||||
|
xilTemac->iStats.iRxRejectedLengthFifoFull++;
|
||||||
|
toggle |= XTE_IPXR_RECV_LFIFO_ABORT_MASK;
|
||||||
|
}
|
||||||
|
xilTemac->iStats.iRxRejectedInterrupts++;
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, toggle);
|
||||||
|
}
|
||||||
|
if(pending & XTE_IPXR_AUTO_NEG_MASK) {
|
||||||
|
printk("%s: Autonegotiation finished\n", DRIVER_PREFIX);
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_AUTO_NEG_MASK);
|
||||||
|
}
|
||||||
|
if(newipier != ipier) {
|
||||||
|
OUT32(base + XTE_IPIER_OFFSET, newipier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PPC_HAS_CLASSIC_EXCEPTIONS
|
||||||
|
rtems_isr xilTemacIsr( rtems_vector_number aVector )
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i=0; i< NUM_XILTEMAC_UNITS; i++ ) {
|
||||||
|
xilTemac = &gXilTemac[i];
|
||||||
|
|
||||||
|
if( xilTemac->iIsPresent ) {
|
||||||
|
xilTemacIsrSingle(xilTemac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rtems_isr xilTemacIsr(void *handle )
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = (struct XilTemac*)handle;
|
||||||
|
|
||||||
|
xilTemacIsrSingle(xilTemac);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacIsrOn(const rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacIsrOff(const rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int xilTemacIsrIsOn(const rtems_irq_connect_data *unused)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int32_t xilTemacSetMulticastFilter(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xilTemacIoctl(struct ifnet* ifp, ioctl_command_t aCommand, caddr_t aData)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
int32_t error = 0;
|
||||||
|
|
||||||
|
switch(aCommand) {
|
||||||
|
case SIOCGIFADDR:
|
||||||
|
case SIOCSIFADDR:
|
||||||
|
ether_ioctl(ifp, aCommand, aData);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIOCSIFFLAGS:
|
||||||
|
switch(ifp->if_flags & (IFF_UP | IFF_RUNNING))
|
||||||
|
{
|
||||||
|
case IFF_RUNNING:
|
||||||
|
xilTemacStop(ifp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFF_UP:
|
||||||
|
xilTemacStart(ifp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFF_UP | IFF_RUNNING:
|
||||||
|
xilTemacReset(ifp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIOCADDMULTI:
|
||||||
|
case SIOCDELMULTI: {
|
||||||
|
struct ifreq* ifr = (struct ifreq*) aData;
|
||||||
|
error = ((aCommand == SIOCADDMULTI) ?
|
||||||
|
( ether_addmulti(ifr, &(xilTemac->iArpcom)) ) :
|
||||||
|
( ether_delmulti(ifr, &(xilTemac->iArpcom)))
|
||||||
|
);
|
||||||
|
/* ENETRESET indicates that driver should update its multicast filters */
|
||||||
|
if(error == ENETRESET)
|
||||||
|
{
|
||||||
|
error = xilTemacSetMulticastFilter( ifp );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIO_RTEMS_SHOW_STATS:
|
||||||
|
xilTemacPrintStats( ifp );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacSend(struct ifnet* ifp)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
|
||||||
|
/* wake up tx thread w/ outbound interface's signal */
|
||||||
|
rtems_event_send( gXilTxThread, xilTemac->iIoEvent );
|
||||||
|
|
||||||
|
ifp->if_flags |= IFF_OACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* align the tx buffer to 32 bytes just for kicks, should make it more
|
||||||
|
* cache friendly */
|
||||||
|
static unsigned char gTxBuf[2048] __attribute__ ((aligned (32)));
|
||||||
|
|
||||||
|
void xilTemacSendPacket(struct ifnet *ifp, struct mbuf* aMbuf)
|
||||||
|
{
|
||||||
|
struct XilTemac *xilTemac = ifp->if_softc;
|
||||||
|
struct mbuf *n = aMbuf;
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("SendPacket\n");
|
||||||
|
printk("TXD: 0x%08x\n", (int32_t) n->m_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* assemble the packet into the tx buffer */
|
||||||
|
for(;;) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
uint32_t i = 0;
|
||||||
|
printk("MBUF: 0x%08x : ", (int32_t) n->m_data);
|
||||||
|
for (i=0;i<n->m_len;i+=2) {
|
||||||
|
printk("%02x%02x ", mtod(n, unsigned char*)[i], mtod(n, unsigned char*)[i+1]);
|
||||||
|
}
|
||||||
|
printk("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( n->m_len > 0 ) {
|
||||||
|
memcpy( &gTxBuf[ len ], (char *)n->m_data, n->m_len);
|
||||||
|
len += n->m_len;
|
||||||
|
}
|
||||||
|
if( (n = n->m_next) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xilTemacFifoWrite64( xilTemac->iAddr, (uint32_t*)gTxBuf, len );
|
||||||
|
/* Set the Transmit Packet Length Register which registers the packet
|
||||||
|
* length, enqueues the packet and signals the xmit unit to start
|
||||||
|
* sending. */
|
||||||
|
OUT32(xilTemac->iAddr + XTE_TPLR_OFFSET, len);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: txpkt, len %d\n", DRIVER_PREFIX, len );
|
||||||
|
memset(gTxBuf, 0, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacTxThreadSingle(struct ifnet* ifp)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
struct mbuf* m;
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: tx send packet, interface '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Send packets till mbuf queue empty or tx fifo full */
|
||||||
|
for(;;) {
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
/* 1) clear out any statuses from previously sent tx frames */
|
||||||
|
while( IN32(base + XTE_IPISR_OFFSET) & XTE_IPXR_XMIT_DONE_MASK ) {
|
||||||
|
IN32(base + XTE_TSR_OFFSET);
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_XMIT_DONE_MASK);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if( i > xilTemac->iStats.iTxMaxDrained ) {
|
||||||
|
xilTemac->iStats.iTxMaxDrained = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2) Check if enough space in tx data fifo _and_ tx tplr for an entire
|
||||||
|
ethernet frame */
|
||||||
|
if( xilTemacTxFifoVacancyBytes( xilTemac->iAddr ) <= ifp->if_mtu ) {
|
||||||
|
/* 2a) If not, enable transmit done interrupt and break out of loop to
|
||||||
|
wait for space */
|
||||||
|
uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
|
||||||
|
ipier |= (XTE_IPXR_XMIT_DONE_MASK);
|
||||||
|
OUT32(base + XTE_IPIER_OFFSET, ipier);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3) Contuine to dequeue mbuf chains till none left */
|
||||||
|
IF_DEQUEUE( &(ifp->if_snd), m);
|
||||||
|
if( !m ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4) Send dequeued mbuf chain */
|
||||||
|
xilTemacSendPacket( ifp, m );
|
||||||
|
|
||||||
|
/* 5) Free mbuf chain */
|
||||||
|
m_freem( m );
|
||||||
|
}
|
||||||
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacTxThread( void *ignore )
|
||||||
|
{
|
||||||
|
struct XilTemac *xilTemac;
|
||||||
|
struct ifnet *ifp;
|
||||||
|
|
||||||
|
rtems_event_set events;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
/* Wait for:
|
||||||
|
- notification from stack of packet to send OR
|
||||||
|
- notification from interrupt handler that there is space available to
|
||||||
|
send already queued packets
|
||||||
|
*/
|
||||||
|
rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
|
||||||
|
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
||||||
|
RTEMS_NO_TIMEOUT,
|
||||||
|
&events );
|
||||||
|
|
||||||
|
for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
|
||||||
|
xilTemac = &gXilTemac[i];
|
||||||
|
|
||||||
|
if( xilTemac->iIsPresent ) {
|
||||||
|
ifp = xilTemac->iIfp;
|
||||||
|
|
||||||
|
if( (ifp->if_flags & IFF_RUNNING) ) {
|
||||||
|
|
||||||
|
if( events & xilTemac->iIoEvent ) {
|
||||||
|
xilTemacTxThreadSingle(ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printk("%s: xilTemacTxThread: event received for device: %s, but device not active\n",
|
||||||
|
DRIVER_PREFIX, xilTemac->iUnitName);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacRxThreadSingle(struct ifnet* ifp)
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac = ifp->if_softc;
|
||||||
|
|
||||||
|
uint32_t npkts = 0;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: rxthread, packet rx on interface %s\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t base = xilTemac->iAddr;
|
||||||
|
|
||||||
|
/* While RECV_DONE_MASK in ipisr stays set */
|
||||||
|
while( IN32(base + XTE_IPISR_OFFSET) & XTE_IPXR_RECV_DONE_MASK ) {
|
||||||
|
|
||||||
|
/* 1) Read the length of the packet */
|
||||||
|
uint32_t bytes = IN32(base + XTE_RPLR_OFFSET);
|
||||||
|
|
||||||
|
/* 2) Read the Read Status Register (which contains no information). When
|
||||||
|
* all of these in the fifo have been read, then XTE_IPXR_RECV_DONE_MASK
|
||||||
|
* will stay turned off, after it's written to */
|
||||||
|
IN32(base + XTE_RSR_OFFSET);
|
||||||
|
npkts++;
|
||||||
|
|
||||||
|
struct mbuf* m;
|
||||||
|
struct ether_header* eh;
|
||||||
|
|
||||||
|
/* 3) Get some memory from the ip stack to store the packet in */
|
||||||
|
MGETHDR(m, M_WAIT, MT_DATA);
|
||||||
|
MCLGET(m, M_WAIT);
|
||||||
|
|
||||||
|
m->m_pkthdr.rcvif = ifp;
|
||||||
|
|
||||||
|
/* 4) Copy the packet into the ip stack's memory */
|
||||||
|
xilTemacFifoRead64( base, mtod(m, uint32_t*), bytes);
|
||||||
|
|
||||||
|
m->m_len = bytes - sizeof(struct ether_header);
|
||||||
|
m->m_pkthdr.len = bytes - sizeof(struct ether_header);
|
||||||
|
|
||||||
|
eh = mtod(m, struct ether_header*);
|
||||||
|
|
||||||
|
m->m_data += sizeof(struct ether_header);
|
||||||
|
|
||||||
|
/* 5) Tell the ip stack about the received packet */
|
||||||
|
ether_input(ifp, eh, m);
|
||||||
|
|
||||||
|
/* 6) Try and turn off XTE_IPXR_RECV_DONE bit in the ipisr. If there's
|
||||||
|
* still more packets (ie RSR ! empty), then it will stay asserted. If
|
||||||
|
* there's no more packets, this will turn it off.
|
||||||
|
*/
|
||||||
|
OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_DONE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End) All Rx packets serviced, renable rx interrupt */
|
||||||
|
uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
|
||||||
|
ipier |= XTE_IPXR_RECV_DONE_MASK;
|
||||||
|
OUT32(base + XTE_IPIER_OFFSET, ipier);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: rxthread, retrieved %d packets\n", DRIVER_PREFIX, npkts );
|
||||||
|
#endif
|
||||||
|
if(npkts > xilTemac->iStats.iRxMaxDrained) {
|
||||||
|
xilTemac->iStats.iRxMaxDrained = npkts;
|
||||||
|
}
|
||||||
|
/* ??) Very very occasionally, under extremely high stress, I get a situation
|
||||||
|
* where we process no packets. That is, the rx thread was evented, but
|
||||||
|
* there was no packet available. I'm not sure how this happens. Ideally,
|
||||||
|
* it shouldn't ocurr, and I suspect a minor bug in the driver. However, for
|
||||||
|
* me it's happenning 3 times in several hunderd million interrupts. Nothing
|
||||||
|
* bad happens, as long as we don't read from the rx fifo's if nothing is
|
||||||
|
* there. It is just not as efficient as possible (rx thread being evented
|
||||||
|
* pointlessly) and a bit disconcerting about how it's ocurring.
|
||||||
|
* The best way to reproduce this is to have two clients run:
|
||||||
|
* $ ping <host> -f -s 65507
|
||||||
|
* This flood pings the device from two clients with the maximum size ping
|
||||||
|
* packet. It absolutely hammers the device under test. Eventually, (if
|
||||||
|
* you leave it running overnight for instance), you'll get a couple of these
|
||||||
|
* stray rx events. */
|
||||||
|
if(npkts == 0) {
|
||||||
|
/*printk("%s: RxThreadSingle: fatal error: event received, but no packets available\n", DRIVER_PREFIX);
|
||||||
|
assert(0); */
|
||||||
|
xilTemac->iStats.iRxStrayEvents++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xilTemacRxThread( void *ignore )
|
||||||
|
{
|
||||||
|
struct XilTemac* xilTemac;
|
||||||
|
struct ifnet* ifp;
|
||||||
|
int i;
|
||||||
|
rtems_event_set events;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: xilTemacRxThread running\n", DRIVER_PREFIX );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
|
||||||
|
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
||||||
|
RTEMS_NO_TIMEOUT,
|
||||||
|
&events);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printk("%s: rxthread, wakeup\n", DRIVER_PREFIX );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(i=0; i< NUM_XILTEMAC_UNITS; i++) {
|
||||||
|
xilTemac = &gXilTemac[i];
|
||||||
|
|
||||||
|
if( xilTemac->iIsPresent ) {
|
||||||
|
ifp = xilTemac->iIfp;
|
||||||
|
|
||||||
|
if( (ifp->if_flags & IFF_RUNNING) != 0 ) {
|
||||||
|
if( events & xilTemac->iIoEvent ) {
|
||||||
|
xilTemacRxThreadSingle(ifp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printk("%s: rxthread, interface %s present but not running\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t xilTemac_driver_attach(struct rtems_bsdnet_ifconfig* aBsdConfig, int aDummy)
|
||||||
|
{
|
||||||
|
struct ifnet* ifp;
|
||||||
|
int32_t mtu;
|
||||||
|
int32_t unit;
|
||||||
|
char* unitName;
|
||||||
|
struct XilTemac* xilTemac;
|
||||||
|
|
||||||
|
unit = rtems_bsdnet_parse_driver_name(aBsdConfig, &unitName);
|
||||||
|
if(unit < 0 )
|
||||||
|
{
|
||||||
|
printk("%s: Interface Unit number < 0\n", DRIVER_PREFIX );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aBsdConfig->bpar == 0 )
|
||||||
|
{
|
||||||
|
printk("%s: Did not specify base address for device '%s'", DRIVER_PREFIX, unitName );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aBsdConfig->hardware_address == NULL )
|
||||||
|
{
|
||||||
|
printk("%s: No MAC address given for interface '%s'\n", DRIVER_PREFIX, unitName );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xilTemac = &gXilTemac[ unit ];
|
||||||
|
memset(xilTemac, 0, sizeof(struct XilTemac));
|
||||||
|
|
||||||
|
xilTemac->iIsPresent = 1;
|
||||||
|
|
||||||
|
snprintf( xilTemac->iUnitName, MAX_UNIT_BYTES, "%s%d", unitName, unit );
|
||||||
|
|
||||||
|
xilTemac->iIfp = &(xilTemac->iArpcom.ac_if);
|
||||||
|
ifp = &(xilTemac->iArpcom.ac_if);
|
||||||
|
xilTemac->iAddr = aBsdConfig->bpar;
|
||||||
|
xilTemac->iIoEvent = gUnitSignals[ unit ];
|
||||||
|
xilTemac->iIsrVector = aBsdConfig->irno;
|
||||||
|
|
||||||
|
memcpy( xilTemac->iArpcom.ac_enaddr, aBsdConfig->hardware_address, ETHER_ADDR_LEN);
|
||||||
|
|
||||||
|
if( aBsdConfig->mtu )
|
||||||
|
{
|
||||||
|
mtu = aBsdConfig->mtu;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtu = ETHERMTU;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifp->if_softc = xilTemac;
|
||||||
|
ifp->if_unit = unit;
|
||||||
|
ifp->if_name = unitName;
|
||||||
|
ifp->if_mtu = mtu;
|
||||||
|
ifp->if_init = xilTemacInit;
|
||||||
|
ifp->if_ioctl = xilTemacIoctl;
|
||||||
|
ifp->if_start = xilTemacSend;
|
||||||
|
ifp->if_output = ether_output;
|
||||||
|
|
||||||
|
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||||
|
|
||||||
|
if(ifp->if_snd.ifq_maxlen == 0)
|
||||||
|
{
|
||||||
|
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if_attach(ifp);
|
||||||
|
ether_ifattach(ifp);
|
||||||
|
|
||||||
|
/* create shared rx & tx threads */
|
||||||
|
if( (gXilRxThread == 0) && (gXilTxThread == 0) )
|
||||||
|
{
|
||||||
|
printk("%s: Creating shared RX/TX threads\n", DRIVER_PREFIX );
|
||||||
|
gXilRxThread = rtems_bsdnet_newproc("xerx", 4096, xilTemacRxThread, NULL );
|
||||||
|
gXilTxThread = rtems_bsdnet_newproc("xetx", 4096, xilTemacTxThread, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("%s: Initializing driver for '%s'\n", DRIVER_PREFIX, xilTemac->iUnitName );
|
||||||
|
|
||||||
|
printk("%s: base address 0x%08X, intnum 0x%02X, \n",
|
||||||
|
DRIVER_PREFIX,
|
||||||
|
aBsdConfig->bpar,
|
||||||
|
aBsdConfig->irno );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
375
c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h
Normal file
375
c/src/lib/libbsp/powerpc/virtex/network/xiltemac.h
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
* Driver for plb inteface of the xilinx temac 3.00a
|
||||||
|
*
|
||||||
|
* Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
|
||||||
|
* Copyright (c) 2007 Linn Products Ltd, Scotland.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XILINX_TEMAC_
|
||||||
|
#define _XILINX_TEMAC_
|
||||||
|
#include <rtems/irq.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define XILTEMAC_DRIVER_PREFIX "xiltemac"
|
||||||
|
|
||||||
|
#define DRIVER_PREFIX XILTEMAC_DRIVER_PREFIX
|
||||||
|
|
||||||
|
|
||||||
|
/** IPIF interrupt and reset registers
|
||||||
|
*/
|
||||||
|
#define XTE_DISR_OFFSET 0x00000000 /**< Device interrupt status */
|
||||||
|
#define XTE_DIPR_OFFSET 0x00000004 /**< Device interrupt pending */
|
||||||
|
#define XTE_DIER_OFFSET 0x00000008 /**< Device interrupt enable */
|
||||||
|
#define XTE_DIIR_OFFSET 0x00000018 /**< Device interrupt ID */
|
||||||
|
#define XTE_DGIE_OFFSET 0x0000001C /**< Device global interrupt enable */
|
||||||
|
#define XTE_IPISR_OFFSET 0x00000020 /**< IP interrupt status */
|
||||||
|
#define XTE_IPIER_OFFSET 0x00000028 /**< IP interrupt enable */
|
||||||
|
#define XTE_DSR_OFFSET 0x00000040 /**< Device software reset (write) */
|
||||||
|
|
||||||
|
/** IPIF transmit fifo
|
||||||
|
*/
|
||||||
|
#define XTE_PFIFO_TX_BASE_OFFSET 0x00002000 /**< Packet FIFO Tx channel */
|
||||||
|
#define XTE_PFIFO_TX_VACANCY_OFFSET 0x00002004 /**< Packet Fifo Tx Vacancy */
|
||||||
|
#define XTE_PFIFO_TX_DATA_OFFSET 0x00002100 /**< IPIF Tx packet fifo port */
|
||||||
|
|
||||||
|
/** IPIF receive fifo
|
||||||
|
*/
|
||||||
|
#define XTE_PFIFO_RX_BASE_OFFSET 0x00002010 /**< Packet FIFO Rx channel */
|
||||||
|
#define XTE_PFIFO_RX_VACANCY_OFFSET 0x00002014 /**< Packet Fifo Rx Vacancy */
|
||||||
|
#define XTE_PFIFO_RX_DATA_OFFSET 0x00002200 /**< IPIF Rx packet fifo port */
|
||||||
|
|
||||||
|
/** IPIF fifo masks
|
||||||
|
*/
|
||||||
|
#define XTE_PFIFO_COUNT_MASK 0x00FFFFFF
|
||||||
|
|
||||||
|
/** IPIF transmit and recieve DMA offsets
|
||||||
|
*/
|
||||||
|
#define XTE_DMA_SEND_OFFSET 0x00002300 /**< DMA Tx channel */
|
||||||
|
#define XTE_DMA_RECV_OFFSET 0x00002340 /**< DMA Rx channel */
|
||||||
|
|
||||||
|
/** IPIF IPIC_TO_TEMAC Core Registers
|
||||||
|
*/
|
||||||
|
#define XTE_CR_OFFSET 0x00001000 /**< Control */
|
||||||
|
#define XTE_TPLR_OFFSET 0x00001004 /**< Tx packet length (FIFO) */
|
||||||
|
#define XTE_TSR_OFFSET 0x00001008 /**< Tx status (FIFO) */
|
||||||
|
#define XTE_RPLR_OFFSET 0x0000100C /**< Rx packet length (FIFO) */
|
||||||
|
#define XTE_RSR_OFFSET 0x00001010 /**< Receive status */
|
||||||
|
#define XTE_IFGP_OFFSET 0x00001014 /**< Interframe gap */
|
||||||
|
#define XTE_TPPR_OFFSET 0x00001018 /**< Tx pause packet */
|
||||||
|
|
||||||
|
/** TEMAC Core Registers
|
||||||
|
* These are registers defined within the device's hard core located in the
|
||||||
|
* processor block. They are accessed with the host interface. These registers
|
||||||
|
* are addressed offset by XTE_HOST_IPIF_OFFSET or by the DCR base address
|
||||||
|
* if so configured.
|
||||||
|
*/
|
||||||
|
#define XTE_HOST_IPIF_OFFSET 0x00003000 /**< Offset of host registers when
|
||||||
|
memory mapped into IPIF */
|
||||||
|
#define XTE_ERXC0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000200) /**< Rx configuration word 0 */
|
||||||
|
#define XTE_ERXC1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000240) /**< Rx configuration word 1 */
|
||||||
|
#define XTE_ETXC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000280) /**< Tx configuration */
|
||||||
|
#define XTE_EFCC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000002C0) /**< Flow control configuration */
|
||||||
|
#define XTE_ECFG_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000300) /**< EMAC configuration */
|
||||||
|
#define XTE_EGMIC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000320) /**< RGMII/SGMII configuration */
|
||||||
|
#define XTE_EMC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000340) /**< Management configuration */
|
||||||
|
#define XTE_EUAW0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000380) /**< Unicast address word 0 */
|
||||||
|
#define XTE_EUAW1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000384) /**< Unicast address word 1 */
|
||||||
|
#define XTE_EMAW0_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000388) /**< Multicast address word 0 */
|
||||||
|
#define XTE_EMAW1_OFFSET (XTE_HOST_IPIF_OFFSET + 0x0000038C) /**< Multicast address word 1 */
|
||||||
|
#define XTE_EAFM_OFFSET (XTE_HOST_IPIF_OFFSET + 0x00000390) /**< Promisciuous mode */
|
||||||
|
#define XTE_EIRS_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003A0) /**< IRstatus */
|
||||||
|
#define XTE_EIREN_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003A4) /**< IRenable */
|
||||||
|
#define XTE_EMIID_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003B0) /**< MIIMwrData */
|
||||||
|
#define XTE_EMIIC_OFFSET (XTE_HOST_IPIF_OFFSET + 0x000003B4) /**< MiiMcnt */
|
||||||
|
|
||||||
|
/* Register masks. The following constants define bit locations of various
|
||||||
|
* control bits in the registers. Constants are not defined for those registers
|
||||||
|
* that have a single bit field representing all 32 bits. For further
|
||||||
|
* information on the meaning of the various bit masks, refer to the HW spec.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Interrupt status bits for top level interrupts
|
||||||
|
* These bits are associated with the XTE_DISR_OFFSET, XTE_DIPR_OFFSET,
|
||||||
|
* and XTE_DIER_OFFSET registers.
|
||||||
|
*/
|
||||||
|
#define XTE_DXR_SEND_FIFO_MASK 0x00000040 /**< Send FIFO channel */
|
||||||
|
#define XTE_DXR_RECV_FIFO_MASK 0x00000020 /**< Receive FIFO channel */
|
||||||
|
#define XTE_DXR_RECV_DMA_MASK 0x00000010 /**< Receive DMA channel */
|
||||||
|
#define XTE_DXR_SEND_DMA_MASK 0x00000008 /**< Send DMA channel */
|
||||||
|
#define XTE_DXR_CORE_MASK 0x00000004 /**< Core */
|
||||||
|
#define XTE_DXR_DPTO_MASK 0x00000002 /**< Data phase timeout */
|
||||||
|
#define XTE_DXR_TERR_MASK 0x00000001 /**< Transaction error */
|
||||||
|
|
||||||
|
/** Interrupt status bits for MAC interrupts
|
||||||
|
* These bits are associated with XTE_IPISR_OFFSET and XTE_IPIER_OFFSET
|
||||||
|
* registers.
|
||||||
|
*/
|
||||||
|
#define XTE_IPXR_XMIT_DONE_MASK 0x00000001 /**< Tx complete */
|
||||||
|
#define XTE_IPXR_RECV_DONE_MASK 0x00000002 /**< Rx complete */
|
||||||
|
#define XTE_IPXR_AUTO_NEG_MASK 0x00000004 /**< Auto negotiation complete */
|
||||||
|
#define XTE_IPXR_RECV_REJECT_MASK 0x00000008 /**< Rx packet rejected */
|
||||||
|
#define XTE_IPXR_XMIT_SFIFO_EMPTY_MASK 0x00000010 /**< Tx status fifo empty */
|
||||||
|
#define XTE_IPXR_RECV_LFIFO_EMPTY_MASK 0x00000020 /**< Rx length fifo empty */
|
||||||
|
#define XTE_IPXR_XMIT_LFIFO_FULL_MASK 0x00000040 /**< Tx length fifo full */
|
||||||
|
#define XTE_IPXR_RECV_LFIFO_OVER_MASK 0x00000080 /**< Rx length fifo overrun
|
||||||
|
Note that this signal is
|
||||||
|
no longer asserted by HW
|
||||||
|
*/
|
||||||
|
#define XTE_IPXR_RECV_LFIFO_UNDER_MASK 0x00000100 /**< Rx length fifo underrun */
|
||||||
|
#define XTE_IPXR_XMIT_SFIFO_OVER_MASK 0x00000200 /**< Tx status fifo overrun */
|
||||||
|
#define XTE_IPXR_XMIT_SFIFO_UNDER_MASK 0x00000400 /**< Tx status fifo underrun */
|
||||||
|
#define XTE_IPXR_XMIT_LFIFO_OVER_MASK 0x00000800 /**< Tx length fifo overrun */
|
||||||
|
#define XTE_IPXR_XMIT_LFIFO_UNDER_MASK 0x00001000 /**< Tx length fifo underrun */
|
||||||
|
#define XTE_IPXR_RECV_PFIFO_ABORT_MASK 0x00002000 /**< Rx packet rejected due to
|
||||||
|
full packet FIFO */
|
||||||
|
#define XTE_IPXR_RECV_LFIFO_ABORT_MASK 0x00004000 /**< Rx packet rejected due to
|
||||||
|
full length FIFO */
|
||||||
|
|
||||||
|
#define XTE_IPXR_RECV_DROPPED_MASK \
|
||||||
|
(XTE_IPXR_RECV_REJECT_MASK | \
|
||||||
|
XTE_IPXR_RECV_PFIFO_ABORT_MASK | \
|
||||||
|
XTE_IPXR_RECV_LFIFO_ABORT_MASK) /**< IPXR bits that indicate a dropped
|
||||||
|
receive frame */
|
||||||
|
#define XTE_IPXR_XMIT_ERROR_MASK \
|
||||||
|
(XTE_IPXR_XMIT_SFIFO_OVER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_SFIFO_UNDER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_LFIFO_OVER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_LFIFO_UNDER_MASK) /**< IPXR bits that indicate transmit
|
||||||
|
errors */
|
||||||
|
|
||||||
|
#define XTE_IPXR_RECV_ERROR_MASK \
|
||||||
|
(XTE_IPXR_RECV_DROPPED_MASK | \
|
||||||
|
XTE_IPXR_RECV_LFIFO_UNDER_MASK) /**< IPXR bits that indicate receive
|
||||||
|
errors */
|
||||||
|
|
||||||
|
#define XTE_IPXR_FIFO_FATAL_ERROR_MASK \
|
||||||
|
(XTE_IPXR_XMIT_SFIFO_OVER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_SFIFO_UNDER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_LFIFO_OVER_MASK | \
|
||||||
|
XTE_IPXR_XMIT_LFIFO_UNDER_MASK | \
|
||||||
|
XTE_IPXR_RECV_LFIFO_UNDER_MASK) /**< IPXR bits that indicate errors with
|
||||||
|
one of the length or status FIFOs
|
||||||
|
that is fatal in nature. These bits
|
||||||
|
can only be cleared by a device
|
||||||
|
reset */
|
||||||
|
|
||||||
|
/** Software reset register (DSR)
|
||||||
|
*/
|
||||||
|
#define XTE_DSR_RESET_MASK 0x0000000A /**< Write this value to DSR to
|
||||||
|
reset entire core */
|
||||||
|
|
||||||
|
|
||||||
|
/** Global interrupt enable register (DGIE)
|
||||||
|
*/
|
||||||
|
#define XTE_DGIE_ENABLE_MASK 0x80000000 /**< Write this value to DGIE to
|
||||||
|
enable interrupts from this
|
||||||
|
device */
|
||||||
|
|
||||||
|
/** Control Register (CR)
|
||||||
|
*/
|
||||||
|
#define XTE_CR_HTRST_MASK 0x00000008 /**< Reset hard temac */
|
||||||
|
#define XTE_CR_BCREJ_MASK 0x00000004 /**< Disable broadcast address
|
||||||
|
filtering */
|
||||||
|
#define XTE_CR_MCREJ_MASK 0x00000002 /**< Disable multicast address
|
||||||
|
filtering */
|
||||||
|
#define XTE_CR_HDUPLEX_MASK 0x00000001 /**< Enable half duplex operation */
|
||||||
|
|
||||||
|
|
||||||
|
/** Transmit Packet Length Register (TPLR)
|
||||||
|
*/
|
||||||
|
#define XTE_TPLR_TXPL_MASK 0x00003FFF /**< Tx packet length in bytes */
|
||||||
|
|
||||||
|
|
||||||
|
/** Transmit Status Register (TSR)
|
||||||
|
*/
|
||||||
|
#define XTE_TSR_TXED_MASK 0x80000000 /**< Excess deferral error */
|
||||||
|
#define XTE_TSR_PFIFOU_MASK 0x40000000 /**< Packet FIFO underrun */
|
||||||
|
#define XTE_TSR_TXA_MASK 0x3E000000 /**< Transmission attempts */
|
||||||
|
#define XTE_TSR_TXLC_MASK 0x01000000 /**< Late collision error */
|
||||||
|
#define XTE_TSR_TPCF_MASK 0x00000001 /**< Transmit packet complete
|
||||||
|
flag */
|
||||||
|
|
||||||
|
#define XTE_TSR_ERROR_MASK \
|
||||||
|
(XTE_TSR_TXED_MASK | \
|
||||||
|
XTE_TSR_PFIFOU_MASK | \
|
||||||
|
XTE_TSR_TXLC_MASK) /**< TSR bits that indicate an
|
||||||
|
error */
|
||||||
|
|
||||||
|
|
||||||
|
/** Receive Packet Length Register (RPLR)
|
||||||
|
*/
|
||||||
|
#define XTE_RPLR_RXPL_MASK 0x00003FFF /**< Rx packet length in bytes */
|
||||||
|
|
||||||
|
|
||||||
|
/** Receive Status Register (RSR)
|
||||||
|
*/
|
||||||
|
#define XTE_RSR_RPCF_MASK 0x00000001 /**< Receive packet complete
|
||||||
|
flag */
|
||||||
|
|
||||||
|
/** Interframe Gap Register (IFG)
|
||||||
|
*/
|
||||||
|
#define XTE_IFG_IFGD_MASK 0x000000FF /**< IFG delay */
|
||||||
|
|
||||||
|
|
||||||
|
/** Transmit Pause Packet Register (TPPR)
|
||||||
|
*/
|
||||||
|
#define XTE_TPPR_TPPD_MASK 0x0000FFFF /**< Tx pause packet data */
|
||||||
|
|
||||||
|
|
||||||
|
/** Receiver Configuration Word 1 (ERXC1)
|
||||||
|
*/
|
||||||
|
#define XTE_ERXC1_RXRST_MASK 0x80000000 /**< Receiver reset */
|
||||||
|
#define XTE_ERXC1_RXJMBO_MASK 0x40000000 /**< Jumbo frame enable */
|
||||||
|
#define XTE_ERXC1_RXFCS_MASK 0x20000000 /**< FCS not stripped */
|
||||||
|
#define XTE_ERXC1_RXEN_MASK 0x10000000 /**< Receiver enable */
|
||||||
|
#define XTE_ERXC1_RXVLAN_MASK 0x08000000 /**< VLAN enable */
|
||||||
|
#define XTE_ERXC1_RXHD_MASK 0x04000000 /**< Half duplex */
|
||||||
|
#define XTE_ERXC1_RXLT_MASK 0x02000000 /**< Length/type check disable */
|
||||||
|
#define XTE_ERXC1_ERXC1_MASK 0x0000FFFF /**< Pause frame source address
|
||||||
|
bits [47:32]. Bits [31:0]
|
||||||
|
are stored in register
|
||||||
|
ERXC0 */
|
||||||
|
|
||||||
|
|
||||||
|
/** Transmitter Configuration (ETXC)
|
||||||
|
*/
|
||||||
|
#define XTE_ETXC_TXRST_MASK 0x80000000 /**< Transmitter reset */
|
||||||
|
#define XTE_ETXC_TXJMBO_MASK 0x40000000 /**< Jumbo frame enable */
|
||||||
|
#define XTE_ETXC_TXFCS_MASK 0x20000000 /**< Generate FCS */
|
||||||
|
#define XTE_ETXC_TXEN_MASK 0x10000000 /**< Transmitter enable */
|
||||||
|
#define XTE_ETXC_TXVLAN_MASK 0x08000000 /**< VLAN enable */
|
||||||
|
#define XTE_ETXC_TXHD_MASK 0x04000000 /**< Half duplex */
|
||||||
|
#define XTE_ETXC_TXIFG_MASK 0x02000000 /**< IFG adjust enable */
|
||||||
|
|
||||||
|
|
||||||
|
/** Flow Control Configuration (EFCC)
|
||||||
|
*/
|
||||||
|
#define XTE_EFCC_TXFLO_MASK 0x40000000 /**< Tx flow control enable */
|
||||||
|
#define XTE_EFCC_RXFLO_MASK 0x20000000 /**< Rx flow control enable */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC Configuration (ECFG)
|
||||||
|
*/
|
||||||
|
#define XTE_ECFG_LINKSPD_MASK 0xC0000000 /**< Link speed */
|
||||||
|
#define XTE_ECFG_RGMII_MASK 0x20000000 /**< RGMII mode enable */
|
||||||
|
#define XTE_ECFG_SGMII_MASK 0x10000000 /**< SGMII mode enable */
|
||||||
|
#define XTE_ECFG_1000BASEX_MASK 0x08000000 /**< 1000BaseX mode enable */
|
||||||
|
#define XTE_ECFG_HOSTEN_MASK 0x04000000 /**< Host interface enable */
|
||||||
|
#define XTE_ECFG_TX16BIT 0x02000000 /**< 16 bit Tx client enable */
|
||||||
|
#define XTE_ECFG_RX16BIT 0x01000000 /**< 16 bit Rx client enable */
|
||||||
|
|
||||||
|
#define XTE_ECFG_LINKSPD_10 0x00000000 /**< XTE_ECFG_LINKSPD_MASK for
|
||||||
|
10 Mbit */
|
||||||
|
#define XTE_ECFG_LINKSPD_100 0x40000000 /**< XTE_ECFG_LINKSPD_MASK for
|
||||||
|
100 Mbit */
|
||||||
|
#define XTE_ECFG_LINKSPD_1000 0x80000000 /**< XTE_ECFG_LINKSPD_MASK for
|
||||||
|
1000 Mbit */
|
||||||
|
|
||||||
|
/** EMAC RGMII/SGMII Configuration (EGMIC)
|
||||||
|
*/
|
||||||
|
#define XTE_EGMIC_RGLINKSPD_MASK 0xC0000000 /**< RGMII link speed */
|
||||||
|
#define XTE_EGMIC_SGLINKSPD_MASK 0x0000000C /**< SGMII link speed */
|
||||||
|
#define XTE_EGMIC_RGSTATUS_MASK 0x00000002 /**< RGMII link status */
|
||||||
|
#define XTE_EGMIC_RGHALFDUPLEX_MASK 0x00000001 /**< RGMII half duplex */
|
||||||
|
|
||||||
|
#define XTE_EGMIC_RGLINKSPD_10 0x00000000 /**< XTE_EGMIC_RGLINKSPD_MASK
|
||||||
|
for 10 Mbit */
|
||||||
|
#define XTE_EGMIC_RGLINKSPD_100 0x40000000 /**< XTE_EGMIC_RGLINKSPD_MASK
|
||||||
|
for 100 Mbit */
|
||||||
|
#define XTE_EGMIC_RGLINKSPD_1000 0x80000000 /**< XTE_EGMIC_RGLINKSPD_MASK
|
||||||
|
for 1000 Mbit */
|
||||||
|
#define XTE_EGMIC_SGLINKSPD_10 0x00000000 /**< XTE_SGMIC_RGLINKSPD_MASK
|
||||||
|
for 10 Mbit */
|
||||||
|
#define XTE_EGMIC_SGLINKSPD_100 0x00000004 /**< XTE_SGMIC_RGLINKSPD_MASK
|
||||||
|
for 100 Mbit */
|
||||||
|
#define XTE_EGMIC_SGLINKSPD_1000 0x00000008 /**< XTE_SGMIC_RGLINKSPD_MASK
|
||||||
|
for 1000 Mbit */
|
||||||
|
|
||||||
|
/** EMAC Management Configuration (EMC)
|
||||||
|
*/
|
||||||
|
#define XTE_EMC_MDIO_MASK 0x00000040 /**< MII management enable */
|
||||||
|
#define XTE_EMC_CLK_DVD_MAX 0x3F /**< Maximum MDIO divisor */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC Unicast Address Register Word 1 (EUAW1)
|
||||||
|
*/
|
||||||
|
#define XTE_EUAW1_MASK 0x0000FFFF /**< Station address bits [47:32]
|
||||||
|
Station address bits [31:0]
|
||||||
|
are stored in register
|
||||||
|
EUAW0 */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC Multicast Address Register Word 1 (EMAW1)
|
||||||
|
*/
|
||||||
|
#define XTE_EMAW1_CAMRNW_MASK 0x00800000 /**< CAM read/write control */
|
||||||
|
#define XTE_EMAW1_CAMADDR_MASK 0x00030000 /**< CAM address mask */
|
||||||
|
#define XTE_EUAW1_MASK 0x0000FFFF /**< Multicast address bits [47:32]
|
||||||
|
Multicast address bits [31:0]
|
||||||
|
are stored in register
|
||||||
|
EMAW0 */
|
||||||
|
#define XTE_EMAW1_CAMMADDR_SHIFT_MASK 16 /**< Number of bits to shift right
|
||||||
|
to align with
|
||||||
|
XTE_EMAW1_CAMADDR_MASK */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC Address Filter Mode (EAFM)
|
||||||
|
*/
|
||||||
|
#define XTE_EAFM_EPPRM_MASK 0x80000000 /**< Promiscuous mode enable */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC MII Management Write Data (EMIID)
|
||||||
|
*/
|
||||||
|
#define XTE_EMIID_MIIMWRDATA_MASK 0x0000FFFF /**< Data port */
|
||||||
|
|
||||||
|
|
||||||
|
/** EMAC MII Management Control (EMIIC)
|
||||||
|
*/
|
||||||
|
#define XTE_EMIID_MIIMDECADDR_MASK 0x0000FFFF /**< Address port */
|
||||||
|
|
||||||
|
|
||||||
|
struct XilTemacStats
|
||||||
|
{
|
||||||
|
volatile uint32_t iInterrupts;
|
||||||
|
|
||||||
|
volatile uint32_t iRxInterrupts;
|
||||||
|
volatile uint32_t iRxRejectedInterrupts;
|
||||||
|
volatile uint32_t iRxRejectedInvalidFrame;
|
||||||
|
volatile uint32_t iRxRejectedDataFifoFull;
|
||||||
|
volatile uint32_t iRxRejectedLengthFifoFull;
|
||||||
|
volatile uint32_t iRxMaxDrained;
|
||||||
|
volatile uint32_t iRxStrayEvents;
|
||||||
|
|
||||||
|
volatile uint32_t iTxInterrupts;
|
||||||
|
volatile uint32_t iTxMaxDrained;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_UNIT_BYTES 50
|
||||||
|
|
||||||
|
struct XilTemac
|
||||||
|
{
|
||||||
|
struct arpcom iArpcom;
|
||||||
|
struct XilTemacStats iStats;
|
||||||
|
struct ifnet* iIfp;
|
||||||
|
|
||||||
|
char iUnitName[MAX_UNIT_BYTES];
|
||||||
|
|
||||||
|
uint32_t iAddr;
|
||||||
|
rtems_event_set iIoEvent;
|
||||||
|
|
||||||
|
int iIsrVector;
|
||||||
|
|
||||||
|
#if PPC_HAS_CLASSIC_EXCEPTIONS
|
||||||
|
rtems_isr_entry iOldHandler;
|
||||||
|
#else
|
||||||
|
rtems_irq_connect_data iOldHandler;
|
||||||
|
#endif
|
||||||
|
int iIsPresent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _XILINX_EMAC_*/
|
||||||
143
c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c
Normal file
143
c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/* opbintctrl.c
|
||||||
|
*
|
||||||
|
* This file contains definitions and declarations for the
|
||||||
|
* Xilinx Off Processor Bus (OPB) Interrupt Controller
|
||||||
|
*
|
||||||
|
* Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
|
||||||
|
* COPYRIGHT (c) 2005 Linn Products Ltd, Scotland.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bsp/opbintctrl.h>
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#include <rtems/powerpc/powerpc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Acknowledge a mask of interrupts.
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void set_iar(uint32_t mask)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set IER state. Used to (dis)enable a mask of vectors.
|
||||||
|
* If you only have to do one, use enable/disable_vector.
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void set_ier(uint32_t mask)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve contents of Interrupt Pending Register
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t get_ipr()
|
||||||
|
{
|
||||||
|
uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE))
|
||||||
|
= 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
|
||||||
|
= 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRQ Handler: this is called from the primary exception dispatcher
|
||||||
|
*/
|
||||||
|
void BSP_irq_handle_at_opbintc(void)
|
||||||
|
{
|
||||||
|
uint32_t ipr, iprcopy, mask, i, c;
|
||||||
|
rtems_irq_connect_data *tbl_entry;
|
||||||
|
iprcopy = ipr = get_ipr();
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
(i < BSP_OPBINTC_PER_IRQ_NUMBER)
|
||||||
|
&& (ipr != 0);
|
||||||
|
i++) {
|
||||||
|
c = (1 << i);
|
||||||
|
|
||||||
|
if ((ipr & c) != 0) {
|
||||||
|
/* interrupt is asserted */
|
||||||
|
mask |= c;
|
||||||
|
ipr &= ~c;
|
||||||
|
|
||||||
|
tbl_entry = &BSP_rtems_irq_tbl[i+BSP_OPBINTC_IRQ_LOWEST_OFFSET];
|
||||||
|
if (tbl_entry->hdl != NULL) {
|
||||||
|
(tbl_entry->hdl) (tbl_entry->handle);
|
||||||
|
} else {
|
||||||
|
printk("opbintctrl: Spurious interrupt; IPR 0x%08X, vector 0x%x\n\r",
|
||||||
|
iprcopy, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask) {
|
||||||
|
/* ack all the interrupts we serviced */
|
||||||
|
set_iar(mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* activate the interrupt controller
|
||||||
|
*/
|
||||||
|
rtems_status_code opb_intc_init(void)
|
||||||
|
{
|
||||||
|
uint32_t msr_value;
|
||||||
|
uint32_t i, mask = 0;
|
||||||
|
|
||||||
|
/* mask off all interrupts */
|
||||||
|
set_ier(0x0);
|
||||||
|
|
||||||
|
for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
|
||||||
|
mask |= (1 << i);
|
||||||
|
}
|
||||||
|
printk("opb_intc_init: mask = 0x%x\n", (unsigned) mask);
|
||||||
|
|
||||||
|
/* make sure interupt status register is clear before we enable the interrupt controller */
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
|
||||||
|
|
||||||
|
/* acknowledge all interrupt sources */
|
||||||
|
set_iar(mask);
|
||||||
|
|
||||||
|
/* Turn on normal hardware operation of interrupt controller */
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
|
||||||
|
(OPB_INTC_MER_HIE);
|
||||||
|
|
||||||
|
/* Enable master interrupt switch for the interrupt controller */
|
||||||
|
*((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
|
||||||
|
(OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
|
||||||
|
|
||||||
|
#if 0 /* EB: we do it somewhere else */
|
||||||
|
/*
|
||||||
|
* enable (non-critical) exceptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
_CPU_MSR_GET(msr_value);
|
||||||
|
msr_value |= PPC_MSR_EE;
|
||||||
|
_CPU_MSR_SET(msr_value);
|
||||||
|
|
||||||
|
/* install exit handler to close opb_intc when program atexit called */
|
||||||
|
/* atexit(opb_intc_exit); */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
79
c/src/lib/libbsp/powerpc/virtex/preinstall.am
Normal file
79
c/src/lib/libbsp/powerpc/virtex/preinstall.am
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
## Automatically generated by ampolish3 - Do not edit
|
||||||
|
|
||||||
|
if AMPOLISH3
|
||||||
|
$(srcdir)/preinstall.am: Makefile.am
|
||||||
|
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
|
||||||
|
endif
|
||||||
|
|
||||||
|
PREINSTALL_DIRS =
|
||||||
|
DISTCLEANFILES += $(PREINSTALL_DIRS)
|
||||||
|
|
||||||
|
all-am: $(PREINSTALL_FILES)
|
||||||
|
|
||||||
|
PREINSTALL_FILES =
|
||||||
|
CLEANFILES = $(PREINSTALL_FILES)
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/$(dirstamp):
|
||||||
|
@$(mkdir_p) $(PROJECT_LIB)
|
||||||
|
@: > $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/$(dirstamp):
|
||||||
|
@$(mkdir_p) $(PROJECT_INCLUDE)
|
||||||
|
@: > $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
|
||||||
|
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/opbintctrl.h: include/opbintctrl.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/opbintctrl.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/opbintctrl.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/irq.h: irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/vectors.h: ../../powerpc/shared/vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
|
||||||
|
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/xiltemac.h: network/xiltemac.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/xiltemac.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/xiltemac.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/xparameters_dflt.h: include/xparameters_dflt.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/xparameters_dflt.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/xparameters_dflt.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
|
||||||
|
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
|
||||||
|
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
|
||||||
|
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/linkcmds.dl: startup/linkcmds.dl $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.dl
|
||||||
|
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.dl
|
||||||
|
|
||||||
43
c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c
Normal file
43
c/src/lib/libbsp/powerpc/virtex/startup/bspclean.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* bsp_cleanup()
|
||||||
|
*
|
||||||
|
* This routine normally is part of start.s and usually returns
|
||||||
|
* control to a monitor.
|
||||||
|
*
|
||||||
|
* INPUT: NONE
|
||||||
|
*
|
||||||
|
* OUTPUT: NONE
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c:
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1999.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
void bsp_cleanup( void )
|
||||||
|
{
|
||||||
|
rtems_fatal_error_occurred(0);
|
||||||
|
}
|
||||||
277
c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
Normal file
277
c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
/* bsp_start()
|
||||||
|
*
|
||||||
|
* This routine starts the application. It includes application,
|
||||||
|
* board, and monitor specific initialization and configuration.
|
||||||
|
* The generic CPU dependent initialization has been performed
|
||||||
|
* before this routine is invoked.
|
||||||
|
*
|
||||||
|
* INPUT: NONE
|
||||||
|
*
|
||||||
|
* OUTPUT: NONE
|
||||||
|
*
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* IMD Ingenieurbuero fuer Microcomputertechnik
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD
|
||||||
|
*
|
||||||
|
* Changes from IMD are covered by the original distributions terms.
|
||||||
|
* This file has been derived from the papyrus BSP:
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Modifications for spooling console driver and control of memory layout
|
||||||
|
* with linker command file by
|
||||||
|
* Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
* for these modifications:
|
||||||
|
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies. IMD makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c:
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
#include <rtems/libcsupport.h>
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
#include <libcpu/cpuIdent.h>
|
||||||
|
#include <libcpu/spr.h>
|
||||||
|
#include <rtems/powerpc/powerpc.h>
|
||||||
|
|
||||||
|
SPR_RW(SPRG0)
|
||||||
|
SPR_RW(SPRG1)
|
||||||
|
|
||||||
|
#include RTEMS_XPARAMETERS_H
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The original table from the application and our copy of it with
|
||||||
|
* some changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern rtems_configuration_table Configuration;
|
||||||
|
|
||||||
|
rtems_configuration_table BSP_Configuration;
|
||||||
|
|
||||||
|
rtems_cpu_table Cpu_table;
|
||||||
|
|
||||||
|
char *rtems_progname;
|
||||||
|
|
||||||
|
uint32_t _heap_start;
|
||||||
|
uint32_t _heap_end;
|
||||||
|
uint32_t _top_of_ram;
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize whatever libc we are using
|
||||||
|
* called from postdriver hook
|
||||||
|
*/
|
||||||
|
|
||||||
|
void bsp_XAssertHandler(const char* file, int line);
|
||||||
|
void bsp_postdriver_hook(void);
|
||||||
|
void bsp_libc_init( void *, uint32_t, int );
|
||||||
|
|
||||||
|
|
||||||
|
void bsp_XAssertHandler(const char* file, int line) {
|
||||||
|
printf("\n***\n*** XAssert Failed! File: %s, Line: %d\n***\n", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* bsp_predriver_hook
|
||||||
|
*
|
||||||
|
* Before drivers are setup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void bsp_predriver_hook(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: bsp_pretasking_hook
|
||||||
|
* Created: 95/03/10
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* BSP pretasking hook. Called just before drivers are initialized.
|
||||||
|
* Used to setup libc and install any BSP extensions.
|
||||||
|
*
|
||||||
|
* NOTES:
|
||||||
|
* Must not use libc (to do io) from here, since drivers are
|
||||||
|
* not yet initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void bsp_pretasking_hook(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t heap_start;
|
||||||
|
uint32_t heap_size;
|
||||||
|
uint32_t heap_end;
|
||||||
|
|
||||||
|
/* round up from the top of workspace to next 64k boundary, get
|
||||||
|
* default heapsize from linker script */
|
||||||
|
heap_start = (((uint32_t)BSP_Configuration.work_space_start +
|
||||||
|
BSP_Configuration.work_space_size) + 0x18000) & 0xffff0000;
|
||||||
|
|
||||||
|
heap_end = _heap_start + (uint32_t)&_HeapSize;
|
||||||
|
|
||||||
|
heap_size = (heap_end - heap_start);
|
||||||
|
|
||||||
|
_heap_start = heap_start;
|
||||||
|
_heap_end = heap_end;
|
||||||
|
|
||||||
|
_top_of_ram = heap_end;
|
||||||
|
|
||||||
|
bsp_libc_init((void *) heap_start, heap_size, 0); /* 64 * 1024 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
XAssertSetCallback((XAssertCallback*)bsp_XAssertHandler);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef RTEMS_DEBUG
|
||||||
|
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bsp_start
|
||||||
|
*
|
||||||
|
* This routine does the bulk of the system initialization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void bsp_start( void )
|
||||||
|
{
|
||||||
|
extern unsigned long *intrStackPtr;
|
||||||
|
register unsigned char* intrStack;
|
||||||
|
ppc_cpu_id_t myCpu;
|
||||||
|
ppc_cpu_revision_t myCpuRevision;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get CPU identification dynamically. Note that the get_ppc_cpu_type()
|
||||||
|
* function store the result in global variables
|
||||||
|
* so that it can be used latter...
|
||||||
|
*/
|
||||||
|
myCpu = get_ppc_cpu_type();
|
||||||
|
myCpuRevision = get_ppc_cpu_revision();
|
||||||
|
/*
|
||||||
|
* initialize the CPU table for this BSP
|
||||||
|
* NOTE: this must be before the exception initialization,
|
||||||
|
* because exception code useses some information from Cpu_table
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||||
|
Cpu_table.predriver_hook = bsp_predriver_hook;
|
||||||
|
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
||||||
|
Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
|
||||||
|
|
||||||
|
/* timebase register ticks/microsecond */
|
||||||
|
Cpu_table.clicks_per_usec = (250000000 / 1000000);
|
||||||
|
|
||||||
|
Cpu_table.serial_per_sec = 14625000; /* = (CPU Clock / UART Internal Clock Divisor) */
|
||||||
|
Cpu_table.serial_external_clock = 0;
|
||||||
|
Cpu_table.timer_internal_clock = 1;
|
||||||
|
Cpu_table.serial_xon_xoff = 0;
|
||||||
|
Cpu_table.serial_cts_rts = 0;
|
||||||
|
Cpu_table.serial_rate = 115200;
|
||||||
|
Cpu_table.timer_average_overhead = 2;
|
||||||
|
Cpu_table.timer_least_valid = 3;
|
||||||
|
Cpu_table.exceptions_in_RAM = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize some SPRG registers related to irq handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE);
|
||||||
|
_write_SPRG1((unsigned int)intrStack);
|
||||||
|
/* signal them that we have fixed PR288 - eventually, this should go away */
|
||||||
|
_write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize default raw exception handlers.
|
||||||
|
* See shared/vectors/vectors_init.c
|
||||||
|
*/
|
||||||
|
initialize_exceptions();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install our own set of exception vectors
|
||||||
|
*/
|
||||||
|
BSP_rtems_irq_mng_init(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate the memory for the RTEMS Work Space. This can come from
|
||||||
|
* a variety of places: hard coded address, malloc'ed from outside
|
||||||
|
* RTEMS world (e.g. simulator or primitive memory manager), or (as
|
||||||
|
* typically done by stock BSPs) by subtracting the required amount
|
||||||
|
* of work space from the last physical address on the CPU board.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to "allocate" the memory for the RTEMS Workspace and
|
||||||
|
* tell the RTEMS configuration where it is. This memory is
|
||||||
|
* not malloc'ed. It is just "pulled from the air".
|
||||||
|
*/
|
||||||
|
/* FIME: plan usage of RAM better:
|
||||||
|
- make top of ram dynamic,
|
||||||
|
- make rest of ram to heap...
|
||||||
|
-remove RAM_END from bsp.h, this cannot be valid...
|
||||||
|
or must be a function call
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
extern int _end;
|
||||||
|
|
||||||
|
/* round _end up to next 64k boundary for start of workspace */
|
||||||
|
BSP_Configuration.work_space_start = (void *)((((uint32_t)&_end) + 0x18000) & 0xffff0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_ask_for_reset(void)
|
||||||
|
{
|
||||||
|
printk("system stopped, press RESET");
|
||||||
|
while(1) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSP_panic(char *s)
|
||||||
|
{
|
||||||
|
printk("%s PANIC %s\n",_RTEMS_version, s);
|
||||||
|
BSP_ask_for_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _BSP_Fatal_error(unsigned int v)
|
||||||
|
{
|
||||||
|
printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
|
||||||
|
BSP_ask_for_reset();
|
||||||
|
}
|
||||||
|
|
||||||
169
c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
Normal file
169
c/src/lib/libbsp/powerpc/virtex/startup/linkcmds
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/* Greg modifications
|
||||||
|
* This file contains directives for the GNU linker which are specific
|
||||||
|
* to the virtex
|
||||||
|
* This file is intended to be used together with dlentry.s
|
||||||
|
* it will generate downloadable code
|
||||||
|
*
|
||||||
|
* Modifications for gen405 by Dennis Ehlin
|
||||||
|
* Modifications for virtex by Keith, Greg, and Bob
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
|
||||||
|
"elf32-powerpc")
|
||||||
|
OUTPUT_ARCH(powerpc)
|
||||||
|
|
||||||
|
ENTRY(download_entry)
|
||||||
|
|
||||||
|
|
||||||
|
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 8M;
|
||||||
|
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM : ORIGIN = 0, LENGTH = 16M
|
||||||
|
/*FLASH : ORIGIN = 0xFFE00000, LENGTH = 16M*/
|
||||||
|
}
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text 0x10000:
|
||||||
|
{
|
||||||
|
text.start = . ;
|
||||||
|
*(.entry)
|
||||||
|
*(.entry2)
|
||||||
|
*(.text*)
|
||||||
|
*(.rodata*)
|
||||||
|
*(.rodata1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special FreeBSD sysctl sections.
|
||||||
|
*/
|
||||||
|
. = ALIGN (16);
|
||||||
|
__start_set_sysctl_set = .;
|
||||||
|
*(set_sysctl_*);
|
||||||
|
__stop_set_sysctl_set = ABSOLUTE(.);
|
||||||
|
*(set_domain_*);
|
||||||
|
*(set_pseudo_*);
|
||||||
|
|
||||||
|
*(.eh_frame)
|
||||||
|
*(.gnu.linkonce.r*)
|
||||||
|
*(.descriptors)
|
||||||
|
*(rom_ver)
|
||||||
|
etext = ALIGN(0x10);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
*(.gnu.linkonce.t*)
|
||||||
|
|
||||||
|
__CTOR_LIST__ = .;
|
||||||
|
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||||
|
*(.ctors)
|
||||||
|
LONG(0)
|
||||||
|
__CTOR_END__ = .;
|
||||||
|
|
||||||
|
__DTOR_LIST__ = .;
|
||||||
|
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||||
|
*(.dtors)
|
||||||
|
LONG(0)
|
||||||
|
__DTOR_END__ = .;
|
||||||
|
|
||||||
|
*(.lit)
|
||||||
|
*(.shdata)
|
||||||
|
_init = .; __init = .; *(.init)
|
||||||
|
_fini = .; __fini = .; *(.fini)
|
||||||
|
_endtext = ALIGN(0x10);
|
||||||
|
text.end = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
text.size = text.end - text.start;
|
||||||
|
|
||||||
|
/* R/W Data */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
*(.data1)
|
||||||
|
*(.data.* .gnu.linkonce.d*)
|
||||||
|
PROVIDE (__SDATA_START__ = .);
|
||||||
|
*(.sdata*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
PROVIDE (__EXCEPT_START__ = .);
|
||||||
|
.gcc_except_table :
|
||||||
|
{
|
||||||
|
*(.gcc_except_table)
|
||||||
|
} >RAM
|
||||||
|
PROVIDE (__EXCEPT_END__ = .);
|
||||||
|
|
||||||
|
__GOT_START__ = .;
|
||||||
|
.got :
|
||||||
|
{
|
||||||
|
s.got = .;
|
||||||
|
*(.got.plt) *(.got)
|
||||||
|
} > RAM
|
||||||
|
__GOT_END__ = .;
|
||||||
|
|
||||||
|
.got1 :
|
||||||
|
{
|
||||||
|
*(.got1)
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
PROVIDE (__GOT2_START__ = .);
|
||||||
|
PROVIDE (_GOT2_START_ = .);
|
||||||
|
.got2 :
|
||||||
|
{
|
||||||
|
*(.got2)
|
||||||
|
} >RAM
|
||||||
|
PROVIDE (__GOT2_END__ = .);
|
||||||
|
PROVIDE (_GOT2_END_ = .);
|
||||||
|
|
||||||
|
PROVIDE (__FIXUP_START__ = .);
|
||||||
|
PROVIDE (_FIXUP_START_ = .);
|
||||||
|
.fixup : { *(.fixup) } >RAM
|
||||||
|
PROVIDE (_FIXUP_END_ = .);
|
||||||
|
PROVIDE (__FIXUP_END__ = .);
|
||||||
|
|
||||||
|
PROVIDE (__SDATA2_START__ = .);
|
||||||
|
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >RAM
|
||||||
|
.sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >RAM
|
||||||
|
PROVIDE (__SBSS2_END__ = .);
|
||||||
|
|
||||||
|
__SBSS_START__ = .;
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
bss.start = .;
|
||||||
|
*(.bss .bss* .gnu.linkonce.b*)
|
||||||
|
*(.sbss*) *(COMMON)
|
||||||
|
bss.end = ALIGN(4);
|
||||||
|
bss.size = bss.end - bss.start;
|
||||||
|
} > RAM
|
||||||
|
__SBSS_END__ = .;
|
||||||
|
|
||||||
|
/* align bottom of 32k init stack at a 32k boundary */
|
||||||
|
. = . + 0x4000;
|
||||||
|
. = ALIGN( 0x8000 );
|
||||||
|
stack.start = .;
|
||||||
|
. = . + 0x8000;
|
||||||
|
stack.end = .;
|
||||||
|
/*
|
||||||
|
* Interrupt stack setup
|
||||||
|
*/
|
||||||
|
IntrStack_start = ALIGN(0x10);
|
||||||
|
. += 0x4000;
|
||||||
|
intrStack = .;
|
||||||
|
PROVIDE(intrStackPtr = intrStack);
|
||||||
|
|
||||||
|
PROVIDE(_end = intrStack);
|
||||||
|
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_aregion 0 : { *(.debug_aregion) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
|
||||||
|
}
|
||||||
154
c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl
Normal file
154
c/src/lib/libbsp/powerpc/virtex/startup/linkcmds.dl
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* This file contains directives for the GNU linker which are specific
|
||||||
|
* to the helas403
|
||||||
|
* This file is intended to be used together with dlentry.s
|
||||||
|
* it will generate downloadable code
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
|
||||||
|
"elf32-powerpc")
|
||||||
|
OUTPUT_ARCH(powerpc)
|
||||||
|
|
||||||
|
ENTRY(download_entry)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM : ORIGIN = 0, LENGTH = 8M
|
||||||
|
FLASH : ORIGIN = 0xFFF00000, LENGTH = 512K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.vectors : 0x00010100
|
||||||
|
{
|
||||||
|
*(.vectors)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
text.start = . ;
|
||||||
|
*(.entry)
|
||||||
|
*(.entry2)
|
||||||
|
*(.text*)
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special FreeBSD sysctl sections.
|
||||||
|
*/
|
||||||
|
. = ALIGN (16);
|
||||||
|
__start_set_sysctl_set = .;
|
||||||
|
*(set_sysctl_*);
|
||||||
|
__stop_set_sysctl_set = ABSOLUTE(.);
|
||||||
|
*(set_domain_*);
|
||||||
|
*(set_pseudo_*);
|
||||||
|
|
||||||
|
*.(eh_frame)
|
||||||
|
*(.descriptors)
|
||||||
|
*(rom_ver)
|
||||||
|
etext = ALIGN(0x10);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
|
||||||
|
__CTOR_LIST__ = .;
|
||||||
|
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||||
|
*(.ctors)
|
||||||
|
LONG(0)
|
||||||
|
__CTOR_END__ = .;
|
||||||
|
|
||||||
|
__DTOR_LIST__ = .;
|
||||||
|
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||||
|
*(.dtors)
|
||||||
|
LONG(0)
|
||||||
|
__DTOR_END__ = .;
|
||||||
|
|
||||||
|
*(.lit)
|
||||||
|
*(.shdata)
|
||||||
|
*(.init)
|
||||||
|
*(.fini)
|
||||||
|
_endtext = ALIGN(0x10);
|
||||||
|
text.end = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
text.size = text.end - text.start;
|
||||||
|
|
||||||
|
/* R/W Data */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
*(.data1)
|
||||||
|
PROVIDE (__SDATA_START__ = .);
|
||||||
|
*(.sdata*)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
PROVIDE (__EXCEPT_START__ = .);
|
||||||
|
.gcc_except_table :
|
||||||
|
{
|
||||||
|
*(.gcc_except_table)
|
||||||
|
} >RAM
|
||||||
|
PROVIDE (__EXCEPT_END__ = .);
|
||||||
|
|
||||||
|
__GOT_START__ = .;
|
||||||
|
.got :
|
||||||
|
{
|
||||||
|
s.got = .;
|
||||||
|
*(.got.plt) *(.got)
|
||||||
|
} > RAM
|
||||||
|
__GOT_END__ = .;
|
||||||
|
|
||||||
|
.got1 :
|
||||||
|
{
|
||||||
|
*(.got1)
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
PROVIDE (__GOT2_START__ = .);
|
||||||
|
PROVIDE (_GOT2_START_ = .);
|
||||||
|
.got2 :
|
||||||
|
{
|
||||||
|
*(.got2)
|
||||||
|
} >RAM
|
||||||
|
PROVIDE (__GOT2_END__ = .);
|
||||||
|
PROVIDE (_GOT2_END_ = .);
|
||||||
|
|
||||||
|
PROVIDE (__FIXUP_START__ = .);
|
||||||
|
PROVIDE (_FIXUP_START_ = .);
|
||||||
|
.fixup : { *(.fixup) } >RAM
|
||||||
|
PROVIDE (_FIXUP_END_ = .);
|
||||||
|
PROVIDE (__FIXUP_END__ = .);
|
||||||
|
|
||||||
|
PROVIDE (__SDATA2_START__ = .);
|
||||||
|
.sdata2 : { *(.sdata2) } >RAM
|
||||||
|
.sbss2 : { *(.sbss2) } >RAM
|
||||||
|
PROVIDE (__SBSS2_END__ = .);
|
||||||
|
|
||||||
|
.sbss2 : { *(.sbss2) } >RAM
|
||||||
|
PROVIDE (__SBSS2_END__ = .);
|
||||||
|
|
||||||
|
__SBSS_START__ = .;
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
bss.start = .;
|
||||||
|
*(.bss .bss* .gnu.linkonce.b*)
|
||||||
|
*(.sbss*) *(COMMON)
|
||||||
|
bss.end = ALIGN(4);
|
||||||
|
} > RAM
|
||||||
|
__SBSS_END__ = .;
|
||||||
|
|
||||||
|
bss.size = bss.end - bss.start;
|
||||||
|
PROVIDE(_end = bss.end);
|
||||||
|
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_aregion 0 : { *(.debug_aregion) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
56
c/src/lib/libbsp/powerpc/virtex/startup/setvec.c
Normal file
56
c/src/lib/libbsp/powerpc/virtex/startup/setvec.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/* set_vector
|
||||||
|
*
|
||||||
|
* This routine installs an interrupt vector on the target Board/CPU.
|
||||||
|
* This routine is allowed to be as board dependent as necessary.
|
||||||
|
*
|
||||||
|
* INPUT:
|
||||||
|
* handler - interrupt handler entry point
|
||||||
|
* vector - vector number
|
||||||
|
* type - 0 indicates raw hardware connect
|
||||||
|
* 1 indicates RTEMS interrupt connect
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* address of previous interrupt handler
|
||||||
|
*
|
||||||
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of i-cubed limited not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* i-cubed limited makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c:
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1999.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
rtems_isr_entry set_vector( /* returns old vector */
|
||||||
|
rtems_isr_entry handler, /* isr routine */
|
||||||
|
rtems_vector_number vector, /* vector number */
|
||||||
|
int type /* RTEMS or RAW intr */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_isr_entry previous_isr;
|
||||||
|
|
||||||
|
rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr );
|
||||||
|
|
||||||
|
return previous_isr;
|
||||||
|
}
|
||||||
63
c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S
Normal file
63
c/src/lib/libcpu/powerpc/new-exceptions/asm_utils.S
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* asm_utils.s
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
|
||||||
|
*
|
||||||
|
* This file contains the low-level support for moving exception
|
||||||
|
* exception code to appropriate location.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtems/asm.h>
|
||||||
|
#include <rtems/score/cpu.h>
|
||||||
|
|
||||||
|
.globl codemove
|
||||||
|
codemove:
|
||||||
|
.type codemove,@function
|
||||||
|
/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
|
||||||
|
cmplw cr1,r3,r4
|
||||||
|
addi r0,r5,3
|
||||||
|
srwi. r0,r0,2
|
||||||
|
beq cr1,4f /* In place copy is not necessary */
|
||||||
|
beq 7f /* Protect against 0 count */
|
||||||
|
mtctr r0
|
||||||
|
bge cr1,2f
|
||||||
|
|
||||||
|
la r8,-4(r4)
|
||||||
|
la r7,-4(r3)
|
||||||
|
1: lwzu r0,4(r8)
|
||||||
|
stwu r0,4(r7)
|
||||||
|
bdnz 1b
|
||||||
|
b 4f
|
||||||
|
|
||||||
|
2: slwi r0,r0,2
|
||||||
|
add r8,r4,r0
|
||||||
|
add r7,r3,r0
|
||||||
|
3: lwzu r0,-4(r8)
|
||||||
|
stwu r0,-4(r7)
|
||||||
|
bdnz 3b
|
||||||
|
|
||||||
|
/* Now flush the cache: note that we must start from a cache aligned
|
||||||
|
* address. Otherwise we might miss one cache line.
|
||||||
|
*/
|
||||||
|
4: cmpwi r6,0
|
||||||
|
add r5,r3,r5
|
||||||
|
beq 7f /* Always flush prefetch queue in any case */
|
||||||
|
subi r0,r6,1
|
||||||
|
andc r3,r3,r0
|
||||||
|
mr r4,r3
|
||||||
|
5: cmplw r4,r5
|
||||||
|
dcbst 0,r4
|
||||||
|
add r4,r4,r6
|
||||||
|
blt 5b
|
||||||
|
sync /* Wait for all dcbst to complete on bus */
|
||||||
|
mr r4,r3
|
||||||
|
6: cmplw r4,r5
|
||||||
|
icbi 0,r4
|
||||||
|
add r4,r4,r6
|
||||||
|
blt 6b
|
||||||
|
7: sync /* Wait for all icbi to complete on bus */
|
||||||
|
isync
|
||||||
|
blr
|
||||||
501
c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
Normal file
501
c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c
Normal file
@@ -0,0 +1,501 @@
|
|||||||
|
/*
|
||||||
|
* raw_exception.c - This file contains implementation of C function to
|
||||||
|
* Instantiate 60x ppc primary exception entries.
|
||||||
|
* More detailed information can be found on motorola
|
||||||
|
* site and more precisely in the following book :
|
||||||
|
*
|
||||||
|
* MPC750
|
||||||
|
* Risc Microporcessor User's Manual
|
||||||
|
* Motorola REF : MPC750UM/AD 8/97
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
|
||||||
|
* Canon Centre Recherche France.
|
||||||
|
*
|
||||||
|
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
|
||||||
|
* to support 603, 603e, 604, 604e exceptions
|
||||||
|
*
|
||||||
|
* moved to "libcpu/powerpc/new-exceptions and consolidated
|
||||||
|
* by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
||||||
|
* to be common for all PPCs with new excpetions
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/powerpc.h>
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
#include <libcpu/raw_exception.h>
|
||||||
|
#include <libcpu/cpuIdent.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static rtems_raw_except_connect_data* raw_except_table;
|
||||||
|
static rtems_raw_except_connect_data default_raw_except_entry;
|
||||||
|
static rtems_raw_except_global_settings* local_settings;
|
||||||
|
|
||||||
|
void * codemove(void *, const void *, unsigned int, unsigned long);
|
||||||
|
|
||||||
|
|
||||||
|
static void* ppc_get_vector_addr(rtems_vector vector)
|
||||||
|
{
|
||||||
|
unsigned vaddr;
|
||||||
|
extern rtems_cpu_table Cpu_table;
|
||||||
|
|
||||||
|
switch(vector) {
|
||||||
|
/*
|
||||||
|
* some vectors are located at odd addresses and only available
|
||||||
|
* on some CPU derivates. this construct will handle them
|
||||||
|
* if available
|
||||||
|
*/
|
||||||
|
#if defined(PPC_HAS_60X_VECTORS)
|
||||||
|
/* Special case; altivec unavailable doesn't fit :-( */
|
||||||
|
case ASM_VEC_VECTOR:
|
||||||
|
vaddr = ASM_VEC_VECTOR_OFFSET;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(ASM_PIT_VECTOR)
|
||||||
|
case ASM_PIT_VECTOR:
|
||||||
|
vaddr = ASM_PIT_VECTOR_OFFSET;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(ASM_FIT_VECTOR)
|
||||||
|
case ASM_FIT_VECTOR:
|
||||||
|
vaddr = ASM_FIT_VECTOR_OFFSET;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(ASM_WDOG_VECTOR)
|
||||||
|
case ASM_WDOG_VECTOR:
|
||||||
|
vaddr = ASM_WDOG_VECTOR_OFFSET;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
vaddr = ((unsigned)vector) << 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( Cpu_table.exceptions_in_RAM )
|
||||||
|
return ((void*) vaddr);
|
||||||
|
|
||||||
|
return ((void*) (vaddr + 0xfff00000));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ( defined(mpc860) || defined(mpc821) )
|
||||||
|
|
||||||
|
int mpc860_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
case ASM_FLOATASSIST_VECTOR:
|
||||||
|
|
||||||
|
case ASM_SOFTEMUL_VECTOR:
|
||||||
|
case ASM_ITLBMISS_VECTOR:
|
||||||
|
case ASM_DTLBMISS_VECTOR:
|
||||||
|
case ASM_ITLBERROR_VECTOR:
|
||||||
|
case ASM_DTLBERROR_VECTOR:
|
||||||
|
|
||||||
|
case ASM_DBREAK_VECTOR:
|
||||||
|
case ASM_IBREAK_VECTOR:
|
||||||
|
case ASM_PERIFBREAK_VECTOR:
|
||||||
|
case ASM_DEVPORT_VECTOR:
|
||||||
|
return 1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(mpc555) || defined(mpc505))
|
||||||
|
|
||||||
|
int ppc_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch (current_ppc_cpu) {
|
||||||
|
case PPC_5XX:
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR:
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
case ASM_FLOATASSIST_VECTOR:
|
||||||
|
|
||||||
|
case ASM_SOFTEMUL_VECTOR:
|
||||||
|
|
||||||
|
case ASM_IPROT_VECTOR:
|
||||||
|
case ASM_DPROT_VECTOR:
|
||||||
|
|
||||||
|
case ASM_DBREAK_VECTOR:
|
||||||
|
case ASM_IBREAK_VECTOR:
|
||||||
|
case ASM_MEBREAK_VECTOR:
|
||||||
|
case ASM_NMEBREAK_VECTOR:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printk("Please complete libcpu/powerpc/shared/new-exceptions/raw_exception.c\n");
|
||||||
|
printk("current_ppc_cpu = %x\n", current_ppc_cpu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ppc405)
|
||||||
|
int ppc405_vector_is_valid(rtems_vector vector)
|
||||||
|
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_PIT_VECTOR:
|
||||||
|
case ASM_ITLBMISS_VECTOR:
|
||||||
|
case ASM_DTLBMISS_VECTOR:
|
||||||
|
return 1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined(ppc405) */
|
||||||
|
|
||||||
|
#if defined(PPC_HAS_60X_VECTORS) /* 60x style cpu types */
|
||||||
|
|
||||||
|
int altivec_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_VEC_VECTOR:
|
||||||
|
case ASM_VEC_ASSIST_VECTOR:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpc750_vector_is_valid(rtems_vector vector)
|
||||||
|
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
case ASM_ADDR_VECTOR:
|
||||||
|
case ASM_SYSMGMT_VECTOR:
|
||||||
|
case ASM_ITM_VECTOR:
|
||||||
|
return 1;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PSIM_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
return 0;
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_PERFMON_VECTOR:
|
||||||
|
return 0;
|
||||||
|
case ASM_IMISS_VECTOR: /* fall through */
|
||||||
|
case ASM_DLMISS_VECTOR:
|
||||||
|
case ASM_DSMISS_VECTOR:
|
||||||
|
case ASM_ADDR_VECTOR:
|
||||||
|
case ASM_SYSMGMT_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_ITM_VECTOR:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpc603_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_PERFMON_VECTOR:
|
||||||
|
return 0;
|
||||||
|
case ASM_IMISS_VECTOR: /* fall through */
|
||||||
|
case ASM_DLMISS_VECTOR:
|
||||||
|
case ASM_DSMISS_VECTOR:
|
||||||
|
case ASM_ADDR_VECTOR:
|
||||||
|
case ASM_SYSMGMT_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_ITM_VECTOR:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpc604_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch(vector) {
|
||||||
|
case ASM_RESET_VECTOR: /* fall through */
|
||||||
|
case ASM_MACH_VECTOR:
|
||||||
|
case ASM_PROT_VECTOR:
|
||||||
|
case ASM_ISI_VECTOR:
|
||||||
|
case ASM_EXT_VECTOR:
|
||||||
|
case ASM_ALIGN_VECTOR:
|
||||||
|
case ASM_PROG_VECTOR:
|
||||||
|
case ASM_FLOAT_VECTOR:
|
||||||
|
case ASM_DEC_VECTOR:
|
||||||
|
case ASM_SYS_VECTOR:
|
||||||
|
case ASM_TRACE_VECTOR:
|
||||||
|
case ASM_PERFMON_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_IMISS_VECTOR: /* fall through */
|
||||||
|
case ASM_DLMISS_VECTOR:
|
||||||
|
case ASM_DSMISS_VECTOR:
|
||||||
|
return 0;
|
||||||
|
case ASM_ADDR_VECTOR: /* fall through */
|
||||||
|
case ASM_SYSMGMT_VECTOR:
|
||||||
|
return 1;
|
||||||
|
case ASM_ITM_VECTOR:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* 60x style cpu types */
|
||||||
|
|
||||||
|
int ppc_vector_is_valid(rtems_vector vector)
|
||||||
|
{
|
||||||
|
switch (current_ppc_cpu) {
|
||||||
|
#if defined(PPC_HAS_60X_VECTORS)
|
||||||
|
case PPC_7400:
|
||||||
|
if ( altivec_vector_is_valid(vector) )
|
||||||
|
return 1;
|
||||||
|
/* else fall thru */
|
||||||
|
case PPC_750:
|
||||||
|
if (!mpc750_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PPC_7455: /* Kate Feng */
|
||||||
|
case PPC_7457:
|
||||||
|
if ( altivec_vector_is_valid(vector) )
|
||||||
|
return 1;
|
||||||
|
/* else fall thru */
|
||||||
|
case PPC_604:
|
||||||
|
case PPC_604e:
|
||||||
|
case PPC_604r:
|
||||||
|
if (!mpc604_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PPC_603:
|
||||||
|
case PPC_603e:
|
||||||
|
case PPC_603le:
|
||||||
|
case PPC_603ev:
|
||||||
|
case PPC_8260:
|
||||||
|
/* case PPC_8240: -- same value as 8260 */
|
||||||
|
case PPC_8245:
|
||||||
|
if (!mpc603_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PPC_PSIM:
|
||||||
|
if (!PSIM_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if ( defined(mpc860) || defined(mpc821) )
|
||||||
|
case PPC_860:
|
||||||
|
if (!mpc860_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(ppc405)
|
||||||
|
case PPC_405:
|
||||||
|
if (!ppc405_vector_is_valid(vector)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
printk("Please complete "
|
||||||
|
"libcpu/powerpc/new-exceptions/raw_exception.c\n"
|
||||||
|
"current_ppc_cpu = %x\n", current_ppc_cpu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ppc_set_exception (const rtems_raw_except_connect_data* except)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
if (!ppc_vector_is_valid(except->exceptIndex)) {
|
||||||
|
printk("ppc_set_exception: vector %d is not valid\n",
|
||||||
|
except->exceptIndex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if default handler is actually connected. If not issue an error.
|
||||||
|
* You must first get the current handler via mpc60x_get_current_exception
|
||||||
|
* and then disconnect it using mpc60x_delete_exception.
|
||||||
|
* RATIONALE : to always have the same transition by forcing the user
|
||||||
|
* to get the previous handler before accepting to disconnect.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (memcmp(ppc_get_vector_addr(except->exceptIndex),
|
||||||
|
(void*)default_raw_except_entry.hdl.raw_hdl,
|
||||||
|
default_raw_except_entry.hdl.raw_hdl_size)) {
|
||||||
|
printk("ppc_set_exception: raw vector not installed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
|
||||||
|
raw_except_table [except->exceptIndex] = *except;
|
||||||
|
codemove((void*)ppc_get_vector_addr(except->exceptIndex),
|
||||||
|
except->hdl.raw_hdl,
|
||||||
|
except->hdl.raw_hdl_size,
|
||||||
|
PPC_CACHE_ALIGNMENT);
|
||||||
|
except->on(except);
|
||||||
|
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ppc_get_current_exception (rtems_raw_except_connect_data* except)
|
||||||
|
{
|
||||||
|
if (!ppc_vector_is_valid(except->exceptIndex)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*except = raw_except_table [except->exceptIndex];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ppc_delete_exception (const rtems_raw_except_connect_data* except)
|
||||||
|
{
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
if (!ppc_vector_is_valid(except->exceptIndex)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check if handler passed is actually connected. If not issue an error.
|
||||||
|
* You must first get the current handler via ppc_get_current_exception
|
||||||
|
* and then disconnect it using ppc_delete_exception.
|
||||||
|
* RATIONALE : to always have the same transition by forcing the user
|
||||||
|
* to get the previous handler before accepting to disconnect.
|
||||||
|
*/
|
||||||
|
if (memcmp(ppc_get_vector_addr(except->exceptIndex),
|
||||||
|
(void*)except->hdl.raw_hdl,
|
||||||
|
except->hdl.raw_hdl_size)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
|
||||||
|
except->off(except);
|
||||||
|
codemove((void*)ppc_get_vector_addr(except->exceptIndex),
|
||||||
|
default_raw_except_entry.hdl.raw_hdl,
|
||||||
|
default_raw_except_entry.hdl.raw_hdl_size,
|
||||||
|
PPC_CACHE_ALIGNMENT);
|
||||||
|
|
||||||
|
|
||||||
|
raw_except_table[except->exceptIndex] = default_raw_except_entry;
|
||||||
|
raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
|
||||||
|
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception global init.
|
||||||
|
*/
|
||||||
|
int ppc_init_exceptions (rtems_raw_except_global_settings* config)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
unsigned int level;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* store various accelerators
|
||||||
|
*/
|
||||||
|
raw_except_table = config->rawExceptHdlTbl;
|
||||||
|
local_settings = config;
|
||||||
|
default_raw_except_entry = config->defaultRawEntry;
|
||||||
|
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
|
||||||
|
for (i=0; i <= LAST_VALID_EXC; i++) {
|
||||||
|
if (!ppc_vector_is_valid(i)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
codemove((void*)ppc_get_vector_addr(i),
|
||||||
|
raw_except_table[i].hdl.raw_hdl,
|
||||||
|
raw_except_table[i].hdl.raw_hdl_size,
|
||||||
|
PPC_CACHE_ALIGNMENT);
|
||||||
|
if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
|
||||||
|
raw_except_table[i].on(&raw_except_table[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
raw_except_table[i].off(&raw_except_table[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_CPU_ISR_Enable(level);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ppc_get_exception_config (rtems_raw_except_global_settings** config)
|
||||||
|
{
|
||||||
|
*config = local_settings;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
324
c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h
Normal file
324
c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.h
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
* raw_execption.h
|
||||||
|
*
|
||||||
|
* This file contains implementation of C function to
|
||||||
|
* Instantiate 60x ppc primary exception entries.
|
||||||
|
* More detailed information can be found on motorola
|
||||||
|
* site and more precisely in the following book :
|
||||||
|
*
|
||||||
|
* MPC750
|
||||||
|
* Risc Microporcessor User's Manual
|
||||||
|
* Mtorola REF : MPC750UM/AD 8/97
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
|
||||||
|
* Canon Centre Recherche France.
|
||||||
|
*
|
||||||
|
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
|
||||||
|
* to support 603, 603e, 604, 604e exceptions
|
||||||
|
*
|
||||||
|
* moved to "libcpu/powerpc/new-exceptions and consolidated
|
||||||
|
* by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
|
||||||
|
* to be common for all PPCs with new excpetions
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBCPU_RAW_EXCEPTION_H
|
||||||
|
#define _LIBCPU_RAW_EXCEPTION_H
|
||||||
|
|
||||||
|
#include <rtems/powerpc/powerpc.h>
|
||||||
|
/*
|
||||||
|
* find out, whether we want to (re)enable the MMU in the assembly code
|
||||||
|
* FIXME: move this to a better location
|
||||||
|
*/
|
||||||
|
#if (defined(ppc403) || defined(ppc405))
|
||||||
|
#define PPC_USE_MMU 0
|
||||||
|
#else
|
||||||
|
#define PPC_USE_MMU 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception Vectors and offsets as defined in the MCP750 manual
|
||||||
|
* used by most PPCs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ASM_RESET_VECTOR 0x01
|
||||||
|
#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_MACH_VECTOR 0x02
|
||||||
|
#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_PROT_VECTOR 0x03
|
||||||
|
#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ISI_VECTOR 0x04
|
||||||
|
#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_EXT_VECTOR 0x05
|
||||||
|
#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ALIGN_VECTOR 0x06
|
||||||
|
#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_PROG_VECTOR 0x07
|
||||||
|
#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_FLOAT_VECTOR 0x08
|
||||||
|
#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DEC_VECTOR 0x09
|
||||||
|
#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8)
|
||||||
|
|
||||||
|
/* Bummer: Altivec unavailable doesn't fit into this scheme... (0xf20).
|
||||||
|
* We'd like to avoid reserved vectors but OTOH we don't want to use
|
||||||
|
* just an available high number because tables (and copies) are of
|
||||||
|
* size LAST_VALID_EXC.
|
||||||
|
* So until there is a CPU that uses 0xA we'll just use that :-(
|
||||||
|
*/
|
||||||
|
#define ASM_VEC_VECTOR 0x0A
|
||||||
|
#define ASM_VEC_VECTOR_OFFSET (0xf20)
|
||||||
|
|
||||||
|
#define ASM_SYS_VECTOR 0x0C
|
||||||
|
#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_TRACE_VECTOR 0x0D
|
||||||
|
#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8)
|
||||||
|
|
||||||
|
#if defined(ppc405)
|
||||||
|
/*
|
||||||
|
* vectors for PPC405
|
||||||
|
*/
|
||||||
|
#define ASM_CRIT_VECTOR ASM_RESET_VECTOR
|
||||||
|
#define ASM_CRIT_VECTOR_OFFSET (ASM_CRIT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_PIT_VECTOR 0x10
|
||||||
|
#define ASM_PIT_VECTOR_OFFSET (ASM_PIT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ITLBMISS_VECTOR 0x11
|
||||||
|
#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DTLBMISS_VECTOR 0x12
|
||||||
|
#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_FIT_VECTOR 0x13
|
||||||
|
#define ASM_FIT_VECTOR_OFFSET (0x1010)
|
||||||
|
|
||||||
|
#define ASM_WDOG_VECTOR 0x14
|
||||||
|
#define ASM_WDOG_VECTOR_OFFSET (0x1020)
|
||||||
|
|
||||||
|
#define LAST_VALID_EXC ASM_WDOG_VECTOR
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bit mask of all exception vectors, that are handled
|
||||||
|
* as "critical" exsceptions (using SRR2/SRR3/rfci)
|
||||||
|
* this value will be evaluated in the default exception entry/exit
|
||||||
|
* code to determine, whether to use SRR0/SRR1/rfi or SRR2/SRR3/rfci
|
||||||
|
*/
|
||||||
|
#define ASM_VECTORS_CRITICAL \
|
||||||
|
(( 1 << (31-ASM_CRIT_VECTOR)) \
|
||||||
|
|(1 << (31-ASM_MACH_VECTOR)) \
|
||||||
|
|(1 << (31-ASM_WDOG_VECTOR)))
|
||||||
|
|
||||||
|
#elif ( defined(mpc860) || defined(mpc821) )
|
||||||
|
/*
|
||||||
|
* vectors for MPC8xx
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: even more vector names might get used in common,
|
||||||
|
* but the names have diverged between different PPC families
|
||||||
|
*/
|
||||||
|
#define ASM_FLOATASSIST_VECTOR 0x0E
|
||||||
|
#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_SOFTEMUL_VECTOR 0x10
|
||||||
|
#define ASM_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ITLBMISS_VECTOR 0x11
|
||||||
|
#define ASM_ITLBMISS_VECTOR_OFFSET (ASM_ITLBMISS_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DTLBMISS_VECTOR 0x12
|
||||||
|
#define ASM_DTLBMISS_VECTOR_OFFSET (ASM_DTLBMISS_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ITLBERROR_VECTOR 0x13
|
||||||
|
#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DTLBERROR_VECTOR 0x14
|
||||||
|
#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DBREAK_VECTOR 0x1C
|
||||||
|
#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_IBREAK_VECTOR 0x1D
|
||||||
|
#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_PERIFBREAK_VECTOR 0x1E
|
||||||
|
#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_DEVPORT_VECTOR 0x1F
|
||||||
|
#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 8)
|
||||||
|
|
||||||
|
#define LAST_VALID_EXC ASM_DEVPORT_VECTOR
|
||||||
|
|
||||||
|
#elif (defined(mpc555) || defined(mpc505))
|
||||||
|
/*
|
||||||
|
* vectorx for MPC5xx
|
||||||
|
*/
|
||||||
|
#define ASM_FLOATASSIST_VECTOR 0x0E
|
||||||
|
|
||||||
|
#define ASM_SOFTEMUL_VECTOR 0x10
|
||||||
|
|
||||||
|
#define ASM_IPROT_VECTOR 0x13
|
||||||
|
#define ASM_DPROT_VECTOR 0x14
|
||||||
|
|
||||||
|
#define ASM_DBREAK_VECTOR 0x1C
|
||||||
|
#define ASM_IBREAK_VECTOR 0x1D
|
||||||
|
#define ASM_MEBREAK_VECTOR 0x1E
|
||||||
|
#define ASM_NMEBREAK_VECTOR 0x1F
|
||||||
|
|
||||||
|
#define LAST_VALID_EXC ASM_NMEBREAK_VECTOR
|
||||||
|
|
||||||
|
#else /* 60x style cpu types */
|
||||||
|
#define PPC_HAS_60X_VECTORS
|
||||||
|
|
||||||
|
#define ASM_PERFMON_VECTOR 0x0F
|
||||||
|
#define ASM_PERFMON_VECTOR_OFFSET (ASM_PERFMON_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_IMISS_VECTOR 0x10
|
||||||
|
|
||||||
|
#define ASM_DLMISS_VECTOR 0x11
|
||||||
|
|
||||||
|
#define ASM_DSMISS_VECTOR 0x12
|
||||||
|
|
||||||
|
#define ASM_ADDR_VECTOR 0x13
|
||||||
|
#define ASM_ADDR_VECTOR_OFFSET (ASM_ADDR_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_SYSMGMT_VECTOR 0x14
|
||||||
|
#define ASM_SYSMGMT_VECTOR_OFFSET (ASM_SYSMGMT_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_VEC_ASSIST_VECTOR 0x16
|
||||||
|
#define ASM_VEC_ASSIST_VECTOR_OFFSET (ASM_VEC_ASSIST_VECTOR << 8)
|
||||||
|
|
||||||
|
#define ASM_ITM_VECTOR 0x17
|
||||||
|
#define ASM_ITM_VECTOR_OFFSET (ASM_ITM_VECTOR << 8)
|
||||||
|
|
||||||
|
#define LAST_VALID_EXC ASM_ITM_VECTOR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bits to be set in MSR in exception entry code
|
||||||
|
*/
|
||||||
|
#if ( PPC_HAS_RI) && ( PPC_USE_MMU)
|
||||||
|
#define PPC_MSR_EXC_BITS (PPC_MSR_RI | PPC_MSR_DR | PPC_MSR_IR)
|
||||||
|
#elif ( PPC_HAS_RI) && (!PPC_USE_MMU)
|
||||||
|
#define PPC_MSR_EXC_BITS (PPC_MSR_RI)
|
||||||
|
#elif (!PPC_HAS_RI) && ( PPC_USE_MMU)
|
||||||
|
#define PPC_MSR_EXC_BITS ( PPC_MSR_DR | PPC_MSR_IR)
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ASM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type definition for raw exceptions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef unsigned char rtems_vector;
|
||||||
|
struct __rtems_raw_except_connect_data__;
|
||||||
|
typedef void (*rtems_raw_except_func) (void);
|
||||||
|
typedef unsigned long rtems_raw_except_hdl_size;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_vector vector;
|
||||||
|
rtems_raw_except_func raw_hdl;
|
||||||
|
rtems_raw_except_hdl_size raw_hdl_size;
|
||||||
|
}rtems_raw_except_hdl;
|
||||||
|
|
||||||
|
typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*);
|
||||||
|
typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*);
|
||||||
|
typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*);
|
||||||
|
|
||||||
|
typedef struct __rtems_raw_except_connect_data__{
|
||||||
|
/*
|
||||||
|
* Exception vector (As defined in the manual)
|
||||||
|
*/
|
||||||
|
rtems_vector exceptIndex;
|
||||||
|
/*
|
||||||
|
* Exception raw handler. See comment on handler properties below in function prototype.
|
||||||
|
*/
|
||||||
|
rtems_raw_except_hdl hdl;
|
||||||
|
/*
|
||||||
|
* function for enabling raw exceptions. In order to be consistent
|
||||||
|
* with the fact that the raw connexion can defined in the
|
||||||
|
* libcpu library, this library should have no knowledge of
|
||||||
|
* board specific hardware to manage exceptions and thus the
|
||||||
|
* "on" routine must enable the except at processor level only.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_raw_except_enable on;
|
||||||
|
/*
|
||||||
|
* function for disabling raw exceptions. In order to be consistent
|
||||||
|
* with the fact that the raw connexion can defined in the
|
||||||
|
* libcpu library, this library should have no knowledge of
|
||||||
|
* board specific hardware to manage exceptions and thus the
|
||||||
|
* "on" routine must disable the except both at device and PIC level.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_raw_except_disable off;
|
||||||
|
/*
|
||||||
|
* function enabling to know what exception may currently occur
|
||||||
|
*/
|
||||||
|
rtems_raw_except_is_enabled isOn;
|
||||||
|
}rtems_raw_except_connect_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* size of all the table fields (*Tbl) described below.
|
||||||
|
*/
|
||||||
|
unsigned int exceptSize;
|
||||||
|
/*
|
||||||
|
* Default handler used when disconnecting exceptions.
|
||||||
|
*/
|
||||||
|
rtems_raw_except_connect_data defaultRawEntry;
|
||||||
|
/*
|
||||||
|
* Table containing initials/current value.
|
||||||
|
*/
|
||||||
|
rtems_raw_except_connect_data* rawExceptHdlTbl;
|
||||||
|
}rtems_raw_except_global_settings;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to set up one raw idt entry
|
||||||
|
*/
|
||||||
|
extern int ppc_set_exception (const rtems_raw_except_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to get one current raw idt entry
|
||||||
|
*/
|
||||||
|
extern int ppc_get_current_exception (rtems_raw_except_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to remove one current raw idt entry
|
||||||
|
*/
|
||||||
|
extern int ppc_delete_exception (const rtems_raw_except_connect_data*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C callable function enabling to check if vector is valid
|
||||||
|
*/
|
||||||
|
extern int ppc_vector_is_valid(rtems_vector vector);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exception global init.
|
||||||
|
*/
|
||||||
|
extern int ppc_init_exceptions (rtems_raw_except_global_settings* config);
|
||||||
|
extern int ppc_get_exception_config (rtems_raw_except_global_settings** config);
|
||||||
|
|
||||||
|
# endif /* ASM */
|
||||||
|
|
||||||
|
#endif
|
||||||
292
c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c
Normal file
292
c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.c
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
/* ictrl.c
|
||||||
|
*
|
||||||
|
* This routine installs and handles external interrupt vectors for
|
||||||
|
* PowerPC 403 CPU built-in external interrupt controller
|
||||||
|
*
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of IMD not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* IMD makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ictrl.h"
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/libio.h>
|
||||||
|
|
||||||
|
#include <stdlib.h> /* for atexit() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR vector table to dispatch external interrupts
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX];
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* some utilities to access the EXI* registers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clear bits in EXISR that have a bit set in mask
|
||||||
|
*/
|
||||||
|
#if defined(ppc405)
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
clr_exisr(uint32_t mask)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0xC0,%0"::"r" (mask));/*EXISR*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXISR
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t
|
||||||
|
get_exisr(void)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
asm volatile ("mfdcr %0,0xC0":"=r" (val));/*EXISR*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t
|
||||||
|
get_exier(void)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
asm volatile ("mfdcr %0,0xC2":"=r" (val));/*EXIER*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
set_exier(uint32_t val)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0xC2,%0"::"r" (val));/*EXIER*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* not ppc405 */
|
||||||
|
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
clr_exisr(uint32_t mask)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0x40,%0"::"r" (mask));/*EXISR*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXISR
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t
|
||||||
|
get_exisr(void)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
asm volatile ("mfdcr %0,0x40":"=r" (val));/*EXISR*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE uint32_t
|
||||||
|
get_exier(void)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
asm volatile ("mfdcr %0,0x42":"=r" (val));/*EXIER*/
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set value of EXIER
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
set_exier(uint32_t val)
|
||||||
|
{
|
||||||
|
asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/
|
||||||
|
}
|
||||||
|
#endif /* ppc405 */
|
||||||
|
/*
|
||||||
|
* enable an external interrupt, make this interrupt consistent
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
enable_ext_irq( uint32_t mask)
|
||||||
|
{
|
||||||
|
uint32_t isrlvl;
|
||||||
|
_CPU_ISR_Disable(isrlvl);
|
||||||
|
set_exier(get_exier() | ((mask)&PPC_EXI_MASK));
|
||||||
|
_CPU_ISR_Enable(isrlvl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disable an external interrupt, make this interrupt consistent
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void
|
||||||
|
disable_ext_irq( uint32_t mask)
|
||||||
|
{
|
||||||
|
uint32_t isrlvl;
|
||||||
|
_CPU_ISR_Disable(isrlvl);
|
||||||
|
set_exier(get_exier() & ~(mask) & PPC_EXI_MASK);
|
||||||
|
_CPU_ISR_Enable(isrlvl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* this function is called, when a external interrupt is present and
|
||||||
|
* enabled but there is no handler installed. It will clear
|
||||||
|
* the corresponding enable bits and call the spurious handler
|
||||||
|
* present in the CPU Configuration Table, if any.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ictrl_spurious_handler(uint32_t spurious_mask,
|
||||||
|
CPU_Interrupt_frame *cpu_frame)
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
|
||||||
|
for (v=0; v < PPC_IRQ_EXT_MAX; v++) {
|
||||||
|
if (VEC_TO_EXMSK(v) & spurious_mask) {
|
||||||
|
clr_exisr(VEC_TO_EXMSK(v));
|
||||||
|
disable_ext_irq(VEC_TO_EXMSK(v));
|
||||||
|
#if 0
|
||||||
|
printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
|
||||||
|
vector, cpu_frame->Interrupt.pcoqfront);
|
||||||
|
#endif
|
||||||
|
if (rtems_cpu_configuration_get_spurious_handler()) {
|
||||||
|
rtems_cpu_configuration_get_spurious_handler()(v + PPC_IRQ_EXT_BASE,cpu_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISR Handler: this is called from the primary exception dispatcher
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ictrl_isr(rtems_vector_number vector,CPU_Interrupt_frame *cpu_frame)
|
||||||
|
{
|
||||||
|
uint32_t istat,
|
||||||
|
mask,
|
||||||
|
global_vec;
|
||||||
|
int exvec;
|
||||||
|
rtems_isr_entry handler;
|
||||||
|
|
||||||
|
istat = get_exisr() & get_exier() & PPC_EXI_MASK;
|
||||||
|
|
||||||
|
/* FIXME: this may be speeded up using cntlzw instruction */
|
||||||
|
for (exvec = 0;exvec < PPC_IRQ_EXT_MAX;exvec++) {
|
||||||
|
mask = VEC_TO_EXMSK(exvec);
|
||||||
|
if (0 != (istat & mask)) {
|
||||||
|
/*clr_exisr(mask); too early to ack*/
|
||||||
|
handler = ictrl_vector_table[exvec];
|
||||||
|
if (handler) {
|
||||||
|
istat &= ~mask;
|
||||||
|
global_vec = exvec + PPC_IRQ_EXT_BASE;
|
||||||
|
(handler)(global_vec);
|
||||||
|
}
|
||||||
|
clr_exisr(mask);/* now we can ack*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (istat != 0) { /* anything left? then we have a spurious interrupt */
|
||||||
|
ictrl_spurious_handler(istat,cpu_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* the following functions form the user interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* install a user vector for one of the external interrupt sources
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_status_code
|
||||||
|
ictrl_set_vector(rtems_isr_entry new_handler,
|
||||||
|
uint32_t vector,
|
||||||
|
rtems_isr_entry *old_handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We put the actual user ISR address in 'ictrl_vector_table'. This will
|
||||||
|
* be used by the _ictrl_isr so the user gets control.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* check for valid vector range */
|
||||||
|
if ((vector >= PPC_IRQ_EXT_BASE) &&
|
||||||
|
(vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) {
|
||||||
|
/* return old handler entry */
|
||||||
|
*old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE];
|
||||||
|
|
||||||
|
if (new_handler != NULL) {
|
||||||
|
/* store handler function... */
|
||||||
|
ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = new_handler;
|
||||||
|
/* then enable it in EXIER register */
|
||||||
|
enable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
|
||||||
|
}
|
||||||
|
else { /* new_handler == NULL */
|
||||||
|
/* then disable it in EXIER register */
|
||||||
|
disable_ext_irq(VEC_TO_EXMSK(vector - PPC_IRQ_EXT_BASE));
|
||||||
|
ictrl_vector_table[vector - PPC_IRQ_EXT_BASE] = NULL;
|
||||||
|
}
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called via atexit()
|
||||||
|
* deactivate the interrupt controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ictrl_exit(void)
|
||||||
|
{
|
||||||
|
/* mark them all unused */
|
||||||
|
disable_ext_irq(~0);
|
||||||
|
clr_exisr(~0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* activate the interrupt controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_status_code
|
||||||
|
ictrl_init(void)
|
||||||
|
{
|
||||||
|
proc_ptr dummy;
|
||||||
|
|
||||||
|
/* mark them all unused */
|
||||||
|
disable_ext_irq(~0);
|
||||||
|
clr_exisr(~0);
|
||||||
|
|
||||||
|
/* install the external interrupt handler */
|
||||||
|
_CPU_ISR_install_vector(PPC_IRQ_EXTERNAL,
|
||||||
|
ictrl_isr,
|
||||||
|
&dummy);
|
||||||
|
atexit(ictrl_exit);
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
95
c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h
Normal file
95
c/src/lib/libcpu/powerpc/ppc403/irq/ictrl.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* ictrl.h
|
||||||
|
*
|
||||||
|
* This file contains definitions and declarations for the
|
||||||
|
* PowerPC 403 CPU built-in external interrupt controller
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Author: Thomas Doerfler <td@imd.m.isar.de>
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1998 by IMD, Puchheim, Germany
|
||||||
|
*
|
||||||
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
|
* without any express or implied warranty:
|
||||||
|
* permission to use, copy, modify, and distribute this file
|
||||||
|
* for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice and this notice appears in all
|
||||||
|
* copies, and that the name of IMD not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
* IMD makes no representations about the suitability
|
||||||
|
* of this software for any purpose.
|
||||||
|
*
|
||||||
|
* Modifications for PPC405GP by Dennis Ehlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _ICTRL_H
|
||||||
|
#define _ICTRL_H
|
||||||
|
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/isr.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* definitions for second level IRQ handler support
|
||||||
|
* External Interrupts via EXTERNAL/EISR
|
||||||
|
*/
|
||||||
|
#define PPC_IRQ_EXT_BASE (PPC_IRQ_LAST+1)
|
||||||
|
|
||||||
|
/* mask for external interrupt status in EXIER/EXISR register */
|
||||||
|
/* note: critical interrupt is in these registers aswell */
|
||||||
|
#ifndef ppc405
|
||||||
|
#define PPC_EXI_MASK 0x0FFFFFFF
|
||||||
|
#else /* ppc405 */
|
||||||
|
#define PPC_EXI_MASK 0xFFFFFFFF
|
||||||
|
#endif /* ppc405 */
|
||||||
|
|
||||||
|
#ifndef ppc405
|
||||||
|
#define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4)
|
||||||
|
#define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5)
|
||||||
|
#else /* ppc405 */
|
||||||
|
#define PPC_IRQ_EXT_UART0 (PPC_IRQ_EXT_BASE+0)
|
||||||
|
#define PPC_IRQ_EXT_UART1 (PPC_IRQ_EXT_BASE+1)
|
||||||
|
#endif /* ppc405 */
|
||||||
|
#define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6)
|
||||||
|
#define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7)
|
||||||
|
#define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8)
|
||||||
|
#define PPC_IRQ_EXT_DMA1 (PPC_IRQ_EXT_BASE+9)
|
||||||
|
#define PPC_IRQ_EXT_DMA2 (PPC_IRQ_EXT_BASE+10)
|
||||||
|
#define PPC_IRQ_EXT_DMA3 (PPC_IRQ_EXT_BASE+11)
|
||||||
|
#define PPC_IRQ_EXT_0 (PPC_IRQ_EXT_BASE+27)
|
||||||
|
#define PPC_IRQ_EXT_1 (PPC_IRQ_EXT_BASE+28)
|
||||||
|
#define PPC_IRQ_EXT_2 (PPC_IRQ_EXT_BASE+29)
|
||||||
|
#define PPC_IRQ_EXT_3 (PPC_IRQ_EXT_BASE+30)
|
||||||
|
#define PPC_IRQ_EXT_4 (PPC_IRQ_EXT_BASE+31)
|
||||||
|
|
||||||
|
#define PPC_IRQ_EXT_MAX (32)
|
||||||
|
|
||||||
|
#define VEC_TO_EXMSK(v) (0x80000000 >> (v))
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* install a user vector for one of the external interrupt sources
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
rtems_status_code
|
||||||
|
ictrl_set_vector(rtems_isr_entry new_handler,
|
||||||
|
uint32_t vector,
|
||||||
|
rtems_isr_entry *old_handler
|
||||||
|
);
|
||||||
|
/*
|
||||||
|
* activate the interrupt controller
|
||||||
|
*/
|
||||||
|
rtems_status_code
|
||||||
|
ictrl_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ICTRL_H */
|
||||||
|
/* end of include file */
|
||||||
Reference in New Issue
Block a user