Motorola MVME2307 BSP submitted by Jay Kulpinski <jskulpin@eng01.gdds.com>.

No modifications made.
This commit is contained in:
Joel Sherrill
1999-10-04 20:41:28 +00:00
parent 92b211a4ca
commit 19ca7978a6
39 changed files with 5254 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../..
subdir = libbsp/powerpc/mvme2307
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/directory.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
SRCS=README
all: $(SRCS)
# shmsupp augments shmdr -- the portable shared memory MPCI layer
# We only build it if HAS_MP was defined
MP_DRIVERS_yes_V = shmsupp
MP_DRIVERS = $(MP_DRIVERS_$(HAS_MP)_V)
# We only build the Network library if HAS_NETWORKING was defined
NETWORK_yes_V = network
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
SUB_DIRS=include clock console startup boot $(MP_DRIVERS) \
nvram timer pci $(NETWORK) wrapup
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,180 @@
This should run on Motorola MVME230x boards, where x is 5, 6, 7,
or 8 designating 16, 32, 64, or 128 MB of DRAM. It should also
work on MVME230x where x is 1, 2, 3, or 4 which is the same board
using a '603 instead of a '604 processor. RTEMS_CPU_MODEL would
need to change in make/custom/mvme2307.cfg.
Application is linked to run from RAM. If running from ROM, it
will copy itself to RAM (0x4000) when it boots. PPCBUG should
be used to load a binary image from the TFTP host into location
0x4000, with an entry point at 0x401c. PPCBUG can be set to
autoboot the application from ROM. PPCBUG does all of the low
level setup of memory controllers and such on the board before
jumping into the RTEMS application.
TODO: Data cache is not enabled. This BSP should probably
be part of the MCP750 BSP as much of the hardware here is
also on the MCP750 board. The dec21140 driver here is derived
from an early version from the MCP750 BSP, but has been
rewritten to use scatter/gather DMA and interrupts rather than
CPU copies and polling. This should be considered for merging
into to the MCP750 BSP. The interrupt conroller code needs to
be better integrated into RTEMS calls like the MCP750. The
BSP should probably be renamed to mvme230x.
----------------------------------------------------------------------------
Building and loading an application:
=============== (host) =======================================
% make
% powerpc-rtems-objcopy --output-target=binary hello.exe /tftpboot/hello.bin
=============== (target - run from RAM) ======================
PPC1-Bug>niop
Controller LUN =00?
Device LUN =00?
Get/Put =G?
File Name =? hello.bin
Memory Address =00004000?
Length =00000000?
Byte Offset =00000000?
Bytes Received =&140780, Bytes Loaded =&140780
Bytes/Second =&140780, Elapsed Time =1 Second(s)
PPC1-Bug>go 401c
Effective address: 0000401C
*** HELLO WORLD TEST ***
Hello World
*** END OF HELLO WORLD TEST ***
PPC1-Bug>
=============== (target - run from ROM) ======================
PPC1-Bug>niop
Controller LUN =00?
Device LUN =00?
Get/Put =G?
File Name =? hello.bin
Memory Address =00004000?
Length =00000000?
Byte Offset =00000000?
Bytes Received =&140780, Bytes Loaded =&140780
Bytes/Second =&140780, Elapsed Time =1 Second(s)
PPC1-Bug>pflash 4000:28000 ff000000
Source Starting/Ending Addresses =00004000/0002BFFF
Destination Starting/Ending Addresses =FF000000/FF027FFF
Number of Effective Bytes =00028000 (&163840)
Program FLASH Memory (Y/N)? y
FLASH Memory Programming Complete
(reset to boot into application)
----------------------------------------------------------------------------
memory map:
0x00000000 - 0x03ffffff RAM
0x80000000 - 0xbf7fffff PCI I/O space
0xc0000000 - 0xfcffffff PCI memory space
0xfd000000 - 0xfdffffff PCI memory space
0xfe000000 - 0xfe7fffff PCI I/O space
0xfef80000 - 0xfef8ffff Falcon registers
0xfeff0000 - 0xfeffffff Raven registers
0xff000000 - 0xff3fffff ROM bank A - application
0xff800000 - 0xff8fffff ROM bank B - PPCBUG
0xfff00000 - 0xffffffff ROM bank A or B
----------------------------------------------------------------------------
Use the PPCBUG "env" command to configure the board:
PPC1-Bug>env
Bug or System environment [B/S] = B?
Field Service Menu Enable [Y/N] = N?
Remote Start Method Switch [G/M/B/N] = B?
Probe System for Supported I/O Controllers [Y/N] = Y?
Auto-Initialize of NVRAM Header Enable [Y/N] = Y?
Network PReP-Boot Mode Enable [Y/N] = N?
Negate VMEbus SYSFAIL* Always [Y/N] = N?
SCSI Bus Reset on Debugger Startup [Y/N] = N?
Primary SCSI Bus Negotiations Type [A/S/N] = A?
Primary SCSI Data Bus Width [W/N] = N?
Secondary SCSI Identifier = "07"?
NVRAM Bootlist (GEV.fw-boot-path) Boot Enable [Y/N] = N?
NVRAM Bootlist (GEV.fw-boot-path) Boot at power-up only [Y/N] = N?
NVRAM Bootlist (GEV.fw-boot-path) Boot Abort Delay = 5?
Auto Boot Enable [Y/N] = N?
Auto Boot at power-up only [Y/N] = N?
Auto Boot Scan Enable [Y/N] = N?
Auto Boot Scan Device Type List = FDISK/CDROM/TAPE/HDISK/?
Auto Boot Controller LUN = 00?
Auto Boot Device LUN = 00?
Auto Boot Partition Number = 00?
Auto Boot Abort Delay = 7?
Auto Boot Default String [NULL for an empty string] = ?
ROM Boot Enable [Y/N] = Y?
ROM Boot at power-up only [Y/N] = N?
ROM Boot Enable search of VMEbus [Y/N] = N?
ROM Boot Abort Delay = 5?
ROM Boot Direct Starting Address = FF000000?
ROM Boot Direct Ending Address = FF3FFFFF?
Network Auto Boot Enable [Y/N] = N?
Network Auto Boot at power-up only [Y/N] = N?
Network Auto Boot Controller LUN = 00?
Network Auto Boot Device LUN = 00?
Network Auto Boot Abort Delay = 5?
Network Auto Boot Configuration Parameters Offset (NVRAM) = 00001000?
Memory Size Enable [Y/N] = Y?
Memory Size Starting Address = 00000000?
Memory Size Ending Address = 02000000?
DRAM Speed in NANO Seconds = 60?
ROM First Access Length (0 - 31) = 10?
ROM Next Access Length (0 - 15) = 0?
DRAM Parity Enable [On-Detection/Always/Never - O/A/N] = O?
L2Cache Parity Enable [On-Detection/Always/Never - O/A/N] = O?
PCI Interrupts Route Control Registers (PIRQ0/1/2/3) = 0A0B0E0F?
Serial Startup Code Master Enable [Y/N] = N?
Serial Startup Code LF Enable [Y/N] = N?
VME3PCI Master Master Enable [Y/N] = Y?
PCI Slave Image 0 Control = 00000000?
PCI Slave Image 0 Base Address Register = 00000000?
PCI Slave Image 0 Bound Address Register = 00000000?
PCI Slave Image 0 Translation Offset = 00000000?
PCI Slave Image 1 Control = C0820000?
PCI Slave Image 1 Base Address Register = 01000000?
PCI Slave Image 1 Bound Address Register = 20000000?
PCI Slave Image 1 Translation Offset = 00000000?
PCI Slave Image 2 Control = C0410000?
PCI Slave Image 2 Base Address Register = 20000000?
PCI Slave Image 2 Bound Address Register = 22000000?
PCI Slave Image 2 Translation Offset = D0000000?
PCI Slave Image 3 Control = C0400000?
PCI Slave Image 3 Base Address Register = 2FFF0000?
PCI Slave Image 3 Bound Address Register = 30000000?
PCI Slave Image 3 Translation Offset = D0000000?
VMEbus Slave Image 0 Control = E0F20000?
VMEbus Slave Image 0 Base Address Register = 00000000?
VMEbus Slave Image 0 Bound Address Register = 02000000?
VMEbus Slave Image 0 Translation Offset = 80000000?
VMEbus Slave Image 1 Control = 00000000?
VMEbus Slave Image 1 Base Address Register = 00000000?
VMEbus Slave Image 1 Bound Address Register = 00000000?
VMEbus Slave Image 1 Translation Offset = 00000000?
VMEbus Slave Image 2 Control = 00000000?
VMEbus Slave Image 2 Base Address Register = 00000000?
VMEbus Slave Image 2 Bound Address Register = 00000000?
VMEbus Slave Image 2 Translation Offset = 00000000?
VMEbus Slave Image 3 Control = 00000000?
VMEbus Slave Image 3 Base Address Register = 00000000?
VMEbus Slave Image 3 Bound Address Register = 00000000?
VMEbus Slave Image 3 Translation Offset = 00000000?
PCI Miscellaneous Register = 10000000?
Special PCI Slave Image Register = 00000000?
Master Control Register = 80C00000?
Miscellaneous Control Register = 52060000?
User AM Codes

View File

@@ -0,0 +1,58 @@
BSP NAME: mvme2307
BOARD: Motorola MVME2307
BUS: VME/PCI
CPU FAMILY: PowerPC
CPU: Motorola MPC604
COPROCESSORS: none
MODE: 32 bit mode/big endian
DEBUG MONITOR: PPCBUG
PERIPHERALS
===========
TIMERS: PPC internal time base register
RESOLUTION: 60 ns
SERIAL PORTS: PC16550 via PPCBUG
REAL-TIME CLOCK: PPC internal decrementer register
DMA: none
VIDEO: none
SCSI: none
NETWORKING: DEC21140
DRIVER INFORMATION
==================
CLOCK DRIVER: PPC internal
IOSUPP DRIVER: N/A
SHMSUPP: N/A
TIMER DRIVER: Intel i8254
TTY DRIVER: PPC internal
STDIO
=====
PORT: Console port 0
ELECTRICAL: RS-232
BAUD: 9600
BITS PER CHARACTER: 8
PARITY: None
STOP BITS: 1
NOTES
=====
PPCBUG interrupt vectors:
00100 reset
00700 program
00c00 syscall
02000 run mode
PPCBUG register usage:
SPR275 must be restored before returning to PPCBUG
SPR272-SPR274 will be changed by PPCBUG
PPCBUG memory usage:
top 768K RAM reserved for BUG (at reset R1 points to top of usable area)
0000-3fff reserved for vectors
MK48T59/559 NVRAM (base = ??)
0000-16f7 - available for user
16f8-1ef7 - PPCBUG
1ef8-1ff7 - configuration data
1ff8-1fff - real time clock registers

View File

@@ -0,0 +1,65 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/boot
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGMS=${ARCH}/start.o
# C source names, if any, go here -- minus the .c
C_PIECES=
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=start
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
all: ${ARCH} $(SRCS) $(OBJS) $(PGM)
$(INSTALL_VARIANT) -m 555 ${PGMS} $(PROJECT_RELEASE)/lib
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,150 @@
/*
* This is based on the mvme-crt0.S file from libgloss/rs6000.
* crt0.S -- startup file for PowerPC systems.
*
* Copyright (c) 1995 Cygnus Support
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*
* $Id$
*/
#include "ppc-asm.h"
.file "start.S"
.section ".got2","aw"
.align 2
.LCTOC1 = .+32768
.extern FUNC_NAME(atexit)
.globl FUNC_NAME(__atexit)
.section ".sdata","aw"
.align 2
FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
.long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
.section ".fixup","aw"
.align 2
.long FUNC_NAME(__atexit)
.section ".got2","aw"
.Ltable = .-.LCTOC1
.long .LCTOC1 /* address we think .LCTOC1 is loaded at */
.Lbss_start = .-.LCTOC1
.long __sbss_start /* need to include sbss and bss sections */
.Lend = .-.LCTOC1
.long _end
.Lstack = .-.LCTOC1 /* stack address if set by user */
.long __stack
.Ltext_start = .-.LCTOC1 /* beginning of text segment */
.long __text_start
.text
/* PPCBUG ROM bootstrap record */
.ascii "BOOT" /* "magic number" */
.long 0x10 /* offset to first instruction */
.long 0x16 /* length of record, including checksum */
.ascii "BOOT" /* routine name */
b _start /* code of routine */
.short 0x6b79 /* checksum */
.short 0x0000 /* space filler */
.Lptr:
.long .LCTOC1-.Laddr
.globl _start
.type _start,@function
_start:
bl .Laddr /* get current address */
.Laddr:
mflr r4 /* real address of .Laddr */
lwz r5,(.Lptr-.Laddr)(r4) /* linker generated address of .LCTOC1 */
add r5,r5,r4 /* correct to real pointer */
lwz r4,.Ltable(r5) /* get linker's idea of where .Laddr is */
subf r4,r4,r5 /* calculate difference between where linked and current */
/* copy text and data to RAM */
lwz r6,.Ltext_start(r5) /* calculate beginning of the text */
lwz r7,.Lbss_start(r5) /* calculate end of the init data */
cmplw 1,r6,r7
bc 4,4,.Ldone1
subf r8,r6,r7 /* number of bytes to copy */
addi r8,r8,3 /* round up to next word boundary */
srwi r9,r8,2 /* number of words to copy */
mtctr r9
addi r6,r6,-4 /* adjust so we can use stwu */
add r8,r6,r4 /* get source address in ROM */
.Lloop1:
lwzu r0,4(r8) /* load word from ROM */
stwu r0,4(r6) /* store word to RAM */
bdnz .Lloop1
.Ldone1:
/* clear bss */
lwz r6,.Lbss_start(r5) /* calculate beginning of the BSS */
lwz r7,.Lend(r5) /* calculate end of the BSS */
cmplw 1,r6,r7
bc 4,4,.Ldone
subf r8,r6,r7 /* number of bytes to zero */
srwi r9,r8,2 /* number of words to zero */
mtctr r9
li r0,0 /* zero to clear memory */
addi r6,r6,-4 /* adjust so we can use stwu */
.Lloop:
stwu r0,4(r6) /* zero bss */
bdnz .Lloop
.Ldone:
lwz r0,.Lstack(r5) /* stack address or 0 */
cmplwi 1,r0,0 /* equal to 0? */
bc 12,6,.Lnostack /* use default stack if == 0 */
mr sp,r0 /* use user defined stack */
.Lnostack:
/* set up initial stack frame */
addi sp,sp,-4 /* make sure we don't overwrite debug mem */
lis r0,0
stw r0,0(sp) /* clear back chain */
stwu sp,-56(sp) /* push another stack frame */
/* jump to RAM and continue */
ba .Lcontinue
.Lcontinue:
/* invalidate instruction cache */
mfspr r4,1008 /* read hid0 */
ori r5,r4,0x00000800 /* set icfi bit */
mtspr 1008,r5
sync
isync
mtspr 1008,r4 /* restore hid0 */
sync
isync
/* Let her rip */
bl FUNC_NAME(boot_card)
/* return value from boot_card is argument to exit */
bl FUNC_NAME(exit)
trap
.Lstart:
.size _start,.Lstart-_start

View 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: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
-lc -lgcc --end-group ecrtn%O%s \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
%{!qrtems: %(old_startfile)} %{qrtems: ecrti%O%s \
%{!qrtems_debug: start.o%s} \
%{qrtems_debug: start_g.o%s}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -T linkcmds%s -e _start -u __vectors}

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/clock
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/clock.rel
# C source names, if any, go here -- minus the .c
C_PIECES=ckinit
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,238 @@
/* ckinit.c
*
* This file provides a template for the clock device driver initialization.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <stdlib.h>
#include <rtems.h>
#include <rtems/libio.h>
#include <bsp.h>
void Clock_exit( void );
rtems_isr Clock_isr( rtems_vector_number vector );
/*
* The interrupt vector number associated with the clock tick device
* driver.
*/
#define CLOCK_VECTOR PPC_IRQ_DECREMENTER
/*
* Clock_driver_ticks is a monotonically increasing counter of the
* number of clock ticks since the driver was initialized.
*/
volatile rtems_unsigned32 Clock_driver_ticks;
/*
* Clocks_per_tick is the number of clocks of the decrementer needed
* to fill BSP_Configuration.microseconds_per_tick.
*
* The clock rate is 1/4 the bus clock, or 16.666667 MHz, so:
*
* Clocks_per_tick = ((50/3)*1E6 clocks/sec) * (1 sec/1E6 us) * (X us/tick)
* = X * 50 / 3 clocks/tick
* where X = BSP_Configuration.microseconds_per_tick
*/
rtems_signed32 Clocks_per_tick;
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* The previous ISR on this clock tick interrupt vector.
*/
rtems_isr_entry Old_ticker;
void Clock_exit( void );
/*
* Inline assembly routines to access the decrementer register
*/
static inline rtems_signed32 read_decrementer(void) {
rtems_signed32 result;
asm volatile ("mfdec %0" : "=r" (result) :);
return result;
}
static inline void write_decrementer(rtems_signed32 value) {
asm volatile ("mtdec %0" : : "r" (value));
}
/*
* Isr Handler
*/
rtems_isr Clock_isr(
rtems_vector_number vector
)
{
rtems_signed32 count, repeat = 0;
const rtems_signed32 period = Clocks_per_tick;
/*
* bump the number of clock driver ticks since initialization
*/
Clock_driver_ticks++;
/*
* be very paranoid and count number of "ticks" in case we missed some
*
* update the decrementer and signal rtems the appropriate number of times
*/
count = read_decrementer();
while (count < 0) {
count += period;
repeat++;
}
write_decrementer(count);
while (repeat-- > 0) {
rtems_clock_tick();
}
}
/*
* Install_clock
*
* Install a clock tick handler and reprograms the chip. This
* is used to initially establish the clock tick.
*/
void Install_clock(
rtems_isr_entry clock_isr
)
{
/*
* Initialize the clock tick device driver variables
*/
Clock_driver_ticks = 0;
switch (Falcon_SYSCR.SystemClock) {
case SYSCLK_50_MHZ:
Clocks_per_tick =
(BSP_Configuration.microseconds_per_tick * 25 + 1) / 2;
break;
case SYSCLK_60_MHZ:
Clocks_per_tick = BSP_Configuration.microseconds_per_tick * 15;
break;
case SYSCLK_67_MHZ:
Clocks_per_tick =
(BSP_Configuration.microseconds_per_tick * 50 + 1) / 3;
break;
}
/*
* If ticks_per_timeslice is configured as non-zero, then the user
* wants a clock tick.
*/
if ( BSP_Configuration.ticks_per_timeslice ) {
Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
/*
* Hardware specific initialize goes here
*/
write_decrementer(Clocks_per_tick);
}
/*
* Schedule the clock cleanup routine to execute if the application exits.
*/
atexit( Clock_exit );
}
/*
* Clean up before the application exits
*/
void Clock_exit( void )
{
if ( BSP_Configuration.ticks_per_timeslice ) {
/* XXX: turn off the timer interrupts */
/* we can't really disable the timer without disabling all external
interupts. we'll slow down the decrementer to it's minimum speed. */
write_decrementer(~0);
/* XXX: If necessary, restore the old vector */
}
}
/*
* Clock_initialize
*
* Device driver entry point for clock tick driver initialization.
*/
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_unsigned32 isrlevel;
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
{
Clock_isr(CLOCK_VECTOR);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
{
rtems_interrupt_disable( isrlevel );
(void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
rtems_interrupt_enable( isrlevel );
}
done:
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/console
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/console.rel
# C source names, if any, go here -- minus the .c
C_PIECES=console printk
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,442 @@
/*
* This file contains the hardware specific portions of the TTY driver
* for the serial port on the MVME230x.
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <termios.h>
#include <bsp.h>
#include <rtems/libio.h>
#include <stdlib.h>
/* PC16550D register definitions */
#define UART_BASE_ADDR ((char *) IO_TO_LOCAL(0x03f8))
#define RBR 0
#define THR 0
#define DLL 0
#define DLM 1
#define LCR 3
# define FIVE_BITS 0x2
# define SIX_BITS 0x2
# define SEVEN_BITS 0x2
# define EIGHT_BITS 0x3
# define ONE_STOP_BIT 0x0
# define TWO_STOP_BITS 0x4
# define NO_PARITY 0x00
# define ODD_PARITY 0x08
# define EVEN_PARITY 0x18
# define DLAB 0x80
#define LSR 5
# define DR 0x01
# define OE 0x02
# define PE 0x04
# define FE 0x08
# define BI 0x10
# define THRE 0x20
# define TEMT 0x40
# define ERR_IN_FIFO 0x40
#define FCR 2
# define ENABLE_FIFOS 0x01
# define RESET_RC_FIFO 0x02
# define RESET_TX_FIFO 0x04
# define FIFO_MODE_1 0x08
# define RX_TRIGGER_1 0x00
# define RX_TRIGGER_4 0x40
# define RX_TRIGGER_8 0x80
# define RX_TRIGGER_14 0xC0
#define IIR 2
# define NO_INTS_PENDING 0x01
# define RX_ERROR 0x06
# define RX_DATA_READY 0x04
# define TX_NOT_FULL 0x02
# define MODEM_STATUS 0x00
# define INT_ID_MASK 0x06
#define IER 1
# define ENA_RX_READY_INT 0x1
# define ENA_TX_EMPTY_INT 0x2
# define ENA_RX_ERROR_INT 0x4
# define ENA_MODEM_STATUS_INT 0x8
#define MSR 6
# define DELTA_CTS 0x01
# define DELTA_DSR 0x02
# define END_OF_RING 0x04
# define DELTA_DCD 0x08
# define CTS 0x10
# define DSR 0x20
# define RING 0x40
# define DCD 0x80
#define MCR 4
# define DTR 0x01
# define RTS 0x02
# define OUT1 0x04
# define OUT2 0x08
# define LOOPBACK 0x10
#define SCR 7
int use_polled_io = CONSOLE_USE_POLLED;
void *tty_ptr_for_irq;
/*
* Hardware-dependent portion of tcsetattr().
*/
static int
setAttributes (int minor, const struct termios *t)
{
int divisor;
volatile char *uart = UART_BASE_ADDR;
char lcr_image = 0;
/* set character size */
switch (t->c_cflag & CSIZE) {
case CS5: lcr_image = FIVE_BITS; break;
case CS6: lcr_image = SIX_BITS; break;
case CS7: lcr_image = SEVEN_BITS; break;
case CS8: lcr_image = EIGHT_BITS; break;
}
/* set number of stop bits */
if (t->c_cflag & CSTOPB) {
lcr_image |= TWO_STOP_BITS;
} else {
lcr_image |= ONE_STOP_BIT;
}
/* set parity */
if ((t->c_cflag & PARENB) == 0) {
lcr_image |= NO_PARITY;
} else if (t->c_cflag & PARODD) {
lcr_image |= ODD_PARITY;
} else {
lcr_image |= EVEN_PARITY;
}
/* set the baud rate */
switch (t->c_cflag & CBAUD) {
default: divisor = -1; break;
case B50: divisor = 2304; break;
case B75: divisor = 1536; break;
case B110: divisor = 1047; break;
case B134: divisor = 857; break;
case B150: divisor = 768; break;
case B200: divisor = 576; break;
case B300: divisor = 384; break;
case B600: divisor = 192; break;
case B1200: divisor = 96; break;
case B1800: divisor = 64; break;
case B2400: divisor = 48; break;
case B4800: divisor = 24; break;
case B9600: divisor = 12; break;
case B19200: divisor = 6; break;
case B38400: divisor = 3; break;
case B57600: divisor = 2; break;
case B115200: divisor = -1; break;
case B230400: divisor = -1; break;
case B460800: divisor = -1; break;
}
if (divisor > 0) {
uart[LCR] = (lcr_image |= DLAB);
uart[DLM] = divisor >> 8;
uart[DLL] = divisor;
lcr_image &= ~DLAB;
}
/* activate the new configuration */
uart[LCR] = lcr_image;
return 0;
}
/*
* Interrupt handler
*/
static rtems_isr consoleInterruptHandler (rtems_vector_number v)
{
volatile char *uart = UART_BASE_ADDR;
volatile char ignore;
char buffer[16], iir_image;
int len;
while (((iir_image = uart[IIR]) & NO_INTS_PENDING) == 0) {
switch (iir_image & INT_ID_MASK) {
case RX_ERROR:
/*
* read the line status register to clear condition.
* nothing done with the information at this point.
*/
ignore = uart[LSR];
break;
case RX_DATA_READY:
/*
* empty the receive fifo and transfer bytes to termios layer
*/
len = 0;
do {
buffer[len++] = uart[RBR];
} while (len < sizeof(buffer) && (uart[LSR] & DR));
rtems_termios_enqueue_raw_characters(tty_ptr_for_irq,
buffer, len);
break;
case TX_NOT_FULL:
/*
* notify termios layer that characters have been sent
*/
len = uart[SCR];
/* we'll get one interrupt when we start - ignore it */
if (len) {
rtems_termios_dequeue_characters(tty_ptr_for_irq, len);
}
break;
case MODEM_STATUS:
/*
* read the modem status register to clear condition.
* nothing done with the information at this point.
*/
ignore = uart[MSR];
break;
}
}
}
/*
* console_inbyte_nonblocking
*
* This routine polls for a character.
*/
int console_inbyte_nonblocking(
int port
)
{
volatile char *uart = UART_BASE_ADDR;
if (uart[LSR] & DR) {
return uart[RBR];
} else {
return -1;
}
}
/*
* Console Termios Support Entry Points
*
*/
int console_write_polled (
int minor,
const char *buf,
int len
)
{
int nwrite = 0;
volatile char *uart = UART_BASE_ADDR;
while (nwrite < len) {
/* wait as long as needed for transmit buffer to empty */
while ((uart[LSR] & THRE) == 0) ;
uart[THR] = *buf++;
nwrite++;
}
/* return value seems to be ignored by termios layer, we'll return count */
return nwrite;
}
int console_write_interrupts (
int minor,
const char *buf,
int len
)
{
const int FIFO_depth = 16;
int nwrite;
volatile char *uart = UART_BASE_ADDR;
/* write up to len characters, stopping if FIFO fills */
for (nwrite = 0; nwrite < len && nwrite < FIFO_depth; nwrite++) {
uart[THR] = *buf++;
}
/* save count of bytes sent so interrupt can report it to termios layer */
uart[SCR] = nwrite;
/* return value seems to be ignored by termios layer, we'll return count */
return nwrite;
}
/*
* Console Device Driver Entry Points
*
*/
/*
* Initialize and register the device
*/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
volatile char *uart = UART_BASE_ADDR;
rtems_termios_initialize();
/*
* Register Device Names
*/
status = rtems_io_register_name( "/dev/console", major, 0 );
if (status != RTEMS_SUCCESSFUL) {
rtems_fatal_error_occurred(status);
}
/* default mode: 9600 bps, 8 bits, 1 stop, no parity */
# define DEFAULT_MODE (EIGHT_BITS | ONE_STOP_BIT | NO_PARITY)
uart[LCR] = DEFAULT_MODE | DLAB;
uart[DLM] = 0;
uart[DLL] = 12;
uart[LCR] = DEFAULT_MODE;
/* enable the receive and transmit FIFOs */
uart[FCR] = ENABLE_FIFOS | RESET_RC_FIFO | RESET_TX_FIFO | RX_TRIGGER_1;
/* set modem control lines */
uart[MCR] = DTR | RTS;
/* zero the scratch register - this will hold a count of tx characters */
uart[SCR] = 0;
/* initialize interrupts */
if (!use_polled_io) {
rtems_isr_entry old_handler;
rtems_status_code sc;
sc = bsp_interrupt_catch(consoleInterruptHandler, IRQ_UART,
&old_handler);
sc = bsp_interrupt_enable(IRQ_UART, PRIORITY_ISA_INT);
uart[IER] = ENA_RX_READY_INT | ENA_TX_EMPTY_INT;
} else {
uart[IER] = 0;
}
return RTEMS_SUCCESSFUL;
}
/*
* Open the device
*/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_status_code sc;
static const rtems_termios_callbacks pollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
console_inbyte_nonblocking, /* pollRead */
console_write_polled, /* write */
setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
static const rtems_termios_callbacks intrCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
NULL, /* pollRead */
console_write_interrupts, /* write */
setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
if ( minor > 1 )
return RTEMS_INVALID_NUMBER;
if (use_polled_io) {
sc = rtems_termios_open (major, minor, arg, &pollCallbacks );
} else {
sc = rtems_termios_open (major, minor, arg, &intrCallbacks );
tty_ptr_for_irq = ((rtems_libio_open_close_args_t *)arg)->iop->data1;
}
return RTEMS_SUCCESSFUL;
}
/*
* Close the device
*/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_close (arg);
}
/*
* Read from the device
*/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_read (arg);
}
/*
* Write to the device
*/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_write (arg);
}
/*
* Handle ioctl request.
*/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_ioctl (arg);
}
/*
* Reserve resources consumed by this driver
*/
void console_reserve_resources(
rtems_configuration_table *configuration
)
{
rtems_termios_reserve_resources( configuration, 1 );
}

View File

@@ -0,0 +1,199 @@
#include <bsp.h>
#if 1
static void outbyte(char c) {
volatile char * const pc16550 = (char *) IO_TO_LOCAL(0x03f8);
# define THR 0
# define LSR 5
# define THRE 0x20
while ((pc16550[LSR] & THRE) == 0) {
;
}
pc16550[THR] = c;
}
#else
/* printk to memory for debugging */
static void outbyte(char c) {
static char *memory_log = (char *) 0x01F00000;
*memory_log++ = c;
if (memory_log >= (char *) 0x01F80000) {
memory_log--;
}
}
#endif
/*-------------------------------------------------------------------------+
| printk.c v1.1 - PC386 BSP - 1997/08/07
+--------------------------------------------------------------------------+
| (C) Copyright 1997 -
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
| http://pandora.ist.utl.pt
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
| Disclaimer:
|
| This file is provided "AS IS" without warranty of any kind, either
| expressed or implied.
+--------------------------------------------------------------------------+
| This code is based on code by: Jose Rufino - IST
|
| $Id$
+--------------------------------------------------------------------------*/
#include <stdarg.h>
/*-------------------------------------------------------------------------+
| Function: printNum
| Description: print number in a given base.
| Global Variables: None.
| Arguments: num - number to print, base - base used to print the number.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void printNum(long unsigned int num, int base, int sign, int width,
int zerofill) {
long unsigned int n;
int count, negative = 0;
char toPrint[80];
char *digits = "0123456789ABCDEF";
if (width > sizeof(toPrint)) {
width = sizeof(toPrint);
}
if ((sign == 1) && ((long) num < 0)) {
negative = 1;
num = -num;
}
count = 0;
while ((n = num / base) > 0) {
toPrint[count++] = digits[num - (n * base)];
num = n;
}
toPrint[count++] = digits[num];
if (count + negative < width) {
/* this needs to be padded out to width */
if (zerofill) {
while (count + negative < width) {
toPrint[count++] = '0';
}
if (negative) {
toPrint[count++] = '-';
}
} else {
if (negative) {
toPrint[count++] = '-';
}
while (count < width) {
toPrint[count++] = ' ';
}
}
} else if (negative) {
toPrint[count++] = '-';
}
for (n = 0; n < count; n++) {
outbyte(toPrint[count - (n + 1)]);
}
}
/*-------------------------------------------------------------------------+
| Function: printk
| Description: a simplified version of printf intended for use when the
console is not yet initialized or in ISR's.
| Global Variables: None.
| Arguments: as in printf: fmt - format string, ... - unnamed arguments.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
int printk_enabled = 1;
void printk(char *fmt, ...) {
va_list ap; /* points to each unnamed argument in turn */
char c, *str;
int lflag, base, sign, width, zero;
/* disable interrupts??? */
if (printk_enabled) {
va_start(ap, fmt); /* make ap point to 1st unnamed arg */
for (; *fmt != '\0'; fmt++) {
lflag = 0;
base = 0;
sign = 0;
width = 0;
if (*fmt == '\n') {
outbyte('\r');
}
if (*fmt == '%') {
c = *++fmt;
if (c == '0') {
zero = 1;
c = *++fmt;
} else {
zero = 0;
}
for (; c >= '0' && c <= '9'; c = *++fmt) {
width = width * 10 + (c - '0');
}
if (c == 'l') {
lflag = 1;
c = *++fmt;
}
switch (c) {
case 'o':
case 'O':
base = 8;
sign = 0;
break;
case 'd':
case 'D':
base = 10;
sign = 1;
break;
case 'u':
case 'U':
base = 10;
sign = 0;
break;
case 'x':
case 'X':
base = 16;
sign = 0;
break;
case 's':
for (str = va_arg(ap, char *); *str; str++) {
outbyte(*str);
width--;
}
while (width-- > 0) {
outbyte(' ');
}
break;
case 'c':
outbyte(va_arg(ap, int));
break;
default:
outbyte(c);
break;
}
if (base) {
printNum(lflag ? va_arg(ap, long int) :
(long int) va_arg(ap, int), base, sign, width, zero);
}
} else {
outbyte(*fmt);
}
}
va_end(ap); /* clean up when done */
/* enable interrupts??? */
}
}

View File

@@ -0,0 +1,52 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/psim/include
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h
#
# Equate files are for including from assembly preprocessed by
# gm4 or gasp. No examples are provided except for those for
# other CPUs. The best way to generate them would be to
# provide a program which generates the constants used based
# on the C equivalents.
#
# If you add equate files, don't forget to uncomment the install line
# below.
#
EQ_FILES =
SRCS = $(H_FILES) $(EQ_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
all: $(SRCS)
@$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,338 @@
/* bsp.h
*
* This include file contains all board IO definitions.
*
* XXX : put yours in here
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __MVME2307_BSP_h
#define __MVME2307_BSP_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <console.h>
#include <clockdrv.h>
/*
* Network driver configuration
*/
struct rtems_bsdnet_ifconfig;
extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach
/*
* Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These
* values are in seconds and need to be converted to ticks for the
* application.
*
*/
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 1
#define Install_tm27_vector( handler ) \
set_vector( (handler), PPC_IRQ_DECREMENTER, 1 )
#define Cause_tm27_intr() \
{ \
unsigned32 _clicks = 1; \
asm volatile( "mtdec %0" : : "r" ((_clicks)) ); \
}
#define Clear_tm27_intr() \
{ \
unsigned32 _clicks = 0xffffffff; \
asm volatile( "mtdec %0" : : "r" ((_clicks)) ); \
}
#define Lower_tm27_intr() \
{ \
unsigned32 _msr = 0; \
_ISR_Set_level( 0 ); \
asm volatile( "mfmsr %0 ;" : "=r" (_msr) :); \
_msr |= 0x8002; \
asm volatile( "mtmsr %0 ;" : : "r" (_msr) ); \
}
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration;
/*
* Device Driver Table Entries
*/
/*
* NOTE: Use the standard Console driver entry
*/
/*
* NOTE: Use the standard Clock driver entry
*/
/*
* Falcon memory controller registers
*/
typedef struct {
unsigned32 SystemId :8;
# define SYSID_MVME2300 0xFD
unsigned32 SystemClock :4;
# define SYSCLK_50_MHZ 0xD
# define SYSCLK_60_MHZ 0xE
# define SYSCLK_67_MHZ 0xF
unsigned32 ExternalCacheSize :4;
# define NO_EXT_CACHE 0xF
unsigned32 ProcessorInfo1 :4;
unsigned32 ProcessorInfo2 :4;
# define PROC_WITH_1M_CACHE 0x4
# define PROC_WITH_512K_CACHE 0x5
# define PROC_WITH_256K_CACHE 0x6
# define PROC_WITH_NO_CACHE 0x7
unsigned32 _ :8;
} FalconSystemConfReg_t;
#define Falcon_SYSCR (*(FalconSystemConfReg_t *) 0xFEF80400)
typedef struct {
unsigned32 MemSize :2;
# define RAM_16_MB 0x0
# define RAM_32_MB 0x1
# define RAM_64_MB 0x2
# define RAM_128_MB 0x3
unsigned32 _ :1;
unsigned32 MemFastRefresh :1;
# define DRAM_NORMAL_REFRESH 0x0
# define DRAM_FAST_REFRESH 0x1
unsigned32 __ :2;
unsigned32 MemSpeed :2;
# define DRAM_70_NSEC 0x0
# define DRAM_60_NSEC 0x1
# define DRAM_50_NSEC 0x3
unsigned32 ___ :1;
unsigned32 RomAType :3;
unsigned32 ____ :1;
unsigned32 RomBType :3;
# define INTEL_FLASH 0x6;
# define UNKNOWN_FLASH 0x7;
unsigned32 L2Type :4;
# define LATE_WRITE_SYNC 0x0
# define PIPELINED_SYNC_BURST 0x1
unsigned32 L2FreqDivider :4;
# define PLL_DISABLED 0x0
# define PLL_DIV_BY_1 0x1
# define PLL_DIV_BY_1_5 0x2
# define PLL_DIV_BY_2 0x3
# define PLL_DIV_BY_2_5 0x4
# define PLL_DIV_BY_3 0x5
unsigned32 _____ :2;
unsigned32 RomASize :3;
# define ROM_A_1_MB 0x0
# define ROM_A_2_MB 0x1
# define ROM_A_4_MB 0x2
# define ROM_A_8_MB 0x3
# define ROM_A_16_MB 0x4
# define ROM_A_32_MB 0x5
# define ROM_A_64_MB 0x6
# define ROM_A_0_MB 0x7
unsigned32 ______ :3;
} FalconMemConfReg_t;
#define Falcon_MEMCR (*(FalconMemConfReg_t *) 0xFEF80404)
extern int end; /* last address in the program */
/*
* PCI bus functions
*/
/*
* address space conversions
*
* address spaces:
* LOCAL - memory space of the PowerPC
* PCI - memory space on the PCI bus
* IO - I/O space on the PCI bus
* VME - memory space on the VME bus
*/
#define IO_TO_LOCAL(address) ((unsigned int)(address) + 0x80000000)
#define PCI_TO_LOCAL(address) ((unsigned int)(address) + 0xC0000000)
#define LOCAL_TO_PCI(address) ((unsigned int)(address) + 0x80000000)
#define INVERSE_LOCAL_TO_PCI(address) ((unsigned int)(address) - 0x80000000)
#define PCI_NOT_FOUND (-1)
#define RAVEN_VENDOR_ID 0x1057
#define RAVEN_DEVICE_ID 0x4801
#define UNIVERSE_VENDOR_ID 0x10E3
#define UNIVERSE_DEVICE_ID 0x0000
#define DEC21140_VENDOR_ID 0x1011
#define DEC21140_DEVICE_ID 0x0009
#define PCI_BASE_ADDRESS_0 0x10
#define PCI_BASE_ADDRESS_1 0x14
#define PCI_INTERRUPT_LINE 60
int pci_make_devsig(int bus, int device, int function); /* returns sig */
int pci_find_by_devid(int vendorId, int devId, int idx); /* returns sig */
int pci_conf_read8(int sig, int off);
int pci_conf_read16(int sig, int off);
int pci_conf_read32(int sig, int off);
void pci_conf_write8(int sig, int off, unsigned int data);
void pci_conf_write16(int sig, int off, unsigned int data);
void pci_conf_write32(int sig, int off, unsigned int data);
static inline void synchronize_io(void) {
asm volatile ("eieio" : :);
}
/*
* functions for accessing little-endian data
*/
static inline void st_le32(volatile int *addr, int data) {
asm volatile ("stwbrx %0,0,%1" : : "r" (data), "r" (addr));
}
static inline void st_le16(volatile short *addr, short data) {
asm volatile ("sthbrx %0,0,%1" : : "r" (data), "r" (addr));
}
static inline int ld_le32(volatile int *addr) {
int data;
asm volatile ("lwbrx %0,0,%1" : "=r" (data) : "r" (addr));
return data;
}
static inline int ld_le16(volatile short *addr) {
int data;
asm volatile ("lhbrx %0,0,%1" : "=r" (data) : "r" (addr));
return data;
}
/*
* interrupt and timer handling
*/
/* ISA interrupts - vectors 0-15 */
#define IRQ_ISA_TIMER 0
#define IRQ_UART 4
#define IRQ_ISA_LM_SIG 5
#define IRQ_ABORT_SWITCH 8
#define IRQ_ISA_ETHERNET 10
#define IRQ_ISA_UNIVERSE 11
#define IRQ_ISA_PMC_PCIX 15
/* Raven interrupts */
#define IRQ_PIC_CASCADE 16
#define IRQ_FALCON_ECC 17
#define IRQ_ETHERNET 18
#define IRQ_VME_LINT0 19
#define IRQ_VME_LINT1 20
#define IRQ_VME_LINT2 21
#define IRQ_VME_LINT3 22
#define IRQ_PMC1A_PMC2B 23
#define IRQ_PMC1B_PMC2C 24
#define IRQ_PMC1C_PMC2D 25
#define IRQ_PMC1D_PMC2A 26
#define IRQ_LM_SIG_0 27
#define IRQ_LM_SIG_1 28
/* Raven timers */
#define IRQ_TIMER_0 29
#define IRQ_TIMER_1 30
#define IRQ_TIMER_2 31
#define IRQ_TIMER_3 32
/* Raven interprocessor interrupts */
#define IRQ_IPI_0 33
#define IRQ_IPI_1 34
#define IRQ_IPI_2 35
#define IRQ_IPI_3 36
/* other */
#define IRQ_SPURIOUS 37
#define IRQ_RAVEN_ERROR 38
/* Raven priority that ISA interrupts use */
#define PRIORITY_ISA_INT 8
rtems_status_code interrupt_controller_init(void);
rtems_status_code bsp_interrupt_catch(rtems_isr_entry new_isr_handler,
rtems_vector_number vector,
rtems_isr_entry *old_isr_handler);
rtems_status_code bsp_interrupt_enable(rtems_vector_number vector,
int priority);
rtems_status_code bsp_interrupt_disable(rtems_vector_number vector);
rtems_status_code bsp_start_timer(int timer, int period_usec);
rtems_status_code bsp_stop_timer(int timer);
rtems_status_code bsp_read_timer(int timer, int *value);
rtems_status_code generate_interprocessor_interrupt(int interrupt);
rtems_status_code set_interrupt_task_priority(int priority);
/* functions */
void bsp_cleanup( void );
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 */
);
int read_nvram(char *buff, int offset, int len);
void printk( char *fmt, ... );
void BSP_fatal_return( void );
void bsp_spurious_initialize( void );
extern rtems_configuration_table BSP_Configuration; /* owned by BSP */
extern rtems_cpu_table Cpu_table; /* owned by BSP */
extern rtems_unsigned32 bsp_isr_level;
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,115 @@
/* 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-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#ifdef __cplusplus
extern "C" {
#endif
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 0
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 0
#define CALLING_OVERHEAD_CLOCK_SET 0
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 0
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 0
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,71 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/network
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/network.rel
# C source names, if any, go here -- minus the .c
C_PIECES=network
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
-DDIAGNOSTIC -DBOOTP_COMPAT
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,946 @@
/*
* RTEMS driver for TULIP based Ethernet Controller
*
* $Header$
*/
/* make sure we can identify the platform (is __i386 valid?) */
#if !defined(__PPC) && !defined(__i386)
# error "unknown platform: should be __i386 or __PPC"
#endif
#include <bsp.h>
#if defined(i386)
#include <pcibios.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <rtems/error.h>
#include <rtems/rtems_bsdnet.h>
#include <rtems/score/cpu.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>
#if defined(i386)
#include <irq.h>
#endif
#ifdef malloc
#undef malloc
#endif
#ifdef free
#undef free
#endif
#define PCI_VENDOR_ID_DEC 0x1011
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
#define IO_MASK 0x3
#define MEM_MASK 0xF
/* command and status registers, 32-bit access, only if MEMORY-ACCESS */
#define CSR0 0x00 /* bus mode register */
#define CSR1 0x02 /* transmit poll demand */
#define CSR2 0x04 /* receive poll demand */
#define CSR3 0x06 /* receive list base address */
#define CSR4 0x08 /* transmit list base address */
#define CSR5 0x0A /* status register */
#define CSR6 0x0C /* operation mode register */
#define CSR7 0x0E /* interrupt mask register */
#define CSR8 0x10 /* missed frame counter */
#define CSR9 0x12 /* Ethernet ROM register */
#define CSR10 0x14 /* reserved */
#define CSR11 0x16 /* full-duplex register */
#define CSR12 0x18 /* SIA status register */
#define CSR13 0x1A
#define CSR14 0x1C
#define CSR15 0x1E /* SIA general register */
#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */
#define RESET_CHIP 0x00000001
#if defined(__PPC)
#define CSR0_MODE 0x0020E002
#define CSR6_INIT 0x0224c000
#else
#define CSR0_MODE 0x01a08000
#define CSR6_INIT 0x020c0000
#endif
#define ROM_ADDRESS 0x00004800
#define CSR6_TX 0x00002000
#define CSR6_TXRX 0x00002002
#define IT_SETUP 0x0001a3ef
#define CLEAR_IT 0xFFFFFFFF
#define NO_IT 0x00000000
#define SETUP_PACKET 0x08000000
#define END_OF_RING 0x02000000
#define CHAINED_ADDRESS 0x01000000
#define OWNED_BY_DEC21140 0x80000000
#define OWNED_BY_HOST 0x00000000
#define LAST_SEGMENT 0x40000000
#define FIRST_SEGMENT 0x20000000
#define NRXBUFS 8 /* number of receive buffers */
#define NTXBUFS 32 /* number of transmit buffers */
/* message descriptor entry */
struct MD {
/* used by hardware */
volatile unsigned32 status;
volatile unsigned32 counts;
unsigned32 buf1, buf2;
/* used by software */
struct mbuf *m;
struct MD *next;
};
static inline void write_descr_status(volatile struct MD *m, unsigned32 status) {
st_le32(&(m->status), status);
}
static inline unsigned32 read_descr_status(volatile struct MD *m) {
return ld_le32(&(m->status));
}
static inline void write_descr_counts(volatile struct MD *m, unsigned32 counts) {
st_le32(&(m->counts), counts);
}
static inline unsigned32 read_descr_counts(volatile struct MD *m) {
return ld_le32(&(m->counts));
}
static inline void set_chain_address(volatile struct MD *m, void *addr) {
st_le32(&(m->buf2), LOCAL_TO_PCI(addr));
}
static inline void set_buffer_address(volatile struct MD *m, void *addr) {
st_le32(&(m->buf1), LOCAL_TO_PCI(addr));
}
static inline void *get_buffer_address(volatile struct MD *m) {
return (void *)INVERSE_LOCAL_TO_PCI(ld_le32(&(m->buf1)));
}
/*
* Number of WDs supported by this driver
*/
#define NDECDRIVER 1
/*
* Receive buffer size -- Allow for a full ethernet packet including CRC
*/
#define RBUF_SIZE 1520
#define ET_MINLEN 60 /* minimum message length */
/*
* RTEMS event used by interrupt handler to signal driver tasks.
* This must not be any of the events used by the network task synchronization.
*/
#define INTERRUPT_EVENT RTEMS_EVENT_1
/*
* RTEMS event used to start transmit daemon.
* This must not be the same as INTERRUPT_EVENT.
*/
#define START_TRANSMIT_EVENT RTEMS_EVENT_2
#if (MCLBYTES < RBUF_SIZE)
# error "Driver must have MCLBYTES > RBUF_SIZE"
#endif
/*
* Per-device data
*/
struct dec21140_softc {
struct arpcom arpcom;
#if defined(__PPC)
int irqInfo;
#else
rtems_irq_connect_data irqInfo;
#endif
struct MD *MDbase;
char *bufferBase;
int acceptBroadcast;
rtems_id rxDaemonTid;
rtems_id txDaemonTid;
struct MD *TxMD;
struct MD *SentTxMD;
int PendingTxCount;
int TxSuspended;
unsigned32 port;
unsigned32 *base;
/*
* Statistics
*/
unsigned32 rxInterrupts;
unsigned32 rxNotFirst;
unsigned32 rxNotLast;
unsigned32 rxGiant;
unsigned32 rxNonOctet;
unsigned32 rxRunt;
unsigned32 rxBadCRC;
unsigned32 rxOverrun;
unsigned32 rxCollision;
unsigned32 txInterrupts;
unsigned32 txDeferred;
unsigned32 txHeartbeat;
unsigned32 txLateCollision;
unsigned32 txRetryLimit;
unsigned32 txUnderrun;
unsigned32 txLostCarrier;
unsigned32 txRawWait;
};
static struct dec21140_softc dec21140_softc[NDECDRIVER];
static rtems_interval ticks_per_second;
/* ================================================================ */
static inline void write_csr(unsigned32 *base, int csr, unsigned32 value) {
synchronize_io();
st_le32(base + csr, value);
}
static inline unsigned32 read_csr(unsigned32 *base, int csr) {
synchronize_io();
return ld_le32(base + csr);
}
/* ================================================================ */
/*
* DEC21140 interrupt handler
*/
static rtems_isr dec21140Enet_interrupt_handler (rtems_vector_number v) {
unsigned32 *tbase;
unsigned32 status;
struct dec21140_softc *sc;
#if NDECDRIVER == 1
sc = &dec21140_softc[0];
#else
# error "need to find dec21140_softc[i] based on vector number"
#endif
tbase = sc->base ;
/*
* Read status
*/
status = read_csr(tbase, CSR5);
write_csr(tbase, CSR5, status); /* clear the bits we've read */
/*
* severe error?
*/
if (status & 0x0000230a){
printk("FATAL ERROR in network driver: CSR5=0x%08x\n", status);
}
/*
* Frame received?
*/
if (status & 0x000000c0){
sc->rxInterrupts++;
rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
}
/*
* Frame transmitted or transmit error?
*/
if (status & 0x00000025) {
if (status & 0x00000004) {
sc->TxSuspended = 1;
}
sc->txInterrupts++;
rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
}
}
#if defined(__i386)
static void nopOn(const rtems_irq_connect_data* notUsed) {
/*
* code should be moved from dec21140Enet_initialize_hardware
* to this location
*/
}
static int dec21140IsOn(const rtems_irq_connect_data* irq) {
return BSP_irq_enabled_at_i8259s (irq->name);
}
#endif
/*
* Initialize the ethernet hardware
*/
#define PPCBUG_HW_ADDR_STORAGE 0x1f2c
static void dec21140Enet_initialize_hardware (struct dec21140_softc *sc) {
rtems_status_code st;
unsigned32 *tbase;
int i;
char *cp, *setup_frm, *eaddrs;
unsigned char *buffer;
struct MD *rmd;
tbase = sc->base;
/*
* WARNING : First write in CSR6
* Then Reset the chip ( 1 in CSR0)
*/
write_csr(tbase, CSR6, CSR6_INIT);
write_csr(tbase, CSR0, RESET_CHIP);
delay_in_bus_cycles(200);
/*
* Init CSR0
*/
write_csr(tbase, CSR0, CSR0_MODE);
read_nvram(sc->arpcom.ac_enaddr, PPCBUG_HW_ADDR_STORAGE, 6);
#ifdef DEC_DEBUG
printk("DC21140 %x:%x:%x:%x:%x:%x IRQ %d IO %x M %x .........\n",
sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
sc->irqInfo, sc->port, sc->base);
#endif
/*
* Init RX ring
*/
#if defined(__i386)
cp = (char *)malloc((NRXBUFS + NTXBUFS) * (sizeof(struct MD) + RBUF_SIZE) +
PG_SIZE);
sc->bufferBase = cp;
cp += (PG_SIZE - (int)cp) & MASK_OFFSET ;
if (_CPU_is_paging_enabled()) {
_CPU_change_memory_mapping_attribute
(NULL, cp,
(NRXBUFS + NTXBUFS) * (sizeof(struct MD) + RBUF_SIZE),
PTE_CACHE_DISABLE | PTE_WRITABLE);
}
#endif
#if defined(__PPC)
cp = (char *)malloc((NRXBUFS + NTXBUFS)*(sizeof(struct MD)+ RBUF_SIZE) +
4096);
#endif
rmd = (struct MD *)cp;
sc->MDbase = rmd;
buffer = cp + ((NRXBUFS + NTXBUFS)*sizeof(struct MD));
write_csr(tbase, CSR3, LOCAL_TO_PCI(sc->MDbase));
for (i = 0 ; i < NRXBUFS; i++){
struct mbuf *m;
/* allocate an mbuf for each receive descriptor */
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
rmd->m = m;
set_buffer_address(rmd, mtod(m, void *));
if (i == NRXBUFS - 1) {
write_descr_counts(rmd, END_OF_RING | RBUF_SIZE);
rmd->next = sc->MDbase;
} else {
write_descr_counts(rmd, CHAINED_ADDRESS | RBUF_SIZE);
set_chain_address(rmd, rmd + 1);
rmd->next = rmd + 1;
}
write_descr_status(rmd, OWNED_BY_DEC21140);
rmd++;
}
/*
* Init TX ring
*/
write_csr(tbase, CSR4, LOCAL_TO_PCI(rmd));
for (i = 0 ; i < NTXBUFS; i++){
set_buffer_address(rmd + i, buffer + NRXBUFS * RBUF_SIZE + i * RBUF_SIZE);
write_descr_counts(rmd + i, FIRST_SEGMENT | LAST_SEGMENT | CHAINED_ADDRESS);
if (i == NTXBUFS - 1) {
set_chain_address(rmd + i, rmd);
(rmd + i)->next = rmd;
} else {
set_chain_address(rmd + i, rmd + i + 1);
(rmd + i)->next = rmd + i + 1;
}
write_descr_status(rmd + i, OWNED_BY_HOST);
}
#if defined(__i386)
sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler;
sc->irqInfo.on = nopOn;
sc->irqInfo.off = nopOn;
sc->irqInfo.isOn = dec21140IsOn;
st = BSP_install_rtems_irq_handler (&sc->irqInfo);
if (!st) {
rtems_panic ("Can't attach DEC21140 interrupt handler for irq %d\n",
sc->irqInfo.name);
}
#endif
#if defined(__PPC)
{
rtems_isr_entry old_handler;
st = bsp_interrupt_catch(dec21140Enet_interrupt_handler,
IRQ_ETHERNET, &old_handler);
if (st != RTEMS_SUCCESSFUL) {
rtems_panic("Can't attach DEC21140 interrupt handler\n");
}
bsp_interrupt_enable(IRQ_ETHERNET, PRIORITY_ISA_INT);
}
#endif
/* no interrupts for now */
write_csr(tbase, CSR7, NO_IT);
/*
* Build setup frame
*/
setup_frm = get_buffer_address(rmd);
eaddrs = (char *)(sc->arpcom.ac_enaddr);
/* Fill the buffer with our physical address. */
for (i = 1; i < 16; i++) {
*setup_frm++ = eaddrs[0];
*setup_frm++ = eaddrs[1];
setup_frm += 2;
*setup_frm++ = eaddrs[2];
*setup_frm++ = eaddrs[3];
setup_frm += 2;
*setup_frm++ = eaddrs[4];
*setup_frm++ = eaddrs[5];
setup_frm += 2;
}
/* Add the broadcast address when doing perfect filtering */
memset((char*)setup_frm, 0xff, 12);
write_descr_counts(rmd, SETUP_PACKET | CHAINED_ADDRESS | 192);
write_descr_status(rmd, OWNED_BY_DEC21140);
/*
* Start TX for setup frame
*/
write_csr(tbase, CSR6, CSR6_INIT | CSR6_TX);
write_csr(tbase, CSR1, 1);
while (read_descr_status(rmd) & OWNED_BY_DEC21140);
sc->SentTxMD = sc->TxMD = rmd + 1;
sc->PendingTxCount = 0;
sc->TxSuspended = 1;
/*
* Set up interrupts
*/
write_csr(tbase, CSR5, IT_SETUP);
write_csr(tbase, CSR7, IT_SETUP);
/*
* Enable RX and TX
*/
write_csr(tbase, CSR6, CSR6_INIT | CSR6_TXRX);
}
static void dec21140_rxDaemon (void *arg) {
unsigned32 *tbase;
struct dec21140_softc *sc = arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct MD *rmd;
unsigned32 len;
unsigned32 rx_status;
rtems_event_set events;
tbase = sc->base;
rmd = sc->MDbase;
for (;;){
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT | RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
while (((rx_status = read_descr_status(rmd)) & OWNED_BY_DEC21140) == 0) {
struct ether_header *eh;
struct mbuf *m = rmd->m;
/*
* packet is good if Error Summary = 0 and First Descriptor = 1
* and Last Descriptor = 1
*/
if ((rx_status & 0x00008300) == 0x00000300) {
/* pass on the packet in the mbuf */
len = (rx_status >> 16) & 0x7ff;
m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
eh = mtod (m, struct ether_header *);
m->m_data += sizeof(struct ether_header);
ether_input (ifp, eh, m);
/* get a new mbuf for the 21140 */
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
rmd->m = m;
set_buffer_address(rmd, mtod(m, void *));
} else {
if ((rx_status & (1 << 9)) == 0) {
sc->rxNotFirst++;
}
if ((rx_status & (1 << 8)) == 0) {
sc->rxNotLast++;
}
if (rx_status & (1 << 7)) {
sc->rxGiant++;
}
if (rx_status & (1 << 2)) {
sc->rxNonOctet++;
}
if (rx_status & (1 << 11)) {
sc->rxRunt++;
}
if (rx_status & (1 << 1)) {
sc->rxBadCRC++;
}
if (rx_status & (1 << 14)) {
sc->rxOverrun++;
}
if (rx_status & (1 << 6)) {
sc->rxCollision++;
}
}
/* give the descriptor back to the 21140 */
write_descr_status(rmd, OWNED_BY_DEC21140);
/* check for more ready descriptors */
rmd = rmd->next;
}
}
}
static void reap_sent_descriptors(struct dec21140_softc *sc) {
struct MD *descr = sc->SentTxMD;
unsigned32 *tbase = sc->base;
unsigned32 tx_status = 0;
struct mbuf *m, *n;
while (sc->PendingTxCount > 0 &&
((tx_status = read_descr_status(descr)) & OWNED_BY_DEC21140) == 0 ) {
for (m = descr->m; m; m = n) {
MFREE(m, n);
}
if (read_descr_counts(descr) & LAST_SEGMENT) {
if (tx_status & (1 << 0)) {
sc->txDeferred++;
}
if (tx_status & (1 << 7)) {
sc->txHeartbeat++;
}
if (tx_status & (1 << 9)) {
sc->txLateCollision++;
}
if (tx_status & (1 << 8)) {
sc->txRetryLimit++;
}
if (tx_status & (1 << 1)) {
sc->txUnderrun++;
write_csr(tbase, CSR1, 0x1); /* restart transmitter */
/* this shouldn't happen - descriptor should still be
owned by 21140 */
printk("ethernet chip underrun error\n");
}
if (tx_status & (1 << 10)) {
sc->txLostCarrier++;
}
}
descr = descr->next;
sc->PendingTxCount--;
}
sc->SentTxMD = descr;
/* check for Underflow and restart transmission */
if ((tx_status & 0x80000002) == 0x80000002) {
sc->txUnderrun++;
write_csr(tbase, CSR1, 0x1); /* restart transmitter */
printk("ethernet chip underrun error\n");
}
}
static void sendpacket (volatile struct ifnet *ifp, struct mbuf *m) {
struct mbuf *mbuf = m;
struct dec21140_softc *sc = ifp->if_softc;
struct MD *descr, *first, *last;
unsigned32 *tbase = sc->base;
int count = 0;
first = last = descr = sc->TxMD;
reap_sent_descriptors(sc);
while (mbuf) {
if (mbuf->m_len) {
/* if no descriptor is available, wait for interrupt */
while ((sc->PendingTxCount + count) == NTXBUFS) {
rtems_event_set events;
rtems_status_code result;
if (sc->PendingTxCount == 0) {
printk("ERROR: too many segments to transmit in mbuf\n");
}
result = rtems_bsdnet_event_receive(INTERRUPT_EVENT,
RTEMS_WAIT | RTEMS_EVENT_ANY,
20 * ticks_per_second,
&events);
if (result == RTEMS_TIMEOUT) {
printk("still waiting for tx descriptor in sendpacket\n");
}
reap_sent_descriptors(sc);
if (sc->TxSuspended) {
sc->TxSuspended = 0;
write_csr(tbase, CSR1, 0x1);
}
}
set_buffer_address(descr, mtod (mbuf, void *));
write_descr_counts(descr, CHAINED_ADDRESS | mbuf->m_len);
last = descr;
if (descr != first) {
write_descr_status(descr, OWNED_BY_DEC21140);
}
descr->m = 0;
count++;
descr = descr->next;
}
mbuf = mbuf->m_next;
}
write_descr_counts(first, read_descr_counts(first) | FIRST_SEGMENT);
write_descr_counts(last, read_descr_counts(last) | LAST_SEGMENT);
last->m = m;
sc->TxMD = descr;
synchronize_io();
write_descr_status(first, OWNED_BY_DEC21140);
sc->PendingTxCount += count;
if (sc->TxSuspended) {
sc->TxSuspended = 0;
synchronize_io();
write_csr(tbase, CSR1, 0x1);
}
}
/*
* Driver transmit daemon
*/
static void dec21140_txDaemon (void *arg) {
struct dec21140_softc *sc = (struct dec21140_softc *)arg;
volatile struct ifnet *ifp = &sc->arpcom.ac_if;
unsigned32 *tbase = sc->base;
struct mbuf *m;
rtems_event_set events;
for (;;) {
/*
* Wait for packet
*/
rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
RTEMS_EVENT_ANY | RTEMS_WAIT,
RTEMS_NO_TIMEOUT, &events);
/*
* Send packets till queue is empty
*/
for (;;) {
/*
* Get the next mbuf chain to transmit.
*/
IF_DEQUEUE(&ifp->if_snd, m);
if (!m) {
break;
}
sendpacket (ifp, m);
}
ifp->if_flags &= ~IFF_OACTIVE;
}
}
static void dec21140_start (struct ifnet *ifp) {
struct dec21140_softc *sc = ifp->if_softc;
ifp->if_flags |= IFF_OACTIVE;
rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
}
/*
* Initialize and start the device
*/
static void dec21140_init (void *arg) {
struct dec21140_softc *sc = arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
if (sc->txDaemonTid == 0) {
/*
* Set up DEC21140 hardware
*/
dec21140Enet_initialize_hardware (sc);
/*
* Start driver tasks
*/
#if NDECDRIVER == 1
sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
dec21140_rxDaemon, sc);
sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
dec21140_txDaemon, sc);
#else
# error "need to fix task IDs"
#endif
}
/*
* Tell the world that we're running.
*/
ifp->if_flags |= IFF_RUNNING;
}
/*
* Stop the device
*/
static void dec21140_stop (struct dec21140_softc *sc) {
unsigned32 *tbase;
struct ifnet *ifp = &sc->arpcom.ac_if;
ifp->if_flags &= ~IFF_RUNNING;
/*
* Stop the transmitter
*/
tbase = sc->base;
write_csr(tbase, CSR7, NO_IT);
write_csr(tbase, CSR6, CSR6_INIT);
free(sc->bufferBase);
}
/*
* Show interface statistics
*/
static void dec21140_stats (struct dec21140_softc *sc) {
printf (" Rx Interrupts:%-8u", sc->rxInterrupts);
printf (" Not First:%-8u", sc->rxNotFirst);
printf (" Not Last:%-8u\n", sc->rxNotLast);
printf (" Giant:%-8u", sc->rxGiant);
printf (" Runt:%-8u", sc->rxRunt);
printf (" Non-octet:%-8u\n", sc->rxNonOctet);
printf (" Bad CRC:%-8u", sc->rxBadCRC);
printf (" Overrun:%-8u", sc->rxOverrun);
printf (" Collision:%-8u\n", sc->rxCollision);
printf (" Tx Interrupts:%-8u", sc->txInterrupts);
printf (" Deferred:%-8u", sc->txDeferred);
printf (" Missed Hearbeat:%-8u\n", sc->txHeartbeat);
printf (" No Carrier:%-8u", sc->txLostCarrier);
printf ("Retransmit Limit:%-8u", sc->txRetryLimit);
printf (" Late Collision:%-8u\n", sc->txLateCollision);
printf (" Underrun:%-8u", sc->txUnderrun);
printf (" Raw output wait:%-8u\n", sc->txRawWait);
}
/*
* Driver ioctl handler
*/
static int dec21140_ioctl (struct ifnet *ifp, int command, caddr_t data) {
struct dec21140_softc *sc = ifp->if_softc;
int error = 0;
switch (command) {
case SIOCGIFADDR:
case SIOCSIFADDR:
ether_ioctl (ifp, command, data);
break;
case SIOCSIFFLAGS:
switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
case IFF_RUNNING:
dec21140_stop (sc);
break;
case IFF_UP:
dec21140_init (sc);
break;
case IFF_UP | IFF_RUNNING:
dec21140_stop (sc);
dec21140_init (sc);
break;
default:
break;
}
break;
case SIO_RTEMS_SHOW_STATS:
dec21140_stats (sc);
break;
/*
* FIXME: All sorts of multicast commands need to be added here!
*/
default:
error = EINVAL;
break;
}
return error;
}
/*
* Attach an DEC21140 driver to the system
*/
int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config) {
struct dec21140_softc *sc;
struct ifnet *ifp;
int mtu;
int i;
#if defined(__i386)
int signature;
int value;
char interrupt;
int diag;
/*
* Initialise PCI module
*/
if (pcib_init() == PCIB_ERR_NOTPRESENT) {
rtems_panic("PCI BIOS not found !!");
}
/*
* First, find a DEC board
*/
if ((diag = pcib_find_by_devid(PCI_VENDOR_ID_DEC,
PCI_DEVICE_ID_DEC_TULIP_FAST,
0,
&signature)) != PCIB_ERR_SUCCESS) {
rtems_panic("DEC PCI board not found !! (%d)\n", diag);
} else {
printk("DEC PCI Device found\n");
}
#endif
#if defined(__PPC)
int sig;
/* search PCI bus for Tulip chip */
sig = pci_find_by_devid(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, 0);
if (sig == PCI_NOT_FOUND) {
printk("PCI scan failed: DEC 21140 not found\n");
return 0;
}
#endif
/*
* Find a free driver
*/
for (i = 0 ; i < NDECDRIVER ; i++) {
sc = &dec21140_softc[i];
ifp = &sc->arpcom.ac_if;
if (ifp->if_softc == NULL) {
break;
}
}
if (i >= NDECDRIVER) {
printk ("Too many DEC drivers.\n");
return 0;
}
/*
* Process options
*/
sc->port = pci_conf_read32(sig, PCI_BASE_ADDRESS_0) & ~IO_MASK;
sc->base = (void *)
PCI_TO_LOCAL(pci_conf_read32(sig, PCI_BASE_ADDRESS_1) & ~MEM_MASK);
sc->irqInfo = pci_conf_read8(sig, 60);
#if defined(__i386)
pcib_conf_read32(signature, 16, &value);
sc->port = value & ~IO_MASK;
pcib_conf_read32(signature, 20, &value);
if (_CPU_is_paging_enabled()) {
_CPU_map_phys_address(&(sc->base),
(void *)(value & ~MEM_MASK),
DEC_REGISTER_SIZE ,
PTE_CACHE_DISABLE | PTE_WRITABLE);
} else {
sc->base = (unsigned32 *)(value & ~MEM_MASK);
}
pcib_conf_read8(signature, 60, &interrupt);
sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
#endif
if (config->hardware_address) {
memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
} else {
memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
}
if (config->mtu) {
mtu = config->mtu;
} else {
mtu = ETHERMTU;
}
sc->acceptBroadcast = !config->ignore_broadcast;
/*
* Set up network interface values
*/
ifp->if_softc = sc;
ifp->if_unit = i + 1;
ifp->if_name = "dc";
ifp->if_mtu = mtu;
ifp->if_init = dec21140_init;
ifp->if_ioctl = dec21140_ioctl;
ifp->if_start = dec21140_start;
ifp->if_output = ether_output;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
if (ifp->if_snd.ifq_maxlen == 0) {
ifp->if_snd.ifq_maxlen = ifqmaxlen;
}
/*
* Attach the interface
*/
if_attach (ifp);
ether_ifattach (ifp);
/*
* Determine clock rate for timeout calculation
*/
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
return 1;
};

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/nvram
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/nvram.rel
# C source names, if any, go here -- minus the .c
C_PIECES=nvram
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,25 @@
#include <bsp.h>
#define ram_addr_low (* (volatile char *) IO_TO_LOCAL(0x0074))
#define ram_addr_high (* (volatile char *) IO_TO_LOCAL(0x0075))
#define ram_data (* (volatile char *) IO_TO_LOCAL(0x0077))
#define ram_end_addr 0x1ff8
int read_nvram(char *buff, int offset, int len) {
int i;
if (offset < 0 || offset >= ram_end_addr) {
return 0;
}
if (offset + len > ram_end_addr) {
len = ram_end_addr - offset;
}
for (i = 0; i < len; i++) {
ram_addr_high = offset >> 8;
ram_addr_low = offset;
*buff++ = ram_data;
offset++;
}
return len;
}

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/pci
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/pci.rel
# C source names, if any, go here -- minus the .c
C_PIECES=interrupts pci
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,41 @@
Device at 0,0,0: Motorola Raven
cmd/status: 22800006
class/rev: 06000001
iobase: not mapped
membase: 3c000000
Device at 0,11,0: Winbond 83C553
cmd/status: 02000007
class/rev: 06010005
iobase: 00000000
membase: 00000000
Device at 0,11,1: Winbond 82C105
cmd/status: 02800005
class/rev: 01018f05
iobase: 010000a1
membase: not mapped
Device at 0,13,0: Tundra CA91C042
cmd/status: 02000006
class/rev: 06800000
iobase: not mapped
membase: 00000000
Device at 0,14,0: DEC 21140
cmd/status: 02800007
class/rev: 02000022
iobase: 01000001
membase: 3bfeff80
Device at 0,17,0: Intel i960 PCI bridge
cmd/status: 02800007
class/rev: ff040003
iobase: 00000000
membase: 00000000
Device at 0,17,1: Intel i960 ATU
cmd/status: 02800106
class/rev: 05800003
iobase: not mapped
membase: 00000000

View File

@@ -0,0 +1,353 @@
#include <rtems.h>
#include <rtems/error.h>
#include <bsp.h>
#define NUMBER_INTERRUPTS (IRQ_RAVEN_ERROR + 1)
#define DISABLE_IRQ 0x80000000
static rtems_isr raven_interrupt_handler(rtems_vector_number vector);
static rtems_isr default_interrupt_handler(rtems_vector_number vector);
static rtems_isr spurious_interrupt_handler(rtems_vector_number vector);
static rtems_isr_entry handlers[NUMBER_INTERRUPTS];
static int *vec_prio_reg_addresses[NUMBER_INTERRUPTS] = {0};
static void *raven_base = 0;
static int timer_frequency = 0;
rtems_status_code interrupt_controller_init(void) {
int i;
int raven_config = pci_find_by_devid(RAVEN_VENDOR_ID, RAVEN_DEVICE_ID, 0);
rtems_isr_entry old_handler;
rtems_status_code sc;
/* get base address of raven registers in LOCAL space */
raven_base =
(void *)PCI_TO_LOCAL(pci_conf_read32(raven_config, PCI_BASE_ADDRESS_1));
/* set cascade mode in global configuration register */
st_le32(raven_base + 0x01020, 0x20000000);
/* set spurious interrupt vector */
st_le32(raven_base + 0x010e0, IRQ_SPURIOUS);
/* get the timer frequency */
timer_frequency = ld_le32(raven_base + 0x010f0);
/* fill in vector/priority register addresses */
vec_prio_reg_addresses[IRQ_PIC_CASCADE] = raven_base + 0x10000;
vec_prio_reg_addresses[IRQ_FALCON_ECC] = raven_base + 0x10020;
vec_prio_reg_addresses[IRQ_ETHERNET] = raven_base + 0x10040;
vec_prio_reg_addresses[IRQ_VME_LINT0] = raven_base + 0x100a0;
vec_prio_reg_addresses[IRQ_VME_LINT1] = raven_base + 0x100c0;
vec_prio_reg_addresses[IRQ_VME_LINT2] = raven_base + 0x100e0;
vec_prio_reg_addresses[IRQ_VME_LINT3] = raven_base + 0x10100;
vec_prio_reg_addresses[IRQ_PMC1A_PMC2B] = raven_base + 0x10120;
vec_prio_reg_addresses[IRQ_PMC1B_PMC2C] = raven_base + 0x10140;
vec_prio_reg_addresses[IRQ_PMC1C_PMC2D] = raven_base + 0x10160;
vec_prio_reg_addresses[IRQ_PMC1D_PMC2A] = raven_base + 0x10180;
vec_prio_reg_addresses[IRQ_LM_SIG_0] = raven_base + 0x101a0;
vec_prio_reg_addresses[IRQ_LM_SIG_1] = raven_base + 0x101c0;
vec_prio_reg_addresses[IRQ_TIMER_0] = raven_base + 0x01120;
vec_prio_reg_addresses[IRQ_TIMER_1] = raven_base + 0x01160;
vec_prio_reg_addresses[IRQ_TIMER_2] = raven_base + 0x011a0;
vec_prio_reg_addresses[IRQ_TIMER_3] = raven_base + 0x011e0;
vec_prio_reg_addresses[IRQ_IPI_0] = raven_base + 0x010a0;
vec_prio_reg_addresses[IRQ_IPI_1] = raven_base + 0x010b0;
vec_prio_reg_addresses[IRQ_IPI_2] = raven_base + 0x010c0;
vec_prio_reg_addresses[IRQ_IPI_3] = raven_base + 0x010d0;
vec_prio_reg_addresses[IRQ_RAVEN_ERROR] = raven_base + 0x10200;
/* initialize all vector/priority registers to level 0, disabled */
for (i = 0; i < NUMBER_INTERRUPTS; i++) {
if (vec_prio_reg_addresses[i]) {
st_le32(vec_prio_reg_addresses[i], DISABLE_IRQ | i);
}
}
/* initialize all interrupt destination registers to processor 0 */
st_le32(raven_base + 0x01130, 1);
st_le32(raven_base + 0x01170, 1);
st_le32(raven_base + 0x011b0, 1);
st_le32(raven_base + 0x011f0, 1);
st_le32(raven_base + 0x10010, 1);
st_le32(raven_base + 0x10030, 1);
st_le32(raven_base + 0x10050, 1);
st_le32(raven_base + 0x10070, 1);
st_le32(raven_base + 0x10090, 1);
st_le32(raven_base + 0x100b0, 1);
st_le32(raven_base + 0x100d0, 1);
st_le32(raven_base + 0x100f0, 1);
st_le32(raven_base + 0x10110, 1);
st_le32(raven_base + 0x10130, 1);
st_le32(raven_base + 0x10150, 1);
st_le32(raven_base + 0x10170, 1);
st_le32(raven_base + 0x10190, 1);
st_le32(raven_base + 0x101b0, 1);
st_le32(raven_base + 0x101d0, 1);
st_le32(raven_base + 0x101f0, 1);
st_le32(raven_base + 0x10210, 1);
/* set up default interrupt handlers */
for (i = 0; i < NUMBER_INTERRUPTS; i++) {
handlers[i] = default_interrupt_handler;
}
handlers[IRQ_SPURIOUS] = spurious_interrupt_handler;
/* enable 8259 PIC interrupt at level 8 */
st_le32(vec_prio_reg_addresses[IRQ_PIC_CASCADE],
0x00c00000 | (PRIORITY_ISA_INT << 16) | IRQ_PIC_CASCADE);
/* attach interrupt handler and enable interrupts */
sc = rtems_interrupt_catch(raven_interrupt_handler, PPC_IRQ_EXTERNAL,
&old_handler);
if (sc != RTEMS_SUCCESSFUL) {
rtems_panic("can't catch interrupt for raven pic\n");
}
return set_interrupt_task_priority(0);
}
#define PCI_Interrupt_Ack_Addr ((unsigned32 *) 0xFEFF0030)
#define NonspecificEOI 0x20
#define PIC1_OCW2 (*(volatile char *)IO_TO_LOCAL(0x20))
#define PIC2_OCW2 (*(volatile char *)IO_TO_LOCAL(0xA0))
static rtems_isr raven_interrupt_handler(rtems_vector_number vector) {
int raven_vector;
int msr_value;
/* read Raven interrupt acknowledge register */
raven_vector = ld_le32(raven_base + 0x200a0);
if (raven_vector == IRQ_PIC_CASCADE) {
/* read PCI interrupt acknowledge register */
int piack_image = ld_le32(PCI_Interrupt_Ack_Addr);
int isa_vector = piack_image & 0x07;
int pic_id = (piack_image >> 3) & 0x1f;
if (pic_id == 0x10) {
isa_vector += 8;
} else if (pic_id != 0x01) {
rtems_panic("unrecognized PIACK value: %08x\n", piack_image);
}
/* set MSRee = 1 */
_CPU_MSR_Value(msr_value);
msr_value |= PPC_MSR_EE;
_CPU_MSR_SET(msr_value);
/* signal EOI to Raven */
st_le32(raven_base + 0x200b0, 0);
/* call handler */
handlers[isa_vector](isa_vector);
/* signal EOI to 8259 PIC */
PIC1_OCW2 = NonspecificEOI;
if (isa_vector >= 8) {
PIC2_OCW2 = NonspecificEOI;
}
} else {
/* set MSRee = 1 */
_CPU_MSR_Value(msr_value);
msr_value |= PPC_MSR_EE;
_CPU_MSR_SET(msr_value);
/* call handler */
handlers[raven_vector](raven_vector);
/* signal EOI to Raven */
st_le32(raven_base + 0x200b0, 0);
}
}
static rtems_isr default_interrupt_handler(rtems_vector_number vector) {
rtems_panic("unhandled interrupt: %d\n", vector);
}
static rtems_isr spurious_interrupt_handler(rtems_vector_number vector) {
rtems_panic("spurious interrupt\n");
}
rtems_status_code bsp_interrupt_catch(rtems_isr_entry new_isr_handler,
rtems_vector_number vector,
rtems_isr_entry *old_isr_handler) {
if (!old_isr_handler || ((int)new_isr_handler & 3) != 0) {
return RTEMS_INVALID_ADDRESS;
}
switch (vector) {
case IRQ_ISA_TIMER: case IRQ_UART: case IRQ_ISA_LM_SIG:
case IRQ_ABORT_SWITCH: case IRQ_ISA_ETHERNET: case IRQ_ISA_UNIVERSE:
case IRQ_ISA_PMC_PCIX: case IRQ_FALCON_ECC: case IRQ_ETHERNET:
case IRQ_VME_LINT0: case IRQ_VME_LINT1: case IRQ_VME_LINT2:
case IRQ_VME_LINT3: case IRQ_PMC1A_PMC2B: case IRQ_PMC1B_PMC2C:
case IRQ_PMC1C_PMC2D: case IRQ_PMC1D_PMC2A: case IRQ_LM_SIG_0:
case IRQ_LM_SIG_1: case IRQ_TIMER_0: case IRQ_TIMER_1:
case IRQ_TIMER_2: case IRQ_TIMER_3: case IRQ_IPI_0:
case IRQ_IPI_1: case IRQ_IPI_2: case IRQ_IPI_3:
case IRQ_RAVEN_ERROR:
*old_isr_handler = handlers[vector];
handlers[vector] = new_isr_handler;
return RTEMS_SUCCESSFUL;
default:
return RTEMS_INVALID_NUMBER;
}
}
#define PIC1_Mask (*(unsigned8 *) IO_TO_LOCAL(0x21))
#define PIC2_Mask (*(unsigned8 *) IO_TO_LOCAL(0xA1))
rtems_status_code bsp_interrupt_enable(rtems_vector_number vector,
int priority) {
switch (vector) {
case IRQ_ISA_TIMER: case IRQ_UART: case IRQ_ISA_LM_SIG:
case IRQ_ABORT_SWITCH: case IRQ_ISA_ETHERNET: case IRQ_ISA_UNIVERSE:
case IRQ_ISA_PMC_PCIX:
if (priority != PRIORITY_ISA_INT) {
return RTEMS_INVALID_NUMBER;
}
if (vector < 8) {
PIC1_Mask &= ~ (1 << vector);
} else {
PIC2_Mask &= ~ (1 << (vector - 8));
}
return RTEMS_SUCCESSFUL;
case IRQ_ETHERNET: case IRQ_VME_LINT0: case IRQ_VME_LINT1:
case IRQ_VME_LINT2: case IRQ_VME_LINT3: case IRQ_PMC1A_PMC2B:
case IRQ_PMC1B_PMC2C: case IRQ_PMC1C_PMC2D: case IRQ_PMC1D_PMC2A:
case IRQ_LM_SIG_0: case IRQ_LM_SIG_1:
if (priority & ~15) {
return RTEMS_INVALID_NUMBER;
}
st_le32(vec_prio_reg_addresses[vector],
0x00400000 | (priority << 16) | vector);
return RTEMS_SUCCESSFUL;
case IRQ_FALCON_ECC: case IRQ_TIMER_0: case IRQ_TIMER_1:
case IRQ_TIMER_2: case IRQ_TIMER_3: case IRQ_IPI_0:
case IRQ_IPI_1: case IRQ_IPI_2: case IRQ_IPI_3:
case IRQ_RAVEN_ERROR:
if (priority & ~15) {
return RTEMS_INVALID_NUMBER;
}
st_le32(vec_prio_reg_addresses[vector], (priority << 16) | vector);
return RTEMS_SUCCESSFUL;
default:
return RTEMS_INVALID_NUMBER;
}
}
rtems_status_code bsp_interrupt_disable(rtems_vector_number vector) {
switch (vector) {
case IRQ_ISA_TIMER: case IRQ_UART: case IRQ_ISA_LM_SIG:
case IRQ_ABORT_SWITCH: case IRQ_ISA_ETHERNET: case IRQ_ISA_UNIVERSE:
case IRQ_ISA_PMC_PCIX:
if (vector < 8) {
PIC1_Mask |= (1 << vector);
} else {
PIC2_Mask |= (1 << (vector - 8));
}
return RTEMS_SUCCESSFUL;
case IRQ_FALCON_ECC: case IRQ_ETHERNET: case IRQ_VME_LINT0:
case IRQ_VME_LINT1: case IRQ_VME_LINT2: case IRQ_VME_LINT3:
case IRQ_PMC1A_PMC2B: case IRQ_PMC1B_PMC2C: case IRQ_PMC1C_PMC2D:
case IRQ_PMC1D_PMC2A: case IRQ_LM_SIG_0: case IRQ_LM_SIG_1:
case IRQ_TIMER_0: case IRQ_TIMER_1: case IRQ_TIMER_2:
case IRQ_TIMER_3: case IRQ_IPI_0: case IRQ_IPI_1:
case IRQ_IPI_2: case IRQ_IPI_3: case IRQ_RAVEN_ERROR:
st_le32(vec_prio_reg_addresses[vector], DISABLE_IRQ | vector);
return RTEMS_SUCCESSFUL;
default:
return RTEMS_INVALID_NUMBER;
}
}
rtems_status_code bsp_start_timer(int timer, int period_usec) {
double counts = (double)period_usec * timer_frequency / 1.0e6 + 0.5;
if (counts < 1.0 || counts > (double)0x7fffffff) {
return RTEMS_INVALID_NUMBER;
}
switch (timer) {
case 0:
st_le32(raven_base + 0x01110, (int)counts);
break;
case 1:
st_le32(raven_base + 0x01150, (int)counts);
break;
case 2:
st_le32(raven_base + 0x01190, (int)counts);
break;
case 3:
st_le32(raven_base + 0x011d0, (int)counts);
break;
default:
return RTEMS_INVALID_NUMBER;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_stop_timer(int timer) {
switch (timer) {
case 0:
st_le32(raven_base + 0x01110, 0x80000000);
break;
case 1:
st_le32(raven_base + 0x01150, 0x80000000);
break;
case 2:
st_le32(raven_base + 0x01190, 0x80000000);
break;
case 3:
st_le32(raven_base + 0x011d0, 0x80000000);
break;
default:
return RTEMS_INVALID_NUMBER;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_read_timer(int timer, int *value) {
switch (timer) {
case 0:
*value = ld_le32(raven_base + 0x01100) & 0x7fffffff;
break;
case 1:
*value = ld_le32(raven_base + 0x01140) & 0x7fffffff;
break;
case 2:
*value = ld_le32(raven_base + 0x01180) & 0x7fffffff;
break;
case 3:
*value = ld_le32(raven_base + 0x011c0) & 0x7fffffff;
break;
default:
return RTEMS_INVALID_NUMBER;
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code generate_interprocessor_interrupt(int interrupt) {
int *dispatch_reg = raven_base + 0x20040;
if (interrupt & ~3) {
return RTEMS_INVALID_NUMBER;
}
dispatch_reg[interrupt << 2] = 1;
return RTEMS_SUCCESSFUL;
}
rtems_status_code set_interrupt_task_priority(int priority) {
if (priority & ~15) {
return RTEMS_INVALID_NUMBER;
}
st_le32(raven_base + 0x20080, priority);
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,70 @@
#include <bsp.h>
#define PCI_Interrupt_Ack (*(volatile unsigned32 *) 0xFEFF0030)
#define PIC1_OCW2 (*(volatile char *)IO_TO_LOCAL(0x0020))
#define PIC2_OCW2 (*(volatile char *)IO_TO_LOCAL(0x00A0))
#define NonspecificEOI 0x20
#define Master_PIC_Mask (*(unsigned8 *) IO_TO_LOCAL(0x0021))
#define Slave_PIC_Mask (*(unsigned8 *) IO_TO_LOCAL(0x00A1))
rtems_isr_entry isa_handlers[16] = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
rtems_status_code isa_interrupt_enable(rtems_vector_number vector) {
if (vector < 0 || vector > 15 || vector == 2) {
return RTEMS_INVALID_NUMBER;
}
if (vector < 8) {
Master_PIC_Mask &= ~ (1 << vector);
} else {
Slave_PIC_Mask &= ~ (1 << (vector - 8));
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code isa_interrupt_disable(rtems_vector_number vector) {
if (vector < 0 || vector > 15 || vector == 2) {
return RTEMS_INVALID_NUMBER;
}
if (vector < 8) {
Master_PIC_Mask |= (1 << vector);
} else {
Slave_PIC_Mask |= (1 << (vector - 8));
}
return RTEMS_SUCCESSFUL;
}
rtems_status_code isa_interrupt_catch(rtems_isr_entry new_isr_handler,
rtems_vector_number vector,
rtems_isr_entry *old_isr_handler) {
if (vector < 0 || vector > 15 || vector == 2) {
return RTEMS_INVALID_NUMBER;
}
if (!old_isr_handler || ((int)new_isr_handler & 3) != 0) {
return RTEMS_INVALID_ADDRESS;
}
*old_isr_handler = isa_handlers[vector];
isa_handlers[vector] = new_isr_handler;
return RTEMS_SUCCESSFUL;
}
rtems_isr isa_interrupt_handler(rtems_vector_number vector) {
unsigned32 piack_image = PCI_Interrupt_Ack;
int pic_id = piack_image >> 27;
rtems_vector_number isa_vector = (piack_image >> 24) & 7;
if (pic_id == 0x10) {
isa_vector += 8;
} else if (pic_id != 0x01) {
printk("unrecognized PIACK value: %08x\n", piack_image);
return;
}
if (isa_handlers[isa_vector] != 0) {
isa_handlers[isa_vector](isa_vector);
}
PIC1_OCW2 = NonspecificEOI;
if (isa_vector >= 8) {
PIC2_OCW2 = NonspecificEOI;
}
}

View File

@@ -0,0 +1,87 @@
#include <bsp.h>
static const void *PciConfAddr = IO_TO_LOCAL(0x0cf8);
static const void *PciConfData = IO_TO_LOCAL(0x0cfc);
int pci_make_devsig(int bus, int device, int function) {
return ((bus & 255) << 16) | ((device & 31) << 11) |
((function & 7) << 8) | 0x80000000;
}
int pci_conf_read8(int sig, int off) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
return *(unsigned char *)(PciConfData + (off & 3));
}
int pci_conf_read16(int sig, int off) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
return ld_le16(PciConfData + (off & 3));
}
int pci_conf_read32(int sig, int off) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
return ld_le32(PciConfData);
}
void pci_conf_write8(int sig, int off, unsigned int data) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
*(unsigned char *)(PciConfData + (off & 3)) = data;
}
void pci_conf_write16(int sig, int off, unsigned int data) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
st_le16(PciConfData + (off & 3), data);
}
void pci_conf_write32(int sig, int off, unsigned int data) {
st_le32(PciConfAddr, sig + (off & 252));
synchronize_io();
st_le32(PciConfData + (off & 3), data);
}
static int recursive_find(int bus, int devid_venid, int idx, int *count) {
int devsig, dev, func, max_func, idreg, class, secondary_bus;
char header_type;
for (dev = 0; dev < 32; dev++) {
devsig = pci_make_devsig(bus, dev, 0);
header_type = pci_conf_read8(devsig, 0x0e);
max_func = (header_type & 0x80) ? 8 : 1; /* multi-function device? */
for (func = 0; func < max_func; func++) {
devsig = pci_make_devsig(bus, dev, func);
idreg = pci_conf_read32(devsig, 0x00);
if (idreg == 0xffffffff) {
break; /* empty slot */
}
if (idreg == devid_venid) {
/* id's match - is it the right instance? */
if (*count == idx) {
return devsig;
} else {
(*count)++;
}
}
class = pci_conf_read32(devsig, 0x08) & 0xffff0000;
if (class == 0x06040000) { /* pci-pci bridge? */
secondary_bus = pci_conf_read8(devsig, 0x19);
devsig = recursive_find(secondary_bus, devid_venid, idx, count);
if (devsig != PCI_NOT_FOUND) {
return devsig;
}
}
}
}
return PCI_NOT_FOUND;
}
int pci_find_by_devid(int vendorId, int devId, int idx) {
int count = 0;
int devid_venid = ((devId << 16) & 0xffff0000) | (vendorId & 0xffff);
return recursive_find(0, devid_venid, idx, &count);
}

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/shmsupp
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/shmsupp.rel
# C source names, if any, go here -- minus the .c
C_PIECES=addrconv getcfg lock mpisr
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,31 @@
/* Shm_Convert_address
*
* No address range conversion is required.
*
* Input parameters:
* address - address to convert
*
* Output parameters:
* returns - converted address
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
void *Shm_Convert_address(
void *address
)
{
return ( address );
}

View File

@@ -0,0 +1,77 @@
/* void Shm_Get_configuration( localnode, &shmcfg )
*
* This routine initializes, if necessary, and returns a pointer
* to the Shared Memory Configuration Table for the XXX target.
*
* INPUT PARAMETERS:
* localnode - local node number
* shmcfg - address of pointer to SHM Config Table
*
* OUTPUT PARAMETERS:
* *shmcfg - pointer to SHM Config Table
*
XXX: FIX THE COMMENTS BELOW WHEN THE CPU IS KNOWN
* NOTES: The XYZ does not have an interprocessor interrupt.
*
* The following table illustrates the configuration limitations:
*
* BUS MAX
* MODE ENDIAN NODES
* ========= ====== =======
* POLLED BIG 2+
* INTERRUPT **** NOT SUPPORTED ****
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
/*
* configured if currently polling of interrupt driven
*/
#define INTERRUPT 0 /* XXX: */
#define POLLING 1 /* XXX: fix me -- is polling ONLY!!! */
shm_config_table BSP_shm_cfgtbl;
void Shm_Get_configuration(
rtems_unsigned32 localnode,
shm_config_table **shmcfg
)
{
BSP_shm_cfgtbl.base = 0x0;
BSP_shm_cfgtbl.length = 1 * MEGABYTE;
BSP_shm_cfgtbl.format = SHM_BIG;
/*
* Override cause_intr or shm_isr if your target has
* special requirements.
*/
BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt;
#ifdef NEUTRAL_BIG
BSP_shm_cfgtbl.convert = NULL_CONVERT;
#else
BSP_shm_cfgtbl.convert = CPU_swap_u32;
#endif
BSP_shm_cfgtbl.poll_intr = POLLED_MODE;
BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT;
BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT;
*shmcfg = &BSP_shm_cfgtbl;
}

View File

@@ -0,0 +1,86 @@
/* Shared Memory Lock Routines
*
* This shared memory locked queue support routine need to be
* able to lock the specified locked queue. Interrupts are
* disabled while the queue is locked to prevent preemption
* and deadlock when two tasks poll for the same lock.
* previous level.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
/*
* Shm_Initialize_lock
*
* Initialize the lock for the specified locked queue.
*/
void Shm_Initialize_lock(
Shm_Locked_queue_Control *lq_cb
)
{
lq_cb->lock = LQ_UNLOCKED;
}
/* void _Shm_Lock( &lq_cb )
*
* This shared memory locked queue support routine locks the
* specified locked queue. It disables interrupts to prevent
* a deadlock condition.
*/
void Shm_Lock(
Shm_Locked_queue_Control *lq_cb
)
{
rtems_unsigned32 isr_level;
rtems_unsigned32 *lockptr = (rtems_unsigned32 *) &lq_cb->lock;
rtems_unsigned32 lock_value;
lock_value = 0x80000000;
rtems_interrupt_disable( isr_level );
Shm_isrstat = isr_level;
while ( lock_value ) {
asm volatile( ""
: "=r" (lockptr), "=r" (lock_value)
: "0" (lockptr), "1" (lock_value)
);
/*
* If not available, then may want to delay to reduce load on lock.
*/
if ( lock_value )
delay( 10 ); /* approximately 10 microseconds */
}
}
/*
* Shm_Unlock
*
* Unlock the lock for the specified locked queue.
*/
void Shm_Unlock(
Shm_Locked_queue_Control *lq_cb
)
{
rtems_unsigned32 isr_level;
lq_cb->lock = SHM_UNLOCK_VALUE;
isr_level = Shm_isrstat;
rtems_interrupt_enable( isr_level );
}

View File

@@ -0,0 +1,47 @@
/* Shm_isr_nobsp()
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <shm.h>
rtems_isr Shm_isr_nobsp( void )
{
/*
* If this routine has to do anything other than the mpisr.c
* found in the generic driver, then copy the contents of the generic
* mpisr.c and augment it to satisfy this particular board. Typically,
* you need to have a board specific mpisr.c when the interrupt
* must be cleared.
*
* If the generic mpisr.c satisifies your requirements, then
* remove this routine from your target's shmsupp/mpisb.c file.
* Then simply install the generic Shm_isr in the Shm_setvec
* routine below.
*/
}
/* Shm_setvec
*
* This driver routine sets the SHM interrupt vector to point to the
* driver's SHM interrupt service routine.
*
* Input parameters: NONE
*
* Output parameters: NONE
*/
void Shm_setvec( void )
{
/* XXX: FIX ME!!! */
}

View File

@@ -0,0 +1,71 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/startup
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@:@srcdir@/../../../shared
PGM=${ARCH}/startup.rel
# C source names, if any, go here -- minus the .c
C_PIECES=bspclean bsplibc bsppost bspstart main sbrk setvec
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=linkcmds $(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
$(INSTALL_CHANGE) $(srcdir)/linkcmds $(PROJECT_RELEASE)/lib
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,31 @@
/* bsp_cleanup()
*
* This routine normally is part of start.s and usually returns
* control to a monitor.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/score/cpu.h>
#include <bsp.h>
void bsp_cleanup( void )
{
/* disable raven interrupts */
set_interrupt_task_priority(15);
/* exit to PPCBUG */
asm volatile ( "li 10,99; sc" : : : "r10");
}

View File

@@ -0,0 +1,159 @@
/*
* This set of routines starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before any of these are invoked.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* All rights assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <libcsupport.h>
#include <string.h>
#include <fcntl.h>
/*
* The original table from the application and our copy of it with
* some changes.
*/
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
/*
* Use the shared implementations of the following routines
*/
void bsp_postdriver_hook(void);
void bsp_libc_init( void *, unsigned32, int );
/*
* bsp_pretasking_hook
*
* BSP pretasking hook. Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*/
void bsp_pretasking_hook(void)
{
extern int end;
rtems_unsigned32 heap_start;
rtems_unsigned32 heap_size;
rtems_isr_entry old_handler;
rtems_status_code sc;
heap_start = (rtems_unsigned32) &end;
if (heap_start & (CPU_ALIGNMENT-1)) {
heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
}
heap_size = BSP_Configuration.work_space_start - (void *)&end;
heap_size &= 0xfffffff0; /* keep it as a multiple of 16 bytes */
bsp_libc_init((void *) heap_start, heap_size, 0);
sc = interrupt_controller_init();
#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 )
{
unsigned char *work_space_start;
unsigned32 RAM_end = 0;
#if 1
/*
* Set MSR to show vectors at 0 XXX
*/
rtems_unsigned32 msr_value;
_CPU_MSR_Value( msr_value );
msr_value &= ~PPC_MSR_EP;
_CPU_MSR_SET( msr_value );
#endif
/*
* Set up our hooks
* Make sure libc_init is done before drivers initialized so that
* they can use atexit()
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
Cpu_table.interrupt_stack_size = (12 * 1024);
/*
* The monitor likes the exception table to be at 0x0.
*/
Cpu_table.exceptions_in_RAM = TRUE;
/*
#if defined(RTEMS_POSIX_API)
BSP_Configuration.work_space_size *= 3;
#endif
*/
/* from PSIM - why? */
BSP_Configuration.work_space_size += 1024;
/* determine memory size */
switch (Falcon_MEMCR.MemSize) {
case RAM_16_MB:
RAM_end = 16 * 1024 * 1024;
break;
case RAM_32_MB:
RAM_end = 32 * 1024 * 1024;
break;
case RAM_64_MB:
RAM_end = 64 * 1024 * 1024;
break;
case RAM_128_MB:
RAM_end = 128 * 1024 * 1024;
break;
}
RAM_end -= 1024 * 1024; /* reserve memory for PPCBUG */
work_space_start =
(unsigned char *)RAM_end - BSP_Configuration.work_space_size;
if ( work_space_start <= (unsigned char *)&end ) {
printk( "bspstart: Not enough RAM!!!\n" );
bsp_cleanup();
}
BSP_Configuration.work_space_start = work_space_start;
/*
* Account for the console's resources
*/
console_reserve_resources( &BSP_Configuration );
}

View File

@@ -0,0 +1,201 @@
/*
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(_start)
/*SEARCH_DIR(/usr1/gnu/cross/powerpc-unknown-eabi//powerpc-unknown-eabi/lib); */
/* Do we need any of these for elf?
__DYNAMIC = 0; */
MEMORY
{
/* VECTORS : ORIGIN = 0x0, LENGTH = 0x4000 */
/* reserve top 1M for PPCBUG */
RAM : ORIGIN = 0x4000, LENGTH = 63M - 0x4000
}
SECTIONS
{
/*
PROVIDE(ppcbug_reset = 0xfff04000);
PROVIDE(ppcbug_general = 0xfff04120);
.vectors 0x00000100 :
{
*(.vectors)
} >VECTORS
*/
/* Read-only sections, merged into text segment: */
/* . = 0x40000 + SIZEOF_HEADERS; */
. = 0x4000;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rela.text : { *(.rela.text) }
.rela.data : { *(.rela.data) }
.rela.rodata : { *(.rela.rodata) }
.rela.got : { *(.rela.got) }
.rela.got1 : { *(.rela.got1) }
.rela.got2 : { *(.rela.got2) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.init : { *(.rela.init) }
.rela.fini : { *(.rela.fini) }
.rela.bss : { *(.rela.bss) }
.rela.plt : { *(.rela.plt) }
.rela.sdata : { *(.rela.sdata2) }
.rela.sbss : { *(.rela.sbss2) }
.rela.sdata2 : { *(.rela.sdata2) }
.rela.sbss2 : { *(.rela.sbss2) }
.plt : { *(.plt) }
.text :
{
PROVIDE (__text_start = .);
*(.text)
*(.gnu.linkonce.t.*)
*(.descriptors)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} >RAM
.init : { *(.init) } >RAM
.fini : { *(.fini) } >RAM
.rodata : { *(.rodata) *(.gnu.linkonce.r*) } >RAM
.rodata1 : { *(.rodata1) } >RAM
_etext = .;
PROVIDE (etext = .);
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) } >RAM
.sbss2 : { *(.sbss2) } >RAM
PROVIDE (__SBSS2_END__ = .);
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
/* . = ALIGN(8) + 0x40000; */
.data :
{
*(.data)
*(.gnu.linkonce.d.*)
CONSTRUCTORS
} >RAM
PROVIDE (__EXCEPT_START__ = .);
.gcc_except_table : { *(.gcc_except_table) } >RAM
PROVIDE (__EXCEPT_END__ = .);
.data1 : { *(.data1) } >RAM
.got1 : { *(.got1) } >RAM
.dynamic : { *(.dynamic) } >RAM
/* Put .ctors and .dtors next to the .got2 section, so that the pointers
get relocated with -mrelocatable. Also put in the .fixup pointers.
The current compiler no longer needs this, but keep it around for 2.7.2 */
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
.got2 : { *(.got2) } >RAM
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__CTOR_LIST__ = .);
.ctors : { *(.ctors) } >RAM
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
.dtors : { *(.dtors) } >RAM
PROVIDE (__DTOR_END__ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
.fixup : { *(.fixup) } >RAM
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
PROVIDE (__GOT_START__ = .);
PROVIDE (_GOT_START_ = .);
s.got = .;
.got : { *(.got) } >RAM
.got.plt : { *(.got.plt) } >RAM
PROVIDE (_GOT_END_ = .);
PROVIDE (__GOT_END__ = .);
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
PROVIDE (__SDATA_START__ = .);
.sdata : { *(.sdata) } >RAM
_edata = .;
PROVIDE (edata = .);
PROVIDE (RAM_END = 0x3f0000);
.sbss :
{
PROVIDE (__sbss_start = .);
*(.sbss)
*(.scommon)
PROVIDE (__sbss_end = .);
} >RAM
PROVIDE (__SBSS_END__ = .);
.bss :
{
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss)
*(COMMON)
} >RAM
. = ALIGN(8) + 0x8000;
PROVIDE(__stack = .);
PROVIDE (_end = .);
PROVIDE (end = .);
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,108 @@
/*
* A simple main which can be used on any embedded target.
*
* This style of initialization insures that the C++ global
* constructors are executed after RTEMS is initialized.
*
* Thanks to Chris Johns <cjohns@plessey.com.au> for this idea.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
char *rtems_progname;
extern void bsp_start( void );
extern void bsp_cleanup( void );
extern rtems_configuration_table Configuration;
extern rtems_configuration_table BSP_Configuration;
extern rtems_cpu_table Cpu_table;
rtems_interrupt_level bsp_isr_level;
int main(int argc, char **argv);
int boot_card(int argc, char **argv)
{
int status;
/*
* Set default values for the CPU Table fields all ports must have.
* These values can be overridden in bsp_start() but they are
* right most of the time.
*/
Cpu_table.pretasking_hook = NULL;
Cpu_table.predriver_hook = NULL;
Cpu_table.postdriver_hook = NULL;
Cpu_table.idle_task = NULL;
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_stack_size = RTEMS_MINIMUM_STACK_SIZE;
Cpu_table.extra_mpci_receive_server_stack = 0;
Cpu_table.stack_allocate_hook = NULL;
Cpu_table.stack_free_hook = NULL;
/*
* Copy the configuration table so we and the BSP wants to change it.
*/
BSP_Configuration = Configuration;
/*
* The atexit hook will be before the static destructor list's entry
* point.
*/
bsp_start();
/*
* Initialize RTEMS but do NOT start multitasking.
*/
bsp_isr_level =
rtems_initialize_executive_early( &BSP_Configuration, &Cpu_table );
/*
* Call main() and get the global constructors invoked if there
* are any.
*/
status = main(argc, argv);
/*
* Perform any BSP specific shutdown actions.
*/
bsp_cleanup();
/*
* Now return to the start code.
*/
return status;
}
int main(int argc, char **argv)
{
if ((argc > 0) && argv && argv[0])
rtems_progname = argv[0];
else
rtems_progname = "RTEMS";
rtems_initialize_executive_late( bsp_isr_level );
return 0;
}

View File

@@ -0,0 +1,58 @@
/* 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-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $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;
}

View File

@@ -0,0 +1,70 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/timer
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
PGM=${ARCH}/timer.rel
# C source names, if any, go here -- minus the .c
C_PIECES=timer
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
H_FILES=
# Assembly source names, if any, go here -- minus the .S
S_PIECES=
S_FILES=$(S_PIECES:%=%.S)
S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/leaf.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${PGM}: ${SRCS} ${OBJS}
$(make-rel)
all: ${ARCH} $(SRCS) $(PGM)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
install: all
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -0,0 +1,91 @@
/* timer.c
*
* This file manages the benchmark timer used by the RTEMS Timing Test
* Suite. Each measured time period is demarcated by calls to
* Timer_initialize() and Read_timer(). Read_timer() usually returns
* the number of microseconds since Timer_initialize() exitted.
*
* This version returns the number of nanoseconds since Timer_initialize()
* exited, since the '604 is very fast at 300MHz. Actual resolution is
* 60 nsec.
*
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
rtems_unsigned32 Timer_start;
rtems_boolean Timer_driver_Find_average_overhead;
void Timer_initialize( void )
{
rtems_unsigned32 clicks;
asm volatile ("mfspr %0,268" : "=r" (clicks) :);
Timer_start = clicks;
}
/*
* The following controls the behavior of Read_timer().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 7 /* On average, it takes 7.4 nanoseconds */
/* (Y countdowns) to start/stop the timer. */
#define NSEC_PER_TICK 60
int Read_timer( void )
{
rtems_unsigned32 clicks;
rtems_unsigned32 total;
/*
* Read the timer and see how many clicks it has been since we started.
* Timer overflows every 257 seconds, so multiple overflows are deemed
* impossible.
*/
asm volatile ("mfspr %0,268" : "=r" (clicks) :);
total = (clicks - Timer_start);
if ( Timer_driver_Find_average_overhead == 1 ) {
return total * NSEC_PER_TICK; /* in nanoseconds */
} else {
/*
* convert total into nanoseconds
*/
return total * NSEC_PER_TICK - AVG_OVERHEAD;
}
}
/*
* Empty function call used in loops to measure basic cost of looping
* in Timing Test Suite.
*/
rtems_status_code Empty_function( void ) {
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(rtems_boolean find_flag) {
Timer_driver_Find_average_overhead = find_flag;
}

View File

@@ -0,0 +1,191 @@
#
# Timing Test Suite Results for the mvme2307 bsp
#
#
Board: Motorola MVME2307
CPU: MPC604
Clock Speed: 300MHz
Memory Configuration: 64MB, ECC Enabled (ECC-Memory Detected)
L2Cache: NONE
Wait States:
Times Reported in: microseconds
Timer Source: on-CPU cycle counter
Column X:
Column Y:
# DESCRIPTION A
== ================================================================= =========
1 rtems_semaphore_create 16.493
rtems_semaphore_delete 16.673
rtems_semaphore_obtain: available 10.381
rtems_semaphore_obtain: not available -- NO_WAIT 10.383
rtems_semaphore_release: no waiting tasks 12.071
2 rtems_semaphore_obtain: not available -- caller blocks 31.929
3 rtems_semaphore_release: task readied -- preempts caller 26.442
4 rtems_task_restart: blocked task -- preempts caller 46.073
rtems_task_restart: ready task -- preempts caller 41.153
rtems_semaphore_release: task readied -- returns to caller 16.709
rtems_task_create 50.860
rtems_task_start 20.581
rtems_task_restart: suspended task -- returns to caller 23.807
rtems_task_delete: suspended task 39.714
rtems_task_restart: ready task -- returns to caller 24.737
rtems_task_restart: blocked task -- returns to caller 28.471
rtems_task_delete: blocked task 41.008
5 rtems_task_suspend: calling task 25.204
rtems_task_resume: task readied -- preempts caller 22.296
6 rtems_task_restart: calling task 30.990
rtems_task_suspend: returns to caller 11.582
rtems_task_resume: task readied -- returns to caller 12.620
rtems_task_delete: ready task 40.913
7 rtems_task_restart: suspended task -- preempts caller 38.087
8 rtems_task_set_priority: obtain current priority 9.727
rtems_task_set_priority: returns to caller 17.030
rtems_task_mode: obtain current mode 3.768
rtems_task_mode: no reschedule 3.766
rtems_task_mode: reschedule -- returns to caller 5.933
rtems_task_mode: reschedule -- preempts caller 22.613
rtems_task_set_note 10.115
rtems_task_get_note 10.236
rtems_clock_set 21.466
rtems_clock_get 2.286
9 rtems_message_queue_create 40.373
rtems_message_queue_send: no waiting tasks 20.370
rtems_message_queue_urgent: no waiting tasks 20.397
rtems_message_queue_receive: available 17.799
rtems_message_queue_flush: no messages flushed 9.405
rtems_message_queue_flush: messages flushed 10.945
rtems_message_queue_delete 19.673
10 rtems_message_queue_receive: not available -- NO_WAIT 11.778
rtems_message_queue_receive: not available -- caller blocks 32.770
11 rtems_message_queue_send: task readied -- preempts caller 33.719
12 rtems_message_queue_send: task readied -- returns to caller 23.653
13 rtems_message_queue_urgent: task readied -- preempts caller 33.713
14 rtems_message_queue_urgent: task readied -- returns to caller 23.651
15 rtems_event_receive: obtain current events 1.275
rtems_event_receive: not available -- NO_WAIT 9.193
rtems_event_receive: not available -- caller blocks 27.196
rtems_event_send: no task readied 9.437
rtems_event_receive: available 9.653
rtems_event_send: task readied -- returns to caller 15.845
16 rtems_event_send: task readied -- preempts caller 26.008
17 rtems_task_set_priority: preempts caller 30.872
18 rtems_task_delete: calling task 53.748
19 rtems_signal_catch 7.253
rtems_signal_send: returns to caller 11.993
rtems_signal_send: signal to self 17.633
exit ASR overhead: returns to calling task 14.933
exit ASR overhead: returns to preempting task 18.413
20 rtems_partition_create 18.473
rtems_region_create 14.573
rtems_partition_get_buffer: available 11.153
rtems_partition_get_buffer: not available 9.593
rtems_partition_return_buffer 12.233
rtems_partition_delete 11.633
rtems_region_get_segment: available 12.533
rtems_region_get_segment: not available -- NO_WAIT 11.633
rtems_region_return_segment: no waiting tasks 13.613
rtems_region_get_segment: not available -- caller blocks 37.673
rtems_region_return_segment: task readied -- preempts caller 36.233
rtems_region_return_segment: task readied -- returns to caller 23.153
rtems_region_delete 12.353
rtems_io_initialize 1.255
rtems_io_open 1.096
rtems_io_close 1.095
rtems_io_read 1.097
rtems_io_write 1.096
rtems_io_control 1.097
21 rtems_task_ident 47.737
rtems_message_queue_ident 46.548
rtems_semaphore_ident 53.196
rtems_partition_ident 46.545
rtems_region_ident 47.380
rtems_port_ident 46.540
rtems_timer_ident 46.548
rtems_rate_monotonic_ident 46.545
22 rtems_message_queue_broadcast: task readied -- returns to caller 31.193
rtems_message_queue_broadcast: no waiting tasks 13.872
rtems_message_queue_broadcast: task readied -- preempts caller 37.853
23 rtems_timer_create 9.353
rtems_timer_fire_after: inactive 14.732
rtems_timer_fire_after: active 15.913
rtems_timer_cancel: active 9.855
rtems_timer_cancel: inactive 8.692
rtems_timer_reset: inactive 13.533
rtems_timer_reset: active 14.703
rtems_timer_fire_when: inactive 19.015
rtems_timer_fire_when: active 18.997
rtems_timer_delete: active 12.040
rtems_timer_delete: inactive 10.825
rtems_task_wake_when 32.645
24 rtems_task_wake_after: yield -- returns to caller 6.760
rtems_task_wake_after: yields -- preempts caller 22.005
25 rtems_clock_tick 6.533
26 _ISR_Disable 0.353
_ISR_Flash 0.053
_ISR_Enable 0.000
_Thread_Disable_dispatch 0.353
_Thread_Enable_dispatch 5.513
_Thread_Set_state 5.513
_Thread_Disptach (NO FP) 19.073
context switch: no floating point contexts 16.253
context switch: self 6.953
context switch: to another task 7.013
context switch: restore 1st FP task 22.673
fp context switch: save idle, restore idle 25.733
fp context switch: save idle, restore initialized 16.253
fp context switch: save initialized, restore initialized 16.673
_Thread_Resume 6.833
_Thread_Unblock 4.733
_Thread_Ready 4.793
_Thread_Get 2.273
_Semaphore_Get 2.073
_Thread_Get: invalid id 0.274
27 interrupt entry overhead: returns to interrupted task 7.013
interrupt exit overhead: returns to interrupted task 8.393
interrupt entry overhead: returns to nested interrupt 4.733
interrupt exit overhead: returns to nested interrupt 7.073
interrupt entry overhead: returns to preempting task 5.093
interrupt exit overhead: returns to preempting task 23.513
28 rtems_port_create 12.473
rtems_port_external_to_internal 9.130
rtems_port_internal_to_external 9.130
rtems_port_delete 11.873
29 rtems_rate_monotonic_create 11.813
rtems_rate_monotonic_period: initiate period -- returns to caller 17.753
rtems_rate_monotonic_period: obtain status 9.533
rtems_rate_monotonic_cancel 13.313
rtems_rate_monotonic_delete: inactive 12.473
rtems_rate_monotonic_delete: active 13.193
rtems_rate_monotonic_period: conclude periods -- caller blocks 23.236

View File

@@ -0,0 +1,77 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ../../../..
subdir = libbsp/powerpc/mvme2307/wrapup
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
# We only build the Network library if HAS_NETWORKING was defined
NETWORK_yes_V = network
NETWORK = $(NETWORK_$(HAS_NETWORKING)_V)
BSP_PIECES=startup clock console nvram timer pci $(NETWORK)
# pieces to pick up out of libcpu/ppc
CPU_PIECES=
GENERIC_PIECES=
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL = @INSTALL@
INSTALL_CHANGE = @INSTALL_CHANGE@
ifeq ($(HAS_MP),yes)
GENERIC_PIECES += shmdr
BSP_PIECES += shmsupp
endif
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS=$(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.o)) \
$(foreach piece, $(CPU_PIECES), \
../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/$(piece).rel) \
$(foreach piece, $(GENERIC_PIECES), \
../../../$(piece)/$(ARCH)/$(piece).rel)
LIB=$(ARCH)/libbsp.a
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
$(LIB): ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) $(LIB)
$(INSTALL_VARIANT) -m 644 $(LIB) $(PROJECT_RELEASE)/lib
$(PROJECT_ROOT)/@RTEMS_BSP@/lib/bsp_specs: ../bsp_specs
$(INSTALL_DATA) $< $@
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status