- importing 'beatnik' BSP from SLAC repository.

This commit is contained in:
Till Straumann
2009-12-03 16:56:50 +00:00
commit b7a6d23a0d
75 changed files with 34935 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
aclocal.m4
autom4te*.cache
config.cache
config.log
config.status
configure
Makefile
Makefile.in

View File

@@ -0,0 +1,197 @@
2009-11-06 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am, irq/discovery_pic.c, irq/irq_init.c:
dump raw_exceptions.rel, raw_exception.h; these have
disappeared. <bsp/vectors.h> must now be included
instead.
* Makefile.am: Add 'altivec.rel'.
* make/custom/beatnik.cfg: Use -mcpu=7400; this enables
AltiVec!
2009-11-06 Till Straumann <strauman@slac.stanford.edu>
* beatnik.cfg, make/custom/beatnik.cfg: moved beatnik.cfg
to new make/custom subdir.
2009-10-20 Till Straumann <strauman@slac.stanford.edu>
* startup/bspstart.c: leave 'work-space start' and initial
stack alone. These are now handled by the shared framework
and linker script etc. Locate interrupt stack after __rtems_end
and obtain its size from the configuration.
2009-10-20 Till Straumann <strauman@slac.stanford.edu>
* network/if_mve/mv643xx_eth.c: made mutex a binary semphore;
simple binary semaphore doesn't support priority inheritance.
This was silently ignored under previous releases but is an
error under 4.10.
2009-10-20 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am, bsp_specs, preinstall.am, flash/flashcfg.c,
include/bspopts.h.in, irq/discovery_pic.c, irq/irq_init.c,
marvell/gt_timer.c, marvell/gt_timer.h, marvel/gti2c.c,
network/if_gfe/if_gfe.c, network/if_gfe/if_gfe_rtems.c,
network/if_mve/mv643xx_eth.c, network/support/bsp_attach.c,
pci/gt_pci_init.c, pci/motload_fixup.c, startup/bspstart.c,
startup/i2c_init.c:
Ported to rtems HEAD (to become rtems-4.10). This consisted
mainly of fixing compiler warnings (mostly: adding prototypes
to function declarations and moving extern declarations to
global scope).
A pecularity: if_gfe.c had to remove 'queue.h' inclusion.
we have two versions of queue.h: one in newlib another one in
rtems - don't know how this is supposed to work...
2009-10-17 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am, network/if_mve_mv643xx_eth.c,
network/if_mve_pub.h: Enhanced low-level API allowing
the user to selectively enable/disable/acknowledge
interrupts and to install their own ISR (rather than having
the driver posting an event to a single task).
2009-10-03 Till Straumann <strauman@slac.stanford.edu>
* network/if_mve/mv643xx_eth.c:
BUGFIX: mbuf leak; consume_rx_mbuf() must release mbuf
if 'len'<=0.
BUGFIX: Must initialize 'media-word' argument before
calling BSP_mve_media_ioctl() (defines PHY instance).
2009-06-05 Till Straumann <strauman@slac.stanford.edu>
* network/if_mve/mv643xx_eth.c, network/if_mve/if_mve_pub.h,
Makefile.am: Added MC address reference count and
BSP_mve_mcast_filter_accept_del() to remove a single
entry from the filter.
2009-06-05 Till Straumann <strauman@slac.stanford.edu>
* network/if_mve/mv643xx_eth.c, network/if_mve/if_mve_pub.h,
Makefile.am: first stab at adding multicast support.
2009-06-05 Till Straumann <strauman@slac.stanford.edu>
* network/if_gfe/if_gfe.c:
o propagate PROMISC flag to hardware (SIOCSIFFLAGS)
o handle case where IFF_PROMISC is set (and wasn't before)
in gfe_hash_fill() routine.
2009-06-02 Till Straumann <strauman@slac.stanford.edu>
* network/if_gfe/if_gfe.c: activated and fixed multicast
support.
2009-06-01 Till Straumann <strauman@slac.stanford.edu>
* network/if_em/if_em.c: activated multicast support.
2008-10-30 Till Straumann <strauman@slac.stanford.edu>
MERGED from rtems-4-7-branch:
* Makefile.am, network/if_mve/mv643xx.c, network/if_mve/if_mve_pub.h:
o Exported new low-level driver entry points:
- BSP_mve_ack_link_chg() so that changes in PHY link status can be
propagated to the serial port when handling link-change interrupts.
- BSP_mve_dump_stats() for printing statistics.
o FIXED reading of statistics counters.
o Count interrupts (statistics) in ISR rather than network daemon
(which is only used by the BSD driver).
2008-10-04 Till Straumann <strauman@slac.stanford.edu>
* beatnik.cfg: updated to 4.9; removed make-exe
make-cxx-exe commands. Replaced CPU cflags to use
-mpowerpc -D__ppc_generic.
2008-10-04 Till Straumann <strauman@slac.stanford.edu>
* startup/linkcmds: increased size of CODE memory
area to 32M.
2008-05-10 Till Straumann <strauman@slac.stanford.edu>
* pci/gt_pci_init.c, pci/pci_io_remap.c: fixed 32-bit
types. RTEMS' pci_config access functions now use uint32_t,
earlier versions used unsigned. Both are incompatible,
unfortunately (gcc regards unsigned and unsigned long different
beasts leading to warnings and alias-issues :-()
2008-05-10 Till Straumann <strauman@slac.stanford.edu>
* network/porting/rtemscompat1.h, network/porting/rtemscompat.h,
network/porting/if_xxx_rtems.c, network/if_gfe/if_gfe_rtems.c:
Fixed 32-bit types (pci config access, byteorder macros differ
depending on RTEMS version :-(). We now check for version and
use appropriate types (unsigned vs. uint32_t).
Silenced more warnings (ifndef DEBUG_MODULAR the METHODSPTR
is always non-zero; hence I ifdef'ed the affected code snippet).
2008-03-20 Till Straumann <strauman@slac.stanford.edu>
* include/bsp.h, startup/bspstart.c: confdefs.h now wants
us to use BSP_INTERRUPT_STACK_SIZE instead of
CONFIGURE_INTERRUPT_STACK_MEMORY.
2008-03-19 Till Straumann <strauman@slac.stanford.edu>
* irq/discovery_pic.c: must spare GPP7_0 etc. summary
interrupts in BSP_enable_irq_at_pic() etc.
New 'new-exceptions/bspsupport' code scans all IRQS
and enables or disables depending on the initial config
having a handler connected. This initial disable operation
switched-off the summaries and I had no GPP interrupts...
2008-01-04 Till Straumann <strauman@slac.stanford.edu>
* startup/bspstart.c: changed Kate's copyright note
again as requested by her email 1/04/2008.
2008-01-04 Till Straumann <strauman@slac.stanford.edu>
* startup/bspstart.c: changed Kate's copyright note
as requested by her email 8/16/2007.
2007-12-11 Till Straumann <strauman@slac.stanford.edu>
* irq/discovery_pic.c: don't print warnings if an
invalid irq number is passed to BSP_disable_irq_at_pic(),
BSP_enable_irq_at_pic(). irq_supp.h says we must
silently ignore.
2007-12-11 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am: use new irq_bspsupport.rel which was
split out of exc_bspsupport.rel to provide finer-grained
control over what BSPs want to use.
2007-12-10 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am, startup/vpd.c, startup/vpd.h:
moved VPD support to ../shared/motorola.
2007-12-08 Till Straumann <strauman@slac.stanford.edu>
* Makefile.am: merged shared/vme/vme_universe.c and
shared/vme/vme_universe_dma.c into one file.
Use vme_universe.c, vmeconfig.c from shared area.
2007-11-30 Till Straumann <strauman@slac.stanford.edu>
* startup/bspstart: removed _Cpu_table.exceptions_in_RAM.
2007/11/27 (TS):
- Generalized flash support and moved to shared area (libchip would probably
more appropriate).
2007/10/22 (TS):
- DECREMENTER interrupt is now handled the same way external interrupts are.
It can also be assigned a priority and the handler is executed in priority
order, i.e., it can be preempted by higher-priority interrupts and
is protected from being preempted by lower-priority irqs.
2007/10/08 (TS):
- ChangeLog added
- (Makefile.am) MUST NOT use -msoft-float because this also prevents CR7
to be set/cleared when calling vararg routines (which may then save/restore
FP args on the stack or do other bad things) :-(
Still don't know how to deal with implicit usage of the FPU by GCC
(problem in ISRs and integer-only tasks).

View File

@@ -0,0 +1,52 @@
/* NOTE: The terms described in this LICENSE file apply only to the
* files created by the author (see below). Consult individual
* file headers for more details. Some files were ported from
* netbsd and/or freebsd and are covered by the respective
* file header copyright notices. E.g., the if_em driver is
* covered by it's own network/if_em/LICENSE.
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/

View File

@@ -0,0 +1,245 @@
##
## $Id$
##
ACLOCAL_AMFLAGS = -I ../../../../aclocal
SUBDIRS = .
CLEANFILES =
DISTCLEANFILES =
noinst_PROGRAMS =
EXTRA_DIST =
include $(top_srcdir)/../../../../automake/compile.am
include $(top_srcdir)/../../bsp.am
include_bspdir = $(includedir)/bsp
dist_project_lib_DATA = bsp_specs
project_lib_DATA =
#include
include_HEADERS = include/bsp.h
nodist_include_HEADERS = include/bspopts.h
nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
DISTCLEANFILES += include/bspopts.h
include_bsp_HEADERS =
#start
EXTRA_DIST += ../../powerpc/shared/start/rtems_crti.S
rtems_crti.$(OBJEXT): ../../powerpc/shared/start/rtems_crti.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
project_lib_DATA += rtems_crti.$(OBJEXT)
EXTRA_DIST += ../../powerpc/shared/start/preload.S
preload.$(OBJEXT): ../../powerpc/shared/start/preload.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
EXTRA_DIST += ../../powerpc/shared/start/vectors_entry.S
vectors_entry.$(OBJEXT): ../../powerpc/shared/start/vectors_entry.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
EXTRA_DIST += ../../powerpc/shared/start/start.S
start.$(OBJEXT): ../../powerpc/shared/start/start.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
motld_start.$(OBJEXT): preload.$(OBJEXT) vectors_entry.$(OBJEXT) start.$(OBJEXT)
$(LD) -o $@ -r $^
project_lib_DATA += motld_start.$(OBJEXT)
#startup
dist_project_lib_DATA += ../shared/startup/linkcmds
build_date.c::
echo 'const char *BSP_build_date="'`date`'";' > $@
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES =
libbsp_a_SOURCES += startup/bspstart.c \
../shared/motorola/vpd.c startup/reboot.c startup/i2c_init.c build_date.c \
../../powerpc/shared/startup/panic.c \
../../powerpc/shared/startup/bspgetworkarea.c \
../../powerpc/shared/startup/probeMemEnd.c \
../../powerpc/shared/startup/pretaskinghook.c \
../../powerpc/shared/startup/zerobss.c \
../../powerpc/shared/startup/pgtbl_setup.c \
../../powerpc/shared/startup/pgtbl_activate.c \
../../powerpc/shared/startup/sbrk.c ../../shared/bootcard.c \
startup/bspclean.c ../../shared/bsplibc.c ../../shared/bsppost.c \
../../shared/bsppredriverhook.c \
../../shared/gnatinstallhandler.c
include_bsp_HEADERS += ../shared/motorola/vpd.h
#pclock
libbsp_a_SOURCES += ../../powerpc/shared/clock/p_clock.c
#console
include_bsp_HEADERS += ../../powerpc/shared/console/consoleIo.h
include_bsp_HEADERS += ../../powerpc/shared/console/uart.h
libbsp_a_SOURCES += \
../../powerpc/shared/console/uart.c \
../../powerpc/shared/console/console.c \
../../powerpc/shared/console/consoleIo.h \
../../powerpc/shared/console/uart.h
#irq
include_bsp_HEADERS += irq/irq.h
libbsp_a_SOURCES += irq/irq_init.c irq/discovery_pic.c
#marvell
include_bsp_HEADERS += marvell/gtreg.h marvell/gtintrreg.h \
marvell/gti2creg.h marvell/gti2c_busdrv.h marvell/gt_timer.h \
marvell/gtpcireg.h
libbsp_a_SOURCES += marvell/discovery.c marvell/gti2c.c marvell/gt_timer.c
#flash
include_bsp_HEADERS += ../shared/flash/flashPgm.h
include_bsp_HEADERS += ../shared/flash/flashPgmPvt.h
libbsp_a_SOURCES += ../shared/flash/flash.c \
../shared/flash/intelFlash.c \
flash/flashcfg.c
#pci
include_bsp_HEADERS += ../../powerpc/shared/pci/pci.h
libbsp_a_SOURCES += ../../powerpc/shared/pci/pci.c \
pci/gt_pci_init.c pci/pci_io_remap.c pci/motload_fixup.c \
../../powerpc/shared/pci/pcifinddevice.c
#vectors
include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h
include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h
include_bsp_HEADERS += ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/ppc_exc_bspsupp.h
#vme
include_bsp_HEADERS += vme/VMEConfig.h \
../../shared/vmeUniverse/vmeUniverse.h \
../../shared/vmeUniverse/vmeUniverseDMA.h \
../../shared/vmeUniverse/vme_am_defs.h \
../../shared/vmeUniverse/vmeTsi148.h \
../../shared/vmeUniverse/vmeTsi148DMA.h \
../../shared/vmeUniverse/bspVmeDmaList.h \
../../shared/vmeUniverse/VME.h \
../../shared/vmeUniverse/VMEDMA.h
libbsp_a_SOURCES += ../shared/vme/vmeconfig.c \
../shared/vme/vme_universe.c \
../../shared/vmeUniverse/vmeUniverse.c \
../../shared/vmeUniverse/vmeTsi148.c \
../../shared/vmeUniverse/bspVmeDmaList.c
#network
if HAS_NETWORKING
include_bsp_HEADERS += network/support/early_enet_link_status.h \
network/support/bsp_bsdnet_attach.h
noinst_PROGRAMS += network_support.rel
network_support_rel_SOURCES = network/support/early_link_status.c \
network/support/bsp_attach.c
network_support_rel_CPPFLAGS = $(AM_CPPFLAGS)
network_support_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
include_bsp_HEADERS += network/if_mve/if_mve_pub.h
noinst_PROGRAMS += network_if_mve_tmp.rel
network_if_mve_tmp_rel_SOURCES = network/if_mve/mv643xx_eth.c
network_if_mve_tmp_rel_CPPFLAGS = $(AM_CPPFLAGS) -DDISABLE_DETACHING
network_if_mve_tmp_rel_CFLAGS = $(AM_CFLAGS)
network_if_mve_tmp_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# remove all unneccessary global symbols to avoid name clashes
# with BSD stuff;
network_if_mve.rel: network_if_mve_tmp.rel
$(OBJCOPY) -G rtems_mve_attach -G rtems_mve_early_link_check_ops \
-G BSP_mve_ack_irqs -G BSP_mve_disable_irqs \
-G BSP_mve_enable_irqs -G BSP_mve_init_hw \
-G BSP_mve_ack_irq_mask -G BSP_mve_disable_irq_mask \
-G BSP_mve_enable_irq_mask -G BSP_mve_setup_1 \
-G BSP_mve_read_eaddr -G BSP_mve_send_buf \
-G BSP_mve_send_buf_raw \
-G BSP_mve_setup -G BSP_mve_stop_hw \
-G BSP_mve_swipe_rx -G BSP_mve_swipe_tx \
-G BSP_mve_detach -G BSP_mve_media_ioctl \
-G BSP_mve_get_tid \
-G BSP_mve_dump_stats -G BSP_mve_ack_link_chg \
-G BSP_mve_mcast_filter_clear \
-G BSP_mve_mcast_filter_accept_all \
-G BSP_mve_mcast_filter_accept_add \
-G BSP_mve_mcast_filter_accept_del \
-G mveth_serial_ctrl_config_val \
$^ $@
include_bsp_HEADERS += network/if_gfe/if_gfe_pub.h
noinst_PROGRAMS += network_if_gfe_tmp.rel
network_if_gfe_tmp_rel_SOURCES = network/if_gfe/if_gfe.c network/if_gfe/if_gfe_rtems.c
network_if_gfe_tmp_rel_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(srcdir)/network/porting -I$(srcdir)/network/if_gfe
network_if_gfe_tmp_rel_CFLAGS = -Wno-unused-variable $(AM_CFLAGS)
network_if_gfe_tmp_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# remove all unneccessary global symbols to avoid name clashes
# with BSD stuff;
network_if_gfe.rel: network_if_gfe_tmp.rel
$(OBJCOPY) -G rtems_gfe_attach -G net_driver_ticks_per_sec \
-G rtems_gfe_setup -G rtems_gfe_early_link_check_ops \
$^ $@
include_bsp_HEADERS += network/if_em/if_em_pub.h
noinst_PROGRAMS += network_if_em_tmp.rel
network_if_em_tmp_rel_SOURCES = network/if_em/if_em.c \
network/if_em/if_em_hw.c \
network/if_em/if_em_rtems.c
network_if_em_tmp_rel_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(srcdir)/network/porting -I$(srcdir)/network/if_em
network_if_em_tmp_rel_CFLAGS = -Wno-unused-variable $(AM_CFLAGS)
network_if_em_tmp_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
network_if_em.rel: network_if_em_tmp.rel
$(OBJCOPY) -G rtems_em_attach -G net_driver_ticks_per_sec \
-G rtems_em_pci_setup -G rtems_em_early_link_check_ops \
$^ $@
endif
# tod
nodist_include_HEADERS += ../../shared/tod.h
libbsp_a_SOURCES += ../../shared/tod.c tod/todcfg.c
libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
../../../libcpu/@RTEMS_CPU@/shared/cache.rel \
../../../libcpu/@RTEMS_CPU@/shared/stack.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/exc_bspsupport.rel \
../../../libcpu/@RTEMS_CPU@/@exceptions@/irq_bspsupport.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/clock.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/altivec.rel
if HAS_NETWORKING
libbsp_a_LIBADD += network_support.rel \
network_if_mve.rel network_if_gfe.rel network_if_em.rel
endif
all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
EXTRA_DIST += README LICENSE ChangeLog
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am

View File

@@ -0,0 +1,178 @@
Some information about this BSP
================================
ACKNOWLEDGEMENTS
----------------
Acknowledgements:
Valuable information was obtained from the following drivers
netbsd: Allegro Networks Inc; Wasabi Systems Inc.
linux: MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
Matthew Dharm, rabeeh, Manish Lachwani, Ralf Baechle.
rtems: Brookhaven National Laboratory; Shuchen Kate Feng
This BSP also builds on top of the work of others who have contributed
to similar RTEMS (powerpc) BSPs, most notably Eric Valette, Eric Norum
and others.
In particular, the Author wishes to thank Shuchen Kate Feng (BNL) for many
inspiring discussions and Dayle Kotturi (SLAC) for her contributions, support
and extensive testing.
LICENSE
-------
See ./LICENSE file.
Note that not all files that are part of this BSP were written by
me (most notably, the ethernet drivers if_gfe [netbsd port] and
if_em [freebsd port]). Consult individual file headers for copyright
and authorship information.
BUILD INFO
----------
(relevant only if you received this BSP unbundled from the RTEMS distribution)
prepare:
- get up-to date RTEMS release
- untar beatnik.tgz into c/src/lib/libbsp/powerpc
- copy beatnik.cfg into make/custom
- patch c/src/lib/libsp/powerpc/acinclude.ac
- run 'bootstrap' from top directory; make sure RTEMS
autoXXX are found first in your PATH
configure:
- configure with your favorite options. BSP name is 'beatnik'
I recommend passing RTEMS_CFLAGS=-g to 'configure'
TARGET
------
Even though this BSP is binary compatible with the MVME5500 it's primary
target was and is the MVME6100 board which in some respects is quite different.
In particular, the discovery chip and the VME bridge exhibit significant
differences.
I am sometimes asked why this BSP provides yet another port of the gfe
and em BSD drivers (which had previously been ported for the mvme5500
BSP by Shuchen Kate Feng [BNL]). The answer is simply a matter of time:
Once support for the 6100 board was completed I found it easier to use
the set of 'quick-and-dirty' wrappers (found in network/porting) that I had
developed for other projects and to do a new port from scratch using that
framework rather than modifying the mvme5500 BSP's drivers. mvme5500 support was
added to this BSP because we own a few of those boards we occasionally
play with but we don't want to build and support an additional BSP for them.
An important detail -- hardware cache snooping -- was borrowed from
Shuchen Kate Feng's gfe driver port, though.
HARDWARE SUPPORT
===============
(some of the headers mentioned below contain more
detailed information)
NOTE: The BSP supports both, the mvme6100 and the mvme5500 boards.
It detects relevant hardware at run-time.
CONSOLE: 2 serial devices, UART driver from 'shared' - no surprises
("/dev/ttyS0", [="/dev/console"], "/dev/ttyS1"). (Only
/dev/ttyS0 is accessible from the front panel.)
CLOCK: Decrementer, same as other PPC BSPs. (FIXME: a discovery timer
could be used.)
PIC (interrupt controller) (bsp/irq.h): Marvell hostbridge
does not implement interrupt priorities. The driver supports
priorities in software (masking lower priority lines during
execution of higher priority ISR). I believe the design of the
IRQ subsystem is as efficient as possible with focus on low
latencies.
In addition to the rtems IRQ API, calls are available to
change IRQ priority and to enable/disable interrupts at the PIC.
EXCEPTIONS: (bspException.h) Routines to install a user callback
for (PPC) exception handling.
PCI (bsp/pci.h): The BSP hides the fact that there are effectively
two 'root' busses (AKA 'hoses') behind the discovery bridge.
Devices are addressed by bus/slot/function-triples and the PCI
subsystem transparently figures out what hose to use.
In addition to rtems' PCI API, a call is available to scan
all devices executing a user callback on each device.
BSP_pciConfigDump() is a convenience wrapper dumping essential
information (IDs, BAs, IRQ pin/line) to the console or a file.
MEMORY MAP: CHRP; all addresses (MEM + I/O) read from PCI config. space
are CPU addresses. For sake of portability, drivers should still
use the _IO_BASE, PCI_MEM_BASE, PCI_DRAM_OFFSET constants.
NVRAM: Address constants are defined in bsp.h
FLASH (bsp/flashPgm.h): Routines to write flash. Highest level
wrapper writes a file to flash.
NOTE: Writing to flash is disabled by default;
call BSP_flashWriteEnable().
I2C (bsp.h, rtems/libi2c.h, libchip/i2c-xxx.h): temp. sensor and eeprom
are available as device files (bsp.h); lower-level interface is
provided by libi2c.h.
NOTE: The I2C devices are not registered and the driver is not
initialized by default. Call BSP_i2c_initialize() to do that;
this will create
/dev/i2c0.vpd-eeprom
/dev/i2c0.usr-eeprom
/dev/i2c0.ds1621
You can then read the board temperature:
fd = open("/dev/i2c0.ds1621",O_RDONLY)
read(fd,&temp,1)
close(fd);
printf("Board Temp. is %idegC\n",(int)temp);
VME: (bsp/VME.h, bsp/vme_am_defs.h, bsp/VMEDMA.h).
*always* use VME.h API, if possible; do *not* use chip drivers
(vmeUniverse.h, vmeTsi148.h) directly unless you know what you are
doing (i.e., if you need specific features provided by the particular
chip; currently, both of the mentioned chip drivers expose entry points
that are designed to be compatible).
VMEConfig.h should not be used by applications as it makes them
dependent on BSP internals. VMEConfig.h is intended to be used
by BSP designers only.
VME interrupt priorities: the VME bridge(s) do not implement
priorities in hardware.
However, on the 5500/6100 multiple physical interrupt
lines/wires connect the VME bridge to the PIC. Hence, it is possible
to assign the different wires different priorities at the PIC
(see above) and to route VME interrupts to different wires according
to their priority. You need to call driver specific routines
for this (vmeXXXIntRoute()), however (for driver-specific API
consult bsp/vmeUniverse.h, bsp/vmeTsi148.h).
For VME DMA *always* use the bsp/VMEDMA.h API. DO NOT use
chip-specific features. Applications written using the bsp/VMEDMA.h
API are portable between the UniverseII and the Tsi148.
HARDWARE TIMERS: (bsp/gt_timer.h). Programmable general-purpose (GPT) and
watchdog timers. Routines are provided to setup, start and stop
GPTs. The setup routine allows for specifying single-shot or periodic
mode and dispatches a user ISR when the GPT expires.
The watchdog timer - when started - issues a hard-reset of the
board if not 'petted' within a configurable timeout period.
NETWORK: (bsp/bsp_bsdnet_attach.h). The BSP offers a call to list
all available interfaces (name, description, 'attach'-method)
for the application to make a selection.
Alternatively, there are BSP_auto_network_driver_name and
BSP_auto_enet_attach(), the latter with the capability to configure
the first NIC with a 'live' link status.
All drivers (rewritten 'mve' for the mv64360 NIC (6100) and BSD ports
'gfe'/'em' (5500)) support the SIOCSIFMEDIA/SIOCGIFMEDIA ioctls
(rtems/rtems_mii_ioctl.h provides helpers to convert strings from/to
control words).
VPD: (bsp/vpd.h). The board's VPD (vital-product-data such as S/N,
MAC addresses and so forth) can be retrieved.
BOOTING: BSP has a relocator-header. Clear MSR and jump to the first
instruction in the binary. R3 and R4, if non-null, point to the
start/end of an optional command line string that is copied into
BSP_commandline_string. The BSP is compatible with 'netboot'.
Have fun.
-- Till Straumann <strauman@slac.stanford.edu>, 2005-2007.

View File

@@ -0,0 +1,13 @@
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*startfile:
%{!qrtems: %(old_startfile)} \
%{!nostdlib: %{qrtems: ecrti%O%s rtems_crti%O%s crtbegin.o%s -e __rtems_entry_point -u __vectors motld_start.o%s}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dp -Bstatic}
*endfile:
%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}

View File

@@ -0,0 +1,40 @@
## Process this file with autoconf to produce a configure script.
##
## configure.ac,v 1.9.2.3 2003/08/11 14:37:22 ralf Exp
AC_PREREQ(2.59)
AC_INIT([rtems-c-src-lib-libbsp-powerpc-beatnik],[_RTEMS_VERSION],[rtems-bugs@rtems.com])
AC_CONFIG_SRCDIR([bsp_specs])
RTEMS_TOP(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.9])
RTEMS_BSP_CONFIGURE
RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
RTEMS_CANONICALIZE_TOOLS
RTEMS_PROG_CCAS
RTEMS_CHECK_TOOL([OBJCOPY],[objcopy])
RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
AS=$CC
AM_PROG_AS
RTEMS_BSPOPTS_SET([PPC_USE_DATA_CACHE],[*],[1])
RTEMS_BSPOPTS_HELP([PPC_USE_DATA_CACHE],
[If defined, then the PowerPC specific code in RTEMS will use
data cache instructions to optimize the context switch code.
This code can conflict with debuggers or emulators. It is known
to break the Corelis PowerPC emulator with at least some combinations
of PowerPC 603e revisions and emulator versions.
The BSP actually contains the call that enables this.])
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile])
RTEMS_PPC_EXCEPTIONS
AC_OUTPUT

View File

@@ -0,0 +1,182 @@
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <bsp.h>
#include <stdio.h>
#include <inttypes.h>
#define STATIC static
#include <bsp/flashPgmPvt.h>
/* MVME Board Specifica; board status reg. 2 where write-enable is controlled... */
#define SYS_FLASHA_WP (1<<5)
#define SYS_FBOOTB_WP (1<<3)
#define SYS_FBA_WP_HDR (1<<2)
#define SYS_FBOOTB_WP_HDR (1<<1)
#define SYS_STATUS_2_REG (1)
/* Forward Declarations */
STATIC struct bankdesc *
bankcheck(int bank, int quiet);
static int
flash_wp(int bank, int enbl);
STATIC uint32_t
read_us_timer(void);
/* Global Variables */
/* motload memory map */
static struct bankdesc mvme5500Flash[] = {
{ 0, 2 }, /* first entry gives number of entries */
{ 0xf2000000, 0x08000000, 0x20000*2, 2, BSP_flash_vendor_intel, 0, 0, 0, },
{ 0xff800000, 0x00800000, 0x20000*2, 2, BSP_flash_vendor_intel, 0, 0, 0, },
};
/* motload memory map */
static struct bankdesc mvme6100Flash[] = {
{ 0, 2 }, /* first entry gives number of entries */
{ 0xf4000000, 0x04000000, 0x20000*2, 2, BSP_flash_vendor_intel, 0, 0, 0, },
{ 0xf8000000, 0x04000000, 0x20000*2, 2, BSP_flash_vendor_intel, 0, 0, 0, },
};
struct flash_bsp_ops BSP_flashBspOps = {
bankcheck : bankcheck,
flash_wp : flash_wp,
read_us_timer: read_us_timer,
};
/* set (enbl:1), clear (enbl:0) or query (enbl:-1) write protection
*
* RETURNS 0 on success, nonzero on error.
*/
static int
flash_wp(int bank, int enbl)
{
BSP_BoardType b;
A8 p;
unsigned char hwp = 0, swp;
/* validate 'bank' argument */
if ( !bankcheck( bank, 0 ) )
return -1;
switch ( (b=BSP_getBoardType()) ) {
default:
fprintf(stderr,"Unknown board type %i\n",b);
return -1;
case MVME5500:
/* bit enables both banks; no readback of jumper available */
p = (A8)(BSP_MV64x60_DEV1_BASE + SYS_STATUS_2_REG);
swp = SYS_FLASHA_WP;
break;
case MVME6100:
{
p = (A8)(BSP_MV64x60_DEV1_BASE + SYS_STATUS_2_REG);
if ( 0 == bank ) {
hwp = SYS_FBA_WP_HDR;
swp = SYS_FLASHA_WP;
} else {
hwp = SYS_FBOOTB_WP_HDR;
swp = SYS_FBOOTB_WP;
}
if ( enbl && (*p & hwp) ) {
fprintf(stderr,"HW write protection enabled (jumper)\n");
return -1;
}
}
break;
}
if ( -1 == enbl ) {
/* query */
return *p & (swp | hwp);
} else {
if ( enbl ) {
*p |= swp;
} else {
*p &= ~swp;;
}
}
return 0;
}
/* Lookup bank description in table */
STATIC struct bankdesc *
bankcheck(int bank, int quiet)
{
struct bankdesc *b;
switch ( BSP_getBoardType() ) {
case MVME5500: b = mvme5500Flash; break;
case MVME6100: b = mvme6100Flash; break;
default:
fprintf(stderr,"Unknown/unsupported board type\n");
return 0;
}
if ( bank >= b->size || bank < 0 ) {
if ( !quiet )
fprintf(stderr,"Invalid flash bank #: %i; (too big)\n", bank);
return 0;
}
return b + bank + 1;
}
STATIC uint32_t read_us_timer(void)
{
uint32_t now, mhz;
/* we burn cycles anyways... */
mhz = BSP_bus_frequency/BSP_time_base_divisor/1000;
asm volatile("mftb %0":"=r"(now));
return now/mhz;
}

View File

@@ -0,0 +1,4 @@
bspopts.h
bspopts.h.in
stamp-h
stamp-h.in

View File

@@ -0,0 +1,273 @@
/*
* bsp.h -- contain BSP API definition.
*
* Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* S. Kate Feng 2003-2007 : Modified it to support the mvme5500 BSP.
*
* Modified for the 'beatnik' BSP by T. Straumann, 2005-2007.
*
* bsp.h,v 1.9.4.2 2003/09/04 18:45:20 joel Exp
*/
#ifndef LIBBSP_BEATNIK_BSP_H
#define LIBBSP_BEATNIK_BSP_H
#include <bspopts.h>
#include <rtems.h>
#include <rtems/console.h>
#include <libcpu/io.h>
#include <rtems/clockdrv.h>
#include <bsp/vectors.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Board type */
typedef enum {
Unknown = 0,
MVME5500,
MVME6100
} BSP_BoardType;
BSP_BoardType
BSP_getBoardType();
/* Discovery Version */
typedef enum {
unknown = 0,
GT_64260_A, /* Revision 0x10 */
GT_64260_B, /* Revision 0x20 */
MV_64360,
} DiscoveryVersion;
/* Determine the type of discovery chip on this board; info
* is cached and repeated calls just return the cached value.
*
* If a non-zero argument is passed, the routine panics
* (BSP_panic) if no recognized bridge is found;
*/
DiscoveryVersion
BSP_getDiscoveryVersion(int assertion);
/*
* confdefs.h overrides for this BSP:
* - termios serial ports (defaults to 1)
* - Interrupt stack space is not minimum if defined.
*/
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
#define BSP_INTERRUPT_STACK_SIZE (16 * 1024)
/*
* base address definitions for several devices
*
*/
#define BSP_MV64x60_BASE (0xf1000000)
#define BSP_MV64x60_DEV1_BASE (0xf1100000)
#define BSP_UART_IOBASE_COM1 ((BSP_MV64x60_DEV1_BASE)+0x20000)
#define BSP_UART_IOBASE_COM2 ((BSP_MV64x60_DEV1_BASE)+0x21000)
#define BSP_UART_USE_SHARED_IRQS
#define BSP_NVRAM_BASE_ADDR (0xf1110000)
#define BSP_NVRAM_END_ADDR (0xf1117fff)
#define BSP_NVRAM_RTC_START (0xf1117ff8)
#define BSP_NVRAM_BOOTPARMS_START (0xf1111000)
#define BSP_NVRAM_BOOTPARMS_END (0xf1111fff)
/* This is only active/used during early init. It defines
* the hose0 base for the shared/generic pci code.
* Our own BSP specific pci initialization will then
* override the PCI configuration (see gt_pci_init.c:BSP_pci_initialize)
*/
#define PCI_CONFIG_ADDR (BSP_MV64x60_BASE + 0xcf8)
#define PCI_CONFIG_DATA (BSP_MV64x60_BASE + 0xcfc)
/* our wonderful PCI initialization remaps everything to CPU addresses
* - before calling BSP_pci_initialize() this is NOT VALID, however
* and the deprecated inl()/outl() etc won't work!
*/
#define _IO_BASE 0x00000000
/* wonderful MotLoad has the base address as seen from the CPU programmed into config space :-) */
#define PCI_MEM_BASE 0
#define PCI_MEM_BASE_ADJUSTMENT 0
#define PCI_DRAM_OFFSET 0
/* PCI <-> local address mapping - no sophisticated windows
* (i.e., no support for cached regions etc. you read a BAR
* from config space and that's 1:1 where the CPU sees it).
* Our memory is mapped 1:1 to PCI also.
*/
#define BSP_PCI2LOCAL_ADDR(a) ((uint32_t)(a))
#define BSP_LOCAL2PCI_ADDR(a) ((uint32_t)(a))
#define BSP_CONFIG_NUM_PCI_CACHE_SLOTS 32
#define BSP_CONSOLE_PORT BSP_UART_COM1
#define BSP_UART_BAUD_BASE 115200
/* I2C Devices */
/* Note that the i2c addresses stated in the manual are
* left-shifted by one bit.
*/
#define BSP_VPD_I2C_ADDR (0xA8>>1) /* the VPD EEPROM */
#define BSP_USR_I2C_ADDR (0xAA>>1) /* the user EEPROM */
#define BSP_THM_I2C_ADDR (0x90>>1) /* the DS1621 temperature sensor & thermostat */
#define BSP_I2C_BUS_DESCRIPTOR gt64260_i2c_bus_descriptor
#define BSP_I2C_BUS0_NAME "/dev/i2c0"
#define BSP_I2C_VPD_EEPROM_NAME "vpd-eeprom"
#define BSP_I2C_USR_EEPROM_NAME "usr-eeprom"
#define BSP_I2C_DS1621_NAME "ds1621"
#define BSP_I2C_THM_NAME BSP_I2C_DS1621_NAME
#define BSP_I2C_DS1621_RAW_NAME "ds1621-raw"
#define BSP_I2C_VPD_EEPROM_DEV_NAME (BSP_I2C_BUS0_NAME"."BSP_I2C_VPD_EEPROM_NAME)
#define BSP_I2C_USR_EEPROM_DEV_NAME (BSP_I2C_BUS0_NAME"."BSP_I2C_USR_EEPROM_NAME)
#define BSP_I2C_DS1621_DEV_NAME (BSP_I2C_BUS0_NAME"."BSP_I2C_DS1621_NAME)
#define BSP_I2C_THM_DEV_NAME BSP_I2C_DS1621_DEV_NAME
#define BSP_I2C_DS1621_RAW_DEV_NAME (BSP_I2C_BUS0_NAME"."BSP_I2C_DS1621_RAW_NAME)
/* Initialize the I2C driver and register all devices
* RETURNS 0 on success, -1 on error.
*
* Access to the VPD and user EEPROMS as well
* as the ds1621 temperature sensor is possible
* by means of file nodes
*
* /dev/i2c0.vpd-eeprom (read-only)
* /dev/i2c0.usr-eeprom (read-write)
* /dev/i2c0.ds1621 (read-only; one byte: board-temp in degC)
* /dev/i2c0.ds1621-raw (read-write; transfer bytes to/from the ds1621)
*/
int
BSP_i2c_initialize();
/* Networking; */
#include <bsp/bsp_bsdnet_attach.h>
/* NOT FOR PUBLIC USE BELOW HERE */
#define BSP_PCI_HOSE0_MEM_BASE 0x80000000 /* must be aligned to size */
#define BSP_PCI_HOSE0_MEM_SIZE 0x20000000
#define BSP_PCI_HOSE1_MEM_BASE 0xe0000000
#define BSP_DEV_AND_PCI_IO_BASE 0xf0000000
#define BSP_DEV_AND_PCI_IO_SIZE 0x10000000
/* maintain coherency between CPU and GT64340 ethernet (& possibly other discovery components) */
#define BSP_RW_PAGE_ATTRIBUTES TRIV121_ATTR_M
extern unsigned BSP_pci_hose1_bus_base;
void BSP_pci_initialize();
/* Exception Handling */
/* Use a task notepad to attach user exception handler info;
* may be changed by application startup code (EPICS uses 11)
*/
#define BSP_EXCEPTION_NOTEPAD 14
#ifndef ASM
#define outport_byte(port,value) outb(value,port)
#define outport_word(port,value) outw(value,port)
#define outport_long(port,value) outl(value,port)
#define inport_byte(port,value) (value = inb(port))
#define inport_word(port,value) (value = inw(port))
#define inport_long(port,value) (value = inl(port))
/*
* Vital Board data Start using DATA RESIDUAL
*/
/*
* Total memory using RESIDUAL DATA
*/
extern unsigned int BSP_mem_size;
/*
* Start of the heap
*/
extern unsigned int BSP_heap_start;
/*
* PCI Bus Frequency
*/
extern unsigned int BSP_bus_frequency;
/*
* processor clock frequency
*/
extern unsigned int BSP_processor_frequency;
/*
* Time base divisior (how many tick for 1 second).
*/
extern unsigned int BSP_time_base_divisor;
extern char BSP_productIdent[20];
extern char BSP_serialNumber[20];
extern char BSP_enetAddr0[7];
extern char BSP_enetAddr1[7];
/*
* The commandline as passed from the bootloader.
*/
extern char *BSP_commandline_string;
#define BSP_Convert_decrementer( _value ) \
((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value)))
extern rtems_configuration_table BSP_Configuration;
extern void BSP_panic(char *s);
extern void bsp_reset(void);
extern int BSP_disconnect_clock_handler (void);
extern int BSP_connect_clock_handler (void);
/* clear hostbridge errors
*
* enableMCP: whether to enable MCP checkstop / machine check interrupts
* on the hostbridge and in HID0.
*
* NOTE: The 5500 and 6100 boards have NO PHYSICAL CONNECTION
* to MCP so 'enableMCP' will always fail!
*
* quiet : be silent
*
* RETURNS : PCI status (hose 0 in byte 0, host 1 in byte 1) and
* VME bridge status (upper 16 bits).
* Zero if no errors were found.
*/
extern unsigned long _BSP_clear_hostbridge_errors(int enableMCP, int quiet);
/* clear vme bridge errors and return (bridge-dependent) 16-bit status
*
* quiet : be silent
*
* RETURNS : 0 if there were no errors, non-zero, bridge-dependent
* 16-bit error status on error.
*
*/
extern unsigned short
(*_BSP_clear_vmebridge_errors)(int);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,995 @@
/* $Id$ */
/* Interrupt driver + dispatcher for the discovery host controller */
/* Author: T. Straumann, 2005-2007
*
* Acknowledgements:
* Valuable information was obtained from the following drivers
* netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
* linux: (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
* rtems: (C) Brookhaven National Laboratory; K. Feng
* but this implementation is original work by the author.
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/gtreg.h>
#include <bsp/gtintrreg.h>
#include <rtems/bspIo.h>
#include <bsp/vectors.h>
#include <libcpu/byteorder.h>
#include <libcpu/spr.h>
/* dont change the order (main_lo, main_hi, gpp) which
* matches the interrupt numbers!
*/
#define MAIN_LO_IDX 0
#define MAIN_HI_IDX 1
#define GPP_IDX 2
#define NUM_INTR_REGS 3
#define SYNC() asm volatile("sync")
/* How many times should the ISR dispatcher check for
* pending interrupts until it decides that something's
* fishy (i.e., a user ISR fails to clear the interrupt
* source)
*/
#define MAX_SPIN_LOOPS 100
/* If FASTER is defined, a few obscure I/O statements found in the linux
* driver are removed
*/
#define FASTER
/* Array helper */
#define NumberOf(arr) (sizeof(arr)/sizeof((arr)[0]))
/* MVME6100 specific; re-define watchdog NMI pin to be a normal output
* so we have a way to raise an interrupt in software (GPP[26] is wired to
* GPP[6] on the MVME6100).
*/
#define MVME6100_IRQ_DEBUG 4
#define GPP_WIRED_OUT_BIT_6100 26 /* CAVEAT: this is bit 26 on the 6100 */
#define GPP_WIRED_OUT_BIT_5500 24 /* CAVEAT: this is bit 24 on the 5500 */
#define GPP_WIRED_IN_BIT 6
/* Ored mask of debugging features to enable */
#define IRQ_DEBUG_BASIC 1
/* This is _very_ lowlevel */
#define IRQ_DEBUG_DISPATCHER 2
/* Record maximal dispatching latency */
#define IRQ_DEBUG_MAXLAT 8 /* PPC only */
#define IRQ_DEBUG (0 /*|(IRQ_DEBUG_BASIC)*/|(MVME6100_IRQ_DEBUG)|(IRQ_DEBUG_MAXLAT))
/**********
* Typedefs
**********/
/* Set of the three relevant cause registers */
typedef volatile unsigned IrqMask[NUM_INTR_REGS];
#define REGP(x) ((volatile uint32_t *)(x))
/* Information we keep about the PIC */
typedef struct _Mv64x60PicRec {
/* base address as seen from CPU */
uintptr_t reg_base;
/* addresses of 'cause' registers */
volatile uint32_t *causes[NUM_INTR_REGS];
/* addresses of 'mask' registers */
volatile uint32_t *masks[NUM_INTR_REGS];
/* masks for all priorities. If an
* interrupt source has priority X,
* its corresponding bit is set
* (enabled) in mcache[i] for all
* i < X and cleared for i >= X
*/
volatile IrqMask mcache[BSP_IRQ_MAX_PRIO+1];
/* Priority we're executing at.
* Thread-level is priority 0,
* ISRs range from 1..MAX_PRIO
*/
volatile rtems_irq_prio current_priority;
} Mv64x60PicRec, *Mv64x60Pic;
/**********
* Globals
**********/
/* Copy of the configuration */
static rtems_irq_global_settings theConfig;
/* PIC description */
static Mv64x60PicRec thePic;
#if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
static unsigned long gpp_out_bit = 0;
#endif
#if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
unsigned long discovery_pic_max_dispatching_latency = 0;
#ifdef __PPC__
static inline unsigned long mftb(void)
{
unsigned long rval;
asm volatile("mftb %0":"=r"(rval));
return rval;
}
#else
#define mftb() 0
#endif
#endif
/**********
* Functions
**********/
/* Debugging helper routines */
static void pregs(volatile uint32_t **p)
{
int i;
for (i=NUM_INTR_REGS-1; i>=0; i--) {
printk(" 0x%08x", ld_le32(p[i]));
printk( i ? " --":"\n");
}
}
static void pmsks(volatile IrqMask p)
{
int i;
for (i=NUM_INTR_REGS-1; i>=0; i--) {
printk(" 0x%08x", p[i]);
printk( i ? " --":"\n");
}
}
void discovery_dump_picregs(void)
{
printk(" ..GPP_IRQ. -- ..MAIN_HI. -- ..MAIN_LO.\n");
printk("Cause:"); pregs(thePic.causes);
printk("Mask: "); pregs(thePic.masks);
}
/* Small inline helpers */
/* return 0 if this PIC is not 'responsible' for a given irq number
* we also 'ignore' the GPP summary bits - these must always remain
* enabled.
*/
static inline int
validIrqNo(rtems_irq_number irq)
{
return
irq >= BSP_PCI_IRQ_LOWEST_OFFSET
&& irq <= BSP_PCI_IRQ_MAX_OFFSET
&& ! (IMH_GPP_SUM & (1<<(irq-32)));
}
/* return 0 if a given priority is outside the valid range */
static inline int
validPri(rtems_irq_prio pri)
{
/* silence compiler warning about limited range of type;
* hope it never changes...
*/
return /* pri>=0 && */ pri <=BSP_IRQ_MAX_PRIO;
}
/* Return position of the most significant bit that is set in 'x' */
static inline int
__ilog2(unsigned x)
{
asm volatile("cntlzw %0, %0":"=&r"(x):"0"(x));
return 31-x;
}
/* Convert irq number to cause register index
* (array of handles in the PicRec).
* ASSUMES: 'irq' within valid range.
*/
static inline unsigned
irqDiv32(unsigned irq)
{
return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)>>5;
}
/* Convert irq number to cause/mask bit number.
* ASSUMES: 'irq' within valid range.
*/
static inline unsigned
irqMod32(unsigned irq)
{
return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)&31;
}
/* NON-ATOMICALLY set/clear bits in a MV64x60 register
*
* register contents at offset 'off' are ANDed with
* complement of the 'clr' mask and ORed with 'set' mask:
*
* *off = (*off & ~clr) | set
*
* ASSUMES: executed from IRQ-disabled section
*/
static inline void
gt_bitmod(unsigned off, unsigned set, unsigned clr)
{
st_le32(REGP(thePic.reg_base + off),
(ld_le32(REGP(thePic.reg_base+off)) & ~clr) | set);
}
static inline unsigned
gt_read(unsigned off)
{
return ld_le32(REGP(thePic.reg_base + off));
}
static inline void
gt_write(unsigned off, unsigned val)
{
st_le32(REGP(thePic.reg_base + off), val);
}
/* Enable interrupt number 'irq' at the PIC.
*
* Checks for valid arguments but has no way of
* communicating violation; prints to console
* if illegal arguments are given.
*
* This routine may be called from ISR level.
*
* Algorithm: set corresponding bit in masks
* for all priorities lower than the
* target irq's priority and push
* mask for the currently executing
* priority out to the PIC.
*/
void
BSP_enable_irq_at_pic(rtems_irq_number irq)
{
unsigned i,j;
unsigned long flags;
volatile uint32_t *p;
uint32_t v,m;
if ( !validIrqNo(irq) ) {
/* API change - must silently ignore...
printk("BSP_enable_irq_at_pic: Invalid argument (irq #%i)\n",irq);
*/
return;
}
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk("IRQ: Enable #%i;",irq);
#endif
if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
/* This is probably a more serious error; don't ignore silently */
printk("BSP_enable_irq_at_pic: illegal argument\n");
return;
}
/* compute register pointer and bit mask */
p = thePic.masks[i];
m = 1<<irqMod32(irq);
rtems_interrupt_disable(flags);
{
/* access table from protected section to be thread-safe */
rtems_irq_prio pri = theConfig.irqPrioTbl[irq];
for ( j=0; j<pri; j++ ) {
thePic.mcache[j][i] |= m;
}
st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
/* linux driver reads back GPP mask; maybe it's wise to do the same */
(void)ld_le32(thePic.masks[GPP_IDX]);
}
SYNC();
rtems_interrupt_enable(flags);
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
#endif
}
/* Disable interrupt number 'irq' at the PIC.
*
* Checks for valid arguments but has no way of
* communicating violation; prints to console
* if illegal arguments are given.
*
* This routine may be called from ISR level.
*
* Algorithm: clear corresponding bit in masks
* for all priorities and push the
* mask for the currently executing
* priority out to the PIC.
*/
int
BSP_disable_irq_at_pic(rtems_irq_number irq)
{
unsigned i,j;
unsigned long flags;
volatile uint32_t *p;
uint32_t v,m;
int rval;
if ( !validIrqNo(irq) ) {
/* API change - must silently ignore...
printk("BSP_disable_irq_at_pic: Invalid argument (irq #%i)\n",irq);
*/
return -1;
}
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk("IRQ: Disable #%i;",irq);
#endif
if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
/* This is probably a more serious error; don't ignore silently */
printk("BSP_enable_irq_at_pic: illegal argument\n");
return -1;
}
/* compute register pointer and bit mask */
p = thePic.masks[i];
m = (1<<irqMod32(irq));
rtems_interrupt_disable(flags);
{
rval = thePic.mcache[thePic.current_priority][i] & m;
for (j=0; j<=BSP_IRQ_MAX_PRIO; j++)
thePic.mcache[j][i] &= ~m;
st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
/* linux driver reads back GPP mask; maybe it's wise to do the same */
(void)ld_le32(thePic.masks[GPP_IDX]);
}
SYNC();
rtems_interrupt_enable(flags);
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
#endif
return rval ? 1 : 0;
}
int
BSP_irq_is_enabled_at_pic(rtems_irq_number irq)
{
unsigned i;
if ( !validIrqNo(irq) ) {
printk("BSP_irq_is_enabled_at_pic: Invalid argument (irq #%i)\n",irq);
return -1;
}
if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
printk("BSP_enable_irq_at_pic: illegal argument\n");
return -1;
}
return ld_le32(thePic.masks[i]) & (1<<irqMod32(irq)) ? 1 : 0;
}
/* Change priority of interrupt number 'irq' to 'pri'
*
* RETURNS: 0 on success, nonzero on failure (illegal args)
*
* NOTE: This routine must not be called from ISR level.
*
* Algorithm: Set bit corresponding to 'irq' in the masks for
* all priorities < pri and clear in all masks
* for priorities >=pri
*/
int
BSP_irq_set_priority(rtems_irq_number irq, rtems_irq_prio pri)
{
unsigned long flags;
volatile uint32_t *p;
uint32_t v,m;
unsigned i,j;
if ( thePic.current_priority > 0 ) {
printk("BSP_irq_set_priority: must not be called from ISR level\n");
return -1;
}
if ( !validPri(pri) ) {
printk("BSP_irq_set_priority: invalid argument (pri #%i)\n",pri);
return -1;
}
if ( BSP_DECREMENTER != irq ) {
if ( !validIrqNo(irq) ) {
printk("BSP_irq_set_priority: invalid argument (irq #%i)\n",irq);
return -1;
}
if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
printk("BSP_irq_set_priority: illegal argument (irq #%i not PCI?)\n", irq);
return -1;
}
}
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk("IRQ: Set Priority #%i -> %i;",irq,pri);
#endif
if ( BSP_DECREMENTER == irq ) {
theConfig.irqPrioTbl[irq] = pri;
return 0;
}
/* compute register pointer and bit mask */
p = thePic.masks[i];
m = 1<<irqMod32(irq);
rtems_interrupt_disable(flags);
{
for (j=0; j<=BSP_IRQ_MAX_PRIO; j++) {
if ( j<pri )
thePic.mcache[j][i] |= m;
else
thePic.mcache[j][i] &= ~m;
}
theConfig.irqPrioTbl[irq] = pri;
st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
/* linux driver reads back GPP mask; maybe it's wise to do the same */
(void)ld_le32(thePic.masks[GPP_IDX]);
}
SYNC();
rtems_interrupt_enable(flags);
#if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
#endif
return 0;
}
/* Initialize the PIC; routine needed by BSP framework
*
* RETURNS: NONZERO on SUCCESS, 0 on error!
*/
int
BSP_setup_the_pic(rtems_irq_global_settings* config)
{
int i;
/*
* Store copy of configuration
*/
theConfig = *config;
/* check config */
if ( theConfig.irqNb <= BSP_PCI_IRQ_MAX_OFFSET ) {
printk("BSP_setup_the_pic: FATAL ERROR: configured IRQ table too small???\n");
return 0;
}
for ( i=0; i<theConfig.irqNb; i++ ) {
if ( !validPri(theConfig.irqPrioTbl[i]) ) {
printk("BSP_setup_the_pic: invalid priority (%i) for irg #%i; setting to 1\n", theConfig.irqPrioTbl[i], i);
theConfig.irqPrioTbl[i]=1;
}
}
/* TODO: Detect; Switch wired-out bit; */
thePic.reg_base = BSP_MV64x60_BASE;
thePic.current_priority = 0;
#if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
#endif
switch ( BSP_getDiscoveryVersion(/* assert */ 1) ) {
case MV_64360:
thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_360_MIC_LO);
thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_360_MIC_HI);
thePic.masks[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_360_C0IM_LO);
thePic.masks[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_360_C0IM_HI);
break;
case GT_64260_A:
case GT_64260_B:
thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_260_MIC_LO);
thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_260_MIC_HI);
thePic.masks[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_260_CIM_LO);
thePic.masks[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_260_CIM_HI);
break;
default:
BSP_panic("Unable to initialize interrupt controller; unknown chip");
break;
}
thePic.causes[GPP_IDX] = REGP(thePic.reg_base + GT_GPP_Interrupt_Cause);
thePic.masks[GPP_IDX] = REGP(thePic.reg_base + GT_GPP_Interrupt_Mask);
/* Initialize mask cache */
for ( i=0; i<=BSP_IRQ_MAX_PRIO; i++ ) {
thePic.mcache[i][MAIN_LO_IDX] = 0;
/* Always enable the summary bits. Otherwise, GPP interrupts dont
* make it 'through' to the GPP cause
*/
thePic.mcache[i][MAIN_HI_IDX] = IMH_GPP_SUM;
thePic.mcache[i][GPP_IDX] = 0;
}
/* mask and clear everything */
for ( i=0; i<NUM_INTR_REGS; i++ ) {
st_le32(thePic.causes[i], 0);
st_le32(thePic.masks[i], 0);
}
/* make sure GPP Irqs are level sensitive */
gt_bitmod(
GT_CommUnitArb_Ctrl, /* reg */
GT_CommUnitArb_Ctrl_GPP_Ints_Level_Sensitive, /* set */
0); /* clr */
/* enable summaries */
st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[thePic.current_priority][MAIN_LO_IDX]);
st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[thePic.current_priority][MAIN_HI_IDX]);
st_le32(thePic.masks[GPP_IDX ], thePic.mcache[thePic.current_priority][GPP_IDX ]);
/* believe the interrupts are all level sensitive (which is good); we leave all the
* inputs configured they way the are by MotLoad...
*/
/* Finally, enable all interrupts for which the configuration table has already
* a handler installed.
*/
for ( i=BSP_PCI_IRQ_LOWEST_OFFSET; i<=BSP_PCI_IRQ_MAX_OFFSET; i++ ) {
if ( theConfig.irqHdlTbl[i].hdl != theConfig.defaultEntry.hdl ) {
BSP_enable_irq_at_pic(i);
}
}
return 1;
}
int discovery_pic_max_loops = 0;
/* Change the priority level we're executing at and mask all interrupts of
* the same and lower priorities
*
* RETURNS old priority;
*/
static inline rtems_irq_prio
change_executing_prio_level(rtems_irq_prio pri)
{
register rtems_irq_prio rval = thePic.current_priority;
thePic.current_priority = pri;
st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[pri][MAIN_LO_IDX]);
st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[pri][MAIN_HI_IDX]);
st_le32(thePic.masks[GPP_IDX ], thePic.mcache[pri][GPP_IDX ]);
/* this DOES seem to be necessary */
(void)ld_le32(thePic.masks[GPP_IDX]);
return rval;
}
/* Scan the three cause register and find the pending interrupt with
* the highest priority.
*
* Two facts make this quite efficient
* a) the PPC has an opcode for finding the number of leading zero-bits
* in a register (__ilog2()).
* b) as we proceed we mask all sources of equal or lower priorites; they won't be
* seen while scanning:
*
* maxpri = 0;
* bits = in_le32(cause);
* while ( bits &= mask[maxpri] ) {
* irq_no = __ilog2(bits);
* maxpri = priority[irq_no];
* }
*
* a) __ilog() is 1-2 machine instructions
* b) while loop is only executed as many times as interrupts of different
* priorities are pending at the same time (and only if lower-priority
* ones are found first; otherwise, the iteration terminates quicker).
*
* ==> highest priority source is found quickly. It takes at most
*
* BSP_IRQ_MAX_PRIO * ( ~3 reg-only instructions + 2 memory access )
* + 2 reg-only instructions + 1 I/O + 1 memory access.
*
*
*/
static unsigned mlc, mhc, gpc;
static int decrementerPending = 0;
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
int decrementerIrqs = 0;
#endif
static inline unsigned
find_highest_priority_pending_irq(rtems_irq_prio *ppri)
{
register int rval = -1;
register rtems_irq_prio *pt = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
register rtems_irq_prio pmax = *ppri;
register unsigned cse,ocse;
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
discovery_dump_picregs();
#endif
if ( decrementerPending ) {
/* Don't flood
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Decrementer IRQ pending\n");
#endif
*/
if ( theConfig.irqPrioTbl[BSP_DECREMENTER] > pmax ) {
pmax = theConfig.irqPrioTbl[BSP_DECREMENTER];
rval = BSP_DECREMENTER;
}
}
mlc = cse = ld_le32(thePic.causes[MAIN_LO_IDX]);
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
#endif
while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
rval = __ilog2(cse);
pmax = pt[rval];
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
mhc = cse = ocse = ld_le32(thePic.causes[MAIN_HI_IDX]);
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
#endif
/* don't look at the GPP summary; only check for 'real' MAIN_HI sources */
cse &= ~IMH_GPP_SUM;
while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
rval = __ilog2(cse) + 32;
pmax = pt[rval];
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
gpc = cse = ld_le32(thePic.causes[GPP_IDX ]);
/* if there were GPP ints, scan the GPP cause now */
if ( ocse & IMH_GPP_SUM ) {
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX ]);
#endif
cse &= thePic.mcache[pmax][GPP_IDX ];
ocse = cse;
while ( cse ) {
rval = __ilog2(cse) + 64;
pmax = pt[rval];
cse &= thePic.mcache[pmax][GPP_IDX ];
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
#ifndef FASTER
/* this doesn't seem to be necessary -- however, the linux people do it... */
out_le32(thePic.causes[GPP_IDX], ~ocse);
#endif
}
#ifndef FASTER
/* this doesn't seem to be necessary -- however, the linux people do it... */
(void)in_le32(thePic.causes[GPP_IDX]);
#endif
*ppri = pmax;
if ( BSP_DECREMENTER == rval ) {
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
decrementerIrqs++;
#endif
decrementerPending = 0;
}
return rval;
}
#if 0 /* TODO: should this be cleaned up ? */
#define _IRQ_DEBUG IRQ_DEBUG_DISPATCHER
static inline unsigned
ffind_highest_priority_pending_irq(rtems_irq_prio *ppri)
{
register int rval = -1;
register rtems_irq_prio *pt = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
register rtems_irq_prio pmax = *ppri;
register unsigned cse,ocse;
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
discovery_dump_picregs();
#endif
cse = in_le32(thePic.causes[MAIN_LO_IDX]);
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
#endif
while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
rval = __ilog2(cse);
pmax = pt[rval];
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
cse = ocse = in_le32(thePic.causes[MAIN_HI_IDX]);
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
#endif
/* don't look at the GPP summary; only check for 'real' MAIN_HI sources */
cse &= ~IMH_GPP_SUM;
while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
rval = __ilog2(cse) + 32;
pmax = pt[rval];
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
/* if there were GPP ints, scan the GPP cause now */
if ( ocse & IMH_GPP_SUM ) {
cse = in_le32(thePic.causes[GPP_IDX ]);
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX ]);
#endif
cse &= thePic.mcache[pmax][GPP_IDX ];
ocse = cse;
while ( cse ) {
rval = __ilog2(cse) + 64;
pmax = pt[rval];
cse &= thePic.mcache[pmax][GPP_IDX ];
#if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
printk("Max pri IRQ now %i\n",rval);
#endif
}
/* this doesn't seem to be necessary -- however, the linux people do it... */
out_le32(thePic.causes[GPP_IDX], ~ocse);
}
/* this doesn't seem to be necessary -- however, the linux people do it... */
(void)in_le32(thePic.causes[GPP_IDX]);
*ppri = pmax;
return rval;
}
#endif
/* Here's our dispatcher; the BSP framework uses the same one for EE and decrementer
* exceptions...
*/
int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
{
register int irq;
int loop, last_irq;
rtems_irq_prio pri;
#if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
unsigned long diff;
#endif
#if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
diff = mftb();
#endif
if (excNum == ASM_DEC_VECTOR) {
decrementerPending = 1;
}
/* Tradeoff: EITHER we loop as long as interrupts are pending
* incurring the overhead of one extra run of the 'find_pending_irq' routine.
* OR we do rely on the handler just being invoked again if multiple
* interrupts are pending.
*
* The first solution gives better worst-case behavior
* the second slightly better average performance.
* --> we go for the first solution. This also enables us to catch
* runaway interrupts, i.e., bad drivers that don't clear interrupts
* at the device. Can be very handy during driver development...
*/
for ( loop=0, last_irq=-1, pri = thePic.current_priority;
(irq=find_highest_priority_pending_irq(&pri)) >=0;
loop++, last_irq = irq ) {
/* raise priority level and remember current one */
pri = change_executing_prio_level(pri);
SYNC();
#if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
if ( 0 == loop ) {
diff = mftb()-diff;
if ( diff > discovery_pic_max_dispatching_latency )
discovery_pic_max_dispatching_latency = diff;
}
#endif
#if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
if ( BSP_DECREMENTER == irq ) {
printk("IRQ: dispatching DECREMENTER\n");
} else {
int idx = irqDiv32(irq);
printk("IRQ: dispatching #%i; causes[%i]=0x%08x\n", irq, idx, ld_le32(thePic.causes[idx]));
}
#endif
bsp_irq_dispatch_list( theConfig.irqHdlTbl, irq, theConfig.defaultEntry.hdl );
/* restore executing priority level */
(void)change_executing_prio_level(pri);
if ( (loop > MAX_SPIN_LOOPS) && (last_irq == irq) ) {
/* try to catch run-away interrupts without disabling a 'legal' one;
* this should never happen with the decrementer (and
* BSP_disable_irq_at_pic(BSP_DECREMENTER) would fail)
*/
printk("Runaway IRQ #%i; disabling\n", irq);
BSP_disable_irq_at_pic(irq);
loop = 0;
}
}
if (!loop) {
if ( decrementerPending && pri >= theConfig.irqPrioTbl[BSP_DECREMENTER] ) {
/* we cannot mask the decrementer interrupt so it is possible that it
* gets delivered even though it has a lower priority than what we're
* currently executing at.
* In this case, we ignore the zero loop count and return;
* the interrupted instance of C_dispatch_irq_handler() will eventually
* lower the executing priority and catch the 'decrementerPending' flag
* we just set.
*/
} else {
printk("Discovery: Spurious interrupt; causes were gpp: 0x%x, mhc: 0x%x, mlc: 0x%x\n", gpc, mhc, mlc);
printk("Current priority level %i, decrementerPending %i\n", pri, decrementerPending);
{
rtems_irq_prio p=pri;
printk("PIC register dump:\n");
discovery_dump_picregs();
printk("Current Priority: %i, found %i\n",pri,find_highest_priority_pending_irq(&p));
discovery_dump_picregs();
for (p=0; p<=BSP_IRQ_MAX_PRIO; p++) {
printk("M[%i] :",p);pmsks(thePic.mcache[p]);
}
}
}
}
else if (loop>discovery_pic_max_loops)
discovery_pic_max_loops = loop;
return 0;
}
#if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
void
discovery_pic_install_debug_irq(void)
{
switch ( BSP_getBoardType() ) {
case MVME6100: gpp_out_bit = GPP_WIRED_OUT_BIT_6100; break;
case MVME5500: gpp_out_bit = GPP_WIRED_OUT_BIT_5500; break;
default:
gpp_out_bit = 0; break;
break;
}
if ( gpp_out_bit ) {
unsigned mppoff;
switch (gpp_out_bit / 8) {
default: /* silence warning; this is never reached */
case 0: mppoff = GT_MPP_Control0; break;
case 1: mppoff = GT_MPP_Control1; break;
case 2: mppoff = GT_MPP_Control2; break;
case 3: mppoff = GT_MPP_Control3; break;
}
/* switch GPP pin allocated to watchdog (value 4) to
* GPP I/O (value 0 ??; have no doc, found out by experimenting)
*/
gt_bitmod(mppoff, 0, (0xf<<(4*(gpp_out_bit % 8))));
/* make it an output */
gt_bitmod(GT_GPP_IO_Control, (1<<gpp_out_bit), 0);
/* don't invert levels */
gt_bitmod(GT_GPP_Level_Control, 0, (1<<GPP_WIRED_IN_BIT) | (1<<gpp_out_bit));
/* clear output */
gt_bitmod(GT_GPP_Value, 0, 1<<gpp_out_bit);
printk("GPP levelctl now 0x%08x\n", gt_read(GT_GPP_Level_Control));
printk("GPP value now 0x%08x\n", gt_read(GT_GPP_Value));
printk("MPP ctl 0 now 0x%08x\n", gt_read(GT_MPP_Control0));
printk("MPP ctl 1 now 0x%08x\n", gt_read(GT_MPP_Control1));
printk("MPP ctl 2 now 0x%08x\n", gt_read(GT_MPP_Control2));
printk("MPP ctl 3 now 0x%08x\n", gt_read(GT_MPP_Control3));
}
}
/* Control the state of the external 'wire' that connects the
* GPP_WIRED_OUT --> GPP_WIRED_IN pins
*/
void
discovery_pic_set_debug_irq(int on)
{
unsigned long flags, clr;
if ( !gpp_out_bit ) {
printk("discovery_pic_set_debug_irq(): unknown wire output\n");
return;
}
if (on) {
on = 1<<gpp_out_bit;
clr = 0;
} else {
clr = 1<<gpp_out_bit;
on = 0;
}
rtems_interrupt_disable(flags);
gt_bitmod(GT_GPP_Value, on, clr);
rtems_interrupt_enable(flags);
}
#endif
#if 0
/* Here's some code for testing */
#endif

View File

@@ -0,0 +1,133 @@
/* irq.h
*
* This include file describe the data structure and the functions implemented
* by rtems to write interrupt handlers.
*
* CopyRight (C) 1999 valette@crf.canon.fr
*
* This code is heavilly inspired by the public specification of STREAM V2
* that can be found at :
*
* <http://www.chorus.com/Documentation/index.html> by following
* the STREAM API Specification Document link.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* Modified by T. Straumann for the beatnik BSP, 2005-2007
* Some information may be based on mvme5500/irq/irq.h by K. Feng.
*/
#ifndef LIBBSP_POWERPC_MOT_PPC_NEW_IRQ_IRQ_H
#define LIBBSP_POWERPC_MOT_PPC_NEW_IRQ_IRQ_H
#define BSP_SHARED_HANDLER_SUPPORT 1
#include <rtems/irq.h>
#include <bsp/vectors.h>
/* This BSP also passes a pointer to the interrupt frame to the handler.
* The PPC ABI guarantees that this will not mess up handlers written
* without knowledge of this feature.
*/
typedef void (*BSP_rtems_irq_hdl)(rtems_irq_hdl_param,BSP_Exception_frame*);
/* legal priorities are 0 <= priority <= MAX_PRIO; 0 effectively disables the interrupt */
#define BSP_IRQ_MAX_PRIO 4
#define BSP_IRQ_MIN_PRIO 1
/* Note that priorites are only honoured for 'PCI' interrupt numbers.
* The discovery pic has no support for hardware priorites; hence they
* are handled in software
*/
#define BSP_IRQ_DEFAULT_PRIORITY 2
#define BSP_PCI_IRQ_LOWEST_OFFSET 0 /* IMPLEMENTATION RELIES ON discovery pic INTERRUPTS HAVING NUMBERS 0..95 */
#define BSP_IRQ_DEV 1 /* device interface interrupt */
#define BSP_IRQ_DMA 2 /* DMA addres error interrupt (260) */
#define BSP_IRQ_CPU 3 /* CPU interface interrupt */
#define BSP_IRQ_IDMA0_1 4 /* IDMA ch. 0..1 complete interrupt (260) */
#define BSP_IRQ_IDMA2_3 5 /* IDMA ch. 2..3 complete interrupt (260) */
#define BSP_IRQ_IDMA4_5 6 /* IDMA ch. 4..5 complete interrupt (260) */
#define BSP_IRQ_IDMA6_7 7 /* IDMA ch. 6..7 complete interrupt (260) */
#define BSP_IRQ_TIME0_1 8 /* Timer 0..1 interrupt; Timer 0 on 64360 */
#define BSP_IRQ_TIME2_3 9 /* Timer 2..3 interrupt; Timer 1 on 64360 */
#define BSP_IRQ_TIME4_5 10 /* Timer 4..5 interrupt; Timer 2 on 64360 */
#define BSP_IRQ_TIME6_7 11 /* Timer 6..7 interrupt; Timer 3 on 64360 */
#define BSP_IRQ_PCI0_0 12 /* PCI 0 interrupt 0 summary (PCI 0 interrupt summary on 64360) */
#define BSP_IRQ_PCI0_1 13 /* PCI 0 interrupt 1 summary (SRAM PAR ERROR on 64360) */
#define BSP_IRQ_PCI0_2 14 /* PCI 0 interrupt 2 summary */
#define BSP_IRQ_PCI0_3 15 /* PCI 0 interrupt 3 summary */
#define BSP_IRQ_PCI1_0 16 /* PCI 1 interrupt 0 summary (PCI 1 interrupt summary on 64360) */
#define BSP_IRQ_ECC 17 /* ECC error interrupt */
#define BSP_IRQ_PCI1_1 18 /* PCI 1 interrupt 1 summary */
#define BSP_IRQ_PCI1_2 19 /* PCI 1 interrupt 2 summary */
#define BSP_IRQ_PCI1_3 20 /* PCI 1 interrupt 3 summary */
#define BSP_IRQ_PCI0OUT_LO 21 /* PCI 0 outbound interrupt summary */
#define BSP_IRQ_PCI0OUT_HI 22 /* PCI 0 outbound interrupt summary */
#define BSP_IRQ_PCI1OUT_LO 23 /* PCI 1 outbound interrupt summary */
#define BSP_IRQ_PCI1OUT_HI 24 /* PCI 1 outbound interrupt summary */
#define BSP_IRQ_PCI0IN_LO 26 /* PCI 0 inbound interrupt summary */
#define BSP_IRQ_PCI0IN_HI 27 /* PCI 0 inbound interrupt summary */
#define BSP_IRQ_PCI1IN_LO 28 /* PCI 1 inbound interrupt summary */
#define BSP_IRQ_PCI1IN_HI 29 /* PCI 1 inbound interrupt summary */
#define BSP_IRQ_ETH0 (32+0) /* Ethernet controller 0 interrupt */
#define BSP_IRQ_ETH1 (32+1) /* Ethernet controller 1 interrupt */
#define BSP_IRQ_ETH2 (32+2) /* Ethernet controller 2 interrupt */
#define BSP_IRQ_SDMA (32+4) /* SDMA interrupt */
#define BSP_IRQ_I2C (32+5) /* I2C interrupt */
#define BSP_IRQ_BRG (32+7) /* Baud Rate Generator interrupt */
#define BSP_IRQ_MPSC0 (32+8) /* MPSC 0 interrupt */
#define BSP_IRQ_MPSC1 (32+10) /* MPSC 1 interrupt */
#define BSP_IRQ_COMM (32+11) /* Comm unit interrupt */
#define BSP_IRQ_GPP7_0 (32+24) /* GPP[7..0] interrupt summary */
#define BSP_IRQ_GPP15_8 (32+25) /* GPP[15..8] interrupt summary */
#define BSP_IRQ_GPP23_16 (32+26) /* GPP[23..16] interrupt summary */
#define BSP_IRQ_GPP31_24 (32+27) /* GPP[31..24] interrupt summary */
#define BSP_IRQ_GPP_0 64
#define BSP_PCI_IRQ_NUMBER (64+32)
#define BSP_PCI_IRQ_MAX_OFFSET (BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER - 1)
#define BSP_PROCESSOR_IRQ_NUMBER 1
#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_PCI_IRQ_MAX_OFFSET+1)
#define BSP_PROCESSOR_IRQ_MAX_OFFSET (BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1)
/* summary */
#define BSP_IRQ_NUMBER (BSP_PCI_IRQ_NUMBER + BSP_PROCESSOR_IRQ_NUMBER)
#define BSP_LOWEST_OFFSET 0
#define BSP_MAX_OFFSET (BSP_LOWEST_OFFSET + BSP_IRQ_NUMBER - 1)
#define BSP_DECREMENTER BSP_PROCESSOR_IRQ_LOWEST_OFFSET
#define BSP_UART_COM1_IRQ BSP_IRQ_GPP_0
#define BSP_UART_COM2_IRQ BSP_IRQ_GPP_0
#ifndef ASM
#ifdef __cplusplus
extern "C" {
#endif
#include <bsp/irq_supp.h>
int BSP_irq_is_enabled_at_pic(rtems_irq_number irq);
/* set priority of an interrupt; must not be called from ISR level */
int BSP_irq_set_priority(rtems_irq_number irq, rtems_irq_prio pri);
/* Not for public use */
void BSP_rtems_irq_mng_init(unsigned cpuId);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@@ -0,0 +1,112 @@
/* irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*
* CopyRight (C) 1999 valette@crf.canon.fr
*
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
* to make it valid for MVME2300 Motorola boards.
*
* Modified by T. Straumann for the 'beatnik' BSP.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/vectors.h>
#include <rtems/bspIo.h>
#if 0
#include <libcpu/io.h>
#include <libcpu/spr.h>
#include <bsp/pci.h>
#include <bsp/residual.h>
#include <bsp/openpic.h>
#include <bsp/irq.h>
#include <bsp.h>
#include <bsp/motorola.h>
#endif
/*
#define SHOW_ISA_PCI_BRIDGE_SETTINGS
*/
extern unsigned int external_exception_vector_prolog_code_size[];
extern void external_exception_vector_prolog_code(void);
extern unsigned int decrementer_exception_vector_prolog_code_size[];
extern void decrementer_exception_vector_prolog_code(void);
/*
* default handler
*/
static void nop_func(void *arg){}
static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
static rtems_irq_global_settings initial_config;
static rtems_irq_prio rtemsPrioTbl[BSP_IRQ_NUMBER];
static rtems_irq_connect_data defaultIrq = {
name: 0,
hdl: nop_func,
handle: 0,
on: 0,
off: 0,
isOn: 0
};
/*
* This code assumes the exceptions management setup has already
* been done. We just need to replace the exceptions that will
* be handled like interrupt. On mcp750/mpc750 and many PPC processors
* this means the decrementer exception and the external exception.
*/
void BSP_rtems_irq_mng_init(unsigned cpuId)
{
int i;
/*
* First initialize the Interrupt management hardware
*/
/*
* Initialize Rtems management interrupt table
*/
/*
* re-init the rtemsIrq table
*/
for (i = BSP_LOWEST_OFFSET; i <= BSP_MAX_OFFSET; i++) {
rtemsIrq[i] = defaultIrq;
rtemsIrq[i].name = i;
rtemsPrioTbl[i] = BSP_IRQ_DEFAULT_PRIORITY;
}
/*
* Init initial Interrupt management config
*/
initial_config.irqNb = BSP_IRQ_NUMBER;
initial_config.defaultEntry = defaultIrq;
initial_config.irqHdlTbl = rtemsIrq;
initial_config.irqBase = BSP_LOWEST_OFFSET;
initial_config.irqPrioTbl = rtemsPrioTbl;
if (!BSP_rtems_irq_mngt_set(&initial_config)) {
/*
* put something here that will show the failure...
*/
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
}
#ifdef TRACE_IRQ_INIT
printk("RTEMS IRQ management is now operationnal\n");
#endif
}

View File

@@ -0,0 +1,167 @@
/* Init
*
* This routine is the initialization task for this test program.
* It is called from init_exec and has the responsibility for creating
* and starting the tasks that make up the test. If the time of day
* clock is required for the test, it should also be set to a known
* value by this function.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* OAR init.c Template modified by T. Straumann who provided
* the implementation of this application.
*
* init.c,v 1.12.4.1 2003/09/04 18:46:30 joel Exp
*/
#define CONFIGURE_INIT
#include <rtems.h>
/* functions */
rtems_task Init(
rtems_task_argument argument
);
/* configuration information */
#include <bsp.h> /* for device driver prototypes */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM
#include <confdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <bsp/irq.h>
#include <rtems/bspIo.h>
void noop(){}
int connected() {return 1;}
rtems_irq_connect_data blah = { 0, 0, noop, noop, connected };
extern void discovery_pic_set_debug_irq();
#define WIRE_IRQ (BSP_IRQ_GPP_0 + 6)
#define ABRT_IRQ (BSP_IRQ_GPP_0 + 2)
static volatile int testno=0;
static volatile int wloops =0;
static volatile int aloops =0;
void wire_hdl()
{
if ( 1 == testno ) {
BSP_disable_irq_at_pic(WIRE_IRQ);
}
if ( 2 == testno || 3 == testno ) {
discovery_pic_set_debug_irq(0);
printk("WIRE -- this message should be printed %s\n", 3==testno ? "FIRST":"SECOND");
} else {
}
/* assume the driver checks for less than 1000 loops */
if ( ++wloops > 1000) {
printk("wire IRQ. FAILURE -- driver couldn't catch runaway ISR. Disabling IRQ source.\n");
discovery_pic_set_debug_irq(0);
BSP_disable_irq_at_pic(WIRE_IRQ);
}
/*
*/
}
void abrt_hdl()
{
aloops++;
if ( 2 == testno || 3 == testno ) {
discovery_pic_set_debug_irq(1);
printk("ABRT -- this message should be printed %s\n", 2==testno ? "FIRST":"SECOND");
} else
printk("ABRT IRQ\n");
if ( 1== testno ) {
BSP_enable_irq_at_pic(WIRE_IRQ);
}
BSP_disable_irq_at_pic(ABRT_IRQ);
}
rtems_task Init(
rtems_task_argument ignored
)
{
blah.name = WIRE_IRQ;
blah.hdl = wire_hdl;
if (!BSP_install_rtems_irq_handler(&blah)) {
fprintf(stderr,"installing handler 1 failed\n");
}
blah.name = ABRT_IRQ;
blah.hdl = abrt_hdl;
if (!BSP_install_rtems_irq_handler(&blah)) {
fprintf(stderr,"installing handler 2 failed\n");
}
printf("Hello, testing the ISR dispatcher...\n");
printf(" 1. Trying to catch runaway interrupt\n");
printf(" If the system freezes, the test failed!\n");
fflush(stdout); sleep(1);
aloops = wloops = 0;
discovery_pic_set_debug_irq(1);
printf(" >>> %s\n", wloops<1000 ? "SUCCESS" : "FAILED");
discovery_pic_set_debug_irq(0);
testno++;
printf(" 2. Testing enabling / disabling interrupt from ISR\n");
printf(" Hit the ABORT key for this test\n");
fflush(stdout); sleep(1);
aloops = wloops = 0;
BSP_disable_irq_at_pic(WIRE_IRQ);
BSP_irq_set_priority(ABRT_IRQ,1);
BSP_enable_irq_at_pic(ABRT_IRQ);
discovery_pic_set_debug_irq(1);
while (!aloops)
;
discovery_pic_set_debug_irq(0);
sleep(2);
printf(" >>> disabling ABRT IRQ from isr %s\n", 1==aloops ? "SUCCESS":"FAILURE");
printf(" flashing WIRE IRQ from isr %s\n", 1==wloops ? "SUCCESS":"FAILURE");
testno++;
printf(" 3. Testing interrupt priorities\n");
BSP_irq_set_priority(ABRT_IRQ,2);
BSP_irq_set_priority(WIRE_IRQ,2);
BSP_enable_irq_at_pic(ABRT_IRQ);
BSP_enable_irq_at_pic(WIRE_IRQ);
printf(" Hit the ABORT key for this test\n");
fflush(stdout); sleep(1);
aloops = wloops = 0;
while (!aloops)
;
sleep(2);
testno++;
printf(" Now we are raising the priority of the wire interrupt\n");
BSP_irq_set_priority(WIRE_IRQ,3);
BSP_enable_irq_at_pic(ABRT_IRQ);
printf(" Hit the ABORT key for this test\n");
fflush(stdout); sleep(1);
aloops = wloops = 0;
while (!aloops)
;
sleep(2);
printf( "That's it; we're done...\n" );
exit( 0 );
}

View File

@@ -0,0 +1,37 @@
#
# Config file for the PowerPC 745x based mvmexxxx
#
#
include $(RTEMS_ROOT)/make/custom/default.cfg
RTEMS_CPU=powerpc
RTEMS_CPU_MODEL=mpc7455
RTEMS_PPC_EXCEPTION_PROCESSING_MODEL=new
# This is the actual bsp directory used during the build process.
RTEMS_BSP_FAMILY=beatnik
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
#
CPU_CFLAGS = -mcpu=7400 -D__ppc_generic
#T. Straumann; disable sdata=eabi for now until CEXP supports it -meabi -msdata=eabi
# optimize flag: typically -0, could use -O4 or -fast
# -O4 is ok for RTEMS
# NOTE: some level of -O may be actually required by inline assembler
#CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions
CFLAGS_OPTIMIZE_V = -O2 -g
# debug flags: typically none, but at least -O1 is required due to this
# BSP using inlined code
CFLAGS_DEBUG_V = -O1 -g
define bsp-post-link
$(default-bsp-post-link)
$(OBJCOPY) -Obinary $@ $(basename $@)$(DOWNEXT)
endef
# Miscellaneous additions go here
START_BASE = motld_start

View File

@@ -0,0 +1,151 @@
/* $Id$ */
/*
* Acknowledgements:
* Valuable information was obtained from the following drivers
* netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
* linux: (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
* rtems: (C) Brookhaven National Laboratory; K. Feng
* but this implementation is original work by the author.
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/gtreg.h>
#include <bsp/pci.h>
#ifndef PCI_VENDOR_ID_MARVELL
#define PCI_VENDOR_ID_MARVELL 0x11ab
#endif
#ifndef PCI_DEVICE_ID_MARVELL_GT64260
#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
#endif
#ifndef PCI_DEVICE_ID_MARVELL_MV64360
#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
#endif
#if 0
#define MV64x60_PCI0_CONFIG_ADDR (BSP_MV64x60_BASE + 0xcf8)
#define MV64x60_PCI0_CONFIG_DATA (BSP_MV64x60_BASE + 0xcfc)
/* read from bus/slot/fn 0/0/0 */
static unsigned long
pci_early_config_read(int offset, int width)
{
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(0<<8)|(PCI_DEVFN(0,0)<<16)|((offset&~3)<<24));
switch (width) {
default:
case 1:
return in_8((unsigned char*)pci.pci_config_data + (offset&3));
case 2:
return in_le16((unsigned short*)pci.pci_config_data + (offset&3));
case 4:
return in_le32((unsigned long *)pci.pci_config_data + (offset&3));
}
}
#endif
DiscoveryVersion
BSP_getDiscoveryVersion(int assertion)
{
static DiscoveryVersion rval = unknown;
if ( unknown ==rval ) {
unsigned char dc;
unsigned short ds;
/* this must work before and after the call to BSP_pciInitialize() --
* since the host bridge is at 0,0,0 it doesn't matter if the hosed
* access methods are installed or not (as a matter of fact this shouldn't
* matter for any device on hose 0)
*/
printk("config addr is 0x%08x\n", BSP_pci_configuration.pci_config_addr);
printk("config data is 0x%08x\n", BSP_pci_configuration.pci_config_data);
pci_read_config_word(0,0,0,PCI_VENDOR_ID, &ds);
if ( PCI_VENDOR_ID_MARVELL != ds ) {
if ( assertion ) {
printk("Host bridge vendor id: 0x%04x\n",ds);
BSP_panic("Host bridge vendor @ pci(0,0,0) is not MARVELL");
}
else return unknown;
}
pci_read_config_word(0,0,0,PCI_DEVICE_ID, &ds);
pci_read_config_byte(0,0,0,PCI_REVISION_ID, &dc);
switch (ds) {
case PCI_DEVICE_ID_MARVELL_MV64360:
rval = MV_64360;
break;
case PCI_DEVICE_ID_MARVELL_GT64260:
switch (dc) {
default:
break;
case 0x10:
return (rval = GT_64260_A);
case 0x20:
return (rval = GT_64260_B);
}
default:
if ( assertion ) {
printk("Marvell device id 0x%04x, revision 0x%02x; check %s:%u\n",
ds, dc,
__FILE__,__LINE__);
BSP_panic("Unknown Marvell bridge or revision@ pci(0,0,0) is not MARVELL");
}
break;
}
}
return rval;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,412 @@
/* $Id$ */
/* Driver for discovery timers and watchdog */
/*
* Acknowledgements:
* Valuable information was obtained from the following drivers
* netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
* linux: (C) MontaVista, Software, Inc; Mark A. Greer.
* rtems: (C) Brookhaven National Laboratory; K. Feng
* but this implementation is original work by the author.
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <bsp/gtreg.h>
#include <libcpu/io.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <rtems/bspIo.h>
#include <stdint.h>
#include "gt_timer.h"
#define DEBUG
static inline uint32_t gt_rd(uint32_t off)
{
return in_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off) );
}
static inline void gt_wr(uint32_t off, uint32_t val)
{
out_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off), val);
}
static inline uint32_t gt_timer_bitmod(uint32_t off, uint32_t clr, uint32_t set)
{
unsigned flags;
uint32_t rval;
rtems_interrupt_disable(flags);
rval = gt_rd( off );
gt_wr( off, (rval & ~clr) | set );
rtems_interrupt_enable(flags);
return rval;
}
#define GT_TIMER_MAX 3
#define TIMER_ARGCHECK(t) do { if ((t)<0 || (t)>GT_TIMER_MAX) return -1; } while (0)
static struct {
void (*isr)(void *);
void *arg;
} gt_timer_isrs[GT_TIMER_MAX+1] = {{0},};
uint32_t BSP_timer_read(uint32_t timer)
{
TIMER_ARGCHECK(timer);
return gt_rd(GT_TIMER_0 + (timer<<2));
}
int
BSP_timer_start(uint32_t timer, uint32_t period)
{
TIMER_ARGCHECK(timer);
gt_wr(GT_TIMER_0 + (timer<<2), period);
return 0;
}
int
BSP_timer_stop(uint32_t timer)
{
TIMER_ARGCHECK(timer);
/* disable, clear period, re-enable */
gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Enb << (timer<<3), 0);
gt_wr(GT_TIMER_0 + (timer<<2), 0);
gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Enb << (timer<<3));
return 0;
}
int
BSP_timer_setup(uint32_t timer, void (*isr)(void *arg), void *arg, int reload)
{
TIMER_ARGCHECK(timer);
if ( isr && gt_timer_isrs[timer].isr )
return -1;
BSP_timer_stop(timer);
/* mask and clear */
gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, GT_TIMER_0_Intr<<timer, 0);
gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, GT_TIMER_0_Intr<<timer, 0);
/* set reload bit */
if ( reload )
gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Rld << (timer<<3));
else
gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Rld << (timer<<3), 0);
asm volatile("":::"memory");
if ( isr ) {
gt_timer_isrs[timer].isr = isr;
gt_timer_isrs[timer].arg = arg;
asm volatile("":::"memory");
gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, 0, GT_TIMER_0_Intr<<timer);
} else {
gt_timer_isrs[timer].isr = 0;
gt_timer_isrs[timer].arg = 0;
}
return 0;
}
static void
gt_timer_hdl(rtems_irq_hdl_param arg)
{
int iarg = (int)arg;
int timer;
uint32_t bit;
for ( ; iarg; iarg >>= 4 ) {
timer = (iarg & 0xf)-1;
bit = GT_TIMER_0_Intr<<timer;
if ( gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, bit, 0) & bit ) {
/* cause was set */
if ( ! gt_timer_isrs[timer].isr ) {
printk("gt_timer: warning; no ISR connected but and IRQ happened (timer # %i)\n", timer);
/* mask */
gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, bit, 0);
} else {
gt_timer_isrs[timer].isr(gt_timer_isrs[timer].arg);
}
}
}
}
int
BSP_timers_initialize(void)
{
rtems_irq_connect_data xx = {0};
int i, ainc, arg;
xx.hdl = gt_timer_hdl;
xx.on = 0;
xx.off = 0;
xx.isOn = 0;
switch (BSP_getDiscoveryVersion(0)) {
case MV_64360:
i = 3;
ainc = 1;
arg = 4;
break;
default:
i = 1;
ainc = 0x0202;
arg = 0x0403;
break;
}
for ( ; i>=0; i--, arg-=ainc ) {
xx.name = BSP_IRQ_TIME0_1 + i;
xx.handle = (rtems_irq_hdl_param)arg;
if ( !BSP_install_rtems_irq_handler(&xx) )
return -1;
}
return 0;
}
int
BSP_timers_uninstall(void)
{
rtems_irq_connect_data xx = {0};
int i;
xx.hdl = gt_timer_hdl;
xx.on = 0;
xx.off = 0;
xx.isOn = 0;
for ( i=0; i<= GT_TIMER_MAX; i++ ) {
if ( BSP_timer_setup(i, 0, 0, 0) )
return -1;
}
switch (BSP_getDiscoveryVersion(0)) {
case MV_64360:
i = 3;
break;
default:
i = 1;
break;
}
for ( ; i >= 0; i-- ) {
xx.name = BSP_IRQ_TIME0_1 + i;
BSP_get_current_rtems_irq_handler(&xx);
if ( !BSP_remove_rtems_irq_handler(&xx) )
return -1;
}
return 0;
}
uint32_t
BSP_timer_clock_get(uint32_t timer)
{
return BSP_bus_frequency;
}
int BSP_timer_instances(void)
{
return GT_TIMER_MAX + 1;
}
#ifdef DEBUG
void BSP_timer_test_isr(void *arg)
{
printk("TIMER IRQ (user arg 0x%x)\n",arg);
}
#endif
/* On a 64260A we can't read the status (on/off), apparently
* so we maintain it locally and assume the firmware has
* not enabled the dog initially...
*/
static uint32_t wdog_on = 0x00ffffff;
static uint32_t rd_wdcnf(void)
{
uint32_t cnf = gt_rd(GT_WDOG_Config);
/* BSD driver says that on the 64260A we always
* read 0xffffffff so we have to maintain the
* status locally (and hope we get the initial
* value right).
*/
if ( ~0 == cnf )
cnf = wdog_on;
return cnf;
}
/* change on/off state assume caller has IRQs disabled */
static void dog_toggle(uint32_t ctl)
{
ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
| GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1a);
gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1b);
}
static void dog_pet(uint32_t ctl)
{
ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
| GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2a);
gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2b);
}
/* Enable watchdog and set a timeout (in us)
* a timeout of 0xffffffff selects the old/existing
* timeout.
*
* RETURNS 0 on success
*/
int
BSP_watchdog_enable(uint32_t timeout_us)
{
unsigned long long x = timeout_us;
unsigned flags;
uint32_t ctl;
x *= BSP_bus_frequency;
x /= 256; /* there seems to be a prescaler */
x /= 1000000; /* us/s */
if ( x > (1<<24)-1 )
x = (1<<24)-1;
if ( 0xffffffff != timeout_us )
timeout_us = x;
rtems_interrupt_disable(flags);
ctl = rd_wdcnf();
/* if enabled, disable first */
if ( GT_WDOG_Config_Enb & ctl ) {
dog_toggle(ctl);
}
if ( 0xffffffff == timeout_us ) {
timeout_us = ctl & ((1<<24)-1);
dog_toggle(ctl);
dog_pet(ctl);
} else {
gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1a);
gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1b);
}
wdog_on = GT_WDOG_Config_Enb | timeout_us;
rtems_interrupt_enable(flags);
return 0;
}
/* Disable watchdog
* RETURNS 0 on success
*/
int BSP_watchdog_disable(void)
{
unsigned long flags;
uint32_t ctl;
rtems_interrupt_disable(flags);
ctl = rd_wdcnf();
if ( (GT_WDOG_Config_Enb & ctl) ) {
dog_toggle(ctl);
wdog_on = ctl & ~(GT_WDOG_Config_Enb);
}
rtems_interrupt_enable(flags);
return 0;
}
/* Check status -- unfortunately there seems to be no way
* to read the running value...
*
* RETURNS nonzero if enabled/running, zero if disabled/stopped
*/
int BSP_watchdog_status(void)
{
uint32_t ctl = rd_wdcnf();
/* report also the current period */
return GT_WDOG_Config_Enb & ctl ? ctl : 0;
}
/* Pet the watchdog (rearm to configured timeout)
* RETURNS: 0 on success, nonzero on failure (watchdog
* currently not running).
*/
int BSP_watchdog_pet(void)
{
unsigned long flags;
if ( !wdog_on )
return -1;
rtems_interrupt_disable(flags);
dog_pet(rd_wdcnf());
rtems_interrupt_enable(flags);
return 0;
}
#ifdef DEBUG_MODULAR
int
_cexpModuleFinalize(void *unused)
{
BSP_watchdog_disable();
return BSP_timers_uninstall();
}
void
_cexpModuleInitialize(void *unused)
{
BSP_timers_initialize();
}
#endif

View File

@@ -0,0 +1,134 @@
#ifndef BSP_GT_TIMER_H
#define BSP_GT_TIMER_H
/* $Id$ */
/* Support for hardware timers in the discovery bridge */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Obtain the number of hardware timers present
* The 'timer' argument in the routines below addresses
* one of 0..(BSP_timer_instances()-1)
*/
int BSP_timer_instances(void);
/* Setup timer but don't start yet; interrupts are enabled if an isr argument is passed
* no interrupts are generated otherwise.
*
* If 'reload' is nonzero then the period is automatically restarted.
*
* RETURNS: 0 on success, nonzero on error (argument error)
*
* NOTE: If an ISR is already connected, it must be removed by passing a NULL isr first.
*/
int BSP_timer_setup(uint32_t timer, void (*isr)(void *arg), void *arg, int reload);
/* Stop timer;
*
* RETURNS: 0 on success, nonzero on argument error
*/
int BSP_timer_stop(uint32_t timer);
/* Start timer with 'period' (in ticks)
*
* RETURNS: 0 on success, nonzero on argument error
*/
int BSP_timer_start(uint32_t timer, uint32_t period);
/* read decrementing timer on the fly
*
* RETURNS: current count in ticks
*/
uint32_t BSP_timer_read(uint32_t timer);
/* get clock rate in Hz */
uint32_t BSP_timer_clock_get(uint32_t timer);
/* Initialize timer facility -- to be used by BSP implementors only
*
* RETURNS: 0 on success, nonzero if ISR wrapper couldn't be installed
*/
int BSP_timers_initialize(void);
/* WATCHDOG TIMER (resets board if enabled and not 'petted' for
* some time).
*/
/* Enable watchdog and set a timeout (in us)
* RETURNS 0 on success
*/
int BSP_watchdog_enable(uint32_t timeout_us);
/* Disable watchdog
* RETURNS 0 on success
*/
int BSP_watchdog_disable(void);
/* Check status -- unfortunately there seems to be no way
* to read the running value...
*
* RETURNS nonzero if enabled/running, zero if disabled/stopped
*/
int BSP_watchdog_status(void);
/* Pet the watchdog (rearm to configured timeout)
* RETURNS: 0 on success, nonzero on failure (watchdog
* currently not running).
*/
int BSP_watchdog_pet(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,447 @@
/* $NetBSD: gti2c.c,v 1.2 2005/02/27 00:27:21 perry Exp $ */
/*
* Copyright (c) 2005 Brocade Communcations, inc.
* All rights reserved.
*
* Written by Matt Thomas for Brocade Communcations, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Brocade Communications, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL EITHER BROCADE COMMUNICATIONS, INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Fixed many things + ported to RTEMS by Till Straumann, 2005 */
#include <stdio.h>
#include <rtems.h>
#include <libcpu/io.h>
#include <sys/errno.h>
#include <rtems/bspIo.h>
#include <rtems/score/sysstate.h>
#include <bsp/irq.h>
#include <rtems/libi2c.h>
#include <sys/cdefs.h>
#include <bsp/gtintrreg.h>
#include <bsp/gti2creg.h>
#include <bsp/gti2c_busdrv.h>
#define ENABLE_IRQ_AT_PIC_HACK /* workaround for a bad HW bug */
#undef DEBUG
#ifndef BSP_IRQ_MIN_PRIO
#define BSP_IRQ_MIN_PRIO 1
#endif
struct gti2c_softc {
uint32_t sc_gt;
uint32_t sc_cntl;
int sc_inited;
rtems_id sc_sync;
int sc_irqs; /* statistics */
};
#ifdef DEBUG
#define STATIC
#else
#define STATIC static
#endif
typedef struct {
rtems_libi2c_bus_t bus_desc;
struct gti2c_softc pvt;
} gti2c_desc_rec, *gti2c_desc;
STATIC rtems_status_code
gt_i2c_init(rtems_libi2c_bus_t *bh);
STATIC rtems_status_code
gt_i2c_send_start(rtems_libi2c_bus_t *bh);
STATIC rtems_status_code
gt_i2c_send_stop(rtems_libi2c_bus_t *bh);
STATIC rtems_status_code
gt_i2c_send_addr(rtems_libi2c_bus_t *bh, uint32_t addr, int rw);
STATIC int
gt_i2c_read_bytes(rtems_libi2c_bus_t *bh, unsigned char *buf, int len);
STATIC int
gt_i2c_write_bytes(rtems_libi2c_bus_t *bh, unsigned char *buf, int len);
static rtems_libi2c_bus_ops_t myops = {
init: gt_i2c_init,
send_start: gt_i2c_send_start,
send_stop: gt_i2c_send_stop,
send_addr: gt_i2c_send_addr,
read_bytes: gt_i2c_read_bytes,
write_bytes: gt_i2c_write_bytes,
};
static gti2c_desc_rec my_bus_tbl = {
{
ops: &myops,
size: sizeof(my_bus_tbl),
},/* public fields */
{
sc_gt: BSP_MV64x60_BASE,
sc_cntl: I2C_Control_TWSIEn,
sc_inited: 0,
sc_sync: 0
} /* our private fields */
};
static inline uint32_t
gt_read(uint32_t base, uint32_t off)
{
return in_le32((volatile unsigned*)(base+off));
}
static inline void
gt_write(uint32_t base, uint32_t off, uint32_t val)
{
out_le32((volatile unsigned*)(base+off), val);
}
static inline void
disable_irq(struct gti2c_softc *sc)
{
uint32_t v = gt_read(sc->sc_gt, I2C_REG_Control);
gt_write(sc->sc_gt, I2C_REG_Control, v & ~I2C_Control_IntEn);
}
static rtems_status_code
gt_i2c_wait(struct gti2c_softc *sc, uint32_t control, uint32_t desired_status)
{
uint32_t status;
rtems_status_code rval;
control |= I2C_Control_IntEn;
gt_write(sc->sc_gt, I2C_REG_Control, control | sc->sc_cntl);
if ( sc->sc_inited ) {
#ifdef ENABLE_IRQ_AT_PIC_HACK
BSP_enable_irq_at_pic(BSP_IRQ_I2C);
#endif
rval = rtems_semaphore_obtain(sc->sc_sync, RTEMS_WAIT, 100);
if ( RTEMS_SUCCESSFUL != rval )
return rval;
} else {
uint32_t then, now;
/* run in polling mode - useful during init */
if ( _System_state_Is_up(_System_state_Get()) ) {
printk("WARNING: gti2c running in polled mode -- should initialize properly!\n");
}
asm volatile("mftb %0":"=r"(then));
do {
asm volatile("mftb %0":"=r"(now));
/* poll timebase for .2 seconds assuming a bus clock of 100MHz */
if ( now - then > (uint32_t)100000000/4/5 )
return RTEMS_TIMEOUT;
} while ( ! (I2C_Control_IFlg & gt_read(sc->sc_gt, I2C_REG_Control)) );
}
status = gt_read(sc->sc_gt, I2C_REG_Status);
if ( status != desired_status && (status!=I2C_Status_ReStarted || desired_status!=I2C_Status_Started) )
return RTEMS_IO_ERROR;
return RTEMS_SUCCESSFUL;
}
static void
gt_i2c_intr(void *arg)
{
struct gti2c_softc * const sc = &my_bus_tbl.pvt;
uint32_t v;
v = gt_read(sc->sc_gt, I2C_REG_Control);
if ((v & I2C_Control_IFlg) == 0) {
printk("gt_i2c_intr: IRQ but IFlg not set??\n");
return;
}
gt_write(sc->sc_gt, I2C_REG_Control, v & ~(I2C_Control_IntEn));
#if 0
gt_read(sc->sc_gt, I2C_REG_Control);
asm volatile("sync");
/* This is how bad it is: after turning off the IntEn bit, the line
* still remains asserted! (shame on you.)
*
* The test below (on MVME6100; the MVME5500 has the same problem
* but the main cause register address is different; substitute
* 0xf100000c for 0xf1000c68 on a 5500).
*
* The skew was 101 TB ticks or ~3us (bus freq 133MHz) which
* really sucks.
*
* Therefore, we must disable the interrupt at the PIC
*/
{unsigned from,to;
asm volatile("mftb %0":"=r"(from));
while ( in_le32((volatile unsigned*)0xf100000c) & 0x20 )
;
asm volatile("mftb %0":"=r"(to));
printk("I2C IRQ remained asserted for %i TB ticks!\n",to-from);
}
#endif
#ifdef ENABLE_IRQ_AT_PIC_HACK
BSP_disable_irq_at_pic(BSP_IRQ_I2C);
#endif
sc->sc_irqs++;
rtems_semaphore_release(sc->sc_sync);
}
STATIC rtems_status_code
gt_i2c_init(rtems_libi2c_bus_t *bh)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
unsigned m,n,N;
disable_irq(sc);
/* reset */
gt_write(sc->sc_gt, I2C_REG_SoftReset, 0);
gt_write(sc->sc_gt, I2C_REG_SlaveAddr, 0);
gt_write(sc->sc_gt, I2C_REG_ExtSlaveAddr, 0);
/* Set baud rate; I don't know the details
* but have to assume that it has to fit into 7 bits
* (as indicated by some experiment)
*/
n = 0, N=1<<n;
do {
n++, N<<=1;
/* increase 2^n until m becomes small enough */
m = BSP_bus_frequency / 10 / 62500 / N;
} while ( m > 16 );
/* n is at least 1 */
if ( n > 8 ) {
n = 8; m = 16; /* nothing else we can do */
}
if ( 0 == m )
m = 1; /* nothing we can do */
gt_write(sc->sc_gt, I2C_REG_BaudRate, I2C_BaudRate(m-1, n-1));
if ( !sc->sc_inited ) {
if ( _System_state_Is_up(_System_state_Get()) ) {
rtems_irq_connect_data ii = {
name: BSP_IRQ_I2C,
hdl: gt_i2c_intr,
on: 0,
off: 0,
isOn: 0
};
rtems_status_code err;
/* synchronization semaphore */
err = rtems_semaphore_create(
rtems_build_name('g','i','2','c'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_LOCAL,
0,
&sc->sc_sync);
if ( err ) {
sc->sc_sync = 0;
return err;
}
if ( !BSP_install_rtems_irq_handler(&ii) ) {
fprintf(stderr,"Unable to install interrupt handler\n");
rtems_semaphore_delete(sc->sc_sync);
return RTEMS_INTERNAL_ERROR;
}
BSP_irq_set_priority(BSP_IRQ_I2C, BSP_IRQ_MIN_PRIO);
sc->sc_inited = 1;
} else {
}
} else {
rtems_semaphore_flush(sc->sc_sync);
}
return RTEMS_SUCCESSFUL;
}
STATIC rtems_status_code
gt_i2c_send_start(rtems_libi2c_bus_t *bh)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
return gt_i2c_wait(sc, I2C_Control_Start, I2C_Status_Started);
}
STATIC rtems_status_code
gt_i2c_send_stop(rtems_libi2c_bus_t *bh)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
uint32_t data;
data = gt_read(sc->sc_gt, I2C_REG_Status);
if ( I2C_Status_Started == data || I2C_Status_ReStarted == data ) {
/* According to the spec, a void message (start - stop sequence)
* is illegal and indeed, the chip plays bad tricks with us, i.e.,
* sometimes it hangs the bus so that it remains idle forever.
* so we have to address someone...
*/
gt_i2c_send_addr(bh, /*just something... */ 8, 1);
data = gt_read(sc->sc_gt, I2C_REG_Status);
}
if ( I2C_Status_AddrReadAck == data ) {
/* Another thing: spec says that the master generates stop only after
* not acknowledging the last byte. Again, the chip doesn't like
* to be stopped in this condition - hence we just do it the favor
* and read a single byte...
*/
gt_i2c_read_bytes(bh, (unsigned char *)&data, 1);
}
gt_write(sc->sc_gt, I2C_REG_Control, I2C_Control_Stop | sc->sc_cntl);
/* should we poll for idle? There seems to be in IRQ when this completes */
return RTEMS_SUCCESSFUL;
}
STATIC rtems_status_code
gt_i2c_send_addr(rtems_libi2c_bus_t *bh, uint32_t addr, int rw)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
uint32_t data, wanted_status;
uint8_t read_mask = rw ? 1 : 0;
rtems_status_code error;
if (read_mask) {
wanted_status = I2C_Status_AddrReadAck;
} else {
wanted_status = I2C_Status_AddrWriteAck;
}
/*
* First byte contains whether this xfer is a read or write.
*/
data = read_mask;
if (addr > 0x7f) {
/*
* If this is a 10bit request, the first address byte is
* 0b11110<b9><b8><r/w>.
*/
data |= 0xf0 | ((addr & 0x300) >> 7);
gt_write(sc->sc_gt, I2C_REG_Data, data);
error = gt_i2c_wait(sc, 0, wanted_status);
if (error)
return error;
/*
* The first address byte has been sent, now to send
* the second one.
*/
if (read_mask) {
wanted_status = I2C_Status_2ndAddrReadAck;
} else {
wanted_status = I2C_Status_2ndAddrWriteAck;
}
data = (uint8_t) addr;
} else {
data |= (addr << 1);
}
gt_write(sc->sc_gt, I2C_REG_Data, data);
return gt_i2c_wait(sc, 0, wanted_status);
}
STATIC int
gt_i2c_read_bytes(rtems_libi2c_bus_t *bh, unsigned char *buf, int len)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
rtems_status_code error;
register unsigned char *p=buf;
while ( len-- > 0 ) {
error = gt_i2c_wait(
sc,
len ? I2C_Control_ACK : 0,
len ? I2C_Status_MasterReadAck : I2C_Status_MasterReadNoAck);
if ( error ) {
return -error;
}
*p++ = gt_read(sc->sc_gt, I2C_REG_Data);
}
return p-buf;
}
STATIC int
gt_i2c_write_bytes(rtems_libi2c_bus_t *bh, unsigned char *buf, int len)
{
struct gti2c_softc * const sc = &((gti2c_desc)bh)->pvt;
int rval = 0;
rtems_status_code error;
while ( len-- > 0 ) {
gt_write(sc->sc_gt, I2C_REG_Data, buf[rval]);
error = gt_i2c_wait(sc, 0, I2C_Status_MasterWriteAck);
if ( error ) {
return -error;
}
rval++;
}
return rval;
}
rtems_libi2c_bus_t *gt64260_i2c_bus_descriptor = &my_bus_tbl.bus_desc;
#ifdef DEBUG_MODULAR
void
_cexpModuleInitialize(void *arg)
{
gt_i2c_init(&gt64260_i2c_bus_descriptor->bus_desc);
}
int
_cexpModuleFinalize(void * arg)
{
struct gti2c_softc * const sc = &gt64260_i2c_bus_descriptor->pvt;
rtems_irq_connect_data ii = {
name: BSP_IRQ_I2C,
hdl: gt_i2c_intr,
on: noop,
off: noop,
isOn: inoop
};
rtems_semaphore_delete(sc->sc_sync);
return !BSP_remove_rtems_irq_handler(&ii);
}
#endif

View File

@@ -0,0 +1,62 @@
#ifndef GT_64260_BUS_DRIVER_H
#define GT_64260_BUS_DRIVER_H
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <rtems/libi2c.h>
/* for registration with libi2c */
extern rtems_libi2c_bus_t *gt64260_i2c_bus_descriptor;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,83 @@
/* $NetBSD: gti2creg.h,v 1.2 2005/02/27 00:27:21 perry Exp $ */
/*
* Copyright (c) 2005 Brocade Communcations, inc.
* All rights reserved.
*
* Written by Matt Thomas for Brocade Communcations, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Brocade Communications, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL EITHER BROCADE COMMUNICATIONS, INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DEV_MARVELL_GTI2CREG_H_
#define _DEV_MARVELL_GTI2CREG_H_
#define I2C_REG_SlaveAddr 0xc000
#define I2C_REG_ExtSlaveAddr 0xc010
#define I2C_REG_Data 0xc004
#define I2C_REG_Control 0xc008
#define I2C_REG_Status 0xc00c
#define I2C_REG_BaudRate 0xc00c
#define I2C_REG_SoftReset 0xc01c
#define I2C_SlaveAddr_GCE 0x0001 /* Act as Slave */
#define I2C_SlaveAddr_SAddr 0x7E
#define I2C_Control_ACK 0x04
#define I2C_Control_IFlg 0x08
#define I2C_Control_Stop 0x10
#define I2C_Control_Start 0x20
#define I2C_Control_TWSIEn 0x40
#define I2C_Control_IntEn 0x80
/*
* F(I2C) = F(Tclk) / ( 10 * (M + 1) * (2^(N+1)))
* For Tclk = 100MHz, M = 4, N = 4: F = 62.5KHz
* For Tclk = 100MHz, M = 13, N = 3: F = 96.2KHz
*/
#define I2C_BaudRate(M, N) (((M) << 3) | (N))
#define I2C_BaudRate_62_5K I2C_BaudRate(4, 4)
#define I2C_BaudRate_96_2K I2C_BaudRate(13, 3)
#define I2C_Status_BusError 0x00 /* Bus error */
#define I2C_Status_Started 0x08 /* Start condition xmitted */
#define I2C_Status_ReStarted 0x10 /* Repeated start condition xmitted */
#define I2C_Status_AddrWriteAck 0x18 /* Adr + wr bit xmtd, ack rcvd */
#define I2C_Status_AddrWriteNoAck 0x20 /* Adr + wr bit xmtd, NO ack rcvd */
#define I2C_Status_MasterWriteAck 0x28 /* Master xmtd data byte, ack rcvd */
#define I2C_Status_MasterWriteNoAck 0x30 /* Master xmtd data byte, NO ack rcvd*/
#define I2C_Status_MasterLostArb 0x38 /* Master lost arbitration during
address or data transfer */
#define I2C_Status_AddrReadAck 0x40 /* Adr + rd bit xmtd, ack rcvd */
#define I2C_Status_AddrReadNoAck 0x48 /* Adr + rd bit xmtd, NO ack rcvd */
#define I2C_Status_MasterReadAck 0x50 /* Master rcvd data bye, ack rcvd */
#define I2C_Status_MasterReadNoAck 0x58 /* Master rcvd data bye, NO ack rcvd */
#define I2C_Status_2ndAddrWriteAck 0xd0 /* 2nd adr + wr bit xmid, ack rcvd */
#define I2C_Status_2ndAddrWriteNoAck 0xd8 /* 2nd adr + wr bit xmid, NO ack rcvd */
#define I2C_Status_2ndAddrReadAck 0xe0 /* 2nd adr + rd bit xmid, ack rcvd */
#define I2C_Status_2ndAddrReadNoAck 0xe8 /* 2nd adr + rd bit xmtd, NO ack rcvd */
#define I2C_Status_Idle 0xf8 /* Idle */
#endif /* _DEV_MARVELL_GTI2CREG_H_ */

View File

@@ -0,0 +1,257 @@
/* $NetBSD: gtintrreg.h,v 1.3 2005/02/27 00:27:21 perry Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* gt64260intr.h: defines for GT-64260 system controller interrupts
*
* creation Sun Jan 7 18:05:59 PST 2001 cliff
*
* NOTE:
* Galileo GT-64260 manual bit defines assume Little Endian
* ordering of bits within bytes, i.e.
* bit #0 --> 0x01
* vs. Motorola Big Endian bit numbering where
* bit #0 --> 0x80
* Consequently we define bits in Little Endian format and plan
* to swizzle bytes during programmed I/O by using lwbrx/swbrx
* to load/store GT-64260 registers.
*/
#ifndef _DISCOVERY_GT64260INTR_H
#define _DISCOVERY_GT64260INTR_H
#define BIT(n) (1<<(n))
/*
* GT-64260 Interrupt Controller Register Map
*/
#define ICR_260_MIC_LO 0xc18 /* main interrupt cause low */
#define ICR_260_MIC_HI 0xc68 /* main interrupt cause high */
#define ICR_260_CIM_LO 0xc1c /* CPU interrupt mask low */
#define ICR_260_CIM_HI 0xc6c /* CPU interrupt mask high */
#define ICR_260_CSC 0xc70 /* CPU select cause */
#define ICR_260_P0IM_LO 0xc24 /* PCI_0 interrupt mask low */
#define ICR_260_P0IM_HI 0xc64 /* PCI_0 interrupt mask high */
#define ICR_260_P0SC 0xc74 /* PCI_0 select cause */
#define ICR_260_P1IM_LO 0xca4 /* PCI_1 interrupt mask low */
#define ICR_260_P1IM_HI 0xce4 /* PCI_1 interrupt mask high */
#define ICR_260_P1SC 0xcf4 /* PCI_1 select cause */
#define ICR_260_CI0M 0xe60 /* CPU int[0] mask */
#define ICR_260_CI1M 0xe64 /* CPU int[1] mask */
#define ICR_260_CI2M 0xe68 /* CPU int[2] mask */
#define ICR_260_CI3M 0xe6c /* CPU int[3] mask */
/*
* MV64360 Interrupt Controller Register Map
*/
#define ICR_360_MIC_LO 0x004 /* main interrupt cause low */
#define ICR_360_MIC_HI 0x00c /* main interrupt cause high */
#define ICR_360_C0IM_LO 0x014 /* CPU 0 interrupt mask low */
#define ICR_360_C0IM_HI 0x01c /* CPU 0 interrupt mask high */
#define ICR_360_C0SC 0x024 /* CPU 0 select cause */
#define ICR_360_C1IM_LO 0x034 /* CPU 1 interrupt mask low */
#define ICR_360_C1IM_HI 0x03c /* CPU 1 interrupt mask high */
#define ICR_360_C1SC 0x044 /* CPU 1 select cause */
#define ICR_360_I0M_LO 0x014 /* Int 0 mask low */
#define ICR_360_I0M_HI 0x01c /* Int 0 mask high */
#define ICR_360_I0SC 0x024 /* Int 0 select cause */
#define ICR_360_I1M_LO 0x034 /* Int 1 mask low */
#define ICR_360_I1M_HI 0x03c /* Int 1 mask high */
#define ICR_360_C1SC 0x044 /* Int 1 select cause */
/*
* IRQs:
* we define IRQs based on bit number in the
* ICU_LEN dimensioned hardware portion of the imask_t bit vector
* which consists of 64 bits of Main Cause and Mask register pairs
* (ICR_MIC_LO, ICR_MIC_HI and ICR_CIM_LO, ICR_CIM_HI)
* as well as 32 bits in GPP registers (see intr.h):
*
* IRQs:
* 31.............................0 63.............................32
* | | |
* imask_t index: | | |
* | | | |
* ^--------- IM_PIC_LO ----------^ ^------ IM_PIC_HI ------------^
* | | |
* Bitmasks: | | |
* | | | |
* ^--------- IML_* --------------^ ^------ IMH_* ----------------^
* | | |
* Registers: | | |
* | | | |
* ^--------- ICR_MIC_LO ---------^ ^------ ICR_MIC_HI -----------^
* ^--------- ICR_CIM_LO ---------^ ^------ ICR_CIM_HI -----------^
*
* IRQs:
* 95............................64 127............................96
* | | |
* imask_t index: | | |
* | | | |
* ^-------- IMASK_GPP ----------^ ^----- IMASK_SOFTINT --------^
* | | |
* Bitmasks: | | |
* | | | |
* ^--------- GPP_* --------------^ ^------ SIBIT(irq) -----------^
* | | |
* Registers: | | |
* | | | |
* ^--- GT_GPP_Interrupt_Cause ---^ ^------- (none) -----------^
* ^--- GT_GPP_Interrupt_Mask ---^
*
*
* Note that GPP interrupts are summarized in the Main Cause Register.
*
* Some IRQs are "resvered" undefined due to gaps in HW register utilization.
*/
#define IRQ_DEV 1 /* device interface interrupt */
#define IRQ_DMA 2 /* DMA addres error interrupt */
#define IRQ_CPU 3 /* CPU interface interrupt */
#define IRQ_IDMA0_1 4 /* IDMA ch. 0..1 complete interrupt */
#define IRQ_IDMA2_3 5 /* IDMA ch. 2..3 complete interrupt */
#define IRQ_IDMA4_5 6 /* IDMA ch. 4..5 complete interrupt */
#define IRQ_IDMA6_7 7 /* IDMA ch. 6..7 complete interrupt */
#define IRQ_TIME0_1 8 /* Timer 0..1 interrupt */
#define IRQ_TIME2_3 9 /* Timer 2..3 interrupt */
#define IRQ_TIME4_5 10 /* Timer 4..5 interrupt */
#define IRQ_TIME6_7 11 /* Timer 6..7 interrupt */
#define IRQ_PCI0_0 12 /* PCI 0 interrupt 0 summary */
#define IRQ_PCI0_1 13 /* PCI 0 interrupt 1 summary */
#define IRQ_PCI0_2 14 /* PCI 0 interrupt 2 summary */
#define IRQ_PCI0_3 15 /* PCI 0 interrupt 3 summary */
#define IRQ_PCI1_0 16 /* PCI 1 interrupt 0 summary */
#define IRQ_ECC 17 /* ECC error interrupt */
#define IRQ_PCI1_1 18 /* PCI 1 interrupt 1 summary */
#define IRQ_PCI1_2 19 /* PCI 1 interrupt 2 summary */
#define IRQ_PCI1_3 20 /* PCI 1 interrupt 3 summary */
#define IRQ_PCI0OUT_LO 21 /* PCI 0 outbound interrupt summary */
#define IRQ_PCI0OUT_HI 22 /* PCI 0 outbound interrupt summary */
#define IRQ_PCI1OUT_LO 23 /* PCI 1 outbound interrupt summary */
#define IRQ_PCI1OUT_HI 24 /* PCI 1 outbound interrupt summary */
#define IRQ_PCI0IN_LO 26 /* PCI 0 inbound interrupt summary */
#define IRQ_PCI0IN_HI 27 /* PCI 0 inbound interrupt summary */
#define IRQ_PCI1IN_LO 28 /* PCI 1 inbound interrupt summary */
#define IRQ_PCI1IN_HI 29 /* PCI 1 inbound interrupt summary */
#define IRQ_ETH0 (32+0) /* Ethernet controller 0 interrupt */
#define IRQ_ETH1 (32+1) /* Ethernet controller 1 interrupt */
#define IRQ_ETH2 (32+2) /* Ethernet controller 2 interrupt */
#define IRQ_SDMA (32+4) /* SDMA interrupt */
#define IRQ_I2C (32+5) /* I2C interrupt */
#define IRQ_BRG (32+7) /* Baud Rate Generator interrupt */
#define IRQ_MPSC0 (32+8) /* MPSC 0 interrupt */
#define IRQ_MPSC1 (32+10) /* MPSC 1 interrupt */
#define IRQ_COMM (32+11) /* Comm unit interrupt */
#define IRQ_GPP7_0 (32+24) /* GPP[7..0] interrupt */
#define IRQ_GPP15_8 (32+25) /* GPP[15..8] interrupt */
#define IRQ_GPP23_16 (32+26) /* GPP[23..16] interrupt */
#define IRQ_GPP31_24 (32+27) /* GPP[31..24] interrupt */
/*
* low word interrupt mask register bits
*/
#define IML_SUM BIT(0)
#define IML_DEV BIT(IRQ_DEV)
#define IML_DMA BIT(IRQ_DMA)
#define IML_CPU BIT(IRQ_CPU)
#define IML_IDMA0_1 BIT(IRQ_IDMA0_1)
#define IML_IDMA2_3 BIT(IRQ_IDMA2_3)
#define IML_IDMA4_5 BIT(IRQ_IDMA4_5)
#define IML_IDMA6_7 BIT(IRQ_IDMA6_7)
#define IML_TIME0_1 BIT(IRQ_TIME0_1)
#define IML_TIME2_3 BIT(IRQ_TIME2_3)
#define IML_TIME4_5 BIT(IRQ_TIME4_5)
#define IML_TIME6_7 BIT(IRQ_TIME6_7)
#define IML_PCI0_0 BIT(IRQ_PCI0_0)
#define IML_PCI0_1 BIT(IRQ_PCI0_1)
#define IML_PCI0_2 BIT(IRQ_PCI0_2)
#define IML_PCI0_3 BIT(IRQ_PCI0_3)
#define IML_PCI1_0 BIT(IRQ_PCI1_0)
#define IML_ECC BIT(IRQ_ECC)
#define IML_PCI1_1 BIT(IRQ_PCI1_1)
#define IML_PCI1_2 BIT(IRQ_PCI1_2)
#define IML_PCI1_3 BIT(IRQ_PCI1_3)
#define IML_PCI0OUT_LO BIT(IRQ_PCI0OUT_LO)
#define IML_PCI0OUT_HI BIT(IRQ_PCI0OUT_HI)
#define IML_PCI1OUT_LO BIT(IRQ_PCI1OUT_LO)
#define IML_PCI1OUT_HI BIT(IRQ_PCI1OUT_HI)
#define IML_PCI0IN_LO BIT(IRQ_PCI0IN_LO)
#define IML_PCI0IN_HI BIT(IRQ_PCI0IN_HI)
#define IML_PCI1IN_LO BIT(IRQ_PCI1IN_LO)
#define IML_PCI1IN_HI BIT(IRQ_PCI1IN_HI)
#define IML_RES (BIT(25)|BIT(30)|BIT(31))
/*
* high word interrupt mask register bits
*/
#define IMH_ETH0 BIT(IRQ_ETH0-32)
#define IMH_ETH1 BIT(IRQ_ETH1-32)
#define IMH_ETH2 BIT(IRQ_ETH2-32)
#define IMH_SDMA BIT(IRQ_SDMA-32)
#define IMH_I2C BIT(IRQ_I2C-32)
#define IMH_BRG BIT(IRQ_BRG-32)
#define IMH_MPSC0 BIT(IRQ_MPSC0-32)
#define IMH_MPSC1 BIT(IRQ_MPSC1-32)
#define IMH_COMM BIT(IRQ_COMM-32)
#define IMH_GPP7_0 BIT(IRQ_GPP7_0-32)
#define IMH_GPP15_8 BIT(IRQ_GPP15_8-32)
#define IMH_GPP23_16 BIT(IRQ_GPP23_16-32)
#define IMH_GPP31_24 BIT(IRQ_GPP31_24-32)
#define IMH_GPP_SUM (IMH_GPP7_0|IMH_GPP15_8|IMH_GPP23_16|IMH_GPP31_24)
#define IMH_RES (BIT(3) |BIT(6) |BIT(9) |BIT(12)|BIT(13)|BIT(14) \
|BIT(15)|BIT(16)|BIT(17)|BIT(18)|BIT(19)|BIT(20) \
|BIT(21)|BIT(22)|BIT(23)|BIT(28)|BIT(29)|BIT(30) \
|BIT(31))
/*
* ICR_CSC "Select Cause" register bits
*/
#define CSC_SEL BIT(30) /* HI/LO select */
#define CSC_STAT BIT(31) /* ? "irq active" : "irq none" */
#define CSC_CAUSE ~(CSC_SEL|CSC_STAT)
/*
* CPU Int[n] Mask bit(s)
*/
#define CPUINT_SEL 0x80000000 /* HI/LO select */
#endif /* _DISCOVERY_GT64260INTR_H */

View File

@@ -0,0 +1,964 @@
/* $NetBSD: gtpcireg.h,v 1.4 2005/12/11 12:22:16 christos Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DEV_GTPCIREG_H
#define _DEV_GTPCIREG_H
#define PCI__BIT(bit) (1U << (bit))
#define PCI__MASK(bit) (PCI__BIT(bit) - 1)
#define PCI__GEN(bus, off, num) (((off)^((bus) << 7))+((num) << 4))
#define PCI__EXT(data, bit, len) (((data) >> (bit)) & PCI__MASK(len))
#define PCI__CLR(data, bit, len) ((data) &= ~(PCI__MASK(len) << (bit)))
#define PCI__INS(bit, new) ((new) << (bit))
#define PCI_SYNC_REG(bus) (0xc0 | ((bus) << 3))
/*
* Table 185: PCI Slave ADDRess Decoding Register Map
*/
#define PCI_SCS0_BAR_SIZE(bus) PCI__GEN(bus, 0x0c08, 0)
#define PCI_SCS2_BAR_SIZE(bus) PCI__GEN(bus, 0x0c0c, 0)
#define PCI_CS0_BAR_SIZE(bus) PCI__GEN(bus, 0x0c10, 0)
#define PCI_CS3_BAR_SIZE(bus) PCI__GEN(bus, 0x0c14, 0)
#define PCI_SCS1_BAR_SIZE(bus) PCI__GEN(bus, 0x0d08, 0)
#define PCI_SCS3_BAR_SIZE(bus) PCI__GEN(bus, 0x0d0c, 0)
#define PCI_CS1_BAR_SIZE(bus) PCI__GEN(bus, 0x0d10, 0)
#define PCI_BOOTCS_BAR_SIZE(bus) PCI__GEN(bus, 0x0d14, 0)
#define PCI_CS2_BAR_SIZE(bus) PCI__GEN(bus, 0x0d18, 0)
#define PCI_P2P_MEM0_BAR_SIZE(bus) PCI__GEN(bus, 0x0d1c, 0)
#define PCI_P2P_MEM1_BAR_SIZE(bus) PCI__GEN(bus, 0x0d20, 0)
#define PCI_P2P_IO_BAR_SIZE(bus) PCI__GEN(bus, 0x0d24, 0)
#define PCI_CPU_BAR_SIZE(bus) PCI__GEN(bus, 0x0d28, 0)
#define PCI_EXPANSION_ROM_BAR_SIZE(bus) PCI__GEN(bus, 0x0d2c, 0)
#define PCI_DAC_SCS0_BAR_SIZE(bus) PCI__GEN(bus, 0x0e00, 0)
#define PCI_DAC_SCS1_BAR_SIZE(bus) PCI__GEN(bus, 0x0e04, 0)
#define PCI_DAC_SCS2_BAR_SIZE(bus) PCI__GEN(bus, 0x0e08, 0)
#define PCI_DAC_SCS3_BAR_SIZE(bus) PCI__GEN(bus, 0x0e0c, 0)
#define PCI_DAC_CS0_BAR_SIZE(bus) PCI__GEN(bus, 0x0e10, 0)
#define PCI_DAC_CS1_BAR_SIZE(bus) PCI__GEN(bus, 0x0e14, 0)
#define PCI_DAC_CS2_BAR_SIZE(bus) PCI__GEN(bus, 0x0e18, 0)
#define PCI_DAC_CS3_BAR_SIZE(bus) PCI__GEN(bus, 0x0e1c, 0)
#define PCI_DAC_BOOTCS_BAR_SIZE(bus) PCI__GEN(bus, 0x0e20, 0)
#define PCI_DAC_P2P_MEM0_BAR_SIZE(bus) PCI__GEN(bus, 0x0e24, 0)
#define PCI_DAC_P2P_MEM1_BAR_SIZE(bus) PCI__GEN(bus, 0x0e28, 0)
#define PCI_DAC_CPU_BAR_SIZE(bus) PCI__GEN(bus, 0x0e2c, 0)
#define PCI_BASE_ADDR_REGISTERS_ENABLE(bus) PCI__GEN(bus, 0x0c3c, 0)
#define PCI_SCS0_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0c48, 0)
#define PCI_SCS1_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d48, 0)
#define PCI_SCS2_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0c4c, 0)
#define PCI_SCS3_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d4c, 0)
#define PCI_CS0_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0c50, 0)
#define PCI_CS1_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d50, 0)
#define PCI_CS2_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d58, 0)
#define PCI_CS3_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0c54, 0)
#define PCI_ADDR_DECODE_CONTROL(bus) PCI__GEN(bus, 0x0d3c, 0)
#define PCI_BOOTCS_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d54, 0)
#define PCI_P2P_MEM0_BASE_ADDR_REMAP_LOW(bus) PCI__GEN(bus, 0x0d5c, 0)
#define PCI_P2P_MEM0_BASE_ADDR_REMAP_HIGH(bus) PCI__GEN(bus, 0x0d60, 0)
#define PCI_P2P_MEM1_BASE_ADDR_REMAP_LOW(bus) PCI__GEN(bus, 0x0d64, 0)
#define PCI_P2P_MEM1_BASE_ADDR_REMAP_HIGH(bus) PCI__GEN(bus, 0x0d68, 0)
#define PCI_P2P_IO_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d6c, 0)
#define PCI_CPU_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0d70, 0)
#define PCI_DAC_SCS0_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f00, 0)
#define PCI_DAC_SCS1_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f04, 0)
#define PCI_DAC_SCS2_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f08, 0)
#define PCI_DAC_SCS3_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f0c, 0)
#define PCI_DAC_CS0_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f10, 0)
#define PCI_DAC_CS1_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f14, 0)
#define PCI_DAC_CS2_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f18, 0)
#define PCI_DAC_CS3_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f1c, 0)
#define PCI_DAC_BOOTCS_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f20, 0)
#define PCI_DAC_P2P_MEM0_BASE_ADDR_REMAP_LOW(bus) PCI__GEN(bus, 0x0f24, 0)
#define PCI_DAC_P2P_MEM0_BASE_ADDR_REMAP_HIGH(bus) PCI__GEN(bus, 0x0f28, 0)
#define PCI_DAC_P2P_MEM1_BASE_ADDR_REMAP_LOW(bus) PCI__GEN(bus, 0x0f2c, 0)
#define PCI_DAC_P2P_MEM1_BASE_ADDR_REMAP_HIGH(bus) PCI__GEN(bus, 0x0f30, 0)
#define PCI_DAC_CPU_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f34, 0)
#define PCI_EXPANSION_ROM_BASE_ADDR_REMAP(bus) PCI__GEN(bus, 0x0f38, 0)
/*
* Table 186: PCI Control Register Map
*/
#define PCI_COMMAND(bus) PCI__GEN(bus, 0x0c00, 0)
#define PCI_MODE(bus) PCI__GEN(bus, 0x0d00, 0)
#define PCI_TIMEOUT_RETRY(bus) PCI__GEN(bus, 0x0c04, 0)
#define PCI_READ_BUFFER_DISCARD_TIMER(bus) PCI__GEN(bus, 0x0d04, 0)
#define PCI_MSI_TRIGGER_TIMER(bus) PCI__GEN(bus, 0x0c38, 0)
#define PCI_ARBITER_CONTROL(bus) PCI__GEN(bus, 0x1d00, 0)
#define PCI_INTERFACE_XBAR_CONTROL_LOW(bus) PCI__GEN(bus, 0x1d08, 0)
#define PCI_INTERFACE_XBAR_CONTROL_HIGH(bus) PCI__GEN(bus, 0x1d0c, 0)
#define PCI_INTERFACE_XBAR_TIMEOUT(bus) PCI__GEN(bus, 0x1d04, 0)
#define PCI_READ_RESPONSE_XBAR_CONTROL_LOW(bus) PCI__GEN(bus, 0x1d18, 0)
#define PCI_READ_RESPONSE_XBAR_CONTROL_HIGH(bus) PCI__GEN(bus, 0x1d1c, 0)
#define PCI_SYNC_BARRIER(bus) PCI__GEN(bus, 0x1d10, 0)
#define PCI_P2P_CONFIGURATION(bus) PCI__GEN(bus, 0x1d14, 0)
#define PCI_P2P_SWAP_CONTROL(bus) PCI__GEN(bus, 0x1d54, 0)
#define PCI_ACCESS_CONTROL_BASE_LOW(bus, n) PCI__GEN(bus, 0x1e00, n)
#define PCI_ACCESS_CONTROL_BASE_HIGH(bus, n) PCI__GEN(bus, 0x1e04, n)
#define PCI_ACCESS_CONTROL_TOP(bus, n) PCI__GEN(bus, 0x1e08, n)
/*
* Table 187: PCI Snoop Control Register Map
*/
#define PCI_SNOOP_CONTROL_BASE_LOW(bus, n) PCI__GEN(bus, 0x1f00, n)
#define PCI_SNOOP_CONTROL_BASE_HIGH(bus, n) PCI__GEN(bus, 0x1f04, n)
#define PCI_SNOOP_CONTROL_TOP(bus, n) PCI__GEN(bus, 0x1f08, n)
/*
* Table 188: PCI Configuration ACCESS_Register Map
*/
#define PCI_CONFIG_ADDR(bus) PCI__GEN(bus, 0x0cf8, 0)
#define PCI_CONFIG_DATA(bus) PCI__GEN(bus, 0x0cfc, 0)
#define PCI_INTR_ACK(bus) PCI__GEN(bus, 0x0c34, 0)
/*
* Table 189: PCI ERROR Report Register Map
*/
#define PCI_SERR_MASK(bus) PCI__GEN(bus, 0x0c28, 0)
#define PCI_ERROR_ADDRESS_LOW(bus) PCI__GEN(bus, 0x1d40, 0)
#define PCI_ERROR_ADDRESS_HIGH(bus) PCI__GEN(bus, 0x1d44, 0)
#define PCI_ERROR_DATA_LOW(bus) PCI__GEN(bus, 0x1d48, 0)
#define PCI_ERROR_DATA_HIGH(bus) PCI__GEN(bus, 0x1d4c, 0)
#define PCI_ERROR_COMMAND(bus) PCI__GEN(bus, 0x1d50, 0)
#define PCI_ERROR_CAUSE(bus) PCI__GEN(bus, 0x1d58, 0)
#define PCI_ERROR_MASK(bus) PCI__GEN(bus, 0x1d5c, 0)
/*
* Table 223: PCI Base Address Registers Enable
* If a bit is clear, the BAR is enabled. If set, disabled. The GT64260]
* prevents disabling both memory mapped and I/O mapped BARs (bits 9 and 10
* cannot simultaneously be set to 1).
*/
#define PCI_BARE_SCS0En PCI__BIT(0) /* SCS[0]* BAR Enable */
#define PCI_BARE_SCS1En PCI__BIT(1) /* SCS[1]* BAR Enable */
#define PCI_BARE_SCS2En PCI__BIT(2) /* SCS[2]* BAR Enable */
#define PCI_BARE_SCS3En PCI__BIT(3) /* SCS[3]* BAR Enable */
#define PCI_BARE_CS0En PCI__BIT(4) /* CS[0]* BAR Enable */
#define PCI_BARE_CS1En PCI__BIT(5) /* CS[1]* BAR Enable */
#define PCI_BARE_CS2En PCI__BIT(6) /* CS[2]* BAR Enable */
#define PCI_BARE_CS3En PCI__BIT(7) /* CS[3]* BAR Enable */
#define PCI_BARE_BootCSEn PCI__BIT(8) /* BootCS* BAR Enable */
#define PCI_BARE_IntMemEn PCI__BIT(9) /* Memory Mapped Internal
* Registers BAR Enable */
#define PCI_BARE_IntIOEn PCI__BIT(10) /* I/O Mapped Internal
* Registers BAR Enable */
#define PCI_BARE_P2PMem0En PCI__BIT(11) /* P2P Mem0 BAR Enable */
#define PCI_BARE_P2PMem1En PCI__BIT(12) /* P2P Mem1 BAR Enable */
#define PCI_BARE_P2PIOEn PCI__BIT(13) /* P2P IO BAR Enable */
#define PCI_BARE_CPUEn PCI__BIT(14) /* CPU BAR Enable */
#define PCI_BARE_DSCS0En PCI__BIT(15) /* DAC SCS[0]* BAR Enable */
#define PCI_BARE_DSCS1En PCI__BIT(16) /* DAC SCS[1]* BAR Enable */
#define PCI_BARE_DSCS2En PCI__BIT(17) /* DAC SCS[2]* BAR Enable */
#define PCI_BARE_DSCS3En PCI__BIT(18) /* DAC SCS[3]* BAR Enable */
#define PCI_BARE_DCS0En PCI__BIT(19) /* DAC CS[0]* BAR Enable */
#define PCI_BARE_DCS1En PCI__BIT(20) /* DAC CS[1]* BAR Enable */
#define PCI_BARE_DCS2En PCI__BIT(21) /* DAC CS[2]* BAR Enable */
#define PCI_BARE_DCS3En PCI__BIT(22) /* DAC CS[3]* BAR Enable */
#define PCI_BARE_DBootCSEn PCI__BIT(23) /* DAC BootCS* BAR Enable */
#define PCI_BARE_DP2PMem0En PCI__BIT(24) /* DAC P2P Mem0 BAR Enable */
#define PCI_BARE_DP2PMem1En PCI__BIT(25) /* DAC P2P Mem1 BAR Enable */
#define PCI_BARE_DCPUEn PCI__BIT(26) /* DAC CPU BAR Enable */
/*
* Table 254: PCI Address Decode Control
* Bits 7:4 and 31:25 are reserved
* 00:00 RemapWrDis Address Remap Registers Write Disable
* 0: Writes to a BAR result in updating the
* corresponding remap register with the BAR's
* new value.
* 1: Writes to a BAR have no affect on the
* corresponding Remap register value.
* 01:01 ExpRomDev Expansion ROM Device (0: CS[3]; 1: BootCS)
* 02:02 VPDDev VPD Device (0: CS[3]; 1: BootCS)
* 03:03 MsgAcc Messaging registers access
* 0: Messaging unit registers are accessible on
* lowest 4Kbyte of SCS[0] BAR space.
* 1: Messaging unit registers are only accessible
* as part of the GT64260 internal space.
* 07:04 Reserved
* 24:08 VPDHighAddr VPD High Address bits
* [31:15] of VPD the address.
* 31:25 Reserved
*/
#define PCI_ADC_RemapWrDis PCI__BIT(0)
#define PCI_ADC_ExpRomDev PCI__BIT(1)
#define PCI_ADC_VPDDev PCI__BIT(2)
#define PCI_ADC_MsgAcc PCI__BIT(3)
#define PCI_ADC_VPDHighAddr_GET(v) PCI__EXT(v, 8, 16)
/*
* Table 255: PCI Command
* 00:00 MByteSwap PCI Master Byte Swap
* NOTE: GT-64120 and GT-64130 compatible.
* When set to 0, the GTO64260 PCI master swaps the bytes
* of the incoming and outgoing PCI data (swap the 8 bytes
* of a longword).
* 01:01 Reserved
* 02:02 Reserved Must be 0.
* 03:03 Reserved
* 04:04 MWrCom PCI Master Write Combine Enable
* When set to 1, write combining is enabled.
* 05:05 MRdCom PCI Master Read Combine Enable
* When set to 1, read combining is enabled.
* 06:06 MWrTrig PCI Master Write Trigger
* 0: Accesses the PCI bus only when the whole burst is
* written into the master write buffer.
* 1: Accesses the PCI bus when the first data is written
* into the master write buffer.
* 07:07 MRdTrig PCI Master Read Trigger
* 0: Returns read data to the initiating unit only when
* the whole burst is written into master read buffer.
* 1: Returns read data to the initiating unit when the
* first read data is written into master read buffer.
* 08:08 MRdLine PCI Master Memory Read Line Enable
* (0: Disable; 1: Enable)
* 09:09 MRdMul PCI Master Memory Read Multiple Enable
* (0: Disable; 1: Enable)
* 10:10 MWordSwap PCI Master Word Swap
* NOTE: GT-64120 and GT-64130 compatible.
* When set to 1, the GT64260 PCI master swaps the 32-bit
* words of the incoming and outgoing PCI data.
* 11:11 SWordSwap PCI Slave Word Swap
* NOTE: GT-64120 and GT-64130 compatible.
* When set to 1, the GT64260 PCI slave swaps the 32-bit
* words of the incoming and outgoing PCI data.
* 12:12 IntBusCtl PCI Interface Unit Internal Bus Control
* NOTE: Reserved for Galileo Technology usage
* 0: Enable internal bus sharing between master and
* slave interfaces.
* 1: Disable internal bus sharing between master and
* slave interfaces.
* 13:13 SBDis PCI Slave Sync Barrier Disable
* When set to 1, the PCI configuration read transaction
* will stop act as sync barrier transaction.
* 14:14 Reserved Must be 0
* 15:15 MReq64 PCI Master REQ64* Enable (0: Disable; 1: Enable)
* 16:16 SByteSwap PCI Slave Byte Swap
* NOTE: GT-64120 and GT-64130 compatible.
* When set to 0, the GT64260 PCI slave swaps the bytes of
* the incoming and outgoing PCI data (swap the 8 bytes of
* a long-word).
* 17:17 MDACEn PCI Master DAC Enable
* 0: Disable (The PCI master never drives the DAC cycle)
* 1: Enable (In case the upper 32-bit address is not 0,
* the PCI master drives the DAC cycle)
* 18:18 M64Allign PCI Master REQ64* assertion on non-aligned
* 0: Disable (The master asserts REQ64* only if
* the address is 64-bit aligned)
* 1: Enable (The master asserts REQ64* even if
* the address is not 64-bit aligned)
* 19:19 PErrProp Parity/ECC Errors Propagation Enable
* 0: Disable (The PCI interface always drives
* correct parity on the PAR signal)
* 1: Enable (In case of slave read bad ECC from
* SDRAM, or master write with bad parity/ECC
* indication from the initiator, the PCI interface
* drives bad parity on the PAR signal)
* 20:20 SSwapEn PCI Slave Swap Enable
* NOTE: Even if the SSwapEn bit is set to 1 and
* the PCI address does not match any of the
* Access Control registers, slave data swapping
* works according to SByteSwap and SWordSwap bits.
* 0: PCI slave data swapping is determined via
* SByteSwap and SWordSwap bits (bits 16 and 11),
* as in the GT-64120/130.
* 1: PCI slave data swapping is determined via PCISwap
* bits [25:24] in the PCI Access Control registers.
* 21:21 MSwapEn PCI Master Swap Enable
* 0: PCI master data swapping is determined via
* MByteSwap and MWordSwap bits (bits 0 and 10),
* as in the GT-64120/130.
* 1: PCI master data swapping is determined via
* PCISwap bits in CPU to PCI Address Decoding
* registers.
* 22:22 MIntSwapEn PCI Master Configuration Transactions Data Swap Enable
* NOTE: Reserved for Galileo Technology usage.
* 0: Disable (The PCI master configuration transaction
* to the PCI bus is always in Little Endian convention)
* 1: Enable (The PCI master configuration transaction to
* the PCI bus is determined according to the setting
* of MSwapEn bit)
* 23:23 LBEn PCI Loop Back Enable
* NOTE: Reserved for Galileo Technology usage.
* 0: Disable (The PCI slave does not respond to
* transactions initiated by the PCI master)
* 1: Enable (The PCI slave does respond to
* transactions initiated by the PCI master,
* if targeted to the slave (address match)
* 26:24 SIntSwap PCI Slave data swap control on PCI accesses to the
* GT64260 internal and configuration registers.
* Bits encoding are the same as bits[26:24] in PCI Access
* Control registers.
* 27:27 Reserved Must be 0.
* 31:28 Reserved Read only.
*/
#define PCI_CMD_MByteSwap PCI__BIT(0)
#define PCI_CMD_MBZ0_2 PCI__BIT(2)
#define PCI_CMD_MWrCom PCI__BIT(4)
#define PCI_CMD_MRdCom PCI__BIT(5)
#define PCI_CMD_MWrTrig PCI__BIT(6)
#define PCI_CMD_MRdTrig PCI__BIT(7)
#define PCI_CMD_MRdLine PCI__BIT(8)
#define PCI_CMD_MRdMul PCI__BIT(9)
#define PCI_CMD_MWordSwap PCI__BIT(10)
#define PCI_CMD_SWordSwap PCI__BIT(11)
#define PCI_CMD_IntBusCtl PCI__BIT(12)
#define PCI_CMD_SBDis PCI__BIT(13)
#define PCI_CMD_MBZ0_14 PCI__BIT(14)
#define PCI_CMD_MReq64 PCI__BIT(15)
#define PCI_CMD_SByteSwap PCI__BIT(16)
#define PCI_CMD_MDCAEn PCI__BIT(17)
#define PCI_CMD_M64Allign PCI__BIT(18)
#define PCI_CMD_PErrProp PCI__BIT(19)
#define PCI_CMD_SSwapEn PCI__BIT(20)
#define PCI_CMD_MSwapEn PCI__BIT(21)
#define PCI_CMD_MIntSwapEn PCI__BIT(22)
#define PCI_CMD_LBEn PCI__BIT(23)
#define PCI_CMD_SIntSwap_GET(v) PCI__EXT(v, 24, 3)
#define PCI_CMD_MBZ0_27 PCI__BIT(27)
/*
* Table 256: PCI Mode
* 00:00 PciID PCI Interface ID -- Read Only (PCI_0: 0x0; PCI_1: 0x1)
* 01:01 Reserved
* 02:02 Pci64 64-bit PCI Interface -- Read Only
* When set to 1, the PCI interface is configured to a
* 64 bit interface.
* 07:03 Reserved
* 08:08 ExpRom Expansion ROM Enable -- Read Only from PCI
* When set to 1, the expansion ROM BAR is enabled.
* 09:09 VPD VPD Enable -- Read Only from PCI
* When set to 1, VPD is supported.
* 10:10 MSI MSI Enable -- Read Only from PCI
* When set to 1, MSI is supported.
* 11:11 PMG Power Management Enable -- Read Only from PCI
* When set to 1, PMG is supported.
* 12:12 HotSwap CompactPCI Hot Swap Enable -- Read Only from PCI
* When set to 1, HotSwap is supported.
* 13:13 BIST BIST Enable -- Read only from PCI
* If set to 1, BIST is enabled.
* 30:14 Reserved
* 31:31 PRst PCI Interface Reset Indication -- Read Only
* Set to 0 as long as the RST* pin is asserted.
*/
#define PCI_MODE_PciID_GET(v) PCI__EXT(v, 0, 1)
#define PCI_MODE_Pci64 PCI__BIT(2)
#define PCI_MODE_ExpRom PCI__BIT(8)
#define PCI_MODE_VPD PCI__BIT(9)
#define PCI_MODE_MSI PCI__BIT(10)
#define PCI_MODE_PMG PCI__BIT(11)
#define PCI_MODE_HotSwap PCI__BIT(12)
#define PCI_MODE_BIST PCI__BIT(13)
#define PCI_MODE_PRst PCI__BIT(31)
/*
* Table 257: PCI Timeout and Retry
* 07:00 Timeout0 Specifies the number of PClk cycles the GT64260 slave
* holds the PCI bus before terminating a transaction
* with RETRY.
* 15:08 Timeout1 Specifies the number of PClk cycles the GT64260 slave
* holds the PCI bus before terminating a transaction
* with DISCONNECT.
* 23:16 RetryCtr Retry Counter
* Specifies the number of retries of the GT64260 Master.
* The GT64260 generates an interrupt when this timer
* expires. A 0x00 value means a retry forever.
* 31:24 Reserved
*/
#define PCI_TMORTRY_Timeout0_GET(v) PCI__EXT(v, 0, 8)
#define PCI_TMORTRY_Timeout1_GET(v) PCI__EXT(v, 8, 8)
#define PCI_TMORTRY_RetryCtr_GET(v) PCI__EXT(v, 16, 8)
/*
* Table 258: PCI Read Buffer Discard Timer
* 15:00 Timer Specifies the number of PClk cycles the GT64260
* slave keeps an non-accessed read buffers (non com-
* pleted delayed read) before invalidating the buffer.
* 23:16 RdBufEn Slave Read Buffers Enable
* Each bit corresponds to one of the eight read buffers.
* If set to 1, buffer is enabled.
* 31:24 Reserved
*/
#define PCI_RdBufDisTmr_Timer_GET(v) PCI__EXT(v, 0, 16)
#define PCI_RdBufDisTmr_RdBufEn_GET(v) PCI__EXT(v, 16, 8)
#define PCI_RdBufDisTmr_RdBufEn0(v) PCI__BIT(16)
#define PCI_RdBufDisTmr_RdBufEn1(v) PCI__BIT(17)
#define PCI_RdBufDisTmr_RdBufEn2(v) PCI__BIT(18)
#define PCI_RdBufDisTmr_RdBufEn3(v) PCI__BIT(19)
#define PCI_RdBufDisTmr_RdBufEn4(v) PCI__BIT(20)
#define PCI_RdBufDisTmr_RdBufEn5(v) PCI__BIT(21)
#define PCI_RdBufDisTmr_RdBufEn6(v) PCI__BIT(22)
#define PCI_RdBufDisTmr_RdBufEn7(v) PCI__BIT(23)
/*
* Table 259: MSI Trigger Timer
* 15:00 Timer Specifies the number of TClk cycles between consecutive
* MSI requests.
* 31:16 Reserved
*/
#define PCI_MSITrigger_Timer_GET(v) PCI__EXT(v, 0, 16)
/*
* Table 260: PCI Arbiter Control
* NOTE: If HPPV (bits [28:21]) is set to 0 and PAEn is set to 1,
* priority scheme is reversed. This means that high priority
* requests are granted if no low priority request is pending.
* 00:00 Reserved Must be 0. 0x0
* 01:01 BDEn Broken Detection Enable
* If set to 1, broken master detection is enabled. A mas-
* ter is said to be broken if it fails to respond to grant
* assertion within a window specified in BV (bits [6:3]).
* 02:02 PAEn Priority Arbitration Enable
* 0: Low priority requests are granted only when no high
* priority request is pending
* 1: Weighted round robin arbitration is performed
* between high priority and low priority groups.
* 06:03 BV Broken Value
* This value sets the maximum number of cycles that the
* arbiter waits for a PCI master to respond to its grant
* assertion. If a PCI master fails to assert FRAME* within
* this time, the PCI arbiter aborts the transaction and
* performs a new arbitration cycle and a maskable
* interrupt is generated. Must be greater than 0.
* NOTE: The PCI arbiter waits for the current
* transaction to end before starting to
* count the wait-for-broken cycles.
* Must be greater than 1 for masters that performs address
* stepping (such as the GTO 64260 PCI master), since they
* require GNT* assertion for two cycles.
* 13:07 P[6:0] Priority
* These bits assign priority levels to the requests
* connected to the PCI arbiter. When a PM bit is set to
* 1, priority of the associated request is high. The
* mapping between P[6:0] bits and the request/grant pairs
* are as follows:
* P[0]: internal PCI master P[1]: external REQ0/GNT0
* P[2]: external REQ1/GNT1 P[3]: external REQ2/GNT2
* P[4]: external REQ3/GNT3 P[5]: external REQ4/GNT4
* P[6]: external REQ5/GNT5
* 20:14 PD[6:0] Parking Disable
* Use these bits to disable parking on any of the PCI
* masters. When a PD bit is set to 1, parking on the
* associated PCI master is disabled.
* NOTE: The arbiter parks on the last master granted
* unless disabled through the PD bit. Also, if
* PD bits are all 1, the PCI arbiter parks on
* the internal PCI master.
* 28:21 HPPV High Priority Preset Value
* This is the preset value of the high priority counter
* (High_cnt). This counter decrements each time a high
* priority request is granted. When the counter reaches
* zero, it reloads with this preset value. The counter
* reloads when a low priority request is granted.
* 30:29 Reserved
* 31:31 EN Enable
* Setting this bit to 1 enables operation of the arbiter.
*/
#define PCI_ARBCTL_MBZ0_0 PCI__BIT(0)
#define PCI_ARBCTL_BDEn PCI__BIT(1)
#define PCI_ARBCTL_PAEn PCI__BIT(2)
#define PCI_ARBCTL_BV_GET(v) PCI__EXT(v, 3, 4)
#define PCI_ARBCTL_P_GET(v) PCI__EXT(v, 7, 7)
#define PCI_ARBCTL_PD_GET(v) PCI__EXT(v, 14, 7)
#define PCI_ARBCTL_HPPV_GET(v) PCI__EXT(v, 21, 7)
#define PCI_ARBCTL_EN PCI__BIT(31)
#define PCI_ARBPRI_IntPci PCI__BIT(0)
#define PCI_ARBPRI_ExtReqGnt0 PCI__BIT(1)
#define PCI_ARBPRI_ExtReqGnt1 PCI__BIT(2)
#define PCI_ARBPRI_EXtReqGnt2 PCI__BIT(3)
#define PCI_ARBPRI_EXtReqGnt3 PCI__BIT(4)
#define PCI_ARBPRI_EXtReqGnt4 PCI__BIT(5)
#define PCI_ARBPRI_EXtReqGnt5 PCI__BIT(6)
/*
* Table 261: PCI Interface Crossbar Control (Low)
* 03:00 Arb0 Slice 0 of PCI master pizza arbiter.
* 07:04 Arb1 Slice 1 of PCI master pizza arbiter.
* 11:08 Arb2 Slice 2 of PCI master pizza arbiter.
* 15:12 Arb3 Slice 3 of PCI master pizza arbiter.
* 19:16 Arb4 Slice 4 of PCI master pizza arbiter.
* 23:20 Arb5 Slice 5 of PCI master pizza arbiter.
* 27:24 Arb6 Slice 6 of PCI master pizza arbiter.
* 31:28 Arb7 Slice 7 of PCI master pizza arbiter.
*/
#define PCI_IFXBRCTL_GET_SLICE(v, n) PCI__EXT(v, (n) * 4, 4)
#define PCI_IFXBRCTL_SET_SLICE(v, n, s) ((void)(PCI__CLR(v, (n)*4, 4),\
(v) |= PCI__INS((n)*4, s)))
/*
* Table 262: PCI Interface Crossbar Control (High)
* 03:00 Arb8 Slice 8 of PCI master pizza arbiter.
* 07:04 Arb9 Slice 9 of PCI master pizza arbiter.
* 11:08 Arb10 Slice 10 of PCI master pizza arbiter.
* 15:12 Arb11 Slice 11 of PCI master pizza arbiter.
* 19:16 Arb12 Slice 12 of PCI master pizza arbiter.
* 23:20 Arb13 Slice 13 of PCI master pizza arbiter.
* 27:24 Arb14 Slice 14 of PCI master pizza arbiter.
* 31:28 Arb15 Slice 15 of PCI master pizza arbiter.
*/
#define PCI_IFXBRCH_GET_SLICE(v, n) PCI__EXT(v, ((n) - 8) * 4, 4)
#define PCI_IFXBRCH_SET_SLICE(v, n, s) ((void)(PCI__CLR(v, ((n)*-8)4, 4),\
(v) |= PCI__INS(((n)-8)*4, s)))
/*
* Table 263: PCI Interface Crossbar Timeout
(NOTE: Reserved for Galileo Technology usage.)
* 07:00 Timeout Crossbar Arbiter Timeout Preset Value
* 15:08 Reserved
* 16:16 TimeoutEn Crossbar Arbiter Timer Enable (1: Disable)
* 31:17 Reserved
*/
#define PCI_IFXBRTMO_Timeout_GET(v) PCI__EXT(v, 0, 8)
#define PCI_IFXBRTMO_TimeoutEn PCI__BIT(16)
/*
* Table 264: PCI Read Response Crossbar Control (Low)
* 03:00 Arb0 Slice 0 of PCI slave pizza arbiter.
* 07:04 Arb1 Slice 1 of PCI slave pizza arbiter.
* 11:08 Arb2 Slice 2 of PCI slave pizza arbiter.
* 15:12 Arb3 Slice 3 of PCI slave pizza arbiter.
* 19:16 Arb4 Slice 4 of PCI slave pizza arbiter.
* 23:20 Arb5 Slice 5 of PCI slave pizza arbiter.
* 27:24 Arb6 Slice 6 of PCI slave pizza arbiter.
* 31:28 Arb7 Slice 7 of PCI slave pizza arbiter.
*/
#define PCI_RRXBRCL_GET_SLICE(v, n) PCI__EXT(v, (n) * 4, 4)
#define PCI_RRXBRCL_SET_SLICE(v, n, s) ((void)(PCI__CLR(v, (n)*4, 4),\
(v) |= PCI__INS((n)*4, s)))
/*
* Table 265: PCI Read Response Crossbar Control (High)
* 03:00 Arb8 Slice 8 of PCI slave pizza arbiter.
* 07:04 Arb9 Slice 9 of PCI slave pizza arbiter.
* 11:08 Arb10 Slice 10 of PCI slave pizza arbiter.
* 15:12 Arb11 Slice 11 of PCI slave pizza arbiter.
* 19:16 Arb12 Slice 12 of PCI slave pizza arbiter.
* 23:20 Arb13 Slice 13 of PCI slave pizza arbiter.
* 27:24 Arb14 Slice 14 of PCI slave pizza arbiter.
* 31:28 Arb15 Slice 15 of PCI slave pizza arbiter.
*/
#define PCI_RRXBRCH_GET_SLICE(v, n) PCI__EXT(v, ((n) - 8) * 4, 4)
#define PCI_RRXBRCH_SET_SLICE(v, n, s) ((void)(PCI__CLR(v, ((n)*-8)4, 4),\
(v) |= PCI__INS(((n)-8)*4, s)))
/*
* Table 266: PCI Sync Barrier Virtual Register
* 31:0 SyncReg Sync Barrier Virtual Register
* PCI read from this register results in PCI slave sync barrier
* action. The returned data is un-deterministic. Read Only.
*/
/*
* Table 267: PCI P2P Configuration
* 07:00 2ndBusL Secondary PCI Interface Bus Range Lower Boundary
* 15:08 2ndBusH Secondary PCI Interface Bus Range Upper Boundary
* 23:16 BusNum The PCI bus number to which the PCI interface
* is connected.
* 28:24 DevNum The PCI interface's device number.
* 31:29 Reserved Reserved.
*/
#define PCI_P2PCFG_2ndBusL_GET(v) PCI__EXT(v, 0, 8)
#define PCI_P2PCFG_2ndBusH_GET(v) PCI__EXT(v, 8, 8)
#define PCI_P2PCFG_BusNum_GET(v) PCI__EXT(v, 16, 8)
#define PCI_P2PCFG_DevNum_GET(v) PCI__EXT(v, 24, 5)
/*
* Table 268: PCI P2P Swap Control
* 02:00 M0Sw P2P Mem0 BAR Swap Control
* 03:03 M0Req64 P2P Mem0 BAR Force REQ64
* 06:04 M1Sw P2P Mem1 BAR Swap Control
* 07:07 M1Req64 P2P Mem1 BAR Force REQ64
* 10:08 DM0Sw P2P DAC Mem0 BAR Swap Control
* 11:11 DM0Req64 P2P DAC Mem0 BAR Force REQ64
* 14:12 DM1Sw P2P DAC Mem1 BAR Swap Control
* 15:15 DM1Req64 P2P DAC Mem1 BAR Force REQ64
* 18:16 IOSw P2P I/O BAR Swap Control
* 19:19 Reserved
* 22:20 CfgSw P2P Configuration Swap Control
* 31:19 Reserved
*/
#define PCI_P2PSWAP_M0Sw_GET(v) PCI__EXT(v, 0, 3)
#define PCI_P2PSWAP_M0Req64 PCI__BIT(3)
#define PCI_P2PSWAP_M1Sw_GET(v) PCI__EXT(v, 4, 3)
#define PCI_P2PSWAP_M1Req64 PCI__BIT(7)
#define PCI_P2PSWAP_DM0Sw_GET(v) PCI__EXT(v, 8, 3)
#define PCI_P2PSWAP_DM0Req64 PCI__BIT(11)
#define PCI_P2PSWAP_DM1Sw_GET(v) PCI__EXT(v, 12, 3)
#define PCI_P2PSWAP_DM1Req64 PCI__BIT(15)
#define PCI_P2PSWAP_CfgSw_GET(v) PCI__EXT(v, 20, 3)
/*
* Table 269: PCI Access Control Base (Low)
* 11:00 Addr Base Address Corresponds to address bits[31:20].
* 12:12 PrefetchEn Read Prefetch Enable
* 0: Prefetch disabled (The PCI slave reads single words)
* 1: Prefetch enabled.
* 14:14 Reserved Must be 0
* 15:15 Reserved
* 16:16 RdPrefetch PCI Read Aggressive Prefetch Enable; 0: Disable;
* 1: Enable (The PCI slave prefetches two
* bursts in advance)
* 17:17 RdLinePrefetch PCI Read Line Aggressive Prefetch Enable; 0: Disable;
* 1: Enable (PCI slave prefetch two bursts in advance)
* 18:18 RdMulPrefetch PCI Read Multiple Aggressive Prefetch Enable
* 0: Disable; 1: Enable (PCI slave prefetch two bursts in
* advance)
* 19:19 Reserved
* 21:20 MBurst PCI Max Burst
* Specifies the maximum burst size for a single transac-
* tion between a PCI slave and the other interfaces
* 00 - 4 64-bit words
* 01 - 8 64-bit words
* 10 - 16 64-bit words
* 11 - Reserved
* 23:22 Reserved
* 25:24 PCISwap Data Swap Control
* 00 - Byte Swap
* 01 - No swapping
* 10 - Both byte and word swap
* 11 - Word swap
* 26:26 Reserved Must be 0
* 27:27 Reserved
* 28:28 AccProt Access Protect (0: PCI access is allowed; 1; Region is
not accessible from PCI)
* 29:29 WrProt Write Protect (0: PCI write is allowed; 1: Region is
* not writeable from PCI)
* 31:30 Reserved
*/
#define PCI_ACCCTLBASEL_Addr_GET(v) PCI__EXT(v, 0, 12)
#define PCI_ACCCTLBASEL_PrefetchEn PCI__BIT(12)
#define PCI_ACCCTLBASEL_MBZ0_14 PCI__BIT(14)
#define PCI_ACCCTLBASEL_RdPrefetch PCI__BIT(16)
#define PCI_ACCCTLBASEL_RdLinePrefetch PCI__BIT(17)
#define PCI_ACCCTLBASEL_RdMulPrefetch PCI__BIT(18)
#define PCI_ACCCTLBASEL_WBurst PCI__EXT(v, 20, 2)
#define PCI_ACCCTLBASEL_WBurst_8_QW PCI__INS(20, PCI_WBURST_8_QW)
#define PCI_ACCCTLBASEL_PCISwap PCI__EXT(v, 24, 2)
#define PCI_ACCCTLBASEL_PCISwap_NoSwap PCI__INS(24, PCI_PCISWAP_NoSwap)
#define PCI_ACCCTLBASEL_MBZ0_26 PCI__BIT(26)
#define PCI_ACCCTLBASEL_AccProt PCI__BIT(28)
#define PCI_ACCCTLBASEL_WrProt PCI__BIT(29)
#define PCI_WBURST_4_QW 0x00
#define PCI_WBURST_8_QW 0x01
#define PCI_WBURST_16_QW 0x02
#define PCI_WBURST_Reserved 0x04
#define PCI_PCISWAP_ByteSwap 0x00
#define PCI_PCISWAP_NoSwap 0x01
#define PCI_PCISWAP_ByteWordSwap 0x02
#define PCI_PCISWAP_WordSwap 0x04
/*
* Table 293: PCI Snoop Control Base (Low)
* 11:00 Addr Base Address Corresponds to address bits[31:20].
* 13:12 Snoop Snoop Type
* 31:14 Reserved
*/
#define PCI_SNOOPCTL_ADDR(v) PCI__EXT(v, 0, 12)
#define PCI_SNOOPCTL_TYPE(v) PCI__EXT(v, 12, 2)
#define PCI_SNOOP_None 0 /* no snoop */
#define PCI_SNOOP_WT 1 /* Snoop to WT region */
#define PCI_SNOOP_WB 2 /* Snoop to WB region */
/*
* Table 305: PCI Configuration Address
*
* 07:02 RegNum Register number.
* 10:08 FunctNum Function number.
* 15:11 DevNum Device number.
* 23:16 BusNum Bus number.
* 31:31 ConfigEn When set, an access to the Configuration Data
* register is translated into a Configuration
* or Special cycle on the PCI bus.
*/
#define PCI_CFG_MAKE_TAG(bus, dev, fun, reg) (PCI__BIT(31)|\
PCI__INS(16, (bus))|\
PCI__INS(11, (dev))|\
PCI__INS( 8, (fun))|\
PCI__INS( 0, (reg)))
#define PCI_CFG_GET_BUSNO(tag) PCI__EXT(tag, 16, 8)
#define PCI_CFG_GET_DEVNO(tag) PCI__EXT(tag, 11, 5)
#define PCI_CFG_GET_FUNCNO(tag) PCI__EXT(tag, 8, 3)
#define PCI_CFG_GET_REGNO(tag) PCI__EXT(tag, 0, 8)
/*
* Table 306: PCI Configuration Data
*
* 31:00 ConfigData The data is transferred to/from the PCI bus when
* the CPU accesses this register and the ConfigEn
* bit in the Configuration Address register is set
*
* A CPU access to this register causes the GT64260 to perform a Configuration
* or Special cycle on the PCI bus.
*/
/*
* Table 307: PCI Interrupt Acknowledge (This register is READ ONLY)
* 31:00 IntAck A CPU read access to this register forces an
* interrupt acknowledge cycle on the PCI bus.
*/
/*
* Table 308: PCI SERR* Mask
*
* NOTE: The GT64260 asserts SERR* only if SERR* is enabled via the PCI Status
* and Command register.
* If the corresponding bit is set, then asserts SERR* upon ...
*/
#define PCI_SERRMSK_SAPerr PCI__BIT(0) /* PCI slave detection of bad
* address parity. */
#define PCI_SERRMSK_SWrPerr PCI__BIT(1) /* PCI slave detection of bad
* write data parity. */
#define PCI_SERRMSK_SRdPerr PCI__BIT(2) /* a PERR* response to read
* data driven by the PCI
* slave. */
#define PCI_SERRMSK_MAPerr PCI__BIT(4) /* a PERR* response to an
* address driven by the PCI
* master. */
#define PCI_SERRMSK_MWrPerr PCI__BIT(5) /* a PERR* response to write
* data driven by the PCI
* master. */
#define PCI_SERRMSK_MRdPerr PCI__BIT(6) /* bad data parity detection
* during a PCI master read
* transaction. */
#define PCI_SERRMSK_MMabort PCI__BIT(8) /* a PCI master generation of
* master abort. */
#define PCI_SERRMSK_MTabort PCI__BIT(9) /* a PCI master detection of
* target abort. */
#define PCI_SERRMSK_MRetry PCI__BIT(11) /* a PCI master reaching retry
* counter limit. */
#define PCI_SERRMSK_SMabort PCI__BIT(16) /* a PCI slave detection of
* master abort. */
#define PCI_SERRMSK_STabort PCI__BIT(17) /* a PCI slave termination of
* a transaction with Target
* Abort. */
#define PCI_SERRMSK_SAccProt PCI__BIT(18) /* a PCI slave access protect
* violation. */
#define PCI_SERRMSK_SWrProt PCI__BIT(19) /* a PCI slave write protect
* violation. */
#define PCI_SERRMSK_SRdBuf PCI__BIT(20) /* the PCI slave's read buffer,
* discard timer expires */
#define PCI_SERRMSK_Arb PCI__BIT(21) /* the internal PCI arbiter
* detection of a broken PCI
* master. */
#define PCI_SERRMSK_ALL_ERRS \
(PCI_SERRMSK_SAPerr|PCI_SERRMSK_SWrPerr|PCI_SERRMSK_SRdPerr \
|PCI_SERRMSK_MAPerr|PCI_SERRMSK_MWrPerr|PCI_SERRMSK_MRdPerr \
|PCI_SERRMSK_MMabort|PCI_SERRMSK_MTabort|PCI_SERRMSK_MRetry \
|PCI_SERRMSK_SMabort|PCI_SERRMSK_STabort|PCI_SERRMSK_SAccProt \
|PCI_SERRMSK_SWrProt|PCI_SERRMSK_SRdBuf|PCI_SERRMSK_Arb)
/*
* Table 309: PCI Error Address (Low) -- Read Only.
* 31:00 ErrAddr PCI address bits [31:0] are latched upon an error
* condition. Upon address latch, no new addresses can
* be registered (due to additional error condition) until
* the register is being read.
*/
/*
* Table 310: PCI Error Address (High) Applicable only when running DAC cycles.
* 31:00 ErrAddr PCI address bits [63:32] are latched upon
* error condition.
*
* NOTE: Upon data sample, no new data is latched until the PCI Error Low
* Address register is read. This means that PCI Error Low Address
* register must bethe last register read by the interrupt handler.
*/
/*
* Table 311: PCI Error Data (Low)
* 31:00 ErrData PCI data bits [31:00] are latched upon error condition.
*/
/*
* Table 312: PCI Error Data (High) Applicable only when running
* 64-bit cycles.
* 31:00 ErrData PCI data bits [63:32] are latched upon error condition.
*/
/*
* Table 313: PCI Error Command
* 03:00 ErrCmd PCI command is latched upon error condition.
* 07:04 Reserved
* 15:08 ErrBE PCI byte enable is latched upon error condition.
* 16:16 ErrPAR PCI PAR is latched upon error condition.
* 17:17 ErrPAR64 PCI PAR64 is latched upon error condition.
* Applicable only when running 64-bit cycles.
* 31:18 Reserved
* NOTE: Upon data sample, no new data is latched until the PCI Error Low
* Address register is read. This means that PCI Error Low Address register
* must be the last register read by the interrupt handler.
*/
#define PCI_ERRCMD_Cmd_GET(v) PCI__EXT(v, 0, 4)
#define PCI_ERRCMD_ByteEn_GET(v) PCI__EXT(v, 8, 8)
#define PCI_ERRCMD_PAR PCI__BIT(16)
#define PCI_ERRCMD_PAR64 PCI__BIT(17)
/*
* Table 314: PCI Interrupt Cause
* 1. All bits are Clear Only. A cause bit set upon error event occurrence.
* A write of 0 clears the bit. A write of 1 has no affect.
* 2. PCI Interrupt bits are organized in four groups:
* bits[ 7: 0] for address and data parity errors,
* bits[15: 8] for PCI master transaction failure (possible external
* target problem),
* bits[23:16] for slave response failure (possible external master problem),
* bits[26:24] for external PCI events that require CPU handle.
*/
#define PCI_IC_SAPerr PCI__BIT(0) /* The PCI slave detected
* bad address parity. */
#define PCI_IC_SWrPerr PCI__BIT(1) /* The PCI slave detected
* bad write data parity. */
#define PCI_IC_SRdPerr PCI__BIT(2) /* PERR* response to read
* data driven by PCI slave. */
#define PCI_IC_MAPerr PCI__BIT(4) /* PERR* response to address
* driven by the PCI master. */
#define PCI_IC_MWrPerr PCI__BIT(5) /* PERR* response to write data
* driven by the PCI master. */
#define PCI_IC_MRdPerr PCI__BIT(6) /* Bad data parity detected
* during the PCI master read
* transaction. */
#define PCI_IC_MMabort PCI__BIT(8) /* The PCI master generated
* master abort. */
#define PCI_IC_MTabort PCI__BIT(9) /* The PCI master detected
* target abort. */
#define PCI_IC_MMasterEn PCI__BIT(10) /* An attempt to generate a PCI
* transaction while master is
* not enabled. */
#define PCI_IC_MRetry PCI__BIT(11) /* The PCI master reached
* retry counter limit. */
#define PCI_IC_SMabort PCI__BIT(16) /* The PCI slave detects an il-
* legal master termination. */
#define PCI_IC_STabort PCI__BIT(17) /* The PCI slave terminates a
* transaction with Target
* Abort. */
#define PCI_IC_SAccProt PCI__BIT(18) /* A PCI slave access protect
* violation. */
#define PCI_IC_SWrProt PCI__BIT(19) /* A PCI slave write protect
* violation. */
#define PCI_IC_SRdBuf PCI__BIT(20) /* A PCI slave read buffer
* discard timer expired. */
#define PCI_IC_Arb PCI__BIT(21) /* Internal PCI arbiter detec-
* tion of a broken master. */
#define PCI_IC_BIST PCI__BIT(24) /* PCI BIST Interrupt */
#define PCI_IC_PMG PCI__BIT(25) /* PCI Power Management
* Interrupt */
#define PCI_IC_PRST PCI__BIT(26) /* PCI Reset Assert */
/*
31:27 Sel Specifies the error event currently being reported in the
Error Address, Error Data, and Error Command registers.
*/
#define PCI_IC_SEL_GET(v) PCI__EXT((v), 27, 5)
#define PCI_IC_SEL_SAPerr 0x00
#define PCI_IC_SEL_SWrPerr 0x01
#define PCI_IC_SEL_SRdPerr 0x02
#define PCI_IC_SEL_MAPerr 0x04
#define PCI_IC_SEL_MWrPerr 0x05
#define PCI_IC_SEL_MRdPerr 0x06
#define PCI_IC_SEL_MMabort 0x08
#define PCI_IC_SEL_MTabort 0x09
#define PCI_IC_SEL_MMasterEn 0x0a
#define PCI_IC_SEL_MRetry 0x0b
#define PCI_IC_SEL_SMabort 0x10
#define PCI_IC_SEL_STabort 0x11
#define PCI_IC_SEL_SAccProt 0x12
#define PCI_IC_SEL_SWrProt 0x13
#define PCI_IC_SEL_SRdBuf 0x14
#define PCI_IC_SEL_Arb 0x15
#define PCI_IC_SEL_BIST 0x18
#define PCI_IC_SEL_PMG 0x19
#define PCI_IC_SEL_PRST 0x1a
#define PCI_IC_SEL_Strings { \
"SAPerr", "SWrPerr", "SRdPerr", "Rsvd#03", \
"MAPerr", "MWrPerr", "MRdPerr", "Rsvd#07", \
"MMabort", "MTabort", "MMasterEn", "MRetry", \
"Rsvd#0c", "Rsvd#0d", "Rsvd#0e", "Rsvd#0f", \
"SMabort", "STabort", "SAccProt", "SWrProt", \
"SRdBuf", "Arb", "Rsvd#16", "Rsvd#17", \
"BIST", "PMG", "PRST", "Rsvd#1b", \
"Rsvd#1c", "Rsvd#1d", "Rsvd#1e", "Rsvd#1f" }
/*
* Table 315: PCI Error Mask
* If the corresponding bit is 1, that interrupt is enabled
* Bits 3, 7, 12:15, 22:23, 27:31 are reserved.
*/
#define PCI_ERRMASK_SAPErr PCI__BIT(0)
#define PCI_ERRMASK_SWrPErr PCI__BIT(1)
#define PCI_ERRMASK_SRdPErr PCI__BIT(2)
#define PCI_ERRMASK_MAPErr PCI__BIT(4)
#define PCI_ERRMASK_MWRPErr PCI__BIT(5)
#define PCI_ERRMASK_MRDPErr PCI__BIT(6)
#define PCI_ERRMASK_MMAbort PCI__BIT(8)
#define PCI_ERRMASK_MTAbort PCI__BIT(9)
#define PCI_ERRMASK_MMasterEn PCI__BIT(10)
#define PCI_ERRMASK_MRetry PCI__BIT(11)
#define PCI_ERRMASK_SMAbort PCI__BIT(16)
#define PCI_ERRMASK_STAbort PCI__BIT(17)
#define PCI_ERRMASK_SAccProt PCI__BIT(18)
#define PCI_ERRMASK_SWrProt PCI__BIT(19)
#define PCI_ERRMASK_SRdBuf PCI__BIT(20)
#define PCI_ERRMASK_Arb PCI__BIT(21)
#define PCI_ERRMASK_BIST PCI__BIT(24)
#define PCI_ERRMASK_PMG PCI__BIT(25)
#define PCI_ERRMASK_PRST PCI__BIT(26)
#endif /* _DEV_GTPCIREG_H_ */

View File

@@ -0,0 +1,854 @@
/* $NetBSD: gtreg.h,v 1.2 2005/02/27 00:27:21 perry Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved. *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DISCOVERY_DEV_GTREG_H_
#define _DISCOVERY_DEV_GTREG_H_
#define GT__BIT(bit) (1U << (bit))
#define GT__MASK(bit) (GT__BIT(bit) - 1)
#define GT__EXT(data, bit, len) (((data) >> (bit)) & GT__MASK(len))
#define GT__CLR(data, bit, len) ((data) &= ~(GT__MASK(len) << (bit)))
#define GT__INS(new, bit) ((new) << (bit))
/*
* Table 30: CPU Address Decode Register Map
*/
#define GT_SCS0_Low_Decode 0x0008
#define GT_SCS0_High_Decode 0x0010
#define GT_SCS1_Low_Decode 0x0208
#define GT_SCS1_High_Decode 0x0210
#define GT_SCS2_Low_Decode 0x0018
#define GT_SCS2_High_Decode 0x0020
#define GT_SCS3_Low_Decode 0x0218
#define GT_SCS3_High_Decode 0x0220
#define GT_CS0_Low_Decode 0x0028
#define GT_CS0_High_Decode 0x0030
#define GT_CS1_Low_Decode 0x0228
#define GT_CS1_High_Decode 0x0230
#define GT_CS2_Low_Decode 0x0248
#define GT_CS2_High_Decode 0x0250
#define GT_CS3_Low_Decode 0x0038
#define GT_CS3_High_Decode 0x0040
#define GT_BootCS_Low_Decode 0x0238
#define GT_BootCS_High_Decode 0x0240
#define GT_PCI0_IO_Low_Decode 0x0048
#define GT_PCI0_IO_High_Decode 0x0050
#define GT_PCI0_Mem0_Low_Decode 0x0058
#define GT_PCI0_Mem0_High_Decode 0x0060
#define GT_PCI0_Mem1_Low_Decode 0x0080
#define GT_PCI0_Mem1_High_Decode 0x0088
#define GT_PCI0_Mem2_Low_Decode 0x0258
#define GT_PCI0_Mem2_High_Decode 0x0260
#define GT_PCI0_Mem3_Low_Decode 0x0280
#define GT_PCI0_Mem3_High_Decode 0x0288
#define GT_PCI1_IO_Low_Decode 0x0090
#define GT_PCI1_IO_High_Decode 0x0098
#define GT_PCI1_Mem0_Low_Decode 0x00a0
#define GT_PCI1_Mem0_High_Decode 0x00a8
#define GT_PCI1_Mem1_Low_Decode 0x00b0
#define GT_PCI1_Mem1_High_Decode 0x00b8
#define GT_PCI1_Mem2_Low_Decode 0x02a0
#define GT_PCI1_Mem2_High_Decode 0x02a8
#define GT_PCI1_Mem3_Low_Decode 0x02b0
#define GT_PCI1_Mem3_High_Decode 0x02b8
#define GT_Internal_Decode 0x0068
#define GT_CPU0_Low_Decode 0x0290
#define GT_CPU0_High_Decode 0x0298
#define GT_CPU1_Low_Decode 0x02c0
#define GT_CPU1_High_Decode 0x02c8
/* ts, 2005/8: it seems that these are implicitely written
* when setting the 'Low_Decode' regs...
*/
#define GT_PCI0_IO_Remap 0x00f0
#define GT_PCI0_Mem0_Remap_Low 0x00f8
#define GT_PCI0_Mem0_Remap_High 0x0320
#define GT_PCI0_Mem1_Remap_Low 0x0100
#define GT_PCI0_Mem1_Remap_High 0x0328
#define GT_PCI0_Mem2_Remap_Low 0x02f8
#define GT_PCI0_Mem2_Remap_High 0x0330
#define GT_PCI0_Mem3_Remap_Low 0x0300
#define GT_PCI0_Mem3_Remap_High 0x0338
#define GT_PCI1_IO_Remap 0x0108
#define GT_PCI1_Mem0_Remap_Low 0x0110
#define GT_PCI1_Mem0_Remap_High 0x0340
#define GT_PCI1_Mem1_Remap_Low 0x0118
#define GT_PCI1_Mem1_Remap_High 0x0348
#define GT_PCI1_Mem2_Remap_Low 0x0310
#define GT_PCI1_Mem2_Remap_High 0x0350
#define GT_PCI1_Mem3_Remap_Low 0x0318
#define GT_PCI1_Mem3_Remap_High 0x0358
/*
* Table 31: CPU Control Register Map
*/
#define GT_CPU_Cfg 0x0000
#define GT_CPU_Mode 0x0120
#define GT_CPU_Master_Ctl 0x0160
#define GT_CPU_If_Xbar_Ctl_Low 0x0150
#define GT_CPU_If_Xbar_Ctl_High 0x0158
#define GT_CPU_If_Xbar_Timeout 0x0168
#define GT_260_CPU_Rd_Rsp_Xbar_Ctl_Low 0x0170
#define GT_260_CPU_Rd_Rsp_Xbar_Ctl_High 0x0178
/*
* Table 32: CPU Sync Barrier Register Map
*/
#define GT_260_PCI_Sync_Barrier(bus) (0x00c0 | ((bus) << 3))
#define GT_260_PCI0_Sync_Barrier 0x00c0
#define GT_260_PCI1_Sync_Barrier 0x00c8
/*
* Table 33: CPU Access Protection Register Map
*/
#define GT_Protect_Low_0 0x0180
#define GT_Protect_High_0 0x0188
#define GT_Protect_Low_1 0x0190
#define GT_Protect_High_1 0x0198
#define GT_Protect_Low_2 0x01a0
#define GT_Protect_High_2 0x01a8
#define GT_Protect_Low_3 0x01b0
#define GT_Protect_High_3 0x01b8
#define GT_260_Protect_Low_4 0x01c0
#define GT_260_Protect_High_4 0x01c8
#define GT_260_Protect_Low_5 0x01d0
#define GT_260_Protect_High_5 0x01d8
#define GT_260_Protect_Low_6 0x01e0
#define GT_260_Protect_High_6 0x01e8
#define GT_260_Protect_Low_7 0x01f0
#define GT_260_Protect_High_7 0x01f8
/*
* Table 34: Snoop Control Register Map
*/
#define GT_260_Snoop_Base_0 0x0380
#define GT_260_Snoop_Top_0 0x0388
#define GT_260_Snoop_Base_1 0x0390
#define GT_260_Snoop_Top_1 0x0398
#define GT_260_Snoop_Base_2 0x03a0
#define GT_260_Snoop_Top_2 0x03a8
#define GT_260_Snoop_Base_3 0x03b0
#define GT_260_Snoop_Top_3 0x03b8
/*
* Table 35: CPU Error Report Register Map
*/
#define GT_CPU_Error_Address_Low 0x0070
#define GT_CPU_Error_Address_High 0x0078
#define GT_CPU_Error_Data_Low 0x0128
#define GT_CPU_Error_Data_High 0x0130
#define GT_CPU_Error_Parity 0x0138
#define GT_CPU_Error_Cause 0x0140
#define GT_CPU_Error_Mask 0x0148
#define GT_DecodeAddr_SET(g, r, v) \
do { \
gt_read((g), GT_Internal_Decode); \
gt_write((g), (r), ((v) & 0xfff00000) >> 20); \
while ((gt_read((g), (r)) & 0xfff) != ((v) >> 20)); \
} while (0)
#define GT_LowAddr_GET(v) (GT__EXT((v), 0, 12) << 20)
#define GT_HighAddr_GET(v) ((GT__EXT((v), 0, 12) << 20) | 0xfffff)
#define GT_MPP_Control0 0xf000
#define GT_MPP_Control1 0xf004
#define GT_MPP_Control2 0xf008
#define GT_MPP_Control3 0xf00c
#define GT_GPP_IO_Control 0xf100
#define GT_GPP_Level_Control 0xf110
#define GT_GPP_Value 0xf104
#define GT_GPP_Interrupt_Cause 0xf108
#define GT_GPP_Interrupt_Mask 0xf10c
/*
* Table 36: SCS[0]* Low Decode Address, Offset: 0x008
* Table 38: SCS[1]* Low Decode Address, Offset: 0x208
* Table 40: SCS[2]* Low Decode Address, Offset: 0x018
* Table 42: SCS[3]* Low Decode Address, Offset: 0x218
* Table 44: CS[0]* Low Decode Address, Offset: 0x028
* Table 46: CS[1]* Low Decode Address, Offset: 0x228
* Table 48: CS[2]* Low Decode Address, Offset: 0x248
* Table 50: CS[3]* Low Decode Address, Offset: 0x038
* Table 52: BootCS* Low Decode Address, Offset: 0x238
* Table 75: CPU 0 Low Decode Address, Offset: 0x290
* Table 77: CPU 1 Low Decode Address, Offset: 0x2c0
*
* 11:00 LowAddr SCS[0] Base Address
* 31:12 Reserved Must be 0.
*/
/*
* Table 37: SCS[0]* High Decode Address, Offset: 0x010
* Table 39: SCS[1]* High Decode Address, Offset: 0x210
* Table 41: SCS[2]* High Decode Address, Offset: 0x020
* Table 43: SCS[3]* High Decode Address, Offset: 0x220
* Table 45: CS[0]* High Decode Address, Offset: 0x030
* Table 47: CS[1]* High Decode Address, Offset: 0x230
* Table 49: CS[2]* High Decode Address, Offset: 0x250
* Table 51: CS[3]* High Decode Address, Offset: 0x040
* Table 53: BootCS* High Decode Address, Offset: 0x240
* Table 76: CPU 0 High Decode Address, Offset: 0x298
* Table 78: CPU 1 High Decode Address, Offset: 0x2c8
*
* 11:00 HighAddr SCS[0] Top Address
* 31:12 Reserved
*/
/*
* Table 54: PCI_0 I/O Low Decode Address, Offset: 0x048
* Table 56: PCI_0 Memory 0 Low Decode Address, Offset: 0x058
* Table 58: PCI_0 Memory 1 Low Decode Address, Offset: 0x080
* Table 60: PCI_0 Memory 2 Low Decode Address, Offset: 0x258
* Table 62: PCI_0 Memory 3 Low Decode Address, Offset: 0x280
* Table 64: PCI_1 I/O Low Decode Address, Offset: 0x090
* Table 66: PCI_1 Memory 0 Low Decode Address, Offset: 0x0a0
* Table 68: PCI_1 Memory 1 Low Decode Address, Offset: 0x0b0
* Table 70: PCI_1 Memory 2 Low Decode Address, Offset: 0x2a0
* Table 72: PCI_1 Memory 3 Low Decode Address, Offset: 0x2b0
*
* 11:00 LowAddr PCI IO/Memory Space Base Address
* 23:12 Reserved
* 26:24 PCISwap PCI Master Data Swap Control (0: Byte Swap;
* 1: No swapping; 2: Both byte and word swap;
* 3: Word swap; 4..7: Reserved)
* 27:27 PCIReq64 PCI master REQ64* policy (Relevant only when
* configured to 64-bit PCI bus and not I/O)
* 0: Assert s REQ64* only when transaction
* is longer than 64-bits.
* 1: Always assert REQ64*.
* 31:28 Reserved
*/
#define GT_PCISwap_GET(v) GT__EXT((v), 24, 3)
#define GT_PCISwap_ByteSwap 0
#define GT_PCISwap_NoSwap 1
#define GT_PCISwap_ByteWordSwap 2
#define GT_PCISwap_WordSwap 3
#define GT_PCI_LowDecode_PCIReq64 GT__BIT(27)
/*
* Table 55: PCI_0 I/O High Decode Address, Offset: 0x050
* Table 57: PCI_0 Memory 0 High Decode Address, Offset: 0x060
* Table 59: PCI_0 Memory 1 High Decode Address, Offset: 0x088
* Table 61: PCI_0 Memory 2 High Decode Address, Offset: 0x260
* Table 63: PCI_0 Memory 3 High Decode Address, Offset: 0x288
* Table 65: PCI_1 I/O High Decode Address, Offset: 0x098
* Table 67: PCI_1 Memory 0 High Decode Address, Offset: 0x0a8
* Table 69: PCI_1 Memory 1 High Decode Address, Offset: 0x0b8
* Table 71: PCI_1 Memory 2 High Decode Address, Offset: 0x2a8
* Table 73: PCI_1 Memory 3 High Decode Address, Offset: 0x2b8
*
* 11:00 HighAddr PCI_0 I/O Space Top Address
* 31:12 Reserved
*/
/*
* Table 74: Internal Space Decode, Offset: 0x068
* 15:00 IntDecode GT64260 Internal Space Base Address
* 23:16 Reserved
* 26:24 PCISwap Same as PCI_0 Memory 0 Low Decode Address.
* NOTE: Reserved for Galileo Technology usage.
* Relevant only for PCI master configuration
* transactions on the PCI bus.
* 31:27 Reserved
*/
/*
* Table 79: PCI_0 I/O Address Remap, Offset: 0x0f0
* Table 80: PCI_0 Memory 0 Address Remap Low, Offset: 0x0f8
* Table 82: PCI_0 Memory 1 Address Remap Low, Offset: 0x100
* Table 84: PCI_0 Memory 2 Address Remap Low, Offset: 0x2f8
* Table 86: PCI_0 Memory 3 Address Remap Low, Offset: 0x300
* Table 88: PCI_1 I/O Address Remap, Offset: 0x108
* Table 89: PCI_1 Memory 0 Address Remap Low, Offset: 0x110
* Table 91: PCI_1 Memory 1 Address Remap Low, Offset: 0x118
* Table 93: PCI_1 Memory 2 Address Remap Low, Offset: 0x310
* Table 95: PCI_1 Memory 3 Address Remap Low, Offset: 0x318
*
* 11:00 Remap PCI IO/Memory Space Address Remap (31:20)
* 31:12 Reserved
*/
/*
* Table 81: PCI_0 Memory 0 Address Remap High, Offset: 0x320
* Table 83: PCI_0 Memory 1 Address Remap High, Offset: 0x328
* Table 85: PCI_0 Memory 2 Address Remap High, Offset: 0x330
* Table 87: PCI_0 Memory 3 Address Remap High, Offset: 0x338
* Table 90: PCI_1 Memory 0 Address Remap High, Offset: 0x340
* Table 92: PCI_1 Memory 1 Address Remap High, Offset: 0x348
* Table 94: PCI_1 Memory 2 Address Remap High, Offset: 0x350
* Table 96: PCI_1 Memory 3 Address Remap High, Offset: 0x358
*
* 31:00 Remap PCI Memory Address Remap (high 32 bits)
*/
/*
* Table 97: CPU Configuration, Offset: 0x000
* 07:00 NoMatchCnt CPU Address Miss Counter
* 08:08 NoMatchCntEn CPU Address Miss Counter Enable
* NOTE: Relevant only if multi-GT is enabled.
* (0: Disabled; 1: Enabled)
* 09:09 NoMatchCntExt CPU address miss counter MSB
* 10:10 Reserved
* 11:11 AACKDelay Address Acknowledge Delay
* 0: AACK* is asserted one cycle after TS*.
* 1: AACK* is asserted two cycles after TS*.
* 12:12 Endianess Must be 0
* NOTE: The GT64260 does not support the PowerPC
* Little Endian convention
* 13:13 Pipeline Pipeline Enable
* 0: Disabled. The GT64260 will not respond with
* AACK* to a new CPU transaction, before the
* previous transaction data phase completes.
* 1: Enabled.
* 14:14 Reserved
* 15:15 TADelay Transfer Acknowledge Delay
* 0: TA* is asserted one cycle after AACK*
* 1: TA* is asserted two cycles after AACK*
* 16:16 RdOOO Read Out of Order Completion
* 0: Not Supported, Data is always returned in
* order (DTI[0-2] is always driven
* 1: Supported
* 17:17 StopRetry Relevant only if PCI Retry is enabled
* 0: Keep Retry all PCI transactions targeted
* to the GT64260.
* 1: Stop Retry of PCI transactions.
* 18:18 MultiGTDec Multi-GT Address Decode
* 0: Normal address decoding
* 1: Multi-GT address decoding
* 19:19 DPValid CPU DP[0-7] Connection. CPU write parity ...
* 0: is not checked. (Not connected)
* 1: is checked (Connected)
* 21:20 Reserved
* 22:22 PErrProp Parity Error Propagation
* 0: GT64260 always drives good parity on
* DP[0-7] during CPU reads.
* 1: GT64260 drives bad parity on DP[0-7] in case
* the read response from the target interface
* comes with erroneous data indication
* (e.g. ECC error from SDRAM interface).
* 25:23 Reserved
* 26:26 APValid CPU AP[0-3] Connection. CPU address parity ...
* 0: is not checked. (Not connected)
* 1: is checked (Connected)
* 27:27 RemapWrDis Address Remap Registers Write Control
* 0: Write to Low Address decode register.
* Results in writing of the corresponding
* Remap register.
* 1: Write to Low Address decode register. No
* affect on the corresponding Remap register.
* 28:28 ConfSBDis Configuration Read Sync Barrier Disable
* 0: enabled; 1: disabled
* 29:29 IOSBDis I/O Read Sync Barrier Disable
* 0: enabled; 1: disabled
* 30:30 ClkSync Clocks Synchronization
* 0: The CPU interface is running with SysClk,
* which is asynchronous to TClk.
* 1: The CPU interface is running with TClk.
* 31:31 Reserved
*/
#define GT_CPUCfg_NoMatchCnt_GET(v) GT__EXT((v), 0, 8)
#define GT_CPUCfg_NoMatchCntEn GT__BIT( 9)
#define GT_CPUCfg_NoMatchCntExt GT__BIT(10)
#define GT_CPUCfg_AACKDelay GT__BIT(11)
#define GT_CPUCfg_Endianess GT__BIT(12)
#define GT_CPUCfg_Pipeline GT__BIT(13)
#define GT_CPUCfg_TADelay GT__BIT(15)
#define GT_CPUCfg_RdOOO GT__BIT(16)
#define GT_CPUCfg_StopRetry GT__BIT(17)
#define GT_CPUCfg_MultiGTDec GT__BIT(18)
#define GT_CPUCfg_DPValid GT__BIT(19)
#define GT_CPUCfg_PErrProp GT__BIT(22)
#define GT_CPUCfg_APValid GT__BIT(26)
#define GT_CPUCfg_RemapWrDis GT__BIT(27)
#define GT_CPUCfg_ConfSBDis GT__BIT(28)
#define GT_CPUCfg_IOSBDis GT__BIT(29)
#define GT_CPUCfg_ClkSync GT__BIT(30)
/*
* Table 98: CPU Mode, Offset: 0x120, Read only
* 01:00 MultiGTID Multi-GT ID
* Represents the ID to which the GT64260 responds
* to during a multi-GT address decoding period.
* 02:02 MultiGT (0: Single; 1: Multiple) GT configuration
* 03:03 RetryEn (0: Don't; 1: Do) Retry PCI transactions
* 07:04 CPUType
* 0x0-0x3: Reserved
* 0x4: 64-bit PowerPC CPU, 60x bus
* 0x5: 64-bit PowerPC CPU, MPX bus
* 0x6-0xf: Reserved
* 31:08 Reserved
*/
#define GT_CPUMode_MultiGTID_GET(v) GT__EXT(v, 0, 2)
#define GT_CPUMode_MultiGT GT__BIT(2)
#define GT_CPUMode_RetryEn GT__BIT(3)
#define GT_CPUMode_CPUType_GET(v) GT__EXT(v, 4, 4)
/*
* Table 99: CPU Master Control, Offset: 0x160
* 07:00 Reserved
* 08:08 IntArb CPU Bus Internal Arbiter Enable
* NOTE: Only relevant to 60x bus mode. When
* running MPX bus, the GT64260 internal
* arbiter must be used.
* 0: Disabled. External arbiter is required.
* 1: Enabled. Use the GT64260 CPU bus arbiter.
* 09:09 IntBusCtl CPU Interface Unit Internal Bus Control
* NOTE: This bit must be set to 1. It is reserved
* for Galileo Technology usage.
* 0: Enable internal bus sharing between master
* and slave interfaces.
* 1: Disable internal bus sharing between master
* and slave interfaces.
* 10:10 MWrTrig Master Write Transaction Trigger
* 0: With first valid write data
* 1: With last valid write data
* 11:11 MRdTrig Master Read Response Trigger
* 0: With first valid read data
* 1: With last valid read data
* 12:12 CleanBlock Clean Block Snoop Transaction Support
* 0: CPU does not support clean block (603e,750)
* 1: CPU supports clean block (604e,G4)
* 13:13 FlushBlock Flush Block Snoop Transaction Support
* 0: CPU does not support flush block (603e,750)
* 1: CPU supports flush block (604e,G4)
* 31:14 Reserved
*/
#define GT_CPUMstrCtl_IntArb GT__BIT(8)
#define GT_CPUMstrCtl_IntBusCtl GT__BIT(9)
#define GT_CPUMstrCtl_MWrTrig GT__BIT(10)
#define GT_CPUMstrCtl_MRdTrig GT__BIT(11)
#define GT_CPUMstrCtl_CleanBlock GT__BIT(12)
#define GT_CPUMstrCtl_FlushBlock GT__BIT(13)
#define GT_ArbSlice_SDRAM 0x0 /* SDRAM interface snoop request */
#define GT_ArbSlice_DEVICE 0x1 /* Device request */
#define GT_ArbSlice_NULL 0x2 /* NULL request */
#define GT_ArbSlice_PCI0 0x3 /* PCI_0 access */
#define GT_ArbSlice_PCI1 0x4 /* PCI_1 access */
#define GT_ArbSlice_COMM 0x5 /* Comm unit access */
#define GT_ArbSlice_IDMA0123 0x6 /* IDMA channels 0/1/2/3 access */
#define GT_ArbSlice_IDMA4567 0x7 /* IDMA channels 4/5/6/7 access */
/* 0x8-0xf: Reserved */
/* Pass in the slice number (from 0..16) as 'n'
*/
#define GT_XbarCtl_GET_ArbSlice(v, n) GT__EXT((v), (((n) & 7)*4, 4)
/*
* Table 100: CPU Interface Crossbar Control Low, Offset: 0x150
* 03:00 Arb0 Slice 0 of CPU Master pizza Arbiter
* 07:04 Arb1 Slice 1 of CPU Master pizza Arbiter
* 11:08 Arb2 Slice 2 of CPU Master pizza Arbiter
* 15:12 Arb3 Slice 3 of CPU Master pizza Arbiter
* 19:16 Arb4 Slice 4 of CPU Master pizza Arbiter
* 23:20 Arb5 Slice 5 of CPU Master pizza Arbiter
* 27:24 Arb6 Slice 6 of CPU Master pizza Arbiter
* 31:28 Arb7 Slice 7 of CPU Master pizza Arbiter
*/
/*
* Table 101: CPU Interface Crossbar Control High, Offset: 0x158
* 03:00 Arb8 Slice 8 of CPU Master pizza Arbiter
* 07:04 Arb9 Slice 9 of CPU Master pizza Arbiter
* 11:08 Arb10 Slice 10 of CPU Master pizza Arbiter
* 15:12 Arb11 Slice 11 of CPU Master pizza Arbiter
* 19:16 Arb12 Slice 12 of CPU Master pizza Arbiter
* 23:20 Arb13 Slice 13 of CPU Master pizza Arbiter
* 27:24 Arb14 Slice 14 of CPU Master pizza Arbiter
* 31:28 Arb15 Slice 15 of CPU Master pizza Arbiter
*/
/*
* Table 102: CPU Interface Crossbar Timeout, Offset: 0x168
* NOTE: Reserved for Galileo Technology usage.
* 07:00 Timeout Crossbar Arbiter Timeout Preset Value
* 15:08 Reserved
* 16:16 TimeoutEn Crossbar Arbiter Timer Enable
* (0: Enable; 1: Disable)
* 31:17 Reserved
*/
/*
* Table 103: CPU Read Response Crossbar Control Low, Offset: 0x170
* 03:00 Arb0 Slice 0 of CPU Slave pizza Arbiter
* 07:04 Arb1 Slice 1 of CPU Slave pizza Arbiter
* 11:08 Arb2 Slice 2 of CPU Slave pizza Arbiter
* 15:12 Arb3 Slice 3 of CPU Slave pizza Arbiter
* 19:16 Arb4 Slice 4 of CPU Slave pizza Arbiter
* 23:20 Arb5 Slice 5 of CPU Slave pizza Arbiter
* 27:24 Arb6 Slice 6 of CPU Slave pizza Arbiter
* 31:28 Arb7 Slice 7 of CPU Slave pizza Arbiter
*/
/*
* Table 104: CPU Read Response Crossbar Control High, Offset: 0x178
* 03:00 Arb8 Slice 8 of CPU Slave pizza Arbiter
* 07:04 Arb9 Slice 9 of CPU Slave pizza Arbiter
* 11:08 Arb10 Slice 10 of CPU Slave pizza Arbiter
* 15:12 Arb11 Slice 11 of CPU Slave pizza Arbiter
* 19:16 Arb12 Slice 12 of CPU Slave pizza Arbiter
* 23:20 Arb13 Slice 13 of CPU Slave pizza Arbiter
* 27:24 Arb14 Slice 14 of CPU Slave pizza Arbiter
* 31:28 Arb15 Slice 15 of CPU Slave pizza Arbiter
*/
/*
* Table 105: PCI_0 Sync Barrier Virtual Register, Offset: 0x0c0
* Table 106: PCI_1 Sync Barrier Virtual Register, Offset: 0x0c8
* NOTE: The read data is random and should be ignored.
* 31:00 SyncBarrier A CPU read from this register creates a
* synchronization barrier cycle.
*/
/*
* Table 107: CPU Protect Address 0 Low, Offset: 0x180
* Table 109: CPU Protect Address 1 Low, Offset: 0x190
* Table 111: CPU Protect Address 2 Low, Offset: 0x1a0
* Table 113: CPU Protect Address 3 Low, Offset: 0x1b0
* Table 115: CPU Protect Address 4 Low, Offset: 0x1c0
* Table 117: CPU Protect Address 5 Low, Offset: 0x1d0
* Table 119: CPU Protect Address 6 Low, Offset: 0x1e0
* Table 121: CPU Protect Address 7 Low, Offset: 0x1f0
*
* 11:00 LowAddr CPU Protect Region Base Address
* Corresponds to address bits[31:20].
* 15:12 Reserved. Must be 0
* 16:16 AccProtect CPU Access Protect
* Access is (0: allowed; 1: forbidden)
* 17:17 WrProtect CPU Write Protect
* Writes are (0: allowed; 1: forbidden)
* 18:18 CacheProtect CPU caching protect. Caching (block read)
* is (0: allowed; 1: forbidden)
* 31:19 Reserved
*/
#define GT_CPU_AccProtect GT__BIT(16)
#define GT_CPU_WrProtect GT__BIT(17)
#define GT_CPU_CacheProtect GT__BIT(18)
/*
* Table 108: CPU Protect Address 0 High, Offset: 0x188
* Table 110: CPU Protect Address 1 High, Offset: 0x198
* Table 112: CPU Protect Address 2 High, Offset: 0x1a8
* Table 114: CPU Protect Address 3 High, Offset: 0x1b8
* Table 116: CPU Protect Address 4 High, Offset: 0x1c8
* Table 118: CPU Protect Address 5 High, Offset: 0x1d8
* Table 120: CPU Protect Address 6 High, Offset: 0x1e8
* Table 122: CPU Protect Address 7 High, Offset: 0x1f8
*
* 11:00 HighAddr CPU Protect Region Top Address
* Corresponds to address bits[31:20]
* 31:12 Reserved
*/
/*
* Table 123: Snoop Base Address 0, Offset: 0x380
* Table 125: Snoop Base Address 1, Offset: 0x390
* Table 127: Snoop Base Address 2, Offset: 0x3a0
* Table 129: Snoop Base Address 3, Offset: 0x3b0
*
* 11:00 LowAddr Snoop Region Base Address [31:20]
* 15:12 Reserved Must be 0.
* 17:16 Snoop Snoop Type
* 0x0: No Snoop
* 0x1: Snoop to WT region
* 0x2: Snoop to WB region
* 0x3: Reserved
* 31:18 Reserved
*/
#define GT_Snoop_GET(v) GT__EXT((v), 16, 2)
#define GT_Snoop_INS(v) GT__INS((v), 16)
#define GT_Snoop_None 0
#define GT_Snoop_WT 1
#define GT_Snoop_WB 2
/*
* Table 124: Snoop Top Address 0, Offset: 0x388
* Table 126: Snoop Top Address 1, Offset: 0x398
* Table 128: Snoop Top Address 2, Offset: 0x3a8
* Table 130: Snoop Top Address 3, Offset: 0x3b8
* 11:00 HighAddr Snoop Region Top Address [31:20]
* 31:12 Reserved
*/
/*
* Table 131: CPU Error Address Low, Offset: 0x070, Read Only.
* In case of multiple errors, only the first one is latched. New error
* report latching is enabled only after the CPU Error Address Low register
* is being read.
* 31:00 ErrAddr Latched address bits [31:0] of a CPU
* transaction in case of:
* o illegal address (failed address decoding)
* o access protection violation
* o bad data parity
* o bad address parity
* Upon address latch, no new address are
* registered (due to additional error condition),
* until the register is being read.
*/
/*
* Table 132: CPU Error Address High, Offset: 0x078, Read Only.
* Once data is latched, no new data can be registered (due to additional
* error condition), until CPU Error Low Address is being read (which
* implies, it should be the last being read by the interrupt handler).
* 03:00 Reserved
* 07:04 ErrPar Latched address parity bits in case
* of bad CPU address parity detection.
* 31:08 Reserved
*/
#define GT_CPUErrorAddrHigh_ErrPar_GET(v) GT__EXT((v), 4, 4)
/*
* Table 133: CPU Error Data Low, Offset: 0x128, Read only.
* 31:00 PErrData Latched data bits [31:0] in case of bad data
* parity sampled on write transactions or on
* master read transactions.
*/
/*
* Table 134: CPU Error Data High, Offset: 0x130, Read only.
* 31:00 PErrData Latched data bits [63:32] in case of bad data
* parity sampled on write transactions or on
* master read transactions.
*/
/*
* Table 135: CPU Error Parity, Offset: 0x138, Read only.
* 07:00 PErrPar Latched data parity bus in case of bad data
* parity sampled on write transactions or on
* master read transactions.
* 31:10 Reserved
*/
#define GT_CPUErrorParity_PErrPar_GET(v) GT__EXT((v), 0, 8)
/*
* Table 136: CPU Error Cause, Offset: 0x140
* Bits[7:0] are clear only. A cause bit is set upon an error condition
* occurrence. Write a 0 value to clear the bit. Writing a 1 value has
* no affect.
* 00:00 AddrOut CPU Address Out of Range
* 01:01 AddrPErr Bad Address Parity Detected
* 02:02 TTErr Transfer Type Violation.
* The CPU attempts to burst (read or write) to an
* internal register.
* 03:03 AccErr Access to a Protected Region
* 04:04 WrErr Write to a Write Protected Region
* 05:05 CacheErr Read from a Caching protected region
* 06:06 WrDataPErr Bad Write Data Parity Detected
* 07:07 RdDataPErr Bad Read Data Parity Detected
* 26:08 Reserved
* 31:27 Sel Specifies the error event currently being
* reported in Error Address, Error Data, and
* Error Parity registers.
* 0x0: AddrOut
* 0x1: AddrPErr
* 0x2: TTErr
* 0x3: AccErr
* 0x4: WrErr
* 0x5: CacheErr
* 0x6: WrDataPErr
* 0x7: RdDataPErr
* 0x8-0x1f: Reserved
*/
#define GT_CPUError_AddrOut GT__BIT(GT_CPUError_Sel_AddrOut)
#define GT_CPUError_AddrPErr GT__BIT(GT_CPUError_Sel_AddrPErr)
#define GT_CPUError_TTErr GT__BIT(GT_CPUError_Sel_TTErr)
#define GT_CPUError_AccErr GT__BIT(GT_CPUError_Sel_AccErr)
#define GT_CPUError_WrErr GT__BIT(GT_CPUError_Sel_WrPErr)
#define GT_CPUError_CacheErr GT__BIT(GT_CPUError_Sel_CachePErr)
#define GT_CPUError_WrDataPErr GT__BIT(GT_CPUError_Sel_WrDataPErr)
#define GT_CPUError_RdDataPErr GT__BIT(GT_CPUError_Sel_RdDataPErr)
#define GT_CPUError_Sel_AddrOut 0
#define GT_CPUError_Sel_AddrPErr 1
#define GT_CPUError_Sel_TTErr 2
#define GT_CPUError_Sel_AccErr 3
#define GT_CPUError_Sel_WrErr 4
#define GT_CPUError_Sel_CacheErr 5
#define GT_CPUError_Sel_WrDataPErr 6
#define GT_CPUError_Sel_RdDataPErr 7
#define GT_CPUError_Sel_GET(v) GT__EXT((v), 27, 5)
/*
* Table 137: CPU Error Mask, Offset: 0x148
* 00:00 AddrOut If set to 1, enables AddrOut interrupt.
* 01:01 AddrPErr If set to 1, enables AddrPErr interrupt.
* 02:02 TTErr If set to 1, enables TTErr interrupt.
* 03:03 AccErr If set to 1, enables AccErr interrupt.
* 04:04 WrErr If set to 1, enables WrErr interrupt.
* 05:05 CacheErr If set to 1, enables CacheErr interrupt.
* 06:06 WrDataPErr If set to 1, enables WrDataPErr interrupt.
* 07:07 RdDataPErr If set to 1, enables RdDataPErr interrupt.
* 31:08 Reserved
*/
/*
* Comm Unit Interrupt registers
*/
/* Comm Unit Arbiter Control */
#define GT_CommUnitArb_Ctrl 0xf300
/* GPP IRQs level vs. edge sensitivity */
#define GT_CommUnitArb_Ctrl_GPP_Ints_Level_Sensitive (1<<10)
#define GT_CommUnitIntr_Cause 0xf310
#define GT_CommUnitIntr_Mask 0xf314
#define GT_CommUnitIntr_ErrAddr 0xf318
#define GT_CommUnitIntr_E0 0x00000007
#define GT_CommUnitIntr_E1 0x00000070
#define GT_CommUnitIntr_E2 0x00000700
#define GT_CommUnitIntr_S0 0x00070000
#define GT_CommUnitIntr_S1 0x00700000
#define GT_CommUnitIntr_Sel 0x70000000
/*
* SDRAM Error Report (ECC) Registers
*/
#define GT_260_ECC_Data_Lo 0x484 /* latched Error Data (low) */
#define GT_260_ECC_Data_Hi 0x480 /* latched Error Data (high) */
#define GT_260_ECC_Addr 0x490 /* latched Error Address */
#define GT_260_ECC_Rec 0x488 /* latched ECC code from SDRAM */
#define GT_260_ECC_Calc 0x48c /* latched ECC code from SDRAM */
#define GT_260_ECC_Ctl 0x494 /* ECC Control */
#define GT_260_ECC_Count 0x498 /* ECC 1-bit error count */
/* Timer/Counter Registers (t. straumann)
*/
#define GT_TIMER_0 0x0850 /* preset / running value */
#define GT_TIMER_1 0x0854
#define GT_TIMER_2 0x0858
#define GT_TIMER_3 0x085c
#define GT_TIMER_0_3_Ctl 0x0864
#define GT_TIMER_0_Ctl_Enb 0x00000001 /* enable timer */
#define GT_TIMER_0_Ctl_Rld 0x00000002 /* reload after expiration */
#define GT_TIMER_1_Ctl_Enb 0x00000100 /* enable timer */
#define GT_TIMER_1_Ctl_Rld 0x00000200 /* reload after expiration */
#define GT_TIMER_2_Ctl_Enb 0x00010000 /* enable timer */
#define GT_TIMER_2_Ctl_Rld 0x00020000 /* reload after expiration */
#define GT_TIMER_3_Ctl_Enb 0x01000000 /* enable timer */
#define GT_TIMER_3_Ctl_Rld 0x02000000 /* reload after expiration */
#define GT_TIMER_0_3_Intr_Cse 0x0868
#define GT_TIMER_0_Intr 0x00000001
#define GT_TIMER_1_Intr 0x00000002
#define GT_TIMER_2_Intr 0x00000004
#define GT_TIMER_3_Intr 0x00000008
#define GT_TIMER_Intr_Smry 0x80000000 /* Interrupt Summary */
#define GT_TIMER_0_3_Intr_Msk 0x086c
/*
* Watchdog Registers
*/
#define GT_WDOG_Config 0xb410
#define GT_WDOG_Value 0xb414
#define GT_WDOG_Value_NMI GT__MASK(24)
#define GT_WDOG_Config_Preset GT__MASK(24)
#define GT_WDOG_Config_Ctl1a GT__BIT(24)
#define GT_WDOG_Config_Ctl1b GT__BIT(25)
#define GT_WDOG_Config_Ctl2a GT__BIT(26)
#define GT_WDOG_Config_Ctl2b GT__BIT(27)
#define GT_WDOG_Config_Enb GT__BIT(31)
#define GT_WDOG_NMI_DFLT (GT__MASK(24) & GT_WDOG_Value_NMI)
#define GT_WDOG_Preset_DFLT (GT__MASK(22) & GT_WDOG_Config_Preset)
/*
* Device Bus Interrupts
*/
#define GT_DEVBUS_ICAUSE 0x4d0 /* Device Interrupt Cause */
#define GT_DEVBUS_IMASK 0x4d4 /* Device Interrupt Mask */
#define GT_DEVBUS_ERR_ADDR 0x4d8 /* Device Error Address */
/*
* bit defines for GT_DEVBUS_ICAUSE, GT_DEVBUS_IMASK
*/
#define GT_DEVBUS_DBurstErr GT__BIT(0)
#define GT_DEVBUS_DRdyErr GT__BIT(1)
#define GT_DEVBUS_Sel GT__BIT(27)
#define GT_DEVBUS_RES ~(GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr|GT_DEVBUS_Sel)
/* MV64360 */
/* Enable individual CPU windows by *clearing* respective bits
* in MV_64360_BASE_ADDR_DISBL
*
* Bit ordering is:
*
* SDRAM_CS_0..3 (1<<0..3)
* DEV_CS_0..3 (1<<4..7)
* BOOT_CS_0..3 (1<<8)
* PCI_0_IO (1<<9)
* PCI_0_MEM_0..3 (1<<10..13)
* PCI_1_IO (1<<14)
* PCI_1_MEM_0..3 (1<<15..18)
* INTERNAL_SRAM (1<<19)
* MV64x60_REGS (1<<20)
*/
#define MV_64360_BASE_ADDR_DISBL (0x278)
/* Internal SRAM */
#define MV_64360_SRAM_BASE (0x268)
#define MV_64360_SRAM_CTRL (0x380)
/* Control register bits */
#define MV_64360_SRAM_CacheWb GT__BIT(1)
/* default setup used by linux, motload (uses 90 instead of b0), ...
* Comments say:
* - parity enabled,
* - parity error propagation
* - arbitration not parked for CPU only
* - other bits are reserved
*/
#define MV_64360_SRAM_Ctl_Setup (0x001600b0)
#define MV_64360_SRAM_TEST_MODE (0x3f4)
#define MV_64340_SRAM_ERR_CAUSE (0x388)
#define MV_64340_SRAM_ERR_ADDR (0x390)
#define MV_64340_SRAM_ERR_ADDR_HI (0X3f8)
#define MV_64340_SRAM_ERR_DATA_LO (0x398)
#define MV_64340_SRAM_ERR_DATA_HI (0x3a0)
#define MV_64340_SRAM_ERR_DATA_PARITY (0x3a8)
#endif /* !_DISCOVERY_DEV_GTREG_H */

View File

@@ -0,0 +1,31 @@
$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/LICENSE,v 1.3 2005/01/06 01:42:38 imp Exp $
/*-
Copyright (c) 2001-2003, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

View File

@@ -0,0 +1,92 @@
#
# Makefile.lib,v 1.5 2000/06/12 15:00:14 joel Exp
#
# Templates/Makefile.lib
# Template library Makefile
#
LIBNAME=libif_em.a # xxx- your library names goes here
#PGMS=${ARCH}/if_em.obj
LIB=${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES=if_em_hw if_em if_em_rtems
#C_PIECES=if_em_hw if_em if_em_rtems if_em.modini
MODOBJS=$(ARCH)/if_em.o $(ARCH)/if_em_hw.o $(ARCH)/if_em.modini.o
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_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_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/lib.cfg
#
# Add local stuff here using +=
#
DEFINES += -DHAVE_LIBBSPEXT
CPPFLAGS += -I. -Ilibchip -Iporting
CFLAGS += -Wno-unused-variable -msoft-float
#
# 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) $(LIB) ${PGMS}
# doesn't work if we define this just after OBJS= :-(
# must be after inclusion of RTEMS_CUSTOM
$(LIB): OBJS=$(filter-out %.modini.o,$(OBJS))
$(LIB): ${OBJS}
$(make-library)
#How to make a relocatable object
$(filter %.obj, $(PGMS)): $(MODOBJS)
$(make-obj)
ifndef RTEMS_SITE_INSTALLDIR
RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
endif
${RTEMS_SITE_INSTALLDIR}/include \
${RTEMS_SITE_INSTALLDIR}/lib \
${RTEMS_SITE_INSTALLDIR}/bin \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/include \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/lib \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/bin :
test -d $@ || mkdir -p $@
# Install the library, appending _g or _p as appropriate.
# for include files, just use $(INSTALL_CHANGE)
#
# NOTES:
# - BSP specific libraries, headers etc. should be installed to
# $RTEMS_SITE_INSTALLDIR)/$(RTEMS_BSP)/lib
#
install: all $(RTEMS_SITE_INSTALLDIR)/lib
$(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib

View File

@@ -0,0 +1,332 @@
$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/README,v 1.10 2005/07/11 02:33:25 delphij Exp $
FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
============================================================
March 18, 2005
Contents
========
- Overview
- Identifying Your Adapter
- Building and Installation
- Speed and Duplex Configuration
- Additional Configurations
- Known Limitations
- Support
- License
Overview
========
This file describes the FreeBSD* driver, version 2.1.x, for the Intel(R)
PRO/1000 Family of Adapters. This driver has been developed for use with
FreeBSD, version 5.x.
For questions related to hardware requirements, refer to the documentation
supplied with your Intel PRO/1000 adapter. All hardware requirements listed
apply to use with FreeBSD.
Identifying Your Adapter
========================
For information on how to identify your adapter, go to the Adapter &
Driver ID Guide at:
http://support.intel.com/support/network/adapter/pro100/21397.htm
For the latest Intel network drivers for FreeBSD, see:
http://appsr.intel.com/scripts-df/support_intel.asp
NOTE: Mobile adapters are not fully supported.
Building and Installation
=========================
NOTE: The driver can be installed as a dynamic loadable kernel module or
compiled into the kernel. You must have kernel sources installed in
order to compile the driver module.
In the instructions below, x.x.x is the driver version as indicated in the
name of the driver tar file.
1. Move the base driver tar file to the directory of your choice. For
example, use /home/username/em or /usr/local/src/em.
2. Untar/unzip the archive:
tar xvfz em-x.x.x.tar.gz
This will create an em-x.x.x directory.
3. To create a loadable module, perform the following steps.
NOTE: To compile the driver into the kernel, go directly to step 4.
a. To compile the module
cd em-x.x.x
make
b. To install the compiled module in system directory:
make install
c. If you want the driver to load automatically when the system is booted:
1. Edit /boot/loader.conf, and add the following line:
if_em_load="YES"
4. To compile the driver into the kernel:
cd em-x.x.x/src
cp if_em* /usr/src/sys/dev/em
cp Makefile.kernel /usr/src/sys/modules/em/Makefile
Edit the /usr/src/sys/conf/files.i386 file, and add the following lines only if
they don't already exist:
dev/em/if_em.c optional em
dev/em/if_em_hw.c optional em
Remove the following lines from the /usr/src/sys/conf/files.i386 file,
if they exist:
dev/em/if_em_fxhw.c optional em
dev/em/if_em_phy.c optional em
Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in
/usr/src/sys/i386/conf, and ensure the following line is present:
device em
Compile and install the kernel. The system must be rebooted for the kernel
updates to take effect. For additional information on compiling the
kernel, consult the FreeBSD operating system documentation.
5. To assign an IP address to the interface, enter the following:
ifconfig em<interface_num> <IP_address>
6. Verify that the interface works. Enter the following, where <IP_address>
is the IP address for another machine on the same subnet as the interface
that is being tested:
ping <IP_address>
7. To configure the IP address to remain after reboot, edit /etc/rc.conf,
and create the appropriate ifconfig_em<interface_num>entry:
ifconfig_em<interface_num>="<ifconfig_settings>"
Example usage:
ifconfig_em0="inet 192.168.10.1 netmask 255.255.255.0"
NOTE: For assistance, see the ifconfig man page.
Speed and Duplex Configuration
==============================
By default, the adapter auto-negotiates the speed and duplex of the
connection. If there is a specific need, the ifconfig utility can be used to
configure the speed and duplex settings on the adapter. Example usage:
ifconfig em<interface_num> <IP_address> media 100baseTX mediaopt
full-duplex
NOTE: Only use mediaopt to set the driver to full-duplex. If mediaopt is
not specified and you are not running at gigabit speed, the driver
defaults to half-duplex.
This driver supports the following media type options:
autoselect - Enables auto-negotiation for speed and duplex.
10baseT/UTP - Sets speed to 10 Mbps. Use the ifconfig mediaopt
option to select full-duplex mode.
100baseTX - Sets speed to 100 Mbps. Use the ifconfig mediaopt
option to select full-duplex mode.
1000baseTX - Sets speed to 1000 Mbps. In this case, the driver
supports only full-duplex mode.
1000baseSX - Sets speed to 1000 Mbps. In this case, the driver
supports only full-duplex mode.
For more information on the ifconfig utility, see the ifconfig man page.
Additional Configurations
=========================
The driver supports Transmit/Receive Checksum Offload and Jumbo Frames on
all but the 82542-based adapters. For specific adapters, refer to the
Identifying Your Adapter section.
Jumbo Frames
------------
To enable Jumbo Frames, use the ifconfig utility to increase the MTU
beyond 1500 bytes.
NOTES: Only enable Jumbo Frames if your network infrastructure supports
them.
The Jumbo Frames setting on the switch must be set to at least
22 bytes larger than that of the MTU.
The Intel PRO/1000 PM Network Connection does not support jumbo
frames.
The Jumbo Frames MTU range for Intel Adapters is 1500 to 16114. The default
MTU range is 1500. To modify the setting, enter the following:
ifconfig em<interface_num> <hostname or IP address> mtu 9000
To confirm the MTU used between two specific devices, use:
route get <destination_IP_address>
VLANs
-----
To create a new VLAN interface:
ifconfig <vlan_name> create
To associate the VLAN interface with a physical interface and
assign a VLAN ID, IP address, and netmask:
ifconfig <vlan_name> <ip_address> netmask <subnet_mask> vlan
<vlan_id> vlandev <physical_interface>
Example:
ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan10 vlandev em0
In this example, all packets will be marked on egress with 802.1Q VLAN
tags, specifying a VLAN ID of 10.
To remove a VLAN interface:
ifconfig <vlan_name> destroy
Polling
-------
NOTES: DEVICE POLLING is only valid for non-SMP kernels.
The driver has to be compiled into the kernel for DEVICE POLLING to be
enabled in the driver.
To enable polling in the driver, add the following options to the kernel
configuration, and then recompile the kernel:
options DEVICE_POLLING
options HZ=1000
At runtime use:
sysctl kern.polling.enable=1 to turn polling on
Use:
sysctl kern.polling.enable=0 to turn polling off
Checksum Offload
----------------
Checksum offloading is not supported on 82542 Gigabit adapters.
Checksum offloading supports both TCP and UDP packets and is
supported for both transmit and receive.
Checksum offloading can be enabled or disabled using ifconfig.
Both transmit and receive offloading will be either enabled or
disabled together. You cannot enable/disable one without the other.
To enable checksum offloading:
ifconfig <interface_num> rxcsum
To disable checksum offloading:
ifconfig <interface_num> -rxcsum
To confirm the current setting:
ifconfig <interface_num>
Look for the presence or absence of the following line:
options=3 <RXCSUM,TXCSUM>
See the ifconfig man page for further information.
Known Limitations
=================
There are known performance issues with this driver when running UDP traffic
with Jumbo Frames.
There is a known compatibility issue where time to link is slow or link is not
established between 82541/82547 controllers and some switches. Known switches
include:
Planex FXG-08TE
I-O Data ETG-SH8
The driver can be compiled with the following changes:
Edit ./em.x.x.x/src/if_em.h to uncomment the #define EM_MASTER_SLAVE
from within the comments. For example, change from:
/* #define EM_MASTER_SLAVE 2 */
to:
#define EM_MASTER_SLAVE 2
Use one of the following options:
1 = Master mode
2 = Slave mode
3 = Auto master/slave
Setting 2 is recommended.
Recompile the module:
a. To compile the module
cd em-x.x.x
make clean
make
b. To install the compiled module in system directory:
make install
Support
=======
For general information and support, go to the Intel support website at:
http://support.intel.com
If an issue is identified, support is through email only at:
freebsdnic@mailbox.intel.com
License
=======
This software program is released under the terms of a license agreement
between you ('Licensee') and Intel. Do not use or load this software or any
associated materials (collectively, the 'Software') until you have carefully
read the full terms and conditions of the LICENSE located in this software
package. By loading or using the Software, you agree to the terms of this
Agreement. If you do not agree with the terms of this Agreement, do not
install or use the Software.
* Other names and brands may be claimed as the property of others.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,493 @@
/**************************************************************************
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/*$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/if_em.h,v 1.31 2005/05/26 23:32:02 tackerman Exp $*/
#ifndef _EM_H_DEFINED_
#define _EM_H_DEFINED_
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#ifndef __rtems__
#include <sys/module.h>
#endif
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#ifndef __rtems__
#include <net/bpf.h>
#include <net/if_types.h>
#include <net/if_vlan_var.h>
#else
#include <net/if_types.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#ifndef __rtems__
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/clock.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#else
#include <netinet/if_ether.h>
#include <bsp/pci.h>
#endif
#ifndef __rtems__
#include <sys/endian.h>
#include <sys/proc.h>
#include "opt_bdg.h"
#include <dev/em/if_em_hw.h>
#else
#include <if_em_hw.h>
#endif
/* Tunables */
/*
* EM_MAX_TXD: Maximum number of Transmit Descriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for others
* Default Value: 256
* This value is the number of transmit descriptors allocated by the driver.
* Increasing this value allows the driver to queue more transmits. Each
* descriptor is 16 bytes.
*/
#define EM_MAX_TXD 256
/*
* EM_MAX_RXD - Maximum number of receive Descriptors
* Valid Range: 80-256 for 82542 and 82543-based adapters
* 80-4096 for others
* Default Value: 256
* This value is the number of receive descriptors allocated by the driver.
* Increasing this value allows the driver to buffer more incoming packets.
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
* descriptor. The maximum MTU size is 16110.
*
*/
#define EM_MAX_RXD 80
/*
* EM_TIDV - Transmit Interrupt Delay Value
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value delays the generation of transmit interrupts in units of
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
* efficiency if properly tuned for specific network traffic. If the
* system is reporting dropped transmits, this value may be set too high
* causing the driver to run out of available transmit descriptors.
*/
#define EM_TIDV 64
/*
* EM_TADV - Transmit Absolute Interrupt Delay Value (Not valid for 82542/82543/82544)
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value, in units of 1.024 microseconds, limits the delay in which a
* transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
* this value ensures that an interrupt is generated after the initial
* packet is sent on the wire within the set amount of time. Proper tuning,
* along with EM_TIDV, may improve traffic throughput in specific
* network conditions.
*/
#define EM_TADV 64
/*
* EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
* Valid Range: 0-65535 (0=off)
* Default Value: 0
* This value delays the generation of receive interrupts in units of 1.024
* microseconds. Receive interrupt reduction can improve CPU efficiency if
* properly tuned for specific network traffic. Increasing this value adds
* extra latency to frame reception and can end up decreasing the throughput
* of TCP traffic. If the system is reporting dropped receives, this value
* may be set too high, causing the driver to run out of available receive
* descriptors.
*
* CAUTION: When setting EM_RDTR to a value other than 0, adapters
* may hang (stop transmitting) under certain network conditions.
* If this occurs a WATCHDOG message is logged in the system event log.
* In addition, the controller is automatically reset, restoring the
* network connection. To eliminate the potential for the hang
* ensure that EM_RDTR is set to 0.
*/
#define EM_RDTR 0
/*
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
* Valid Range: 0-65535 (0=off)
* Default Value: 64
* This value, in units of 1.024 microseconds, limits the delay in which a
* receive interrupt is generated. Useful only if EM_RDTR is non-zero,
* this value ensures that an interrupt is generated after the initial
* packet is received within the set amount of time. Proper tuning,
* along with EM_RDTR, may improve traffic throughput in specific network
* conditions.
*/
#define EM_RADV 64
/*
* This parameter controls the maximum no of times the driver will loop
* in the isr.
* Minimum Value = 1
*/
#define EM_MAX_INTR 3
/*
* Inform the stack about transmit checksum offload capabilities.
*/
#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP)
/*
* This parameter controls the duration of transmit watchdog timer.
*/
#define EM_TX_TIMEOUT 5 /* set to 5 seconds */
/*
* This parameter controls when the driver calls the routine to reclaim
* transmit descriptors.
*/
#ifndef __rtems__
#define EM_TX_CLEANUP_THRESHOLD EM_MAX_TXD / 8
#else
#define EM_TX_CLEANUP_THRESHOLD (adapter->tx_cleanup_threshold)
#endif
/*
* This parameter controls whether or not autonegotation is enabled.
* 0 - Disable autonegotiation
* 1 - Enable autonegotiation
*/
#define DO_AUTO_NEG 1
/*
* This parameter control whether or not the driver will wait for
* autonegotiation to complete.
* 1 - Wait for autonegotiation to complete
* 0 - Don't wait for autonegotiation to complete
*/
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
/*
* EM_MASTER_SLAVE is only defined to enable a workaround for a known compatibility issue
* with 82541/82547 devices and some switches. See the "Known Limitations" section of
* the README file for a complete description and a list of affected switches.
*
* 0 = Hardware default
* 1 = Master mode
* 2 = Slave mode
* 3 = Auto master/slave
*/
/* #define EM_MASTER_SLAVE 2 */
/* Tunables -- End */
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define EM_VENDOR_ID 0x8086
#define EM_MMBA 0x0010 /* Mem base address */
#define EM_ROUNDUP(size, unit) (((size) + (unit) - 1) & ~((unit) - 1))
#define EM_JUMBO_PBA 0x00000028
#define EM_DEFAULT_PBA 0x00000030
#define EM_SMARTSPEED_DOWNSHIFT 3
#define EM_SMARTSPEED_MAX 15
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define PCI_ANY_ID (~0U)
#define ETHER_ALIGN 2
/* Defines for printing debug information */
#define DEBUG_INIT 0
#define DEBUG_IOCTL 0
#define DEBUG_HW 0
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
/* Supported RX Buffer Sizes */
#define EM_RXBUFFER_2048 2048
#define EM_RXBUFFER_4096 4096
#define EM_RXBUFFER_8192 8192
#define EM_RXBUFFER_16384 16384
#define EM_MAX_SCATTER 64
/* ******************************************************************************
* vendor_info_array
*
* This array contains the list of Subvendor/Subdevice IDs on which the driver
* should load.
*
* ******************************************************************************/
typedef struct _em_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
unsigned int subdevice_id;
unsigned int index;
} em_vendor_info_t;
struct em_buffer {
struct mbuf *m_head;
#ifndef __rtems__
bus_dmamap_t map; /* bus_dma map for packet */
#endif
};
/*
* Bus dma allocation structure used by
* em_dma_malloc and em_dma_free.
*/
struct em_dma_alloc {
bus_addr_t dma_paddr; /* 64bit in descriptors */
#ifndef __rtems__
caddr_t dma_vaddr;
bus_dma_tag_t dma_tag;
bus_dmamap_t dma_map;
bus_dma_segment_t dma_seg;
bus_size_t dma_size;
int dma_nseg;
#else
caddr_t dma_vaddr;
caddr_t malloc_base;
#endif
};
typedef enum _XSUM_CONTEXT_T {
OFFLOAD_NONE,
OFFLOAD_TCP_IP,
OFFLOAD_UDP_IP
} XSUM_CONTEXT_T;
struct adapter;
struct em_int_delay_info {
struct adapter *adapter; /* Back-pointer to the adapter struct */
int offset; /* Register offset to read/write */
int value; /* Current value in usecs */
};
/* For 82544 PCIX Workaround */
typedef struct _ADDRESS_LENGTH_PAIR
{
u_int64_t address;
u_int32_t length;
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
typedef struct _DESCRIPTOR_PAIR
{
ADDRESS_LENGTH_PAIR descriptor[4];
u_int32_t elements;
} DESC_ARRAY, *PDESC_ARRAY;
/* Our adapter structure */
struct adapter {
struct arpcom interface_data;
struct adapter *next;
struct adapter *prev;
struct em_hw hw;
/* FreeBSD operating-system-specific structures */
struct em_osdep osdep;
#ifndef __rtems__
struct device *dev;
struct resource *res_memory;
struct resource *res_ioport;
struct resource *res_interrupt;
void *int_handler_tag;
struct ifmedia media;
struct callout timer;
struct callout tx_fifo_timer;
int io_rid;
struct ifmedia media;
#endif
u_int8_t unit;
#ifndef __rtems__
struct mtx mtx;
int em_insert_vlan_header;
#else
device_t dev;
unsigned char irq_no;
unsigned char b,d,f;
rtems_id tid;
#endif
/* Info about the board itself */
#ifndef __rtems__
u_int32_t part_num;
#else
uint32_t part_num;
#endif
u_int8_t link_active;
u_int16_t link_speed;
u_int16_t link_duplex;
u_int32_t smartspeed;
struct em_int_delay_info tx_int_delay;
struct em_int_delay_info tx_abs_int_delay;
struct em_int_delay_info rx_int_delay;
struct em_int_delay_info rx_abs_int_delay;
XSUM_CONTEXT_T active_checksum_context;
/*
* Transmit definitions
*
* We have an array of num_tx_desc descriptors (handled
* by the controller) paired with an array of tx_buffers
* (at tx_buffer_area).
* The index of the next available descriptor is next_avail_tx_desc.
* The number of remaining tx_desc is num_tx_desc_avail.
*/
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
struct em_tx_desc *tx_desc_base;
u_int32_t next_avail_tx_desc;
u_int32_t oldest_used_tx_desc;
volatile u_int16_t num_tx_desc_avail;
u_int16_t num_tx_desc;
u_int32_t txd_cmd;
struct em_buffer *tx_buffer_area;
#ifndef __rtems__
bus_dma_tag_t txtag; /* dma tag for tx */
#endif
#ifdef __rtems__
u_int16_t tx_cleanup_threshold;
#endif
/*
* Receive definitions
*
* we have an array of num_rx_desc rx_desc (handled by the
* controller), and paired with an array of rx_buffers
* (at rx_buffer_area).
* The next pair to check on receive is at offset next_rx_desc_to_check
*/
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
struct em_rx_desc *rx_desc_base;
u_int32_t next_rx_desc_to_check;
u_int16_t num_rx_desc;
u_int32_t rx_buffer_len;
struct em_buffer *rx_buffer_area;
#ifndef __rtems__
bus_dma_tag_t rxtag;
#endif
/* Jumbo frame */
struct mbuf *fmp;
struct mbuf *lmp;
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
unsigned long mbuf_alloc_failed;
unsigned long mbuf_cluster_failed;
unsigned long no_tx_desc_avail1;
unsigned long no_tx_desc_avail2;
unsigned long no_tx_map_avail;
unsigned long no_tx_dma_setup;
/* Used in for 82547 10Mb Half workaround */
#define EM_PBA_BYTES_SHIFT 0xA
#define EM_TX_HEAD_ADDR_SHIFT 7
#define EM_PBA_TX_MASK 0xFFFF0000
#define EM_FIFO_HDR 0x10
#define EM_82547_PKT_THRESH 0x3e0
u_int32_t tx_fifo_size;
u_int32_t tx_fifo_head;
u_int32_t tx_fifo_head_addr;
u_int64_t tx_fifo_reset_cnt;
u_int64_t tx_fifo_wrk_cnt;
u_int32_t tx_head_addr;
/* For 82544 PCIX Workaround */
boolean_t pcix_82544;
boolean_t in_detach;
struct em_hw_stats stats;
};
#define EM_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
#define EM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx)
#define EM_LOCK(_sc) mtx_lock(&(_sc)->mtx)
#define EM_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
#define EM_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED)
#ifdef __rtems__
/* Initialize bare minimals so we can check the phy link status;
* 'rtems_em_pci_setup()' must have been run on the device already!
*/
int
em_hw_early_init(device_t dev);
#endif
#endif /* _EM_H_DEFINED_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
/**************************************************************************
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/*$FreeBSD: /repoman/r/ncvs/src/sys/dev/em/if_em_osdep.h,v 1.14 2005/05/26 23:32:02 tackerman Exp $*/
#ifndef _RTEMS_OS_H_
#define _RTEMS_OS_H_
#include <rtems.h>
#include <rtemscompat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <bsp/pci.h>
/* Eventually, we should include this
#include <rtems/rtems-mii-ioctl.h>
*/
#define IFM_LINK_OK IFM_FLAG0
#define IFM_ANEG_DIS IFM_FLAG1
#define ASSERT(x) if(!(x)) panic("EM: x")
/* The happy-fun DELAY macro is defined in /usr/src/sys/i386/include/clock.h */
#define usec_delay(x) DELAY(x)
#define msec_delay(x) DELAY(1000*(x))
/* TODO: Should we be paranoid about delaying in interrupt context? */
#define msec_delay_irq(x) DELAY(1000*(x))
#define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F);
#if DBG
#define DEBUGOUT(S) printf(S "\n")
#define DEBUGOUT1(S,A) printf(S "\n",A)
#define DEBUGOUT2(S,A,B) printf(S "\n",A,B)
#define DEBUGOUT3(S,A,B,C) printf(S "\n",A,B,C)
#define bootverbose (1)
#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S "\n",A,B,C,D,E,F,G)
#else
#define DEBUGOUT(S)
#define DEBUGOUT1(S,A)
#define DEBUGOUT2(S,A,B)
#define DEBUGOUT3(S,A,B,C)
#define bootverbose (0)
#define DEBUGOUT7(S,A,B,C,D,E,F,G)
#endif
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
struct em_osdep
{
unsigned mem_bus_space_handle;
device_t dev;
};
struct rtems_ifmedia {
int ifm_media;
};
#define E1000_WRITE_FLUSH(hw) E1000_READ_REG(hw, STATUS)
/* Read from an absolute offset in the adapter's memory space */
#define E1000_READ_OFFSET(hw, offset) \
bus_space_read_4( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
offset)
/* Write to an absolute offset in the adapter's memory space */
#define E1000_WRITE_OFFSET(hw, offset, value) \
bus_space_write_4( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
offset, \
value)
/* Convert a register name to its offset in the adapter's memory space */
#define E1000_REG_OFFSET(hw, reg) \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg)
#define E1000_READ_REG(hw, reg) \
E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg))
#define E1000_WRITE_REG(hw, reg, value) \
E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg), value)
#define E1000_READ_REG_ARRAY(hw, reg, index) \
E1000_READ_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2))
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2), value)
#define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \
bus_space_write_1( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REG_OFFSET(hw, reg) + (index), \
value)
#define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \
bus_space_write_2( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REG_OFFSET(hw, reg) + (index), \
value)
#define E1000_WRITE_REG_ARRAY_DWORD(hw, reg, index, value) \
E1000_WRITE_OFFSET(hw, E1000_REG_OFFSET(hw, reg) + ((index) << 2), value)
#endif /* _FREEBSD_OS_H_ */

View File

@@ -0,0 +1,23 @@
/* $Id$ */
#ifndef RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H
#define RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <bsp/early_enet_link_status.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int rtems_em_attach(struct rtems_bsdnet_ifconfig *, int);
extern int rtems_em_pci_setup(int);
extern rtems_bsdnet_early_link_check_ops rtems_em_early_link_check_ops;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,106 @@
/* $Id$ */
#include "if_xxx_rtems.c"
#include <bsp/early_enet_link_status.h>
#include <bsp/if_em_pub.h>
/* Provide a routine to check link status early,
* i.e., before the network is really running.
* In case someone wants to decide whether to use/configure
* this interface at all :-)
*
* NOTE: this routine tries to enable autonegotiation!
*
* unit: unit number starting with 1 (usual BSDNET convention)
*
* RETURNS: Phy status register contents (1<<2 means link up).
* or -1 on error.
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
static int
em_early_init(int idx)
{
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
return em_hw_early_init(&the_em_devs[idx]);
}
static int
em_early_read_phy(int idx, unsigned reg)
{
unsigned short data;
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
/* Bizarre - I always have to read PHY_STATUS twice until a good link
* status is read
*/
if ( em_read_phy_reg(&the_em_devs[idx].d_softc.hw, reg, &data) )
return -1;
if ( PHY_STATUS == reg ) {
/* read again */
if ( em_read_phy_reg(&the_em_devs[idx].d_softc.hw, PHY_STATUS, &data) )
return -1;
}
return data;
}
static int
em_early_write_phy(int idx, unsigned reg, unsigned val)
{
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
return em_write_phy_reg(&the_em_devs[idx].d_softc.hw, reg, val);
}
rtems_bsdnet_early_link_check_ops
rtems_em_early_link_check_ops = {
init: em_early_init,
read_phy: em_early_read_phy,
write_phy: em_early_write_phy,
name: NETDRIVER,
num_slots: NETDRIVER_SLOTS
};

View File

@@ -0,0 +1,110 @@
#ifndef RTEMS_COMPAT_DEFS_H
#define RTEMS_COMPAT_DEFS_H
/* Number of device instances the driver should support
* - may be limited to 1 depending on IRQ API
* (braindamaged PC586 and powerpc)
*/
#define NETDRIVER_SLOTS 1
/* String name to print with error messages */
#define NETDRIVER "em"
/* Name snippet used to make global symbols unique to this driver */
#define NETDRIVER_PREFIX em
#define adapter em_softc
#define interface_data arpcom
/* Define according to endianness of the *ethernet*chip*
* (not the CPU - most probably are LE)
* This must be either NET_CHIP_LE or NET_CHIP_BE
*/
#define NET_CHIP_LE
#undef NET_CHIP_BE
/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
* depending whether the CPU sees it in memory address space
* or (e.g. x86) uses special I/O instructions.
*/
#define NET_CHIP_MEM_IO
#undef NET_CHIP_PORT_IO
/* The name of the hijacked 'bus handle' field in the softc
* structure. We use this field to store the chip's base address.
*/
#define NET_SOFTC_BHANDLE_FIELD osdep.mem_bus_space_handle
/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
* (only if present, i.e., if the BSDNET driver has no respective
* header, leave this undefined).
*
*/
#define IF_REG_HEADER <if_em.h>
#undef IF_VAR_HEADER
/* define if a pci device */
#define NETDRIVER_PCI <bsp/pci.h>
/* Macros to disable and enable interrupts, respectively.
* The 'disable' macro is expanded in the ISR, the 'enable'
* macro is expanded in the driver task.
* The global network semaphore usually provides mutex
* protection of the device registers.
* Special care must be taken when coding the 'disable' macro,
* however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
* as:
* - macro must not clear any status flags
* - macro must save/restore any context information
* (e.g., a address register pointer or a bank switch register)
*
* ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
*/
#define NET_ENABLE_IRQS(sc) do { \
E1000_WRITE_REG(&sc->hw, IMS, (IMS_ENABLE_MASK)); \
} while (0)
#define NET_DISABLE_IRQS(sc) do { \
E1000_WRITE_REG(&sc->hw, IMC, 0xffffffff); \
} while (0)
#define KASSERT(a...) do {} while (0)
/* dmamap stuff; these are defined just to work with the current version
* of this driver and the implementation must be carefully checked if
* a newer version is merged.!
*
* The more cumbersome routines have been commented in the source, the
* simpler ones are defined to be NOOPs here so the source gets less
* cluttered...
*
* ASSUMPTIONS:
*
* -> dmamap_sync cannot sync caches; assume we have HW snooping
*
*/
typedef unsigned bus_size_t;
typedef unsigned bus_addr_t;
typedef struct {
unsigned ds_addr;
unsigned ds_len;
} bus_dma_segment_t;
#define bus_dma_tag_destroy(args...) do {} while(0)
#define bus_dmamap_destroy(args...) do {} while(0)
#define bus_dmamap_unload(args...) do {} while (0)
#ifdef __PPC__
#define bus_dmamap_sync(args...) do { asm volatile("sync":::"memory"); } while (0)
#else
#define bus_dmamap_sync(args...) do {} while (0)
#endif
#define BUS_DMA_NOWAIT 0xdeadbeef /* unused */
#endif

View File

@@ -0,0 +1,90 @@
#
# Makefile.lib,v 1.5 2000/06/12 15:00:14 joel Exp
#
# Templates/Makefile.lib
# Template library Makefile
#
LIBNAME=libif_gfe.a
LIB=${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES=if_gfe if_gfe_rtems if_gfe.modini
PGMS = $(ARCH)/if_gfe.obj
MODOBJS = $(OBJS)
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_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_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/lib.cfg
#
# Add local stuff here using +=
#
DEFINES += -DDEBUG_MODULAR
#-DDEBUG
CPPFLAGS += -I. -Ilibchip -Iporting
# bsdnet newproc generated daemon is non-FP;
# prevent optimizer from generating FP instructions
CFLAGS += -Wno-unused-variable -msoft-float
#
# 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) $(LIB) $(PGMS)
$(LIB): ${OBJS}
$(make-library)
#How to make a relocatable object
$(filter %.obj, $(PGMS)): $(MODOBJS)
$(make-obj)
ifndef RTEMS_SITE_INSTALLDIR
RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
endif
${RTEMS_SITE_INSTALLDIR}/include \
${RTEMS_SITE_INSTALLDIR}/lib \
${RTEMS_SITE_INSTALLDIR}/bin \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/include \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/lib \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/bin :
test -d $@ || mkdir -p $@
# Install the library, appending _g or _p as appropriate.
# for include files, just use $(INSTALL_CHANGE)
#
# NOTES:
# - BSP specific libraries, headers etc. should be installed to
# $RTEMS_SITE_INSTALLDIR)/$(RTEMS_BSP)/lib
#
install: all $(RTEMS_SITE_INSTALLDIR)/lib
$(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib
$(INSTALL_VARIANT) -m 644 ${PGMS} ${RTEMS_SITE_INSTALLDIR}/bin

View File

@@ -0,0 +1,854 @@
/* $NetBSD: gtethreg.h,v 1.2.10.1 2005/04/29 11:28:55 kent Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DEV_GTETHREG_H_
#define _DEV_GTETHREG_H_
#define ETH__BIT(bit) (1U << (bit))
#define ETH__LLBIT(bit) (1LLU << (bit))
#define ETH__MASK(bit) (ETH__BIT(bit) - 1)
#define ETH__LLMASK(bit) (ETH__LLBIT(bit) - 1)
#define ETH__GEN(n, off) (0x2400+((n) << 10)+(ETH__ ## off))
#define ETH__EXT(data, bit, len) (((data) >> (bit)) & ETH__MASK(len))
#define ETH__LLEXT(data, bit, len) (((data) >> (bit)) & ETH__LLMASK(len))
#define ETH__CLR(data, bit, len) ((data) &= ~(ETH__MASK(len) << (bit)))
#define ETH__INS(new, bit) ((new) << (bit))
#define ETH__LLINS(new, bit) ((uint64_t)(new) << (bit))
/*
* Descriptors used for both receive & transmit data. Note that the descriptor
* must start on a 4LW boundary. Since the GT accesses the descriptor as
* two 64-bit quantities, we must present them 32bit quantities in the right
* order based on endianess.
*/
struct gt_eth_desc {
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
u_int32_t ed_lencnt; /* length is hi 16 bits; count (rx) is lo 16 */
u_int32_t ed_cmdsts; /* command (hi16)/status (lo16) bits */
u_int32_t ed_nxtptr; /* next descriptor (must be 4LW aligned) */
u_int32_t ed_bufptr; /* pointer to packet buffer */
#endif
#if defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
u_int32_t ed_cmdsts; /* command (hi16)/status (lo16) bits */
u_int32_t ed_lencnt; /* length is hi 16 bits; count (rx) is lo 16 */
u_int32_t ed_bufptr; /* pointer to packet buffer */
u_int32_t ed_nxtptr; /* next descriptor (must be 4LW aligned) */
#endif
};
/* Table 578: Ethernet TX Descriptor - Command/Status word
* All bits except F, EI, AM, O are only valid if TX_CMD_L is also set,
* otherwise should be 0 (tx).
*/
#define TX_STS_LC ETH__BIT(5) /* Late Collision */
#define TX_STS_UR ETH__BIT(6) /* Underrun error */
#define TX_STS_RL ETH__BIT(8) /* Retransmit Limit (excession coll) */
#define TX_STS_COL ETH__BIT(9) /* Collision Occurred */
#define TX_STS_RC(v) ETH__GETBITS(v, 10, 4) /* Retransmit Count */
#define TX_STS_ES ETH__BIT(15) /* Error Summary (LC|UR|RL) */
#define TX_CMD_L ETH__BIT(16) /* Last - End Of Packet */
#define TX_CMD_F ETH__BIT(17) /* First - Start Of Packet */
#define TX_CMD_P ETH__BIT(18) /* Pad Packet */
#define TX_CMD_GC ETH__BIT(22) /* Generate CRC */
#define TX_CMD_EI ETH__BIT(23) /* Enable Interrupt */
#define TX_CMD_AM ETH__BIT(30) /* Auto Mode */
#define TX_CMD_O ETH__BIT(31) /* Ownership (1=GT 0=CPU) */
#define TX_CMD_FIRST (TX_CMD_F|TX_CMD_O)
#define TX_CMD_LAST (TX_CMD_L|TX_CMD_GC|TX_CMD_P|TX_CMD_O)
/* Table 582: Ethernet RX Descriptor - Command/Status Word
* All bits except F, EI, AM, O are only valid if RX_CMD_L is also set,
* otherwise should be ignored (rx).
*/
#define RX_STS_CE ETH__BIT(0) /* CRC Error */
#define RX_STS_COL ETH__BIT(1) /* Collision sensed during reception */
#define RX_STS_LC ETH__BIT(5) /* Late Collision (Reserved) */
#define RX_STS_OR ETH__BIT(6) /* Overrun Error */
#define RX_STS_MFL ETH__BIT(7) /* Max Frame Len Error */
#define RX_STS_SF ETH__BIT(8) /* Short Frame Error (< 64 bytes) */
#define RX_STS_FT ETH__BIT(11) /* Frame Type (1 = 802.3) */
#define RX_STS_M ETH__BIT(12) /* Missed Frame */
#define RX_STS_HE ETH__BIT(13) /* Hash Expired (manual match) */
#define RX_STS_IGMP ETH__BIT(14) /* IGMP Packet */
#define RX_STS_ES ETH__BIT(15) /* Error Summary (CE|COL|LC|OR|MFL|SF) */
#define RX_CMD_L ETH__BIT(16) /* Last - End Of Packet */
#define RX_CMD_F ETH__BIT(17) /* First - Start Of Packet */
#define RX_CMD_EI ETH__BIT(23) /* Enable Interrupt */
#define RX_CMD_AM ETH__BIT(30) /* Auto Mode */
#define RX_CMD_O ETH__BIT(31) /* Ownership (1=GT 0=CPU) */
/* Table 586: Hash Table Entry Fields
*/
#define HSH_V ETH__LLBIT(0) /* Entry is valid */
#define HSH_S ETH__LLBIT(1) /* Skip this entry */
#define HSH_RD ETH__LLBIT(2) /* Receive(1) / Discard (0) */
#define HSH_R ETH__LLBIT(2) /* Receive(1) */
#define HSH_PRIO_GET(v) ETH__LLEXT(v, 51, 2)
#define HSH_PRIO_INS(v) ETH__LLINS(v, 51)
#define HSH_ADDR_MASK 0x7fffff8LLU
#define HSH_LIMIT 12
#define ETH_EPAR 0x2000 /* PHY Address Register */
#define ETH_ESMIR 0x2010 /* SMI Register */
#define ETH_BASE_ETH0 0x2400 /* Ethernet0 Register Base */
#define ETH_BASE_ETH1 0x2800 /* Ethernet1 Register Base */
#define ETH_BASE_ETH2 0x2c00 /* Ethernet2 Register Base */
#define ETH_SIZE 0x0400 /* Register Space */
#define ETH__EBASE 0x0000 /* Base of Registers */
#define ETH__EPCR 0x0000 /* Port Config. Register */
#define ETH__EPCXR 0x0008 /* Port Config. Extend Reg */
#define ETH__EPCMR 0x0010 /* Port Command Register */
#define ETH__EPSR 0x0018 /* Port Status Register */
#define ETH__ESPR 0x0020 /* Port Serial Parameters Reg */
#define ETH__EHTPR 0x0028 /* Port Hash Table Pointer Reg*/
#define ETH__EFCSAL 0x0030 /* Flow Control Src Addr Low */
#define ETH__EFCSAH 0x0038 /* Flow Control Src Addr High */
#define ETH__ESDCR 0x0040 /* SDMA Configuration Reg */
#define ETH__ESDCMR 0x0048 /* SDMA Command Register */
#define ETH__EICR 0x0050 /* Interrupt Cause Register */
#define ETH__EIMR 0x0058 /* Interrupt Mask Register */
#define ETH__EFRDP0 0x0080 /* First Rx Desc Pointer 0 */
#define ETH__EFRDP1 0x0084 /* First Rx Desc Pointer 1 */
#define ETH__EFRDP2 0x0088 /* First Rx Desc Pointer 2 */
#define ETH__EFRDP3 0x008c /* First Rx Desc Pointer 3 */
#define ETH__ECRDP0 0x00a0 /* Current Rx Desc Pointer 0 */
#define ETH__ECRDP1 0x00a4 /* Current Rx Desc Pointer 1 */
#define ETH__ECRDP2 0x00a8 /* Current Rx Desc Pointer 2 */
#define ETH__ECRDP3 0x00ac /* Current Rx Desc Pointer 3 */
#define ETH__ECTDP0 0x00e0 /* Current Tx Desc Pointer 0 */
#define ETH__ECTDP1 0x00e4 /* Current Tx Desc Pointer 1 */
#define ETH__EDSCP2P0L 0x0060 /* IP Differentiated Services
CodePoint to Priority0 low */
#define ETH__EDSCP2P0H 0x0064 /* IP Differentiated Services
CodePoint to Priority0 high*/
#define ETH__EDSCP2P1L 0x0068 /* IP Differentiated Services
CodePoint to Priority1 low */
#define ETH__EDSCP2P1H 0x006c /* IP Differentiated Services
CodePoint to Priority1 high*/
#define ETH__EVPT2P 0x0068 /* VLAN Prio. Tag to Priority */
#define ETH__EMIBCTRS 0x0100 /* MIB Counters */
#define ETH_BASE(n) ETH__GEN(n, EBASE)
#define ETH_EPCR(n) ETH__GEN(n, EPCR) /* Port Config. Register */
#define ETH_EPCXR(n) ETH__GEN(n, EPCXR) /* Port Config. Extend Reg */
#define ETH_EPCMR(n) ETH__GEN(n, EPCMR) /* Port Command Register */
#define ETH_EPSR(n) ETH__GEN(n, EPSR) /* Port Status Register */
#define ETH_ESPR(n) ETH__GEN(n, ESPR) /* Port Serial Parameters Reg */
#define ETH_EHTPR(n) ETH__GEN(n, EHPTR) /* Port Hash Table Pointer Reg*/
#define ETH_EFCSAL(n) ETH__GEN(n, EFCSAL) /* Flow Control Src Addr Low */
#define ETH_EFCSAH(n) ETH__GEN(n, EFCSAH) /* Flow Control Src Addr High */
#define ETH_ESDCR(n) ETH__GEN(n, ESDCR) /* SDMA Configuration Reg */
#define ETH_ESDCMR(n) ETH__GEN(n, ESDCMR) /* SDMA Command Register */
#define ETH_EICR(n) ETH__GEN(n, EICR) /* Interrupt Cause Register */
#define ETH_EIMR(n) ETH__GEN(n, EIMR) /* Interrupt Mask Register */
#define ETH_EFRDP0(n) ETH__GEN(n, EFRDP0) /* First Rx Desc Pointer 0 */
#define ETH_EFRDP1(n) ETH__GEN(n, EFRDP1) /* First Rx Desc Pointer 1 */
#define ETH_EFRDP2(n) ETH__GEN(n, EFRDP2) /* First Rx Desc Pointer 2 */
#define ETH_EFRDP3(n) ETH__GEN(n, EFRDP3) /* First Rx Desc Pointer 3 */
#define ETH_ECRDP0(n) ETH__GEN(n, ECRDP0) /* Current Rx Desc Pointer 0 */
#define ETH_ECRDP1(n) ETH__GEN(n, ECRDP1) /* Current Rx Desc Pointer 1 */
#define ETH_ECRDP2(n) ETH__GEN(n, ECRDP2) /* Current Rx Desc Pointer 2 */
#define ETH_ECRDP3(n) ETH__GEN(n, ECRDP3) /* Current Rx Desc Pointer 3 */
#define ETH_ECTDP0(n) ETH__GEN(n, ECTDP0) /* Current Tx Desc Pointer 0 */
#define ETH_ECTDP1(n) ETH__GEN(n, ECTDP1) /* Current Tx Desc Pointer 1 */
#define ETH_EDSCP2P0L(n) ETH__GEN(n, EDSCP2P0L) /* IP Differentiated Services
CodePoint to Priority0 low */
#define ETH_EDSCP2P0H(n) ETH__GEN(n, EDSCP2P0H) /* IP Differentiated Services
CodePoint to Priority0 high*/
#define ETH_EDSCP2P1L(n) ETH__GEN(n, EDSCP2P1L) /* IP Differentiated Services
CodePoint to Priority1 low */
#define ETH_EDSCP2P1H(n) ETH__GEN(n, EDSCP1P1H) /* IP Differentiated Services
CodePoint to Priority1 high*/
#define ETH_EVPT2P(n) ETH__GEN(n, EVPT2P) /* VLAN Prio. Tag to Priority */
#define ETH_EMIBCTRS(n) ETH__GEN(n, EMIBCTRS) /* MIB Counters */
#define ETH_EPAR_PhyAD_GET(v, n) (((v) >> ((n) * 5)) & 0x1f)
#define ETH_ESMIR_READ(phy, reg) (ETH__INS(phy, 16)|\
ETH__INS(reg, 21)|\
ETH_ESMIR_ReadOpcode)
#define ETH_ESMIR_WRITE(phy, reg, val) (ETH__INS(phy, 16)|\
ETH__INS(reg, 21)|\
ETH__INS(val, 0)|\
ETH_ESMIR_WriteOpcode)
#define ETH_ESMIR_Value_GET(v) ETH__EXT(v, 0, 16)
#define ETH_ESMIR_WriteOpcode 0
#define ETH_ESMIR_ReadOpcode ETH__BIT(26)
#define ETH_ESMIR_ReadValid ETH__BIT(27)
#define ETH_ESMIR_Busy ETH__BIT(28)
/*
* Table 597: Port Configuration Register (PCR)
* 00:00 PM Promiscuous mode
* 0: Normal mode (Frames are only received if the
* destination address is found in the hash
* table)
* 1: Promiscuous mode (Frames are received
* regardless of their destination address.
* Errored frames are discarded unless the Port
* Configuration register's PBF bit is set)
* 01:01 RBM Reject Broadcast Mode
* 0: Receive broadcast address
* 1: Reject frames with broadcast address
* Overridden by the promiscuous mode.
* 02:02 PBF Pass Bad Frames
* (0: Normal mode, 1: Pass bad Frames)
* The Ethernet receiver passes to the CPU errored
* frames (like fragments and collided packets)
* that are normally rejected.
* NOTE: Frames are only passed if they
* successfully pass address filtering.
* 06:03 Reserved
* 07:07 EN Enable (0: Disabled, 1: Enable)
* When enabled, the ethernet port is ready to
* transmit/receive.
* 09:08 LPBK Loop Back Mode
* 00: Normal mode
* 01: Internal loop back mode (TX data is looped
* back to the RX lines. No transition is seen
* on the interface pins)
* 10: External loop back mode (TX data is looped
* back to the RX lines and also transmitted
* out to the MII interface pins)
* 11: Reserved
* 10:10 FC Force Collision
* 0: Normal mode.
* 1: Force Collision on any TX frame.
* For RXM test (in Loopback mode).
* 11:11 Reserved.
* 12:12 HS Hash Size
* 0: 8K address filtering
* (256KB of memory space required).
* 1: 512 address filtering
* ( 16KB of memory space required).
* 13:13 HM Hash Mode (0: Hash Func. 0; 1: Hash Func. 1)
* 14:14 HDM Hash Default Mode
* 0: Discard addresses not found in address table
* 1: Pass addresses not found in address table
* 15:15 HD Duplex Mode (0: Half Duplex, 1: Full Duplex)
* NOTE: Valid only when auto-negotiation for
* duplex mode is disabled.
* 30:16 Reserved
* 31:31 ACCS Accelerate Slot Time
* (0: Normal mode, 1: Reserved)
*/
#define ETH_EPCR_PM ETH__BIT(0)
#define ETH_EPCR_RBM ETH__BIT(1)
#define ETH_EPCR_PBF ETH__BIT(2)
#define ETH_EPCR_EN ETH__BIT(7)
#define ETH_EPCR_LPBK_GET(v) ETH__BIT(v, 8, 2)
#define ETH_EPCR_LPBK_Normal 0
#define ETH_EPCR_LPBK_Internal 1
#define ETH_EPCR_LPBK_External 2
#define ETH_EPCR_FC ETH__BIT(10)
#define ETH_EPCR_HS ETH__BIT(12)
#define ETH_EPCR_HS_8K 0
#define ETH_EPCR_HS_512 ETH_EPCR_HS
#define ETH_EPCR_HM ETH__BIT(13)
#define ETH_EPCR_HM_0 0
#define ETH_EPCR_HM_1 ETH_EPCR_HM
#define ETH_EPCR_HDM ETH__BIT(14)
#define ETH_EPCR_HDM_Discard 0
#define ETH_EPCR_HDM_Pass ETH_EPCR_HDM
#define ETH_EPCR_HD_Half 0
#define ETH_EPCR_HD_Full ETH_EPCR_HD_Full
#define ETH_EPCR_ACCS ETH__BIT(31)
/*
* Table 598: Port Configuration Extend Register (PCXR)
* 00:00 IGMP IGMP Packets Capture Enable
* 0: IGMP packets are treated as normal Multicast
* packets.
* 1: IGMP packets on IPv4/Ipv6 over Ethernet/802.3
* are trapped and sent to high priority RX
* queue.
* 01:01 SPAN Spanning Tree Packets Capture Enable
* 0: BPDU (Bridge Protocol Data Unit) packets are
* treated as normal Multicast packets.
* 1: BPDU packets are trapped and sent to high
* priority RX queue.
* 02:02 PAR Partition Enable (0: Normal, 1: Partition)
* When more than 61 collisions occur while
* transmitting, the port enters Partition mode.
* It waits for the first good packet from the
* wire and then goes back to Normal mode. Under
* Partition mode it continues transmitting, but
* it does not receive.
* 05:03 PRIOtx Priority weight in the round-robin between high
* and low priority TX queues.
* 000: 1 pkt from HIGH, 1 pkt from LOW.
* 001: 2 pkt from HIGH, 1 pkt from LOW.
* 010: 4 pkt from HIGH, 1 pkt from LOW.
* 011: 6 pkt from HIGH, 1 pkt from LOW.
* 100: 8 pkt from HIGH, 1 pkt from LOW.
* 101: 10 pkt from HIGH, 1 pkt from LOW.
* 110: 12 pkt from HIGH, 1 pkt from LOW.
* 111: All pkt from HIGH, 0 pkt from LOW. LOW is
* served only if HIGH is empty.
* NOTE: If the HIGH queue is emptied before
* finishing the count, the count is reset
* until the next first HIGH comes in.
* 07:06 PRIOrx Default Priority for Packets Received on this
* Port (00: Lowest priority, 11: Highest priority)
* 08:08 PRIOrx_Override Override Priority for Packets Received on this
* Port (0: Do not override, 1: Override with
* <PRIOrx> field)
* 09:09 DPLXen Enable Auto-negotiation for Duplex Mode
* (0: Enable, 1: Disable)
* 11:10 FCTLen Enable Auto-negotiation for 802.3x Flow-control
* 0: Enable; When enabled, 1 is written (through
* SMI access) to the PHY's register 4 bit 10
* to advertise flow-control capability.
* 1: Disable; Only enables flow control after the
* PHY address is set by the CPU. When changing
* the PHY address the flow control
* auto-negotiation must be disabled.
* 11:11 FLP Force Link Pass
* (0: Force Link Pass, 1: Do NOT Force Link pass)
* 12:12 FCTL 802.3x Flow-Control Mode (0: Enable, 1: Disable)
* NOTE: Only valid when auto negotiation for flow
* control is disabled.
* 13:13 Reserved
* 15:14 MFL Max Frame Length
* Maximum packet allowed for reception (including
* CRC): 00: 1518 bytes, 01: 1536 bytes,
* 10: 2048 bytes, 11: 64K bytes
* 16:16 MIBclrMode MIB Counters Clear Mode (0: Clear, 1: No effect)
* 17:17 MIBctrMode Reserved. (MBZ)
* 18:18 Speed Port Speed (0: 10Mbit/Sec, 1: 100Mbit/Sec)
* NOTE: Only valid if SpeedEn bit is set.
* 19:19 SpeedEn Enable Auto-negotiation for Speed
* (0: Enable, 1: Disable)
* 20:20 RMIIen RMII enable
* 0: Port functions as MII port
* 1: Port functions as RMII port
* 21:21 DSCPen DSCP enable
* 0: IP DSCP field decoding is disabled.
* 1: IP DSCP field decoding is enabled.
* 31:22 Reserved
*/
#define ETH_EPCXR_IGMP ETH__BIT(0)
#define ETH_EPCXR_SPAN ETH__BIT(1)
#define ETH_EPCXR_PAR ETH__BIT(2)
#define ETH_EPCXR_PRIOtx_GET(v) ETH__EXT(v, 3, 3)
#define ETH_EPCXR_PRIOrx_GET(v) ETH__EXT(v, 3, 3)
#define ETH_EPCXR_PRIOrx_Override ETH__BIT(8)
#define ETH_EPCXR_DLPXen ETH__BIT(9)
#define ETH_EPCXR_FCTLen ETH__BIT(10)
#define ETH_EPCXR_FLP ETH__BIT(11)
#define ETH_EPCXR_FCTL ETH__BIT(12)
#define ETH_EPCXR_MFL_GET(v) ETH__EXT(v, 14, 2)
#define ETH_EPCXR_MFL_1518 0
#define ETH_EPCXR_MFL_1536 1
#define ETH_EPCXR_MFL_2084 2
#define ETH_EPCXR_MFL_64K 3
#define ETH_EPCXR_MIBclrMode ETH__BIT(16)
#define ETH_EPCXR_MIBctrMode ETH__BIT(17)
#define ETH_EPCXR_Speed ETH__BIT(18)
#define ETH_EPCXR_SpeedEn ETH__BIT(19)
#define ETH_EPCXR_RMIIEn ETH__BIT(20)
#define ETH_EPCXR_DSCPEn ETH__BIT(21)
/*
* Table 599: Port Command Register (PCMR)
* 14:00 Reserved
* 15:15 FJ Force Jam / Flow Control
* When in half-duplex mode, the CPU uses this bit
* to force collisions on the Ethernet segment.
* When the CPU recognizes that it is going to run
* out of receive buffers, it can force the
* transmitter to send jam frames, forcing
* collisions on the wire. To allow transmission
* on the Ethernet segment, the CPU must clear the
* FJ bit when more resources are available. When
* in full-duplex and flow-control is enabled, this
* bit causes the port's transmitter to send
* flow-control PAUSE packets. The CPU must reset
* this bit when more resources are available.
* 31:16 Reserved
*/
#define ETH_EPCMR_FJ ETH__BIT(15)
/*
* Table 600: Port Status Register (PSR) -- Read Only
* 00:00 Speed Indicates Port Speed (0: 10Mbs, 1: 100Mbs)
* 01:01 Duplex Indicates Port Duplex Mode (0: Half, 1: Full)
* 02:02 Fctl Indicates Flow-control Mode
* (0: enabled, 1: disabled)
* 03:03 Link Indicates Link Status (0: down, 1: up)
* 04:04 Pause Indicates that the port is in flow-control
* disabled state. This bit is set when an IEEE
* 802.3x flow-control PAUSE (XOFF) packet is
* received (assuming that flow-control is
* enabled and the port is in full-duplex mode).
* Reset when XON is received, or when the XOFF
* timer has expired.
* 05:05 TxLow Tx Low Priority Status
* Indicates the status of the low priority
* transmit queue: (0: Stopped, 1: Running)
* 06:06 TxHigh Tx High Priority Status
* Indicates the status of the high priority
* transmit queue: (0: Stopped, 1: Running)
* 07:07 TXinProg TX in Progress
* Indicates that the port's transmitter is in an
* active transmission state.
* 31:08 Reserved
*/
#define ETH_EPSR_Speed ETH__BIT(0)
#define ETH_EPSR_Duplex ETH__BIT(1)
#define ETH_EPSR_Fctl ETH__BIT(2)
#define ETH_EPSR_Link ETH__BIT(3)
#define ETH_EPSR_Pause ETH__BIT(4)
#define ETH_EPSR_TxLow ETH__BIT(5)
#define ETH_EPSR_TxHigh ETH__BIT(6)
#define ETH_EPSR_TXinProg ETH__BIT(7)
/*
* Table 601: Serial Parameters Register (SPR)
* 01:00 JAM_LENGTH Two bits to determine the JAM Length
* (in Backpressure) as follows:
* 00 = 12K bit-times
* 01 = 24K bit-times
* 10 = 32K bit-times
* 11 = 48K bit-times
* 06:02 JAM_IPG Five bits to determine the JAM IPG.
* The step is four bit-times. The value may vary
* between 4 bit time to 124.
* 11:07 IPG_JAM_TO_DATA Five bits to determine the IPG JAM to DATA.
* The step is four bit-times. The value may vary
* between 4 bit time to 124.
* 16:12 IPG_DATA Inter-Packet Gap (IPG)
* The step is four bit-times. The value may vary
* between 12 bit time to 124.
* NOTE: These bits may be changed only when the
* Ethernet ports is disabled.
* 21:17 Data_Blind Data Blinder
* The number of nibbles from the beginning of the
* IPG, in which the IPG counter is restarted when
* detecting a carrier activity. Following this
* value, the port enters the Data Blinder zone and
* does not reset the IPG counter. This ensures
* fair access to the medium.
* The default is 10 hex (64 bit times - 2/3 of the
* default IPG). The step is 4 bit-times. Valid
* range is 3 to 1F hex nibbles.
* NOTE: These bits may be only changed when the
* Ethernet port is disabled.
* 22:22 Limit4 The number of consecutive packet collisions that
* occur before the collision counter is reset.
* 0: The port resets its collision counter after
* 16 consecutive retransmit trials and
* restarts the Backoff algorithm.
* 1: The port resets its collision counter and
* restarts the Backoff algorithm after 4
* consecutive transmit trials.
* 31:23 Reserved
*/
#define ETH_ESPR_JAM_LENGTH_GET(v) ETH__EXT(v, 0, 2)
#define ETH_ESPR_JAM_IPG_GET(v) ETH__EXT(v, 2, 5)
#define ETH_ESPR_IPG_JAM_TO_DATA_GET(v) ETH__EXT(v, 7, 5)
#define ETH_ESPR_IPG_DATA_GET(v) ETH__EXT(v, 12, 5)
#define ETH_ESPR_Data_Bilnd_GET(v) ETH__EXT(v, 17, 5)
#define ETH_ESPR_Limit4(v) ETH__BIT(22)
/*
* Table 602: Hash Table Pointer Register (HTPR)
* 31:00 HTP 32-bit pointer to the address table.
* Bits [2:0] must be set to zero.
*/
/*
* Table 603: Flow Control Source Address Low (FCSAL)
* 15:0 SA[15:0] Source Address
* The least significant bits of the source
* address for the port. This address is used for
* Flow Control.
* 31:16 Reserved
*/
/*
* Table 604: Flow Control Source Address High (FCSAH)
* 31:0 SA[47:16] Source Address
* The most significant bits of the source address
* for the port. This address is used for Flow
* Control.
*/
/*
* Table 605: SDMA Configuration Register (SDCR)
* 01:00 Reserved
* 05:02 RC Retransmit Count
* Sets the maximum number of retransmits per
* packet. After executing retransmit for RC
* times, the TX SDMA closes the descriptor with a
* Retransmit Limit error indication and processes
* the next packet. When RC is set to 0, the
* number of retransmits is unlimited. In this
* case, the retransmit process is only terminated
* if CPU issues an Abort command.
* 06:06 BLMR Big/Little Endian Receive Mode
* The DMA supports Big or Little Endian
* configurations on a per channel basis. The BLMR
* bit only affects data transfer to memory.
* 0: Big Endian
* 1: Little Endian
* 07:07 BLMT Big/Little Endian Transmit Mode
* The DMA supports Big or Little Endian
* configurations on a per channel basis. The BLMT
* bit only affects data transfer from memory.
* 0: Big Endian
* 1: Little Endian
* 08:08 POVR PCI Override
* When set, causes the SDMA to direct all its
* accesses in PCI_0 direction and overrides
* normal address decoding process.
* 09:09 RIFB Receive Interrupt on Frame Boundaries
* When set, the SDMA Rx generates interrupts only
* on frame boundaries (i.e. after writing the
* frame status to the descriptor).
* 11:10 Reserved
* 13:12 BSZ Burst Size
* Sets the maximum burst size for SDMA
* transactions:
* 00: Burst is limited to 1 64bit words.
* 01: Burst is limited to 2 64bit words.
* 10: Burst is limited to 4 64bit words.
* 11: Burst is limited to 8 64bit words.
* 31:14 Reserved
*/
#define ETH_ESDCR_RC_GET(v) ETH__EXT(v, 2, 4)
#define ETH_ESDCR_BLMR ETH__BIT(6)
#define ETH_ESDCR_BLMT ETH__BIT(7)
#define ETH_ESDCR_POVR ETH__BIT(8)
#define ETH_ESDCR_RIFB ETH__BIT(9)
#define ETH_ESDCR_BSZ_GET(v) ETH__EXT(v, 12, 2)
#define ETH_ESDCR_BSZ_SET(v, n) (ETH__CLR(v, 12, 2),\
(v) |= ETH__INS(n, 12))
#define ETH_ESDCR_BSZ_1 0
#define ETH_ESDCR_BSZ_2 1
#define ETH_ESDCR_BSZ_4 2
#define ETH_ESDCR_BSZ_8 3
#define ETH_ESDCR_BSZ_Strings { "1 64-bit word", "2 64-bit words", \
"4 64-bit words", "8 64-bit words" }
/*
* Table 606: SDMA Command Register (SDCMR)
* 06:00 Reserved
* 07:07 ERD Enable RX DMA.
* Set to 1 by the CPU to cause the SDMA to start
* a receive process. Cleared when the CPU issues
* an Abort Receive command.
* 14:08 Reserved
* 15:15 AR Abort Receive
* Set to 1 by the CPU to abort a receive SDMA
* operation. When the AR bit is set, the SDMA
* aborts its current operation and moves to IDLE.
* No descriptor is closed. The AR bit is cleared
* upon entering IDLE. After setting the AR bit,
* the CPU must poll the bit to verify that the
* abort sequence is completed.
* 16:16 STDH Stop TX High
* Set to 1 by the CPU to stop the transmission
* process from the high priority queue at the end
* of the current frame. An interrupt is generated
* when the stop command has been executed.
* Writing 1 to STDH resets TXDH bit.
* Writing 0 to this bit has no effect.
* 17:17 STDL Stop TX Low
* Set to 1 by the CPU to stop the transmission
* process from the low priority queue at the end
* of the current frame. An interrupt is generated
* when the stop command has been executed.
* Writing 1 to STDL resets TXDL bit.
* Writing 0 to this bit has no effect.
* 22:18 Reserved
* 23:23 TXDH Start Tx High
* Set to 1 by the CPU to cause the SDMA to fetch
* the first descriptor and start a transmit
* process from the high priority Tx queue.
* Writing 1 to TXDH resets STDH bit.
* Writing 0 to this bit has no effect.
* 24:24 TXDL Start Tx Low
* Set to 1 by the CPU to cause the SDMA to fetch
* the first descriptor and start a transmit
* process from the low priority Tx queue.
* Writing 1 to TXDL resets STDL bit.
* Writing 0 to this bit has no effect.
* 30:25 Reserved
* 31:31 AT Abort Transmit
* Set to 1 by the CPU to abort a transmit DMA
* operation. When the AT bit is set, the SDMA
* aborts its current operation and moves to IDLE.
* No descriptor is closed. Cleared upon entering
* IDLE. After setting AT bit, the CPU must poll
* it in order to verify that the abort sequence
* is completed.
*/
#define ETH_ESDCMR_ERD ETH__BIT(7)
#define ETH_ESDCMR_AR ETH__BIT(15)
#define ETH_ESDCMR_STDH ETH__BIT(16)
#define ETH_ESDCMR_STDL ETH__BIT(17)
#define ETH_ESDCMR_TXDH ETH__BIT(23)
#define ETH_ESDCMR_TXDL ETH__BIT(24)
#define ETH_ESDCMR_AT ETH__BIT(31)
/*
* Table 607: Interrupt Cause Register (ICR)
* 00:00 RxBuffer Rx Buffer Return
* Indicates an Rx buffer returned to CPU ownership
* or that the port finished reception of a Rx
* frame in either priority queues.
* NOTE: In order to get a Rx Buffer return per
* priority queue, use bit 19:16. This bit is
* set upon closing any Rx descriptor which
* has its EI bit set. To limit the
* interrupts to frame (rather than buffer)
* boundaries, the user must set SDMA
* Configuration register's RIFB bit. When
* the RIFB bit is set, an interrupt
* generates only upon closing the first
* descriptor of a received packet, if this
* descriptor has it EI bit set.
* 01:01 Reserved
* 02:02 TxBufferHigh Tx Buffer for High priority Queue
* Indicates a Tx buffer returned to CPU ownership
* or that the port finished transmission of a Tx
* frame.
* NOTE: This bit is set upon closing any Tx
* descriptor which has its EI bit set. To
* limit the interrupts to frame (rather than
* buffer) boundaries, the user must set EI
* only in the last descriptor.
* 03:03 TxBufferLow Tx Buffer for Low Priority Queue
* Indicates a Tx buffer returned to CPU ownership
* or that the port finished transmission of a Tx
* frame.
* NOTE: This bit is set upon closing any Tx
* descriptor which has its EI bit set. To
* limit the interrupts to frame (rather than
* buffer) boundaries, the user must set EI
* only in the last descriptor.
* 05:04 Reserved
* 06:06 TxEndHigh Tx End for High Priority Queue
* Indicates that the Tx DMA stopped processing the
* high priority queue after stop command, or that
* it reached the end of the high priority
* descriptor chain.
* 07:07 TxEndLow Tx End for Low Priority Queue
* Indicates that the Tx DMA stopped processing the
* low priority queue after stop command, or that
* it reached the end of the low priority
* descriptor chain.
* 08:08 RxError Rx Resource Error
* Indicates a Rx resource error event in one of
* the priority queues.
* NOTE: To get a Rx Resource Error Indication per
* priority queue, use bit 23:20.
* 09:09 Reserved
* 10:10 TxErrorHigh Tx Resource Error for High Priority Queue
* Indicates a Tx resource error event during
* packet transmission from the high priority queue
* 11:11 TxErrorLow Tx Resource Error for Low Priority Queue
* Indicates a Tx resource error event during
* packet transmission from the low priority queue
* 12:12 RxOVR Rx Overrun
* Indicates an overrun event that occurred during
* reception of a packet.
* 13:13 TxUdr Tx Underrun
* Indicates an underrun event that occurred during
* transmission of packet from either queue.
* 15:14 Reserved
* 16:16 RxBuffer-Queue[0] Rx Buffer Return in Priority Queue[0]
* Indicates a Rx buffer returned to CPU ownership
* or that the port completed reception of a Rx
* frame in a receive priority queue[0]
* 17:17 RxBuffer-Queue[1] Rx Buffer Return in Priority Queue[1]
* Indicates a Rx buffer returned to CPU ownership
* or that the port completed reception of a Rx
* frame in a receive priority queue[1].
* 18:18 RxBuffer-Queue[2] Rx Buffer Return in Priority Queue[2]
* Indicates a Rx buffer returned to CPU ownership
* or that the port completed reception of a Rx
* frame in a receive priority queue[2].
* 19:19 RxBuffer-Queue[3] Rx Buffer Return in Priority Queue[3]
* Indicates a Rx buffer returned to CPU ownership
* or that the port completed reception of a Rx
* frame in a receive priority queue[3].
* 20:20 RxError-Queue[0] Rx Resource Error in Priority Queue[0]
* Indicates a Rx resource error event in receive
* priority queue[0].
* 21:21 RxError-Queue[1] Rx Resource Error in Priority Queue[1]
* Indicates a Rx resource error event in receive
* priority queue[1].
* 22:22 RxError-Queue[2] Rx Resource Error in Priority Queue[2]
* Indicates a Rx resource error event in receive
* priority queue[2].
* 23:23 RxError-Queue[3] Rx Resource Error in Priority Queue[3]
* Indicates a Rx resource error event in receive
* priority queue[3].
* 27:24 Reserved
* 28:29 MIIPhySTC MII PHY Status Change
* Indicates a status change reported by the PHY
* connected to this port. Set when the MII
* management interface block identifies a change
* in PHY's register 1.
* 29:29 SMIdone SMI Command Done
* Indicates that the SMI completed a MII
* management command (either read or write) that
* was initiated by the CPU writing to the SMI
* register.
* 30:30 Reserved
* 31:31 EtherIntSum Ethernet Interrupt Summary
* This bit is a logical OR of the (unmasked) bits
* [30:04] in the Interrupt Cause register.
*/
#define ETH_IR_RxBuffer ETH__BIT(0)
#define ETH_IR_TxBufferHigh ETH__BIT(2)
#define ETH_IR_TxBufferLow ETH__BIT(3)
#define ETH_IR_TxEndHigh ETH__BIT(6)
#define ETH_IR_TxEndLow ETH__BIT(7)
#define ETH_IR_RxError ETH__BIT(8)
#define ETH_IR_TxErrorHigh ETH__BIT(10)
#define ETH_IR_TxErrorLow ETH__BIT(11)
#define ETH_IR_RxOVR ETH__BIT(12)
#define ETH_IR_TxUdr ETH__BIT(13)
#define ETH_IR_RxBuffer_0 ETH__BIT(16)
#define ETH_IR_RxBuffer_1 ETH__BIT(17)
#define ETH_IR_RxBuffer_2 ETH__BIT(18)
#define ETH_IR_RxBuffer_3 ETH__BIT(19)
#define ETH_IR_RxBuffer_GET(v) ETH__EXT(v, 16, 4)
#define ETH_IR_RxError_0 ETH__BIT(20)
#define ETH_IR_RxError_1 ETH__BIT(21)
#define ETH_IR_RxError_2 ETH__BIT(22)
#define ETH_IR_RxError_3 ETH__BIT(23)
#define ETH_IR_RxError_GET(v) ETH__EXT(v, 20, 4)
#define ETH_IR_RxBits (ETH_IR_RxBuffer_0|\
ETH_IR_RxBuffer_1|\
ETH_IR_RxBuffer_2|\
ETH_IR_RxBuffer_3|\
ETH_IR_RxError_0|\
ETH_IR_RxError_1|\
ETH_IR_RxError_2|\
ETH_IR_RxError_3)
#define ETH_IR_MIIPhySTC ETH__BIT(28)
#define ETH_IR_SMIdone ETH__BIT(29)
#define ETH_IR_EtherIntSum ETH__BIT(31)
#define ETH_IR_Summary ETH__BIT(31)
/*
* Table 608: Interrupt Mask Register (IMR)
* 31:00 Various Mask bits for the Interrupt Cause register.
*/
/*
* Table 609: IP Differentiated Services CodePoint to Priority0 low (DSCP2P0L),
* 31:00 Priority0_low The LSB priority bits for DSCP[31:0] entries.
*/
/*
* Table 610: IP Differentiated Services CodePoint to Priority0 high (DSCP2P0H)
* 31:00 Priority0_high The LSB priority bits for DSCP[63:32] entries.
*/
/*
* Table 611: IP Differentiated Services CodePoint to Priority1 low (DSCP2P1L)
* 31:00 Priority1_low The MSB priority bits for DSCP[31:0] entries.
*/
/*
* Table 612: IP Differentiated Services CodePoint to Priority1 high (DSCP2P1H)
* 31:00 Priority1_high The MSB priority bit for DSCP[63:32] entries.
*/
/*
* Table 613: VLAN Priority Tag to Priority (VPT2P)
* 07:00 Priority0 The LSB priority bits for VLAN Priority[7:0]
* entries.
* 15:08 Priority1 The MSB priority bits for VLAN Priority[7:0]
* entries.
* 31:16 Reserved
*/
/* Address control registers -- these are offsets from the GT base
* and NOT from the ethernet port base. <tss>
*/
#define ETH_ACTL_0_LO 0xf200
/* Enable hardware cache snooping;
* Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
*/
/* Ethernet address control (Low) snoop bits */
#define RxBSnoopEn ETH__BIT(6) /* Rx buffer snoop enable,1=enable*/
#define TxBSnoopEn ETH__BIT(14) /* Tx buffer snoop enable */
#define RxDSnoopEn ETH__BIT(22) /* Rx descriptor snoop enable */
#define TxDSnoopEn ETH__BIT(30) /* Tx descriptor snoop enable */
#define ETH_ACTL_0_HI 0xf204
/* Ethernet address control (High), snoop bits */
#define HashSnoopEn ETH__BIT(6) /* Hash Table snoop enable */
#define ETH_ACTL_1_LO 0xf220
#define ETH_ACTL_1_HI 0xf224
#define ETH_ACTL_2_LO 0xf240
#define ETH_ACTL_2_HI 0xf244
#endif /* _DEV_GTETHREG_H_ */

View File

@@ -0,0 +1,170 @@
/* $NetBSD: gtvar.h,v 1.7.4.1 2005/04/29 11:28:56 kent Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* gtvar.h -- placeholder for GT system controller driver
*/
#ifndef _DISCOVERY_DEV_GTVAR_H_
#define _DISCOVERY_DEV_GTVAR_H_
#include <sys/systm.h>
struct gt_softc {
#ifndef __rtems__
struct device gt_dev;
bus_dma_tag_t gt_dmat;
bus_space_tag_t gt_memt; /* the GT itself */
bus_space_tag_t gt_pci0_memt; /* PCI0 mem space */
bus_space_tag_t gt_pci0_iot; /* PCI0 i/o space */
boolean_t gt_pci0_host; /* We're host on PCI0 if TRUE */
bus_space_tag_t gt_pci1_memt; /* PCI1 mem space */
bus_space_tag_t gt_pci1_iot; /* PCI1 i/o space */
boolean_t gt_pci1_host; /* We're host on PCI1 if TRUE */
bus_space_handle_t gt_memh; /* to access the GT registers */
#else
unsigned gt_memh;
#endif
int gt_childmask; /* what children are present */
};
#define GT_CHILDOK(gt, ga, cd, pos, max) \
(((ga)->ga_unit) < (max) && \
!((gt)->gt_childmask & (1 << (((ga)->ga_unit) + (pos)))) && \
!strcmp((ga)->ga_name, (cd)->cd_name))
#define GT_MPSCOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 0, 2)
#define GT_PCIOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 2, 2)
#define GT_ETHEROK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 4, 3)
#define GT_OBIOOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 7, 5)
#define GT_I2COK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 12, 1)
#define GT_CHILDFOUND(gt, ga, pos) \
((void)(((gt)->gt_childmask |= (1 << (((ga)->ga_unit) + (pos))))))
#define GT_MPSCFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 0)
#define GT_PCIFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 2)
#define GT_ETHERFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 4)
#define GT_OBIOFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 7)
#define GT_I2CFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 12)
#ifndef __rtems__
struct gt_attach_args {
const char *ga_name; /* class name of device */
bus_dma_tag_t ga_dmat; /* dma tag */
bus_space_tag_t ga_memt; /* GT bus space tag */
bus_space_handle_t ga_memh; /* GT bus space handle */
int ga_unit; /* instance of ga_name */
};
struct obio_attach_args {
const char *oa_name; /* call name of device */
bus_space_tag_t oa_memt; /* bus space tag */
bus_addr_t oa_offset; /* offset (absolute) to device */
bus_size_t oa_size; /* size (strided) of device */
int oa_irq; /* irq */
};
#endif
#ifdef _KERNEL
#ifndef __rtems__
#include "locators.h"
#endif
#ifdef DEBUG
extern int gtpci_debug;
#endif
/*
* Locators for GT private devices, as specified to config.
*/
#define GT_UNK_UNIT GTCF_UNIT_DEFAULT /* wcarded 'function' */
#define OBIO_UNK_OFFSET OBIOCF_OFFSET_DEFAULT /* wcarded 'offset' */
#define OBIO_UNK_SIZE OBIOCF_SIZE_DEFAULT /* wcarded 'size' */
#define OBIO_UNK_IRQ OBIOCF_IRQ_DEFAULT /* wcarded 'irq' */
void gt_attach_common(struct gt_softc *);
uint32_t gt_read_mpp(void);
int gt_cfprint(void *, const char *);
#ifndef __rtems__
/* int gt_bs_extent_init(struct discovery_bus_space *, char *); AKB */
int gt_mii_read(struct device *, struct device *, int, int);
void gt_mii_write(struct device *, struct device *, int, int, int);
int gtget_macaddr(struct gt_softc *,int, char *);
void gt_watchdog_service(void);
bus_addr_t gt_dma_phys_to_bus_mem(bus_dma_tag_t, bus_addr_t);
bus_addr_t gt_dma_bus_mem_to_phys(bus_dma_tag_t, bus_addr_t);
#define gt_read(gt,o) \
bus_space_read_4((gt)->gt_memt, (gt)->gt_memh, (o))
#define gt_write(gt,o,v) \
bus_space_write_4((gt)->gt_memt, (gt)->gt_memh, (o), (v))
#else
#endif
#if defined(__powerpc__)
static __inline volatile int
atomic_add(volatile int *p, int v)
{
int rv;
int rtmp;
__asm __volatile(
"1: lwarx %0,0,%3\n"
" add %1,%4,%0\n"
" stwcx. %1,0,%3\n"
" bne- 1b\n"
" sync"
: "=&r"(rv), "=&r"(rtmp), "=m"(*p)
: "r"(p), "r"(v), "m"(*p)
: "cc");
return rv;
}
#endif /* __powerpc__ */
#endif /* _KERNEL */
#endif /* _DISCOVERY_DEV_GTVAR_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
/* $Id$ */
#ifndef RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H
#define RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <bsp/early_enet_link_status.h>
#include <net/ethernet.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int
rtems_gfe_attach(struct rtems_bsdnet_ifconfig *, int);
/* enet_addr must be 6 bytes long */
int
rtems_gfe_setup(int unit, char *enet_addr, uint32_t base_addr);
extern rtems_bsdnet_early_link_check_ops
rtems_gfe_early_link_check_ops;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,130 @@
/* $Id$ */
/* Author: T. Straumann <strauman@slac.stanford.edu>; see ../../LICENSE */
#include "rtemscompat.h"
#include "gtethreg.h"
#include <bsp/early_enet_link_status.h>
#include <bsp/if_gfe_pub.h>
#include <bsp/irq.h>
/* from if_gfe.c */
#define GE_READ(sc, reg) \
bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg)
#define GE_WRITE(sc, reg, v) \
bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg, (v))
#define GT_READ(sc, reg) \
bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg)
#define GT_WRITE(sc, reg, v) \
bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg, (v))
#include "if_xxx_rtems.c"
#include <bsp.h>
#include <libcpu/io.h>
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_setup)(
int unit,
char *ea,
uint32_t base_addr)
{
struct NET_SOFTC *sc;
if ( !ea ) {
fprintf(stderr,"Station address argument missing\n");
return 0;
}
if ( !(sc=net_drv_check_unit(unit)) ) {
fprintf(stderr,"Bad unit number -- (not enought driver slots?)\n");
return 0;
}
unit--;
#ifdef DEBUG_MODULAR
if ( !METHODSPTR ) {
fprintf(stderr,"Methods not set -- module not loaded?\n");
return 0;
}
#endif
if ( !base_addr ) {
#ifdef BSP_MV64x60_BASE
base_addr = BSP_MV64x60_BASE;
#else
fprintf(stderr,"Missing GT64260 base address\n");
return 0;
#endif
}
sc->sc_gt_memh = base_addr;
/* must set this as well to indicate that the device is set up */
sc->NET_SOFTC_BHANDLE_FIELD = base_addr + 0x2400 + (unit<<10);
sc->sc_macno = unit;
memcpy( sc->arpcom.ac_enaddr, ea, ETHER_ADDR_LEN);
if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit]) ) {
printf(NETDRIVER": Unit %i set up\n", unit + 1);
sc->irq_no = BSP_IRQ_ETH0 + unit;
return 1;
}
return 0;
}
static int
gfe_early_init(int idx)
{
struct gfe_softc *sc;
uint32_t d;
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
sc = device_get_softc(&the_gfe_devs[idx]);
d = bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, ETH_EPAR);
sc->sc_phyaddr = ETH_EPAR_PhyAD_GET(d, sc->sc_macno);
sc->sc_dev.dv_xname = NETDRIVER;
return 0;
}
static int
gfe_early_read_phy(int idx, unsigned reg)
{
uint32_t rval;
struct gfe_softc *sc;
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
sc = device_get_softc(&the_gfe_devs[idx]);
if ( gfe_mii_read( 0, sc, reg, &rval) )
return -1;
return rval & 0xffff;
}
static int
gfe_early_write_phy(int idx, unsigned reg, unsigned val)
{
struct gfe_softc *sc;
if ( idx < 0 || idx >= NETDRIVER_SLOTS )
return -1;
sc = device_get_softc(&the_gfe_devs[idx]);
return gfe_mii_write( 0, sc, reg, val);
}
rtems_bsdnet_early_link_check_ops
rtems_gfe_early_link_check_ops = {
init: gfe_early_init,
read_phy: gfe_early_read_phy,
write_phy: gfe_early_write_phy,
name: NETDRIVER,
num_slots: NETDRIVER_SLOTS
};

View File

@@ -0,0 +1,225 @@
#ifndef IF_GFEVAR_H
#define IF_GFEVAR_H
/* $NetBSD: if_gfevar.h,v 1.4.10.1 2005/04/29 11:28:56 kent Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* NOTE: GE_RXDESC_MAX * 16 <= GE_RXDESC_MEMSIZE */
/* NOTE: the driver needs 4*GE_RXDESC_MAX mbuf clusters (4 queues) */
#ifndef __rtems__
#define GE_RXDESC_MEMSIZE (1 * PAGE_SIZE)
#define GE_RXDESC_MAX 64
#define GE_RXBUF_SIZE 2048
#define GE_RXBUF_MEMSIZE (GE_RXDESC_MAX*GE_RXBUF_SIZE)
#else
#define GE_RXDESC_MEMSIZE (GE_RXDESC_MAX * sizeof(struct gt_eth_desc))
#define GE_RXDESC_MAX (sc->num_rxdesc)
#define GE_RXBUF_MEMSIZE 0
#endif
#define GE_RXBUF_NSEGS ((GE_RXBUF_MEMSIZE/PAGE_SIZE)+1)
#define GE_DMSEG_MAX (GE_RXBUF_NSEGS)
struct gfe_dmamem {
bus_dmamap_t gdm_map; /* dmamem'ed memory */
#ifdef __rtems__
void *gdm_unaligned_buf;
#endif
caddr_t gdm_kva; /* kva of tx memory */
int gdm_nsegs; /* # of segment in gdm_segs */
int gdm_maxsegs; /* maximum # of segments allowed */
size_t gdm_size; /* size of memory region */
bus_dma_segment_t gdm_segs[GE_DMSEG_MAX]; /* dma segment of tx memory */
};
/* With a 4096 page size, we get 256 descriptors per page.
*/
#ifndef __rtems__
#define GE_TXDESC_MEMSIZE (1 * PAGE_SIZE)
#define GE_TXDESC_MAX (GE_TXDESC_MEMSIZE / 16)
#define GE_TXBUF_SIZE (4 * PAGE_SIZE)
#else
#define GE_TXDESC_MEMSIZE (sc->num_txdesc * sizeof(struct gt_eth_desc))
#define GE_TXDESC_MAX (sc->num_txdesc)
#endif
struct gfe_txqueue {
struct ifqueue txq_pendq; /* these are ready to go to the GT */
struct ifqueue txq_sentq;
struct gfe_dmamem txq_desc_mem; /* transmit descriptor memory */
#ifndef __rtems__
struct gfe_dmamem txq_buf_mem; /* transmit buffer memory */
#endif
unsigned int txq_lo; /* next to be given to GT */
unsigned int txq_fi; /* next to be returned to CPU */
#ifndef __rtems__
unsigned int txq_ei_gapcount; /* counter until next EI */
#endif
unsigned int txq_nactive; /* number of active descriptors */
#ifndef __rtems__
unsigned int txq_outptr; /* where to put next transmit packet */
unsigned int txq_inptr; /* start of 1st queued tx packet */
#endif
uint32_t txq_intrbits; /* bits to write to EIMR */
uint32_t txq_esdcmrbits; /* bits to write to ESDCMR */
uint32_t txq_epsrbits; /* bits to test with EPSR */
volatile struct gt_eth_desc *txq_descs; /* ptr to tx descriptors */
bus_addr_t txq_ectdp; /* offset to cur. tx desc ptr reg */
bus_addr_t txq_desc_busaddr; /* bus addr of tx descriptors */
#ifndef __rtems__
bus_addr_t txq_buf_busaddr; /* bus addr of tx buffers */
#endif
};
/* With a 4096 page size, we get 256 descriptors per page. We want 1024
* which will give us about 8ms of 64 byte packets (2ms for each priority
* queue).
*/
#ifndef __rtems__
struct gfe_rxbuf {
uint8_t rb_data[GE_RXBUF_SIZE];
};
#endif
struct gfe_rxqueue {
struct gfe_dmamem rxq_desc_mem; /* receive descriptor memory */
#ifndef __rtems__
struct gfe_dmamem rxq_buf_mem; /* receive buffer memory */
struct mbuf *rxq_curpkt; /* mbuf for current packet */
#endif
volatile struct gt_eth_desc *rxq_descs;
#ifndef __rtems__
struct gfe_rxbuf *rxq_bufs;
#else
struct mbuf **rxq_bufs;
#endif
unsigned int rxq_fi; /* next to be returned to CPU */
unsigned int rxq_active; /* # of descriptors given to GT */
uint32_t rxq_intrbits; /* bits to write to EIMR */
bus_addr_t rxq_desc_busaddr; /* bus addr of rx descriptors */
uint32_t rxq_cmdsts; /* save cmdsts from first descriptor */
bus_size_t rxq_efrdp;
bus_size_t rxq_ecrdp;
};
enum gfe_txprio {
GE_TXPRIO_HI=1,
GE_TXPRIO_LO=0,
GE_TXPRIO_NONE=2
};
enum gfe_rxprio {
GE_RXPRIO_HI=3,
GE_RXPRIO_MEDHI=2,
GE_RXPRIO_MEDLO=1,
GE_RXPRIO_LO=0
};
#ifdef __rtems__
#define sc_ec arpcom
#define ec_if ac_if
#define sc_dev arpcom
#define dv_xname ac_if.if_name
#endif
struct gfe_softc {
#ifndef __rtems__
struct device sc_dev; /* must be first */
struct ethercom sc_ec; /* common ethernet glue */
struct callout sc_co; /* resource recovery */
mii_data_t sc_mii; /* mii interface */
/*
*
*/
bus_space_tag_t sc_gt_memt;
bus_space_handle_t sc_gt_memh;
bus_space_handle_t sc_memh; /* subregion for ethernet */
bus_dma_tag_t sc_dmat;
#else
struct arpcom sc_ec;
unsigned sc_gt_memh;
unsigned sc_memh;
unsigned char irq_no;
rtems_id tid;
int sc_phyaddr;
int num_rxdesc, num_txdesc;
#endif
int sc_macno; /* which mac? 0, 1, or 2 */
unsigned int sc_tickflags;
#define GE_TICK_TX_IFSTART 0x0001
#define GE_TICK_RX_RESTART 0x0002
unsigned int sc_flags;
#define GE_ALLMULTI 0x0001
#define GE_PHYSTSCHG 0x0002
#define GE_RXACTIVE 0x0004
#define GE_NOFREE 0x0008 /* Don't free on disable */
uint32_t sc_pcr; /* current EPCR value */
uint32_t sc_pcxr; /* current EPCXR value */
uint32_t sc_intrmask; /* current EIMR value */
uint32_t sc_idlemask; /* suspended EIMR bits */
size_t sc_max_frame_length; /* maximum frame length */
/*
* Hash table related members
*/
struct gfe_dmamem sc_hash_mem; /* dma'ble hash table */
uint64_t *sc_hashtable;
unsigned int sc_hashmask; /* 0x1ff or 0x1fff */
/*
* Transmit related members
*/
struct gfe_txqueue sc_txq[2]; /* High & Low transmit queues */
/*
* Receive related members
*/
struct gfe_rxqueue sc_rxq[4]; /* Hi/MedHi/MedLo/Lo receive queues */
};
#ifdef __rtems__
int
gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval);
int
gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t value);
#endif
#endif

View File

@@ -0,0 +1,122 @@
#ifndef RTEMS_COMPAT_DEFS_H
#define RTEMS_COMPAT_DEFS_H
/* Number of device instances the driver should support
* - may be limited to 1 depending on IRQ API
* (braindamaged PC586 and powerpc)
*/
#define NETDRIVER_SLOTS 1
/* String name to print with error messages */
#define NETDRIVER "gfe"
/* Name snippet used to make global symbols unique to this driver */
#define NETDRIVER_PREFIX gfe
/* Define according to endianness of the *ethernet*chip*
* (not the CPU - most probably are LE)
* This must be either NET_CHIP_LE or NET_CHIP_BE
*/
#define NET_CHIP_LE
#undef NET_CHIP_BE
/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
* depending whether the CPU sees it in memory address space
* or (e.g. x86) uses special I/O instructions.
*/
#define NET_CHIP_MEM_IO
#undef NET_CHIP_PORT_IO
/* The name of the hijacked 'bus handle' field in the softc
* structure. We use this field to store the chip's base address.
*/
#define NET_SOFTC_BHANDLE_FIELD sc_memh
/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
* (only if present, i.e., if the BSDNET driver has no respective
* header, leave this undefined).
*
*/
#undef IF_REG_HEADER
#define IF_VAR_HEADER <if_gfevar.h>
/* define if a pci device */
/*
#define NETDRIVER_PCI <bsp/pci.h>
*/
#undef NETDRIVER_PCI
/* Macros to disable and enable interrupts, respectively.
* The 'disable' macro is expanded in the ISR, the 'enable'
* macro is expanded in the driver task.
* The global network semaphore usually provides mutex
* protection of the device registers.
* Special care must be taken when coding the 'disable' macro,
* however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
* as:
* - macro must not clear any status flags
* - macro must save/restore any context information
* (e.g., a address register pointer or a bank switch register)
*
* ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
*/
#define NET_DISABLE_IRQS(sc) GE_WRITE(sc, EIMR, 0)
#define NET_ENABLE_IRQS(sc) GE_WRITE(sc, EIMR, sc->sc_intrmask)
/* Driver may provide a macro/function to copy the hardware address
* from the device into 'softc.arpcom'.
* If this is undefined, the driver must to the copy itself.
* Preferrably, it should check soft.arpcom.ac_enaddr for all
* zeros and leave it alone if it is nonzero, i.e., write it
* to the hardware.
#define NET_READ_MAC_ADDR(sc)
*/
typedef struct {
uint32_t ds_addr;
uint32_t ds_len;
} bus_dma_segment_t;
#define dm_segs gdm_segs
#define dm_nsegs gdm_nsegs
typedef struct gfe_dmamem *bus_dmamap_t;
typedef uint32_t bus_addr_t;
typedef uint32_t bus_size_t;
typedef struct device blah;
#define BUS_DMA_NOCACHE 0xdeadbeef
#ifdef __PPC__
#define bus_dmamap_sync(args...) do { asm volatile("sync":::"memory"); } while(0)
#else
#error "Dont' know how to sync memory on your CPU"
#endif
int ether_sprintf_r(const unsigned char *enaddr, char *buf, int len);
/* we have it although we're not ansi */
int snprintf(char *, size_t, const char *,...);
#include <string.h>
/* declare in every routine using ether_sprintf */
#define SPRINTFVARDECL char rtems_sprintf_local_buf[3*6] /* ethernet string */
#define ether_sprintf_macro(a) \
(snprintf(rtems_sprintf_local_buf, \
sizeof(rtems_sprintf_local_buf), \
"%02X:%02X:%02X:%02X:%02X:%02X", \
a[0],a[1],a[2],a[3],a[4],a[5]) ? \
rtems_sprintf_local_buf : 0 \
)
#define aprint_normal(args...) printf(args)
#define aprint_error(args...) fprintf(stderr,args)
#define delay(arg) DELAY(arg)
#define KASSERT(a...) do {} while (0)
#endif

View File

@@ -0,0 +1,423 @@
/* $Id$ */
#ifndef RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H
#define RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <bsp/early_enet_link_status.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int rtems_mve_attach(struct rtems_bsdnet_ifconfig *, int);
extern rtems_bsdnet_early_link_check_ops rtems_mve_early_link_check_ops;
/* Low-level Driver API.
* This provides driver access to applications that want to use e.g., the second
* ethernet interface w/o running the BSD TCP/IP stack.
*/
/* Opaque handle */
struct mveth_private;
/* Direct assignment of MVE flags to user API relies on irqs and x-irqs not overlapping */
#define BSP_MVE_IRQ_RX (1<<2)
#define BSP_MVE_IRQ_TX (1<<0)
#define BSP_MVE_IRQ_LINK (1<<16)
/* Setup an interface.
* Allocates resources for descriptor rings and sets up the driver software structure.
*
* Arguments:
* unit:
* interface # (1..2). The interface must not be attached to BSD.
*
* driver_tid:
* ISR posts RTEMS event # ('unit' - 1) to task with ID 'driver_tid' and disables interrupts
* from this interface.
*
* void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred):
* Pointer to user-supplied callback to release a buffer that had been sent
* by BSP_mve_send_buf() earlier. The callback is passed 'cleanup_txbuf_arg'
* and a flag indicating whether the send had been successful.
* The driver no longer accesses 'user_buf' after invoking this callback.
* CONTEXT: This callback is executed either by BSP_mve_swipe_tx() or
* BSP_mve_send_buf(), BSP_mve_init_hw(), BSP_mve_stop_hw() (the latter
* ones calling BSP_mve_swipe_tx()).
* void *cleanup_txbuf_arg:
* Closure argument that is passed on to 'cleanup_txbuf()' callback;
*
* void *(*alloc_rxbuf)(int *p_size, unsigned long *p_data_addr),
* Pointer to user-supplied callback to allocate a buffer for subsequent
* insertion into the RX ring by the driver.
* RETURNS: opaque handle to the buffer (which may be a more complex object
* such as an 'mbuf'). The handle is not used by the driver directly
* but passed back to the 'consume_rxbuf()' callback.
* Size of the available data area and pointer to buffer's data area
* in '*psize' and '*p_data_area', respectively.
* If no buffer is available, this routine should return NULL in which
* case the driver drops the last packet and re-uses the last buffer
* instead of handing it out to 'consume_rxbuf()'.
* CONTEXT: Called when initializing the RX ring (BSP_mve_init_hw()) or when
* swiping it (BSP_mve_swipe_rx()).
*
*
* void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len);
* Pointer to user-supplied callback to pass a received buffer back to
* the user. The driver no longer accesses the buffer after invoking this
* callback (with 'len'>0, see below). 'user_buf' is the buffer handle
* previously generated by 'alloc_rxbuf()'.
* The callback is passed 'cleanup_rxbuf_arg' and a 'len'
* argument giving the number of bytes that were received.
* 'len' may be <=0 in which case the 'user_buf' argument is NULL.
* 'len' == 0 means that the last 'alloc_rxbuf()' had failed,
* 'len' < 0 indicates a receiver error. In both cases, the last packet
* was dropped/missed and the last buffer will be re-used by the driver.
* NOTE: the data are 'prefixed' with two bytes, i.e., the ethernet packet header
* is stored at offset 2 in the buffer's data area. Also, the FCS (4 bytes)
* is appended. 'len' accounts for both.
* CONTEXT: Called from BSP_mve_swipe_rx().
* void *cleanup_rxbuf_arg:
* Closure argument that is passed on to 'consume_rxbuf()' callback;
*
* rx_ring_size, tx_ring_size:
* How many big to make the RX and TX descriptor rings. Note that the sizes
* may be 0 in which case a reasonable default will be used.
* If either ring size is < 0 then the RX or TX will be disabled.
* Note that it is illegal in this case to use BSP_mve_swipe_rx() or
* BSP_mve_swipe_tx(), respectively.
*
* irq_mask:
* Interrupts to enable. OR of flags from above.
*
*/
struct mveth_private *
BSP_mve_setup(
int unit,
rtems_id driver_tid,
void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
void *cleanup_txbuf_arg,
void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
void *consume_rxbuf_arg,
int rx_ring_size,
int tx_ring_size,
int irq_mask
);
/*
* Alternate 'setup' routine allowing the user to install an ISR rather
* than a task ID.
* All parameters (other than 'isr' / 'isr_arg') and the return value
* are identical to the BSP_mve_setup() entry point.
*/
struct mveth_private *
BSP_mve_setup_1(
int unit,
void (*isr)(void *isr_arg),
void *isr_arg,
void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),
void *cleanup_txbuf_arg,
void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),
void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),
void *consume_rxbuf_arg,
int rx_ring_size,
int tx_ring_size,
int irq_mask
);
/*
* Initialize interface hardware
*
* 'mp' handle obtained by from BSP_mve_setup().
* 'promisc' whether to set promiscuous flag.
* 'enaddr' pointer to six bytes with MAC address. Read
* from the device if NULL.
*
* Note: Multicast filters are cleared by this routine.
* However, in promiscuous mode the mcast filters
* are programmed to accept all multicast frames.
*/
void
BSP_mve_init_hw(struct mveth_private *mp, int promisc, unsigned char *enaddr);
/*
* Clear multicast hash filter. No multicast frames are accepted
* after executing this routine (unless the hardware was initialized
* in 'promiscuous' mode).
*/
void
BSP_mve_mcast_filter_clear(struct mveth_private *mp);
/*
* Program multicast filter to accept all multicast frames
*/
void
BSP_mve_mcast_filter_accept_all(struct mveth_private *mp);
/*
* Add a MAC address to the multicast filter.
* Existing entries are not changed but note that
* the filter is imperfect, i.e., multiple MAC addresses
* may alias to a single filter entry. Hence software
* filtering must still be performed.
*
* If a higher-level driver implements IP multicasting
* then multiple IP addresses may alias to the same MAC
* address. This driver maintains a 'reference-count'
* which is incremented every time the same MAC-address
* is passed to this routine; the address is only removed
* from the filter if BSP_mve_mcast_filter_accept_del()
* is called the same number of times (or by BSP_mve_mcast_filter_clear).
*/
void
BSP_mve_mcast_filter_accept_add(struct mveth_private *mp, unsigned char *enaddr);
/*
* Remove a MAC address from the multicast filter.
* This routine decrements the reference count of the given
* MAC-address and removes it from the filter once the
* count reaches zero.
*/
void
BSP_mve_mcast_filter_accept_del(struct mveth_private *mp, unsigned char *enaddr);
/*
* Shutdown hardware and clean out the rings
*/
void
BSP_mve_stop_hw(struct mveth_private *mp);
/* calls BSP_mve_stop_hw(), releases all resources and marks the interface
* as unused.
* RETURNS 0 on success, nonzero on failure.
* NOTE: the handle MUST NOT be used after successful execution of this
* routine.
*/
int
BSP_mve_detach(struct mveth_private *mp);
/*
* Enqueue a mbuf chain or a raw data buffer for transmission;
* RETURN: #bytes sent or -1 if there are not enough free descriptors
*
* If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain.
* OTOH, a raw data packet (or a different type of buffer)
* may be send (non-BSD driver) by pointing data_p to the start of
* the data and passing 'len' > 0.
* 'm_head' is passed back to the 'cleanup_txbuf()' callback.
*
* Comments: software cache-flushing incurs a penalty if the
* packet cannot be queued since it is flushed anyways.
* The algorithm is slightly more efficient in the normal
* case, though.
*
* RETURNS: # bytes enqueued to device for transmission or -1 if no
* space in the TX ring was available.
*/
int
BSP_mve_send_buf(struct mveth_private *mp, void *m_head, void *data_p, int len);
/* Descriptor scavenger; cleanup the TX ring, passing all buffers
* that have been sent to the cleanup_tx() callback.
* This routine is called from BSP_mve_send_buf(), BSP_mve_init_hw(),
* BSP_mve_stop_hw().
*
* RETURNS: number of buffers processed.
*/
int
BSP_mve_swipe_tx(struct mveth_private *mp);
/* Retrieve all received buffers from the RX ring, replacing them
* by fresh ones (obtained from the alloc_rxbuf() callback). The
* received buffers are passed to consume_rxbuf().
*
* RETURNS: number of buffers processed.
*/
int
BSP_mve_swipe_rx(struct mveth_private *mp);
/* read ethernet address from hw to buffer */
void
BSP_mve_read_eaddr(struct mveth_private *mp, unsigned char *eaddr);
/* read/write media word.
* 'cmd': can be SIOCGIFMEDIA, SIOCSIFMEDIA, 0 or 1. The latter
* are aliased to the former for convenience.
* 'parg': pointer to media word.
*
* RETURNS: 0 on success, nonzero on error
*
* NOTE: This routine is thread-safe.
*/
int
BSP_mve_media_ioctl(struct mveth_private *mp, int cmd, int *parg);
/* Interrupt related routines */
/* Note: the BSP_mve_enable/disable/ack_irqs() entry points
* are deprecated.
* The newer API where the user passes a mask allows
* for more selective control.
*/
/* Enable all supported interrupts at device */
void
BSP_mve_enable_irqs(struct mveth_private *mp);
/* Disable all supported interrupts at device */
void
BSP_mve_disable_irqs(struct mveth_private *mp);
/* Acknowledge (and clear) all supported interrupts.
* RETURNS: interrupts that were raised.
*/
uint32_t
BSP_mve_ack_irqs(struct mveth_private *mp);
/* Enable interrupts included in 'mask' (leaving
* already enabled interrupts on). If the mask
* includes bits that were not passed to the 'setup'
* routine then the behavior is undefined.
*/
void
BSP_mve_enable_irq_mask(struct mveth_private *mp, uint32_t irq_mask);
/* Disable interrupts included in 'mask' (leaving
* other ones that are currently enabled on). If the
* mask includes bits that were not passed to the 'setup'
* routine then the behavior is undefined.
*
* RETURNS: Bitmask of interrupts that were enabled upon entry
* into this routine. This can be used to restore the
* previous state.
*/
uint32_t
BSP_mve_disable_irq_mask(struct mveth_private *mp, uint32_t irq_mask);
/* Acknowledge and clear selected interrupts.
*
* RETURNS: All pending interrupts.
*
* NOTE: Only pending interrupts contained in 'mask'
* are cleared. Others are left pending.
*
* This routine can be used to check for pending
* interrupts (pass mask == 0) or to clear all
* interrupts (pass mask == -1).
*/
uint32_t
BSP_mve_ack_irq_mask(struct mveth_private *mp, uint32_t mask);
/* If the PHY link status changes then some
* internal settings in the ethernet controller's
* serial port need to be updated to match the
* PHY settings. Use this routine to perform the
* necessary steps after a link change has been
* detected.
*
* RETURNS: 0 on success, -1 if the PHY state
* could not be determined.
*
* The current state of the media as read
* by BSP_mve_media_ioctl() is returned in
* *pmedia.
*
* NOTE: This routine calls BSP_mve_media_ioctl().
*/
int
BSP_mve_ack_link_chg(struct mveth_private *mp, int *pmedia);
/* Retrieve the driver daemon TID that was passed to
* BSP_mve_setup().
*/
rtems_id
BSP_mve_get_tid(struct mveth_private *mp);
/* Dump statistics to file (stdout if NULL)
*
* NOTE: this routine is not thread safe
*/
void
BSP_mve_dump_stats(struct mveth_private *mp, FILE *f);
/*
*
* Example driver task loop (note: no synchronization of
* buffer access shown!).
* RTEMS_EVENTx = 0,1 or 2 depending on IF unit.
*
* / * setup (obtain handle) and initialize hw here * /
*
* do {
* / * ISR disables IRQs and posts event * /
* rtems_event_receive( RTEMS_EVENTx, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs );
* irqs = BSP_mve_ack_irqs(handle);
* if ( irqs & BSP_MVE_IRQ_TX ) {
* BSP_mve_swipe_tx(handle); / * cleanup_txbuf() callback executed * /
* }
* if ( irqs & BSP_MVE_IRQ_RX ) {
* BSP_mve_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * /
* }
* if ( irqs & BSP_MVE_IRQ_LINK ) {
* / * update serial port settings from current link status * /
* BSP_mve_ack_link_chg(handle, 0);
* }
* BSP_mve_enable_irqs(handle);
* } while (1);
*
*/
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
#include <rtems.h>
#include <bsp.h>
#include <bsp/if_mve_pub.h>
#include <stdlib.h>
#include <stdio.h>
/* Demo for the mv64360 ethernet quirk:
*
* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
* $$ buffer segments < 8 bytes must be aligned $$
* $$ to 8 bytes but larger segments are not $$
* $$ sensitive to alignment. $$
* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*
* How to use:
*
* Init MVE driver on (unused) unit 2:
*
* mve = mvtst_init(2)
*
* data = { 1,2,3,4,5,6,7,8,9,0xa,0xb, ... }
*
* Alloc 2-element mbuf chain (1st holds an
* ethernet header which is > 8bytes so we can't
* test this with only 1 mbuf. The 2nd mbuf holds
* a small fragment of data).
*
* mb = mvtst_getbuf(mve)
*
* Copy data into aligned area inside 2nd mbuf,
* (so that you can see if the chip starts using
* the aligned area rather than the unaligned
* buffer pointer). Point mbuf's data pointer
* at 'off'set from the aligned area:
*
* mvtst_putbuf(mb, data, len, offset)
*
* Send chain off:
*
* BSP_mve_send_buf(mve, mb, 0, 0)
*
* Watch raw data:
*
* tcpdump -XX -vv -s0 ether host <my-ether-addr>
*
* E.g, if offset = 1, len = 2 then we would like
* to see
*
* GOOD:
* < 14 header bytes > 0x02, 0x03
* but if the chip starts DMA at aligned address
* we see instead
* BAD:
* < 14 header bytes > 0x01, 0x02
*/
static inline void *rmalloc(size_t l) { return malloc(l); }
static inline void rfree(void *p) { return free(p); }
#define _KERNEL
#include <sys/mbuf.h>
static void
cleanup_buf(void *u_b, void *closure, int error)
{
rtems_bsdnet_semaphore_obtain();
m_freem((struct mbuf*)u_b);
rtems_bsdnet_semaphore_release();
}
struct mbuf *mvtst_getbuf(struct mveth_private *mp)
{
struct mbuf *m,*n;
if ( !mp ) {
printf("need driver ptr arg\n");
return 0;
}
rtems_bsdnet_semaphore_obtain();
MGETHDR(m, M_DONTWAIT, MT_DATA);
MGET(n, M_DONTWAIT, MT_DATA);
m->m_next = n;
rtems_bsdnet_semaphore_release();
/* Ethernet header */
memset( mtod(m, unsigned char*), 0xff, 6);
BSP_mve_read_eaddr(mp, mtod(m, unsigned char*) + 6);
/* Arbitrary; setting to IP but we don't bother
* to setup a real IP header. We just watch the
* raw packet contents...
*/
mtod(m, unsigned char*)[12] = 0x08;
mtod(m, unsigned char*)[13] = 0x00;
m->m_pkthdr.len = m->m_len = 14;
n->m_len = 0;
return m;
}
int
mvtst_putbuf(struct mbuf *m, void *data, int len, int off)
{
int i;
if ( m ) {
m->m_pkthdr.len += len;
if ( ( m= m->m_next ) ) {
m->m_len = len;
memcpy(mtod(m, void*), data, 32);
m->m_data += off;
printf("m.dat: 0x%08x, m.data: 0x%08x\n", m->m_dat, m->m_data);
for ( i=0; i< 16; i++ ) {
printf(" %02x,",mtod(m, unsigned char*)[i]);
}
printf("\n");
}
}
return 0;
}
static void *alloc_rxbuf(int *p_size, unsigned long *paddr)
{
return *(void**)paddr = rmalloc((*p_size = 1800));
}
static void consume_buf(void *buf, void *closure, int len)
{
rfree(buf);
}
void *
mvtst_init(int unit)
{
struct mveth_private *mp;
mp = BSP_mve_setup(
unit, 0,
cleanup_buf, 0,
alloc_rxbuf,
consume_buf, 0,
10, 10,
0);
if ( mp )
BSP_mve_init_hw(mp, 0, 0);
return mp;
}

View File

@@ -0,0 +1,323 @@
#ifndef KERNEL
#define KERNEL
#endif
#include <rtems.h>
#include <rtems/rtems_bsdnet_internal.h>
#include <bsp.h>
#include <sys/mbuf.h>
#include "mv64340_eth_ll.h"
#include <string.h>
#include <assert.h>
#include <netinet/in.h>
#include <stdio.h>
#define RX_SPACING 1
#define TX_SPACING 1
#define RX_RING_SIZE (MV64340_RX_QUEUE_SIZE*RX_SPACING)
#define TX_RING_SIZE (MV64340_TX_QUEUE_SIZE*TX_SPACING)
struct eth_rx_desc rx_ring[RX_RING_SIZE] __attribute__((aligned(32)));
struct eth_rx_desc rx_ring[RX_RING_SIZE] = {{0},};
struct eth_tx_desc tx_ring[TX_RING_SIZE] __attribute__((aligned(32)));
struct eth_tx_desc tx_ring[TX_RING_SIZE] = {{0},};
/* packet buffers */
char rx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
char rx_buf[MV64340_RX_QUEUE_SIZE][2048];
char tx_buf[MV64340_RX_QUEUE_SIZE][2048] __attribute__((aligned(8)));
char tx_buf[MV64340_RX_QUEUE_SIZE][2048];
char BcHeader[22] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* dst */
0x00, 0x01, 0xaf, 0x13, 0xb5, 0x3e, /* src */
00, 00, /* len */
0xAA, /* dsap */
0xAA, /* ssap */
0x03, /* ctrl */
0x08, 0x00, 0x56, /* snap_org [stanford] */
0x80, 0x5b, /* snap_type (stanford kernel) */
};
struct mv64340_private mveth = {
port_num: 0,
port_mac_addr: {0x00,0x01,0xAF,0x13,0xB5,0x3C},
/* port_config .. tx_resource_err are set by port_init */
0
};
struct pkt_info p0,p1;
static inline void rx_stopq(int port)
{
MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port), 0x0000ff00);
}
static inline void tx_stopq(int port)
{
MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port), 0x0000ff00);
}
#define MV64360_ENET2MEM_SNOOP_NONE 0x0000
#define MV64360_ENET2MEM_SNOOP_WT 0x1000
#define MV64360_ENET2MEM_SNOOP_WB 0x2000
#if 0
int
mveth_init(struct mv64340_private *mp)
{
int i;
mp->p_rx_desc_area = rx_ring;
mp->p_tx_desc_area = tx_ring;
rx_stopq(mp->port_num);
tx_stopq(mp->port_num);
/* MotLoad has cache snooping disabled on the ENET2MEM windows.
* Some comments in (linux) indicate that there are errata
* which cause problems which is a real bummer.
* We try it anyways...
*/
{
unsigned long disbl, bar;
disbl = MV_READ(MV64340_ETH_BASE_ADDR_ENABLE_REG);
/* disable all 6 windows */
MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
/* set WB snooping */
for ( i=0; i<6*8; i+=8 ) {
if ( (bar = MV_READ(MV64340_ETH_BAR_0 + i)) && MV_READ(MV64340_ETH_SIZE_REG_0 + i) ) {
MV_WRITE(MV64340_ETH_BAR_0 + i, bar | MV64360_ENET2MEM_SNOOP_WB);
/* read back to flush fifo [linux comment] */
(void)MV_READ(MV64340_ETH_BAR_0 + i);
}
}
/* restore/re-enable */
MV_WRITE(MV64340_ETH_BASE_ADDR_ENABLE_REG, disbl);
}
eth_port_init(mp);
sleep(1);
mveth_init_tx_desc_ring(mp);
mveth_init_rx_desc_ring(mp);
#if 0
for ( i = 0; i<MV64340_RX_QUEUE_SIZE; i++ ) {
p0.byte_cnt = sizeof(rx_buf[0]);
p0.buf_ptr = (dma_addr_t)rx_buf[i];
p0.return_info = (void*)i;
/* other fields are not used by ll driver */
assert ( ETH_OK == eth_rx_return_buff(mp,&p0) );
}
memset(&p0, 0, sizeof(p0));
#endif
return eth_port_start(mp);
}
#endif
void
mveth_stop(struct mv64340_private *mp)
{
extern void mveth_stop_hw();
rtems_bsdnet_semaphore_obtain();
mveth_stop_hw(mp);
rtems_bsdnet_semaphore_release();
}
extern int mveth_send_mbuf();
extern int mveth_swipe_tx();
int
mveth_tx(struct mv64340_private *mp, char *data, int len, int nbufs)
{
int rval = -1,l;
char *p;
struct mbuf *m;
char *emsg = 0;
rtems_bsdnet_semaphore_obtain();
MGETHDR(m, M_WAIT, MT_DATA);
if ( !m ) {
emsg="Unable to allocate header\n";
goto bail;
}
MCLGET(m, M_WAIT);
if ( !(m->m_flags & M_EXT) ) {
m_freem(m);
emsg="Unable to allocate cluster\n";
goto bail;
}
p = mtod(m, char *);
l = 0;
switch (nbufs) {
case 3:
default:
emsg="nbufs arg must be 1..3\n";
goto bail;
case 1:
l += sizeof(BcHeader);
memcpy(p, &BcHeader, sizeof(BcHeader));
p += sizeof(BcHeader);
case 2:
memcpy(p,data,len);
l += len;
m->m_len = m->m_pkthdr.len = l;
if ( 2 == nbufs ) {
M_PREPEND(m, sizeof (BcHeader), M_WAIT);
if (!m) {
emsg = "Unable to prepend\n";
goto bail;
}
p = mtod(m, char*);
memcpy(p,&BcHeader,sizeof(BcHeader));
l += sizeof(BcHeader);
}
break;
}
*(short*)(mtod(m, char*) + 12) = htons(l-14);
rval = mveth_send_mbuf(mp,m);
bail:
rtems_bsdnet_semaphore_release();
if (emsg)
printf(emsg);
#if 0
/*
* Add local net header. If no space in first mbuf,
* allocate another.
*/
M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
if (m == 0)
senderr(ENOBUFS);
eh = mtod(m, struct ether_header *);
(void)memcpy(&eh->ether_type, &type,
sizeof(eh->ether_type));
(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
(void)memcpy(eh->ether_shost, ac->ac_enaddr,
sizeof(eh->ether_shost));
#endif
return rval;
}
int
mveth_protected(int (*p)(struct mv64340_private*), struct mv64340_private *mp)
{
int rval;
rtems_bsdnet_semaphore_obtain();
rval = p(mp);
rtems_bsdnet_semaphore_release();
return rval;
}
int
mveth_rx(struct mv64340_private *mp)
{
extern int mveth_swipe_rx();
return mveth_protected(mveth_swipe_rx,mp);
}
int
mveth_reclaim(struct mv64340_private *mp)
{
extern int mveth_swipe_tx();
return mveth_protected(mveth_swipe_tx,mp);
}
int preth(FILE *f, char *p)
{
int i;
for (i=0; i<4; i++)
fprintf(f,"%02X:",p[i]);
fprintf(f,"%02X",p[i]);
return 6;
}
char *errcode2str(st)
{
char *rval;
switch(st) {
case ETH_OK:
rval = "OK";
break;
case ETH_ERROR:
rval = "Fundamental error.";
break;
case ETH_RETRY:
rval = "Could not process request. Try later.";
break;
case ETH_END_OF_JOB:
rval = "Ring has nothing to process.";
break;
case ETH_QUEUE_FULL:
rval = "Ring resource error.";
break;
case ETH_QUEUE_LAST_RESOURCE:
rval = "Ring resources about to exhaust.";
break;
default:
rval = "UNKNOWN"; break;
}
return rval;
}
#if 0
int
mveth_rx(struct mv64340_private *mp)
{
int st;
struct pkt_info p;
if ( ETH_OK != (st=eth_port_receive(mp, &p)) ) {
fprintf(stderr,"receive: %s\n", errcode2str(st));
return -1;
}
printf("%i bytes received from ", p.byte_cnt);
preth(stdout,(char*)p.buf_ptr+6);
printf(" (desc. stat: 0x%08x)\n", p.cmd_sts);
p.byte_cnt = sizeof(rx_buf[0]);
p.buf_ptr -= RX_BUF_OFFSET;
if ( ETH_OK != (st=eth_rx_return_buff(mp,&p) ) ) {
fprintf(stderr,"returning buffer: %s\n", errcode2str(st));
return -1;
}
return 0;
}
#endif
int
dring()
{
int i;
if (1) {
struct eth_rx_desc *pr;
printf("RX:\n");
for (i=0, pr=rx_ring; i<RX_RING_SIZE; i+=RX_SPACING, pr+=RX_SPACING) {
dcbi(pr);
printf("cnt: 0x%04x, size: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
pr->byte_cnt, pr->buf_size, pr->cmd_sts, pr->next_desc_ptr, pr->buf_ptr);
}
}
if (1) {
struct eth_tx_desc *pt;
printf("TX:\n");
for (i=0, pt=tx_ring; i<TX_RING_SIZE; i+=TX_SPACING, pt+=TX_SPACING) {
dcbi(pt);
printf("cnt: 0x%04x, stat: 0x%08x, next: 0x%08x, buf: 0x%08x\n",
pt->byte_cnt, pt->cmd_sts, pt->next_desc_ptr, pt->buf_ptr);
}
}
return 0;
}

View File

@@ -0,0 +1,51 @@
/* NOTE: The terms described in this LICENSE file apply only to the
* files created by the author (see below). Consult individual
* file headers for more details. Some files were ported from
* netbsd and/or freebsd and are covered by the respective
* file header copyright notices.
*/
/*
* Authorship
* ----------
* This software ('RTEMS-portability wrappers for BSD network drivers') was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'RTEMS-portability wrappers for BSD network drivers' software was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/

View File

@@ -0,0 +1,84 @@
#
# Makefile.lib,v 1.5 2000/06/12 15:00:14 joel Exp
#
# Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
# License: see LICENSE file.
#
# Templates/Makefile.lib
# Template library Makefile
#
LIBNAME=libif_XXX.a # XXX- your library names goes here
LIB=${ARCH}/${LIBNAME}
# C and C++ source names, if any, go here -- minus the .c or .cc
C_PIECES=if_XXX if_XXX_rtems
C_FILES=$(C_PIECES:%=%.c)
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
CC_PIECES=
CC_FILES=$(CC_PIECES:%=%.cc)
CC_O_FILES=$(CC_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_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(RTEMS_ROOT)/make/lib.cfg
#
# Add local stuff here using +=
#
#DEFINES += -DHAVE_LIBBSPEXT -DDEBUG_MODULAR
CPPFLAGS += -I. -Ilibchip -Iporting
# bsdnet newproc generated daemon is non-FP;
# prevent optimizer from generating FP instructions
CFLAGS += -Wno-unused-variable -msoft-float
#
# 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) $(LIB)
$(LIB): ${OBJS}
$(make-library)
ifndef RTEMS_SITE_INSTALLDIR
RTEMS_SITE_INSTALLDIR = $(PROJECT_RELEASE)
endif
${RTEMS_SITE_INSTALLDIR}/include \
${RTEMS_SITE_INSTALLDIR}/lib \
${RTEMS_SITE_INSTALLDIR}/bin \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/include \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/lib \
${RTEMS_SITE_INSTALLDIR}/$(RTEMS_BSP)/bin :
test -d $@ || mkdir -p $@
# Install the library, appending _g or _p as appropriate.
# for include files, just use $(INSTALL_CHANGE)
#
# NOTES:
# - BSP specific libraries, headers etc. should be installed to
# $RTEMS_SITE_INSTALLDIR)/$(RTEMS_BSP)/lib
#
install: all $(RTEMS_SITE_INSTALLDIR)/lib
$(INSTALL_VARIANT) -m 644 ${LIB} ${RTEMS_SITE_INSTALLDIR}/lib

View File

@@ -0,0 +1,106 @@
Templates to help porting freebsd networking drivers
to rtems (focus on i386 and powerpc) using a 'quick and dirty'
approach.
This is not an elegant piece of software -- be warned.
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
Release info: $Name$
Usage:
A obtain the freebsd driver source. It usually is made
up of a
if_XXX.c -- core driver
if_XXXreg.h -- core header
if_XXXvar.h -- some have it, some don't
if_XXX_<bus>.c -- glue to integrate the core
driver with different environments
(such as pccard, pci, ...). There
are several of these.
Note that you might have to get an older version
as some structures and interfaces may have undergone
significant changes since the bsd/networking version that
was ported to rtems.
B Copy the Makefile and rtemscompat_defs.h templates to the
driver source dir and edit them.
C Edit if_XXXreg.h and comment all unneeded fields from the
'softc' structure declaration with
#ifndef __rtems__
#endif
In particular, the bushandle field (as defined in rtemscompat_defs.h)
above, see comments in the template) must be re-declared:
#ifndef __rtems__
bus_space_handle_t XXX_bhandle;
#else
unsigned XXX_bhandle;
unsigned char irq_no;
unsigned char b,d,f; /* PCI tuple; needed for PCI only */
rtems_id tid; /* driver task id */
#endif
Later, the compilation attempts will help identifying
fields that need to be removed.
I like the #ifdef __rtems__ construct as it minimizes changes
to the source thus making merging updated driver versions easier.
D Edit if_XXX.c; at the very top, include the lines
#ifdef __rtems__
#include <rtemscompat.h>
#endif
use the #ifndef __rtems__ #endif construct to comment
unneeded / unsupported inclusion of headers and code pieces.
- inclusion of net/if_media.h must usually be mapped to
libchip/if_media.h
comment all vm, machine, bus, mii etc. related headers.
- replace inclusion of if_XXXreg.h by
#include "if_XXXreg.h"
#include <rtemscompat1.h>
- work through the if_XXX.c and if_XXXreg.h files commenting
stuff until if_XXX.c compiles. This might involve hacking
the helper headers.
- pay attention to endian issues; things may need to be fixed!
- at the top where the freebsd 'methods' and the like are
commented, add a definition of the driver methods for RTEMS:
#ifdef __rtems__
net_drv_tbl_t METHODS = {
n_probe : XXX_probe,
n_attach : XXX_attach,
n_detach : XXX_detach, /* optional; */
n_intr : XXX_intr, /* freebsd ISR; executed from daemon under RTEMS */
};
#endif
- make sure all the if_xxx methods are set; in particular,
set
sc->if_output = ether_output;
- on input:
you can use DO_ETHER_INPUT_SKIPPING_ETHER_HEADER() macro
-- if you don't MAKE SURE THE RECEIVING INTERFACE IS SET
in the mbuf packet header!!!
E create 'rtems_<chip>_setup()' to probe for devices and
set the softc struct's base address, interrupt line and
bus/dev/fun triple (PCI only).
For PCI devices, a generic setup routine already comes with
porting/if_xxx_rtems.c -> nothing needs to be written!

View File

@@ -0,0 +1,34 @@
#include <rtems.h>
#include <porting/rtemscompat.h>
/* CEXP module initialization/finalization */
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
void
_cexpModuleInitialize(void *unused)
{
extern void NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)(char *);
METHODSPTR = &METHODS;
/*
#ifdef DEBUG
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)("192.168.2.13/255.255.255.0");
#endif
*/
}
int
_cexpModuleFinalize(void *unused)
{
#ifdef DEBUG
extern int NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)();
if (NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)())
return -1;
METHODSPTR = 0;
return 0;
#else
return -1;
#endif
}

View File

@@ -0,0 +1,504 @@
/* $Id$ */
#include <rtemscompat.h>
/* Template for driver task, setup and attach routines. To be instantiated
* by defining the relevant symbols in header files.
*/
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
/* $Name$ */
#include <rtems/irq.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <net/if_media.h>
#ifdef IF_REG_HEADER
#include IF_REG_HEADER
#endif
#ifdef IF_VAR_HEADER
#include IF_VAR_HEADER
#endif
#include <rtemscompat1.h>
#define EX_EVENT RTEMS_EVENT_1
#undef IRQ_AT_8259
NETDEV_DECL = { /*[0]:*/{ /* softc: */ { /* arpcom: */{ /* ac_if: */ { 0 }}}}};
static void net_daemon(void *arg);
#ifdef HAVE_LIBBSPEXT
#include <bsp/bspExt.h>
static void the_net_isr(void *);
#else
static void noop(const rtems_irq_connect_data *unused) {}
static int noop1(const rtems_irq_connect_data *unused) { return 0;}
#if ISMINVERSION(4,6,99)
static void the_net_isr(rtems_irq_hdl_param);
#else
static void the_net_isr();
#if NETDRIVER_SLOTS > 1
#error only one instance supported (stupid IRQ API)
#else
static struct NET_SOFTC *thesc;
#endif
#endif
#endif
#if defined(NETDRIVER_PCI)
/* Public setup routine for PCI devices;
* TODO: currently doesn't work for subsystem vendor/id , i.e.
* devices behind a standard PCI interface...
*/
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(int inst);
#endif
static unsigned
NET_EMBEMB(,NETDRIVER_PREFIX,_net_driver_ticks_per_sec) = 0;
/* other drivers may already have this created */
extern unsigned net_driver_ticks_per_sec
__attribute__((weak, alias(NET_STRSTR(NETDRIVER_PREFIX)"_net_driver_ticks_per_sec") ));
#ifdef DEBUG_MODULAR
net_drv_tbl_t * volatile METHODSPTR = 0;
#endif
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_attach)
(struct rtems_bsdnet_ifconfig *config, int attaching)
{
int error = 0;
device_t dev = net_dev_get(config);
struct NET_SOFTC *sc;
struct ifnet *ifp;
#ifndef HAVE_LIBBSPEXT
rtems_irq_connect_data irq_data = {
0,
the_net_isr,
#if ISMINVERSION(4,6,99)
0,
#endif
noop,
noop,
noop1 };
#endif
if ( !dev )
return 1;
if ( !dev->d_softc.NET_SOFTC_BHANDLE_FIELD ) {
#if defined(NETDRIVER_PCI)
device_printf(dev,NETDRIVER" unit not configured; executing setup...");
/* setup should really be performed prior to attaching.
* Wipe the device; setup and re-obtain the device...
*/
memset(dev,0,sizeof(*dev));
error = NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(-1);
/* re-obtain the device */
dev = net_dev_get(config);
if ( !dev ) {
printk("Unable to re-assign device structure???\n");
return 1;
}
if (error <= 0) {
device_printf(dev,NETDRIVER" FAILED; unable to attach interface, sorry\n");
return 1;
}
device_printf(dev,"success\n");
#else
device_printf(dev,NETDRIVER" unit not configured; use 'rtems_"NETDRIVER"_setup()'\n");
return 1;
#endif
}
if ( !net_driver_ticks_per_sec )
rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &net_driver_ticks_per_sec );
sc = device_get_softc( dev );
ifp = &sc->arpcom.ac_if;
#ifdef DEBUG_MODULAR
if (!METHODSPTR) {
device_printf(dev,NETDRIVER": method pointer not set\n");
return -1;
}
#endif
if ( attaching ) {
if ( ifp->if_init ) {
device_printf(dev,NETDRIVER" Driver already attached.\n");
return -1;
}
if ( config->hardware_address ) {
/* use configured MAC address */
memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
} else {
#ifdef NET_READ_MAC_ADDR
NET_READ_MAC_ADDR(sc);
#endif
}
if ( METHODSPTR->n_attach(dev) ) {
device_printf(dev,NETDRIVER"_attach() failed\n");
return -1;
}
} else {
if ( !ifp->if_init ) {
device_printf(dev,NETDRIVER" Driver not attached.\n");
return -1;
}
if ( METHODSPTR->n_detach ) {
if ( METHODSPTR->n_detach(dev) ) {
device_printf(dev,NETDRIVER"_detach() failed\n");
return -1;
}
} else {
device_printf(dev,NETDRIVER"_detach() not implemented\n");
return -1;
}
}
if ( !sc->tid )
sc->tid = rtems_bsdnet_newproc(NETDRIVER"d", 4096, net_daemon, sc);
if (attaching) {
#ifdef DEBUG
printf("Installing IRQ # %i\n",sc->irq_no);
#endif
#ifdef HAVE_LIBBSPEXT
if ( bspExtInstallSharedISR(sc->irq_no, the_net_isr, sc, 0) )
#else
/* BSP dependent :-( */
irq_data.name = sc->irq_no;
#if ISMINVERSION(4,6,99)
irq_data.handle = (rtems_irq_hdl_param)sc;
#else
thesc = sc;
#endif
if ( ! BSP_install_rtems_irq_handler( &irq_data ) )
#endif
{
fprintf(stderr,NETDRIVER": unable to install ISR\n");
error = -1;
}
} else {
if ( sc->irq_no ) {
#ifdef DEBUG
printf("Removing IRQ # %i\n",sc->irq_no);
#endif
#ifdef HAVE_LIBBSPEXT
if (bspExtRemoveSharedISR(sc->irq_no, the_net_isr, sc))
#else
/* BSP dependent :-( */
irq_data.name = sc->irq_no;
#if ISMINVERSION(4,6,99)
irq_data.handle = (rtems_irq_hdl_param)sc;
#endif
if ( ! BSP_remove_rtems_irq_handler( &irq_data ) )
#endif
{
fprintf(stderr,NETDRIVER": unable to uninstall ISR\n");
error = -1;
}
}
}
return error;
}
static void
the_net_isr(
#ifdef HAVE_LIBBSPEXT
void *thesc
#elif ISMINVERSION(4,6,99)
rtems_irq_hdl_param thesc
#endif
)
{
struct NET_SOFTC *sc = thesc;
/* disable interrupts */
NET_DISABLE_IRQS(sc);
rtems_event_send( sc->tid, EX_EVENT );
}
static void net_daemon(void *arg)
{
struct NET_SOFTC *sc = arg;
rtems_event_set evs;
for (;;) {
rtems_bsdnet_event_receive(
EX_EVENT,
RTEMS_WAIT | RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&evs);
METHODSPTR->n_intr(sc);
/* re-enable interrupts */
NET_ENABLE_IRQS(sc);
}
}
static struct NET_SOFTC *
net_drv_check_unit(int unit)
{
unit--;
if ( unit < 0 || unit >= NETDRIVER_SLOTS ) {
fprintf(stderr,"Invalid unit # %i (not in %i..%i)\n", unit+1, 1, NETDRIVER_SLOTS);
return 0;
}
if ( THEDEVS[unit].d_name ) {
fprintf(stderr,"Unit %i already set up\n", unit+1);
return 0;
}
memset( &THEDEVS[unit], 0, sizeof(THEDEVS[0]) );
return &THEDEVS[unit].d_softc;
}
struct rtems_bsdnet_ifconfig NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config) = {
NETDRIVER"1",
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_attach),
0
};
#ifdef DEBUG
void
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringup)(char *ipaddr)
{
short flags;
struct sockaddr_in addr;
char *mask;
if (!ipaddr) {
printf("Need an ip[/mask] argument (dot notation)\n");
return;
}
ipaddr = strdup(ipaddr);
if ( (mask = strchr(ipaddr,'/')) ) {
*mask++=0;
} else {
mask = "255.255.255.0";
}
#if defined(NETDRIVER_PCI)
/* this fails if already setup */
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(-1);
#endif
rtems_bsdnet_attach(&NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config));
flags = IFF_UP /*| IFF_PROMISC*/;
if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFFLAGS,&flags) < 0 ) {
printf("Can't bring '"NETDRIVER"1' up\n");
goto cleanup;
}
memset(&addr,0,sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(mask);
if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFNETMASK,&addr) < 0 ) {
printf("Unable to set netmask on '"NETDRIVER"1'\n");
goto cleanup;
}
addr.sin_addr.s_addr = inet_addr(ipaddr);
if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFADDR,&addr) < 0 ) {
printf("Unable to set address on '"NETDRIVER"1'\n");
goto cleanup;
}
cleanup:
the_real_free (ipaddr);
}
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_bringdown)()
{
short flags;
flags = 0;
if ( rtems_bsdnet_ifconfig(NETDRIVER"1",SIOCSIFFLAGS,&flags) < 0 ) {
printf("Can't bring '"NETDRIVER"1' down\n");
return -1;
}
rtems_bsdnet_detach(&NET_EMBEMB(NETDRIVER_PREFIX,_dbg,_config));
return 0;
}
#endif
#if defined(NETDRIVER_PCI) && !defined(NETDRIVER_OWN_SETUP)
/* Public setup routine for PCI devices;
* TODO: currently doesn't work for subsystem vendor/id , i.e.
* devices behind a standard PCI interface...
* passing 'inst' > only sets-up the 'inst'th card; passing
* 'inst' == 0 sets-up all matching cards.
*/
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_pci_setup)(int inst)
{
unsigned b,d,f,i,isio,unit;
rtemscompat_32_t base;
unsigned short cmd,id;
unsigned char h;
struct NET_SOFTC *sc;
unsigned try[] = { PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, 0 };
#ifdef DEBUG_MODULAR
if ( !METHODSPTR ) {
fprintf(stderr,NETDRIVER": Methods pointer not set\n");
return -1;
}
#endif
/* 0 can be reached when looking for the desired instance */
if ( 0 == inst )
inst = -1;
#ifdef HAVE_LIBBSPEXT
/* make sure it's initialized */
bspExtInit();
#endif
/* scan PCI for supported devices */
for ( b=0, sc=0, unit=0; b<pci_bus_count(); b++ ) {
for ( d=0; d<PCI_MAX_DEVICES; d++ ) {
pci_read_config_word(b,d,0,PCI_VENDOR_ID,&id);
if ( 0xffff == id )
continue; /* empty slot */
pci_read_config_byte(b,d,0,PCI_HEADER_TYPE,&h);
h = h&0x80 ? PCI_MAX_FUNCTIONS : 1; /* multifunction device ? */
for ( f=0; f<h; f++ ) {
if ( !sc && !(sc=net_drv_check_unit(unit+1))) {
fprintf(stderr,"Not enough driver slots; stop looking for more devices...\n");
return unit;
}
pci_read_config_word(b,d,f,PCI_VENDOR_ID,&id);
if ( 0xffff == id )
continue; /* empty slot */
pci_read_config_word(b,d,f,PCI_CLASS_DEVICE,&id);
if ( PCI_CLASS_NETWORK_ETHERNET != id )
continue; /* only look at ethernet devices */
sc->b = b;
sc->d = d;
sc->f = f;
for ( i=0, base=0, isio=0; try[i]; i++ ) {
pci_read_config_dword(b,d,f,try[i],&base);
if ( base ) {
if ( (isio = (PCI_BASE_ADDRESS_SPACE_IO == (base & PCI_BASE_ADDRESS_SPACE )) ) ) {
#ifdef NET_CHIP_PORT_IO
base &= PCI_BASE_ADDRESS_IO_MASK;
sc->NET_SOFTC_BHANDLE_FIELD = PCI_IO_2LOCAL(base,b);
#ifdef DEBUG
printf("Found PCI I/O Base 0x%08x\n", (unsigned)base);
#endif
#else
base = 0;
continue;
#endif
} else {
#ifdef NET_CHIP_MEM_IO
base &= PCI_BASE_ADDRESS_MEM_MASK;
sc->NET_SOFTC_BHANDLE_FIELD = PCI2LOCAL(base,b);
#ifdef DEBUG
printf("Found PCI MEM Base 0x%08x\n", (unsigned)base);
#endif
#else
base = 0;
continue;
#endif
}
break;
}
}
if ( !base ) {
#ifdef DEBUG
fprintf(stderr, NETDRIVER": (warning) Neither PCI base address 0 nor 1 are configured; skipping bus %i, slot %i, fn %i...\n",b,d,f);
#endif
continue;
}
if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit]) && (inst < 0 || !--inst) ) {
pci_read_config_word(b,d,f,PCI_COMMAND,&cmd);
pci_write_config_word(b,d,f,PCI_COMMAND,
cmd | (isio ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY) | PCI_COMMAND_MASTER );
pci_read_config_byte(b,d,f,PCI_INTERRUPT_LINE,&sc->irq_no);
printf(NETDRIVER": card found @PCI[%s] 0x%08x (local 0x%08x), IRQ %i\n",
(isio ? "io" : "mem"), (unsigned)base, sc->NET_SOFTC_BHANDLE_FIELD, sc->irq_no);
sc = 0; /* need to allocate a new slot */
unit++;
if ( 0 == inst ) {
/* found desired instance */
goto terminated;
}
}
}
}
}
terminated:
return unit;
}
#else
/* simple skeleton
int
NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_setup)(
int unit,
void *base_addr,
int irq_no)
{
struct NET_SOFTC *sc;
if ( !(sc=net_drv_check_unit(unit)) ) {
fprintf(stderr,"Bad unit number -- (not enought driver slots?)\n");
return 0;
}
sc->NET_SOFTC_BHANDLE_FIELD = base_addr;
if ( 0 == METHODSPTR->n_probe(&THEDEVS[unit-1]) ) {
sc->irq_no = irq_no;
printf(NETDRIVER": Unit %i set up\n", unit);
return unit;
}
return 0;
}
*/
#endif

View File

@@ -0,0 +1,405 @@
/*-
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/pci/pcireg.h,v 1.39.4.3 2005/04/02 05:03:34 jmg Exp $
*
*/
/*
* PCIM_xxx: mask to locate subfield in register
* PCIR_xxx: config register offset
* PCIC_xxx: device class
* PCIS_xxx: device subclass
* PCIP_xxx: device programming interface
* PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
* PCID_xxx: device ID
* PCIY_xxx: capability identification number
*/
/* some PCI bus constants */
#define PCI_BUSMAX 255
#define PCI_SLOTMAX 31
#define PCI_FUNCMAX 7
#define PCI_REGMAX 255
#define PCI_MAXHDRTYPE 2
/* PCI config header registers for all devices */
#define PCIR_DEVVENDOR 0x00
#define PCIR_VENDOR 0x00
#define PCIR_DEVICE 0x02
#define PCIR_COMMAND 0x04
#define PCIM_CMD_PORTEN 0x0001
#define PCIM_CMD_MEMEN 0x0002
#define PCIM_CMD_BUSMASTEREN 0x0004
#define PCIM_CMD_SPECIALEN 0x0008
#define PCIM_CMD_MWRICEN 0x0010
#define PCIM_CMD_PERRESPEN 0x0040
#define PCIM_CMD_SERRESPEN 0x0100
#define PCIM_CMD_BACKTOBACK 0x0200
#define PCIR_STATUS 0x06
#define PCIM_STATUS_CAPPRESENT 0x0010
#define PCIM_STATUS_66CAPABLE 0x0020
#define PCIM_STATUS_BACKTOBACK 0x0080
#define PCIM_STATUS_PERRREPORT 0x0100
#define PCIM_STATUS_SEL_FAST 0x0000
#define PCIM_STATUS_SEL_MEDIMUM 0x0200
#define PCIM_STATUS_SEL_SLOW 0x0400
#define PCIM_STATUS_SEL_MASK 0x0600
#define PCIM_STATUS_STABORT 0x0800
#define PCIM_STATUS_RTABORT 0x1000
#define PCIM_STATUS_RMABORT 0x2000
#define PCIM_STATUS_SERR 0x4000
#define PCIM_STATUS_PERR 0x8000
#define PCIR_REVID 0x08
#define PCIR_PROGIF 0x09
#define PCIR_SUBCLASS 0x0a
#define PCIR_CLASS 0x0b
#define PCIR_CACHELNSZ 0x0c
#define PCIR_LATTIMER 0x0d
#define PCIR_HDRTYPE 0x0e
#ifndef BURN_BRIDGES
#define PCIR_HEADERTYPE PCIR_HDRTYPE
#endif
#define PCIM_HDRTYPE 0x7f
#define PCIM_HDRTYPE_NORMAL 0x00
#define PCIM_HDRTYPE_BRIDGE 0x01
#define PCIM_HDRTYPE_CARDBUS 0x02
#define PCIM_MFDEV 0x80
#define PCIR_BIST 0x0f
/* Capability Identification Numbers */
#define PCIY_PMG 0x01 /* PCI Power Management */
#define PCIY_AGP 0x02 /* AGP */
#define PCIY_VPD 0x03 /* Vital Product Data */
#define PCIY_SLOTID 0x04 /* Slot Identification */
#define PCIY_MSI 0x05 /* Message Signaled Interrupts */
#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */
#define PCIY_PCIX 0x07 /* PCI-X */
#define PCIY_HT 0x08 /* HyperTransport */
#define PCIY_VENDOR 0x09 /* Vendor Unique */
#define PCIY_DEBUG 0x0a /* Debug port */
#define PCIY_CRES 0x0b /* CompactPCI central resource control */
#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */
#define PCIY_AGP8X 0x0e /* AGP 8x */
#define PCIY_SECDEV 0x0f /* Secure Device */
#define PCIY_EXPRESS 0x10 /* PCI Express */
#define PCIY_MSIX 0x11 /* MSI-X */
/* config registers for header type 0 devices */
#define PCIR_BARS 0x10
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
#ifndef BURN_BRIDGES
#define PCIR_MAPS PCIR_BARS
#endif
#define PCIR_CARDBUSCIS 0x28
#define PCIR_SUBVEND_0 0x2c
#define PCIR_SUBDEV_0 0x2e
#define PCIR_BIOS 0x30
#define PCIM_BIOS_ENABLE 0x01
#define PCIR_CAP_PTR 0x34
#define PCIR_INTLINE 0x3c
#define PCIR_INTPIN 0x3d
#define PCIR_MINGNT 0x3e
#define PCIR_MAXLAT 0x3f
/* config registers for header type 1 (PCI-to-PCI bridge) devices */
#define PCIR_SECSTAT_1 0x1e
#define PCIR_PRIBUS_1 0x18
#define PCIR_SECBUS_1 0x19
#define PCIR_SUBBUS_1 0x1a
#define PCIR_SECLAT_1 0x1b
#define PCIR_IOBASEL_1 0x1c
#define PCIR_IOLIMITL_1 0x1d
#define PCIR_IOBASEH_1 0x30
#define PCIR_IOLIMITH_1 0x32
#define PCIM_BRIO_16 0x0
#define PCIM_BRIO_32 0x1
#define PCIM_BRIO_MASK 0xf
#define PCIR_MEMBASE_1 0x20
#define PCIR_MEMLIMIT_1 0x22
#define PCIR_PMBASEL_1 0x24
#define PCIR_PMLIMITL_1 0x26
#define PCIR_PMBASEH_1 0x28
#define PCIR_PMLIMITH_1 0x2c
#define PCIR_BRIDGECTL_1 0x3e
#define PCIR_SUBVEND_1 0x34
#define PCIR_SUBDEV_1 0x36
/* config registers for header type 2 (CardBus) devices */
#define PCIR_SECSTAT_2 0x16
#define PCIR_PRIBUS_2 0x18
#define PCIR_SECBUS_2 0x19
#define PCIR_SUBBUS_2 0x1a
#define PCIR_SECLAT_2 0x1b
#define PCIR_MEMBASE0_2 0x1c
#define PCIR_MEMLIMIT0_2 0x20
#define PCIR_MEMBASE1_2 0x24
#define PCIR_MEMLIMIT1_2 0x28
#define PCIR_IOBASE0_2 0x2c
#define PCIR_IOLIMIT0_2 0x30
#define PCIR_IOBASE1_2 0x34
#define PCIR_IOLIMIT1_2 0x38
#define PCIR_BRIDGECTL_2 0x3e
#define PCIR_SUBVEND_2 0x40
#define PCIR_SUBDEV_2 0x42
#define PCIR_PCCARDIF_2 0x44
/* PCI device class, subclass and programming interface definitions */
#define PCIC_OLD 0x00
#define PCIS_OLD_NONVGA 0x00
#define PCIS_OLD_VGA 0x01
#define PCIC_STORAGE 0x01
#define PCIS_STORAGE_SCSI 0x00
#define PCIS_STORAGE_IDE 0x01
#define PCIP_STORAGE_IDE_MODEPRIM 0x01
#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02
#define PCIP_STORAGE_IDE_MODESEC 0x04
#define PCIP_STORAGE_IDE_PROGINDSEC 0x08
#define PCIP_STORAGE_IDE_MASTERDEV 0x80
#define PCIS_STORAGE_FLOPPY 0x02
#define PCIS_STORAGE_IPI 0x03
#define PCIS_STORAGE_RAID 0x04
#define PCIS_STORAGE_OTHER 0x80
#define PCIC_NETWORK 0x02
#define PCIS_NETWORK_ETHERNET 0x00
#define PCIS_NETWORK_TOKENRING 0x01
#define PCIS_NETWORK_FDDI 0x02
#define PCIS_NETWORK_ATM 0x03
#define PCIS_NETWORK_ISDN 0x04
#define PCIS_NETWORK_OTHER 0x80
#define PCIC_DISPLAY 0x03
#define PCIS_DISPLAY_VGA 0x00
#define PCIS_DISPLAY_XGA 0x01
#define PCIS_DISPLAY_3D 0x02
#define PCIS_DISPLAY_OTHER 0x80
#define PCIC_MULTIMEDIA 0x04
#define PCIS_MULTIMEDIA_VIDEO 0x00
#define PCIS_MULTIMEDIA_AUDIO 0x01
#define PCIS_MULTIMEDIA_TELE 0x02
#define PCIS_MULTIMEDIA_OTHER 0x80
#define PCIC_MEMORY 0x05
#define PCIS_MEMORY_RAM 0x00
#define PCIS_MEMORY_FLASH 0x01
#define PCIS_MEMORY_OTHER 0x80
#define PCIC_BRIDGE 0x06
#define PCIS_BRIDGE_HOST 0x00
#define PCIS_BRIDGE_ISA 0x01
#define PCIS_BRIDGE_EISA 0x02
#define PCIS_BRIDGE_MCA 0x03
#define PCIS_BRIDGE_PCI 0x04
#define PCIS_BRIDGE_PCMCIA 0x05
#define PCIS_BRIDGE_NUBUS 0x06
#define PCIS_BRIDGE_CARDBUS 0x07
#define PCIS_BRIDGE_RACEWAY 0x08
#define PCIS_BRIDGE_OTHER 0x80
#define PCIC_SIMPLECOMM 0x07
#define PCIS_SIMPLECOMM_UART 0x00
#define PCIP_SIMPLECOMM_UART_16550A 0x02
#define PCIS_SIMPLECOMM_PAR 0x01
#define PCIS_SIMPLECOMM_MULSER 0x02
#define PCIS_SIMPLECOMM_MODEM 0x03
#define PCIS_SIMPLECOMM_OTHER 0x80
#define PCIC_BASEPERIPH 0x08
#define PCIS_BASEPERIPH_PIC 0x00
#define PCIS_BASEPERIPH_DMA 0x01
#define PCIS_BASEPERIPH_TIMER 0x02
#define PCIS_BASEPERIPH_RTC 0x03
#define PCIS_BASEPERIPH_PCIHOT 0x04
#define PCIS_BASEPERIPH_OTHER 0x80
#define PCIC_INPUTDEV 0x09
#define PCIS_INPUTDEV_KEYBOARD 0x00
#define PCIS_INPUTDEV_DIGITIZER 0x01
#define PCIS_INPUTDEV_MOUSE 0x02
#define PCIS_INPUTDEV_SCANNER 0x03
#define PCIS_INPUTDEV_GAMEPORT 0x04
#define PCIS_INPUTDEV_OTHER 0x80
#define PCIC_DOCKING 0x0a
#define PCIS_DOCKING_GENERIC 0x00
#define PCIS_DOCKING_OTHER 0x80
#define PCIC_PROCESSOR 0x0b
#define PCIS_PROCESSOR_386 0x00
#define PCIS_PROCESSOR_486 0x01
#define PCIS_PROCESSOR_PENTIUM 0x02
#define PCIS_PROCESSOR_ALPHA 0x10
#define PCIS_PROCESSOR_POWERPC 0x20
#define PCIS_PROCESSOR_MIPS 0x30
#define PCIS_PROCESSOR_COPROC 0x40
#define PCIC_SERIALBUS 0x0c
#define PCIS_SERIALBUS_FW 0x00
#define PCIS_SERIALBUS_ACCESS 0x01
#define PCIS_SERIALBUS_SSA 0x02
#define PCIS_SERIALBUS_USB 0x03
#define PCIP_SERIALBUS_USB_UHCI 0x00
#define PCIP_SERIALBUS_USB_OHCI 0x10
#define PCIP_SERIALBUS_USB_EHCI 0x20
#define PCIS_SERIALBUS_FC 0x04
#define PCIS_SERIALBUS_SMBUS 0x05
#define PCIC_WIRELESS 0x0d
#define PCIS_WIRELESS_IRDA 0x00
#define PCIS_WIRELESS_IR 0x01
#define PCIS_WIRELESS_RF 0x10
#define PCIS_WIRELESS_OTHER 0x80
#define PCIC_INTELLIIO 0x0e
#define PCIS_INTELLIIO_I2O 0x00
#define PCIC_SATCOM 0x0f
#define PCIS_SATCOM_TV 0x01
#define PCIS_SATCOM_AUDIO 0x02
#define PCIS_SATCOM_VOICE 0x03
#define PCIS_SATCOM_DATA 0x04
#define PCIC_CRYPTO 0x10
#define PCIS_CRYPTO_NETCOMP 0x00
#define PCIS_CRYPTO_ENTERTAIN 0x10
#define PCIS_CRYPTO_OTHER 0x80
#define PCIC_DASP 0x11
#define PCIS_DASP_DPIO 0x00
#define PCIS_DASP_OTHER 0x80
#define PCIC_OTHER 0xff
/* PCI power manangement */
#define PCIR_POWER_CAP 0x2
#define PCIM_PCAP_SPEC 0x0007
#define PCIM_PCAP_PMEREQCLK 0x0008
#define PCIM_PCAP_PMEREQPWR 0x0010
#define PCIM_PCAP_DEVSPECINIT 0x0020
#define PCIM_PCAP_DYNCLOCK 0x0040
#define PCIM_PCAP_SECCLOCK 0x00c0
#define PCIM_PCAP_CLOCKMASK 0x00c0
#define PCIM_PCAP_REQFULLCLOCK 0x0100
#define PCIM_PCAP_D1SUPP 0x0200
#define PCIM_PCAP_D2SUPP 0x0400
#define PCIM_PCAP_D0PME 0x1000
#define PCIM_PCAP_D1PME 0x2000
#define PCIM_PCAP_D2PME 0x4000
#define PCIR_POWER_STATUS 0x4
#define PCIM_PSTAT_D0 0x0000
#define PCIM_PSTAT_D1 0x0001
#define PCIM_PSTAT_D2 0x0002
#define PCIM_PSTAT_D3 0x0003
#define PCIM_PSTAT_DMASK 0x0003
#define PCIM_PSTAT_REPENABLE 0x0010
#define PCIM_PSTAT_PMEENABLE 0x0100
#define PCIM_PSTAT_D0POWER 0x0000
#define PCIM_PSTAT_D1POWER 0x0200
#define PCIM_PSTAT_D2POWER 0x0400
#define PCIM_PSTAT_D3POWER 0x0600
#define PCIM_PSTAT_D0HEAT 0x0800
#define PCIM_PSTAT_D1HEAT 0x1000
#define PCIM_PSTAT_D2HEAT 0x1200
#define PCIM_PSTAT_D3HEAT 0x1400
#define PCIM_PSTAT_DATAUNKN 0x0000
#define PCIM_PSTAT_DATADIV10 0x2000
#define PCIM_PSTAT_DATADIV100 0x4000
#define PCIM_PSTAT_DATADIV1000 0x6000
#define PCIM_PSTAT_DATADIVMASK 0x6000
#define PCIM_PSTAT_PME 0x8000
#define PCIR_POWER_PMCSR 0x6
#define PCIM_PMCSR_DCLOCK 0x10
#define PCIM_PMCSR_B2SUPP 0x20
#define PCIM_BMCSR_B3SUPP 0x40
#define PCIM_BMCSR_BPCE 0x80
#define PCIR_POWER_DATA 0x7
/* PCI Message Signalled Interrupts (MSI) */
#define PCIR_MSI_CTRL 0x2
#define PCIM_MSICTRL_VECTOR 0x0100
#define PCIM_MSICTRL_64BIT 0x0080
#define PCIM_MSICTRL_MME_MASK 0x0070
#define PCIM_MSICTRL_MME_1 0x0000
#define PCIM_MSICTRL_MME_2 0x0010
#define PCIM_MSICTRL_MME_4 0x0020
#define PCIM_MSICTRL_MME_8 0x0030
#define PCIM_MSICTRL_MME_16 0x0040
#define PCIM_MSICTRL_MME_32 0x0050
#define PCIM_MSICTRL_MMC_MASK 0x000E
#define PCIM_MSICTRL_MMC_1 0x0000
#define PCIM_MSICTRL_MMC_2 0x0002
#define PCIM_MSICTRL_MMC_4 0x0004
#define PCIM_MSICTRL_MMC_8 0x0006
#define PCIM_MSICTRL_MMC_16 0x0008
#define PCIM_MSICTRL_MMC_32 0x000A
#define PCIM_MSICTRL_MSI_ENABLE 0x0001
#define PCIR_MSI_ADDR 0x4
#define PCIR_MSI_ADDR_HIGH 0x8
#define PCIR_MSI_DATA 0x8
#define PCIR_MSI_DATA_64BIT 0xc
#define PCIR_MSI_MASK 0x10
#define PCIR_MSI_PENDING 0x14
/* PCI-X definitions */
#define PCIXR_COMMAND 0x96
#define PCIXR_DEVADDR 0x98
#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */
#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */
#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */
#define PCIXR_STATUS 0x9A
#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */
#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */
#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */
#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */
#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */
#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */
#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */
#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */
#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */

View File

@@ -0,0 +1,459 @@
#ifndef RTEMS_COMPAT_BSD_NET_H
#define RTEMS_COMPAT_BSD_NET_H
/* BSD -> rtems wrappers; stuff that must be defined
* prior to including most BSD headers
*/
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
#include <rtems.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <stdlib.h>
/* Check for RTEMS version; true if >= ma.mi.re */
#define ISMINVERSION(ma,mi,re) \
( __RTEMS_MAJOR__ > (ma) \
|| (__RTEMS_MAJOR__ == (ma) && __RTEMS_MINOR__ > (mi)) \
|| (__RTEMS_MAJOR__ == (ma) && __RTEMS_MINOR__ == (mi) && __RTEMS_REVISION__ >= (re)) \
)
/* 'align' ARG is evaluated more than once */
#define _DO_ALIGN(addr, align) (((uint32_t)(addr) + (align) - 1) & ~((align)-1))
/* malloc/free are redefined :-( */
static inline void *the_real_malloc(size_t n)
{
return malloc(n);
}
static inline void the_real_free(void *p)
{
return free(p);
}
#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
#include <rtems/rtems_bsdnet.h>
#include <rtems/rtems_bsdnet_internal.h>
#ifdef __i386__
#include <libcpu/cpu.h>
#elif defined(__PPC__)
#include <libcpu/io.h>
#else
#error "dunno what IO ops to use on this architecture"
#endif
#include <rtems/bspIo.h>
#include "rtemscompat_defs.h"
#define NET_EMB(x,y,z) x ## y ## z
#define NET_EMBEMB(x,y,z) NET_EMB(x,y,z)
#define NET_STR(arg) #arg
#define NET_STRSTR(arg) NET_STR(arg)
#define NET_SOFTC NET_EMBEMB(,NETDRIVER_PREFIX,_softc)
#define METHODS NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_methods)
extern struct _net_drv_tbl METHODS;
#ifdef DEBUG_MODULAR
#define METHODSPTR NET_EMBEMB(rtems_,NETDRIVER_PREFIX,_methods_p)
extern struct _net_drv_tbl *volatile METHODSPTR;
#else
#define METHODSPTR (&METHODS)
#endif
#if defined(__LITTLE_ENDIAN__) || (__i386__)
static inline uint16_t htole16(uint16_t v) { return v; }
static inline uint32_t htole32(uint32_t v) { return v; }
static inline uint64_t htole64(uint64_t v) { return v; }
static inline uint16_t le16toh(uint16_t v) { return v; }
static inline uint32_t le32toh(uint32_t v) { return v; }
static inline uint64_t le64toh(uint64_t v) { return v; }
#elif defined(__BIG_ENDIAN__)
#ifdef __PPC__
#include <libcpu/byteorder.h>
/* Different RTEMS versions use different types
* for 32-bit (unsigned vs. unsigned long which
* always cause gcc warnings and possible alias
* violations, sigh).
*/
#if ISMINVERSION(4,8,0)
typedef uint32_t rtemscompat_32_t;
#else
typedef unsigned rtemscompat_32_t;
#endif
static inline uint16_t
htole16(uint16_t v)
{
uint16_t rval;
st_le16(&rval,v);
return rval;
}
static inline uint16_t
le16toh(uint16_t v)
{
return ld_le16((unsigned short*)&v);
}
static inline uint32_t
htole32(uint32_t v)
{
rtemscompat_32_t rval;
st_le32(&rval,v);
return rval;
}
static inline uint32_t
le32toh(uint32_t v)
{
rtemscompat_32_t vv = v;
return ld_le32(&vv);
}
/* Compiler generated floating point instructions for this
* and rtems_bsdnet_newproc()-generated tasks are non-FP
* :-(
*/
static inline uint64_t
htole64(uint64_t v)
{
union {
rtemscompat_32_t tmp[2];
uint64_t rval;
} u;
st_le32( &u.tmp[0], (unsigned)(v&0xffffffff) );
st_le32( &u.tmp[1], (unsigned)((v>>32)&0xffffffff) );
return u.rval;
}
#else
#error "need htoleXX() implementation for this CPU arch"
#endif
#else
#error "Unknown CPU endianness"
#endif
#ifdef __PPC__
#define _out_byte(a,v) out_8((volatile unsigned char*)(a),(v))
#define _inp_byte(a) in_8((volatile unsigned char*)(a))
#ifdef NET_CHIP_LE
#define _out_word(a,v) out_le16((volatile unsigned short*)(a),(v))
#define _out_long(a,v) out_le32((volatile unsigned *)(a),(v))
#define _inp_word(a) in_le16((volatile unsigned short*)(a))
#define _inp_long(a) in_le32((volatile unsigned *)(a))
#elif defined(NET_CHIP_BE)
#define _out_word(a,v) out_be16((volatile unsigned short*)(a),(v))
#define _out_long(a,v) out_be32((volatile unsigned *)(a),(v))
#define _inp_word(a) in_be16((volatile unsigned short*)(a))
#define _inp_long(a) in_be32((volatile unsigned *)(a))
#else
#error rtemscompat_defs.h must define either NET_CHIP_LE or NET_CHIP_BE
#endif
static inline void wrle32(unsigned *a, unsigned v)
{
asm volatile("stwbrx %1,0,%2":"=m"(*a):"r"(v),"r"(a));
}
static inline unsigned rdle32(unsigned *a)
{
asm volatile("lwbrx %0,0,%0":"=r"(a):"0"(a),"m"(*a));
return (unsigned)a;
}
static inline void orle32(unsigned *a,unsigned v) { wrle32(a, rdle32(a) | v); }
static inline void anle32(unsigned *a,unsigned v) { wrle32(a, rdle32(a) & v); }
static inline void wrle16(unsigned short *a, unsigned short v)
{
asm volatile("sthbrx %1,0,%2":"=m"(*a):"r"(v),"r"(a));
}
static inline unsigned short rdle16(unsigned short *a)
{
asm volatile("lhbrx %0,0,%0":"=r"(a):"0"(a),"m"(*a));
return (unsigned short)(unsigned)a;
}
static inline void orle16(unsigned short *a,unsigned short v) { wrle16(a, rdle16(a) | v); }
static inline void anle16(unsigned short *a,unsigned short v) { wrle16(a, rdle16(a) & v); }
#endif
#ifdef __i386__
#ifdef NET_CHIP_BE
#error dunno how to output BE data
#endif
static inline void wrle32(volatile unsigned *p, unsigned v) { *p = v; }
static inline void orle32(volatile unsigned *p, unsigned v) { *p |= v; }
static inline void anle32(volatile unsigned *p, unsigned v) { *p &= v; }
static inline unsigned rdle32(volatile unsigned *p) { return *p; }
static inline void wrle16(volatile unsigned short *p, unsigned short v) { *p = v; }
static inline void orle16(volatile unsigned short *p, unsigned short v) { *p |= v; }
static inline void anle16(volatile unsigned short *p, unsigned short v) { *p &= v; }
static inline unsigned short rdle16(volatile unsigned short *p) { return *p; }
#ifdef NET_CHIP_MEM_IO
#ifdef __i386__
static inline void _out_byte(unsigned a, unsigned char v) { *(volatile unsigned char*)a = v; }
static inline unsigned char _inp_byte(unsigned a) { return *(volatile unsigned char*)a; }
#ifdef NET_CHIP_LE
static inline void _out_word(unsigned a, unsigned short v) { *(volatile unsigned short*)a = v; }
static inline unsigned short _inp_word(unsigned a) { return *(volatile unsigned short*)a; }
static inline void _out_long(unsigned a, unsigned v) { *(volatile unsigned *)a = v; }
static inline unsigned _inp_long(unsigned a) { return *(volatile unsigned *)a; }
#elif defined(NET_CHIP_BE)
#error "BE memory IO not implemented for i386 yet"
#else
#error rtemscompat_defs.h must define either NET_CHIP_LE or NET_CHIP_BE
#endif
#else
#error "Memory IO not implemented for this CPU architecture yet"
#endif
#elif defined(NET_CHIP_PORT_IO)
#define _out_byte(addr,val) outport_byte((addr),(val))
#define _out_word(addr,val) outport_word((addr),(val))
#define _out_long(addr,val) outport_long((addr),(val))
static inline u_int8_t _inp_byte(volatile unsigned char *a)
{
register u_int8_t rval;
inport_byte((unsigned short)(unsigned)a,rval);
return rval;
}
static inline u_int16_t _inp_word(volatile unsigned short *a)
{
register u_int16_t rval;
inport_word((unsigned short)(unsigned)a,rval);
return rval;
}
static inline u_int32_t _inp_long(volatile unsigned *a)
{
register u_int32_t rval;
inport_long((unsigned short)(unsigned)a,rval);
return rval;
}
#else
#error either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO must be defined
#endif
#endif
#ifndef __FBSDID
#define __FBSDID(arg)
#endif
#define _KERNEL
#define device_printf(device,format,args...) printk(format,## args)
static inline u_int8_t bus_space_do_read_1(u_long handle, unsigned reg)
{
return _inp_byte((volatile unsigned char*)((handle)+(reg)));
}
static inline u_int16_t bus_space_do_read_2(u_long handle, unsigned reg)
{
return _inp_word((volatile unsigned short*)((handle)+(reg)));
}
static inline u_int32_t bus_space_do_read_4(u_long handle, unsigned reg)
{
return _inp_long((volatile unsigned *)((handle)+(reg)));
}
#define bus_space_read_1(tag,handle,reg) bus_space_do_read_1((handle),(reg))
#define bus_space_read_2(tag,handle,reg) bus_space_do_read_2((handle),(reg))
#define bus_space_read_4(tag,handle,reg) bus_space_do_read_4((handle),(reg))
static inline void bus_space_do_write_multi_1(u_long handle, unsigned reg, unsigned char *addr, int cnt)
{
int i; for (i=0; i<cnt; i++) _out_byte( (handle) + (reg), (addr)[i]);
}
static inline void bus_space_do_write_multi_2(u_long handle, unsigned reg, unsigned short *addr, int cnt)
{
int i; for (i=0; i<cnt; i++) _out_word( (handle) + (reg), (addr)[i]);
}
static inline void bus_space_do_write_multi_4(u_long handle, unsigned reg, unsigned long *addr, int cnt)
{
int i; for (i=0; i<cnt; i++) _out_long( (handle) + (reg), (addr)[i]);
}
#define bus_space_write_multi_1(tag, handle, reg, addr, cnt) \
bus_space_do_write_multi_1(handle, reg, addr, cnt)
#define bus_space_write_multi_2(tag, handle, reg, addr, cnt) \
bus_space_do_write_multi_2(handle, reg, addr, cnt)
#define bus_space_write_multi_4(tag, handle, reg, addr, cnt) \
bus_space_do_write_multi_4(handle, reg, addr, cnt)
static inline void bus_space_do_read_multi_1(u_long handle, unsigned reg, unsigned char *addr, int cnt)
{
int i; for (i=0; i<cnt; i++)
(addr)[i] = _inp_byte((volatile unsigned char*)((handle)+(reg)));
}
static inline void bus_space_do_read_multi_2(u_long handle, unsigned reg, unsigned short *addr, int cnt)
{
int i; for (i=0; i<cnt; i++)
(addr)[i] = _inp_word((volatile unsigned short*)((handle)+(reg)));
}
static inline void bus_space_do_read_multi_4(u_long handle, unsigned reg, unsigned long *addr, int cnt)
{
int i; for (i=0; i<cnt; i++)
(addr)[i] = _inp_long((volatile unsigned *)((handle)+(reg)));
}
#define bus_space_read_multi_1(tag, handle, reg, addr, cnt) \
bus_space_do_read_multi_1(handle, reg, addr, cnt)
#define bus_space_read_multi_2(tag, handle, reg, addr, cnt) \
bus_space_do_read_multi_2(handle, reg, addr, cnt)
#define bus_space_read_multi_4(tag, handle, reg, addr, cnt) \
bus_space_do_read_multi_4(handle, reg, addr, cnt)
#define bus_space_write_1(tag, handle, reg, val) \
do { _out_byte( (handle) + (reg), (val)); } while (0)
#define bus_space_write_2(tag, handle, reg, val) \
do { _out_word( (handle) + (reg), (val)); } while (0)
#define bus_space_write_4(tag, handle, reg, val) \
do { _out_long( (handle) + (reg), (val)); } while (0)
#define BPF_MTAP(a,b) do { } while (0)
extern unsigned net_driver_ticks_per_sec;
#ifdef __PPC__
/* PPC has a timebase - based delay */
#define DELAY(n) do { \
if ( (n) > 10000 ) \
rtems_task_wake_after((((n)*net_driver_ticks_per_sec)/1000000) + 1); \
else \
rtems_bsp_delay(n); \
} while (0)
#else
#warning "Have no good usec delay implementation"
#define DELAY(n) do { \
rtems_task_wake_after((((n)*net_driver_ticks_per_sec)/1000000) + 1); \
} while (0)
#endif
#define IRQ_LOCKED(code) \
do { unsigned long _xtre_irq_flags; \
rtems_interrupt_disable(_xtre_irq_flags); \
do { code } while(0); \
rtems_interrupt_enable(_xtre_irq_flags); \
} while (0)
typedef struct _netdev_t *device_t;
typedef void (driver_intr_t)(void *);
#define if_xname if_name
/* need to replace those with LOCAL2PCI() and make sure the bus handle is initialized
* (on most BSPs we get away with PCI_DRAM_OFFSET [no bus handle needed at all]
*/
#ifndef PCI_DRAM_OFFSET
#define PCI_DRAM_OFFSET 0
#endif
#ifndef PCI_MEM_BASE
#define PCI_MEM_BASE 0
#endif
#define kvtop(a) ((unsigned long)(a) + PCI_DRAM_OFFSET)
#define vtophys(a) ((unsigned long)(a) + PCI_DRAM_OFFSET)
#define PCI2LOCAL(a,bus) ((unsigned long)(a) + PCI_MEM_BASE)
#ifdef PCI0_IO_BASE /* special mvme5500 hack :-( */
#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + PCI0_IO_BASE)
#elif defined(PCI_IO_BASE)
#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + PCI_IO_BASE)
#elif defined(_IO_BASE)
#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a) + _IO_BASE)
#else
#warning "Unable to determine base address of PCI IO space; using ZERO"
#define PCI_IO_2LOCAL(a,bus) ((unsigned long)(a))
#endif
#define if_printf(if,fmt,args...) printf("%s:"fmt,(if)->if_name,args)
#ifndef BUS_PROBE_DEFAULT
#define BUS_PROBE_DEFAULT 0
#endif
static inline void *
contigmalloc(
unsigned long size,
int type,
int flags,
unsigned long lo,
unsigned long hi,
unsigned long align,
unsigned long bound)
{
void *ptr = rtems_bsdnet_malloc(size + sizeof(ptr) + align-1, type, flags);
char *rval = 0;
if ( ptr ) {
unsigned tmp = (unsigned)ptr + align - 1;
tmp -= tmp % align;
rval = (char*)tmp;
/* save backlink */
*(void**)(rval+size) = ptr;
}
return rval;
}
static inline void
contigfree(void *ptr, size_t size, int type)
{
rtems_bsdnet_free( *(void**)((unsigned)ptr + size), type);
}
/* callout stuff */
#define callout_init(args...) do {} while (0);
#define callout_reset(args...) do {} while (0);
#define callout_stop(args...) do {} while (0);
#define IFQ_DRV_IS_EMPTY(q) (0 == (q)->ifq_head)
#define IFQ_DRV_DEQUEUE(q,m) IF_DEQUEUE((q),(m))
#define IFQ_DRV_PREPEND(q,m) IF_PREPEND((q),(m))
#define DO_ETHER_INPUT_SKIPPING_ETHER_HEADER(ifp,m) \
{ struct ether_header *eh; \
eh = mtod(m, struct ether_header*); \
m->m_data += sizeof(struct ether_header); \
m->m_len -= sizeof(struct ether_header); \
m->m_pkthdr.len -= sizeof(struct ether_header); \
m->m_pkthdr.rcvif = ifp; \
ether_input(ifp, eh, m); \
} while (0)
#ifndef __KERNEL_RCSID
#define __KERNEL_RCSID(arg...)
#endif
#endif

View File

@@ -0,0 +1,219 @@
#ifndef RTEMS_COMPAT1_BSD_NET_H
#define RTEMS_COMPAT1_BSD_NET_H
/* BSD -> RTEMS conversion wrappers; stuff that must be defined
* after most BSD headers are included.
*/
#include <netinet/in.h>
#include <netinet/if_ether.h>
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
typedef struct _netdev_t {
struct NET_SOFTC d_softc; /* MUST BE FIRST FIELD */
char *d_name;
char *d_desc;
int d_unit;
int flags;
/* pointer to ifconfig only valid during excution of
* the n_attach/n_detach methods (see below)
*/
struct rtems_bsdnet_ifconfig *d_ifconfig;
} netdev_t;
#define THEDEVS NET_EMBEMB(the_,NETDRIVER_PREFIX,_devs)
#define NETDEV_DECL netdev_t THEDEVS[NETDRIVER_SLOTS]
extern NETDEV_DECL;
typedef struct _net_drv_tbl {
int (*n_probe)(device_t);
int (*n_attach)(device_t);
int (*n_detach)(device_t);
void (*n_intr)(void *);
} net_drv_tbl_t;
static inline netdev_t *
net_dev_get(struct rtems_bsdnet_ifconfig *config)
{
int unitNo;
char *unitName;
unitNo = rtems_bsdnet_parse_driver_name(config, &unitName);
if ( unitNo < 0 )
return 0;
if ( unitNo <=0 || unitNo > NETDRIVER_SLOTS ) {
device_printf(dev, "Bad "NETDRIVER" unit number.\n");
return 0;
}
if ( THEDEVS[unitNo-1].d_unit && THEDEVS[unitNo-1].d_unit != unitNo ) {
device_printf(dev, "Unit # mismatch !!??\n");
return 0;
}
THEDEVS[unitNo-1].d_unit = unitNo;
THEDEVS[unitNo-1].d_name = unitName;
THEDEVS[unitNo-1].d_ifconfig = config;
return &THEDEVS[unitNo - 1];
}
/* kludge; that's why softc needs to be first */
static inline netdev_t *
softc_get_device(struct NET_SOFTC *sc)
{
return (netdev_t *)sc;
}
static inline struct NET_SOFTC *
device_get_softc(netdev_t *dev)
{ return &dev->d_softc; }
static inline int
device_get_unit(netdev_t *dev)
{ return dev->d_unit; }
static inline char *
device_get_name(netdev_t *dev)
{ return dev->d_name; }
static inline void
if_initname(struct ifnet *ifp, char *name, int unit)
{
ifp->if_name = name;
ifp->if_unit = unit;
}
static inline void
device_set_desc(netdev_t *dev, char *str)
{
dev->d_desc = str;
}
static inline void
device_set_desc_copy(netdev_t *dev, char *str)
{
dev->d_desc = strdup(str);
}
static inline int
device_is_attached(netdev_t *dev)
{
return dev->d_softc.arpcom.ac_if.if_addrlist && dev->d_softc.arpcom.ac_if.if_init;
}
#ifdef NETDRIVER_PCI
#include NETDRIVER_PCI
#include <pcireg.h>
static inline unsigned
pci_read_config(device_t dev, unsigned addr, unsigned width)
{
rtemscompat_32_t d;
unsigned short s;
unsigned char b;
struct NET_SOFTC *sc = device_get_softc(dev);
switch (width) {
case 1: pci_read_config_byte(sc->b, sc->d, sc->f, addr, &b);
return b;
case 2: pci_read_config_word(sc->b, sc->d, sc->f, addr, &s);
return s;
case 4: pci_read_config_dword(sc->b, sc->d, sc->f, addr, &d);
return d;
default:
break;
}
return 0xdeadbeef;
}
static inline void
pci_write_config(device_t dev, unsigned addr, unsigned width, unsigned val)
{
struct NET_SOFTC *sc = device_get_softc(dev);
switch (width) {
case 1: pci_write_config_byte(sc->b, sc->d, sc->f, addr, val);
return ;
case 2: pci_write_config_word(sc->b, sc->d, sc->f, addr, val);
return ;
case 4: pci_write_config_dword(sc->b, sc->d, sc->f, addr, val);
return ;
default:
break;
}
}
static inline unsigned short
pci_get_vendor(device_t dev)
{
return pci_read_config(dev, PCIR_VENDOR, 2);
}
static inline unsigned short
pci_get_device(device_t dev)
{
return pci_read_config(dev, PCIR_DEVICE, 2);
}
static inline unsigned short
pci_get_subvendor(device_t dev)
{
return pci_read_config(dev, PCIR_SUBVEND_0, 2);
}
static inline unsigned short
pci_get_subdevice(device_t dev)
{
return pci_read_config(dev, PCIR_SUBDEV_0, 2);
}
static inline void
pci_enable_busmaster(device_t dev)
{
pci_write_config(
dev,
PCIR_COMMAND,
2,
pci_read_config(dev, PCIR_COMMAND, 2)
| PCIM_CMD_BUSMASTEREN);
}
#define mtx_init(a,b,c,d) do {} while(0)
#define mtx_initialized(ma) (1)
#define mtx_destroy(ma) do {} while(0)
#define mtx_lock(a) do {} while(0)
#define mtx_unlock(a) do {} while(0)
#define mtx_assert(a,b) do {} while(0)
#define callout_handle_init(x) do {} while (0)
#define untimeout(a...) do {} while (0)
#if !ISMINVERSION(4,6,99)
#define pci_bus_count BusCountPCI
#endif
#endif
/* Ugly hack to allow unloading/reloading the driver core.
* Needed because rtems' bsdnet release doesn't implement
* if_detach(). Therefore, we bring the interface down but
* keep the device record alive...
*/
static inline void
__ether_ifdetach(struct ifnet *ifp)
{
ifp->if_flags = 0;
ifp->if_ioctl = 0;
ifp->if_start = 0;
ifp->if_watchdog = 0;
ifp->if_init = 0;
}
#endif

View File

@@ -0,0 +1,97 @@
#ifndef RTEMS_COMPAT_DEFS_H
#define RTEMS_COMPAT_DEFS_H
/* Symbol definitions for a particular driver */
/* Copyright: Till Straumann <strauman@slac.stanford.edu>, 2005;
* License: see LICENSE file.
*/
/* Number of device instances the driver should support
* - may be limited to 1 depending on IRQ API
* (braindamaged PC586 and powerpc)
*/
#define NETDRIVER_SLOTS 1
/* String name to print with error messages */
#define NETDRIVER "PCN"
/* Name snippet used to make global symbols unique to this driver */
#define NETDRIVER_PREFIX pcn
/* Define according to endianness of the *ethernet*chip*
* (not the CPU - most probably are LE)
* This must be either NET_CHIP_LE or NET_CHIP_BE
*/
#define NET_CHIP_LE
#undef NET_CHIP_BE
/* Define either NET_CHIP_MEM_IO or NET_CHIP_PORT_IO,
* depending whether the CPU sees it in memory address space
* or (e.g. x86) uses special I/O instructions.
*/
#define NET_CHIP_MEM_IO
#undef NET_CHIP_PORT_IO
/* The name of the hijacked 'bus handle' field in the softc
* structure. We use this field to store the chip's base address.
*/
#define NET_SOFTC_BHANDLE_FIELD pcn_bhandle
/* define the names of the 'if_XXXreg.h' and 'if_XXXvar.h' headers
* (only if present, i.e., if the BSDNET driver has no respective
* header, leave this undefined).
*
*/
#undef IF_REG_HEADER <if_XXXreg.h>
#undef IF_VAR_HEADER <if_XXXvar.h>
/* define if a pci device */
#define NETDRIVER_PCI <bsp/pci.h>
/* Macros to disable and enable interrupts, respectively.
* The 'disable' macro is expanded in the ISR, the 'enable'
* macro is expanded in the driver task.
* The global network semaphore usually provides mutex
* protection of the device registers.
* Special care must be taken when coding the 'disable' macro,
* however to MAKE SURE THERE ARE NO OTHER SIDE EFFECTS such
* as:
* - macro must not clear any status flags
* - macro must save/restore any context information
* (e.g., a address register pointer or a bank switch register)
*
* ARGUMENT: the macro arg is a pointer to the driver's 'softc' structure
*/
/* Here EXAMPLES for the pcnet chip which addresses registers indirectly
* through a 'address-pointer' (RAP) and 'data-port' (RDP) register pair:
#define NET_DISABLE_IRQS(sc) do { \
unsigned rap = CSR_READ_4((sc),PCN_IO32_RAP); \
unsigned val; \
CSR_WRITE_4((sc),PCN_IO32_RAP,PCN_CSR_CSR); \
val = CSR_READ_4((sc),PCN_IO32_RDP); \
CSR_WRITE_4((sc), PCN_IO32_RDP, val & ~(CSR0_INT_STATUS_MASK | PCN_CSR_INTEN)); \
CSR_WRITE_4((sc), PCN_IO32_RAP, rap); \
} while (0)
#define NET_ENABLE_IRQS(sc) do { \
unsigned flags,val; \
rtems_interrupt_disable(flags); \
CSR_WRITE_4((sc),PCN_IO32_RAP,PCN_CSR_CSR); \
val = CSR_READ_4((sc),PCN_IO32_RDP); \
CSR_WRITE_4((sc), PCN_IO32_RDP, (val & ~CSR0_INT_STATUS_MASK) | PCN_CSR_INTEN); \
rtems_interrupt_enable(flags); \
} while (0)
*/
/* Driver may provide a macro/function to copy the hardware address
* from the device into 'softc.arpcom'.
* If this is undefined, the driver must to the copy itself.
* Preferrably, it should check soft.arpcom.ac_enaddr for all
* zeros and leave it alone if it is nonzero, i.e., write it
* to the hardware.
#define NET_READ_MAC_ADDR(sc)
*/
#define KASSERT(a...) do {} while (0)
#endif

View File

@@ -0,0 +1,468 @@
/* $Id$ */
/* BSP specific wrapper for rtems_bsdnet_attach(). This wrapper
* dispatches to the correct driver attach routine depending on
* the board type, boot parameters, link status etc.
*
* Also, it performs board-specific setup of driver parameters
* (such as ethernet address, base addresses and the like)
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <bsp/pci.h>
#include <bsp/early_enet_link_status.h>
#include <bsp/if_mve_pub.h>
#include <bsp/if_gfe_pub.h>
#include <bsp/if_em_pub.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define IS_6100() (MVME6100 == BSP_getBoardType())
#define IS_5500() (MVME5500 == BSP_getBoardType())
static int bsp_gfe_attach(struct rtems_bsdnet_ifconfig *, int);
static int mvme5500_em_attach (struct rtems_bsdnet_ifconfig *, int);
static int mvme5500_em_find_onboard_unit(void);
char BSP_auto_network_driver_name[20] = {0,};
static BSP_NetIFDescRec mvme6100_netifs[] = {
{
name: "mve1",
description: "MV64360 built-in 10/100/1000 Ethernet 1",
attach_fn: rtems_mve_attach
},
{
name: "mve2",
description: "MV64360 built-in 10/100/1000 Ethernet 2",
attach_fn: rtems_mve_attach
},
{
name: 0,
}
};
static BSP_NetIFDescRec mvme5500_netifs[] = {
{
name: "em1",
description: "Intel 82544 on-board 10/100/1000 Ethernet (port 1)",
attach_fn: mvme5500_em_attach,
},
{
name: "gfe1",
description: "GT64260 built-in 10/100 Ethernet (port 2)",
attach_fn: bsp_gfe_attach,
},
{
name: 0,
}
};
/* wrap the 'gfe' and 'em' attach functions.
* RATIONALE: 'rtems_gfe_attach()' and 'rtems_em_attach()' are
* *chip* specific functions. However, they require
* some *board* specific parameter setup prior to
* being attached which is what these wrappers do...
*/
static unsigned em_info[];
static int scan4irqLine(int bus, int dev, int fn, void *uarg)
{
unsigned char byte;
unsigned short word;
int i;
/* count the number of 82544 we find */
pci_read_config_word(bus, dev, fn, PCI_VENDOR_ID, &word);
if ( 0x8086 != word )
return 0;
pci_read_config_word(bus, dev, fn, PCI_DEVICE_ID, &word);
for ( i = 0; em_info[i]; i++ ) {
if ( em_info[i] == word )
break;
}
if ( !em_info[i] )
return 0;
/* found a candidate; bump unit number */
(*(int *)uarg)++;
pci_read_config_byte(bus, dev, fn, PCI_INTERRUPT_LINE, &byte);
/* On the mvme5500 the 82544 is hooked to GPP IRQ 20 */
return ( BSP_IRQ_GPP_0 + 20 == byte ) ? 1 : 0;
}
/* Setup only once */
static void
onboard_em_setup_once(void)
{
static char done = 0;
/* If scanning didn't do anything, passing 0 will setup all interfaces */
if ( !done
&& rtems_em_pci_setup( mvme5500_em_find_onboard_unit() > 0 ) ) {
done=1;
}
}
static void
onboard_gfe_setup_once(void)
{
static char done = 0;
/* must setup HW address -- note that the label on the
* board indicates that the gfe is the second interface
* but motLoad etc. interprets the order actually
* the other way round...
*/
if ( !done
&& rtems_gfe_setup( 1, BSP_enetAddr0, BSP_MV64x60_BASE ) > 0 ) {
done=1;
}
}
/* Find the unit number of the on-board 82544 (even if there is another one
* plugged into PMC...
*
* RETURNS: unit # (>0) or zero if nothing at all was found. (New board rev.
* with the 82544 hooked to a different IRQ line, new PCI device ID,
* ...)
*/
static int
mvme5500_em_find_onboard_unit(void)
{
int unit = 0;
void *h;
/* Determine the on-board 'em' adapter; we know it's interrupt line :-) */
for ( h=0; (h=BSP_pciScan(h, scan4irqLine, &unit)); )
/* nothing else to do */;
return h ? unit : 0;
}
static int
mvme5500_em_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
{
if ( attaching ) {
onboard_em_setup_once();
/* Make sure there is no conflict in MAC address -- see below
* why we 'swap' the addresses. (We actually don't but swap the
* order of the interfaces so they match the label.)
*/
if ( !ifcfg->hardware_address )
ifcfg->hardware_address = BSP_enetAddr1;
}
return rtems_em_attach(ifcfg, attaching);
}
static int
bsp_gfe_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
{
if ( attaching ) {
onboard_gfe_setup_once();
}
return rtems_gfe_attach(ifcfg, attaching);
}
BSP_NetIFDesc
BSP_availableNetIFs(void)
{
if ( IS_6100() )
return mvme6100_netifs;
if ( IS_5500() )
return mvme5500_netifs;
fprintf(stderr,"BSP_availableNetIFs() -- productIdent not set? unable to identify board type\n");
return 0;
}
typedef int (*read_op_t)(int,unsigned);
typedef int (*write_op_t)(int,unsigned,unsigned);
struct poll_job {
read_op_t rdop;
write_op_t wrop;
int unit;
};
static int
check_phys(struct poll_job *job)
{
struct poll_job *j;
int rval = -2;
for ( j=job; j->rdop; j++ ) {
unsigned w;
w = j->rdop(j->unit, 1/*status*/);
if ( 0x04 & w ) /* active link */
return j-job;
if ( !(0x20 & w) ) /* aneg not done */
rval = -1;
}
return rval;
}
/* check a number of phys
* RETURNS: -1 if at least one is still busy
* -2 if all are terminated but no link is found
* >=0 index of first IF with a live link
*/
static int
poll_phys(struct poll_job *job)
{
int rval;
struct poll_job *j = job;
int retry = 4;
/* see if we already have a link */
if ( (rval=check_phys(job)) < 0 ) {
/* no - start negotiation */
for ( j = job; j->rdop; j++ ) {
j->wrop(j->unit, 0/* ctrl */, 0x1200 /* start aneg */);
}
do {
sleep(1);
} while ( -1 == (rval = check_phys(job)) && retry-- );
}
return rval;
}
/* note that detaching is not supported by the current version of the BSD stack */
int
BSP_auto_enet_attach(struct rtems_bsdnet_ifconfig *ifcfg, int attaching)
{
int i = -1;
BSP_NetIFDesc d = BSP_availableNetIFs();
struct poll_job job[3];
if ( !d )
return -1;
/* If they pass a name, find the attach fn */
if ( ifcfg->name && RTEMS_BSP_NETWORK_DRIVER_NAME != ifcfg->name && attaching ) {
for (i = 0; d[i].name; i++ ) {
if ( !strcmp(d[i].name, ifcfg->name) ) {
ifcfg->attach = d[i].attach_fn;
break;
}
}
if ( !d[i].name ) {
fprintf(stderr,"WARNING: have no '%s' interface - using default\n", ifcfg->name);
ifcfg->name = 0;
}
}
if ( !ifcfg->name || ifcfg->name == RTEMS_BSP_NETWORK_DRIVER_NAME ) {
/* automatically choose and attach an interface */
if ( RTEMS_BSP_NETWORK_DRIVER_NAME[0] ) {
fprintf(stderr,
"Configuration error: 'auto' network if already chosen (%s)\n",
RTEMS_BSP_NETWORK_DRIVER_NAME);
return -1;
}
if ( IS_6100() ) {
#define ops rtems_mve_early_link_check_ops
assert(ops.num_slots >= 2);
ops.init(0);
ops.init(1);
job[0].rdop = ops.read_phy;
job[0].wrop = ops.write_phy;
job[0].unit = 0;
job[1].rdop = ops.read_phy;
job[1].wrop = ops.write_phy;
job[1].unit = 1;
#undef ops
} else if ( IS_5500() ) {
#define opsgfe rtems_gfe_early_link_check_ops
#define opsem rtems_em_early_link_check_ops
assert(opsgfe.num_slots >= 1);
onboard_gfe_setup_once();
opsgfe.init(0);
assert(opsem.num_slots >= 1);
onboard_em_setup_once();
opsem.init(0);
job[0].rdop = opsem.read_phy;
job[0].wrop = opsem.write_phy;
job[0].unit = 0;
job[1].rdop = opsgfe.read_phy;
job[1].wrop = opsgfe.write_phy;
job[1].unit = 0;
#undef opsgfe
#undef opsem
}
job[2].rdop = 0; /* tag end */
i = poll_phys(job);
if ( i >= 0 ) {
printf("L");
} else {
i = 0;
printf("No l");
}
printf("ink detected; attaching %s\n",d[i].name);
/* set attach function and IF name */
ifcfg->attach = d[i].attach_fn;
ifcfg->name = RTEMS_BSP_NETWORK_DRIVER_NAME;
strcpy(RTEMS_BSP_NETWORK_DRIVER_NAME, d[i].name);
}
return ifcfg->attach(ifcfg, attaching);
}
/* from 'em' */
/* PCI Device IDs */
#define E1000_DEV_ID_82542 0x1000
#define E1000_DEV_ID_82543GC_FIBER 0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER 0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM 0x100D
#define E1000_DEV_ID_82540EM 0x100E
#define E1000_DEV_ID_82541ER_LOM 0x1014
#define E1000_DEV_ID_82540EM_LOM 0x1015
#define E1000_DEV_ID_82540EP_LOM 0x1016
#define E1000_DEV_ID_82540EP 0x1017
#define E1000_DEV_ID_82540EP_LP 0x101E
#define E1000_DEV_ID_82545EM_COPPER 0x100F
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82545GM_COPPER 0x1026
#define E1000_DEV_ID_82545GM_FIBER 0x1027
#define E1000_DEV_ID_82545GM_SERDES 0x1028
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EI_MOBILE 0x1018
#define E1000_DEV_ID_82541ER 0x1078
#define E1000_DEV_ID_82547GI 0x1075
#define E1000_DEV_ID_82541GI 0x1076
#define E1000_DEV_ID_82541GI_MOBILE 0x1077
#define E1000_DEV_ID_82541GI_LF 0x107C
#define E1000_DEV_ID_82546GB_COPPER 0x1079
#define E1000_DEV_ID_82546GB_FIBER 0x107A
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019
#define E1000_DEV_ID_82547EI_MOBILE 0x101A
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
static unsigned em_info[] =
{
/* Intel(R) PRO/1000 Network Connection */
E1000_DEV_ID_82540EM,
E1000_DEV_ID_82540EM_LOM,
E1000_DEV_ID_82540EP,
E1000_DEV_ID_82540EP_LOM,
E1000_DEV_ID_82540EP_LP,
E1000_DEV_ID_82541EI,
E1000_DEV_ID_82541ER,
E1000_DEV_ID_82541ER_LOM,
E1000_DEV_ID_82541EI_MOBILE,
E1000_DEV_ID_82541GI,
E1000_DEV_ID_82541GI_LF,
E1000_DEV_ID_82541GI_MOBILE,
E1000_DEV_ID_82542,
E1000_DEV_ID_82543GC_FIBER,
E1000_DEV_ID_82543GC_COPPER,
E1000_DEV_ID_82544EI_COPPER,
E1000_DEV_ID_82544EI_FIBER,
E1000_DEV_ID_82544GC_COPPER,
E1000_DEV_ID_82544GC_LOM,
E1000_DEV_ID_82545EM_COPPER,
E1000_DEV_ID_82545EM_FIBER,
E1000_DEV_ID_82545GM_COPPER,
E1000_DEV_ID_82545GM_FIBER,
E1000_DEV_ID_82545GM_SERDES,
E1000_DEV_ID_82546EB_COPPER,
E1000_DEV_ID_82546EB_FIBER,
E1000_DEV_ID_82546EB_QUAD_COPPER,
E1000_DEV_ID_82546GB_COPPER,
E1000_DEV_ID_82546GB_FIBER,
E1000_DEV_ID_82546GB_SERDES,
E1000_DEV_ID_82546GB_PCIE,
E1000_DEV_ID_82546GB_QUAD_COPPER,
E1000_DEV_ID_82547EI,
E1000_DEV_ID_82547EI_MOBILE,
E1000_DEV_ID_82547GI,
E1000_DEV_ID_82573E,
E1000_DEV_ID_82573E_IAMT,
/* required last entry */
0,
};

View File

@@ -0,0 +1,80 @@
/* $Id$ */
#ifndef BSP_BSDNET_ATTACH_INFO_H
#define BSP_BSDNET_ATTACH_INFO_H
/* Author: Till Straumann, 2005; see ../../LICENSE */
/* Rationale: traditionally, BSPs only supported a single networking interface
* the BSP defined RTEMS_NETWORK_DRIVER_NAME & friends macros
* for applications to use.
* If more than one interface is present, this simple approach is
* not enough.
* Hence, this BSP exports a routine declaring all available interfaces
* so the application can make a choice.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Fwd. decl just in case */
struct rtems_bsdnet_ifconfig;
typedef struct {
/* name of the interface */
const char *name;
/* optional description (to be used by chooser 'help' function etc.) */
const char *description;
/* driver 'attach' function */
int (*attach_fn)(struct rtems_bsdnet_ifconfig*, int);
} BSP_NetIFDescRec, *BSP_NetIFDesc;
/* Return a pointer to the (static) list of network interface descriptions
* of this board.
*
* NOTES: A NULL value is returned if e.g., the board type cannot be determined
* or for other reasons.
* The 'description' field is optional, i.e., may be NULL.
* The list is terminated by an element with a NULL name field.
* The interfaces are listed in the order they are labelled.
*/
BSP_NetIFDesc
BSP_availableNetIFs();
/* Define this macro so applications can conditionally compile this API */
#define BSP_HAS_MULTIPLE_NETIFS(x) BSP_availableNetIFs()
/* Legacy macro; applications should use BSP_Available_NetIfs() to choose
* an interface and attach function.
*/
extern char BSP_auto_network_driver_name[20];
#define RTEMS_BSP_NETWORK_DRIVER_NAME BSP_auto_network_driver_name
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH BSP_auto_enet_attach
/* This routine checks the name field passed in the 'ifconfig'.
* If the name is NULL or points to the BSP_auto_network_driver_name
* array, the routine checks all interfaces for an active link and
* attaches the first alive one.
* It also updates 'ifconfig' to reflect the chosen interface's name
* and attach function.
*
* If another name is passed in, the routine scans
* the available interfaces for that name and uses it, if found.
* Eventually, a default interface is chosen (provided that
* the board type is successfully detected).
*
* Note that only ONE interface chained into rtems_bsdnet_config
* may use the "auto" name.
*
*/
int
BSP_auto_enet_attach(struct rtems_bsdnet_ifconfig *ifconfig, int attaching);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,31 @@
/*$Id$*/
#ifndef BSP_EARLY_ENET_LINK_STATUS_H
#define BSP_EARLY_ENET_LINK_STATUS_H
/* Determine link status of ethernet device before network is initialized */
/* T. Straumann, 2005; see ../../LICENSE */
#include <rtems.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int (*init)(int idx); /* perform enough initialization to access (default) phy */
int (*read_phy)(int idx, unsigned reg);
int (*write_phy)(int idx, unsigned reg, unsigned val);
const char *name; /* driver name */
unsigned char num_slots; /* max number of supported devices */
unsigned char initialized; /* must be initialized to 0; */
} rtems_bsdnet_early_link_check_ops;
int
BSP_early_check_link_status(int unit, rtems_bsdnet_early_link_check_ops *ops);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,41 @@
/* $Id$ */
#include <rtems.h>
#include <bsp/early_enet_link_status.h>
#include <rtems/bspIo.h>
/* T. Straumann, 2005; see ../../LICENSE */
static const char *ename = ": rtems_em_early_check_link_status() - ";
int
BSP_early_check_link_status(int unit, rtems_bsdnet_early_link_check_ops *ops)
{
int status;
unit--;
if ( unit < 0 || unit >= ops->num_slots ) {
printk("%s%sinvalid unit # %i (not in %i..%i)\n",
ops->name, ename, unit+1, 1, ops->num_slots);
return -1;
}
if ( !ops->initialized ) {
if ( ops->init(unit) ) {
printk("%s%sFAILURE to init hardware\n",ops->name, ename);
return -1;
}
/* Start autoneg */
if ( ops->write_phy(unit, 0, 0x1200) ) {
printk("%s%sFAILURE to start autonegotiation\n",ops->name, ename);
return -1;
}
/* Dont wait here; the caller can do this on various interfaces
* and wait herself.
*/
ops->initialized = 1;
}
if ( (status = ops->read_phy(unit, 1)) < 0 ) {
printk("%s%sFAILURE to read phy status\n", ops->name, ename);
}
return status;
}

View File

@@ -0,0 +1,274 @@
/* $Id$ */
/* PCI configuration space access */
/*
* Acknowledgements:
* Valuable information was obtained from the following drivers
* netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
* linux: (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
* rtems: (C) Brookhaven National Laboratory; K. Feng
*/
/*
* Original file header of libbsp/shared/pci.c where this file is based upon.
*
* Copyright (C) 1999 valette@crf.canon.fr
*
* This code is heavily inspired by the public specification of STREAM V2
* that can be found at :
*
* <http://www.chorus.com/Documentation/index.html> by following
* the STREAM API Specification Document link.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*
* Till Straumann, <strauman@slac.stanford.edu>, 1/2002
* - separated bridge detection code out of this file
*/
#include <rtems.h>
#include <bsp.h>
#include <libcpu/io.h>
#include <bsp/pci.h>
#include <rtems/bspIo.h>
#include <stdint.h>
/* set to max so we get early access to hose 0 */
unsigned BSP_pci_hose1_bus_base = (unsigned)-1;
#define MV64x60_PCI0_CONFIG_ADDR (BSP_MV64x60_BASE + 0xcf8)
#define MV64x60_PCI0_CONFIG_DATA (BSP_MV64x60_BASE + 0xcfc)
#define MV64x60_PCI1_CONFIG_ADDR (BSP_MV64x60_BASE + 0xc78)
#define MV64x60_PCI1_CONFIG_DATA (BSP_MV64x60_BASE + 0xc7c)
#define PCI_BUS2HOSE(bus) (bus<BSP_pci_hose1_bus_base?0:1)
void detect_host_bridge(void)
{
}
typedef struct {
volatile unsigned char *pci_config_addr;
volatile unsigned char *pci_config_data;
} PciHoseCfg;
static PciHoseCfg hoses[2] = {
{
pci_config_addr: (volatile unsigned char *)(MV64x60_PCI0_CONFIG_ADDR),
pci_config_data: (volatile unsigned char *)(MV64x60_PCI0_CONFIG_DATA),
},
{
pci_config_addr: (volatile unsigned char *)(MV64x60_PCI1_CONFIG_ADDR),
pci_config_data: (volatile unsigned char *)(MV64x60_PCI1_CONFIG_DATA),
}
};
#define pci hoses[hose]
#define HOSE_PREAMBLE \
uint8_t hose; \
if (bus < BSP_pci_hose1_bus_base) { \
hose = 0; \
} else { \
hose = 1; \
bus -= BSP_pci_hose1_bus_base; \
}
/* Sigh; we have to copy those out from the shared area... */
static int
indirect_pci_read_config_byte(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint8_t *val) {
HOSE_PREAMBLE;
out_be32((volatile unsigned *) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
*val = in_8(pci.pci_config_data + (offset&3));
return PCIBIOS_SUCCESSFUL;
}
static int
indirect_pci_read_config_word(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint16_t *val) {
HOSE_PREAMBLE;
*val = 0xffff;
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
*val = in_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)));
return PCIBIOS_SUCCESSFUL;
}
static int
indirect_pci_read_config_dword(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint32_t *val) {
HOSE_PREAMBLE;
*val = 0xffffffff;
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
*val = in_le32((volatile unsigned *)pci.pci_config_data);
return PCIBIOS_SUCCESSFUL;
}
static int
indirect_pci_write_config_byte(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint8_t val) {
HOSE_PREAMBLE;
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
out_8(pci.pci_config_data + (offset&3), val);
return PCIBIOS_SUCCESSFUL;
}
static int
indirect_pci_write_config_word(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint16_t val) {
HOSE_PREAMBLE;
if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
out_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)), val);
return PCIBIOS_SUCCESSFUL;
}
static int
indirect_pci_write_config_dword(unsigned char bus, unsigned char slot,
unsigned char function,
unsigned char offset, uint32_t val) {
HOSE_PREAMBLE;
if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
out_be32((unsigned int*) pci.pci_config_addr,
0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
out_le32((volatile unsigned *)pci.pci_config_data, val);
return PCIBIOS_SUCCESSFUL;
}
const pci_config_access_functions pci_hosed_indirect_functions = {
indirect_pci_read_config_byte,
indirect_pci_read_config_word,
indirect_pci_read_config_dword,
indirect_pci_write_config_byte,
indirect_pci_write_config_word,
indirect_pci_write_config_dword
};
extern unsigned char ucMaxPCIBus; /* importing this is ugly */
/* This is a very ugly hack. I don't want to change the shared
* code to support multiple hoses so we hide everything under
* the hood with horrible kludges for now. Sorry.
*/
void
BSP_pci_initialize(void)
{
#if 0 /* These values are already set up for the shared/pci.c code */
{
extern pci_config_access_functions pci_indirect_functions;
/* by means of the PCI_CONFIG_ADDR/PCI_CONFIG_DATA macros (bsp.h) */
BSP_pci_configuration.pci_config_addr = hoses[0].pci_config_addr;
BSP_pci_configuration.pci_config_data = hoses[0].pci_config_data;
BSP_pci_configuration.pci_functions = &pci_indirect_functions;
}
#endif
/* initialize the first hose */
/* scan hose 0 and sets the maximum bus number */
pci_initialize();
/* remember the boundary */
BSP_pci_hose1_bus_base = pci_bus_count();
/* so far, so good -- now comes the cludgy part: */
/* hack/reset the bus count */
ucMaxPCIBus = 0;
/* scan hose 1 */
BSP_pci_configuration.pci_config_addr = hoses[1].pci_config_addr;
BSP_pci_configuration.pci_config_data = hoses[1].pci_config_data;
pci_initialize();
/* check for overflow of an unsigned char */
if ( BSP_pci_hose1_bus_base + pci_bus_count() > 255 ) {
BSP_panic("Too many PCI busses in the system");
}
/* readjust total number */
ucMaxPCIBus+=BSP_pci_hose1_bus_base;
/* install new access functions that can hide the hoses */
BSP_pci_configuration.pci_config_addr = (volatile unsigned char *)0xdeadbeef;
BSP_pci_configuration.pci_config_data = (volatile unsigned char *)0xdeadbeef;
BSP_pci_configuration.pci_functions = &pci_hosed_indirect_functions;
}
#define PCI_ERR_BITS 0xf900
#define PCI_STATUS_OK(x) (!((x)&PCI_ERR_BITS))
/* For now, just clear errors in the PCI status reg.
*
* Returns: (for diagnostic purposes)
* original settings (i.e. before applying the clearing
* sequence)
* (pci_status(hose_1)&0xff00) | ((pci_status(hose_2)>>8)&0xff)
*/
static unsigned long clear_hose_errors(int bus, int quiet)
{
unsigned long rval;
uint16_t pcistat;
int count;
int hose = PCI_BUS2HOSE(bus);
/* read error status for info return */
pci_read_config_word(bus,0,0,PCI_STATUS,&pcistat);
rval = pcistat;
count=10;
do {
/* clear error reporting registers */
/* clear PCI status register */
pci_write_config_word(bus,0,0,PCI_STATUS, PCI_ERR_BITS);
/* read new status */
pci_read_config_word(bus,0,0,PCI_STATUS, &pcistat);
} while ( ! PCI_STATUS_OK(pcistat) && count-- );
if ( !PCI_STATUS_OK(rval) && !quiet) {
printk("Cleared PCI errors at discovery (hose %i): pci_stat was 0x%04x\n", hose, rval);
}
if ( !PCI_STATUS_OK(pcistat) ) {
printk("Unable to clear PCI errors at discovery (hose %i) still 0x%04x after 10 attempts\n",hose, pcistat);
}
return rval;
}
unsigned short
(*_BSP_clear_vmebridge_errors)(int) = 0;
unsigned long
_BSP_clear_hostbridge_errors(int enableMCP, int quiet)
{
unsigned long rval;
/* MCP is not connected */
if ( enableMCP )
return -1;
rval = (clear_hose_errors(0, quiet) & PCI_ERR_BITS)>>8;
rval |= clear_hose_errors(BSP_pci_hose1_bus_base, quiet) & PCI_ERR_BITS;
/* Tsi148 doesn't propagate VME bus errors to PCI status reg. */
if ( _BSP_clear_vmebridge_errors )
rval |= _BSP_clear_vmebridge_errors(quiet)<<16;
return rval;
}

View File

@@ -0,0 +1,182 @@
/* $Id$ */
/* remap the zero-based PCI IO spaces of both hoses to a single
* address space
*
* This must be called AFTER to BSP_pci_initialize()
*/
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <bsp.h>
#include <libcpu/io.h>
#include <bsp/pci.h>
#include <bsp/irq.h>
#include <rtems/bspIo.h>
#include <bsp/gtreg.h>
#include "pci_io_remap.h"
static int
fixup_irq_line(int bus, int slot, int fun, void *uarg)
{
unsigned char line;
pci_read_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, &line);
if ( line < BSP_IRQ_GPP_0 ) {
pci_write_config_byte( bus, slot, fun, PCI_INTERRUPT_LINE, line + BSP_IRQ_GPP_0 );
}
return 0;
}
void BSP_motload_pci_fixup(void)
{
uint32_t b0,b1,r0,r1,lim,dis;
/* MotLoad on the mvme5500 and mvme6100 configures the PCI
* busses nicely, i.e., the values read from the memory address
* space BARs by means of PCI config cycles directly reflect the
* CPU memory map. Thus, the presence of two hoses is already hidden.
*
* Unfortunately, all PCI I/O addresses are 'zero-based' i.e.,
* a hose-specific base address would have to be added to
* the values read from config space.
*
* We fix this here so I/O BARs also reflect the CPU memory map.
*
* Furthermore, the mvme5500 uses
* f000.0000
* ..f07f.ffff for PCI-0 / hose0
*
* and
*
* f080.0000
* ..f0ff.0000 for PCI-1 / hose 0
*
* whereas the mvme6100 does it the other way round...
*/
b0 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Low_Decode) );
b1 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Low_Decode) );
r0 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap) );
r1 = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap) );
switch ( BSP_getDiscoveryVersion(0) ) {
case MV_64360:
/* In case of the MV64360 the 'limit' is actually a 'size'!
* Disable by setting special bits in the 'BAR disable reg'.
*/
dis = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL) );
/* disable PCI0 I/O and PCI1 I/O */
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis | (1<<9) | (1<<14) );
/* remap busses on hose 0; if the remap register was already set, assume
* that someone else [such as the bootloader] already performed the fixup
*/
if ( (b0 & 0xffff) && 0 == (r0 & 0xffff) ) {
rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xffff)<<16 );
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xffff) );
}
/* remap busses on hose 1 */
if ( (b1 & 0xffff) && 0 == (r1 & 0xffff) ) {
rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xffff)<<16 );
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xffff) );
}
/* re-enable */
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + MV_64360_BASE_ADDR_DISBL), dis );
break;
case GT_64260_A:
case GT_64260_B:
if ( (b0 & 0xfff) && 0 == (r0 & 0xfff) ) { /* base are only 12 bits */
/* switch window off by setting the limit < base */
lim = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode) );
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), 0 );
/* remap busses on hose 0 */
rtems_pci_io_remap( 0, BSP_pci_hose1_bus_base, (b0 & 0xfff)<<20 );
/* BTW: it seems that writing the base register also copies the
* value into the 'remap' register automatically (??)
*/
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_Remap), (b0 & 0xfff) );
/* re-enable */
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI0_IO_High_Decode), lim );
}
if ( (b1 & 0xfff) && 0 == (r1 & 0xfff) ) { /* base are only 12 bits */
/* switch window off by setting the limit < base */
lim = in_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode) );
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), 0 );
/* remap busses on hose 1 */
rtems_pci_io_remap( BSP_pci_hose1_bus_base, pci_bus_count(), (b1 & 0xfff)<<20 );
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_Remap), (b1 & 0xfff) );
/* re-enable */
out_le32( (volatile unsigned*)(BSP_MV64x60_BASE + GT_PCI1_IO_High_Decode), lim );
}
break;
default:
BSP_panic("Unknown discovery version; switch in file: "__FILE__" not implemented (yet)");
break; /* never get here */
}
/* Fixup the IRQ lines; the mvme6100 maps them nicely into our scheme, i.e., GPP
* interrupts start at 64 upwards
*
* The mvme5500 is apparently initialized differently :-(. GPP interrupts start at 0
* Since all PCI interrupts are wired to GPP we simply check for a value < 64 and
* reprogram the interrupt line register.
*/
BSP_pciScan(0, fixup_irq_line, 0);
}

View File

@@ -0,0 +1,207 @@
/* $Id$ */
/* Adjust a PCI bus range's I/O address space by adding an offset */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#include <bsp/pci.h>
#include <stdint.h>
#ifndef PCI_MULTI_FUN
#define PCI_MULTI_FUN 0x80
#endif
#ifndef PCI_HEADER_TYPE_MSK
#define PCI_HEADER_TYPE_MSK 0x7f
#endif
/* Reconfigure all I/O base address registers for a range of PCI busses
* (from and including 'bus_from' up to and not including 'bus_to').
* adding an offset. This involves adjusting the base and limit registers
* of PCI-PCI bridges, too.
*
* RESTRICTIONS: 'offset' must be 4k aligned (PCI req.); no argument check
* on the bus numbers is done.
*
* RETURNS: 0 on success and a number > 0 indicating the number of
* non-32bit bridges found where the offset couldn't be added.
* Devices behind such a bridge are not accessible through I/O
* and should probably be switched off (not done by this code).
*/
int
rtems_pci_io_remap(int bus_from, int bus_to, uint32_t offset)
{
int rval = 0;
int bus, dev, fun, maxf;
int bar, numBars = 0;
uint8_t b;
uint16_t s;
uint32_t d;
unsigned int bas, lim;
if ( offset & ((1<<12)-1) ) {
BSP_panic("rtems_pci_io_remap(): offset must be 4k aligned");
return -1;
}
for ( bus=bus_from; bus < bus_to; bus++ ) {
for ( dev = 0; dev<PCI_MAX_DEVICES; dev++ ) {
maxf = 1;
for ( fun = 0; fun < maxf; fun++ ) {
pci_read_config_word( bus, dev, fun, PCI_VENDOR_ID, &s );
if ( 0xffff == s )
continue;
pci_read_config_byte( bus, dev, fun, PCI_HEADER_TYPE, &b );
/* readjust the max. function number to scan if this is a multi-function
* device.
*/
if ( 0 == fun && (PCI_MULTI_FUN & b) )
maxf = PCI_MAX_FUNCTIONS;
/* Check the header type; panic if unknown.
* header type 0 has 6 bars, header type 1 (PCI-PCI bridge) has 2
*/
b &= PCI_HEADER_TYPE_MSK;
switch ( b ) {
default:
printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
BSP_panic("rtems_pci_io_remap(): unknown PCI header type");
return -1; /* keep compiler happy */
case PCI_HEADER_TYPE_CARDBUS:
printk("PCI header type %i (@%i/%i/%i)\n", b, bus, dev, fun);
BSP_panic("rtems_pci_io_remap(): don't know how to deal with Cardbus bridge");
return -1;
case PCI_HEADER_TYPE_NORMAL:
numBars = 6*4; /* loop below counts reg. offset in bytes */
break;
case PCI_HEADER_TYPE_BRIDGE:
numBars = 2*4; /* loop below counts reg. offset in bytes */
break;
}
for ( bar = 0; bar < numBars; bar+=4 ) {
pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, &d );
if ( PCI_BASE_ADDRESS_SPACE_IO & d ) {
/* It's an I/O BAR; remap */
d &= PCI_BASE_ADDRESS_IO_MASK;
if ( d ) {
/* IO bar was configured; add offset */
d += offset;
pci_write_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0 + bar, d );
}
} else {
/* skip upper half of 64-bit window */
d &= PCI_BASE_ADDRESS_MEM_TYPE_MASK;
if ( PCI_BASE_ADDRESS_MEM_TYPE_64 == d )
bar+=4;
}
}
/* Now it's time to deal with bridges */
if ( PCI_HEADER_TYPE_BRIDGE == b ) {
/* must adjust the limit registers */
pci_read_config_byte( bus, dev, fun, PCI_IO_LIMIT, &b );
pci_read_config_word( bus, dev, fun, PCI_IO_LIMIT_UPPER16, &s );
lim = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
lim += offset;
pci_read_config_byte( bus, dev, fun, PCI_IO_BASE, &b );
pci_read_config_word( bus, dev, fun, PCI_IO_BASE_UPPER16, &s );
bas = (s<<16) + (( b & PCI_IO_RANGE_MASK ) << 8);
bas += offset;
b &= PCI_IO_RANGE_TYPE_MASK;
switch ( b ) {
default:
printk("Unknown IO range type 0x%x (@%i/%i/%i)\n", b, bus, dev, fun);
BSP_panic("rtems_pci_io_remap(): unknown IO range type");
return -1;
case PCI_IO_RANGE_TYPE_16:
if ( bas > 0xffff || lim > 0xffff ) {
printk("PCI I/O range type 1 (16bit) bridge (@%i/%i/%i) found:\n", bus, dev, fun);
printk("WARNING: base (0x%08x) or limit (0x%08x) exceed 16-bit;\n", bas, lim);
printk(" devices behind this bridge are NOT accessible!\n");
/* FIXME: should we disable devices behind this bridge ? */
bas = lim = 0;
}
break;
case PCI_IO_RANGE_TYPE_32:
break;
}
b = (uint8_t)((bas>>8) & PCI_IO_RANGE_MASK);
pci_write_config_byte( bus, dev, fun, PCI_IO_BASE, b );
s = (uint16_t)((bas>>16)&0xffff);
pci_write_config_word( bus, dev, fun, PCI_IO_BASE_UPPER16, s);
b = (uint8_t)((lim>>8) & PCI_IO_RANGE_MASK);
pci_write_config_byte( bus, dev, fun, PCI_IO_LIMIT, b );
s = (uint16_t)((lim>>16)&0xffff);
pci_write_config_word( bus, dev, fun, PCI_IO_LIMIT_UPPER16, s );
}
}
}
}
return rval;
}

View File

@@ -0,0 +1,66 @@
#ifndef RTEMS_PCI_IO_REMAP_H
#define RTEMS_PCI_IO_REMAP_H
/* Reconfigure all I/O base address registers for a range of PCI busses
* (from and including 'bus_from' up to and not including 'bus_to').
* adding an offset. This involves adjusting the base and limit registers
* of PCI-PCI bridges, too.
*
* RESTRICTIONS: 'offset' must be 4k aligned (PCI req.); no argument check
* on the bus numbers is done.
*
* RETURNS: 0 on success and a number > 0 indicating the number of
* non-32bit bridges found where the offset couldn't be added.
* Devices behind such a bridge are not accessible through I/O
* and should probably be switched off (not done by this code).
*/
int
rtems_pci_io_remap(int bus_from, int bus_to, uint32_t offset);
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#endif

View File

@@ -0,0 +1,188 @@
## Automatically generated by ampolish3 - Do not edit
if AMPOLISH3
$(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
PREINSTALL_DIRS =
DISTCLEANFILES += $(PREINSTALL_DIRS)
all-local: $(TMPINSTALL_FILES)
TMPINSTALL_FILES =
CLEANFILES += $(TMPINSTALL_FILES)
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES += $(PREINSTALL_FILES)
$(PROJECT_LIB)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_LIB)
@: > $(PROJECT_LIB)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
$(PROJECT_LIB)/rtems_crti.$(OBJEXT): rtems_crti.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
$(PROJECT_LIB)/motld_start.$(OBJEXT): motld_start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/motld_start.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/motld_start.$(OBJEXT)
$(PROJECT_LIB)/linkcmds: ../shared/startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
$(PROJECT_INCLUDE)/bsp/vpd.h: ../shared/motorola/vpd.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vpd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vpd.h
$(PROJECT_INCLUDE)/bsp/consoleIo.h: ../../powerpc/shared/console/consoleIo.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/consoleIo.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/consoleIo.h
$(PROJECT_INCLUDE)/bsp/uart.h: ../../powerpc/shared/console/uart.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/uart.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/uart.h
$(PROJECT_INCLUDE)/bsp/irq.h: irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/bsp/gtreg.h: marvell/gtreg.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gtreg.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gtreg.h
$(PROJECT_INCLUDE)/bsp/gtintrreg.h: marvell/gtintrreg.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gtintrreg.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gtintrreg.h
$(PROJECT_INCLUDE)/bsp/gti2creg.h: marvell/gti2creg.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gti2creg.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gti2creg.h
$(PROJECT_INCLUDE)/bsp/gti2c_busdrv.h: marvell/gti2c_busdrv.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gti2c_busdrv.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gti2c_busdrv.h
$(PROJECT_INCLUDE)/bsp/gt_timer.h: marvell/gt_timer.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gt_timer.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gt_timer.h
$(PROJECT_INCLUDE)/bsp/gtpcireg.h: marvell/gtpcireg.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gtpcireg.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gtpcireg.h
$(PROJECT_INCLUDE)/bsp/flashPgm.h: ../shared/flash/flashPgm.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/flashPgm.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/flashPgm.h
$(PROJECT_INCLUDE)/bsp/flashPgmPvt.h: ../shared/flash/flashPgmPvt.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/flashPgmPvt.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/flashPgmPvt.h
$(PROJECT_INCLUDE)/bsp/pci.h: ../../powerpc/shared/pci/pci.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pci.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pci.h
$(PROJECT_INCLUDE)/bsp/vectors.h: ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
$(PROJECT_INCLUDE)/bsp/irq_supp.h: ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq_supp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq_supp.h
$(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h: ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/ppc_exc_bspsupp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/ppc_exc_bspsupp.h
$(PROJECT_INCLUDE)/bsp/VMEConfig.h: vme/VMEConfig.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VMEConfig.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VMEConfig.h
$(PROJECT_INCLUDE)/bsp/vmeUniverse.h: ../../shared/vmeUniverse/vmeUniverse.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeUniverse.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeUniverse.h
$(PROJECT_INCLUDE)/bsp/vmeUniverseDMA.h: ../../shared/vmeUniverse/vmeUniverseDMA.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeUniverseDMA.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeUniverseDMA.h
$(PROJECT_INCLUDE)/bsp/vme_am_defs.h: ../../shared/vmeUniverse/vme_am_defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vme_am_defs.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vme_am_defs.h
$(PROJECT_INCLUDE)/bsp/vmeTsi148.h: ../../shared/vmeUniverse/vmeTsi148.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeTsi148.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeTsi148.h
$(PROJECT_INCLUDE)/bsp/vmeTsi148DMA.h: ../../shared/vmeUniverse/vmeTsi148DMA.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeTsi148DMA.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeTsi148DMA.h
$(PROJECT_INCLUDE)/bsp/bspVmeDmaList.h: ../../shared/vmeUniverse/bspVmeDmaList.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bspVmeDmaList.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bspVmeDmaList.h
$(PROJECT_INCLUDE)/bsp/VME.h: ../../shared/vmeUniverse/VME.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VME.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VME.h
$(PROJECT_INCLUDE)/bsp/VMEDMA.h: ../../shared/vmeUniverse/VMEDMA.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VMEDMA.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VMEDMA.h
if HAS_NETWORKING
$(PROJECT_INCLUDE)/bsp/early_enet_link_status.h: network/support/early_enet_link_status.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/early_enet_link_status.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/early_enet_link_status.h
$(PROJECT_INCLUDE)/bsp/bsp_bsdnet_attach.h: network/support/bsp_bsdnet_attach.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bsp_bsdnet_attach.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bsp_bsdnet_attach.h
$(PROJECT_INCLUDE)/bsp/if_mve_pub.h: network/if_mve/if_mve_pub.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/if_mve_pub.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/if_mve_pub.h
$(PROJECT_INCLUDE)/bsp/if_gfe_pub.h: network/if_gfe/if_gfe_pub.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/if_gfe_pub.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/if_gfe_pub.h
$(PROJECT_INCLUDE)/bsp/if_em_pub.h: network/if_em/if_em_pub.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/if_em_pub.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/if_em_pub.h
endif
$(PROJECT_INCLUDE)/tod.h: ../../shared/tod.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tod.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tod.h

View File

@@ -0,0 +1,11 @@
#include <bsp.h>
#include <rtems/bspIo.h>
void bsp_cleanup(void)
{
/* We can't go back to MotLoad since we blew it's memory area
* and vectors. Just pull the reset line...
*/
printk("bsp_cleanup(): RTEMS terminated -- no way back to MotLoad so I reset the card\n");
bsp_reset();
}

View File

@@ -0,0 +1,397 @@
/*
* This routine starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before this routine is invoked.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* Modified to support the MCP750.
* Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
*
* Modified to support the Synergy VGM & Motorola PowerPC boards.
* (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
*
* Modified to support the mvme5500 BSP
* (C) by Kate Feng <feng1@bnl.gov>, 2003, 2004
* under the contract DE-AC02-98CH10886 with the Deaprtment of Energy
*
* T. Straumann: 2005-2007; stolen again for 'beatnik'...
*/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <rtems/system.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <rtems/bspIo.h>
#include <rtems/powerpc/powerpc.h>
/*#include <bsp/consoleIo.h>*/
#include <libcpu/spr.h> /* registers.h is included here */
#include <bsp.h>
#include <bsp/uart.h>
#include <bsp/pci.h>
#include <bsp/gtreg.h>
#include <bsp/gt_timer.h>
#include <libcpu/bat.h>
#include <libcpu/pte121.h>
#include <libcpu/cpuIdent.h>
#include <bsp/vectors.h>
#include <bsp/vpd.h>
/* for RTEMS_VERSION :-( I dont like the preassembled string */
#include <rtems/sptables.h>
#ifdef __RTEMS_APPLICATION__
#undef __RTEMS_APPLICATION__
#endif
#define SHOW_MORE_INIT_SETTINGS
BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
extern char *BSP_build_date;
extern void bsp_cleanup(void);
extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
extern void BSP_pgtbl_activate(Triv121PgTbl);
extern void BSP_motload_pci_fixup(void);
extern unsigned long __rtems_end[];
/* We really shouldn't use these since MMUoff also sets IP;
* nevertheless, during early init I don't care for now
*/
extern void MMUoff(void);
extern void MMUon(void);
extern uint32_t probeMemoryEnd(void);
SPR_RW(SPRG0)
SPR_RW(SPRG1)
SPR_RO(HID1)
/* Table of PLL multipliers for 7455/7457:
01000 2 00010 7.5 00000 11.5 00001 17
10000 3 11000 8 10111 12 00101 18
10100 4 01100 8.5 11111 12.5 00111 20
10110 5 01111 9 01011 13 01001 21
10010 5.5 01110 9.5 11100 13.5 01101 24
11010 6 10101 10 11001 14 11101 28
01010 6.5 10001 10.5 00011 15 00110 bypass
00100 7 10011 11 11011 16 11110 off
*/
/* Sorted according to CFG bits and multiplied by 2 it looks
* like this (note that this is in sequential order, not
* tabulated as above)
*/
signed char mpc7450PllMultByTwo[32] = {
23, 34, 15, 30,
14, 36, 2/*bypass*/, 40,
4, 42, 13, 26,
17, 48, 19, 18,
6, 21, 11, 22,
8, 20, 10, 24,
16, 28, 12, 32,
27, 56, 0/*off*/, 25,
};
uint32_t bsp_clicks_per_usec = 0;
/*
* Total memory using probing.
*/
unsigned int BSP_mem_size;
/*
* PCI Bus Frequency
*/
unsigned int BSP_bus_frequency = 0xdeadbeef;
/*
* processor clock frequency
*/
unsigned int BSP_processor_frequency = 0xdeadbeef;
/*
* Time base divisior (bus freq / TB clock)
*/
unsigned int BSP_time_base_divisor = 4000; /* most 604+ CPUs seem to use this */
/* Board identification string */
char BSP_productIdent[20] = {0};
char BSP_serialNumber[20] = {0};
/* VPD appends an extra char -- what for ? */
char BSP_enetAddr0[7] = {0};
char BSP_enetAddr1[7] = {0};
/*
* The original table from the application and our copy of it with
* some changes.
*/
extern rtems_configuration_table Configuration;
char *rtems_progname;
/*
* Use the shared implementations of the following routines
*/
extern void bsp_pretasking_hook(void);
#define CMDLINE_BUF_SIZE 2048
static char cmdline_buf[CMDLINE_BUF_SIZE];
char *BSP_commandline_string = cmdline_buf;
/* this routine is called early and must be safe with a not properly
* aligned stack
*/
char *
save_boot_params(void *r3, void *r4, void* r5, char *cmdline_start, char *cmdline_end)
{
int i=cmdline_end-cmdline_start;
if ( i >= CMDLINE_BUF_SIZE )
i = CMDLINE_BUF_SIZE-1;
else if ( i < 0 )
i = 0;
memmove(cmdline_buf, cmdline_start, i);
cmdline_buf[i]=0;
return cmdline_buf;
}
static BSP_BoardType board_type = Unknown;
BSP_BoardType
BSP_getBoardType( void )
{
return board_type;
}
/*
* bsp_start
*
* This routine does the bulk of the system initialization.
*/
void bsp_start( void )
{
unsigned char *stack;
char *chpt;
uint32_t intrStackStart;
uint32_t intrStackSize;
Triv121PgTbl pt=0;
VpdBufRec vpdData [] = {
{ key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
{ key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
{ key: CpuClockHz, instance: 0, buf: &BSP_processor_frequency, buflen: sizeof(BSP_processor_frequency) },
{ key: BusClockHz, instance: 0, buf: &BSP_bus_frequency, buflen: sizeof(BSP_bus_frequency) },
{ key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
{ key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
VPD_END
};
/* T. Straumann: 4/2005
*
* Need to map the system registers early, so we can printk...
* (otherwise we silently die)
*/
/* map the PCI 0, 1 Domain I/O space, GT64260B registers
* and the reserved area so that the size is the power of 2.
*/
setdbat(7, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_SIZE, IO_PAGE);
/* Intersperse messages with actions to help locate problems */
printk("-----------------------------------------\n");
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() & friends functions
* store the result in global variables so that it can be used latter...
* This also verifies that we run on a known CPU.
*/
get_ppc_cpu_type();
get_ppc_cpu_revision();
/* Make sure we detect a known host bridge */
BSP_getDiscoveryVersion(/* assert detection */ 1);
printk("Welcome to %s ($Name$)\n", _RTEMS_version );
/* Leave all caches as MotLoad left them. Seems to be fine */
/*
* the initial stack has aready been set to this value in start.S
* so there is no need to set it in r1 again... It is just for info
* so that it can be printed without accessing R1.
*/
asm volatile("mr %0, 1":"=r"(stack));
/* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
*((uint32_t *)stack) = 0;
/*
* Initialize the interrupt related settings
* SPRG0 = interrupt nesting level count
* SPRG1 = software managed IRQ stack
*
* This could be done latter (e.g in IRQ_INIT) but it helps to understand
* some settings below...
*/
intrStackStart = (uint32_t)__rtems_end;
intrStackSize = rtems_configuration_get_interrupt_stack_size();
/*
* Initialize default raw exception handlers. See vectors/vectors_init.c
*/
ppc_exc_initialize(
PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
intrStackStart,
intrStackSize
);
printk("CPU: %s\n", get_ppc_cpu_type_name(current_ppc_cpu));
/*
* Initialize RTEMS IRQ system
*/
BSP_rtems_irq_mng_init(0);
printk("Build Date: %s\n",BSP_build_date);
BSP_vpdRetrieveFields(vpdData);
if ( !strncmp(BSP_productIdent,"MVME5500",8) )
board_type = MVME5500;
else if ( !strncmp(BSP_productIdent,"MVME6100",8) )
board_type = MVME6100;
printk("Board Type: %s (S/N %s)\n",
BSP_productIdent[0] ? BSP_productIdent : "n/a",
BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
if ( 0xdeadbeef == BSP_bus_frequency ) {
BSP_bus_frequency = 133333333;
printk("Bus Clock Freq NOT FOUND in VPD; using %10u Hz\n",
BSP_bus_frequency);
} else {
printk("Bus Clock Freq: %10u Hz\n",
BSP_bus_frequency);
}
if ( 0xdeadbeef == BSP_processor_frequency ) {
BSP_processor_frequency = BSP_bus_frequency/2;
BSP_processor_frequency *= mpc7450PllMultByTwo[ (_read_HID1() >> (31-19)) & 31 ];
}
printk("CPU Clock Freq: %10u Hz\n", BSP_processor_frequency);
/* probe real memory size; if it's more than 256M we can't currently access it
* since at this point only BAT-0 maps 0..256M
*/
BSP_mem_size = probeMemoryEnd();
if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
char *endp;
uint32_t sz;
chpt+=6 /* strlen("MEMSZ=") */;
sz = strtoul(chpt, &endp, 0);
if ( endp != chpt )
BSP_mem_size = sz;
}
printk("Memory: %10u bytes\n", BSP_mem_size);
if ( BSP_mem_size > 0x10000000 ) {
uint32_t s;
if ( BSP_mem_size > 0x80000000 ) {
BSP_mem_size = 0x80000000;
printk("Memory clipped to 0x%08x for now, sorry\n", BSP_mem_size);
}
for ( s = 0x20000000; s < BSP_mem_size ; s<<=1)
;
MMUoff();
/* since it's currently in use we must first surrender it */
setdbat(0, 0, 0, 0, 0);
setdbat(0, 0, 0, s, _PAGE_RW);
MMUon();
}
printk("-----------------------------------------\n");
/* Maybe not setup yet because of the warning message */
/* Allocate and set up the page table mappings
* This is only available on >604 CPUs.
*
* NOTE: This setup routine may modify the available memory
* size. It is essential to call it before
* calculating the workspace etc.
*/
pt = BSP_pgtbl_setup(&BSP_mem_size);
if (!pt)
printk("WARNING: unable to setup page tables.\n");
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
#endif
/*
* Set up our hooks
* Make sure libc_init is done before drivers initialized so that
* they can use atexit()
*/
bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Configuration.work_space_size = %x\n", Configuration.work_space_size);
#endif
/* Activate the page table mappings only after
* initializing interrupts because the irq_mng_init()
* routine needs to modify the text
*/
if ( pt ) {
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Page table setup finished; will activate it NOW...\n");
#endif
BSP_pgtbl_activate(pt);
}
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Going to start PCI buses scanning and initialization\n");
#endif
BSP_pci_initialize();
/* need to tweak the motload setup */
BSP_motload_pci_fixup();
/* map 512M, 256 for PCI 256 for VME */
setdbat(5,BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_SIZE, IO_PAGE);
setdbat(6,BSP_PCI_HOSE1_MEM_BASE, BSP_PCI_HOSE1_MEM_BASE, 0x10000000, IO_PAGE);
#ifdef SHOW_MORE_INIT_SETTINGS
printk("Number of PCI buses found is : %d\n", pci_bus_count());
#endif
/*
* Initialize hardware timer facility (not used by BSP itself)
* Needs PCI to identify discovery version...
*/
BSP_timers_initialize();
#ifdef SHOW_MORE_INIT_SETTINGS
printk("MSR %x \n", _read_MSR());
printk("Exit from bspstart\n");
#endif
}

View File

@@ -0,0 +1,132 @@
/* $Id$ */
#include <rtems.h>
#include <bsp.h>
#include <rtems/libi2c.h>
#include <libchip/i2c-2b-eeprom.h>
#include <libchip/i2c-ds1621.h>
#include <bsp/gti2c_busdrv.h>
#include <rtems/libio.h>
#include <stdio.h>
#include <sys/stat.h>
/* Register i2c bus driver & devices */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
int
BSP_i2c_initialize( void )
{
int busno;
/* Initialize the library */
if ( rtems_libi2c_initialize() ) {
fprintf(stderr,"Initializing I2C library failed\n");
return -1;
}
/* Register our bus driver */
if ( (busno=rtems_libi2c_register_bus(
BSP_I2C_BUS0_NAME,
BSP_I2C_BUS_DESCRIPTOR) ) < 0 ) {
perror("Registering gt64260 i2c bus driver");
return -1;
}
/* Now register higher level drivers; note that
* the i2c address in the manual is actually left-shifted
* by one bit, i.e., as it would go on the bus.
*/
/* Use read-only driver for VPD */
if ( rtems_libi2c_register_drv(
BSP_I2C_VPD_EEPROM_NAME,
i2c_2b_eeprom_ro_driver_descriptor,
busno,
BSP_VPD_I2C_ADDR) < 0 ) {
perror("Registering i2c VPD eeprom driver failed");
return -1;
}
/* Use read-write driver for user eeprom -- you still might
* have to disable HW write-protection on your board.
*/
if ( rtems_libi2c_register_drv(
BSP_I2C_USR_EEPROM_NAME,
i2c_2b_eeprom_driver_descriptor,
busno,
BSP_USR_I2C_ADDR) < 0 ) {
perror("Registering i2c USR eeprom driver failed");
return -1;
}
/* The thermostat */
if ( rtems_libi2c_register_drv(
BSP_I2C_DS1621_NAME,
i2c_ds1621_driver_descriptor,
busno,
BSP_THM_I2C_ADDR) < 0 ) {
perror("Registering i2c ds1621 temp sensor. driver failed");
return -1;
}
/* Finally, as an example, register raw access to the
* ds1621. The driver above just reads the 8 msb of the
* temperature but doesn't support anything else. Using
* the raw device node you can write/read individual
* control bytes yourself and e.g., program the thermostat...
*/
if ( mknod(
BSP_I2C_DS1621_RAW_DEV_NAME,
0666 | S_IFCHR,
rtems_filesystem_make_dev_t(rtems_libi2c_major,
RTEMS_LIBI2C_MAKE_MINOR(busno,BSP_THM_I2C_ADDR))) ) {
perror("Creating device node for raw ds1621 access failed");
return -1;
}
printf("I2C devices registered\n");
return 0;
}

View File

@@ -0,0 +1,261 @@
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(_start)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
PROVIDE (__stack = 0);
MEMORY {
BOTTOM : ORIGIN = 0x00, LENGTH = 0x80
MAILBOX : ORIGIN = 0x80, LENGTH = 0x80 /* RESERVED */
VECTORS : ORIGIN = 0x100 , LENGTH = 0x3000 - 0x100
CODE : ORIGIN = 0x3000 , LENGTH = 32M-0x3000
}
SECTIONS
{
/* discard the 'shared/vector.S' entry point section */
/DISCARD/ :
{
*(.entry_point_section)
}
.vectors :
{
/* should be the first thing... */
*(.ppc_preloader_section)
/*
* This section is used only if NO_DYNAMIC_EXCEPTION_VECTOR_INSTALL
* is defined in vectors/vectors.S
* *(.vectors)
* We actually RELY on dynamic vector installation since we need
* this space for the preloader...
*/
} > VECTORS
/* START OF THE LOADED IMAGE (parts moved by the preloader) */
.image_start :
{
__rtems_start = ABSOLUTE(.);
} > CODE
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) } > CODE
.hash : { *(.hash) } > CODE
.dynsym : { *(.dynsym) } > CODE
.dynstr : { *(.dynstr) } > CODE
.gnu.version : { *(.gnu.version) } > CODE
.gnu.version_d : { *(.gnu.version_d) } > CODE
.gnu.version_r : { *(.gnu.version_r) } > CODE
.rela.text :
{ *(.rela.text) *(.rela.gnu.linkonce.t*) } > CODE
.rela.data :
{ *(.rela.data) *(.rela.gnu.linkonce.d*) } > CODE
.rela.rodata :
{ *(.rela.rodata) *(.rela.gnu.linkonce.r*) } > CODE
.rela.got : { *(.rela.got) } > CODE
.rela.got1 : { *(.rela.got1) } > CODE
.rela.got2 : { *(.rela.got2) } > CODE
.rela.ctors : { *(.rela.ctors) } > CODE
.rela.dtors : { *(.rela.dtors) } > CODE
.rela.init : { *(.rela.init) } > CODE
.rela.fini : { *(.rela.fini) } > CODE
.rela.bss : { *(.rela.bss) } > CODE
.rela.plt : { *(.rela.plt) } > CODE
.rela.sdata : { *(.rela.sdata) } > CODE
.rela.sbss : { *(.rela.sbss) } > CODE
.rela.sdata2 : { *(.rela.sdata2) } > CODE
.rela.sbss2 : { *(.rela.sbss2) } > CODE
.init : { *(.init) } >CODE
.text :
{
*(.text*)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
} > CODE
.fini : { _fini = .; *(.fini) } >CODE
.rodata : { *(.rodata*) *(.gnu.linkonce.r*) } > CODE
.rodata1 : { *(.rodata1) } > CODE
_SDA2_BASE_ = __SDATA2_START__ + 0x8000;
.sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } > CODE
.sbss2 : {
PROVIDE (__sbss2_start = .);
*(.sbss2*) *(.gnu.linkonce.sb2.*)
/* avoid empty sdata2/sbss2 area because __eabi wouldn't set up r2
* (IMPORTANT if run-time loading is involved)
*/
. += 1 ;
PROVIDE (__sbss2_end = .);
} > CODE
.eh_frame : { *.(eh_frame) } >CODE
_etext = .;
PROVIDE (etext = .);
/* 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). */
.data ALIGN(0x1000) :
{
PROVIDE(__DATA_START__ = ABSOLUTE(.) );
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
} > CODE
.data1 : { *(.data1) } > CODE
PROVIDE (__EXCEPT_START__ = .);
.gcc_except_table : { *(.gcc_except_table) } > CODE
PROVIDE (__EXCEPT_END__ = .);
.got1 : { *(.got1) } > CODE
.dynamic : { *(.dynamic) } > CODE
/* 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_ = .);
.got2 : { *(.got2) } > CODE
/*
PROVIDE (__CTOR_LIST__ = .);
.ctors : { *(.ctors) } > CODE
PROVIDE (__CTOR_END__ = .);
*/
.ctors :
{
KEEP(*crtbegin.o(.ctors))
KEEP(*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
} > CODE
.dtors :
{
KEEP(*crtbegin.o(.dtors))
KEEP(*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
} > CODE
/*
PROVIDE (__DTOR_LIST__ = .);
.dtors : { *(.dtors) } > CODE
PROVIDE (__DTOR_END__ = .);
*/
PROVIDE (_FIXUP_START_ = .);
.fixup : { *(.fixup) } > CODE
PROVIDE (_FIXUP_END_ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (_GOT_START_ = .);
.got : { *(.got) } > CODE
.got.plt : { *(.got.plt) } > CODE
PROVIDE (_GOT_END_ = .);
.jcr : { KEEP (*(.jcr)) } > CODE
/* 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. */
_SDA_BASE_ = __SDATA_START__ + 0x8000;
.sdata : { *(.sdata*) *(.gnu.linkonce.s.*) } > CODE
_edata = .;
PROVIDE (edata = .);
/* END OF THE LOADED IMAGE (parts moved by the preloader) */
/* BELOW THIS POINT, NO LOADABLE ITEMS MUST APPEAR */
.sbss :
{
PROVIDE (__sbss_start = ABSOLUTE(.));
*(.sbss) *(.sbss.*) *(.gnu.linkonce.sb.*)
*(.scommon)
*(.dynsbss)
/* avoid empty sdata/sbss area because __eabi wouldn't set up r13
* (IMPORTANT if run-time loading is involved)
*/
. += 1 ;
PROVIDE (__sbss_end = ABSOLUTE(.));
} > CODE
.plt : { *(.plt) } > CODE
.bss :
{
PROVIDE (__bss_start = ABSOLUTE(.));
*(.dynbss)
*(.bss*) *(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(16);
} > CODE
/* proper alignment for SYSV stack
* (init stack is allocated just after __rtems_end
*/
. = ALIGN(16);
_end = . ;
__rtems_end = . ;
PROVIDE (end = .);
/DISCARD/ :
{
*(.comment)
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* 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,16 @@
#include <rtems.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <libcpu/io.h>
#include <libcpu/stackTrace.h>
void bsp_reset()
{
printk("Printing a stack trace for your convenience :-)\n");
CPU_print_stack();
printk("RTEMS terminated; Rebooting ...\n");
/* Mvme5500 board reset : 2004 S. Kate Feng <feng1@bnl.gov> */
out_8((volatile unsigned char*) (BSP_MV64x60_DEV1_BASE +2), 0x80);
}

View File

@@ -0,0 +1,36 @@
/*
* This file contains the RTC driver table for Motorola shared BSPs.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <bsp.h>
#include <libchip/rtc.h>
#include <libchip/m48t08.h>
/* The following table configures the RTC drivers used in this BSP */
rtc_tbl RTC_Table[] = {
{
"/dev/rtc", /* sDeviceName */
RTC_M48T08, /* deviceType */
&m48t08_fns, /* pDeviceFns */
rtc_probe, /* deviceProbe */
NULL, /* pDeviceParams */
BSP_NVRAM_RTC_START, /* ulCtrlPort1 */
0x00, /* ulDataPort */
m48t08_get_register, /* getRegister */
m48t08_set_register /* setRegister */
}
};
/* Some information used by the RTC driver */
#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
size_t RTC_Count = NUM_RTCS;
rtems_device_minor_number RTC_Minor;

View File

@@ -0,0 +1,112 @@
#ifndef RTEMS_BSP_VME_CONFIG_H
#define RTEMS_BSP_VME_CONFIG_H
/* $Id$ */
/* BSP specific address space configuration parameters */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#define _VME_DRIVER_TSI148
#define _VME_DRIVER_UNIVERSE
/*
* NOTE: the BSP (startup/bspstart.c) uses
* hardcoded window lengths that match this
* layout when setting BATs:
*/
#define _VME_A32_WIN0_ON_PCI 0x90000000
/* If _VME_CSR_ON_PCI is defined then the A32 window is reduced to accommodate
* CSR for space.
*/
#define _VME_CSR_ON_PCI 0x9e000000
#define _VME_A24_ON_PCI 0x9f000000
#define _VME_A16_ON_PCI 0x9fff0000
/* start of the A32 window on the VME bus
* TODO: this should perhaps be a configuration option
*/
#define _VME_A32_WIN0_ON_VME 0x20000000
/* if _VME_DRAM_OFFSET is defined, the BSP
* will map our RAM onto the VME bus, starting
* at _VME_DRAM_OFFSET
*/
#define _VME_DRAM_OFFSET 0x90000000
#define BSP_VME_INSTALL_IRQ_MGR(err) \
do { \
err = -1; \
switch (BSP_getBoardType()) { \
case MVME6100: \
err = theOps->install_irq_mgr( \
VMETSI148_IRQ_MGR_FLAG_SHARED, \
0, BSP_IRQ_GPP_0 + 20, \
1, BSP_IRQ_GPP_0 + 21, \
2, BSP_IRQ_GPP_0 + 22, \
3, BSP_IRQ_GPP_0 + 23, \
-1); \
break; \
\
case MVME5500: \
err = theOps->install_irq_mgr( \
VMEUNIVERSE_IRQ_MGR_FLAG_SHARED | \
VMEUNIVERSE_IRQ_MGR_FLAG_PW_WORKAROUND, \
0, BSP_IRQ_GPP_0 + 12, \
1, BSP_IRQ_GPP_0 + 13, \
2, BSP_IRQ_GPP_0 + 14, \
3, BSP_IRQ_GPP_0 + 15, \
-1); \
break; \
\
default: \
printk("WARNING: unknown board; "); \
break; \
} \
if ( err ) \
printk("VME interrupt manager NOT INSTALLED (error: %i)\n", err); \
} while (0)
#endif

View File

@@ -0,0 +1,217 @@
/* $Id$ */
/* Setup/glue to attach VME DMA driver to the beatnik BSP */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <stdio.h>
#include <stdint.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/VME.h>
#include <bsp/vmeTsi148.h>
#include <bsp/vmeUniverse.h>
#include <bsp/VMEDMA.h>
#include <bsp/vmeTsi148DMA.h>
#include <bsp/vmeUniverseDMA.h>
#include <bsp/bspVmeDmaList.h>
typedef struct DmaOpsRec_ {
int (*setup)(int, uint32_t, uint32_t, void *);
int (*start)(int, uint32_t, uint32_t, uint32_t);
uint32_t (*status)(int);
VMEDmaListClass listClass;
} DmaOpsRec, *DmaOps;
static DmaOpsRec universeOps = {
vmeUniverseDmaSetup,
vmeUniverseDmaStart,
vmeUniverseDmaStatus,
&vmeUniverseDmaListClass,
};
static DmaOpsRec tsiOps = {
vmeTsi148DmaSetup,
vmeTsi148DmaStart,
vmeTsi148DmaStatus,
&vmeTsi148DmaListClass,
};
static int setup(int a, uint32_t b, uint32_t c, void *d);
static int start(int a, uint32_t b, uint32_t c, uint32_t d);
static uint32_t status(int a);
static DmaOpsRec jumpstartOps = {
setup,
start,
status,
0
};
static DmaOps dmaOps = &jumpstartOps;
static DmaOps selectOps()
{
return (MVME6100 != BSP_getBoardType()) ?
&universeOps : &tsiOps;
}
static int
setup(int a, uint32_t b, uint32_t c, void *d)
{
return (dmaOps=selectOps())->setup(a,b,c,d);
}
static int
start(int a, uint32_t b, uint32_t c, uint32_t d)
{
return (dmaOps=selectOps())->start(a,b,c,d);
}
static uint32_t
status(int a)
{
return (dmaOps=selectOps())->status(a);
}
int
BSP_VMEDmaSetup(int channel, uint32_t bus_mode, uint32_t xfer_mode, void *custom_setup)
{
return dmaOps->setup(channel, bus_mode, xfer_mode, custom_setup);
}
int
BSP_VMEDmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes)
{
return dmaOps->start(channel, pci_addr, vme_addr, n_bytes);
}
uint32_t
BSP_VMEDmaStatus(int channel)
{
return dmaOps->status(channel);
}
BSP_VMEDmaListDescriptor
BSP_VMEDmaListDescriptorSetup(
BSP_VMEDmaListDescriptor d,
uint32_t attr_mask,
uint32_t xfer_mode,
uint32_t pci_addr,
uint32_t vme_addr,
uint32_t n_bytes)
{
VMEDmaListClass pc;
if ( !d ) {
if ( ! (pc = dmaOps->listClass) ) {
pc = (dmaOps = selectOps())->listClass;
}
return BSP_VMEDmaListDescriptorNewTool(
pc,
attr_mask,
xfer_mode,
pci_addr,
vme_addr,
n_bytes);
}
return BSP_VMEDmaListDescriptorSetupTool(d, attr_mask, xfer_mode, pci_addr, vme_addr, n_bytes);
}
int
BSP_VMEDmaListStart(int channel, BSP_VMEDmaListDescriptor list)
{
return BSP_VMEDmaListDescriptorStartTool(0, channel, list);
}
/* NOT thread safe! */
int
BSP_VMEDmaInstallISR(int channel, BSP_VMEDmaIRQCallback cb, void *usr_arg)
{
int vec;
BSP_VME_ISR_t curr;
void *carg;
if ( MVME6100 != BSP_getBoardType() ) {
if ( channel != 0 )
return -1;
vec = UNIV_DMA_INT_VEC;
} else {
if ( channel < 0 || channel > 1 )
return -1;
vec = (channel ? TSI_DMA1_INT_VEC : TSI_DMA_INT_VEC );
}
curr = BSP_getVME_isr(vec, &carg);
if ( cb && curr ) {
/* IRQ currently in use */
return -1;
}
if ( !cb && !curr ) {
/* Allow uninstall if no handler is currently installed;
* just make sure IRQ is disabled
*/
BSP_disableVME_int_lvl(vec);
return 0;
}
if ( cb ) {
if ( BSP_installVME_isr(vec, (BSP_VME_ISR_t)cb, usr_arg) )
return -4;
BSP_enableVME_int_lvl(vec);
} else {
BSP_disableVME_int_lvl(vec);
if ( BSP_removeVME_isr(vec, curr, carg) )
return -4;
}
return 0;
}

View File

@@ -0,0 +1,305 @@
/* $Id$ */
/* Standard VME bridge configuration for MVME5500, MVME6100 */
/*
* Authorship
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
* Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
* under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
* Neither the United States nor the United States Department of Energy,
* nor any of their employees, makes any warranty, express or implied, or
* assumes any legal liability or responsibility for the accuracy,
* completeness, or usefulness of any data, apparatus, product, or process
* disclosed, or represents that its use would not infringe privately owned
* rights.
*
* Stanford disclaimer of liability
* --------------------------------
* Stanford University makes no representations or warranties, express or
* implied, nor assumes any liability for the use of this software.
*
* Stanford disclaimer of copyright
* --------------------------------
* Stanford University, owner of the copyright, hereby disclaims its
* copyright and all other rights in this software. Hence, anyone may
* freely use it for any purpose without restriction.
*
* Maintenance of notices
* ----------------------
* In the interest of clarity regarding the origin and status of this
* SLAC software, this and all the preceding Stanford University notices
* are to remain affixed to any copy or derivative of this software made
* or distributed by the recipient and are to be affixed to any copy of
* software made or distributed by the recipient that contains a copy or
* derivative of this software.
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
#include <rtems.h>
#include <rtems/bspIo.h>
#include <bsp.h>
#include <bsp/VME.h>
#include <bsp/VMEConfig.h>
#include <bsp/irq.h>
#include <bsp/vmeUniverse.h>
#define _VME_TSI148_DECLARE_SHOW_ROUTINES
#include <bsp/vmeTsi148.h>
#include <libcpu/bat.h>
/* Use a weak alias for the VME configuration.
* This permits individual applications to override
* this routine.
* They may even create an 'empty'
*
* void BSP_vme_config(void) {}
*
* which will avoid linking in the Universe driver
* at all :-).
*/
void BSP_vme_config(void) __attribute__ (( weak, alias("__BSP_default_vme_config") ));
typedef struct {
int (*xlate_adrs)(int, int, unsigned long, unsigned long, unsigned long *);
int (*install_isr)(unsigned long, BSP_VME_ISR_t, void *);
int (*remove_isr)(unsigned long, BSP_VME_ISR_t, void *);
BSP_VME_ISR_t (*get_isr)(unsigned long vector, void **);
int (*enable_int_lvl)(unsigned int);
int (*disable_int_lvl)(unsigned int);
int (*outbound_p_cfg)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (*inbound_p_cfg) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
void (*outbound_p_show)(FILE*);
void (*inbound_p_show) (FILE*);
void (*reset_bus)(void);
int (*install_irq_mgr)(int, int, int, ...);
} VMEOpsRec, *VMEOps;
static VMEOpsRec uniOpsRec = {
xlate_adrs: vmeUniverseXlateAddr,
install_isr: vmeUniverseInstallISR,
remove_isr: vmeUniverseRemoveISR,
get_isr: vmeUniverseISRGet,
enable_int_lvl: vmeUniverseIntEnable,
disable_int_lvl: vmeUniverseIntDisable,
outbound_p_cfg: vmeUniverseMasterPortCfg,
inbound_p_cfg: vmeUniverseSlavePortCfg,
outbound_p_show: vmeUniverseMasterPortsShow,
inbound_p_show: vmeUniverseSlavePortsShow,
reset_bus: vmeUniverseResetBus,
install_irq_mgr: vmeUniverseInstallIrqMgrAlt,
};
static VMEOpsRec tsiOpsRec = {
xlate_adrs: vmeTsi148XlateAddr,
install_isr: vmeTsi148InstallISR,
remove_isr: vmeTsi148RemoveISR,
get_isr: vmeTsi148ISRGet,
enable_int_lvl: vmeTsi148IntEnable,
disable_int_lvl: vmeTsi148IntDisable,
outbound_p_cfg: vmeTsi148OutboundPortCfg,
inbound_p_cfg: vmeTsi148InboundPortCfg,
outbound_p_show: vmeTsi148OutboundPortsShow,
inbound_p_show: vmeTsi148InboundPortsShow,
reset_bus: vmeTsi148ResetBus,
install_irq_mgr: vmeTsi148InstallIrqMgrAlt,
};
static VMEOps theOps = 0;
int
BSP_vme2local_adrs(unsigned long am, unsigned long vmeaddr, unsigned long *plocaladdr)
{
int rval=theOps->xlate_adrs(1,0,am,vmeaddr,plocaladdr);
*plocaladdr+=PCI_MEM_BASE;
return rval;
}
int
BSP_local2vme_adrs(unsigned long am, unsigned long localaddr, unsigned long *pvmeaddr)
{
return theOps->xlate_adrs(0, 0, am,localaddr+PCI_DRAM_OFFSET,pvmeaddr);
}
int
BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
{
return theOps->install_isr(vector, handler, arg);
}
int
BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *arg)
{
return theOps->remove_isr(vector, handler, arg);
}
/* retrieve the currently installed ISR for a given vector */
BSP_VME_ISR_t
BSP_getVME_isr(unsigned long vector, void **parg)
{
return theOps->get_isr(vector, parg);
}
int
BSP_enableVME_int_lvl(unsigned int level)
{
return theOps->enable_int_lvl(level);
}
int
BSP_disableVME_int_lvl(unsigned int level)
{
return theOps->disable_int_lvl(level);
}
int
BSP_VMEOutboundPortCfg(
unsigned long port,
unsigned long address_space,
unsigned long vme_address,
unsigned long pci_address,
unsigned long size)
{
return theOps->outbound_p_cfg(port, address_space, vme_address, pci_address, size);
}
int
BSP_VMEInboundPortCfg(
unsigned long port,
unsigned long address_space,
unsigned long vme_address,
unsigned long pci_address,
unsigned long size)
{
return theOps->inbound_p_cfg(port, address_space, vme_address, pci_address, size);
}
void
BSP_VMEOutboundPortsShow(FILE *f)
{
theOps->outbound_p_show(f);
}
void
BSP_VMEInboundPortsShow(FILE *f)
{
theOps->inbound_p_show(f);
}
void
BSP_VMEResetBus(void)
{
theOps->reset_bus();
}
static unsigned short
tsi_clear_errors(int quiet)
{
unsigned long v;
unsigned short rval;
v = vmeTsi148ClearVMEBusErrors(0);
/* return bits 8..23 of VEAT; set bit 15 to make sure rval is nonzero on error */
rval = v ? ((v>>8) & 0xffff) | (1<<15) : 0;
return rval;
}
void
__BSP_default_vme_config(void)
{
int err = 1;
if ( 0 == vmeUniverseInit() ) {
theOps = &uniOpsRec;
vmeUniverseReset();
} else if ( 0 == vmeTsi148Init() ) {
theOps = &tsiOpsRec;
vmeTsi148Reset();
_BSP_clear_vmebridge_errors = tsi_clear_errors;
} else
return; /* no VME bridge found chip */
/* map VME address ranges */
BSP_VMEOutboundPortCfg(
0,
VME_AM_EXT_SUP_DATA,
_VME_A32_WIN0_ON_VME,
_VME_A32_WIN0_ON_PCI,
0x0e000000
);
BSP_VMEOutboundPortCfg(
1,
VME_AM_STD_SUP_DATA,
0x00000000,
_VME_A24_ON_PCI,
0x00ff0000);
BSP_VMEOutboundPortCfg(
2,
VME_AM_SUP_SHORT_IO,
0x00000000,
_VME_A16_ON_PCI,
0x00010000);
#ifdef _VME_CSR_ON_PCI
/* Map VME64 CSR */
BSP_VMEOutboundPortCfg(
7,
VME_AM_CSR,
0,
_VME_CSR_ON_PCI,
0x01000000);
#endif
#ifdef _VME_DRAM_OFFSET
/* map our memory to VME */
BSP_VMEInboundPortCfg(
0,
VME_AM_EXT_SUP_DATA | VME_AM_IS_MEMORY,
_VME_DRAM_OFFSET,
PCI_DRAM_OFFSET,
BSP_mem_size);
#endif
/* stdio is not yet initialized; the driver will revert to printk */
BSP_VMEOutboundPortsShow(0);
BSP_VMEInboundPortsShow(0);
switch (BSP_getBoardType()) {
case MVME6100:
err = theOps->install_irq_mgr(
VMETSI148_IRQ_MGR_FLAG_SHARED,
0, BSP_IRQ_GPP_0 + 20,
1, BSP_IRQ_GPP_0 + 21,
2, BSP_IRQ_GPP_0 + 22,
3, BSP_IRQ_GPP_0 + 23,
-1);
break;
case MVME5500:
err = theOps->install_irq_mgr(
VMEUNIVERSE_IRQ_MGR_FLAG_SHARED |
VMEUNIVERSE_IRQ_MGR_FLAG_PW_WORKAROUND,
0, BSP_IRQ_GPP_0 + 12,
1, BSP_IRQ_GPP_0 + 13,
2, BSP_IRQ_GPP_0 + 14,
3, BSP_IRQ_GPP_0 + 15,
-1);
break;
default:
printk("WARNING: unknown board; ");
break;
}
if ( err )
printk("VME interrupt manager NOT INSTALLED (error: %i)\n", err);
}