mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-08 12:46:46 +03:00
Compare commits
9 Commits
LABEL_2004
...
LABEL_2004
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cfbab3d82 | ||
|
|
cbd8a35c6d | ||
|
|
074cff0d28 | ||
|
|
028ab6b598 | ||
|
|
63e73c9a8e | ||
|
|
cd0a9de68b | ||
|
|
2d1a537d87 | ||
|
|
3f85ce2785 | ||
|
|
3c74e32a98 |
109
CHANGELOG
109
CHANGELOG
@@ -2,6 +2,115 @@
|
||||
Changes for U-Boot 1.0.2:
|
||||
======================================================================
|
||||
|
||||
* Patch by Masami Komiy, 22 Feb 2004:
|
||||
Add support for NFS for file download
|
||||
|
||||
* Patch by Andrea Scian, 17 Feb 2004:
|
||||
Add support for S3C44B0 processor and DAVE B2 board
|
||||
|
||||
* Patch by Steven Scholz, 20 Feb 2004:
|
||||
- Add support for MII commands on AT91RM9200 boards
|
||||
- some cleanup in AT91RM9200 ethernet code
|
||||
|
||||
* Patch by Peter Ryser, 20 Feb 2004:
|
||||
Add support for the Xilinx ML300 platform
|
||||
|
||||
* Patch by Stephan Linz, 17 Feb 2004:
|
||||
Fix watchdog support for NIOS
|
||||
|
||||
* Patch by Josh Fryman, 16 Feb 2004:
|
||||
Fix byte-swapping for cfi_flash.c for different bus widths
|
||||
|
||||
* Patch by Jon Diekema, 14 Jeb 2004:
|
||||
Remove duplicate "FPGA Support" notes from the README file
|
||||
|
||||
* Patches by Reinhard Meyer, 14 Feb 2004:
|
||||
- update board/emk tree; use common flash driver
|
||||
- Corrected tested bits in machine check exception in cpu/mpc5xxx/traps.c
|
||||
[adapted for other PPC CPUs -- wd]
|
||||
- Added support for the M48T08 on the EVAL5200 board in rtc/mk48t59.c
|
||||
|
||||
* Patch by Jon Diekema, 13 Feb 2004:
|
||||
Call show_boot_progress() whenever POST "FAILED" is printed.
|
||||
|
||||
* Patch by Nishant Kamat, 13 Feb 2004:
|
||||
Add support for TI OMAP1610 H2 Board
|
||||
Fixes for cpu/arm926ejs/interrupt.c
|
||||
(based on Richard Woodruff's patch for arm925, 16 Oct 03)
|
||||
Fix for a timer bug in OMAP1610 Innovator
|
||||
Add support for CS0 (ROM)/CS3 (Flash) boot in OMAP1610 Innovator and H2
|
||||
|
||||
* Patches by Stephan Linz, 12 Feb 2004:
|
||||
- add support for NIOS timer with variable period preload counter value
|
||||
- prepare POST framework support for NIOS targets
|
||||
|
||||
* Patch by Denis Peter, 11 Feb 2004:
|
||||
add POST support for the MIP405 board
|
||||
|
||||
* Patch by Laurent Mohin, 10 Feb 2004:
|
||||
Fix buffer overflow in common/usb.c
|
||||
|
||||
* Patch by Tolunay Orkun, 10 Feb 2004:
|
||||
Add support for Cogent CSB272 board
|
||||
|
||||
* Patch by Thomas Elste, 10 Feb 2004:
|
||||
Add support for NET+50 CPU and ModNET50 board
|
||||
|
||||
* Patch by Sam Song, 10 Feb 2004:
|
||||
Fix typos in cfi_flash.c
|
||||
|
||||
* Patch by Leon Kukovec, 10 Feb 2004
|
||||
Fixed long dir entry slot id calculation in get_vfatname
|
||||
|
||||
* Patch by Robin Gilks, 10 Feb 2004:
|
||||
add "itest" command (operators: -eq, -ne, -lt, -gt, -le, -ge, ==,
|
||||
!=, <>, <, >, <=, >=)
|
||||
|
||||
* Fix problem with side effects in macros in include/usb.h
|
||||
|
||||
* Patch by David Benson, 13 Nov 2003:
|
||||
bug 841358 - fix TFTP download size limit
|
||||
|
||||
* Fixing bug 850768:
|
||||
improper flush_cache() in load_serial()
|
||||
|
||||
* Fixing bug 834943:
|
||||
MPC8540 - missing volatile declarations
|
||||
|
||||
* Patch by Stephen Williams, 09 Feb 2004:
|
||||
Add support for Xilinx SystemACE chip:
|
||||
- New files common/cmd_ace.c and include/systemace.h
|
||||
- Hook systemace support into cmd_fat and the partition manager
|
||||
|
||||
* Patch by Travis Sawyer, 09 Feb 2004:
|
||||
Add bi_opbfreq & bi_iic_fast to 440GX bd_info as needed for Linux
|
||||
|
||||
* Patch by Travis Sawyer, 09 Feb 2004:
|
||||
o 440GX:
|
||||
- Fix PCI Indirect access for type 1 config cycles with ppc440.
|
||||
- Add phymode for 440 enet
|
||||
- fix pci pre init
|
||||
o XPedite1K:
|
||||
- Change board_pre_init to board_early_init_f
|
||||
- Add user flash to bus controller setup
|
||||
- Fix pci pre init
|
||||
- Fix is_pci_host to check GPIO for monarch bit
|
||||
- Force xpedite1k to pci conventional mode (via #define option)
|
||||
|
||||
* Patch by Brad Kemp, 4 Feb 2004:
|
||||
- handle the machine check that is generated during the PCI scans
|
||||
on 82xx processors.
|
||||
- define the registers used in the IMMR by the PCI subsystem.
|
||||
|
||||
* Patch by Pierre Aubert, 03 Feb 2004:
|
||||
cpu/mpc5xxx/start.S: copy MBAR into SPR311
|
||||
|
||||
* Patch by Jeff Angielski, 03 Feb 2004:
|
||||
Fix copy & paste error in cpu/mpc8260/pci.c
|
||||
|
||||
* Patch by Reinhard Meyer, 24 Jan 2004:
|
||||
Fix typo in cpu/mpc5xxx/pci_mpc5200.c
|
||||
|
||||
* Add Auto-MDIX support for INCA-IP
|
||||
|
||||
* Some code cleanup
|
||||
|
||||
@@ -187,6 +187,9 @@ Scott McNutt <smcnutt@artesyncp.com>
|
||||
|
||||
EBONY PPC440GP
|
||||
|
||||
Tolunay Orkun <torkun@nextio.com>
|
||||
csb272 PPC4xx
|
||||
|
||||
Keith Outwater <Keith_Outwater@mvis.com>
|
||||
|
||||
GEN860T MPC860T
|
||||
@@ -307,9 +310,14 @@ Gary Jennejohn <gj@denx.de>
|
||||
trab ARM920T
|
||||
|
||||
Kshitij Gupta <kshitij@ti.com>
|
||||
|
||||
omap1510inn ARM925T
|
||||
omap1610inn ARM926EJS
|
||||
|
||||
Nishant Kamat <nskamat@ti.com>
|
||||
|
||||
omap1610h2 ARM926EJS
|
||||
|
||||
David Müller <d.mueller@elsoft.ch>
|
||||
|
||||
smdk2410 ARM920T
|
||||
|
||||
30
MAKEALL
30
MAKEALL
@@ -40,7 +40,7 @@ LIST_8xx=" \
|
||||
GEN860T_SC GENIETV GTH hermes \
|
||||
IAD210 ICU862_100MHz IP860 IVML24 \
|
||||
IVML24_128 IVML24_256 IVMS8 IVMS8_128 \
|
||||
IVMS8_256 KUP4K LANTEC lwmon \
|
||||
IVMS8_256 KUP4K LANTEC lwmon \
|
||||
MBX MBX860T MHPC MPC86xADS \
|
||||
MVS1 NETVIA NETVIA_V2 NX823 \
|
||||
pcu_e QS823 QS850 QS860T \
|
||||
@@ -56,15 +56,15 @@ LIST_8xx=" \
|
||||
#########################################################################
|
||||
|
||||
LIST_4xx=" \
|
||||
ADCIOP AR405 ASH405 BUBINGA405EP \
|
||||
CANBT CPCI405 CPCI4052 CPCI405AB \
|
||||
CPCI440 CPCIISER4 CRAYL1 DASA_SIM \
|
||||
DP405 DU405 EBONY ERIC \
|
||||
EXBITGEN HUB405 MIP405 MIP405T \
|
||||
ML2 OCRTC ORSG PCI405 \
|
||||
PIP405 PLU405 PMC405 PPChameleonEVB \
|
||||
VOH405 W7OLMC W7OLMG WALNUT405 \
|
||||
XPEDITE1K \
|
||||
ADCIOP AR405 ASH405 BUBINGA405EP \
|
||||
CANBT CPCI405 CPCI4052 CPCI405AB \
|
||||
CPCI440 CPCIISER4 CRAYL1 csb272 \
|
||||
DASA_SIM DP405 DU405 EBONY \
|
||||
ERIC EXBITGEN HUB405 MIP405 \
|
||||
MIP405T ML2 ml300 OCRTC \
|
||||
ORSG PCI405 PIP405 PLU405 \
|
||||
PMC405 PPChameleonEVB VOH405 W7OLMC \
|
||||
W7OLMG WALNUT405 XPEDITE1K \
|
||||
"
|
||||
|
||||
#########################################################################
|
||||
@@ -72,9 +72,9 @@ LIST_4xx=" \
|
||||
#########################################################################
|
||||
|
||||
LIST_824x=" \
|
||||
A3000 BMW CPC45 CU824 \
|
||||
debris MOUSSE MUSENKI MVBLUE \
|
||||
OXC PN62 Sandpoint8240 Sandpoint8245 \
|
||||
A3000 BMW CPC45 CU824 \
|
||||
debris MOUSSE MUSENKI MVBLUE \
|
||||
OXC PN62 Sandpoint8240 Sandpoint8245 \
|
||||
SL8245 utx8245 \
|
||||
"
|
||||
|
||||
@@ -128,14 +128,14 @@ LIST_SA="dnp1110 lart shannon"
|
||||
## ARM7 Systems
|
||||
#########################################################################
|
||||
|
||||
LIST_ARM7="ep7312 impa7"
|
||||
LIST_ARM7="B2 ep7312 impa7"
|
||||
|
||||
#########################################################################
|
||||
## ARM9 Systems
|
||||
#########################################################################
|
||||
|
||||
LIST_ARM9=" \
|
||||
at91rm9200dk omap1510inn omap1610inn \
|
||||
at91rm9200dk omap1510inn omap1610h2 omap1610inn \
|
||||
smdk2400 smdk2410 trab \
|
||||
VCMA9 \
|
||||
"
|
||||
|
||||
35
Makefile
35
Makefile
@@ -558,6 +558,9 @@ CPCIISER4_config: unconfig
|
||||
CRAYL1_config:unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx L1 cray
|
||||
|
||||
csb272_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx csb272
|
||||
|
||||
DASA_SIM_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx dasa_sim esd
|
||||
|
||||
@@ -590,6 +593,9 @@ MIP405T_config:unconfig
|
||||
ML2_config:unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx ml2
|
||||
|
||||
ml300_config:unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx ml300 xilinx
|
||||
|
||||
OCRTC_config \
|
||||
ORSG_config: unconfig
|
||||
@./mkconfig $(@:_config=) ppc ppc4xx ocrtc esd
|
||||
@@ -909,11 +915,25 @@ shannon_config : unconfig
|
||||
|
||||
xtract_trab = $(subst _bigram,,$(subst _bigflash,,$(subst _old,,$(subst _config,,$1))))
|
||||
|
||||
xtract_omap1610xxx = $(subst _cs0boot,,$(subst _cs3boot,, $(subst _config,,$1)))
|
||||
|
||||
omap1510inn_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm925t omap1510inn
|
||||
|
||||
omap1610inn_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm926ejs omap1610inn
|
||||
omap1610inn_config \
|
||||
omap1610inn_cs0boot_config \
|
||||
omap1610inn_cs3boot_config \
|
||||
omap1610h2_config \
|
||||
omap1610h2_cs0boot_config \
|
||||
omap1610h2_cs3boot_config : unconfig
|
||||
@if [ "$(findstring _cs0boot_, $@)" ] ; then \
|
||||
echo "#define CONFIG_CS0_BOOT" >> ./include/config.h ; \
|
||||
echo "Configured for CS0 boot"; \
|
||||
else \
|
||||
echo "#define CONFIG_CS3_BOOT" >> ./include/config.h ; \
|
||||
echo "Configured for CS3 boot"; \
|
||||
fi;
|
||||
@./mkconfig -a $(call xtract_omap1610xxx,$@) arm arm926ejs omap1610inn
|
||||
|
||||
smdk2400_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t smdk2400
|
||||
@@ -949,6 +969,14 @@ trab_old_config: unconfig
|
||||
VCMA9_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm920t vcma9 mpl
|
||||
|
||||
|
||||
#########################################################################
|
||||
## S3C44B0 Systems
|
||||
#########################################################################
|
||||
|
||||
B2_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm s3c44b0 B2 dave
|
||||
|
||||
#########################################################################
|
||||
## ARM720T Systems
|
||||
#########################################################################
|
||||
@@ -959,6 +987,9 @@ impa7_config : unconfig
|
||||
ep7312_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm720t ep7312
|
||||
|
||||
modnet50_config : unconfig
|
||||
@./mkconfig $(@:_config=) arm arm720t modnet50
|
||||
|
||||
#########################################################################
|
||||
## XScale Systems
|
||||
#########################################################################
|
||||
|
||||
88
README
88
README
@@ -219,7 +219,7 @@ Directory Hierarchy:
|
||||
- board/omap1510inn
|
||||
Files specific to OMAP 1510 Innovator boards
|
||||
- board/omap1610inn
|
||||
Files specific to OMAP 1610 Innovator boards
|
||||
Files specific to OMAP 1610 Innovator and H2 boards
|
||||
- board/pcippc2 Files specific to PCIPPC2/PCIPPC6 boards
|
||||
- board/pm826 Files specific to PM826 boards
|
||||
- board/ppmc8260
|
||||
@@ -375,11 +375,12 @@ The following options need to be configured:
|
||||
ARM based boards:
|
||||
-----------------
|
||||
|
||||
CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
|
||||
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
|
||||
CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610
|
||||
CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
|
||||
CONFIG_TRAB, CONFIG_VCMA9, CONFIG_AT91RM9200DK
|
||||
CONFIG_HHP_CRADLE, CONFIG_DNP1110, CONFIG_EP7312,
|
||||
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
|
||||
CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610,
|
||||
CONFIG_H2_OMAP1610, CONFIG_SHANNON, CONFIG_SMDK2400,
|
||||
CONFIG_SMDK2410, CONFIG_TRAB, CONFIG_VCMA9,
|
||||
CONFIG_AT91RM9200DK
|
||||
|
||||
|
||||
- CPU Module Type: (if CONFIG_COGENT is defined)
|
||||
@@ -644,6 +645,7 @@ The following options need to be configured:
|
||||
CFG_CMD_IMLS List all found images
|
||||
CFG_CMD_IMMAP * IMMR dump support
|
||||
CFG_CMD_IRQ * irqinfo
|
||||
CFG_CMD_ITEST * Integer/string test of 2 values
|
||||
CFG_CMD_JFFS2 * JFFS2 Support
|
||||
CFG_CMD_KGDB * kgdb
|
||||
CFG_CMD_LOADB loadb
|
||||
@@ -1151,60 +1153,6 @@ The following options need to be configured:
|
||||
SPI configuration items (port pins to use, etc). For
|
||||
an example, see include/configs/sacsng.h.
|
||||
|
||||
- FPGA Support: CONFIG_FPGA_COUNT
|
||||
|
||||
Specify the number of FPGA devices to support.
|
||||
|
||||
CONFIG_FPGA
|
||||
|
||||
Used to specify the types of FPGA devices. For
|
||||
example,
|
||||
#define CONFIG_FPGA CFG_XILINX_VIRTEX2
|
||||
|
||||
CFG_FPGA_PROG_FEEDBACK
|
||||
|
||||
Enable printing of hash marks during FPGA
|
||||
configuration.
|
||||
|
||||
CFG_FPGA_CHECK_BUSY
|
||||
|
||||
Enable checks on FPGA configuration interface busy
|
||||
status by the configuration function. This option
|
||||
will require a board or device specific function to
|
||||
be written.
|
||||
|
||||
CONFIG_FPGA_DELAY
|
||||
|
||||
If defined, a function that provides delays in the
|
||||
FPGA configuration driver.
|
||||
|
||||
CFG_FPGA_CHECK_CTRLC
|
||||
|
||||
Allow Control-C to interrupt FPGA configuration
|
||||
|
||||
CFG_FPGA_CHECK_ERROR
|
||||
|
||||
Check for configuration errors during FPGA bitfile
|
||||
loading. For example, abort during Virtex II
|
||||
configuration if the INIT_B line goes low (which
|
||||
indicated a CRC error).
|
||||
|
||||
CFG_FPGA_WAIT_INIT
|
||||
|
||||
Maximum time to wait for the INIT_B line to deassert
|
||||
after PROB_B has been deasserted during a Virtex II
|
||||
FPGA configuration sequence. The default time is 500 mS.
|
||||
|
||||
CFG_FPGA_WAIT_BUSY
|
||||
|
||||
Maximum time to wait for BUSY to deassert during
|
||||
Virtex II FPGA configuration. The default is 5 mS.
|
||||
|
||||
CFG_FPGA_WAIT_CONFIG
|
||||
|
||||
Time to wait after FPGA configuration. The default is
|
||||
200 mS.
|
||||
|
||||
- FPGA Support: CONFIG_FPGA_COUNT
|
||||
|
||||
Specify the number of FPGA devices to support.
|
||||
@@ -1410,6 +1358,20 @@ The following options need to be configured:
|
||||
allows to read/write in Dataflash via the standard
|
||||
commands cp, md...
|
||||
|
||||
- SystemACE Support:
|
||||
CONFIG_SYSTEMACE
|
||||
|
||||
Adding this option adds support for Xilinx SystemACE
|
||||
chips attached via some sort of local bus. The address
|
||||
of the chip must alsh be defined in the
|
||||
CFG_SYSTEMACE_BASE macro. For example:
|
||||
|
||||
#define CONFIG_SYSTEMACE
|
||||
#define CFG_SYSTEMACE_BASE 0xf0000000
|
||||
|
||||
When SystemACE support is added, the "ace" device type
|
||||
becomes available to the fat commands, i.e. fatls.
|
||||
|
||||
- Show boot progress:
|
||||
CONFIG_SHOW_BOOT_PROGRESS
|
||||
|
||||
@@ -1450,6 +1412,10 @@ The following options need to be configured:
|
||||
14 common/cmd_bootm.c No initial ramdisk, no multifile, continue.
|
||||
15 common/cmd_bootm.c All preparation done, transferring control to OS
|
||||
|
||||
-30 lib_ppc/board.c Fatal error, hang the system
|
||||
-31 post/post.c POST test failed, detected by post_output_backlog()
|
||||
-32 post/post.c POST test failed, detected by post_run_single()
|
||||
|
||||
-1 common/cmd_doc.c Bad usage of "doc" command
|
||||
-1 common/cmd_doc.c No boot device
|
||||
-1 common/cmd_doc.c Unknown Chip ID on boot device
|
||||
@@ -2024,7 +1990,7 @@ configurations; the following names are supported:
|
||||
at91rm9200dk_config omap1510inn_config MPC8260ADS_config
|
||||
omap1610inn_config ZPC1900_config MPC8540ADS_config
|
||||
MPC8560ADS_config QS850_config QS823_config
|
||||
QS860T_config DUET_ADS_config
|
||||
QS860T_config DUET_ADS_config omap1610h2_config
|
||||
|
||||
Note: for some board special configuration names may exist; check if
|
||||
additional information is available from the board vendor; for
|
||||
|
||||
51
board/csb272/Makefile
Normal file
51
board/csb272/Makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
#OBJS = $(BOARD).o flash.o
|
||||
#OBJS = $(BOARD).o strataflash.o
|
||||
OBJS = $(BOARD).o
|
||||
|
||||
SOBJS = init.o
|
||||
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
36
board/csb272/config.mk
Normal file
36
board/csb272/config.mk
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2004
|
||||
# Tolunay Orkun, NextIO Inc., torkun@nextio.com.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# Cogent CSB272 board
|
||||
#
|
||||
|
||||
LDFLAGS += $(LINKER_UNDEFS)
|
||||
|
||||
TEXT_BASE := 0xFFFC0000
|
||||
#TEXT_BASE := 0x00100000
|
||||
|
||||
PLATFORM_RELFLAGS := $(PLATFORM_RELFLAGS)
|
||||
174
board/csb272/csb272.c
Normal file
174
board/csb272/csb272.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* (C) Copyright 2004
|
||||
* Tolunay Orkun, Nextio Inc., torkun@nextio.com
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <asm/u-boot.h>
|
||||
#include <asm/processor.h>
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <miiphy.h>
|
||||
#include <405gp_enet.h>
|
||||
|
||||
/*
|
||||
* Configuration data for AMIS FS6377-01 Programmable 3-PLL Clock Generator
|
||||
*
|
||||
* CLKA output => Epson LCD Controller
|
||||
* CLKB output => Not Connected
|
||||
* CLKC output => Ethernet
|
||||
* CLKD output => UART external clock
|
||||
*
|
||||
* Note: these values are obtained from device after init by micromonitor
|
||||
*/
|
||||
uchar pll_fs6377_regs[16] = {
|
||||
0x28, 0xef, 0x53, 0x03, 0x4b, 0x80, 0x32, 0x80,
|
||||
0x94, 0x32, 0x80, 0xd4, 0x56, 0xf6, 0xf6, 0xe0 };
|
||||
|
||||
/*
|
||||
* pll_init: Initialize AMIS IC FS6377-01 PLL
|
||||
*
|
||||
* PLL supplies Epson LCD Clock, Ethernet Clock and UART external clock
|
||||
*
|
||||
*/
|
||||
int pll_init(void)
|
||||
{
|
||||
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
|
||||
|
||||
return i2c_write(CFG_I2C_PLL_ADDR, 0, 1,
|
||||
(uchar *) pll_fs6377_regs, sizeof(pll_fs6377_regs));
|
||||
}
|
||||
|
||||
/*
|
||||
* board_pre_init: do any preliminary board initialization
|
||||
*
|
||||
*/
|
||||
int board_pre_init(void)
|
||||
{
|
||||
/* initialize PLL so UART, LCD, Ethernet clocked at correctly */
|
||||
(void) get_clocks();
|
||||
pll_init();
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Interrupt controller setup for the Walnut board.
|
||||
| Note: IRQ 0-15 405GP internally generated; active high; level sensitive
|
||||
| IRQ 16 405GP internally generated; active low; level sensitive
|
||||
| IRQ 17-24 RESERVED
|
||||
| IRQ 25 (EXT IRQ 0) FPGA; active high; level sensitive
|
||||
| IRQ 26 (EXT IRQ 1) SMI; active high; level sensitive
|
||||
| IRQ 27 (EXT IRQ 2) Not Used
|
||||
| IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
|
||||
| IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
|
||||
| IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
|
||||
| IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
|
||||
| Note for Walnut board:
|
||||
| An interrupt taken for the FPGA (IRQ 25) indicates that either
|
||||
| the Mouse, Keyboard, IRDA, or External Expansion caused the
|
||||
| interrupt. The FPGA must be read to determine which device
|
||||
| caused the interrupt. The default setting of the FPGA clears
|
||||
|
|
||||
+-------------------------------------------------------------------------*/
|
||||
|
||||
mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
|
||||
mtdcr (uicer, 0x00000000); /* disable all ints */
|
||||
mtdcr (uiccr, 0x00000000); /* set all to be non-critical */
|
||||
mtdcr (uicpr, 0xFFFFFF83); /* set int polarities */
|
||||
mtdcr (uictr, 0x10000000); /* set int trigger levels */
|
||||
mtdcr (uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority */
|
||||
mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
|
||||
|
||||
mtebc (epcr, 0xa8400000); /* EBC always driven */
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
* checkboard: identify/verify the board we are running
|
||||
*
|
||||
* Remark: we just assume it is correct board here!
|
||||
*
|
||||
*/
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("BOARD: Cogent CSB272\n");
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
* initram: Determine the size of mounted DRAM
|
||||
*
|
||||
* Size is determined by reading SDRAM configuration registers as
|
||||
* configured by initialization code
|
||||
*
|
||||
*/
|
||||
long initdram (int board_type)
|
||||
{
|
||||
ulong tot_size;
|
||||
ulong bank_size;
|
||||
ulong tmp;
|
||||
|
||||
tot_size = 0;
|
||||
|
||||
mtdcr (memcfga, mem_mb0cf);
|
||||
tmp = mfdcr (memcfgd);
|
||||
if (tmp & 0x00000001) {
|
||||
bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
|
||||
tot_size += bank_size;
|
||||
}
|
||||
|
||||
mtdcr (memcfga, mem_mb1cf);
|
||||
tmp = mfdcr (memcfgd);
|
||||
if (tmp & 0x00000001) {
|
||||
bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
|
||||
tot_size += bank_size;
|
||||
}
|
||||
|
||||
mtdcr (memcfga, mem_mb2cf);
|
||||
tmp = mfdcr (memcfgd);
|
||||
if (tmp & 0x00000001) {
|
||||
bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
|
||||
tot_size += bank_size;
|
||||
}
|
||||
|
||||
mtdcr (memcfga, mem_mb3cf);
|
||||
tmp = mfdcr (memcfgd);
|
||||
if (tmp & 0x00000001) {
|
||||
bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
|
||||
tot_size += bank_size;
|
||||
}
|
||||
|
||||
return tot_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* last_stage_init: final configurations (such as PHY etc)
|
||||
*
|
||||
*/
|
||||
int last_stage_init(void)
|
||||
{
|
||||
/* initialize the PHY */
|
||||
miiphy_reset(CONFIG_PHY_ADDR);
|
||||
miiphy_write(CONFIG_PHY_ADDR, PHY_BMCR,
|
||||
PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); /* AUTO neg */
|
||||
miiphy_write(CONFIG_PHY_ADDR, PHY_FCSCR, 0x0d08); /* LEDs */
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
216
board/csb272/init.S
Normal file
216
board/csb272/init.S
Normal file
@@ -0,0 +1,216 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This source code has been made available to you by IBM on an AS-IS
|
||||
* basis. Anyone receiving this source is licensed under IBM
|
||||
* copyrights to use it in any way he or she deems fit, including
|
||||
* copying it, modifying it, compiling it, and redistributing it either
|
||||
* with or without modifications. No license under IBM patents or
|
||||
* patent applications is to be implied by the copyright license.
|
||||
*
|
||||
* Any user of this software should understand that IBM cannot provide
|
||||
* technical support for this software and will not be responsible for
|
||||
* any consequences resulting from the use of this software.
|
||||
*
|
||||
* Any person who transfers this source code or any derivative work
|
||||
* must include the IBM copyright notice, this paragraph, and the
|
||||
* preceding two paragraphs in the transferred software.
|
||||
*
|
||||
* COPYRIGHT I B M CORPORATION 1995
|
||||
* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <config.h>
|
||||
#include <ppc4xx.h>
|
||||
|
||||
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
|
||||
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
#define LI32(reg,val) \
|
||||
addis reg,0,val@h;\
|
||||
ori reg,reg,val@l
|
||||
|
||||
#define WDCR_EBC(reg,val) \
|
||||
addi r4,0,reg;\
|
||||
mtdcr ebccfga,r4;\
|
||||
addis r4,0,val@h;\
|
||||
ori r4,r4,val@l;\
|
||||
mtdcr ebccfgd,r4
|
||||
|
||||
#define WDCR_SDRAM(reg,val) \
|
||||
addi r4,0,reg;\
|
||||
mtdcr memcfga,r4;\
|
||||
addis r4,0,val@h;\
|
||||
ori r4,r4,val@l;\
|
||||
mtdcr memcfgd,r4
|
||||
|
||||
/******************************************************************************
|
||||
* Function: ext_bus_cntlr_init
|
||||
*
|
||||
* Description: Configures EBC Controller and a few basic chip selects.
|
||||
*
|
||||
* CS0 is setup to get the Boot Flash out of the addresss range
|
||||
* so that we may setup a stack. CS7 is setup so that we can
|
||||
* access and reset the hardware watchdog.
|
||||
*
|
||||
* IMPORTANT: For pass1 this code must run from
|
||||
* cache since you can not reliably change a peripheral banks
|
||||
* timing register (pbxap) while running code from that bank.
|
||||
* For ex., since we are running from ROM on bank 0, we can NOT
|
||||
* execute the code that modifies bank 0 timings from ROM, so
|
||||
* we run it from cache.
|
||||
*
|
||||
* Notes: Does NOT use the stack.
|
||||
*****************************************************************************/
|
||||
.section ".text"
|
||||
.align 2
|
||||
.globl ext_bus_cntlr_init
|
||||
.type ext_bus_cntlr_init, @function
|
||||
ext_bus_cntlr_init:
|
||||
mflr r0
|
||||
/********************************************************************
|
||||
* Prefetch entire ext_bus_cntrl_init function into the icache.
|
||||
* This is necessary because we are going to change the same CS we
|
||||
* are executing from. Otherwise a CPU lockup may occur.
|
||||
*******************************************************************/
|
||||
bl ..getAddr
|
||||
..getAddr:
|
||||
mflr r3 /* get address of ..getAddr */
|
||||
|
||||
/* Calculate number of cache lines for this function */
|
||||
addi r4, 0, (((.Lfe0 - ..getAddr) / CFG_CACHELINE_SIZE) + 2)
|
||||
mtctr r4
|
||||
..ebcloop:
|
||||
icbt r0, r3 /* prefetch cache line for addr in r3*/
|
||||
addi r3, r3, CFG_CACHELINE_SIZE /* move to next cache line */
|
||||
bdnz ..ebcloop /* continue for $CTR cache lines */
|
||||
|
||||
/********************************************************************
|
||||
* Delay to ensure all accesses to ROM are complete before changing
|
||||
* bank 0 timings. 200usec should be enough.
|
||||
* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles.
|
||||
*******************************************************************/
|
||||
addis r3, 0, 0x0
|
||||
ori r3, r3, 0xA000 /* wait 200us from reset */
|
||||
mtctr r3
|
||||
..spinlp:
|
||||
bdnz ..spinlp /* spin loop */
|
||||
|
||||
/********************************************************************
|
||||
* SETUP CPC0_CR0
|
||||
*******************************************************************/
|
||||
LI32(r4, 0x007000c0)
|
||||
mtdcr cntrl0, r4
|
||||
|
||||
/********************************************************************
|
||||
* Setup CPC0_CR1: Change PCIINT signal to PerWE
|
||||
*******************************************************************/
|
||||
mfdcr r4, cntrl1
|
||||
ori r4, r4, 0x4000
|
||||
mtdcr cntrl1, r4
|
||||
|
||||
/********************************************************************
|
||||
* Setup External Bus Controller (EBC).
|
||||
*******************************************************************/
|
||||
WDCR_EBC(epcr, 0xd84c0000)
|
||||
/********************************************************************
|
||||
* Memory Bank 0 (Intel 28F128J3 Flash) initialization
|
||||
*******************************************************************/
|
||||
/*WDCR_EBC(pb0ap, 0x02869200)*/
|
||||
WDCR_EBC(pb0ap, 0x07869200)
|
||||
WDCR_EBC(pb0cr, 0xfe0bc000)
|
||||
/********************************************************************
|
||||
* Memory Bank 1 (Holtek HT6542B PS/2) initialization
|
||||
*******************************************************************/
|
||||
WDCR_EBC(pb1ap, 0x1f869200)
|
||||
WDCR_EBC(pb1cr, 0xf0818000)
|
||||
/********************************************************************
|
||||
* Memory Bank 2 (Epson S1D13506) initialization
|
||||
*******************************************************************/
|
||||
WDCR_EBC(pb2ap, 0x05860300)
|
||||
WDCR_EBC(pb2cr, 0xf045a000)
|
||||
/********************************************************************
|
||||
* Memory Bank 3 (Philips SJA1000 CAN Controllers) initialization
|
||||
*******************************************************************/
|
||||
WDCR_EBC(pb3ap, 0x0387d200)
|
||||
WDCR_EBC(pb3cr, 0xf021c000)
|
||||
/********************************************************************
|
||||
* Memory Bank 4-7 (Unused) initialization
|
||||
*******************************************************************/
|
||||
WDCR_EBC(pb4ap, 0)
|
||||
WDCR_EBC(pb4cr, 0)
|
||||
WDCR_EBC(pb5ap, 0)
|
||||
WDCR_EBC(pb5cr, 0)
|
||||
WDCR_EBC(pb6ap, 0)
|
||||
WDCR_EBC(pb6cr, 0)
|
||||
WDCR_EBC(pb7ap, 0)
|
||||
WDCR_EBC(pb7cr, 0)
|
||||
|
||||
/* We are all done */
|
||||
mtlr r0 /* Restore link register */
|
||||
blr /* Return to calling function */
|
||||
.Lfe0: .size ext_bus_cntlr_init,.Lfe0-ext_bus_cntlr_init
|
||||
/* end ext_bus_cntlr_init() */
|
||||
|
||||
/******************************************************************************
|
||||
* Function: sdram_init
|
||||
*
|
||||
* Description: Configures SDRAM memory banks.
|
||||
*
|
||||
* Notes: Does NOT use the stack.
|
||||
*****************************************************************************/
|
||||
.section ".text"
|
||||
.align 2
|
||||
.globl sdram_init
|
||||
.type sdram_init, @function
|
||||
sdram_init:
|
||||
|
||||
/*
|
||||
* Disable memory controller to allow
|
||||
* values to be changed.
|
||||
*/
|
||||
WDCR_SDRAM(mem_mcopt1, 0x00000000)
|
||||
|
||||
/*
|
||||
* Configure Memory Banks
|
||||
*/
|
||||
WDCR_SDRAM(mem_mb0cf, 0x00084001)
|
||||
WDCR_SDRAM(mem_mb1cf, 0x00000000)
|
||||
WDCR_SDRAM(mem_mb2cf, 0x00000000)
|
||||
WDCR_SDRAM(mem_mb3cf, 0x00000000)
|
||||
|
||||
/*
|
||||
* Set up SDTR1 (SDRAM Timing Register)
|
||||
*/
|
||||
WDCR_SDRAM(mem_sdtr1, 0x00854009)
|
||||
|
||||
/*
|
||||
* Set RTR (Refresh Timing Register)
|
||||
*/
|
||||
WDCR_SDRAM(mem_rtr, 0x10000000)
|
||||
/* WDCR_SDRAM(mem_rtr, 0x05f00000) */
|
||||
|
||||
/********************************************************************
|
||||
* Delay to ensure 200usec have elapsed since reset. Assume worst
|
||||
* case that the core is running 200Mhz:
|
||||
* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles
|
||||
*******************************************************************/
|
||||
addis r3, 0, 0x0000
|
||||
ori r3, r3, 0xA000 /* Wait >200us from reset */
|
||||
mtctr r3
|
||||
..spinlp2:
|
||||
bdnz ..spinlp2 /* spin loop */
|
||||
|
||||
/********************************************************************
|
||||
* Set memory controller options reg, MCOPT1.
|
||||
*******************************************************************/
|
||||
WDCR_SDRAM(mem_mcopt1,0x80800000)
|
||||
|
||||
..sdri_done:
|
||||
blr /* Return to calling function */
|
||||
.Lfe1: .size sdram_init,.Lfe1-sdram_init
|
||||
/* end sdram_init() */
|
||||
151
board/csb272/u-boot.lds
Normal file
151
board/csb272/u-boot.lds
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
.resetvec 0xFFFFFFFC :
|
||||
{
|
||||
*(.resetvec)
|
||||
} = 0xffff
|
||||
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
cpu/ppc4xx/start.o (.text)
|
||||
board/csb272/init.o (.text)
|
||||
cpu/ppc4xx/kgdb.o (.text)
|
||||
cpu/ppc4xx/traps.o (.text)
|
||||
cpu/ppc4xx/interrupts.o (.text)
|
||||
cpu/ppc4xx/serial.o (.text)
|
||||
cpu/ppc4xx/cpu_init.o (.text)
|
||||
cpu/ppc4xx/speed.o (.text)
|
||||
cpu/ppc4xx/405gp_enet.o (.text)
|
||||
common/dlmalloc.o (.text)
|
||||
lib_generic/crc32.o (.text)
|
||||
|
||||
lib_ppc/extable.o (.text)
|
||||
lib_ppc/board.o (.text)
|
||||
lib_generic/zlib.o (.text)
|
||||
/* . = env_offset;*/
|
||||
/* common/environment.o(.text)*/
|
||||
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
}
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.str1.4)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x00FF) & 0xFFFFFF00;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(256);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(256);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
128
board/dave/B2/B2.c
Normal file
128
board/dave/B2/B2.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* (C) Copyright 2004
|
||||
* DAVE Srl
|
||||
* http://www.dave-tech.it
|
||||
* http://www.wawnet.biz
|
||||
* mailto:info@wawnet.biz
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
/*
|
||||
* Miscelaneous platform dependent initialization
|
||||
*/
|
||||
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
u32 temp;
|
||||
|
||||
/* Configuration Port Control Register*/
|
||||
/* Port A */
|
||||
PCONA = 0x3ff;
|
||||
|
||||
/* Port B */
|
||||
PCONB = 0xff;
|
||||
PDATB = 0xFFFF;
|
||||
|
||||
/* Port C */
|
||||
/*
|
||||
PCONC = 0xff55ff15;
|
||||
PDATC = 0x0;
|
||||
PUPC = 0xffff;
|
||||
*/
|
||||
|
||||
/* Port D */
|
||||
/*
|
||||
PCOND = 0xaaaa;
|
||||
PUPD = 0xff;
|
||||
*/
|
||||
|
||||
/* Port E */
|
||||
PCONE = 0x0001aaa9;
|
||||
PDATE = 0x0;
|
||||
PUPE = 0xff;
|
||||
|
||||
/* Port F */
|
||||
PCONF = 0x124955;
|
||||
PDATF = 0xff; /* B2-eth_reset tied high level */
|
||||
/*
|
||||
PUPF = 0x1e3;
|
||||
*/
|
||||
|
||||
/* Port G */
|
||||
PUPG = 0x1;
|
||||
PCONG = 0x3; /*PG0= EINT0= ETH_INT prepared for linux kernel*/
|
||||
|
||||
INTMSK = 0x03fffeff;
|
||||
INTCON = 0x05;
|
||||
|
||||
/*
|
||||
Configure chip ethernet interrupt as High level
|
||||
Port G EINT 0-7 EINT0 -> CHIP ETHERNET
|
||||
*/
|
||||
temp = EXTINT;
|
||||
temp &= ~0x7;
|
||||
temp |= 0x1; /*LEVEL_HIGH*/
|
||||
EXTINT = temp;
|
||||
|
||||
/*
|
||||
Reset SMSC LAN91C96 chip
|
||||
*/
|
||||
temp= PCONF;
|
||||
temp |= 0x00000040;
|
||||
PCONF = temp;
|
||||
|
||||
/* Reset high */
|
||||
temp = PDATF;
|
||||
temp |= (1 << 3);
|
||||
PDATF = temp;
|
||||
|
||||
/* Short delay */
|
||||
for (temp=0;temp<10;temp++)
|
||||
{
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
/* Reset low */
|
||||
temp = PDATF;
|
||||
temp &= ~(1 << 3);
|
||||
PDATF = temp;
|
||||
|
||||
/* arch number MACH_TYPE_MBA44B0 */
|
||||
gd->bd->bi_arch_number = 178;
|
||||
|
||||
/* location of boot parameters */
|
||||
gd->bd->bi_boot_params = 0x0c000100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
48
board/dave/B2/Makefile
Normal file
48
board/dave/B2/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
# Marius Groeger <mgroeger@sysgo.de>
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := B2.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $(OBJS) $(SOBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend
|
||||
|
||||
#########################################################################
|
||||
30
board/dave/B2/config.mk
Normal file
30
board/dave/B2/config.mk
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
# Marius Groeger <mgroeger@sysgo.de>
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
TEXT_BASE = 0x0C100000
|
||||
|
||||
PLATFORM_CPPFLAGS += -Uarm
|
||||
79
board/dave/B2/flash.c
Normal file
79
board/dave/B2/flash.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
/*
|
||||
* include common flash code (for esd boards)
|
||||
*/
|
||||
#include "../common/flash.c"
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (vu_long * addr, flash_info_t * info);
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
#ifdef __DEBUG_START_FROM_SRAM__
|
||||
return CFG_DUMMY_FLASH_SIZE;
|
||||
#else
|
||||
unsigned long size_b0;
|
||||
int i;
|
||||
uint pbcr;
|
||||
unsigned long base_b0;
|
||||
int size_val = 0;
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Static FLASH Bank configuration here - FIXME XXX */
|
||||
|
||||
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
size_b0, size_b0<<20);
|
||||
}
|
||||
|
||||
/* Setup offsets */
|
||||
flash_get_offsets (0, &flash_info[0]);
|
||||
|
||||
/* Monitor protection ON by default */
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
-CFG_MONITOR_LEN,
|
||||
0xffffffff,
|
||||
&flash_info[0]);
|
||||
|
||||
flash_info[0].size = size_b0;
|
||||
|
||||
return (size_b0);
|
||||
#endif
|
||||
}
|
||||
167
board/dave/B2/memsetup.S
Normal file
167
board/dave/B2/memsetup.S
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* (C) Copyright 2004
|
||||
* DAVE Srl
|
||||
*
|
||||
* http://www.dave-tech.it
|
||||
* http://www.wawnet.biz
|
||||
* mailto:info@wawnet.biz
|
||||
*
|
||||
* memsetup-sa1110.S (blob): memory setup for various SA1110 architectures
|
||||
* Modified By MATTO
|
||||
*
|
||||
* Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Documentation:
|
||||
* Intel Corporation, "Intel StrongARM SA-1110 Microprocessor
|
||||
* Advanced Developer's manual, December 1999
|
||||
*
|
||||
* Intel has a very hard to find SDRAM configurator on their web site:
|
||||
* http://appzone.intel.com/hcd/sa1110/memory/index.asp
|
||||
*
|
||||
* NOTE: This code assumes that an SA1110 CPU *always* uses SDRAM. This
|
||||
* appears to be true, but it might be possible that somebody designs a
|
||||
* board with mixed EDODRAM/SDRAM memory (which is a bad idea). -- Erik
|
||||
*
|
||||
* 04-10-2001: SELETZ
|
||||
* - separated memory config for multiple platform support
|
||||
* - perform SA1110 Hardware Reset Procedure
|
||||
*
|
||||
*/
|
||||
|
||||
.equ B0_Tacs, 0x0 /* 0clk */
|
||||
.equ B0_Tcos, 0x0 /* 0clk */
|
||||
.equ B0_Tacc, 0x4 /* 6clk */
|
||||
.equ B0_Tcoh, 0x0 /* 0clk */
|
||||
.equ B0_Tah, 0x0 /* 0clk */
|
||||
.equ B0_Tacp, 0x0 /* 0clk */
|
||||
.equ B0_PMC, 0x0 /* normal(1data) */
|
||||
/* Bank 1 parameter */
|
||||
.equ B1_Tacs, 0x3 /* 4clk */
|
||||
.equ B1_Tcos, 0x3 /* 4clk */
|
||||
.equ B1_Tacc, 0x7 /* 14clkv */
|
||||
.equ B1_Tcoh, 0x3 /* 4clk */
|
||||
.equ B1_Tah, 0x3 /* 4clk */
|
||||
.equ B1_Tacp, 0x3 /* 6clk */
|
||||
.equ B1_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 2 parameter - LAN91C96 */
|
||||
.equ B2_Tacs, 0x3 /* 4clk */
|
||||
.equ B2_Tcos, 0x3 /* 4clk */
|
||||
.equ B2_Tacc, 0x7 /* 14clk */
|
||||
.equ B2_Tcoh, 0x3 /* 4clk */
|
||||
.equ B2_Tah, 0x3 /* 4clk */
|
||||
.equ B2_Tacp, 0x3 /* 6clk */
|
||||
.equ B2_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 3 parameter */
|
||||
.equ B3_Tacs, 0x3 /* 4clk */
|
||||
.equ B3_Tcos, 0x3 /* 4clk */
|
||||
.equ B3_Tacc, 0x7 /* 14clk */
|
||||
.equ B3_Tcoh, 0x3 /* 4clk */
|
||||
.equ B3_Tah, 0x3 /* 4clk */
|
||||
.equ B3_Tacp, 0x3 /* 6clk */
|
||||
.equ B3_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 4 parameter */
|
||||
.equ B4_Tacs, 0x3 /* 4clk */
|
||||
.equ B4_Tcos, 0x3 /* 4clk */
|
||||
.equ B4_Tacc, 0x7 /* 14clk */
|
||||
.equ B4_Tcoh, 0x3 /* 4clk */
|
||||
.equ B4_Tah, 0x3 /* 4clk */
|
||||
.equ B4_Tacp, 0x3 /* 6clk */
|
||||
.equ B4_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 5 parameter */
|
||||
.equ B5_Tacs, 0x3 /* 4clk */
|
||||
.equ B5_Tcos, 0x3 /* 4clk */
|
||||
.equ B5_Tacc, 0x7 /* 14clk */
|
||||
.equ B5_Tcoh, 0x3 /* 4clk */
|
||||
.equ B5_Tah, 0x3 /* 4clk */
|
||||
.equ B5_Tacp, 0x3 /* 6clk */
|
||||
.equ B5_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 6(if SROM) parameter */
|
||||
.equ B6_Tacs, 0x3 /* 4clk */
|
||||
.equ B6_Tcos, 0x3 /* 4clk */
|
||||
.equ B6_Tacc, 0x7 /* 14clk */
|
||||
.equ B6_Tcoh, 0x3 /* 4clk */
|
||||
.equ B6_Tah, 0x3 /* 4clk */
|
||||
.equ B6_Tacp, 0x3 /* 6clk */
|
||||
.equ B6_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 7(if SROM) parameter */
|
||||
.equ B7_Tacs, 0x3 /* 4clk */
|
||||
.equ B7_Tcos, 0x3 /* 4clk */
|
||||
.equ B7_Tacc, 0x7 /* 14clk */
|
||||
.equ B7_Tcoh, 0x3 /* 4clk */
|
||||
.equ B7_Tah, 0x3 /* 4clk */
|
||||
.equ B7_Tacp, 0x3 /* 6clk */
|
||||
.equ B7_PMC, 0x0 /* normal(1data) */
|
||||
|
||||
/* Bank 6 parameter */
|
||||
.equ B6_MT, 0x3 /* SDRAM */
|
||||
.equ B6_Trcd, 0x0 /* 2clk */
|
||||
.equ B6_SCAN, 0x0 /* 10bit */
|
||||
|
||||
.equ B7_MT, 0x3 /* SDRAM */
|
||||
.equ B7_Trcd, 0x0 /* 2clk */
|
||||
.equ B7_SCAN, 0x0 /* 10bit */
|
||||
|
||||
|
||||
/* REFRESH parameter */
|
||||
.equ REFEN, 0x1 /* Refresh enable */
|
||||
.equ TREFMD, 0x0 /* CBR(CAS before RAS)/Auto refresh */
|
||||
.equ Trp, 0x0 /* 2clk */
|
||||
.equ Trc, 0x3 /* 0x1=5clk 0x3=11clk*/
|
||||
.equ Tchr, 0x0 /* 0x2=3clk 0x0=0clks */
|
||||
.equ REFCNT, 879
|
||||
|
||||
MEMORY_CONFIG:
|
||||
.long 0x12111900 /* Bank0 = OM[1:0] , Bank1-7 16bit, Bank2=Nowait,UB/LB*/
|
||||
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) /*GCS0*/
|
||||
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) /*GCS1*/
|
||||
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) /*GCS2*/
|
||||
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) /*GCS3*/
|
||||
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) /*GCS4*/
|
||||
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) /*GCS5*/
|
||||
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) /*GCS6*/
|
||||
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) /*GCS7*/
|
||||
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) /*REFRESH RFEN=1, TREFMD=0, trp=3clk, trc=5clk, tchr=3clk,count=1019*/
|
||||
.word 0x17 /*SCLK power down mode, BANKSIZE 16M/16M*/
|
||||
.word 0x20 /*MRSR6 CL=2clk*/
|
||||
.word 0x20 /*MRSR7*/
|
||||
|
||||
|
||||
.globl memsetup
|
||||
memsetup:
|
||||
|
||||
/*
|
||||
the next instruction fail due memory relocation...
|
||||
we'll find the right MEMORY_CONFIG address with the next 3 lines...
|
||||
*/
|
||||
/*ldr r0, =MEMORY_CONFIG*/
|
||||
mov r0, pc
|
||||
ldr r1, =(0x38+4)
|
||||
sub r0, r0, r1
|
||||
|
||||
ldmia r0, {r1-r13}
|
||||
ldr r0, =0x01c80000
|
||||
stmia r0, {r1-r13}
|
||||
mov pc, lr
|
||||
57
board/dave/B2/u-boot.lds
Normal file
57
board/dave/B2/u-boot.lds
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
cpu/s3c44b0/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
armboot_end_data = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
.bss : { *(.bss) }
|
||||
|
||||
armboot_end = .;
|
||||
}
|
||||
@@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ppc4xx.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
@@ -578,15 +577,27 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
for (; i<4 && cnt>0; ++i) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*src++)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | *src++;
|
||||
#endif
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt==0 && i<4; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
@@ -600,9 +611,14 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
*/
|
||||
while (cnt >= 4) {
|
||||
data = 0;
|
||||
#ifdef CONFIG_B2
|
||||
data = (*(ulong*)src);
|
||||
src += 4;
|
||||
#else
|
||||
for (i=0; i<4; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
#endif
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
@@ -619,11 +635,19 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
*/
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*src++)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | *src++;
|
||||
#endif
|
||||
--cnt;
|
||||
}
|
||||
for (; i<4; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (write_word(info, wp, data));
|
||||
|
||||
@@ -28,15 +28,33 @@
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
typedef unsigned char FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned char FLASH_PORT_WIDTHV;
|
||||
#define FLASH_ID_MASK 0xFF
|
||||
#if defined (CONFIG_TOP860)
|
||||
typedef unsigned short FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned short FLASH_PORT_WIDTHV;
|
||||
#define FLASH_ID_MASK 0xFF
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define FLASH_CYCLE1 0x0aaa
|
||||
#define FLASH_CYCLE2 0x0555
|
||||
#define FLASH_CYCLE1 0x0555
|
||||
#define FLASH_CYCLE2 0x02aa
|
||||
#define FLASH_ID1 0
|
||||
#define FLASH_ID2 1
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_TOP5200)
|
||||
typedef unsigned char FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned char FLASH_PORT_WIDTHV;
|
||||
#define FLASH_ID_MASK 0xFF
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define FLASH_CYCLE1 0x0aaa
|
||||
#define FLASH_CYCLE2 0x0555
|
||||
#define FLASH_ID1 0
|
||||
#define FLASH_ID2 2
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
@@ -179,12 +197,33 @@ void flash_print_info (flash_info_t *info)
|
||||
printf (" Sector Start Addresses:");
|
||||
|
||||
for (i=0; i<info->sector_count; ++i) {
|
||||
ulong size;
|
||||
int erased;
|
||||
ulong *flash = (unsigned long *) info->start[i];
|
||||
|
||||
if ((i % 5) == 0) {
|
||||
printf ("\n ");
|
||||
}
|
||||
|
||||
printf (" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
size =
|
||||
(i != (info->sector_count - 1)) ?
|
||||
(info->start[i + 1] - info->start[i]) >> 2 :
|
||||
(info->start[0] + info->size - info->start[i]) >> 2;
|
||||
|
||||
for (
|
||||
flash = (unsigned long *) info->start[i], erased = 1;
|
||||
(flash != (unsigned long *) info->start[i] + size) && erased;
|
||||
flash++
|
||||
)
|
||||
erased = *flash == ~0x0UL;
|
||||
|
||||
printf (" %08lX %s %s",
|
||||
info->start[i],
|
||||
erased ? "E": " ",
|
||||
info->protect[i] ? "(RO)" : " ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
@@ -212,7 +251,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
* This works for any bus width and any FLASH device width.
|
||||
*/
|
||||
udelay(100);
|
||||
switch (addr[0] & 0xff) {
|
||||
switch (addr[FLASH_ID1] & 0xff) {
|
||||
|
||||
case (uchar)AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
@@ -225,7 +264,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf ("unknown vendor=%x ", addr[0] & 0xff);
|
||||
printf ("unknown vendor=%x ", addr[FLASH_ID1] & 0xff);
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
@@ -233,7 +272,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
}
|
||||
|
||||
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
|
||||
if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[2]) {
|
||||
if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[FLASH_ID2]) {
|
||||
|
||||
case (FPW)AMD_ID_LV160B:
|
||||
info->flash_id += FLASH_AM160B;
|
||||
@@ -255,7 +294,7 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("unknown AMD device=%x ", (FPW)addr[2]);
|
||||
printf ("unknown AMD device=%x ", (FPW)addr[FLASH_ID2]);
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
|
||||
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := $(BOARD).o flash.o
|
||||
OBJS := $(BOARD).o ../common/flash.o ../common/vpd.o ../common/am79c874.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Reinhard Meyer, EMK Elektronik GmbH, r.meyer@emk-elektronik.de
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
typedef unsigned char FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned char FLASH_PORT_WIDTHV;
|
||||
#define FLASH_ID_MASK 0xFF
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define FLASH_CYCLE1 0x0aaa
|
||||
#define FLASH_CYCLE2 0x0555
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
|
||||
static void flash_reset(flash_info_t *info);
|
||||
static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
|
||||
static flash_info_t *flash_get_info(ulong base);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* flash_init()
|
||||
*
|
||||
* sets up flash_info and returns size of FLASH (bytes)
|
||||
*/
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
unsigned long size = 0;
|
||||
int i = 0;
|
||||
extern void flash_preinit(void);
|
||||
extern void flash_afterinit(uint, ulong, ulong);
|
||||
ulong flashbase = CFG_FLASH_BASE;
|
||||
|
||||
flash_preinit();
|
||||
|
||||
/* There is only ONE FLASH device */
|
||||
memset(&flash_info[i], 0, sizeof(flash_info_t));
|
||||
flash_info[i].size =
|
||||
flash_get_size((FPW *)flashbase, &flash_info[i]);
|
||||
size += flash_info[i].size;
|
||||
|
||||
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
|
||||
/* monitor protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE+monitor_flash_len-1,
|
||||
flash_get_info(CFG_MONITOR_BASE));
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ENV_IS_IN_FLASH
|
||||
/* ENV protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR+CFG_ENV_SIZE-1,
|
||||
flash_get_info(CFG_ENV_ADDR));
|
||||
#endif
|
||||
|
||||
|
||||
flash_afterinit(i, flash_info[i].start[0], flash_info[i].size);
|
||||
return size ? size : 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_reset(flash_info_t *info)
|
||||
{
|
||||
FPWV *base = (FPWV *)(info->start[0]);
|
||||
|
||||
/* Put FLASH back in read mode */
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
|
||||
*base = (FPW)0x00FF00FF; /* Intel Read Mode */
|
||||
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
|
||||
*base = (FPW)0x00F000F0; /* AMD Read Mode */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static flash_info_t *flash_get_info(ulong base)
|
||||
{
|
||||
int i;
|
||||
flash_info_t * info;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
|
||||
info = & flash_info[i];
|
||||
if (info->size &&
|
||||
info->start[0] <= base && base <= info->start[0] + info->size - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
uchar *boottype;
|
||||
uchar *bootletter;
|
||||
uchar *fmt;
|
||||
uchar botbootletter[] = "B";
|
||||
uchar topbootletter[] = "T";
|
||||
uchar botboottype[] = "bottom boot sector";
|
||||
uchar topboottype[] = "top boot sector";
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD: printf ("AMD "); break;
|
||||
#if 0
|
||||
case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break;
|
||||
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
|
||||
case FLASH_MAN_SST: printf ("SST "); break;
|
||||
case FLASH_MAN_STM: printf ("STM "); break;
|
||||
case FLASH_MAN_INTEL: printf ("INTEL "); break;
|
||||
#endif
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
/* check for top or bottom boot, if it applies */
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
boottype = botboottype;
|
||||
bootletter = botbootletter;
|
||||
}
|
||||
else {
|
||||
boottype = topboottype;
|
||||
bootletter = topbootletter;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AM160T:
|
||||
case FLASH_AM160B:
|
||||
fmt = "29LV160%s (16 Mbit, %s)\n";
|
||||
break;
|
||||
case FLASH_AMDLV065D:
|
||||
fmt = "29LV065 (64 Mbit, uniform sectors)\n";
|
||||
break;
|
||||
default:
|
||||
fmt = "Unknown Chip Type\n";
|
||||
break;
|
||||
}
|
||||
|
||||
printf (fmt, bootletter, boottype);
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20,
|
||||
info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
|
||||
for (i=0; i<info->sector_count; ++i) {
|
||||
if ((i % 5) == 0) {
|
||||
printf ("\n ");
|
||||
}
|
||||
|
||||
printf (" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
|
||||
ulong flash_get_size (FPWV *addr, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
ulong offset;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
|
||||
addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */
|
||||
addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */
|
||||
|
||||
/* The manufacturer codes are only 1 byte, so just use 1 byte.
|
||||
* This works for any bus width and any FLASH device width.
|
||||
*/
|
||||
udelay(100);
|
||||
switch (addr[0] & 0xff) {
|
||||
|
||||
case (uchar)AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case (uchar)INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
printf ("unknown vendor=%x ", addr[0] & 0xff);
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
|
||||
if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[2]) {
|
||||
|
||||
case (FPW)AMD_ID_LV160B:
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
#ifdef CFG_LOWBOOT
|
||||
offset = 0;
|
||||
#else
|
||||
offset = 0x00e00000;
|
||||
#endif
|
||||
info->start[0] = (ulong)addr + offset;
|
||||
info->start[1] = (ulong)addr + offset + 0x4000;
|
||||
info->start[2] = (ulong)addr + offset + 0x6000;
|
||||
info->start[3] = (ulong)addr + offset + 0x8000;
|
||||
for (i = 4; i < info->sector_count; i++)
|
||||
{
|
||||
info->start[i] = (ulong)addr + offset + 0x10000 * (i-3);
|
||||
}
|
||||
break;
|
||||
|
||||
case (FPW)AMD_ID_LV065D:
|
||||
info->flash_id += FLASH_AMDLV065D;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x00800000;
|
||||
#ifdef CFG_LOWBOOT
|
||||
offset = 0;
|
||||
#else
|
||||
offset = 0x00800000;
|
||||
#endif
|
||||
for( i = 0; i < info->sector_count; i++ )
|
||||
info->start[i] = (ulong)addr + offset + (i * 0x10000);
|
||||
break; /* => 8 or 16 MB */
|
||||
|
||||
default:
|
||||
printf ("unknown AMD device=%x ", (FPW)addr[2]);
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* => no or unknown flash */
|
||||
}
|
||||
|
||||
/* Put FLASH back in read mode */
|
||||
flash_reset(info);
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
FPWV *addr;
|
||||
int flag, prot, sect;
|
||||
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
|
||||
ulong start, now, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AMDLV065D:
|
||||
break;
|
||||
case FLASH_UNKNOWN:
|
||||
default:
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
last = get_timer(0);
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
|
||||
|
||||
if (info->protect[sect] != 0) /* protected, skip it */
|
||||
continue;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
addr = (FPWV *)(info->start[sect]);
|
||||
if (intel) {
|
||||
*addr = (FPW)0x00500050; /* clear status register */
|
||||
*addr = (FPW)0x00200020; /* erase setup */
|
||||
*addr = (FPW)0x00D000D0; /* erase confirm */
|
||||
}
|
||||
else {
|
||||
/* must be AMD style if not Intel */
|
||||
FPWV *base; /* first address in bank */
|
||||
|
||||
base = (FPWV *)(info->start[0]);
|
||||
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
|
||||
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
|
||||
base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */
|
||||
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
|
||||
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
|
||||
*addr = (FPW)0x00300030; /* erase sector */
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
start = get_timer(0);
|
||||
|
||||
/* wait at least 50us for AMD, 80us for Intel.
|
||||
* Let's wait 1 ms.
|
||||
*/
|
||||
udelay (1000);
|
||||
|
||||
while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
|
||||
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
|
||||
if (intel) {
|
||||
/* suspend erase */
|
||||
*addr = (FPW)0x00B000B0;
|
||||
}
|
||||
|
||||
flash_reset(info); /* reset to read mode */
|
||||
rcode = 1; /* failed */
|
||||
break;
|
||||
}
|
||||
|
||||
/* show that we're waiting */
|
||||
if ((get_timer(last)) > CFG_HZ) {/* every second */
|
||||
putc ('.');
|
||||
last = get_timer(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* show that we're waiting */
|
||||
if ((get_timer(last)) > CFG_HZ) { /* every second */
|
||||
putc ('.');
|
||||
last = get_timer(0);
|
||||
}
|
||||
|
||||
flash_reset(info); /* reset to read mode */
|
||||
}
|
||||
|
||||
printf (" done\n");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
|
||||
int bytes; /* number of bytes to program in current word */
|
||||
int left; /* number of bytes left to program */
|
||||
int i, res;
|
||||
|
||||
for (left = cnt, res = 0;
|
||||
left > 0 && res == 0;
|
||||
addr += sizeof(data), left -= sizeof(data) - bytes) {
|
||||
|
||||
bytes = addr & (sizeof(data) - 1);
|
||||
addr &= ~(sizeof(data) - 1);
|
||||
|
||||
/* combine source and destination data so can program
|
||||
* an entire word of 16 or 32 bits
|
||||
*/
|
||||
for (i = 0; i < sizeof(data); i++) {
|
||||
data <<= 8;
|
||||
if (i < bytes || i - bytes >= left )
|
||||
data += *((uchar *)addr + i);
|
||||
else
|
||||
data += *src++;
|
||||
}
|
||||
|
||||
/* write one word to the flash */
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
res = write_word_amd(info, (FPWV *)addr, data);
|
||||
break;
|
||||
default:
|
||||
/* unknown flash type, error! */
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
res = 1; /* not really a timeout, but gives error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash for AMD FLASH
|
||||
* A word is 16 or 32 bits, whichever the bus width of the flash bank
|
||||
* (not an individual chip) is.
|
||||
*
|
||||
* returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
|
||||
{
|
||||
ulong start;
|
||||
int flag;
|
||||
int res = 0; /* result, assume success */
|
||||
FPWV *base; /* first address in flash bank */
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*dest & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
|
||||
|
||||
base = (FPWV *)(info->start[0]);
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
|
||||
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
|
||||
base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */
|
||||
|
||||
*dest = data; /* start programming the data */
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
start = get_timer (0);
|
||||
|
||||
/* data polling for D7 */
|
||||
while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*dest = (FPW)0x00F000F0; /* reset bank */
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
@@ -156,53 +156,9 @@ void flash_afterinit(uint bank, ulong start, ulong size)
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/* read 'factory' part of EEPROM */
|
||||
uchar buf[81];
|
||||
uchar *p;
|
||||
uint length;
|
||||
uint addr;
|
||||
uint len;
|
||||
extern void read_factory_r (void);
|
||||
read_factory_r ();
|
||||
|
||||
/* get length first */
|
||||
addr = CFG_FACT_OFFSET;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, 2)) {
|
||||
bailout:
|
||||
printf ("cannot read factory configuration\n");
|
||||
printf ("be sure to set ethaddr yourself!\n");
|
||||
return 0;
|
||||
}
|
||||
length = buf[0] + (buf[1] << 8);
|
||||
addr += 2;
|
||||
|
||||
/* sanity check */
|
||||
if (length < 20 || length > CFG_FACT_SIZE - 2)
|
||||
goto bailout;
|
||||
|
||||
/* read lines */
|
||||
while (length > 0) {
|
||||
/* read one line */
|
||||
len = length > 80 ? 80 : length;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, len))
|
||||
goto bailout;
|
||||
/* mark end of buffer */
|
||||
buf[len] = 0;
|
||||
/* search end of line */
|
||||
for (p = buf; *p && *p != 0x0a; p++);
|
||||
if (!*p)
|
||||
goto bailout;
|
||||
*p++ = 0;
|
||||
/* advance to next line start */
|
||||
length -= p - buf;
|
||||
addr += p - buf;
|
||||
/*printf ("%s\n", buf); */
|
||||
/* search for our specific entry */
|
||||
if (!strncmp ((char *) buf, "[RLA/lan/Ethernet] ", 19)) {
|
||||
setenv ("ethaddr", buf + 19);
|
||||
} else if (!strncmp ((char *) buf, "[BOARD/SERIAL] ", 15)) {
|
||||
setenv ("serial#", buf + 15);
|
||||
} else if (!strncmp ((char *) buf, "[BOARD/TYPE] ", 13)) {
|
||||
setenv ("board_id", buf + 13);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o
|
||||
OBJS = $(BOARD).o ../common/flash.o ../common/vpd.o ../common/am79c874.o
|
||||
|
||||
$(LIB): .depend $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
@@ -1,489 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* EMK Elektronik GmbH <www.emk-elektronik.de>
|
||||
* Reinhard Meyer <r.meyer@emk-elektronik.de>
|
||||
*
|
||||
* copied from the BMW Port - seems that its similiar enough
|
||||
* to be easily adaped ;) --- Well, it turned out to become a
|
||||
* merger between parts of the EMKstax Flash routines and the
|
||||
* BMW funtion frames...
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
#define FLASH_WORD_SIZE unsigned short
|
||||
#define FLASH_WORD_WIDTH (sizeof (FLASH_WORD_SIZE))
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* software product ID entry/exit
|
||||
*****************************************************************************/
|
||||
static void FlashProductIdMode (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
int on_off)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = on_off ? 0x90 : 0xf0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* sector erase start
|
||||
*****************************************************************************/
|
||||
static void FlashSectorErase (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
volatile FLASH_WORD_SIZE *a)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = 0x80;
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
a[0] = 0x30;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* program a word
|
||||
*****************************************************************************/
|
||||
static void FlashProgWord (
|
||||
volatile FLASH_WORD_SIZE *b,
|
||||
volatile FLASH_WORD_SIZE *a,
|
||||
FLASH_WORD_SIZE v)
|
||||
{
|
||||
b[0x5555] = 0xaa;
|
||||
b[0x2aaa] = 0x55;
|
||||
b[0x5555] = 0xa0;
|
||||
a[0] = v;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* reset bank, back to read mode
|
||||
*****************************************************************************/
|
||||
static void FlashReset (volatile FLASH_WORD_SIZE *b)
|
||||
{
|
||||
b[0] = 0xf0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* identify FLASH chip
|
||||
* this code is a stripped version of the FlashGetType() function in EMKstax
|
||||
*****************************************************************************/
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE * const flash = (volatile FLASH_WORD_SIZE *) CFG_FLASH_BASE;
|
||||
FLASH_WORD_SIZE manu, dev;
|
||||
flash_info_t * const pflinfo = &flash_info[0];
|
||||
int j;
|
||||
|
||||
/* get Id Bytes */
|
||||
FlashProductIdMode (flash, 1);
|
||||
manu = flash[0];
|
||||
dev = flash[1];
|
||||
FlashProductIdMode (flash, 0);
|
||||
|
||||
pflinfo->size = 0;
|
||||
pflinfo->sector_count = 0;
|
||||
pflinfo->flash_id = 0xffffffff;
|
||||
pflinfo->portwidth = FLASH_CFI_16BIT;
|
||||
pflinfo->chipwidth = FLASH_CFI_BY16;
|
||||
|
||||
switch (manu&0xff)
|
||||
{
|
||||
case 0x01: /* AMD */
|
||||
pflinfo->flash_id = FLASH_MAN_AMD;
|
||||
switch (dev&0xff)
|
||||
{
|
||||
case 0x49:
|
||||
pflinfo->size = 0x00200000;
|
||||
pflinfo->sector_count = 35;
|
||||
pflinfo->flash_id |= FLASH_AM160B;
|
||||
pflinfo->start[0] = CFG_FLASH_BASE;
|
||||
pflinfo->start[1] = CFG_FLASH_BASE + 0x4000;
|
||||
pflinfo->start[2] = CFG_FLASH_BASE + 0x6000;
|
||||
pflinfo->start[3] = CFG_FLASH_BASE + 0x8000;
|
||||
for (j = 4; j < 35; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-3);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xf9:
|
||||
pflinfo->size = 0x00400000;
|
||||
pflinfo->sector_count = 71;
|
||||
pflinfo->flash_id |= FLASH_AM320B;
|
||||
pflinfo->start[0] = CFG_FLASH_BASE;
|
||||
pflinfo->start[1] = CFG_FLASH_BASE + 0x4000;
|
||||
pflinfo->start[2] = CFG_FLASH_BASE + 0x6000;
|
||||
pflinfo->start[3] = CFG_FLASH_BASE + 0x8000;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00002000 * (j);
|
||||
}
|
||||
for (j = 8; j < 71; j++)
|
||||
{
|
||||
pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-7);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("unknown AMD dev=%x ", dev);
|
||||
pflinfo->flash_id |= FLASH_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("unknown manu=%x ", manu);
|
||||
}
|
||||
return pflinfo->size;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* print info about a FLASH
|
||||
*****************************************************************************/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
static const char unk[] = "Unknown";
|
||||
unsigned int i;
|
||||
const char *mfct=unk,
|
||||
*type=unk;
|
||||
|
||||
if(info->flash_id != FLASH_UNKNOWN)
|
||||
{
|
||||
switch (info->flash_id & FLASH_VENDMASK)
|
||||
{
|
||||
case FLASH_MAN_AMD:
|
||||
mfct = "AMD";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK)
|
||||
{
|
||||
case FLASH_AM160B:
|
||||
type = "AM29LV160B (16 Mbit, bottom boot sect)";
|
||||
break;
|
||||
case FLASH_AM320B:
|
||||
type = "AM29LV320B (32 Mbit, bottom boot sect)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf (
|
||||
"\n Brand: %s Type: %s\n"
|
||||
" Size: %lu KB in %d Sectors\n",
|
||||
mfct,
|
||||
type,
|
||||
info->size >> 10,
|
||||
info->sector_count
|
||||
);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned int erased;
|
||||
unsigned long *flash = (unsigned long *) info->start[i];
|
||||
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
size =
|
||||
(i != (info->sector_count - 1)) ?
|
||||
(info->start[i + 1] - info->start[i]) >> 2 :
|
||||
(info->start[0] + info->size - info->start[i]) >> 2;
|
||||
|
||||
for (
|
||||
flash = (unsigned long *) info->start[i], erased = 1;
|
||||
(flash != (unsigned long *) info->start[i] + size) && erased;
|
||||
flash++
|
||||
)
|
||||
erased = *flash == ~0x0UL;
|
||||
|
||||
printf (
|
||||
"%s %08lX %s %s",
|
||||
(i % 5) ? "" : "\n ",
|
||||
info->start[i],
|
||||
erased ? "E" : " ",
|
||||
info->protect[i] ? "RO" : " "
|
||||
);
|
||||
}
|
||||
|
||||
puts ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* erase one or more sectors
|
||||
*****************************************************************************/
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
|
||||
int flag,
|
||||
prot,
|
||||
sect,
|
||||
l_sect;
|
||||
ulong start,
|
||||
now,
|
||||
last;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last))
|
||||
{
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
{
|
||||
printf ("- missing\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((info->flash_id == FLASH_UNKNOWN) ||
|
||||
(info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP)))
|
||||
{
|
||||
printf ("Can't erase unknown flash type - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect=s_first; sect<=s_last; ++sect)
|
||||
{
|
||||
if (info->protect[sect])
|
||||
{
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot)
|
||||
{
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
l_sect = -1;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++)
|
||||
{
|
||||
if (info->protect[sect] == 0)
|
||||
{ /* not protected */
|
||||
FlashSectorErase ((FLASH_WORD_SIZE *)info->start[0], (FLASH_WORD_SIZE *)info->start[sect]);
|
||||
l_sect = sect;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
/*
|
||||
* We wait for the last triggered sector
|
||||
*/
|
||||
if (l_sect < 0)
|
||||
goto DONE;
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
addr = (FLASH_WORD_SIZE *)info->start[l_sect];
|
||||
while ((addr[0] & 0x0080) != 0x0080)
|
||||
{
|
||||
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT)
|
||||
{
|
||||
printf ("Timeout\n");
|
||||
return 1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000)
|
||||
{ /* every second */
|
||||
serial_putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
/* reset to read mode */
|
||||
FlashReset ((FLASH_WORD_SIZE *)info->start[0]);
|
||||
|
||||
printf (" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*****************************************************************************/
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp,
|
||||
wp,
|
||||
data;
|
||||
int i,
|
||||
l,
|
||||
rc;
|
||||
|
||||
wp = (addr & ~(FLASH_WORD_WIDTH-1)); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes, if there are...
|
||||
*/
|
||||
if ((l = addr - wp) != 0)
|
||||
{
|
||||
data = 0;
|
||||
|
||||
/* get the current before the new data into our data word */
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now merge the to be programmed values */
|
||||
for (; i<4 && cnt>0; ++i, ++cp, --cnt)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
|
||||
/* get the current after the new data into our data word */
|
||||
for (; cnt==0 && i<FLASH_WORD_WIDTH; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now write the combined word */
|
||||
if ((rc = write_word (info, wp, data)) != 0)
|
||||
{
|
||||
return (rc);
|
||||
}
|
||||
wp += FLASH_WORD_WIDTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= FLASH_WORD_WIDTH)
|
||||
{
|
||||
data = 0;
|
||||
for (i=0; i<FLASH_WORD_WIDTH; ++i)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_word (info, wp, data)) != 0)
|
||||
{
|
||||
return (rc);
|
||||
}
|
||||
wp += FLASH_WORD_WIDTH;
|
||||
cnt -= FLASH_WORD_WIDTH;
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes, if there are...
|
||||
*/
|
||||
data = 0;
|
||||
|
||||
/* now merge the to be programmed values */
|
||||
for (i=0, cp=wp; i<FLASH_WORD_WIDTH && cnt>0; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
|
||||
/* get the current after the new data into our data word */
|
||||
for (; i<FLASH_WORD_WIDTH; ++i, ++cp)
|
||||
{
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
}
|
||||
|
||||
/* now write the combined word */
|
||||
return (write_word (info, wp, data));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*****************************************************************************/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data)
|
||||
{
|
||||
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)info->start[0];
|
||||
volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
|
||||
FLASH_WORD_SIZE data2 = data;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*dest2 & data2) != data2)
|
||||
{
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
FlashProgWord (addr2, dest2, data2);
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((*dest2 & 0x0080) != (data2 & 0x0080))
|
||||
{
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -119,6 +119,20 @@ long int initdram (int board_type)
|
||||
return -(memctl->memc_or2 & 0xffff0000);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* prepare for FLASH detection
|
||||
*****************************************************************************/
|
||||
void flash_preinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* finalize FLASH setup
|
||||
*****************************************************************************/
|
||||
void flash_afterinit(uint bank, ulong start, ulong size)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* otherinits after RAM is there and we are relocated to RAM
|
||||
* note: though this is an int function, nobody cares for the result!
|
||||
@@ -126,52 +140,8 @@ long int initdram (int board_type)
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/* read 'factory' part of EEPROM */
|
||||
uchar buf[81];
|
||||
uchar *p;
|
||||
uint length;
|
||||
uint addr;
|
||||
uint len;
|
||||
extern void read_factory_r (void);
|
||||
read_factory_r ();
|
||||
|
||||
/* get length first */
|
||||
addr = CFG_FACT_OFFSET;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, 2)) {
|
||||
bailout:
|
||||
printf ("cannot read factory configuration\n");
|
||||
printf ("be sure to set ethaddr yourself!\n");
|
||||
return 0;
|
||||
}
|
||||
length = buf[0] + (buf[1] << 8);
|
||||
addr += 2;
|
||||
|
||||
/* sanity check */
|
||||
if (length < 20 || length > CFG_FACT_SIZE - 2)
|
||||
goto bailout;
|
||||
|
||||
/* read lines */
|
||||
while (length > 0) {
|
||||
/* read one line */
|
||||
len = length > 80 ? 80 : length;
|
||||
if (eeprom_read (CFG_I2C_FACT_ADDR, addr, buf, len))
|
||||
goto bailout;
|
||||
/* mark end of buffer */
|
||||
buf[len] = 0;
|
||||
/* search end of line */
|
||||
for (p = buf; *p && *p != 0x0a; p++);
|
||||
if (!*p)
|
||||
goto bailout;
|
||||
*p++ = 0;
|
||||
/* advance to next line start */
|
||||
length -= p - buf;
|
||||
addr += p - buf;
|
||||
/*printf ("%s\n", buf); */
|
||||
/* search for our specific entry */
|
||||
if (!strncmp ((char *) buf, "[RLA/lan/Ethernet] ", 19)) {
|
||||
setenv ("ethaddr", buf + 19);
|
||||
} else if (!strncmp ((char *) buf, "[BOARD/SERIAL] ", 15)) {
|
||||
setenv ("serial#", buf + 15);
|
||||
} else if (!strncmp ((char *) buf, "[BOARD/TYPE] ", 13)) {
|
||||
setenv ("board_id", buf + 13);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -2747,4 +2747,4 @@
|
||||
0x05,0x02,0x02,0x03,0x02,0x02,0x03,0x02,0x02,0x01,0x07,0x03,0x02,0x02,0x02,0x04,
|
||||
0x02,0x01,0x04,0x02,0x01,0x02,0x01,0x02,0x01,0x01,0xe5,0x05,0x04,0x03,0x07,0xe5,
|
||||
0xe5,0x03,0x04,0x04,0x0b,0x02,0xe5,0x01,0xe5,0x01,0xe5,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
|
||||
@@ -341,11 +341,7 @@ static int setup_sdram_common (sdram_info_t info[2])
|
||||
tras_clocks = info[0].tras_clocks;
|
||||
if (!info[0].registered)
|
||||
registered = 0;
|
||||
if (info[0].ecc != 2indent: Standard input:491: Warning:old style assignment ambiguity in "=*". Assuming "= *"
|
||||
|
||||
indent: Standard input:492: Warning:old style assignment ambiguity in "=*". Assuming "= *"
|
||||
|
||||
)
|
||||
if (info[0].ecc != 2)
|
||||
ecc = 0;
|
||||
}
|
||||
|
||||
|
||||
47
board/modnet50/Makefile
Normal file
47
board/modnet50/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := modnet50.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend
|
||||
|
||||
#########################################################################
|
||||
29
board/modnet50/config.mk
Normal file
29
board/modnet50/config.mk
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
# Marius Groeger <mgroeger@sysgo.de>
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
TEXT_BASE = 0x00f00000
|
||||
#CROSS_COMPILE = arm-elf-
|
||||
536
board/modnet50/flash.c
Normal file
536
board/modnet50/flash.c
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* MAZeT GmbH <www.mazet.de>
|
||||
* Stephan Linz <linz@mazet.de>, <linz@li-pro.net>
|
||||
*
|
||||
* The most stuff comes from PPCBoot and Linux.
|
||||
*
|
||||
* IMMS gGmbH <www.imms.de>
|
||||
* Thomas Elste <info@elste.org>
|
||||
*
|
||||
* Modifications for ModNET50 Board
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/netarm_registers.h>
|
||||
|
||||
#define SCR (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_SYSTEM_CONTROL))
|
||||
|
||||
#define ALIGN_ABORT_OFF SCR = SCR & ~NETARM_GEN_SYS_CFG_ALIGN_ABORT
|
||||
#define ALIGN_ABORT_ON SCR = SCR | NETARM_GEN_SYS_CFG_ALIGN_ABORT
|
||||
|
||||
#define PROG_ADDR (0x555*2)
|
||||
#define SETUP_ADDR (0x555*2)
|
||||
#define ID_ADDR (0x555*2)
|
||||
#define UNLOCK_ADDR1 (0x555*2)
|
||||
#define UNLOCK_ADDR2 (0x2AA*2)
|
||||
|
||||
#define UNLOCK_CMD1 (0xAA)
|
||||
#define UNLOCK_CMD2 (0x55)
|
||||
#define ERASE_SUSPEND_CMD (0xB0)
|
||||
#define ERASE_RESUME_CMD (0x30)
|
||||
#define RESET_CMD (0xF0)
|
||||
#define ID_CMD (0x90)
|
||||
#define SECERASE_CMD (0x30)
|
||||
#define CHIPERASE_CMD (0x10)
|
||||
#define PROG_CMD (0xa0)
|
||||
#define SETUP_CMD (0x80)
|
||||
|
||||
#define DQ2 (0x04)
|
||||
#define DQ3 (DQ2*2)
|
||||
#define DQ5 (DQ3*4)
|
||||
#define DQ6 (DQ5*2)
|
||||
|
||||
#define WRITE_UNLOCK(addr) { \
|
||||
*(volatile __u16*)(addr + UNLOCK_ADDR1) = (__u16)UNLOCK_CMD1; \
|
||||
*(volatile __u16*)(addr + UNLOCK_ADDR2) = (__u16)UNLOCK_CMD2; \
|
||||
}
|
||||
|
||||
#define CONFIG_AM29_RESERVED (0)
|
||||
#define K (1024)
|
||||
#define MB (4)
|
||||
|
||||
#define CELL_SIZE (64*K)
|
||||
#define DEVICE_SIZE (MB*K*K)
|
||||
#define CELLS_PER_DEVICE (DEVICE_SIZE/CELL_SIZE)
|
||||
#define RESERVED_CELLS (CONFIG_AM29_RESERVED*K)/CELL_SIZE
|
||||
#define MAX_FLASH_DEVICES (1)
|
||||
#define AVAIL_SIZE (DEVICE_SIZE*MAX_FLASH_DEVICES - RESERVED_CELLS*CELL_SIZE)
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
static __u16 toggling_bits;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
ulong flash_get_size (ulong baseaddr, flash_info_t * info)
|
||||
{
|
||||
short i;
|
||||
__u16 flashtest;
|
||||
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
WRITE_UNLOCK (baseaddr);
|
||||
*(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) ID_CMD;
|
||||
flashtest /* manufacturer ID */ = *(volatile __u16 *) (baseaddr);
|
||||
*(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) RESET_CMD;
|
||||
|
||||
switch ((__u32) ((flashtest << 16) + flashtest)) {
|
||||
case AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD & FLASH_VENDMASK;
|
||||
break;
|
||||
case FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ & FLASH_VENDMASK;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
WRITE_UNLOCK (baseaddr);
|
||||
*(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) ID_CMD;
|
||||
flashtest /* device ID */ = *(volatile __u16 *) (baseaddr + 2);
|
||||
*(volatile __u16 *) (baseaddr + ID_ADDR) = (__u16) RESET_CMD;
|
||||
|
||||
/* toggling_bits = (flashtest == TOSHIBA)?(DQ6):(DQ2|DQ6); */
|
||||
toggling_bits = (DQ2 | DQ6);
|
||||
|
||||
switch ((__u32) ((flashtest << 16) + flashtest)) {
|
||||
case AMD_ID_LV160B:
|
||||
info->flash_id +=
|
||||
(FLASH_AM160LV | FLASH_AM160B) & FLASH_TYPEMASK;
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
info->size = CFG_FLASH_SIZE;
|
||||
/* 1*16K Boot Block
|
||||
2*8K Parameter Block
|
||||
1*32K Small Main Block */
|
||||
info->start[0] = baseaddr;
|
||||
info->start[1] = baseaddr + 0x4000;
|
||||
info->start[2] = baseaddr + 0x6000;
|
||||
info->start[3] = baseaddr + 0x8000;
|
||||
for (i = 1; i < info->sector_count; i++)
|
||||
info->start[3 + i] = baseaddr + i * CFG_MAIN_SECT_SIZE;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* Write auto select command sequence and test FLASH answer */
|
||||
WRITE_UNLOCK (info->start[i]);
|
||||
*(volatile __u16 *) (info->start[i] + ID_ADDR) = (__u16) ID_CMD;
|
||||
flashtest /* protected verify */ = *(volatile __u16 *) (info->start[i] + 4);
|
||||
*(volatile __u16 *) (info->start[i] + ID_ADDR) = (__u16) RESET_CMD;
|
||||
if (flashtest & 0x0001) {
|
||||
info->protect[i] = 1; /* D0 = 1 if protected */
|
||||
} else {
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
ulong flash_init (void)
|
||||
{
|
||||
ulong size = 0;
|
||||
int i;
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Static FLASH Bank configuration here (only one bank) */
|
||||
size = flash_get_size (CFG_FLASH_BASE, &flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN || size == 0) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
size, size >> 20);
|
||||
}
|
||||
|
||||
/*
|
||||
* protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0]);
|
||||
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t * info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
printf ("AMD ");
|
||||
break;
|
||||
case FLASH_MAN_FUJ:
|
||||
printf ("Fujitsu ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AMDL323B:
|
||||
printf ("29DL323B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case (FLASH_AM160LV | FLASH_AM160B):
|
||||
printf ("29LV160BE (1M x 16, bottom sector)\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
if ((i % 4) == 0)
|
||||
printf ("\n ");
|
||||
printf (" S%02d @ 0x%08lX%s", i,
|
||||
info->start[i], info->protect[i] ? " !" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
int flash_check_protection (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
int sect, prot = 0;
|
||||
|
||||
for (sect = s_first; sect <= s_last; sect++)
|
||||
if (info->protect[sect])
|
||||
prot++;
|
||||
if (prot)
|
||||
printf ("- can't erase %d protected sectors\n", prot);
|
||||
return prot;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
int flash_check_erase_amd (ulong start)
|
||||
{
|
||||
__u16 v1, v2;
|
||||
|
||||
v1 = *(volatile __u16 *) (start);
|
||||
v2 = *(volatile __u16 *) (start);
|
||||
|
||||
if (((v1 ^ v2) & toggling_bits) == toggling_bits) {
|
||||
if (((v1 | v2) & DQ5) == DQ5) {
|
||||
printf ("[DQ5] ");
|
||||
/* OOPS: exceeded timing limits */
|
||||
|
||||
v1 = *(volatile __u16 *) (start);
|
||||
v2 = *(volatile __u16 *) (start);
|
||||
|
||||
if (((v1 ^ v2) & toggling_bits) == toggling_bits) {
|
||||
|
||||
printf ("[%s] ",
|
||||
((toggling_bits & (DQ2 | DQ6)) ==
|
||||
(DQ2 | DQ6)) ? "DQ2,DQ6" : "DQ6");
|
||||
|
||||
/* OOPS: there is an erasure in progress,
|
||||
* try to reset chip */
|
||||
*(volatile __u16 *) (start) =
|
||||
(__u16) RESET_CMD;
|
||||
|
||||
return 1; /* still busy */
|
||||
}
|
||||
}
|
||||
return 1; /* still busy */
|
||||
}
|
||||
return 0; /* be free */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
int flag, sect, setup_offset = 0;
|
||||
int rc = ERR_OK;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
return ERR_UNKNOWN_FLASH_TYPE;
|
||||
}
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
printf ("- no sectors to erase\n");
|
||||
return ERR_INVAL;
|
||||
}
|
||||
|
||||
if (flash_check_protection (info, s_first, s_last))
|
||||
return ERR_PROTECTED;
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_FUJ:
|
||||
case FLASH_MAN_AMD:
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (FLASH_AM160LV | FLASH_AM160B):
|
||||
setup_offset = UNLOCK_ADDR1; /* just the adress for setup_cmd differs */
|
||||
case FLASH_AMDL323B:
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
flag = disable_interrupts ();
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last && !ctrlc ();
|
||||
sect++) {
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
if (info->protect[sect] == 0) {
|
||||
/* not protected */
|
||||
/* Write sector erase command sequence */
|
||||
WRITE_UNLOCK (info->start[0]);
|
||||
*(volatile __u16 *) (info->start[0] +
|
||||
setup_offset) =
|
||||
(__u16) SETUP_CMD;
|
||||
WRITE_UNLOCK (info->start[0]);
|
||||
*(volatile __u16 *) (info->
|
||||
start[sect]) =
|
||||
(__u16) SECERASE_CMD;
|
||||
|
||||
/* wait some time */
|
||||
reset_timer_masked ();
|
||||
while (get_timer_masked () < 1000) {
|
||||
}
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
while (flash_check_erase_amd (info->start[sect])) {
|
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("timeout!\n");
|
||||
/* OOPS: reach timeout,
|
||||
* try to reset chip
|
||||
*/
|
||||
*(volatile __u16 *) (info-> start[sect]) = (__u16) RESET_CMD;
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere_323B;
|
||||
}
|
||||
}
|
||||
printf ("ok.\n");
|
||||
} else {
|
||||
printf ("protected!\n");
|
||||
}
|
||||
}
|
||||
if (ctrlc ())
|
||||
printf ("User Interrupt!\n");
|
||||
outahere_323B:
|
||||
/* allow flash to settle - wait 10 ms */
|
||||
udelay_masked (10000);
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
return rc;
|
||||
default:
|
||||
printf ("- unknown chip type\n");
|
||||
return ERR_UNKNOWN_FLASH_TYPE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf ("- unknown vendor ");
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
int flash_check_write_amd (ulong dest)
|
||||
{
|
||||
__u16 v1, v2;
|
||||
|
||||
v1 = *(volatile __u16 *) (dest);
|
||||
v2 = *(volatile __u16 *) (dest);
|
||||
|
||||
/* DQ6 toggles during write */
|
||||
if (((v1 ^ v2) & DQ6) == DQ6) {
|
||||
if (((v1 | v2) & DQ5) == DQ5) {
|
||||
printf ("[DQ5] @ %08lX\n", dest);
|
||||
|
||||
/* OOPS: exceeded timing limits,
|
||||
* try to reset chip */
|
||||
*(volatile __u16 *) (dest) = (__u16) RESET_CMD;
|
||||
return 0; /* be free */
|
||||
}
|
||||
return 1; /* still busy */
|
||||
}
|
||||
|
||||
return 0; /* be free */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash
|
||||
*/
|
||||
static int write_word (flash_info_t * info, ulong dest, ushort data)
|
||||
{
|
||||
int rc = ERR_OK;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*(__u16 *) (dest) & data) != data)
|
||||
return ERR_NOT_ERASED;
|
||||
|
||||
/*
|
||||
* Disable interrupts which might cause a timeout
|
||||
* here. Remember that our exception vectors are
|
||||
* at address 0 in the flash, and we don't want a
|
||||
* (ticker) exception to happen while the flash
|
||||
* chip is in programming mode.
|
||||
*/
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Write program command sequence */
|
||||
WRITE_UNLOCK (info->start[0]);
|
||||
|
||||
/* Flash dependend program seqence */
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_FUJ:
|
||||
case FLASH_MAN_AMD:
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (FLASH_AM160LV | FLASH_AM160B):
|
||||
*(volatile __u16 *) (info->start[0] + UNLOCK_ADDR1) =
|
||||
(__u16) PROG_CMD;
|
||||
*(volatile __u16 *) (dest) = (__u16) data;
|
||||
break;
|
||||
case FLASH_AMDL323B:
|
||||
*(volatile __u16 *) (dest) = (__u16) PROG_CMD;
|
||||
*(volatile __u16 *) (dest) = (__u16) data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
while (flash_check_write_amd (dest)) {
|
||||
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
|
||||
printf ("timeout! @ %08lX\n", dest);
|
||||
/* OOPS: reach timeout,
|
||||
* try to reset chip */
|
||||
*(volatile __u16 *) (dest) = (__u16) RESET_CMD;
|
||||
|
||||
rc = ERR_TIMOUT;
|
||||
goto outahere_323B;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if Flash was (accurately) written */
|
||||
if (*(__u16 *) (dest) != data)
|
||||
rc = ERR_PROG_ERROR;
|
||||
|
||||
outahere_323B:
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash.
|
||||
*/
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
ushort data;
|
||||
int l;
|
||||
int i, rc;
|
||||
|
||||
wp = (addr & ~1); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
for (; i < 2 && cnt > 0; ++i) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < 2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
|
||||
if ((rc = write_word (info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 2) {
|
||||
data = *((ushort *) src);
|
||||
if ((rc = write_word (info, wp, data)) != 0)
|
||||
return (rc);
|
||||
src += 2;
|
||||
wp += 2;
|
||||
cnt -= 2;
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
return ERR_OK;
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
|
||||
data = (data >> 8) | (*src++ << 8);
|
||||
--cnt;
|
||||
}
|
||||
for (; i < 2; ++i, ++cp) {
|
||||
data = (data >> 8) | (*(uchar *) cp << 8);
|
||||
}
|
||||
|
||||
return write_word (info, wp, data);
|
||||
}
|
||||
204
board/modnet50/memsetup.S
Normal file
204
board/modnet50/memsetup.S
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Memory Setup stuff - taken from Linux
|
||||
*
|
||||
* Copyright (c) 2002 Stephan Linz <linz@mazet.de>, <linz@li-pro.net>
|
||||
* (c) 2004 IMMS gGmbH <www.imms.de>, Thomas Elste <info@elste.org>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/netarm_registers.h>
|
||||
|
||||
|
||||
/* some parameters for the board */
|
||||
#define FLASH_90ns_WAIT_STATES ((NETARM_PLL_COUNT_VAL + 2) / 3)
|
||||
#define FLASH_70ns_WAIT_STATES 4
|
||||
|
||||
#define NETARM_MMAP_CS0_BASE (PHYS_FLASH_1)
|
||||
#if 1
|
||||
#define NETARM_MMAP_CS0_MASK (~(PHYS_FLASH_1_SIZE - 1))
|
||||
#else
|
||||
#define NETARM_MMAP_CS0_MASK (~(1000000 - 1))
|
||||
#endif
|
||||
#define NETARM_MMAP_CS1_BASE (PHYS_SDRAM_1)
|
||||
#define NETARM_MMAP_CS1_MASK (~(PHYS_SDRAM_1_SIZE - 1))
|
||||
#define NETARM_MMAP_CS2_BASE (PHYS_SDRAM_2)
|
||||
#define NETARM_MMAP_CS2_MASK (~(PHYS_SDRAM_2_SIZE - 1))
|
||||
#if defined(CONFIG_NETARM_EEPROM) && defined(PHYS_NVRAM_1) && defined(PHYS_NVRAM_SIZE)
|
||||
#define NETARM_MMAP_CS3_BASE (PHYS_NVRAM_1)
|
||||
#define NETARM_MMAP_CS3_MASK (~(PHYS_NVRAM_SIZE - 1))
|
||||
#endif
|
||||
#define NETARM_MMAP_CS4_BASE (PHYS_EXT_1)
|
||||
#define NETARM_MMAP_CS4_MASK (~(PHYS_EXT_SIZE - 1))
|
||||
|
||||
/* setting up the memory */
|
||||
.globl memsetup
|
||||
memsetup:
|
||||
|
||||
#if defined(CONFIG_MODNET50)
|
||||
ldr pc, =(_jump_to_high + NETARM_MMAP_CS0_BASE - TEXT_BASE)
|
||||
|
||||
_jump_to_high:
|
||||
/*
|
||||
* MEM Config Reg
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
ldr r0, =NETARM_MEM_MODULE_BASE
|
||||
ldr r1, =( NETARM_MEM_REFR_PERIOD_USEC(16) | \
|
||||
NETARM_MEM_CFG_REFRESH_EN | \
|
||||
NETARM_MEM_CFG_REFR_CYCLE_5CLKS )
|
||||
str r1, [r0, #+NETARM_MEM_MODULE_CONFIG]
|
||||
|
||||
|
||||
memsetup_cs0:
|
||||
/*
|
||||
* Base Addr / Option Reg 0 (Flash)
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS0_BASE) | \
|
||||
NETARM_MEM_BAR_DRAM_FP | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_INT | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_BAL | \
|
||||
NETARM_MEM_BAR_VALID )
|
||||
str r1, [r0, #+NETARM_MEM_CS0_BASE_ADDR]
|
||||
|
||||
/* trust that the bus size for flash was strapped correctly */
|
||||
/* this saves the bus width in r2 and then ORs it back in */
|
||||
/* it's pretty safe assumption, otherwise it wouldn't boot */
|
||||
ldr r2, [r0, #+NETARM_MEM_CS0_OPTIONS]
|
||||
and r2, r2, #NETARM_MEM_OPT_BUS_SIZE_MASK
|
||||
|
||||
/* just a test: assume 32 bit flash mem */
|
||||
/* mov r2, #NETARM_MEM_OPT_32BIT */
|
||||
|
||||
ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS0_MASK) | \
|
||||
NETARM_MEM_OPT_WAIT_STATES(FLASH_70ns_WAIT_STATES) | \
|
||||
NETARM_MEM_OPT_BCYC_4 | \
|
||||
NETARM_MEM_OPT_BSIZE_16 | \
|
||||
NETARM_MEM_OPT_16BIT | \
|
||||
NETARM_MEM_OPT_READ_ASYNC | \
|
||||
NETARM_MEM_OPT_WRITE_ASYNC )
|
||||
|
||||
orr r1, r1, r2
|
||||
str r1, [r0, #+NETARM_MEM_CS0_OPTIONS]
|
||||
|
||||
|
||||
memsetup_cs1:
|
||||
/*
|
||||
* Base Addr / Option Reg 1 (DRAM #1)
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
#ifdef CONFIG_NETARM_NET40_REV2
|
||||
/* we have to config SDRAM in burst mode */
|
||||
ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) | \
|
||||
NETARM_MEM_OPT_BCYC_2 | \
|
||||
NETARM_MEM_OPT_BSIZE_16 | \
|
||||
NETARM_MEM_OPT_WAIT_STATES(0) | \
|
||||
NETARM_MEM_OPT_32BIT | \
|
||||
NETARM_MEM_OPT_READ_ASYNC | \
|
||||
NETARM_MEM_OPT_WRITE_ASYNC )
|
||||
str r1, [r0, #+NETARM_MEM_CS1_OPTIONS]
|
||||
|
||||
ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | \
|
||||
NETARM_MEM_BAR_DRAM_SYNC | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_INT | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_UNBAL | \
|
||||
NETARM_MEM_BAR_DRAM_SEL | \
|
||||
NETARM_MEM_BAR_BURST_EN | \
|
||||
NETARM_MEM_BAR_VALID )
|
||||
str r1, [r0, #+NETARM_MEM_CS1_BASE_ADDR]
|
||||
#else
|
||||
/* we have to config FPDRAM in burst mode with smaller burst access size */
|
||||
ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS1_MASK) | \
|
||||
NETARM_MEM_OPT_BCYC_2 | \
|
||||
NETARM_MEM_OPT_BSIZE_16 | \
|
||||
NETARM_MEM_OPT_WAIT_STATES(0) | \
|
||||
NETARM_MEM_OPT_32BIT | \
|
||||
NETARM_MEM_OPT_READ_ASYNC | \
|
||||
NETARM_MEM_OPT_WRITE_ASYNC )
|
||||
str r1, [r0, #+NETARM_MEM_CS1_OPTIONS]
|
||||
|
||||
ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS1_BASE) | \
|
||||
NETARM_MEM_BAR_DRAM_SYNC | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_INT | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_UNBAL | \
|
||||
NETARM_MEM_BAR_DRAM_SEL | \
|
||||
NETARM_MEM_BAR_BURST_EN | \
|
||||
NETARM_MEM_BAR_VALID )
|
||||
str r1, [r0, #+NETARM_MEM_CS1_BASE_ADDR]
|
||||
|
||||
#endif /* CONFIG_NETARM_NET40_REV2 */
|
||||
|
||||
|
||||
memsetup_cs3:
|
||||
/*
|
||||
* Base Addr / Option Reg 3 (EEPROM, NVRAM)
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
#if defined(CONFIG_NETARM_EEPROM) && defined(PHYS_NVRAM_1) && defined(PHYS_NVRAM_SIZE)
|
||||
ldr r1, =( NETARM_MEM_OPT_BASE_USE(NETARM_MMAP_CS3_MASK) | \
|
||||
NETARM_MEM_OPT_BCYC_3 | \
|
||||
NETARM_MEM_OPT_BSIZE_2 | \
|
||||
NETARM_MEM_OPT_WAIT_STATES(10) | \
|
||||
NETARM_MEM_OPT_8BIT | \
|
||||
NETARM_MEM_OPT_READ_ASYNC | \
|
||||
NETARM_MEM_OPT_WRITE_ASYNC )
|
||||
str r1, [r0, #+NETARM_MEM_CS3_OPTIONS]
|
||||
|
||||
ldr r1, =( NETARM_MEM_BAR_BASE(NETARM_MMAP_CS3_BASE) | \
|
||||
NETARM_MEM_BAR_DRAM_FP | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_INT | \
|
||||
NETARM_MEM_BAR_DRAM_MUX_BAL | \
|
||||
NETARM_MEM_BAR_VALID )
|
||||
str r1, [r0, #+NETARM_MEM_CS3_BASE_ADDR]
|
||||
#else
|
||||
/* we don't need EEPROM --> no config */
|
||||
ldr r1, =( 0 )
|
||||
str r1, [r0, #+NETARM_MEM_CS3_OPTIONS]
|
||||
|
||||
ldr r1, =( 0 )
|
||||
str r1, [r0, #+NETARM_MEM_CS3_BASE_ADDR]
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
/*
|
||||
#error "missing CONFIG_MODNET50 (see your config.h)"
|
||||
*/
|
||||
#endif /* CONFIG_MODNET50 */
|
||||
|
||||
|
||||
memsetup_end:
|
||||
/*
|
||||
* manipulate address in lr and ip to match new
|
||||
* address space
|
||||
*/
|
||||
ldr r3, =(NETARM_MMAP_CS0_BASE)
|
||||
mov r0, lr
|
||||
add r0, r3, r0
|
||||
mov lr, r0
|
||||
mov r0, ip
|
||||
add r0, r3, r0
|
||||
mov ip, r0
|
||||
|
||||
/* everything is fine now */
|
||||
mov pc, lr
|
||||
52
board/modnet50/modnet50.c
Normal file
52
board/modnet50/modnet50.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* Miscelaneous platform dependent initialisations
|
||||
*/
|
||||
|
||||
int board_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* address for the kernel command line */
|
||||
gd->bd->bi_boot_params = 0x800;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
if (CONFIG_NR_DRAM_BANKS == 2) {
|
||||
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
|
||||
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
68
board/modnet50/u-boot.lds
Normal file
68
board/modnet50/u-boot.lds
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
cpu/arm720t/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
/* 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) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
||||
@@ -709,6 +709,18 @@ void print_mip405_rev (void)
|
||||
var, pcbrev + 'A', part & 0x7F, vers);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
/*
|
||||
* Returns 1 if keys pressed to start the power-on long-running tests
|
||||
* Called from board_init_f().
|
||||
*/
|
||||
int post_hotkeys_pressed(void)
|
||||
{
|
||||
return 0; /* No hotkeys supported */
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void mem_test_reloc(void);
|
||||
extern int mk_date (char *, struct rtc_time *);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Kshitij Gupta <Kshitij@ti.com>
|
||||
*
|
||||
* Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
@@ -105,7 +107,28 @@ void flash__init (void)
|
||||
*************************************************************/
|
||||
void ether__init (void)
|
||||
{
|
||||
#define ETH_CONTROL_REG 0x0400000b
|
||||
#define ETH_CONTROL_REG 0x0400030b
|
||||
|
||||
#ifdef CONFIG_H2_OMAP1610
|
||||
#define LAN_RESET_REGISTER 0x0400001c
|
||||
|
||||
/* The debug board on which the lan chip resides may not be powered
|
||||
* ON at the same time as the OMAP chip. So wait in a loop until the
|
||||
* lan reset register (on the debug board) is available (powered on)
|
||||
* and reset the lan chip.
|
||||
*/
|
||||
|
||||
*((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0000;
|
||||
do {
|
||||
*((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0001;
|
||||
udelay (3);
|
||||
} while (*((volatile unsigned short *) LAN_RESET_REGISTER) != 0x0001);
|
||||
|
||||
do {
|
||||
*((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0000;
|
||||
udelay (3);
|
||||
} while (*((volatile unsigned short *) LAN_RESET_REGISTER) != 0x0000);
|
||||
#endif
|
||||
|
||||
*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
|
||||
udelay (3);
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Kshitij Gupta <Kshitij@ti.com>
|
||||
*
|
||||
* Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
@@ -248,6 +250,22 @@ common_tc:
|
||||
ldr r1, VAL_TC_EMIFS_CS3_CONFIG
|
||||
ldr r0, REG_TC_EMIFS_CS3_CONFIG
|
||||
str r1, [r0] /* Chip Select 3 */
|
||||
|
||||
#ifdef CONFIG_H2_OMAP1610
|
||||
/* inserting additional 2 clock cycle hold time for LAN */
|
||||
ldr r0, REG_TC_EMIFS_CS1_ADVANCED
|
||||
ldr r1, VAL_TC_EMIFS_CS1_ADVANCED
|
||||
str r1, [r0]
|
||||
#endif
|
||||
/* Start MPU Timer 1 */
|
||||
ldr r0, REG_MPU_LOAD_TIMER
|
||||
ldr r1, VAL_MPU_LOAD_TIMER
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, REG_MPU_CNTL_TIMER
|
||||
ldr r1, VAL_MPU_CNTL_TIMER
|
||||
str r1, [r0]
|
||||
|
||||
/* back to arch calling code */
|
||||
mov pc, lr
|
||||
|
||||
@@ -266,6 +284,11 @@ REG_TC_EMIFS_CS2_CONFIG: /* 32 bits */
|
||||
REG_TC_EMIFS_CS3_CONFIG: /* 32 bits */
|
||||
.word 0xfffecc1c
|
||||
|
||||
#ifdef CONFIG_H2_OMAP1610
|
||||
REG_TC_EMIFS_CS1_ADVANCED: /* 32 bits */
|
||||
.word 0xfffecc54
|
||||
#endif
|
||||
|
||||
/* MPU clock/reset/power mode control registers */
|
||||
REG_ARM_CKCTL: /* 16 bits */
|
||||
.word 0xfffece00
|
||||
@@ -338,6 +361,11 @@ REG_DLL_LRD_CONTROL:
|
||||
REG_WATCHDOG:
|
||||
.word 0xfffec808
|
||||
|
||||
REG_MPU_LOAD_TIMER:
|
||||
.word 0xfffec600
|
||||
REG_MPU_CNTL_TIMER:
|
||||
.word 0xfffec500
|
||||
|
||||
/* 96 MHz Samsung Mobile DDR */
|
||||
SDRAM_CONFIG_VAL:
|
||||
.word 0x001200f4
|
||||
@@ -350,6 +378,7 @@ VAL_ARM_CKCTL:
|
||||
VAL_DPLL1_CTL:
|
||||
.word 0x2830
|
||||
|
||||
#ifdef CONFIG_INNOVATOROMAP1610
|
||||
VAL_TC_EMIFS_CS0_CONFIG:
|
||||
.word 0x002130b0
|
||||
VAL_TC_EMIFS_CS1_CONFIG:
|
||||
@@ -358,6 +387,21 @@ VAL_TC_EMIFS_CS2_CONFIG:
|
||||
.word 0x000055f0
|
||||
VAL_TC_EMIFS_CS3_CONFIG:
|
||||
.word 0x88011131
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_H2_OMAP1610
|
||||
VAL_TC_EMIFS_CS0_CONFIG:
|
||||
.word 0x00203331
|
||||
VAL_TC_EMIFS_CS1_CONFIG:
|
||||
.word 0x8180fff3
|
||||
VAL_TC_EMIFS_CS2_CONFIG:
|
||||
.word 0xf800f22a
|
||||
VAL_TC_EMIFS_CS3_CONFIG:
|
||||
.word 0x88011131
|
||||
VAL_TC_EMIFS_CS1_ADVANCED:
|
||||
.word 0x00000022
|
||||
#endif
|
||||
|
||||
VAL_TC_EMIFF_SDRAM_CONFIG:
|
||||
.word 0x010290fc
|
||||
VAL_TC_EMIFF_MRS:
|
||||
@@ -376,6 +420,11 @@ WATCHDOG_VAL1:
|
||||
WATCHDOG_VAL2:
|
||||
.word 0x000000a0
|
||||
|
||||
VAL_MPU_LOAD_TIMER:
|
||||
.word 0xffffffff
|
||||
VAL_MPU_CNTL_TIMER:
|
||||
.word 0xffffffa1
|
||||
|
||||
/* command values */
|
||||
.equ CMD_SDRAM_NOP, 0x00000000
|
||||
.equ CMD_SDRAM_PRECHARGE, 0x00000001
|
||||
|
||||
165
board/xilinx/common/xbasic_types.c
Normal file
165
board/xilinx/common/xbasic_types.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xbasic_types.c
|
||||
*
|
||||
* This file contains basic functions for Xilinx software IP.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a rpm 11/07/03 Added XNullHandler function as a stub interrupt handler
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/**
|
||||
* This variable allows testing to be done easier with asserts. An assert
|
||||
* sets this variable such that a driver can evaluate this variable
|
||||
* to determine if an assert occurred.
|
||||
*/
|
||||
unsigned int XAssertStatus;
|
||||
|
||||
/**
|
||||
* This variable allows the assert functionality to be changed for testing
|
||||
* such that it does not wait infinitely. Use the debugger to disable the
|
||||
* waiting during testing of asserts.
|
||||
*/
|
||||
u32 XWaitInAssert = TRUE;
|
||||
|
||||
/* The callback function to be invoked when an assert is taken */
|
||||
static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Implements assert. Currently, it calls a user-defined callback function
|
||||
* if one has been set. Then, it potentially enters an infinite loop depending
|
||||
* on the value of the XWaitInAssert variable.
|
||||
*
|
||||
* @param File is the name of the filename of the source
|
||||
* @param Line is the linenumber within File
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XAssert(char *File, int Line)
|
||||
{
|
||||
/* if the callback has been set then invoke it */
|
||||
if (XAssertCallbackRoutine != NULL) {
|
||||
(*XAssertCallbackRoutine) (File, Line);
|
||||
}
|
||||
|
||||
/* if specified, wait indefinitely such that the assert will show up
|
||||
* in testing
|
||||
*/
|
||||
while (XWaitInAssert) {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Sets up a callback function to be invoked when an assert occurs. If there
|
||||
* was already a callback installed, then it is replaced.
|
||||
*
|
||||
* @param Routine is the callback to be invoked when an assert is taken
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function has no effect if NDEBUG is set
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XAssertSetCallback(XAssertCallback Routine)
|
||||
{
|
||||
XAssertCallbackRoutine = Routine;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Null handler function. This follows the XInterruptHandler signature for
|
||||
* interrupt handlers. It can be used to assign a null handler (a stub) to an
|
||||
* interrupt controller vector table.
|
||||
*
|
||||
* @param NullParameter is an arbitrary void pointer and not used.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XNullHandler(void *NullParameter)
|
||||
{
|
||||
}
|
||||
283
board/xilinx/common/xbasic_types.h
Normal file
283
board/xilinx/common/xbasic_types.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xbasic_types.h
|
||||
*
|
||||
* This file contains basic types for Xilinx software IP. These types do not
|
||||
* follow the standard naming convention with respect to using the component
|
||||
* name in front of each name because they are considered to be primitives.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This file contains items which are architecture dependent.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a rmm 12/14/01 First release
|
||||
* rmm 05/09/03 Added "xassert always" macros to rid ourselves of diab
|
||||
* compiler warnings
|
||||
* 1.00a rpm 11/07/03 Added XNullHandler function as a stub interrupt handler
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
|
||||
#define XBASIC_TYPES_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
/** Null */
|
||||
|
||||
#define XCOMPONENT_IS_READY 0x11111111 /* component has been initialized */
|
||||
#define XCOMPONENT_IS_STARTED 0x22222222 /* component has been started */
|
||||
|
||||
/* the following constants and declarations are for unit test purposes and are
|
||||
* designed to be used in test applications.
|
||||
*/
|
||||
#define XTEST_PASSED 0
|
||||
#define XTEST_FAILED 1
|
||||
|
||||
#define XASSERT_NONE 0
|
||||
#define XASSERT_OCCURRED 1
|
||||
|
||||
extern unsigned int XAssertStatus;
|
||||
extern void XAssert(char *, int);
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/** @name Primitive types
|
||||
* These primitive types are created for transportability.
|
||||
* They are dependent upon the target architecture.
|
||||
* @{
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef struct {
|
||||
u32 Upper;
|
||||
u32 Lower;
|
||||
} Xuint64;
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* This data type defines an interrupt handler for a device.
|
||||
* The argument points to the instance of the component
|
||||
*/
|
||||
typedef void (*XInterruptHandler) (void *InstancePtr);
|
||||
|
||||
/**
|
||||
* This data type defines a callback to be invoked when an
|
||||
* assert occurs. The callback is invoked only when asserts are enabled
|
||||
*/
|
||||
typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber);
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Return the most significant half of the 64 bit data type.
|
||||
*
|
||||
* @param x is the 64 bit word.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The upper 32 bits of the 64 bit word.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XUINT64_MSW(x) ((x).Upper)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Return the least significant half of the 64 bit data type.
|
||||
*
|
||||
* @param x is the 64 bit word.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The lower 32 bits of the 64 bit word.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XUINT64_LSW(x) ((x).Lower)
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This assert macro is to be used for functions that do not return anything
|
||||
* (void). This in conjunction with the XWaitInAssert boolean can be used to
|
||||
* accomodate tests so that asserts which fail allow execution to continue.
|
||||
*
|
||||
* @param expression is the expression to evaluate. If it evaluates to false,
|
||||
* the assert occurs.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Returns void unless the XWaitInAssert variable is true, in which case
|
||||
* no return is made and an infinite loop is entered.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XASSERT_VOID(expression) \
|
||||
{ \
|
||||
if (expression) { \
|
||||
XAssertStatus = XASSERT_NONE; \
|
||||
} else { \
|
||||
XAssert(__FILE__, __LINE__); \
|
||||
XAssertStatus = XASSERT_OCCURRED; \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This assert macro is to be used for functions that do return a value. This in
|
||||
* conjunction with the XWaitInAssert boolean can be used to accomodate tests so
|
||||
* that asserts which fail allow execution to continue.
|
||||
*
|
||||
* @param expression is the expression to evaluate. If it evaluates to false,
|
||||
* the assert occurs.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Returns 0 unless the XWaitInAssert variable is true, in which case
|
||||
* no return is made and an infinite loop is entered.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XASSERT_NONVOID(expression) \
|
||||
{ \
|
||||
if (expression) { \
|
||||
XAssertStatus = XASSERT_NONE; \
|
||||
} else { \
|
||||
XAssert(__FILE__, __LINE__); \
|
||||
XAssertStatus = XASSERT_OCCURRED; \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Always assert. This assert macro is to be used for functions that do not
|
||||
* return anything (void). Use for instances where an assert should always
|
||||
* occur.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Returns void unless the XWaitInAssert variable is true, in which case
|
||||
* no return is made and an infinite loop is entered.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XASSERT_VOID_ALWAYS() \
|
||||
{ \
|
||||
XAssert(__FILE__, __LINE__); \
|
||||
XAssertStatus = XASSERT_OCCURRED; \
|
||||
return; \
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Always assert. This assert macro is to be used for functions that do return
|
||||
* a value. Use for instances where an assert should always occur.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Returns void unless the XWaitInAssert variable is true, in which case
|
||||
* no return is made and an infinite loop is entered.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XASSERT_NONVOID_ALWAYS() \
|
||||
{ \
|
||||
XAssert(__FILE__, __LINE__); \
|
||||
XAssertStatus = XASSERT_OCCURRED; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define XASSERT_VOID(expression)
|
||||
#define XASSERT_VOID_ALWAYS()
|
||||
#define XASSERT_NONVOID(expression)
|
||||
#define XASSERT_NONVOID_ALWAYS()
|
||||
#endif
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XAssertSetCallback(XAssertCallback Routine);
|
||||
void XNullHandler(void *NullParameter);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
252
board/xilinx/common/xbuf_descriptor.h
Normal file
252
board/xilinx/common/xbuf_descriptor.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* FILENAME:
|
||||
*
|
||||
* xbuf_descriptor.h
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This file contains the interface for the XBufDescriptor component.
|
||||
* The XBufDescriptor component is a passive component that only maps over
|
||||
* a buffer descriptor data structure shared by the scatter gather DMA hardware
|
||||
* and software. The component's primary purpose is to provide encapsulation of
|
||||
* the buffer descriptor processing. See the source file xbuf_descriptor.c for
|
||||
* details.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Most of the functions of this component are implemented as macros in order
|
||||
* to optimize the processing. The names are not all uppercase such that they
|
||||
* can be switched between macros and functions easily.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XBUF_DESCRIPTOR_H /* prevent circular inclusions */
|
||||
#define XBUF_DESCRIPTOR_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xdma_channel_i.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* The following constants allow access to all fields of a buffer descriptor
|
||||
* and are necessary at this level of visibility to allow macros to access
|
||||
* and modify the fields of a buffer descriptor. It is not expected that the
|
||||
* user of a buffer descriptor would need to use these constants.
|
||||
*/
|
||||
|
||||
#define XBD_DEVICE_STATUS_OFFSET 0
|
||||
#define XBD_CONTROL_OFFSET 1
|
||||
#define XBD_SOURCE_OFFSET 2
|
||||
#define XBD_DESTINATION_OFFSET 3
|
||||
#define XBD_LENGTH_OFFSET 4
|
||||
#define XBD_STATUS_OFFSET 5
|
||||
#define XBD_NEXT_PTR_OFFSET 6
|
||||
#define XBD_ID_OFFSET 7
|
||||
#define XBD_FLAGS_OFFSET 8
|
||||
#define XBD_RQSTED_LENGTH_OFFSET 9
|
||||
|
||||
#define XBD_SIZE_IN_WORDS 10
|
||||
|
||||
/*
|
||||
* The following constants define the bits of the flags field of a buffer
|
||||
* descriptor
|
||||
*/
|
||||
|
||||
#define XBD_FLAGS_LOCKED_MASK 1UL
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
typedef u32 XBufDescriptor[XBD_SIZE_IN_WORDS];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/* each of the following macros are named the same as functions rather than all
|
||||
* upper case in order to allow either the macros or the functions to be
|
||||
* used, see the source file xbuf_descriptor.c for documentation
|
||||
*/
|
||||
|
||||
#define XBufDescriptor_Initialize(InstancePtr) \
|
||||
{ \
|
||||
(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_ID_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = 0); \
|
||||
(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = 0); \
|
||||
}
|
||||
|
||||
#define XBufDescriptor_GetControl(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetControl(InstancePtr, Control) \
|
||||
(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = (u32)Control)
|
||||
|
||||
#define XBufDescriptor_IsLastControl(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) & \
|
||||
XDC_CONTROL_LAST_BD_MASK)
|
||||
|
||||
#define XBufDescriptor_SetLast(InstancePtr) \
|
||||
(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) |= XDC_CONTROL_LAST_BD_MASK)
|
||||
|
||||
#define XBufDescriptor_GetSrcAddress(InstancePtr) \
|
||||
((u32 *)(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET)))
|
||||
|
||||
#define XBufDescriptor_SetSrcAddress(InstancePtr, Source) \
|
||||
(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = (u32)Source)
|
||||
|
||||
#define XBufDescriptor_GetDestAddress(InstancePtr) \
|
||||
((u32 *)(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)))
|
||||
|
||||
#define XBufDescriptor_SetDestAddress(InstancePtr, Destination) \
|
||||
(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = (u32)Destination)
|
||||
|
||||
#define XBufDescriptor_GetLength(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) - \
|
||||
*((u32 *)InstancePtr + XBD_LENGTH_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetLength(InstancePtr, Length) \
|
||||
{ \
|
||||
(*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = (u32)(Length)); \
|
||||
(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
|
||||
}
|
||||
|
||||
#define XBufDescriptor_GetStatus(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetStatus(InstancePtr, Status) \
|
||||
(*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = (u32)Status)
|
||||
|
||||
#define XBufDescriptor_IsLastStatus(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET) & \
|
||||
XDC_STATUS_LAST_BD_MASK)
|
||||
|
||||
#define XBufDescriptor_GetDeviceStatus(InstancePtr) \
|
||||
((u32)(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)))
|
||||
|
||||
#define XBufDescriptor_SetDeviceStatus(InstancePtr, Status) \
|
||||
(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = (u32)Status)
|
||||
|
||||
#define XBufDescriptor_GetNextPtr(InstancePtr) \
|
||||
(XBufDescriptor *)(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetNextPtr(InstancePtr, NextPtr) \
|
||||
(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = (u32)NextPtr)
|
||||
|
||||
#define XBufDescriptor_GetId(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_ID_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetId(InstancePtr, Id) \
|
||||
(*((u32 *)InstancePtr + XBD_ID_OFFSET) = (u32)Id)
|
||||
|
||||
#define XBufDescriptor_GetFlags(InstancePtr) \
|
||||
(u32)(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET))
|
||||
|
||||
#define XBufDescriptor_SetFlags(InstancePtr, Flags) \
|
||||
(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = (u32)Flags)
|
||||
|
||||
#define XBufDescriptor_Lock(InstancePtr) \
|
||||
(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) |= XBD_FLAGS_LOCKED_MASK)
|
||||
|
||||
#define XBufDescriptor_Unlock(InstancePtr) \
|
||||
(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) &= ~XBD_FLAGS_LOCKED_MASK)
|
||||
|
||||
#define XBufDescriptor_IsLocked(InstancePtr) \
|
||||
(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) & XBD_FLAGS_LOCKED_MASK)
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/* The following prototypes are provided to allow each of the functions to
|
||||
* be implemented as a function rather than a macro, and to provide the
|
||||
* syntax to allow users to understand how to call the macros, they are
|
||||
* commented out to prevent linker errors
|
||||
*
|
||||
|
||||
u32 XBufDescriptor_Initialize(XBufDescriptor* InstancePtr);
|
||||
|
||||
u32 XBufDescriptor_GetControl(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetControl(XBufDescriptor* InstancePtr, u32 Control);
|
||||
|
||||
u32 XBufDescriptor_IsLastControl(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetLast(XBufDescriptor* InstancePtr);
|
||||
|
||||
u32 XBufDescriptor_GetLength(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetLength(XBufDescriptor* InstancePtr, u32 Length);
|
||||
|
||||
u32 XBufDescriptor_GetStatus(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetStatus(XBufDescriptor* InstancePtr, u32 Status);
|
||||
u32 XBufDescriptor_IsLastStatus(XBufDescriptor* InstancePtr);
|
||||
|
||||
u32 XBufDescriptor_GetDeviceStatus(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetDeviceStatus(XBufDescriptor* InstancePtr,
|
||||
u32 Status);
|
||||
|
||||
u32 XBufDescriptor_GetSrcAddress(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetSrcAddress(XBufDescriptor* InstancePtr,
|
||||
u32 SourceAddress);
|
||||
|
||||
u32 XBufDescriptor_GetDestAddress(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetDestAddress(XBufDescriptor* InstancePtr,
|
||||
u32 DestinationAddress);
|
||||
|
||||
XBufDescriptor* XBufDescriptor_GetNextPtr(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetNextPtr(XBufDescriptor* InstancePtr,
|
||||
XBufDescriptor* NextPtr);
|
||||
|
||||
u32 XBufDescriptor_GetId(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetId(XBufDescriptor* InstancePtr, u32 Id);
|
||||
|
||||
u32 XBufDescriptor_GetFlags(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_SetFlags(XBufDescriptor* InstancePtr, u32 Flags);
|
||||
|
||||
void XBufDescriptor_Lock(XBufDescriptor* InstancePtr);
|
||||
void XBufDescriptor_Unlock(XBufDescriptor* InstancePtr);
|
||||
u32 XBufDescriptor_IsLocked(XBufDescriptor* InstancePtr);
|
||||
|
||||
void XBufDescriptor_Copy(XBufDescriptor* InstancePtr,
|
||||
XBufDescriptor* DestinationPtr);
|
||||
|
||||
*/
|
||||
|
||||
#endif /* end of protection macro */
|
||||
738
board/xilinx/common/xdma_channel.c
Normal file
738
board/xilinx/common/xdma_channel.c
Normal file
@@ -0,0 +1,738 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* FILENAME:
|
||||
*
|
||||
* xdma_channel.c
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This file contains the DMA channel component. This component supports
|
||||
* a distributed DMA design in which each device can have it's own dedicated
|
||||
* DMA channel, as opposed to a centralized DMA design. This component
|
||||
* performs processing for DMA on all devices.
|
||||
*
|
||||
* See xdma_channel.h for more information about this component.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xdma_channel.h"
|
||||
#include "xbasic_types.h"
|
||||
#include "xio.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_Initialize
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function initializes a DMA channel. This function must be called
|
||||
* prior to using a DMA channel. Initialization of a channel includes setting
|
||||
* up the registers base address, and resetting the channel such that it's in a
|
||||
* known state. Interrupts for the channel are disabled when the channel is
|
||||
* reset.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* BaseAddress contains the base address of the registers for the DMA channel.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* XST_SUCCESS indicating initialization was successful.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
|
||||
{
|
||||
/* assert to verify input arguments, don't assert base address */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
|
||||
/* setup the base address of the registers for the DMA channel such
|
||||
* that register accesses can be done
|
||||
*/
|
||||
InstancePtr->RegBaseAddress = BaseAddress;
|
||||
|
||||
/* initialize the scatter gather list such that it indicates it has not
|
||||
* been created yet and the DMA channel is ready to use (initialized)
|
||||
*/
|
||||
InstancePtr->GetPtr = NULL;
|
||||
InstancePtr->PutPtr = NULL;
|
||||
InstancePtr->CommitPtr = NULL;
|
||||
InstancePtr->LastPtr = NULL;
|
||||
|
||||
InstancePtr->TotalDescriptorCount = 0;
|
||||
InstancePtr->ActiveDescriptorCount = 0;
|
||||
InstancePtr->IsReady = XCOMPONENT_IS_READY;
|
||||
|
||||
/* initialize the version of the component
|
||||
*/
|
||||
XVersion_FromString(&InstancePtr->Version, "1.00a");
|
||||
|
||||
/* reset the DMA channel such that it's in a known state and ready
|
||||
* and indicate the initialization occured with no errors, note that
|
||||
* the is ready variable must be set before this call or reset will assert
|
||||
*/
|
||||
XDmaChannel_Reset(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_IsReady
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function determines if a DMA channel component has been successfully
|
||||
* initialized such that it's ready to use.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* TRUE if the DMA channel component is ready, FALSE otherwise.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XDmaChannel_IsReady(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments used by the base component */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
|
||||
return InstancePtr->IsReady == XCOMPONENT_IS_READY;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_GetVersion
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the software version for the specified DMA channel
|
||||
* component.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* A pointer to the software version of the specified DMA channel.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XVersion *
|
||||
XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* return a pointer to the version of the DMA channel */
|
||||
|
||||
return &InstancePtr->Version;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_SelfTest
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function performs a self test on the specified DMA channel. This self
|
||||
* test is destructive as the DMA channel is reset and a register default is
|
||||
* verified.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr is a pointer to the DMA channel to be operated on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* XST_SUCCESS is returned if the self test is successful, or one of the
|
||||
* following errors.
|
||||
*
|
||||
* XST_DMA_RESET_REGISTER_ERROR Indicates the control register value
|
||||
* after a reset was not correct
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* This test does not performs a DMA transfer to test the channel because the
|
||||
* DMA hardware will not currently allow a non-local memory transfer to non-local
|
||||
* memory (memory copy), but only allows a non-local memory to or from the device
|
||||
* memory (typically a FIFO).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define XDC_CONTROL_REG_RESET_MASK 0x98000000UL /* control reg reset value */
|
||||
|
||||
XStatus
|
||||
XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* reset the DMA channel such that it's in a known state before the test
|
||||
* it resets to no interrupts enabled, the desired state for the test
|
||||
*/
|
||||
XDmaChannel_Reset(InstancePtr);
|
||||
|
||||
/* this should be the first test to help prevent a lock up with the polling
|
||||
* loop that occurs later in the test, check the reset value of the DMA
|
||||
* control register to make sure it's correct, return with an error if not
|
||||
*/
|
||||
ControlReg = XDmaChannel_GetControl(InstancePtr);
|
||||
if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
|
||||
return XST_DMA_RESET_REGISTER_ERROR;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_Reset
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function resets the DMA channel. This is a destructive operation such
|
||||
* that it should not be done while a channel is being used. If the DMA channel
|
||||
* is transferring data into other blocks, such as a FIFO, it may be necessary
|
||||
* to reset other blocks. This function does not modify the contents of a
|
||||
* scatter gather list for a DMA channel such that the user is responsible for
|
||||
* getting buffer descriptors from the list if necessary.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XDmaChannel_Reset(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* reset the DMA channel such that it's in a known state, the reset
|
||||
* register is self clearing such that it only has to be set
|
||||
*/
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
|
||||
XDC_RESET_MASK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_GetControl
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the control register contents of the DMA channel.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The control register contents of the DMA channel. One or more of the
|
||||
* following values may be contained the register. Each of the values are
|
||||
* unique bit masks.
|
||||
*
|
||||
* XDC_DMACR_SOURCE_INCR_MASK Increment the source address
|
||||
* XDC_DMACR_DEST_INCR_MASK Increment the destination address
|
||||
* XDC_DMACR_SOURCE_LOCAL_MASK Local source address
|
||||
* XDC_DMACR_DEST_LOCAL_MASK Local destination address
|
||||
* XDC_DMACR_SG_ENABLE_MASK Scatter gather enable
|
||||
* XDC_DMACR_GEN_BD_INTR_MASK Individual buffer descriptor interrupt
|
||||
* XDC_DMACR_LAST_BD_MASK Last buffer descriptor in a packet
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XDmaChannel_GetControl(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* return the contents of the DMA control register */
|
||||
|
||||
return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_SetControl
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the control register of the specified DMA channel.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* Control contains the value to be written to the control register of the DMA
|
||||
* channel. One or more of the following values may be contained the register.
|
||||
* Each of the values are unique bit masks such that they may be ORed together
|
||||
* to enable multiple bits or inverted and ANDed to disable multiple bits.
|
||||
*
|
||||
* XDC_DMACR_SOURCE_INCR_MASK Increment the source address
|
||||
* XDC_DMACR_DEST_INCR_MASK Increment the destination address
|
||||
* XDC_DMACR_SOURCE_LOCAL_MASK Local source address
|
||||
* XDC_DMACR_DEST_LOCAL_MASK Local destination address
|
||||
* XDC_DMACR_SG_ENABLE_MASK Scatter gather enable
|
||||
* XDC_DMACR_GEN_BD_INTR_MASK Individual buffer descriptor interrupt
|
||||
* XDC_DMACR_LAST_BD_MASK Last buffer descriptor in a packet
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
|
||||
{
|
||||
/* assert to verify input arguments except the control which can't be
|
||||
* asserted since all values are valid
|
||||
*/
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* set the DMA control register to the specified value */
|
||||
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET, Control);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_GetStatus
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the status register contents of the DMA channel.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The status register contents of the DMA channel. One or more of the
|
||||
* following values may be contained the register. Each of the values are
|
||||
* unique bit masks.
|
||||
*
|
||||
* XDC_DMASR_BUSY_MASK The DMA channel is busy
|
||||
* XDC_DMASR_BUS_ERROR_MASK A bus error occurred
|
||||
* XDC_DMASR_BUS_TIMEOUT_MASK A bus timeout occurred
|
||||
* XDC_DMASR_LAST_BD_MASK The last buffer descriptor of a packet
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XDmaChannel_GetStatus(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* return the contents of the DMA status register */
|
||||
|
||||
return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_SetIntrStatus
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the interrupt status register of the specified DMA channel.
|
||||
* Setting any bit of the interrupt status register will clear the bit to
|
||||
* indicate the interrupt processing has been completed. The definitions of each
|
||||
* bit in the register match the definition of the bits in the interrupt enable
|
||||
* register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* Status contains the value to be written to the status register of the DMA
|
||||
* channel. One or more of the following values may be contained the register.
|
||||
* Each of the values are unique bit masks such that they may be ORed together
|
||||
* to enable multiple bits or inverted and ANDed to disable multiple bits.
|
||||
*
|
||||
* XDC_IXR_DMA_DONE_MASK The dma operation is done
|
||||
* XDC_IXR_DMA_ERROR_MASK The dma operation had an error
|
||||
* XDC_IXR_PKT_DONE_MASK A packet is complete
|
||||
* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached
|
||||
* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
|
||||
* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
|
||||
* XDC_IXR_BD_MASK A buffer descriptor is done
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status)
|
||||
{
|
||||
/* assert to verify input arguments except the status which can't be
|
||||
* asserted since all values are valid
|
||||
*/
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* set the interrupt status register with the specified value such that
|
||||
* all bits which are set in the register are cleared effectively clearing
|
||||
* any active interrupts
|
||||
*/
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_GetIntrStatus
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the interrupt status register of the specified DMA channel.
|
||||
* The interrupt status register indicates which interrupts are active
|
||||
* for the DMA channel. If an interrupt is active, the status register must be
|
||||
* set (written) with the bit set for each interrupt which has been processed
|
||||
* in order to clear the interrupts. The definitions of each bit in the register
|
||||
* match the definition of the bits in the interrupt enable register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The interrupt status register contents of the specified DMA channel.
|
||||
* One or more of the following values may be contained the register.
|
||||
* Each of the values are unique bit masks.
|
||||
*
|
||||
* XDC_IXR_DMA_DONE_MASK The dma operation is done
|
||||
* XDC_IXR_DMA_ERROR_MASK The dma operation had an error
|
||||
* XDC_IXR_PKT_DONE_MASK A packet is complete
|
||||
* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached
|
||||
* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
|
||||
* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
|
||||
* XDC_IXR_SG_END_MASK Current descriptor was the end of the list
|
||||
* XDC_IXR_BD_MASK A buffer descriptor is done
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* return the contents of the interrupt status register */
|
||||
|
||||
return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_SetIntrEnable
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the interrupt enable register of the specified DMA
|
||||
* channel. The interrupt enable register contains bits which enable
|
||||
* individual interrupts for the DMA channel. The definitions of each bit
|
||||
* in the register match the definition of the bits in the interrupt status
|
||||
* register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* Enable contains the interrupt enable register contents to be written
|
||||
* in the DMA channel. One or more of the following values may be contained
|
||||
* the register. Each of the values are unique bit masks such that they may be
|
||||
* ORed together to enable multiple bits or inverted and ANDed to disable
|
||||
* multiple bits.
|
||||
*
|
||||
* XDC_IXR_DMA_DONE_MASK The dma operation is done
|
||||
* XDC_IXR_DMA_ERROR_MASK The dma operation had an error
|
||||
* XDC_IXR_PKT_DONE_MASK A packet is complete
|
||||
* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached
|
||||
* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
|
||||
* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
|
||||
* XDC_IXR_SG_END_MASK Current descriptor was the end of the list
|
||||
* XDC_IXR_BD_MASK A buffer descriptor is done
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable)
|
||||
{
|
||||
/* assert to verify input arguments except the enable which can't be
|
||||
* asserted since all values are valid
|
||||
*/
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* set the interrupt enable register to the specified value */
|
||||
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_GetIntrEnable
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the interrupt enable of the DMA channel. The
|
||||
* interrupt enable contains flags which enable individual interrupts for the
|
||||
* DMA channel. The definitions of each bit in the register match the definition
|
||||
* of the bits in the interrupt status register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The interrupt enable of the DMA channel. One or more of the following values
|
||||
* may be contained the register. Each of the values are unique bit masks.
|
||||
*
|
||||
* XDC_IXR_DMA_DONE_MASK The dma operation is done
|
||||
* XDC_IXR_DMA_ERROR_MASK The dma operation had an error
|
||||
* XDC_IXR_PKT_DONE_MASK A packet is complete
|
||||
* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached
|
||||
* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
|
||||
* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
|
||||
* XDC_IXR_BD_MASK A buffer descriptor is done
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* return the contents of the interrupt enable register */
|
||||
|
||||
return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION:
|
||||
*
|
||||
* XDmaChannel_Transfer
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function starts the DMA channel transferring data from a memory source
|
||||
* to a memory destination. This function only starts the operation and returns
|
||||
* before the operation may be complete. If the interrupt is enabled, an
|
||||
* interrupt will be generated when the operation is complete, otherwise it is
|
||||
* necessary to poll the channel status to determine when it's complete. It is
|
||||
* the responsibility of the caller to determine when the operation is complete
|
||||
* by handling the generated interrupt or polling the status. It is also the
|
||||
* responsibility of the caller to ensure that the DMA channel is not busy with
|
||||
* another transfer before calling this function.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* InstancePtr contains a pointer to the DMA channel to operate on.
|
||||
*
|
||||
* SourcePtr contains a pointer to the source memory where the data is to
|
||||
* be tranferred from and must be 32 bit aligned.
|
||||
*
|
||||
* DestinationPtr contains a pointer to the destination memory where the data
|
||||
* is to be transferred and must be 32 bit aligned.
|
||||
*
|
||||
* ByteCount contains the number of bytes to transfer during the DMA operation.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* The DMA h/w will not currently allow a non-local memory transfer to non-local
|
||||
* memory (memory copy), but only allows a non-local memory to or from the device
|
||||
* memory (typically a FIFO).
|
||||
*
|
||||
* It is the responsibility of the caller to ensure that the cache is
|
||||
* flushed and invalidated both before and after the DMA operation completes
|
||||
* if the memory pointed to is cached. The caller must also ensure that the
|
||||
* pointers contain a physical address rather than a virtual address
|
||||
* if address translation is being used.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XDmaChannel_Transfer(XDmaChannel * InstancePtr,
|
||||
u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount)
|
||||
{
|
||||
/* assert to verify input arguments and the alignment of any arguments
|
||||
* which have expected alignments
|
||||
*/
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(SourcePtr != NULL);
|
||||
XASSERT_VOID(((u32) SourcePtr & 3) == 0);
|
||||
XASSERT_VOID(DestinationPtr != NULL);
|
||||
XASSERT_VOID(((u32) DestinationPtr & 3) == 0);
|
||||
XASSERT_VOID(ByteCount != 0);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* setup the source and destination address registers for the transfer */
|
||||
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
|
||||
(u32) SourcePtr);
|
||||
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
|
||||
(u32) DestinationPtr);
|
||||
|
||||
/* start the DMA transfer to copy from the source buffer to the
|
||||
* destination buffer by writing the length to the length register
|
||||
*/
|
||||
XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
|
||||
}
|
||||
291
board/xilinx/common/xdma_channel.h
Normal file
291
board/xilinx/common/xdma_channel.h
Normal file
@@ -0,0 +1,291 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* FILENAME:
|
||||
*
|
||||
* xdma_channel.h
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This file contains the DMA channel component implementation. This component
|
||||
* supports a distributed DMA design in which each device can have it's own
|
||||
* dedicated DMA channel, as opposed to a centralized DMA design.
|
||||
* A device which uses DMA typically contains two DMA channels, one for
|
||||
* sending data and the other for receiving data.
|
||||
*
|
||||
* This component is designed to be used as a basic building block for
|
||||
* designing a device driver. It provides registers accesses such that all
|
||||
* DMA processing can be maintained easier, but the device driver designer
|
||||
* must still understand all the details of the DMA channel.
|
||||
*
|
||||
* The DMA channel allows a CPU to minimize the CPU interaction required to move
|
||||
* data between a memory and a device. The CPU requests the DMA channel to
|
||||
* perform a DMA operation and typically continues performing other processing
|
||||
* until the DMA operation completes. DMA could be considered a primitive form
|
||||
* of multiprocessing such that caching and address translation can be an issue.
|
||||
*
|
||||
* Scatter Gather Operations
|
||||
*
|
||||
* The DMA channel may support scatter gather operations. A scatter gather
|
||||
* operation automates the DMA channel such that multiple buffers can be
|
||||
* sent or received with minimal software interaction with the hardware. Buffer
|
||||
* descriptors, contained in the XBufDescriptor component, are used by the
|
||||
* scatter gather operations of the DMA channel to describe the buffers to be
|
||||
* processed.
|
||||
*
|
||||
* Scatter Gather List Operations
|
||||
*
|
||||
* A scatter gather list may be supported by each DMA channel. The scatter
|
||||
* gather list allows buffer descriptors to be put into the list by a device
|
||||
* driver which requires scatter gather. The hardware processes the buffer
|
||||
* descriptors which are contained in the list and modifies the buffer
|
||||
* descriptors to reflect the status of the DMA operations. The device driver
|
||||
* is notified by interrupt that specific DMA events occur including scatter
|
||||
* gather events. The device driver removes the completed buffer descriptors
|
||||
* from the scatter gather list to evaluate the status of each DMA operation.
|
||||
*
|
||||
* The scatter gather list is created and buffer descriptors are inserted into
|
||||
* the list. Buffer descriptors are never removed from the list after it's
|
||||
* creation such that a put operation copies from a temporary buffer descriptor
|
||||
* to a buffer descriptor in the list. Get operations don't copy from the list
|
||||
* to a temporary, but return a pointer to the buffer descriptor in the list.
|
||||
* A buffer descriptor in the list may be locked to prevent it from being
|
||||
* overwritten by a put operation. This allows the device driver to get a
|
||||
* descriptor from a scatter gather list and prevent it from being overwritten
|
||||
* until the buffer associated with the buffer descriptor has been processed.
|
||||
*
|
||||
* Typical Scatter Gather Processing
|
||||
*
|
||||
* The following steps illustrate the typical processing to use the
|
||||
* scatter gather features of a DMA channel.
|
||||
*
|
||||
* 1. Create a scatter gather list for the DMA channel which puts empty buffer
|
||||
* descriptors into the list.
|
||||
* 2. Create buffer descriptors which describe the buffers to be filled with
|
||||
* receive data or the buffers which contain data to be sent.
|
||||
* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
|
||||
* gather operations are requested.
|
||||
* 4. Commit the buffer descriptors in the list such that they are ready to be
|
||||
* used by the DMA channel hardware.
|
||||
* 5. Start the scatter gather operations of the DMA channel.
|
||||
* 6. Process any interrupts which occur as a result of the scatter gather
|
||||
* operations or poll the DMA channel to determine the status.
|
||||
*
|
||||
* Interrupts
|
||||
*
|
||||
* Each DMA channel has the ability to generate an interrupt. This component
|
||||
* does not perform processing for the interrupt as this processing is typically
|
||||
* tightly coupled with the device which is using the DMA channel. It is the
|
||||
* responsibility of the caller of DMA functions to manage the interrupt
|
||||
* including connecting to the interrupt and enabling/disabling the interrupt.
|
||||
*
|
||||
* Critical Sections
|
||||
*
|
||||
* It is the responsibility of the device driver designer to use critical
|
||||
* sections as necessary when calling functions of the DMA channel. This
|
||||
* component does not use critical sections and it does access registers using
|
||||
* read-modify-write operations. Calls to DMA functions from a main thread
|
||||
* and from an interrupt context could produce unpredictable behavior such that
|
||||
* the caller must provide the appropriate critical sections.
|
||||
*
|
||||
* Address Translation
|
||||
*
|
||||
* All addresses of data structures which are passed to DMA functions must
|
||||
* be physical (real) addresses as opposed to logical (virtual) addresses.
|
||||
*
|
||||
* Caching
|
||||
*
|
||||
* The memory which is passed to the function which creates the scatter gather
|
||||
* list must not be cached such that buffer descriptors are non-cached. This
|
||||
* is necessary because the buffer descriptors are kept in a ring buffer and
|
||||
* not directly accessible to the caller of DMA functions.
|
||||
*
|
||||
* The caller of DMA functions is responsible for ensuring that any data
|
||||
* buffers which are passed to the DMA channel are cache-line aligned if
|
||||
* necessary.
|
||||
*
|
||||
* The caller of DMA functions is responsible for ensuring that any data
|
||||
* buffers which are passed to the DMA channel have been flushed from the cache.
|
||||
*
|
||||
* The caller of DMA functions is responsible for ensuring that the cache is
|
||||
* invalidated prior to using any data buffers which are the result of a DMA
|
||||
* operation.
|
||||
*
|
||||
* Memory Alignment
|
||||
*
|
||||
* The addresses of data buffers which are passed to DMA functions must be
|
||||
* 32 bit word aligned since the DMA hardware performs 32 bit word transfers.
|
||||
*
|
||||
* Mutual Exclusion
|
||||
*
|
||||
* The functions of the DMA channel are not thread safe such that the caller
|
||||
* of all DMA functions is responsible for ensuring mutual exclusion for a
|
||||
* DMA channel. Mutual exclusion across multiple DMA channels is not
|
||||
* necessary.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Many of the provided functions which are register accessors don't provide
|
||||
* a lot of error detection. The caller is expected to understand the impact
|
||||
* of a function call based upon the current state of the DMA channel. This
|
||||
* is done to minimize the overhead in this component.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XDMA_CHANNEL_H /* prevent circular inclusions */
|
||||
#define XDMA_CHANNEL_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xdma_channel_i.h" /* constants shared with buffer descriptor */
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xversion.h"
|
||||
#include "xbuf_descriptor.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* the following constants provide access to the bit fields of the DMA control
|
||||
* register (DMACR)
|
||||
*/
|
||||
#define XDC_DMACR_SOURCE_INCR_MASK 0x80000000UL /* increment source address */
|
||||
#define XDC_DMACR_DEST_INCR_MASK 0x40000000UL /* increment dest address */
|
||||
#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL /* local source address */
|
||||
#define XDC_DMACR_DEST_LOCAL_MASK 0x10000000UL /* local dest address */
|
||||
#define XDC_DMACR_SG_DISABLE_MASK 0x08000000UL /* scatter gather disable */
|
||||
#define XDC_DMACR_GEN_BD_INTR_MASK 0x04000000UL /* descriptor interrupt */
|
||||
#define XDC_DMACR_LAST_BD_MASK XDC_CONTROL_LAST_BD_MASK /* last buffer */
|
||||
/* descriptor */
|
||||
|
||||
/* the following constants provide access to the bit fields of the DMA status
|
||||
* register (DMASR)
|
||||
*/
|
||||
#define XDC_DMASR_BUSY_MASK 0x80000000UL /* channel is busy */
|
||||
#define XDC_DMASR_BUS_ERROR_MASK 0x40000000UL /* bus error occurred */
|
||||
#define XDC_DMASR_BUS_TIMEOUT_MASK 0x20000000UL /* bus timeout occurred */
|
||||
#define XDC_DMASR_LAST_BD_MASK XDC_STATUS_LAST_BD_MASK /* last buffer */
|
||||
/* descriptor */
|
||||
#define XDC_DMASR_SG_BUSY_MASK 0x08000000UL /* scatter gather is busy */
|
||||
|
||||
/* the following constants provide access to the bit fields of the interrupt
|
||||
* status register (ISR) and the interrupt enable register (IER), bit masks
|
||||
* match for both registers such that they are named IXR
|
||||
*/
|
||||
#define XDC_IXR_DMA_DONE_MASK 0x1UL /* dma operation done */
|
||||
#define XDC_IXR_DMA_ERROR_MASK 0x2UL /* dma operation error */
|
||||
#define XDC_IXR_PKT_DONE_MASK 0x4UL /* packet done */
|
||||
#define XDC_IXR_PKT_THRESHOLD_MASK 0x8UL /* packet count threshold */
|
||||
#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL /* packet wait bound reached */
|
||||
#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL /* scatter gather disable
|
||||
acknowledge occurred */
|
||||
#define XDC_IXR_SG_END_MASK 0x40UL /* last buffer descriptor
|
||||
disabled scatter gather */
|
||||
#define XDC_IXR_BD_MASK 0x80UL /* buffer descriptor done */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* the following structure contains data which is on a per instance basis
|
||||
* for the XDmaChannel component
|
||||
*/
|
||||
typedef struct XDmaChannelTag {
|
||||
XVersion Version; /* version of the driver */
|
||||
u32 RegBaseAddress; /* base address of registers */
|
||||
u32 IsReady; /* device is initialized and ready */
|
||||
|
||||
XBufDescriptor *PutPtr; /* keep track of where to put into list */
|
||||
XBufDescriptor *GetPtr; /* keep track of where to get from list */
|
||||
XBufDescriptor *CommitPtr; /* keep track of where to commit in list */
|
||||
XBufDescriptor *LastPtr; /* keep track of the last put in the list */
|
||||
u32 TotalDescriptorCount; /* total # of descriptors in the list */
|
||||
u32 ActiveDescriptorCount; /* # of descriptors pointing to buffers
|
||||
* in the buffer descriptor list */
|
||||
} XDmaChannel;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
|
||||
u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr);
|
||||
XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr);
|
||||
XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_Reset(XDmaChannel * InstancePtr);
|
||||
|
||||
/* Control functions */
|
||||
|
||||
u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control);
|
||||
|
||||
/* Status functions */
|
||||
|
||||
u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status);
|
||||
u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable);
|
||||
u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr);
|
||||
|
||||
/* DMA without scatter gather functions */
|
||||
|
||||
void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
|
||||
u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount);
|
||||
|
||||
/* Scatter gather functions */
|
||||
|
||||
XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr);
|
||||
XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr,
|
||||
XBufDescriptor ** BufDescriptorPtr);
|
||||
XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
|
||||
u32 * MemoryPtr, u32 ByteCount);
|
||||
u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr);
|
||||
|
||||
XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
|
||||
XBufDescriptor * BufDescriptorPtr);
|
||||
XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
|
||||
XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
|
||||
XBufDescriptor ** BufDescriptorPtr);
|
||||
|
||||
/* Packet functions for interrupt collescing */
|
||||
|
||||
u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr);
|
||||
XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
|
||||
u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr);
|
||||
void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound);
|
||||
u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
110
board/xilinx/common/xdma_channel_i.h
Normal file
110
board/xilinx/common/xdma_channel_i.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* FILENAME:
|
||||
*
|
||||
* xdma_channel_i.h
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This file contains data which is shared internal data for the DMA channel
|
||||
* component. It is also shared with the buffer descriptor component which is
|
||||
* very tightly coupled with the DMA channel component.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* The last buffer descriptor constants must be located here to prevent a
|
||||
* circular dependency between the DMA channel component and the buffer
|
||||
* descriptor component.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XDMA_CHANNEL_I_H /* prevent circular inclusions */
|
||||
#define XDMA_CHANNEL_I_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xversion.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define XDC_DMA_CHANNEL_V1_00_A "1.00a"
|
||||
|
||||
/* the following constant provides access to the bit fields of the DMA control
|
||||
* register (DMACR) which must be shared between the DMA channel component
|
||||
* and the buffer descriptor component
|
||||
*/
|
||||
#define XDC_CONTROL_LAST_BD_MASK 0x02000000UL /* last buffer descriptor */
|
||||
|
||||
/* the following constant provides access to the bit fields of the DMA status
|
||||
* register (DMASR) which must be shared between the DMA channel component
|
||||
* and the buffer descriptor component
|
||||
*/
|
||||
#define XDC_STATUS_LAST_BD_MASK 0x10000000UL /* last buffer descriptor */
|
||||
|
||||
/* the following constants provide access to each of the registers of a DMA
|
||||
* channel
|
||||
*/
|
||||
#define XDC_RST_REG_OFFSET 0 /* reset register */
|
||||
#define XDC_MI_REG_OFFSET 0 /* module information register */
|
||||
#define XDC_DMAC_REG_OFFSET 4 /* DMA control register */
|
||||
#define XDC_SA_REG_OFFSET 8 /* source address register */
|
||||
#define XDC_DA_REG_OFFSET 12 /* destination address register */
|
||||
#define XDC_LEN_REG_OFFSET 16 /* length register */
|
||||
#define XDC_DMAS_REG_OFFSET 20 /* DMA status register */
|
||||
#define XDC_BDA_REG_OFFSET 24 /* buffer descriptor address register */
|
||||
#define XDC_SWCR_REG_OFFSET 28 /* software control register */
|
||||
#define XDC_UPC_REG_OFFSET 32 /* unserviced packet count register */
|
||||
#define XDC_PCT_REG_OFFSET 36 /* packet count threshold register */
|
||||
#define XDC_PWB_REG_OFFSET 40 /* packet wait bound register */
|
||||
#define XDC_IS_REG_OFFSET 44 /* interrupt status register */
|
||||
#define XDC_IE_REG_OFFSET 48 /* interrupt enable register */
|
||||
|
||||
/* the following constant is written to the reset register to reset the
|
||||
* DMA channel
|
||||
*/
|
||||
#define XDC_RESET_MASK 0x0000000AUL
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#endif /* end of protection macro */
|
||||
1317
board/xilinx/common/xdma_channel_sg.c
Normal file
1317
board/xilinx/common/xdma_channel_sg.c
Normal file
File diff suppressed because it is too large
Load Diff
81
board/xilinx/common/xio.h
Normal file
81
board/xilinx/common/xio.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* xio.h
|
||||
*
|
||||
* Defines XIo functions for Xilinx OCP in terms of Linux primitives
|
||||
*
|
||||
* Author: MontaVista Software, Inc.
|
||||
* source@mvista.com
|
||||
*
|
||||
* Copyright 2002 MontaVista Software Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef XIO_H
|
||||
#define XIO_H
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include <asm/io.h>
|
||||
|
||||
typedef u32 XIo_Address;
|
||||
|
||||
extern inline u8
|
||||
XIo_In8(XIo_Address InAddress)
|
||||
{
|
||||
return (u8) in_8((volatile unsigned char *) InAddress);
|
||||
}
|
||||
extern inline u16
|
||||
XIo_In16(XIo_Address InAddress)
|
||||
{
|
||||
return (u16) in_be16((volatile unsigned short *) InAddress);
|
||||
}
|
||||
extern inline u32
|
||||
XIo_In32(XIo_Address InAddress)
|
||||
{
|
||||
return (u32) in_be32((volatile unsigned *) InAddress);
|
||||
}
|
||||
extern inline void
|
||||
XIo_Out8(XIo_Address OutAddress, u8 Value)
|
||||
{
|
||||
out_8((volatile unsigned char *) OutAddress, Value);
|
||||
}
|
||||
extern inline void
|
||||
XIo_Out16(XIo_Address OutAddress, u16 Value)
|
||||
{
|
||||
out_be16((volatile unsigned short *) OutAddress, Value);
|
||||
}
|
||||
extern inline void
|
||||
XIo_Out32(XIo_Address OutAddress, u32 Value)
|
||||
{
|
||||
out_be32((volatile unsigned *) OutAddress, Value);
|
||||
}
|
||||
|
||||
#define XIo_ToLittleEndian16(s,d) (*(u16*)(d) = cpu_to_le16((u16)(s)))
|
||||
#define XIo_ToLittleEndian32(s,d) (*(u32*)(d) = cpu_to_le32((u32)(s)))
|
||||
#define XIo_ToBigEndian16(s,d) (*(u16*)(d) = cpu_to_be16((u16)(s)))
|
||||
#define XIo_ToBigEndian32(s,d) (*(u32*)(d) = cpu_to_be32((u32)(s)))
|
||||
|
||||
#define XIo_FromLittleEndian16(s,d) (*(u16*)(d) = le16_to_cpu((u16)(s)))
|
||||
#define XIo_FromLittleEndian32(s,d) (*(u32*)(d) = le32_to_cpu((u32)(s)))
|
||||
#define XIo_FromBigEndian16(s,d) (*(u16*)(d) = be16_to_cpu((u16)(s)))
|
||||
#define XIo_FromBigEndian32(s,d) (*(u32*)(d) = be32_to_cpu((u32)(s)))
|
||||
|
||||
#endif /* XIO_H */
|
||||
763
board/xilinx/common/xipif_v1_23_b.h
Normal file
763
board/xilinx/common/xipif_v1_23_b.h
Normal file
@@ -0,0 +1,763 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILENAME:
|
||||
*
|
||||
* xipif.h
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* The XIpIf component encapsulates the IPIF, which is the standard interface
|
||||
* that IP must adhere to when connecting to a bus. The purpose of this
|
||||
* component is to encapsulate the IPIF processing such that maintainability
|
||||
* is increased. This component does not provide a lot of abstraction from
|
||||
* from the details of the IPIF as it is considered a building block for
|
||||
* device drivers. A device driver designer must be familiar with the
|
||||
* details of the IPIF hardware to use this component.
|
||||
*
|
||||
* The IPIF hardware provides a building block for all hardware devices such
|
||||
* that each device does not need to reimplement these building blocks. The
|
||||
* IPIF contains other building blocks, such as FIFOs and DMA channels, which
|
||||
* are also common to many devices. These blocks are implemented as separate
|
||||
* hardware blocks and instantiated within the IPIF. The primary hardware of
|
||||
* the IPIF which is implemented by this software component is the interrupt
|
||||
* architecture. Since there are many blocks of a device which may generate
|
||||
* interrupts, all the interrupt processing is contained in the common part
|
||||
* of the device, the IPIF. This interrupt processing is for the device level
|
||||
* only and does not include any processing for the interrupt controller.
|
||||
*
|
||||
* A device is a mechanism such as an Ethernet MAC. The device is made
|
||||
* up of several parts which include an IPIF and the IP. The IPIF contains most
|
||||
* of the device infrastructure which is common to all devices, such as
|
||||
* interrupt processing, DMA channels, and FIFOs. The infrastructure may also
|
||||
* be referred to as IPIF internal blocks since they are part of the IPIF and
|
||||
* are separate blocks that can be selected based upon the needs of the device.
|
||||
* The IP of the device is the logic that is unique to the device and interfaces
|
||||
* to the IPIF of the device.
|
||||
*
|
||||
* In general, there are two levels of registers within the IPIF. The first
|
||||
* level, referred to as the device level, contains registers which are for the
|
||||
* entire device. The second level, referred to as the IP level, contains
|
||||
* registers which are specific to the IP of the device. The two levels of
|
||||
* registers are designed to be hierarchical such that the device level is
|
||||
* is a more general register set above the more specific registers of the IP.
|
||||
* The IP level of registers provides functionality which is typically common
|
||||
* across all devices and allows IP designers to focus on the unique aspects
|
||||
* of the IP.
|
||||
*
|
||||
* Critical Sections
|
||||
*
|
||||
* It is the responsibility of the device driver designer to use critical
|
||||
* sections as necessary when calling functions of the IPIF. This component
|
||||
* does not use critical sections and it does access registers using
|
||||
* read-modify-write operations. Calls to IPIF functions from a main thread
|
||||
* and from an interrupt context could produce unpredictable behavior such that
|
||||
* the caller must provide the appropriate critical sections.
|
||||
*
|
||||
* Mutual Exclusion
|
||||
*
|
||||
* The functions of the IPIF are not thread safe such that the caller of all
|
||||
* functions is responsible for ensuring mutual exclusion for an IPIF. Mutual
|
||||
* exclusion across multiple IPIF components is not necessary.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.23b jhl 02/27/01 Repartioned to minimize size
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIPIF_H /* prevent circular inclusions */
|
||||
#define XIPIF_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xversion.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* the following constants define the register offsets for the registers of the
|
||||
* IPIF, there are some holes in the memory map for reserved addresses to allow
|
||||
* other registers to be added and still match the memory map of the interrupt
|
||||
* controller registers
|
||||
*/
|
||||
#define XIIF_V123B_DISR_OFFSET 0UL /* device interrupt status register */
|
||||
#define XIIF_V123B_DIPR_OFFSET 4UL /* device interrupt pending register */
|
||||
#define XIIF_V123B_DIER_OFFSET 8UL /* device interrupt enable register */
|
||||
#define XIIF_V123B_DIIR_OFFSET 24UL /* device interrupt ID register */
|
||||
#define XIIF_V123B_DGIER_OFFSET 28UL /* device global interrupt enable reg */
|
||||
#define XIIF_V123B_IISR_OFFSET 32UL /* IP interrupt status register */
|
||||
#define XIIF_V123B_IIER_OFFSET 40UL /* IP interrupt enable register */
|
||||
#define XIIF_V123B_RESETR_OFFSET 64UL /* reset register */
|
||||
|
||||
#define XIIF_V123B_RESET_MASK 0xAUL
|
||||
|
||||
/* the following constant is used for the device global interrupt enable
|
||||
* register, to enable all interrupts for the device, this is the only bit
|
||||
* in the register
|
||||
*/
|
||||
#define XIIF_V123B_GINTR_ENABLE_MASK 0x80000000UL
|
||||
|
||||
/* the following constants contain the masks to identify each internal IPIF
|
||||
* condition in the device registers of the IPIF, interrupts are assigned
|
||||
* in the register from LSB to the MSB
|
||||
*/
|
||||
#define XIIF_V123B_ERROR_MASK 1UL /* LSB of the register */
|
||||
|
||||
/* The following constants contain interrupt IDs which identify each internal
|
||||
* IPIF condition, this value must correlate with the mask constant for the
|
||||
* error
|
||||
*/
|
||||
#define XIIF_V123B_ERROR_INTERRUPT_ID 0 /* interrupt bit #, (LSB = 0) */
|
||||
#define XIIF_V123B_NO_INTERRUPT_ID 128 /* no interrupts are pending */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_RESET
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Reset the IPIF component and hardware. This is a destructive operation that
|
||||
* could cause the loss of data since resetting the IPIF of a device also
|
||||
* resets the device using the IPIF and any blocks, such as FIFOs or DMA
|
||||
* channels, within the IPIF. All registers of the IPIF will contain their
|
||||
* reset value when this function returns.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* the following constant is used in the reset register to cause the IPIF to
|
||||
* reset
|
||||
*/
|
||||
#define XIIF_V123B_RESET(RegBaseAddress) \
|
||||
XIo_Out32(RegBaseAddress + XIIF_V123B_RESETR_OFFSET, XIIF_V123B_RESET_MASK)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_WRITE_DISR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the device interrupt status register to the value.
|
||||
* This register indicates the status of interrupt sources for a device
|
||||
* which contains the IPIF. The status is independent of whether interrupts
|
||||
* are enabled and could be used for polling a device at a higher level rather
|
||||
* than a more detailed level.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* device which contains the IPIF. With the exception of some internal IPIF
|
||||
* conditions, the contents of this register are not latched but indicate
|
||||
* the live status of the interrupt sources within the device. Writing any of
|
||||
* the non-latched bits of the register will have no effect on the register.
|
||||
*
|
||||
* For the latched bits of this register only, setting a bit which is zero
|
||||
* within this register causes an interrupt to generated. The device global
|
||||
* interrupt enable register and the device interrupt enable register must be set
|
||||
* appropriately to allow an interrupt to be passed out of the device. The
|
||||
* interrupt is cleared by writing to this register with the bits to be
|
||||
* cleared set to a one and all others to zero. This register implements a
|
||||
* toggle on write functionality meaning any bits which are set in the value
|
||||
* written cause the bits in the register to change to the opposite state.
|
||||
*
|
||||
* This function writes the specified value to the register such that
|
||||
* some bits may be set and others cleared. It is the caller's responsibility
|
||||
* to get the value of the register prior to setting the value to prevent a
|
||||
* destructive behavior.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* Status contains the value to be written to the interrupt status register of
|
||||
* the device. The only bits which can be written are the latched bits which
|
||||
* contain the internal IPIF conditions. The following values may be used to
|
||||
* set the status register or clear an interrupt condition.
|
||||
*
|
||||
* XIIF_V123B_ERROR_MASK Indicates a device error in the IPIF
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_WRITE_DISR(RegBaseAddress, Status) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_DISR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the device interrupt status register contents.
|
||||
* This register indicates the status of interrupt sources for a device
|
||||
* which contains the IPIF. The status is independent of whether interrupts
|
||||
* are enabled and could be used for polling a device at a higher level.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* device which contains the IPIF. With the exception of some internal IPIF
|
||||
* conditions, the contents of this register are not latched but indicate
|
||||
* the live status of the interrupt sources within the device.
|
||||
*
|
||||
* For only the latched bits of this register, the interrupt may be cleared by
|
||||
* writing to these bits in the status register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* A status which contains the value read from the interrupt status register of
|
||||
* the device. The bit definitions are specific to the device with
|
||||
* the exception of the latched internal IPIF condition bits. The following
|
||||
* values may be used to detect internal IPIF conditions in the status.
|
||||
*
|
||||
* XIIF_V123B_ERROR_MASK Indicates a device error in the IPIF
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_DISR(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_WRITE_DIER
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the device interrupt enable register contents.
|
||||
* This register controls which interrupt sources of the device are allowed to
|
||||
* generate an interrupt. The device global interrupt enable register must also
|
||||
* be set appropriately for an interrupt to be passed out of the device.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* device which contains the IPIF. Setting a bit in this register enables that
|
||||
* interrupt source to generate an interrupt. Clearing a bit in this register
|
||||
* disables interrupt generation for that interrupt source.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupts source may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent an destructive behavior.
|
||||
*
|
||||
* An interrupt source may not be enabled to generate an interrupt, but can
|
||||
* still be polled in the interrupt status register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* Enable contains the value to be written to the interrupt enable register
|
||||
* of the device. The bit definitions are specific to the device with
|
||||
* the exception of the internal IPIF conditions. The following
|
||||
* values may be used to enable the internal IPIF conditions interrupts.
|
||||
*
|
||||
* XIIF_V123B_ERROR_MASK Indicates a device error in the IPIF
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Signature: u32 XIIF_V123B_WRITE_DIER(u32 RegBaseAddress,
|
||||
* u32 Enable)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_WRITE_DIER(RegBaseAddress, Enable) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_DIER
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the device interrupt enable register contents.
|
||||
* This register controls which interrupt sources of the device
|
||||
* are allowed to generate an interrupt. The device global interrupt enable
|
||||
* register and the device interrupt enable register must also be set
|
||||
* appropriately for an interrupt to be passed out of the device.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* device which contains the IPIF. Setting a bit in this register enables that
|
||||
* interrupt source to generate an interrupt if the global enable is set
|
||||
* appropriately. Clearing a bit in this register disables interrupt generation
|
||||
* for that interrupt source regardless of the global interrupt enable.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The value read from the interrupt enable register of the device. The bit
|
||||
* definitions are specific to the device with the exception of the internal
|
||||
* IPIF conditions. The following values may be used to determine from the
|
||||
* value if the internal IPIF conditions interrupts are enabled.
|
||||
*
|
||||
* XIIF_V123B_ERROR_MASK Indicates a device error in the IPIF
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_DIER(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_DIPR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the device interrupt pending register contents.
|
||||
* This register indicates the pending interrupt sources, those that are waiting
|
||||
* to be serviced by the software, for a device which contains the IPIF.
|
||||
* An interrupt must be enabled in the interrupt enable register of the IPIF to
|
||||
* be pending.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* the device which contains the IPIF. With the exception of some internal IPIF
|
||||
* conditions, the contents of this register are not latched since the condition
|
||||
* is latched in the IP interrupt status register, by an internal block of the
|
||||
* IPIF such as a FIFO or DMA channel, or by the IP of the device. This register
|
||||
* is read only and is not latched, but it is necessary to acknowledge (clear)
|
||||
* the interrupt condition by performing the appropriate processing for the IP
|
||||
* or block within the IPIF.
|
||||
*
|
||||
* This register can be thought of as the contents of the interrupt status
|
||||
* register ANDed with the contents of the interrupt enable register.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The value read from the interrupt pending register of the device. The bit
|
||||
* definitions are specific to the device with the exception of the latched
|
||||
* internal IPIF condition bits. The following values may be used to detect
|
||||
* internal IPIF conditions in the value.
|
||||
*
|
||||
* XIIF_V123B_ERROR_MASK Indicates a device error in the IPIF
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_DIPR(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_DIPR_OFFSET)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_DIIR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the device interrupt ID for the highest priority interrupt
|
||||
* which is pending from the interrupt ID register. This function provides
|
||||
* priority resolution such that faster interrupt processing is possible.
|
||||
* Without priority resolution, it is necessary for the software to read the
|
||||
* interrupt pending register and then check each interrupt source to determine
|
||||
* if an interrupt is pending. Priority resolution becomes more important as the
|
||||
* number of interrupt sources becomes larger.
|
||||
*
|
||||
* Interrupt priorities are based upon the bit position of the interrupt in the
|
||||
* interrupt pending register with bit 0 being the highest priority. The
|
||||
* interrupt ID is the priority of the interrupt, 0 - 31, with 0 being the
|
||||
* highest priority. The interrupt ID register is live rather than latched such
|
||||
* that multiple calls to this function may not yield the same results. A
|
||||
* special value, outside of the interrupt priority range of 0 - 31, is
|
||||
* contained in the register which indicates that no interrupt is pending. This
|
||||
* may be useful for allowing software to continue processing interrupts in a
|
||||
* loop until there are no longer any interrupts pending.
|
||||
*
|
||||
* The interrupt ID is designed to allow a function pointer table to be used
|
||||
* in the software such that the interrupt ID is used as an index into that
|
||||
* table. The function pointer table could contain an instance pointer, such
|
||||
* as to DMA channel, and a function pointer to the function which handles
|
||||
* that interrupt. This design requires the interrupt processing of the device
|
||||
* driver to be partitioned into smaller more granular pieces based upon
|
||||
* hardware used by the device, such as DMA channels and FIFOs.
|
||||
*
|
||||
* It is not mandatory that this function be used by the device driver software.
|
||||
* It may choose to read the pending register and resolve the pending interrupt
|
||||
* priorities on it's own.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* An interrupt ID, 0 - 31, which identifies the highest priority interrupt
|
||||
* which is pending. A value of XIIF_NO_INTERRUPT_ID indicates that there is
|
||||
* no interrupt pending. The following values may be used to identify the
|
||||
* interrupt ID for the internal IPIF interrupts.
|
||||
*
|
||||
* XIIF_V123B_ERROR_INTERRUPT_ID Indicates a device error in the IPIF
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_DIIR(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_DIIR_OFFSET)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_GLOBAL_INTR_DISABLE
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function disables all interrupts for the device by writing to the global
|
||||
* interrupt enable register. This register provides the ability to disable
|
||||
* interrupts without any modifications to the interrupt enable register such
|
||||
* that it is minimal effort to restore the interrupts to the previous enabled
|
||||
* state. The corresponding function, XIpIf_GlobalIntrEnable, is provided to
|
||||
* restore the interrupts to the previous enabled state. This function is
|
||||
* designed to be used in critical sections of device drivers such that it is
|
||||
* not necessary to disable other device interrupts.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_GINTR_DISABLE(RegBaseAddress) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, 0)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_GINTR_ENABLE
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function writes to the global interrupt enable register to enable
|
||||
* interrupts from the device. This register provides the ability to enable
|
||||
* interrupts without any modifications to the interrupt enable register such
|
||||
* that it is minimal effort to restore the interrupts to the previous enabled
|
||||
* state. This function does not enable individual interrupts as the interrupt
|
||||
* enable register must be set appropriately. This function is designed to be
|
||||
* used in critical sections of device drivers such that it is not necessary to
|
||||
* disable other device interrupts.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_GINTR_ENABLE(RegBaseAddress) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, \
|
||||
XIIF_V123B_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_IS_GINTR_ENABLED
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function determines if interrupts are enabled at the global level by
|
||||
* reading the gloabl interrupt register. This register provides the ability to
|
||||
* disable interrupts without any modifications to the interrupt enable register
|
||||
* such that it is minimal effort to restore the interrupts to the previous
|
||||
* enabled state.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_IS_GINTR_ENABLED(RegBaseAddress) \
|
||||
(XIo_In32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET) == \
|
||||
XIIF_V123B_GINTR_ENABLE_MASK)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_WRITE_IISR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the IP interrupt status register to the specified value.
|
||||
* This register indicates the status of interrupt sources for the IP of the
|
||||
* device. The IP is defined as the part of the device that connects to the
|
||||
* IPIF. The status is independent of whether interrupts are enabled such that
|
||||
* the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* IP. All bits of this register are latched. Setting a bit which is zero
|
||||
* within this register causes an interrupt to be generated. The device global
|
||||
* interrupt enable register and the device interrupt enable register must be set
|
||||
* appropriately to allow an interrupt to be passed out of the device. The
|
||||
* interrupt is cleared by writing to this register with the bits to be
|
||||
* cleared set to a one and all others to zero. This register implements a
|
||||
* toggle on write functionality meaning any bits which are set in the value
|
||||
* written cause the bits in the register to change to the opposite state.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some status bits may be set and others cleared. It is the caller's
|
||||
* responsibility to get the value of the register prior to setting the value
|
||||
* to prevent an destructive behavior.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* Status contains the value to be written to the IP interrupt status
|
||||
* register. The bit definitions are specific to the device IP.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_WRITE_IISR(RegBaseAddress, Status) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET, (Status))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_IISR
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function gets the contents of the IP interrupt status register.
|
||||
* This register indicates the status of interrupt sources for the IP of the
|
||||
* device. The IP is defined as the part of the device that connects to the
|
||||
* IPIF. The status is independent of whether interrupts are enabled such
|
||||
* that the status register may also be polled when interrupts are not enabled.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* device. All bits of this register are latched. Writing a 1 to a bit within
|
||||
* this register causes an interrupt to be generated if enabled in the interrupt
|
||||
* enable register and the global interrupt enable is set. Since the status is
|
||||
* latched, each status bit must be acknowledged in order for the bit in the
|
||||
* status register to be updated. Each bit can be acknowledged by writing a
|
||||
* 0 to the bit in the status register.
|
||||
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* A status which contains the value read from the IP interrupt status register.
|
||||
* The bit definitions are specific to the device IP.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_IISR(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_WRITE_IIER
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This function sets the IP interrupt enable register contents. This register
|
||||
* controls which interrupt sources of the IP are allowed to generate an
|
||||
* interrupt. The global interrupt enable register and the device interrupt
|
||||
* enable register must also be set appropriately for an interrupt to be
|
||||
* passed out of the device containing the IPIF and the IP.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* IP. Setting a bit in this register enables the interrupt source to generate
|
||||
* an interrupt. Clearing a bit in this register disables interrupt generation
|
||||
* for that interrupt source.
|
||||
*
|
||||
* This function writes only the specified value to the register such that
|
||||
* some interrupt sources may be enabled and others disabled. It is the
|
||||
* caller's responsibility to get the value of the interrupt enable register
|
||||
* prior to setting the value to prevent an destructive behavior.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* Enable contains the value to be written to the IP interrupt enable register.
|
||||
* The bit definitions are specific to the device IP.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_WRITE_IIER(RegBaseAddress, Enable) \
|
||||
XIo_Out32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET, (Enable))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MACRO:
|
||||
*
|
||||
* XIIF_V123B_READ_IIER
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
*
|
||||
* This function gets the IP interrupt enable register contents. This register
|
||||
* controls which interrupt sources of the IP are allowed to generate an
|
||||
* interrupt. The global interrupt enable register and the device interrupt
|
||||
* enable register must also be set appropriately for an interrupt to be
|
||||
* passed out of the device containing the IPIF and the IP.
|
||||
*
|
||||
* Each bit of the register correlates to a specific interrupt source within the
|
||||
* IP. Setting a bit in this register enables the interrupt source to generate
|
||||
* an interrupt. Clearing a bit in this register disables interrupt generation
|
||||
* for that interrupt source.
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* RegBaseAddress contains the base address of the IPIF registers.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
*
|
||||
* The contents read from the IP interrupt enable register. The bit definitions
|
||||
* are specific to the device IP.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* Signature: u32 XIIF_V123B_READ_IIER(u32 RegBaseAddress)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XIIF_V123B_READ_IIER(RegBaseAddress) \
|
||||
XIo_In32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET)
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization Functions
|
||||
*/
|
||||
XStatus XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
448
board/xilinx/common/xpacket_fifo_v1_00_b.c
Normal file
448
board/xilinx/common/xpacket_fifo_v1_00_b.c
Normal file
@@ -0,0 +1,448 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* @file xpacket_fifo_v1_00_b.c
|
||||
*
|
||||
* Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h
|
||||
* for more information about the component.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b rpm 03/26/02 First release
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xio.h"
|
||||
#include "xstatus.h"
|
||||
#include "xpacket_fifo_v1_00_b.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* width of a FIFO word */
|
||||
|
||||
#define XPF_FIFO_WIDTH_BYTE_COUNT 4UL
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************* Variable Definitions ******************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* This function initializes a packet FIFO. Initialization resets the
|
||||
* FIFO such that it's empty and ready to use.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
* @param RegBaseAddress contains the base address of the registers for
|
||||
* the packet FIFO.
|
||||
* @param DataBaseAddress contains the base address of the data for
|
||||
* the packet FIFO.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Always returns XST_SUCCESS.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
|
||||
u32 RegBaseAddress, u32 DataBaseAddress)
|
||||
{
|
||||
/* assert to verify input argument are valid */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
|
||||
/* initialize the component variables to the specified state */
|
||||
|
||||
InstancePtr->RegBaseAddress = RegBaseAddress;
|
||||
InstancePtr->DataBaseAddress = DataBaseAddress;
|
||||
InstancePtr->IsReady = XCOMPONENT_IS_READY;
|
||||
|
||||
/* reset the FIFO such that it's empty and ready to use and indicate the
|
||||
* initialization was successful, note that the is ready variable must be
|
||||
* set prior to calling the reset function to prevent an assert
|
||||
*/
|
||||
XPF_V100B_RESET(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* This function performs a self-test on the specified packet FIFO. The self
|
||||
* test resets the FIFO and reads a register to determine if it is the correct
|
||||
* reset value. This test is destructive in that any data in the FIFO will
|
||||
* be lost.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the packet FIFO to be operated on.
|
||||
*
|
||||
* @param FifoType specifies the type of FIFO, read or write, for the self test.
|
||||
* The FIFO type is specified by the values XPF_READ_FIFO_TYPE or
|
||||
* XPF_WRITE_FIFO_TYPE.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS is returned if the selftest is successful, or
|
||||
* XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the
|
||||
* occupancy/vacancy count register after a reset does not match the
|
||||
* specified reset value.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType)
|
||||
{
|
||||
u32 Register;
|
||||
|
||||
/* assert to verify valid input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID((FifoType == XPF_READ_FIFO_TYPE) ||
|
||||
(FifoType == XPF_WRITE_FIFO_TYPE));
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* reset the fifo and then check to make sure the occupancy/vacancy
|
||||
* register contents are correct for a reset condition
|
||||
*/
|
||||
XPF_V100B_RESET(InstancePtr);
|
||||
|
||||
Register = XIo_In32(InstancePtr->RegBaseAddress +
|
||||
XPF_COUNT_STATUS_REG_OFFSET);
|
||||
|
||||
/* check the value of the register to ensure that it's correct for the
|
||||
* specified FIFO type since both FIFO types reset to empty, but a bit
|
||||
* in the register changes definition based upon FIFO type
|
||||
*/
|
||||
|
||||
if (FifoType == XPF_READ_FIFO_TYPE) {
|
||||
/* check the regiser value for a read FIFO which should be empty */
|
||||
|
||||
if (Register != XPF_EMPTY_FULL_MASK) {
|
||||
return XST_PFIFO_BAD_REG_VALUE;
|
||||
}
|
||||
} else {
|
||||
/* check the register value for a write FIFO which should not be full
|
||||
* on reset
|
||||
*/
|
||||
if ((Register & XPF_EMPTY_FULL_MASK) != 0) {
|
||||
return XST_PFIFO_BAD_REG_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* the test was successful */
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is
|
||||
* currently 32 bits wide such that an input buffer which is a series of bytes
|
||||
* is filled from the FIFO a word at a time. If the requested byte count is not
|
||||
* a multiple of 32 bit words, it is necessary for this function to format the
|
||||
* remaining 32 bit word from the FIFO into a series of bytes in the buffer.
|
||||
* There may be up to 3 extra bytes which must be extracted from the last word
|
||||
* of the FIFO and put into the buffer.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
* @param BufferPtr points to the memory buffer to write the data into. This
|
||||
* buffer must be 32 bit aligned or an alignment exception could be
|
||||
* generated. Since this buffer is a byte buffer, the data is assumed to
|
||||
* be endian independent.
|
||||
* @param ByteCount contains the number of bytes to read from the FIFO. This
|
||||
* number of bytes must be present in the FIFO or an error will be
|
||||
* returned.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS indicates the operation was successful. If the number of
|
||||
* bytes specified by the byte count is not present in the FIFO
|
||||
* XST_PFIFO_LACK_OF_DATA is returned.
|
||||
*
|
||||
* If the function was successful, the specified buffer is modified to contain
|
||||
* the bytes which were removed from the FIFO.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Note that the exact number of bytes which are present in the FIFO is
|
||||
* not known by this function. It can only check for a number of 32 bit
|
||||
* words such that if the byte count specified is incorrect, but is still
|
||||
* possible based on the number of words in the FIFO, up to 3 garbage bytes
|
||||
* may be present at the end of the buffer.
|
||||
* <br><br>
|
||||
* This function assumes that if the device consuming data from the FIFO is
|
||||
* a byte device, the order of the bytes to be consumed is from the most
|
||||
* significant byte to the least significant byte of a 32 bit word removed
|
||||
* from the FIFO.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
|
||||
u8 * BufferPtr, u32 ByteCount)
|
||||
{
|
||||
u32 FifoCount;
|
||||
u32 WordCount;
|
||||
u32 ExtraByteCount;
|
||||
u32 *WordBuffer = (u32 *) BufferPtr;
|
||||
|
||||
/* assert to verify valid input arguments including 32 bit alignment of
|
||||
* the buffer pointer
|
||||
*/
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufferPtr != NULL);
|
||||
XASSERT_NONVOID(((u32) BufferPtr &
|
||||
(XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
|
||||
XASSERT_NONVOID(ByteCount != 0);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* get the count of how many 32 bit words are in the FIFO, if there aren't
|
||||
* enought words to satisfy the request, return an error
|
||||
*/
|
||||
|
||||
FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
|
||||
XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
|
||||
|
||||
if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
|
||||
return XST_PFIFO_LACK_OF_DATA;
|
||||
}
|
||||
|
||||
/* calculate the number of words to read from the FIFO before the word
|
||||
* containing the extra bytes, and calculate the number of extra bytes
|
||||
* the extra bytes are defined as those at the end of the buffer when
|
||||
* the buffer does not end on a 32 bit boundary
|
||||
*/
|
||||
WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
|
||||
ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
|
||||
|
||||
/* Read the 32 bit words from the FIFO for all the buffer except the
|
||||
* last word which contains the extra bytes, the following code assumes
|
||||
* that the buffer is 32 bit aligned, otherwise an alignment exception could
|
||||
* be generated
|
||||
*/
|
||||
for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
|
||||
WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress);
|
||||
}
|
||||
|
||||
/* if there are extra bytes to handle, read the last word from the FIFO
|
||||
* and insert the extra bytes into the buffer
|
||||
*/
|
||||
if (ExtraByteCount > 0) {
|
||||
u32 LastWord;
|
||||
u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
|
||||
|
||||
/* get the last word from the FIFO for the extra bytes */
|
||||
|
||||
LastWord = XIo_In32(InstancePtr->DataBaseAddress);
|
||||
|
||||
/* one extra byte in the last word, put the byte into the next location
|
||||
* of the buffer, bytes in a word of the FIFO are ordered from most
|
||||
* significant byte to least
|
||||
*/
|
||||
if (ExtraByteCount == 1) {
|
||||
ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
|
||||
}
|
||||
|
||||
/* two extra bytes in the last word, put each byte into the next two
|
||||
* locations of the buffer
|
||||
*/
|
||||
else if (ExtraByteCount == 2) {
|
||||
ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
|
||||
ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
|
||||
}
|
||||
/* three extra bytes in the last word, put each byte into the next three
|
||||
* locations of the buffer
|
||||
*/
|
||||
else if (ExtraByteCount == 3) {
|
||||
ExtraBytesBuffer[0] = (u8) (LastWord >> 24);
|
||||
ExtraBytesBuffer[1] = (u8) (LastWord >> 16);
|
||||
ExtraBytesBuffer[2] = (u8) (LastWord >> 8);
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Write data into a packet FIFO. The packet FIFO is currently 32 bits wide
|
||||
* such that an input buffer which is a series of bytes must be written into the
|
||||
* FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is
|
||||
* necessary for this function to format the remaining bytes into a single 32
|
||||
* bit word to be inserted into the FIFO. This is necessary to avoid any
|
||||
* accesses past the end of the buffer.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
* @param BufferPtr points to the memory buffer that data is to be read from
|
||||
* and written into the FIFO. Since this buffer is a byte buffer, the data
|
||||
* is assumed to be endian independent. This buffer must be 32 bit aligned
|
||||
* or an alignment exception could be generated.
|
||||
* @param ByteCount contains the number of bytes to read from the buffer and to
|
||||
* write to the FIFO.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS is returned if the operation succeeded. If there is not enough
|
||||
* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is
|
||||
* returned.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function assumes that if the device inserting data into the FIFO is
|
||||
* a byte device, the order of the bytes in each 32 bit word is from the most
|
||||
* significant byte to the least significant byte.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
|
||||
u8 * BufferPtr, u32 ByteCount)
|
||||
{
|
||||
u32 FifoCount;
|
||||
u32 WordCount;
|
||||
u32 ExtraByteCount;
|
||||
u32 *WordBuffer = (u32 *) BufferPtr;
|
||||
|
||||
/* assert to verify valid input arguments including 32 bit alignment of
|
||||
* the buffer pointer
|
||||
*/
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufferPtr != NULL);
|
||||
XASSERT_NONVOID(((u32) BufferPtr &
|
||||
(XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
|
||||
XASSERT_NONVOID(ByteCount != 0);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/* get the count of how many words may be inserted into the FIFO */
|
||||
|
||||
FifoCount = XIo_In32(InstancePtr->RegBaseAddress +
|
||||
XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
|
||||
|
||||
/* Calculate the number of 32 bit words required to insert the specified
|
||||
* number of bytes in the FIFO and determine the number of extra bytes
|
||||
* if the buffer length is not a multiple of 32 bit words
|
||||
*/
|
||||
|
||||
WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT;
|
||||
ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT;
|
||||
|
||||
/* take into account the extra bytes in the total word count */
|
||||
|
||||
if (ExtraByteCount > 0) {
|
||||
WordCount++;
|
||||
}
|
||||
|
||||
/* if there's not enough room in the FIFO to hold the specified
|
||||
* number of bytes, then indicate an error,
|
||||
*/
|
||||
if (FifoCount < WordCount) {
|
||||
return XST_PFIFO_NO_ROOM;
|
||||
}
|
||||
|
||||
/* readjust the word count to not take into account the extra bytes */
|
||||
|
||||
if (ExtraByteCount > 0) {
|
||||
WordCount--;
|
||||
}
|
||||
|
||||
/* Write all the bytes of the buffer which can be written as 32 bit
|
||||
* words into the FIFO, waiting to handle the extra bytes seperately
|
||||
*/
|
||||
for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
|
||||
XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]);
|
||||
}
|
||||
|
||||
/* if there are extra bytes to handle, extract them from the buffer
|
||||
* and create a 32 bit word and write it to the FIFO
|
||||
*/
|
||||
if (ExtraByteCount > 0) {
|
||||
u32 LastWord = 0;
|
||||
u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
|
||||
|
||||
/* one extra byte in the buffer, put the byte into the last word
|
||||
* to be inserted into the FIFO, perform this processing inline rather
|
||||
* than in a loop to help performance
|
||||
*/
|
||||
if (ExtraByteCount == 1) {
|
||||
LastWord = ExtraBytesBuffer[0] << 24;
|
||||
}
|
||||
|
||||
/* two extra bytes in the buffer, put each byte into the last word
|
||||
* to be inserted into the FIFO
|
||||
*/
|
||||
else if (ExtraByteCount == 2) {
|
||||
LastWord = ExtraBytesBuffer[0] << 24 |
|
||||
ExtraBytesBuffer[1] << 16;
|
||||
}
|
||||
|
||||
/* three extra bytes in the buffer, put each byte into the last word
|
||||
* to be inserted into the FIFO
|
||||
*/
|
||||
else if (ExtraByteCount == 3) {
|
||||
LastWord = ExtraBytesBuffer[0] << 24 |
|
||||
ExtraBytesBuffer[1] << 16 |
|
||||
ExtraBytesBuffer[2] << 8;
|
||||
}
|
||||
|
||||
/* write the last 32 bit word to the FIFO and return with no errors */
|
||||
|
||||
XIo_Out32(InstancePtr->DataBaseAddress, LastWord);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
306
board/xilinx/common/xpacket_fifo_v1_00_b.h
Normal file
306
board/xilinx/common/xpacket_fifo_v1_00_b.h
Normal file
@@ -0,0 +1,306 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* @file xpacket_fifo_v1_00_b.h
|
||||
*
|
||||
* This component is a common component because it's primary purpose is to
|
||||
* prevent code duplication in drivers. A driver which must handle a packet
|
||||
* FIFO uses this component rather than directly manipulating a packet FIFO.
|
||||
*
|
||||
* A FIFO is a device which has dual port memory such that one user may be
|
||||
* inserting data into the FIFO while another is consuming data from the FIFO.
|
||||
* A packet FIFO is designed for use with packet protocols such as Ethernet and
|
||||
* ATM. It is typically only used with devices when DMA and/or Scatter Gather
|
||||
* is used. It differs from a nonpacket FIFO in that it does not provide any
|
||||
* interrupts for thresholds of the FIFO such that it is less useful without
|
||||
* DMA.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This component has the capability to generate an interrupt when an error
|
||||
* condition occurs. It is the user's responsibility to provide the interrupt
|
||||
* processing to handle the interrupt. This component provides the ability to
|
||||
* determine if that interrupt is active, a deadlock condition, and the ability
|
||||
* to reset the FIFO to clear the condition. In this condition, the device which
|
||||
* is using the FIFO should also be reset to prevent other problems. This error
|
||||
* condition could occur as a normal part of operation if the size of the FIFO
|
||||
* is not setup correctly. See the hardware IP specification for more details.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b rpm 03/26/02 First release
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef XPACKET_FIFO_H /* prevent circular inclusions */
|
||||
#define XPACKET_FIFO_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* These constants specify the FIFO type and are mutually exclusive
|
||||
*/
|
||||
#define XPF_READ_FIFO_TYPE 0 /* a read FIFO */
|
||||
#define XPF_WRITE_FIFO_TYPE 1 /* a write FIFO */
|
||||
|
||||
/*
|
||||
* These constants define the offsets to each of the registers from the
|
||||
* register base address, each of the constants are a number of bytes
|
||||
*/
|
||||
#define XPF_RESET_REG_OFFSET 0UL
|
||||
#define XPF_MODULE_INFO_REG_OFFSET 0UL
|
||||
#define XPF_COUNT_STATUS_REG_OFFSET 4UL
|
||||
|
||||
/*
|
||||
* This constant is used with the Reset Register
|
||||
*/
|
||||
#define XPF_RESET_FIFO_MASK 0x0000000A
|
||||
|
||||
/*
|
||||
* These constants are used with the Occupancy/Vacancy Count Register. This
|
||||
* register also contains FIFO status
|
||||
*/
|
||||
#define XPF_COUNT_MASK 0x0000FFFF
|
||||
#define XPF_DEADLOCK_MASK 0x20000000
|
||||
#define XPF_ALMOST_EMPTY_FULL_MASK 0x40000000
|
||||
#define XPF_EMPTY_FULL_MASK 0x80000000
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*
|
||||
* The XPacketFifo driver instance data. The driver is required to allocate a
|
||||
* variable of this type for every packet FIFO in the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 RegBaseAddress; /* Base address of registers */
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
u32 DataBaseAddress; /* Base address of data for FIFOs */
|
||||
} XPacketFifoV100b;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Reset the specified packet FIFO. Resetting a FIFO will cause any data
|
||||
* contained in the FIFO to be lost.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XPF_V100B_RESET(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_RESET(InstancePtr) \
|
||||
XIo_Out32((InstancePtr)->RegBaseAddress + XPF_RESET_REG_OFFSET, XPF_RESET_FIFO_MASK);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Get the occupancy count for a read packet FIFO and the vacancy count for a
|
||||
* write packet FIFO. These counts indicate the number of 32-bit words
|
||||
* contained (occupancy) in the FIFO or the number of 32-bit words available
|
||||
* to write (vacancy) in the FIFO.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The occupancy or vacancy count for the specified packet FIFO.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XPF_V100B_GET_COUNT(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_GET_COUNT(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_COUNT_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Determine if the specified packet FIFO is almost empty. Almost empty is
|
||||
* defined for a read FIFO when there is only one data word in the FIFO.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the packet FIFO is almost empty, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XPF_V100B_IS_ALMOST_EMPTY(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_IS_ALMOST_EMPTY(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_ALMOST_EMPTY_FULL_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Determine if the specified packet FIFO is almost full. Almost full is
|
||||
* defined for a write FIFO when there is only one available data word in the
|
||||
* FIFO.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the packet FIFO is almost full, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XPF_V100B_IS_ALMOST_FULL(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_IS_ALMOST_FULL(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_ALMOST_EMPTY_FULL_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Determine if the specified packet FIFO is empty. This applies only to a
|
||||
* read FIFO.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the packet FIFO is empty, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XPF_V100B_IS_EMPTY(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_IS_EMPTY(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_EMPTY_FULL_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Determine if the specified packet FIFO is full. This applies only to a
|
||||
* write FIFO.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the packet FIFO is full, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XPF_V100B_IS_FULL(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_IS_FULL(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_EMPTY_FULL_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Determine if the specified packet FIFO is deadlocked. This condition occurs
|
||||
* when the FIFO is full and empty at the same time and is caused by a packet
|
||||
* being written to the FIFO which exceeds the total data capacity of the FIFO.
|
||||
* It occurs because of the mark/restore features of the packet FIFO which allow
|
||||
* retransmission of a packet. The software should reset the FIFO and any devices
|
||||
* using the FIFO when this condition occurs.
|
||||
*
|
||||
* @param InstancePtr contains a pointer to the FIFO to operate on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This component has the capability to generate an interrupt when an error
|
||||
* condition occurs. It is the user's responsibility to provide the interrupt
|
||||
* processing to handle the interrupt. This function provides the ability to
|
||||
* determine if a deadlock condition, and the ability to reset the FIFO to
|
||||
* clear the condition.
|
||||
*
|
||||
* In this condition, the device which is using the FIFO should also be reset
|
||||
* to prevent other problems. This error condition could occur as a normal part
|
||||
* of operation if the size of the FIFO is not setup correctly.
|
||||
*
|
||||
* Signature: u32 XPF_V100B_IS_DEADLOCKED(XPacketFifoV100b *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XPF_V100B_IS_DEADLOCKED(InstancePtr) \
|
||||
(XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
|
||||
XPF_DEADLOCK_MASK)
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/* Standard functions */
|
||||
|
||||
XStatus XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
|
||||
u32 RegBaseAddress, u32 DataBaseAddress);
|
||||
XStatus XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType);
|
||||
|
||||
/* Data functions */
|
||||
|
||||
XStatus XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
|
||||
u8 * ReadBufferPtr, u32 ByteCount);
|
||||
XStatus XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
|
||||
u8 * WriteBufferPtr, u32 ByteCount);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
347
board/xilinx/common/xstatus.h
Normal file
347
board/xilinx/common/xstatus.h
Normal file
@@ -0,0 +1,347 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xstatus.h
|
||||
*
|
||||
* This file contains Xilinx software status codes. Status codes have their
|
||||
* own data type called XStatus. These codes are used throughout the Xilinx
|
||||
* device drivers.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSTATUS_H /* prevent circular inclusions */
|
||||
#define XSTATUS_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*********************** Common statuses 0 - 500 *****************************/
|
||||
|
||||
#define XST_SUCCESS 0L
|
||||
#define XST_FAILURE 1L
|
||||
#define XST_DEVICE_NOT_FOUND 2L
|
||||
#define XST_DEVICE_BLOCK_NOT_FOUND 3L
|
||||
#define XST_INVALID_VERSION 4L
|
||||
#define XST_DEVICE_IS_STARTED 5L
|
||||
#define XST_DEVICE_IS_STOPPED 6L
|
||||
#define XST_FIFO_ERROR 7L /* an error occurred during an
|
||||
operation with a FIFO such as
|
||||
an underrun or overrun, this
|
||||
error requires the device to
|
||||
be reset */
|
||||
#define XST_RESET_ERROR 8L /* an error occurred which requires
|
||||
the device to be reset */
|
||||
#define XST_DMA_ERROR 9L /* a DMA error occurred, this error
|
||||
typically requires the device
|
||||
using the DMA to be reset */
|
||||
#define XST_NOT_POLLED 10L /* the device is not configured for
|
||||
polled mode operation */
|
||||
#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to put
|
||||
the specified data into */
|
||||
#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large enough
|
||||
to hold the expected data */
|
||||
#define XST_NO_DATA 13L /* there was no data available */
|
||||
#define XST_REGISTER_ERROR 14L /* a register did not contain the
|
||||
expected value */
|
||||
#define XST_INVALID_PARAM 15L /* an invalid parameter was passed
|
||||
into the function */
|
||||
#define XST_NOT_SGDMA 16L /* the device is not configured for
|
||||
scatter-gather DMA operation */
|
||||
#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */
|
||||
#define XST_NO_CALLBACK 18L /* a callback has not yet been
|
||||
* registered */
|
||||
#define XST_NO_FEATURE 19L /* device is not configured with
|
||||
* the requested feature */
|
||||
#define XST_NOT_INTERRUPT 20L /* device is not configured for
|
||||
* interrupt mode operation */
|
||||
#define XST_DEVICE_BUSY 21L /* device is busy */
|
||||
#define XST_ERROR_COUNT_MAX 22L /* the error counters of a device
|
||||
* have maxed out */
|
||||
#define XST_IS_STARTED 23L /* used when part of device is
|
||||
* already started i.e.
|
||||
* sub channel */
|
||||
#define XST_IS_STOPPED 24L /* used when part of device is
|
||||
* already stopped i.e.
|
||||
* sub channel */
|
||||
|
||||
/***************** Utility Component statuses 401 - 500 *********************/
|
||||
|
||||
#define XST_MEMTEST_FAILED 401L /* memory test failed */
|
||||
|
||||
/***************** Common Components statuses 501 - 1000 *********************/
|
||||
|
||||
/********************* Packet Fifo statuses 501 - 510 ************************/
|
||||
|
||||
#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */
|
||||
#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */
|
||||
#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value
|
||||
was invalid after reset */
|
||||
|
||||
/************************** DMA statuses 511 - 530 ***************************/
|
||||
|
||||
#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer
|
||||
failed */
|
||||
#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value
|
||||
was invalid after reset */
|
||||
#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains
|
||||
no buffer descriptors ready
|
||||
to be processed */
|
||||
#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */
|
||||
#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */
|
||||
#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of
|
||||
the scatter gather list are
|
||||
being used */
|
||||
#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer
|
||||
descriptor which is to be
|
||||
copied over in the scatter
|
||||
list is locked */
|
||||
#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have been
|
||||
put into the scatter gather
|
||||
list to be commited */
|
||||
#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold
|
||||
specified was larger than the
|
||||
total # of buffer descriptors
|
||||
in the scatter gather list */
|
||||
#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has
|
||||
already been created */
|
||||
#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has
|
||||
been created */
|
||||
#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which was
|
||||
being started was not committed
|
||||
to the list */
|
||||
#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to start
|
||||
has already been used by the
|
||||
hardware so it can't be reused
|
||||
*/
|
||||
|
||||
/************************** IPIF statuses 531 - 550 ***************************/
|
||||
|
||||
#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width
|
||||
was passed into the function */
|
||||
#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at
|
||||
reset was not valid */
|
||||
#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device interrupt
|
||||
status register did not read
|
||||
back correctly */
|
||||
#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status
|
||||
register did not reset when
|
||||
acked */
|
||||
#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable
|
||||
register was not updated when
|
||||
other registers changed */
|
||||
#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt
|
||||
status register did not read
|
||||
back correctly */
|
||||
#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status register
|
||||
did not reset when acked */
|
||||
#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register was
|
||||
not updated correctly when other
|
||||
registers changed */
|
||||
#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending
|
||||
register did not indicate the
|
||||
expected value */
|
||||
#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID register
|
||||
did not indicate the expected
|
||||
value */
|
||||
|
||||
/****************** Device specific statuses 1001 - 4095 *********************/
|
||||
|
||||
/********************* Ethernet statuses 1001 - 1050 *************************/
|
||||
|
||||
#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big enough
|
||||
* to hold the minimum number of
|
||||
* buffers or descriptors */
|
||||
#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */
|
||||
#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */
|
||||
#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in progress */
|
||||
#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Adapter is out of buffers */
|
||||
#define XST_EMAC_PARSE_ERROR 1006L /* Invalid adapter init string */
|
||||
#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late
|
||||
* collision on polled send */
|
||||
|
||||
/*********************** UART statuses 1051 - 1075 ***************************/
|
||||
#define XST_UART
|
||||
|
||||
#define XST_UART_INIT_ERROR 1051L
|
||||
#define XST_UART_START_ERROR 1052L
|
||||
#define XST_UART_CONFIG_ERROR 1053L
|
||||
#define XST_UART_TEST_FAIL 1054L
|
||||
#define XST_UART_BAUD_ERROR 1055L
|
||||
#define XST_UART_BAUD_RANGE 1056L
|
||||
|
||||
/************************ IIC statuses 1076 - 1100 ***************************/
|
||||
|
||||
#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */
|
||||
#define XST_IIC_BUS_BUSY 1077 /* bus found busy */
|
||||
#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with */
|
||||
/* general call address */
|
||||
#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design */
|
||||
/* value after reset not valid */
|
||||
#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg */
|
||||
/* didn't return value written */
|
||||
#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg */
|
||||
/* didn't return written value */
|
||||
#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */
|
||||
|
||||
/*********************** ATMC statuses 1101 - 1125 ***************************/
|
||||
|
||||
#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM
|
||||
controller hit the max value
|
||||
which requires the statistics
|
||||
to be cleared */
|
||||
|
||||
/*********************** Flash statuses 1126 - 1150 **************************/
|
||||
|
||||
#define XST_FLASH_BUSY 1126L /* Flash is erasing or programming */
|
||||
#define XST_FLASH_READY 1127L /* Flash is ready for commands */
|
||||
#define XST_FLASH_ERROR 1128L /* Flash had detected an internal
|
||||
error. Use XFlash_DeviceControl
|
||||
to retrieve device specific codes */
|
||||
#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase state */
|
||||
#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write state */
|
||||
#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by
|
||||
driver */
|
||||
#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */
|
||||
#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */
|
||||
#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase operation
|
||||
aborted due to a timeout */
|
||||
#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its
|
||||
addressible range */
|
||||
#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */
|
||||
#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately from
|
||||
write/erase function with
|
||||
XFL_NON_BLOCKING_WRITE/ERASE
|
||||
option cleared */
|
||||
#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */
|
||||
|
||||
/*********************** SPI statuses 1151 - 1175 ****************************/
|
||||
|
||||
#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave */
|
||||
#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */
|
||||
#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit register */
|
||||
#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive register */
|
||||
#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected yet */
|
||||
#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being
|
||||
* selected */
|
||||
#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as master */
|
||||
#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as slave-only */
|
||||
#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while disabled */
|
||||
|
||||
/********************** OPB Arbiter statuses 1176 - 1200 *********************/
|
||||
|
||||
#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have either
|
||||
* one master assigned to two or more
|
||||
* priorities, or one master not
|
||||
* assigned to any priority
|
||||
*/
|
||||
#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify the
|
||||
* priority levels without first
|
||||
* suspending the use of priority
|
||||
* levels
|
||||
*/
|
||||
#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled but
|
||||
* bus parking was not enabled
|
||||
*/
|
||||
#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed
|
||||
* priority mode to allow the
|
||||
* priorities to be changed
|
||||
*/
|
||||
|
||||
/************************ Intc statuses 1201 - 1225 **************************/
|
||||
|
||||
#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */
|
||||
#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */
|
||||
|
||||
/********************** TmrCtr statuses 1226 - 1250 **************************/
|
||||
|
||||
#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */
|
||||
|
||||
/********************** WdtTb statuses 1251 - 1275 ***************************/
|
||||
|
||||
#define XST_WDTTB_TIMER_FAILED 1251L
|
||||
|
||||
/********************** PlbArb statuses 1276 - 1300 **************************/
|
||||
|
||||
#define XST_PLBARB_FAIL_SELFTEST 1276L
|
||||
|
||||
/********************** Plb2Opb statuses 1301 - 1325 *************************/
|
||||
|
||||
#define XST_PLB2OPB_FAIL_SELFTEST 1301L
|
||||
|
||||
/********************** Opb2Plb statuses 1326 - 1350 *************************/
|
||||
|
||||
#define XST_OPB2PLB_FAIL_SELFTEST 1326L
|
||||
|
||||
/********************** SysAce statuses 1351 - 1360 **************************/
|
||||
|
||||
#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */
|
||||
|
||||
/********************** PCI Bridge statuses 1361 - 1375 **********************/
|
||||
|
||||
#define XST_PCI_INVALID_ADDRESS 1361L
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* The status typedef.
|
||||
*/
|
||||
typedef u32 XStatus;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#endif /* end of protection macro */
|
||||
350
board/xilinx/common/xversion.c
Normal file
350
board/xilinx/common/xversion.c
Normal file
@@ -0,0 +1,350 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file contains the implementation of the XVersion component. This
|
||||
* component represents a version ID. It is encapsulated within a component
|
||||
* so that it's type and implementation can change without affecting users of
|
||||
* it.
|
||||
*
|
||||
* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
|
||||
* X is the major revision, YY is the minor revision, and Z is the
|
||||
* compatability revision.
|
||||
*
|
||||
* Packed versions are also utilized for the configuration ROM such that
|
||||
* memory is minimized. A packed version consumes only 16 bits and is
|
||||
* formatted as follows.
|
||||
*
|
||||
* <pre>
|
||||
* Revision Range Bit Positions
|
||||
*
|
||||
* Major Revision 0 - 9 Bits 15 - 12
|
||||
* Minor Revision 0 - 99 Bits 11 - 5
|
||||
* Compatability Revision a - z Bits 4 - 0
|
||||
</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xversion.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* the following constants define the masks and shift values to allow the
|
||||
* revisions to be packed and unpacked, a packed version is packed into a 16
|
||||
* bit value in the following format, XXXXYYYYYYYZZZZZ, where XXXX is the
|
||||
* major revision, YYYYYYY is the minor revision, and ZZZZZ is the compatability
|
||||
* revision
|
||||
*/
|
||||
#define XVE_MAJOR_SHIFT_VALUE 12
|
||||
#define XVE_MINOR_ONLY_MASK 0x0FE0
|
||||
#define XVE_MINOR_SHIFT_VALUE 5
|
||||
#define XVE_COMP_ONLY_MASK 0x001F
|
||||
|
||||
/* the following constants define the specific characters of a version string
|
||||
* for each character of the revision, a version string is in the following
|
||||
* format, "X.YYZ" where X is the major revision (0 - 9), YY is the minor
|
||||
* revision (00 - 99), and Z is the compatability revision (a - z)
|
||||
*/
|
||||
#define XVE_MAJOR_CHAR 0 /* major revision 0 - 9 */
|
||||
#define XVE_MINOR_TENS_CHAR 2 /* minor revision tens 0 - 9 */
|
||||
#define XVE_MINOR_ONES_CHAR 3 /* minor revision ones 0 - 9 */
|
||||
#define XVE_COMP_CHAR 4 /* compatability revision a - z */
|
||||
#define XVE_END_STRING_CHAR 5
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static u32 IsVersionStringValid(s8 * StringPtr);
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Unpacks a packed version into the specified version. Versions are packed
|
||||
* into the configuration ROM to reduce the amount storage. A packed version
|
||||
* is a binary format as oppossed to a non-packed version which is implemented
|
||||
* as a string.
|
||||
*
|
||||
* @param InstancePtr points to the version to unpack the packed version into.
|
||||
* @param PackedVersion contains the packed version to unpack.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion)
|
||||
{
|
||||
/* not implemented yet since CROM related */
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Packs a version into the specified packed version. Versions are packed into
|
||||
* the configuration ROM to reduce the amount storage.
|
||||
*
|
||||
* @param InstancePtr points to the version to pack.
|
||||
* @param PackedVersionPtr points to the packed version which will receive
|
||||
* the new packed version.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A status, XST_SUCCESS, indicating the packing was accomplished
|
||||
* successfully, or an error, XST_INVALID_VERSION, indicating the specified
|
||||
* input version was not valid such that the pack did not occur
|
||||
* <br><br>
|
||||
* The packed version pointed to by PackedVersionPtr is modified with the new
|
||||
* packed version if the status indicates success.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersionPtr)
|
||||
{
|
||||
/* not implemented yet since CROM related */
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Determines if two versions are equal.
|
||||
*
|
||||
* @param InstancePtr points to the first version to be compared.
|
||||
* @param VersionPtr points to a second version to be compared.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the versions are equal, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr)
|
||||
{
|
||||
u8 *Version1 = (u8 *) InstancePtr;
|
||||
u8 *Version2 = (u8 *) VersionPtr;
|
||||
int Index;
|
||||
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(VersionPtr != NULL);
|
||||
|
||||
/* check each byte of the versions to see if they are the same,
|
||||
* return at any point a byte differs between them
|
||||
*/
|
||||
for (Index = 0; Index < sizeof (XVersion); Index++) {
|
||||
if (Version1[Index] != Version2[Index]) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* No byte was found to be different between the versions, so indicate
|
||||
* the versions are equal
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Converts a version to a null terminated string.
|
||||
*
|
||||
* @param InstancePtr points to the version to convert.
|
||||
* @param StringPtr points to the string which will be the result of the
|
||||
* conversion. This does not need to point to a null terminated
|
||||
* string as an input, but must point to storage which is an adequate
|
||||
* amount to hold the result string.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The null terminated string is inserted at the location pointed to by
|
||||
* StringPtr if the status indicates success.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* It is necessary for the caller to have already allocated the storage to
|
||||
* contain the string. The amount of memory necessary for the string is
|
||||
* specified in the version header file.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(StringPtr != NULL);
|
||||
|
||||
/* since version is implemented as a string, just copy the specified
|
||||
* input into the specified output
|
||||
*/
|
||||
XVersion_Copy(InstancePtr, (XVersion *) StringPtr);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Initializes a version from a null terminated string. Since the string may not
|
||||
* be a format which is compatible with the version, an error could occur.
|
||||
*
|
||||
* @param InstancePtr points to the version which is to be initialized.
|
||||
* @param StringPtr points to a null terminated string which will be
|
||||
* converted to a version. The format of the string must match the
|
||||
* version string format which is X.YYX where X = 0 - 9, YY = 00 - 99,
|
||||
* Z = a - z.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A status, XST_SUCCESS, indicating the conversion was accomplished
|
||||
* successfully, or XST_INVALID_VERSION indicating the version string format
|
||||
* was not valid.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr)
|
||||
{
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(StringPtr != NULL);
|
||||
|
||||
/* if the version string specified is not valid, return an error */
|
||||
|
||||
if (!IsVersionStringValid(StringPtr)) {
|
||||
return XST_INVALID_VERSION;
|
||||
}
|
||||
|
||||
/* copy the specified string into the specified version and indicate the
|
||||
* conversion was successful
|
||||
*/
|
||||
XVersion_Copy((XVersion *) StringPtr, InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copies the contents of a version to another version.
|
||||
*
|
||||
* @param InstancePtr points to the version which is the source of data for
|
||||
* the copy operation.
|
||||
* @param VersionPtr points to another version which is the destination of
|
||||
* the copy operation.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr)
|
||||
{
|
||||
u8 *Source = (u8 *) InstancePtr;
|
||||
u8 *Destination = (u8 *) VersionPtr;
|
||||
int Index;
|
||||
|
||||
/* assert to verify input arguments */
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(VersionPtr != NULL);
|
||||
|
||||
/* copy each byte of the source version to the destination version */
|
||||
|
||||
for (Index = 0; Index < sizeof (XVersion); Index++) {
|
||||
Destination[Index] = Source[Index];
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Determines if the specified version is valid.
|
||||
*
|
||||
* @param StringPtr points to the string to be validated.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* TRUE if the version string is a valid format, FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static u32
|
||||
IsVersionStringValid(s8 * StringPtr)
|
||||
{
|
||||
/* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
|
||||
* YY = 00 - 99, and Z = a - z, then indicate it's not valid
|
||||
*/
|
||||
if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
|
||||
(StringPtr[XVE_MAJOR_CHAR] > '9') ||
|
||||
(StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
|
||||
(StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
|
||||
(StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
|
||||
(StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
|
||||
(StringPtr[XVE_COMP_CHAR] < 'a') ||
|
||||
(StringPtr[XVE_COMP_CHAR] > 'z')) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
97
board/xilinx/common/xversion.h
Normal file
97
board/xilinx/common/xversion.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file contains the interface for the XVersion component. This
|
||||
* component represents a version ID. It is encapsulated within a component
|
||||
* so that it's type and implementation can change without affecting users of
|
||||
* it.
|
||||
*
|
||||
* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
|
||||
* X is the major revision, YY is the minor revision, and Z is the
|
||||
* compatability revision.
|
||||
*
|
||||
* Packed versions are also utilized for the configuration ROM such that
|
||||
* memory is minimized. A packed version consumes only 16 bits and is
|
||||
* formatted as follows.
|
||||
*
|
||||
* <pre>
|
||||
* Revision Range Bit Positions
|
||||
*
|
||||
* Major Revision 0 - 9 Bits 15 - 12
|
||||
* Minor Revision 0 - 99 Bits 11 - 5
|
||||
* Compatability Revision a - z Bits 4 - 0
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XVERSION_H /* prevent circular inclusions */
|
||||
#define XVERSION_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/* the following data type is used to hold a null terminated version string
|
||||
* consisting of the following format, "X.YYX"
|
||||
*/
|
||||
typedef s8 XVersion[6];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion);
|
||||
|
||||
XStatus XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersion);
|
||||
|
||||
u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr);
|
||||
|
||||
void XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr);
|
||||
|
||||
XStatus XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr);
|
||||
|
||||
void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
57
board/xilinx/ml300/Makefile
Normal file
57
board/xilinx/ml300/Makefile
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
CFLAGS += -I../ml300 -I../common -I../xilinx_enet
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o serial.o \
|
||||
../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
|
||||
../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
|
||||
../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
|
||||
../xilinx_enet/xemac_intr_dma.o \
|
||||
../common/xbasic_types.o ../common/xdma_channel.o \
|
||||
../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
|
||||
../common/xversion.o
|
||||
|
||||
SOBJS = init.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
29
board/xilinx/ml300/config.mk
Normal file
29
board/xilinx/ml300/config.mk
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# (C) Copyright 2000
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# esd ADCIOP boards
|
||||
#
|
||||
|
||||
#TEXT_BASE = 0xFFFE0000
|
||||
TEXT_BASE = 0x04000000
|
||||
48
board/xilinx/ml300/init.S
Normal file
48
board/xilinx/ml300/init.S
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* init.S: Stubs for U-Boot initialization
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
.globl ext_bus_cntlr_init
|
||||
ext_bus_cntlr_init:
|
||||
blr
|
||||
|
||||
.globl sdram_init
|
||||
sdram_init:
|
||||
blr
|
||||
109
board/xilinx/ml300/ml300.c
Normal file
109
board/xilinx/ml300/ml300.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* ml300.c: U-Boot platform support for Xilinx ML300 board
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/processor.h>
|
||||
#include "xparameters.h"
|
||||
|
||||
int
|
||||
board_pre_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
checkboard(void)
|
||||
{
|
||||
unsigned char *s = getenv("serial#");
|
||||
unsigned char *e;
|
||||
|
||||
if (!s || strncmp(s, "ML300", 9)) {
|
||||
printf("### No HW ID - assuming ML300");
|
||||
} else {
|
||||
for (e = s; *e; ++e) {
|
||||
if (*e == ' ')
|
||||
break;
|
||||
}
|
||||
|
||||
for (; s < e; ++s) {
|
||||
putc(*s);
|
||||
}
|
||||
}
|
||||
|
||||
putc('\n');
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
long int
|
||||
initdram(int board_type)
|
||||
{
|
||||
return 128 * 1024 * 1024;
|
||||
}
|
||||
|
||||
int
|
||||
testdram(void)
|
||||
{
|
||||
printf("test: xxx MB - ok\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* implement functions originally in cpu/ppc4xx/speed.c */
|
||||
void
|
||||
get_sys_info(sys_info_t * sysInfo)
|
||||
{
|
||||
sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ;
|
||||
|
||||
/* only correct if the PLB and OPB run at the same frequency */
|
||||
sysInfo->freqPLB = XPAR_UARTNS550_0_CLOCK_FREQ_HZ;
|
||||
sysInfo->freqPCI = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 3;
|
||||
}
|
||||
|
||||
ulong
|
||||
get_PCI_freq(void)
|
||||
{
|
||||
ulong val;
|
||||
PPC405_SYS_INFO sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
val = sys_info.freqPCI;
|
||||
return val;
|
||||
}
|
||||
155
board/xilinx/ml300/serial.c
Normal file
155
board/xilinx/ml300/serial.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/u-boot.h>
|
||||
#include <asm/processor.h>
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <configs/ml300.h>
|
||||
#include "xparameters.h"
|
||||
|
||||
#define USE_CHAN1 \
|
||||
((defined XPAR_UARTNS550_0_BASEADDR) && (defined CFG_INIT_CHAN1))
|
||||
#define USE_CHAN2 \
|
||||
((defined XPAR_UARTNS550_1_BASEADDR) && (defined CFG_INIT_CHAN2))
|
||||
|
||||
#if USE_CHAN1
|
||||
#include <ns16550.h>
|
||||
#endif
|
||||
|
||||
#if USE_CHAN1
|
||||
const NS16550_t COM_PORTS[] = { (NS16550_t) (XPAR_UARTNS550_0_BASEADDR + 3)
|
||||
#if USE_CHAN2
|
||||
, (NS16550_t) (XPAR_UARTNS550_1_BASEADDR + 3)
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
serial_init(void)
|
||||
{
|
||||
#if USE_CHAN1
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
int clock_divisor;
|
||||
|
||||
clock_divisor = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 16 / gd->baudrate;
|
||||
(void) NS16550_init(COM_PORTS[0], clock_divisor);
|
||||
#if USE_CHAN2
|
||||
clock_divisor = XPAR_UARTNS550_1_CLOCK_FREQ_HZ / 16 / gd->baudrate;
|
||||
(void) NS16550_init(COM_PORTS[1], clock_divisor);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
serial_putc(const char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
|
||||
|
||||
NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
|
||||
}
|
||||
|
||||
int
|
||||
serial_getc(void)
|
||||
{
|
||||
return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
|
||||
}
|
||||
|
||||
int
|
||||
serial_tstc(void)
|
||||
{
|
||||
return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
|
||||
}
|
||||
|
||||
void
|
||||
serial_setbrg(void)
|
||||
{
|
||||
#if USE_CHAN1
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
int clock_divisor;
|
||||
|
||||
clock_divisor = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 16 / gd->baudrate;
|
||||
NS16550_reinit(COM_PORTS[0], clock_divisor);
|
||||
#if USE_CHAN2
|
||||
clock_divisor = XPAR_UARTNS550_1_CLOCK_FREQ_HZ / 16 / gd->baudrate;
|
||||
NS16550_reinit(COM_PORTS[1], clock_divisor);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
serial_puts(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
serial_putc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
|
||||
void
|
||||
kgdb_serial_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
putDebugChar(int c)
|
||||
{
|
||||
serial_putc(c);
|
||||
}
|
||||
|
||||
void
|
||||
putDebugStr(const char *str)
|
||||
{
|
||||
serial_puts(str);
|
||||
}
|
||||
|
||||
int
|
||||
getDebugChar(void)
|
||||
{
|
||||
return serial_getc();
|
||||
}
|
||||
|
||||
void
|
||||
kgdb_interruptible(int yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CFG_CMD_KGDB */
|
||||
41
board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
Normal file
41
board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
if[$
|
||||
# -ne 1 ]
|
||||
then echo "usage: Ltypes filename" > &2 exit 2 fi FILE = "$1"
|
||||
#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
|
||||
TMPFILE = $ {
|
||||
FILE}
|
||||
|
||||
. ` date "+%s" ` touch $TMPFILE || exit 1
|
||||
# Change all the Xilinx types to Linux types and put the result into a temp file
|
||||
sed
|
||||
- e 's/\bXTRUE\b/TRUE/g'
|
||||
- e 's/\bXFALSE\b/FALSE/g'
|
||||
- e 's/\bXNULL\b/NULL/g'
|
||||
- e 's/<asm/delay.h>/<asm\/delay.h>/g'
|
||||
- e 's/\bXENV_USLEEP\b/udelay/g'
|
||||
- e 's/\bXuint8\b/u8/g'
|
||||
- e 's/\bXuint16\b/u16/g'
|
||||
- e 's/\bXuint32\b/u32/g'
|
||||
- e 's/\bXint8\b/s8/g'
|
||||
- e 's/\bXint16\b/s16/g'
|
||||
- e 's/\bXint32\b/s32/g' - e 's/\bXboolean\b/u32/g' "${FILE}" > "${TMPFILE}"
|
||||
# Overlay the original file with the temp file
|
||||
mv "${TMPFILE}" "${FILE}"
|
||||
# Are we doing xbasic_types.h?
|
||||
if["${FILE##*/}" = xbasic_types.h]
|
||||
then
|
||||
# Remember as you're reading this that we've already gone through the prior
|
||||
# sed script. We need to do some other things to xbasic_types.h:
|
||||
# 1) Add ifndefs around TRUE and FALSE defines
|
||||
# 2) Remove definition of NULL as NULL
|
||||
# 3) Replace most of the primitive types section with a #include
|
||||
sed - e '/u32 true/,/#define false/Ic\
|
||||
#ifndef TRUE\
|
||||
#define TRUE 1\
|
||||
#endif\
|
||||
#ifndef FALSE\
|
||||
#define FALSE 0\
|
||||
#endif' - e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' - e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\
|
||||
#include <linux/types.h>' "${FILE}" > "${TMPFILE}" mv "${TMPFILE}" "${FILE}" fi
|
||||
@@ -0,0 +1,48 @@
|
||||
# (c) Copyright 2004 Xilinx Inc.
|
||||
# Author: Xilinx, Inc.
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
#
|
||||
# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
# COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
# ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
# XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
# FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
# ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
# WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
# CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
# FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
#
|
||||
# Xilinx hardware products are not intended for use in life support
|
||||
# appliances, devices, or systems. Use in such applications is
|
||||
# expressly prohibited.
|
||||
#
|
||||
#
|
||||
# (c) Copyright 2002-2004 Xilinx Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN LIBRARY uboot OPTION DRC = uboot_drc;
|
||||
|
||||
BEGIN ARRAY connected_periphs PROPERTY desc = "Peripherals connected to U-Boot";
|
||||
PROPERTY size = 0;
|
||||
PARAM name = periph_name, desc = "Name of Peripheral connected", type = string;
|
||||
END ARRAY
|
||||
PARAMETER name = TARGET_DIR, desc =
|
||||
"Target Directory for U-Boot BSP", type = string;
|
||||
|
||||
END LIBRARY
|
||||
@@ -0,0 +1,298 @@
|
||||
#
|
||||
# Author: Xilinx, Inc.
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
#
|
||||
# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
# COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
# ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
# XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
# FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
# ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
# WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
# CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
# FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
#
|
||||
# Xilinx hardware products are not intended for use in life support
|
||||
# appliances, devices, or systems. Use in such applications is
|
||||
# expressly prohibited.
|
||||
#
|
||||
#
|
||||
# (c) Copyright 2002-2004 Xilinx Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Globals
|
||||
lappend drvlist
|
||||
set ltypes "../../../sw_services/uboot_v1_00_a/data/Ltypes"
|
||||
|
||||
proc uboot_drc {lib_handle} {
|
||||
puts "U-Boot DRC..."
|
||||
}
|
||||
|
||||
proc generate {libname} {
|
||||
|
||||
global drvlist
|
||||
|
||||
# Get list of peripherals connected to uboot
|
||||
set conn_periphs [xget_handle $libname "ARRAY" "connected_periphs"]
|
||||
#lappend drvlist
|
||||
if {[string compare -nocase $conn_periphs ""] != 0} {
|
||||
set conn_periphs_elems [xget_handle $conn_periphs "ELEMENTS" "*"]
|
||||
# For each periph
|
||||
foreach periph_elem $conn_periphs_elems {
|
||||
set periph [xget_value $periph_elem "PARAMETER" "periph_name"]
|
||||
# 1. Get driver
|
||||
set drv [xget_swhandle $periph]
|
||||
set posn [lsearch -exact $drvlist $drv]
|
||||
if {$posn == -1} {
|
||||
lappend drvlist $drv
|
||||
}
|
||||
}
|
||||
|
||||
set file_handle [xopen_include_file "xparameters.h"]
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
puts $file_handle "/* U-Boot Redefines */"
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
|
||||
foreach drv $drvlist {
|
||||
set drvname [xget_value $drv "NAME"]
|
||||
|
||||
#Redefines xparameters.h
|
||||
if {[string compare -nocase $drvname "uartns550"] == 0} {
|
||||
xredefine_uartns550 $drv "xparameters.h"
|
||||
} elseif {[string compare -nocase $drvname "emac"] == 0} {
|
||||
xredefine_emac $drv "xparameters.h"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# define core_clock
|
||||
xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ"
|
||||
}
|
||||
|
||||
proc xget_corefreq {} {
|
||||
set processor [xget_processor]
|
||||
set name [xget_value $processor "NAME"]
|
||||
puts "procname : $name"
|
||||
set processor_driver [xget_swhandle [xget_value $processor "NAME"]]
|
||||
puts "procdrv : $processor_driver"
|
||||
if {[string compare -nocase $processor_driver ""] != 0} {
|
||||
set arg "CORE_CLOCK_FREQ_HZ"
|
||||
#set retval [xget_value $processor_driver "PARAMETER" $arg]
|
||||
set retval [xget_dname [xget_value $processor_driver "NAME"] $arg]
|
||||
return $retval
|
||||
}
|
||||
}
|
||||
|
||||
# procedure that adds # defines to xparameters.h as XPAR_argument
|
||||
proc xredefine_params {handle file_name args} {
|
||||
|
||||
puts "xredfine ..."
|
||||
# Open include file
|
||||
set file_handle [xopen_include_file $file_name]
|
||||
puts "args : $args"
|
||||
|
||||
foreach arg $args {
|
||||
if {[string compare -nocase $arg "CORE_CLOCK_FREQ_HZ"] == 0} {
|
||||
set value [xget_corefreq]
|
||||
puts "corefreq : $value"
|
||||
} else {
|
||||
set value [xget_value $handle "PARAMETER" $arg]
|
||||
puts "value : $value"
|
||||
}
|
||||
|
||||
if {$value != ""} {
|
||||
set value [xformat_addr_string $value $arg]
|
||||
set name [string toupper $arg]
|
||||
set name [format "XPAR_%s" $name]
|
||||
puts $file_handle "#define $name $value"
|
||||
}
|
||||
}
|
||||
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
||||
|
||||
# uart redefines...
|
||||
proc xredefine_uartns550 {drvhandle file_name} {
|
||||
|
||||
xredefine_include_file $drvhandle $file_name "uartns550" "C_BASEADDR" "C_HIGHADDR" "CLOCK_HZ" "DEVICE_ID"
|
||||
|
||||
}
|
||||
|
||||
proc xredefine_emac {drvhandle file_name} {
|
||||
|
||||
xredefine_include_file $drvhandle $file_name "emac" "C_BASEADDR" "C_HIGHADDR" "C_DMA_PRESENT" "C_MII_EXIST" "C_ERR_COUNT_EXIST" "DEVICE_ID"
|
||||
|
||||
}
|
||||
|
||||
#######################
|
||||
|
||||
proc xredefine_include_file {drv_handle file_name drv_string args} {
|
||||
|
||||
# Open include file
|
||||
set file_handle [xopen_include_file $file_name]
|
||||
|
||||
# Get all peripherals connected to this driver
|
||||
set periphs [xget_periphs $drv_handle]
|
||||
|
||||
set pname [format "XPAR_%s_" [string toupper $drv_string]]
|
||||
|
||||
# Print all parameters for all peripherals
|
||||
set device_id 0
|
||||
set sub_periphs 1
|
||||
foreach periph $periphs {
|
||||
puts "$periph : $drv_string : $sub_periphs"
|
||||
|
||||
for {set i 0} {$i < $sub_periphs} {incr i} {
|
||||
foreach arg $args {
|
||||
set name "${pname}${device_id}_"
|
||||
|
||||
if {[string compare -nocase "CLOCK_HZ" $arg] == 0} {
|
||||
set xdrv_string [format "%s%s" "X" $drv_string]
|
||||
set value [xget_dname $xdrv_string $arg]
|
||||
set name "${name}CLOCK_FREQ_HZ"
|
||||
} else {
|
||||
if {[string match C_* $arg]} {
|
||||
set name [format "%s%s" $name [string range $arg 2 end]]
|
||||
} else {
|
||||
set name "${name}${arg}"
|
||||
}
|
||||
set value [xget_name $periph $arg]
|
||||
}
|
||||
|
||||
if {[string compare -nocase "uartns550" $drv_string] == 0} {
|
||||
if {[string compare -nocase "C_BASEADDR" $arg] == 0} {
|
||||
set value [format "(%s%s%s)" $value "+" "0x1000"]
|
||||
}
|
||||
}
|
||||
|
||||
puts $file_handle "#define $name $value"
|
||||
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
|
||||
incr device_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
||||
|
||||
##################################################
|
||||
# procedure post_generate
|
||||
# This generates the drivers directory for uboot
|
||||
# and runs the ltypes script
|
||||
##################################################
|
||||
|
||||
proc post_generate {lib_handle} {
|
||||
|
||||
global drvlist
|
||||
|
||||
# Create U-Boot tree structure
|
||||
set pwd [pwd]
|
||||
set common_dir "uboot/board/xilinx/common"
|
||||
set xilinx_enet_dir "uboot/board/xilinx/xilinx_enet"
|
||||
set ml300_dir "uboot/board/xilinx/ml300"
|
||||
|
||||
exec bash -c "mkdir -p $common_dir $xilinx_enet_dir $ml300_dir"
|
||||
|
||||
# Copy files for xilinx_ocp
|
||||
xcopy_commonfiles
|
||||
|
||||
foreach drv $drvlist {
|
||||
set drvname [xget_value $drv "NAME"]
|
||||
set ver [xget_value $drv "PARAMETER" "DRIVER_VER"]
|
||||
set ver [string map {. _} $ver]
|
||||
set dirname [format "%s_v%s" $drvname $ver]
|
||||
|
||||
if {[string compare -nocase $drvname "emac"] == 0} {
|
||||
xcopy_emac $drv $dirname
|
||||
}
|
||||
}
|
||||
|
||||
# Call Ltypes Script here
|
||||
set uboot "uboot"
|
||||
xltype_file $uboot
|
||||
|
||||
# Move xparameters.h around
|
||||
exec bash -c "cp ../../include/xparameters.h $ml300_dir"
|
||||
|
||||
# copy the whole U-Boot BSP to its final destination
|
||||
set value [xget_value $lib_handle "PARAMETER" TARGET_DIR]
|
||||
puts "TARGET_DIR : $value"
|
||||
|
||||
if {$value != ""} {
|
||||
if {[file isdirectory $value] == 0} {
|
||||
exec bash -c "mkdir -p $value"
|
||||
}
|
||||
exec bash -c "cp -Rp uboot/* $value"
|
||||
}
|
||||
}
|
||||
|
||||
proc xcopy_commonfiles {} {
|
||||
|
||||
global drvlist
|
||||
|
||||
set common_dir "uboot/board/xilinx/common"
|
||||
|
||||
foreach drv $drvlist {
|
||||
set depends [xget_value $drv "OPTION" "DEPENDS"]
|
||||
foreach dep $depends {
|
||||
puts "dep : $dep"
|
||||
if {[file isdirectory "../$dep"] == 1} {
|
||||
exec bash -c "cp -f ../$dep/src/*.c $common_dir"
|
||||
exec bash -c "cp -f ../$dep/src/*.h $common_dir"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proc xcopy_emac {drv_handle dirname} {
|
||||
set emac "board/xilinx/xilinx_enet"
|
||||
xcopy_dir $dirname $emac
|
||||
}
|
||||
|
||||
proc xcopy_dir {srcdir dstdir} {
|
||||
|
||||
set dstdirname [format "%s%s" "uboot/" $dstdir]
|
||||
if {[file isdirectory "../$srcdir"] == 1} {
|
||||
# Copy files from src to dst
|
||||
exec bash -c "mkdir -p $dstdirname"
|
||||
exec bash -c "cp -f ../$srcdir/src/*.c $dstdirname"
|
||||
exec bash -c "cp -f ../$srcdir/src/*.h $dstdirname"
|
||||
} else {
|
||||
puts "$srcdir does not exist ..."
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc xltype_file {filename} {
|
||||
|
||||
global ltypes
|
||||
|
||||
puts $filename
|
||||
|
||||
if {[file isdirectory $filename]} {
|
||||
foreach entry [glob -nocomplain [file join $filename *]] {
|
||||
xltype_file $entry
|
||||
}
|
||||
} else {
|
||||
exec bash -c "$ltypes $filename"
|
||||
}
|
||||
|
||||
}
|
||||
146
board/xilinx/ml300/u-boot.lds
Normal file
146
board/xilinx/ml300/u-boot.lds
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
/*
|
||||
cpu/ppc4xx/start.o (.text)
|
||||
board/xilinx/ml300/init.o (.text)
|
||||
cpu/ppc4xx/kgdb.o (.text)
|
||||
cpu/ppc4xx/traps.o (.text)
|
||||
cpu/ppc4xx/interrupts.o (.text)
|
||||
cpu/ppc4xx/serial.o (.text)
|
||||
cpu/ppc4xx/cpu_init.o (.text)
|
||||
cpu/ppc4xx/speed.o (.text)
|
||||
cpu/ppc4xx/405gp_enet.o (.text)
|
||||
common/dlmalloc.o (.text)
|
||||
lib_generic/crc32.o (.text)
|
||||
lib_ppc/extable.o (.text)
|
||||
lib_generic/zlib.o (.text)
|
||||
*/
|
||||
/* . = env_offset;*/
|
||||
/* common/environment.o(.text)*/
|
||||
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
}
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.str1.4)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x00FF) & 0xFFFFFF00;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(256);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(256);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
135
board/xilinx/ml300/u-boot.lds.debug
Normal file
135
board/xilinx/ml300/u-boot.lds.debug
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
mpc8xx/start.o (.text)
|
||||
common/dlmalloc.o (.text)
|
||||
lib_generic/vsprintf.o (.text)
|
||||
lib_generic/crc32.o (.text)
|
||||
lib_ppc/extable.o (.text)
|
||||
|
||||
common/environment.o(.text)
|
||||
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
}
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
216
board/xilinx/ml300/xparameters.h
Normal file
216
board/xilinx/ml300/xparameters.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by libgen.
|
||||
* Version: Xilinx EDK 6.1.2 EDK_G.14
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Description: Driver parameters
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#define XPAR_XPCI_NUM_INSTANCES 1
|
||||
#define XPAR_XPCI_CLOCK_HZ 33333333
|
||||
#define XPAR_OPB_PCI_REF_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_PCI_REF_0_BASEADDR 0x20000000
|
||||
#define XPAR_OPB_PCI_REF_0_HIGHADDR 0x3FFFFFFF
|
||||
#define XPAR_OPB_PCI_REF_0_CONFIG_ADDR 0x3C000000
|
||||
#define XPAR_OPB_PCI_REF_0_CONFIG_DATA 0x3C000004
|
||||
#define XPAR_OPB_PCI_REF_0_LCONFIG_ADDR 0x3E000000
|
||||
#define XPAR_OPB_PCI_REF_0_MEM_BASEADDR 0x20000000
|
||||
#define XPAR_OPB_PCI_REF_0_MEM_HIGHADDR 0x37FFFFFF
|
||||
#define XPAR_OPB_PCI_REF_0_IO_BASEADDR 0x38000000
|
||||
#define XPAR_OPB_PCI_REF_0_IO_HIGHADDR 0x3BFFFFFF
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XEMAC_NUM_INSTANCES 1
|
||||
#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000
|
||||
#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF
|
||||
#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
|
||||
#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
|
||||
#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_0 0
|
||||
#define XPAR_MY_OPB_GPIO_0_BASEADDR_0 0x90000000
|
||||
#define XPAR_MY_OPB_GPIO_0_HIGHADDR_0 (0x90000000+0x7)
|
||||
#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_1 1
|
||||
#define XPAR_MY_OPB_GPIO_0_BASEADDR_1 (0x90000000+0x8)
|
||||
#define XPAR_MY_OPB_GPIO_0_HIGHADDR_1 (0x90000000+0x1F)
|
||||
#define XPAR_XGPIO_NUM_INSTANCES 2
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XIIC_NUM_INSTANCES 1
|
||||
#define XPAR_OPB_IIC_0_BASEADDR 0xA8000000
|
||||
#define XPAR_OPB_IIC_0_HIGHADDR 0xA80001FF
|
||||
#define XPAR_OPB_IIC_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_IIC_0_TEN_BIT_ADR 0
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XUARTNS550_NUM_INSTANCES 2
|
||||
#define XPAR_XUARTNS550_CLOCK_HZ 100000000
|
||||
#define XPAR_OPB_UART16550_0_BASEADDR 0xA0000000
|
||||
#define XPAR_OPB_UART16550_0_HIGHADDR 0xA0001FFF
|
||||
#define XPAR_OPB_UART16550_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_UART16550_1_BASEADDR 0xA0010000
|
||||
#define XPAR_OPB_UART16550_1_HIGHADDR 0xA0011FFF
|
||||
#define XPAR_OPB_UART16550_1_DEVICE_ID 1
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XSPI_NUM_INSTANCES 1
|
||||
#define XPAR_OPB_SPI_0_BASEADDR 0xA4000000
|
||||
#define XPAR_OPB_SPI_0_HIGHADDR 0xA400007F
|
||||
#define XPAR_OPB_SPI_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_SPI_0_FIFO_EXIST 1
|
||||
#define XPAR_OPB_SPI_0_SPI_SLAVE_ONLY 0
|
||||
#define XPAR_OPB_SPI_0_NUM_SS_BITS 1
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XPS2_NUM_INSTANCES 2
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0 0
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0 0xA9000000
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0 (0xA9000000+0x3F)
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1 1
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1 (0xA9000000+0x1000)
|
||||
#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1 (0xA9000000+0x103F)
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XTOUCHSCREEN_NUM_INSTANCES 1
|
||||
#define XPAR_OPB_TSD_REF_0_BASEADDR 0xAA000000
|
||||
#define XPAR_OPB_TSD_REF_0_HIGHADDR 0xAA000007
|
||||
#define XPAR_OPB_TSD_REF_0_DEVICE_ID 0
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR 0xA6000000
|
||||
#define XPAR_OPB_AC97_CONTROLLER_REF_0_HIGHADDR 0xA60000FF
|
||||
#define XPAR_OPB_PAR_PORT_REF_0_BASEADDR 0x90010000
|
||||
#define XPAR_OPB_PAR_PORT_REF_0_HIGHADDR 0x900100FF
|
||||
#define XPAR_PLB_DDR_0_BASEADDR 0x00000000
|
||||
#define XPAR_PLB_DDR_0_HIGHADDR 0x0FFFFFFF
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XINTC_HAS_IPR 1
|
||||
#define XPAR_INTC_MAX_NUM_INTR_INPUTS 18
|
||||
#define XPAR_XINTC_USE_DCR 0
|
||||
#define XPAR_XINTC_NUM_INSTANCES 1
|
||||
#define XPAR_DCR_INTC_0_BASEADDR 0xD0000FC0
|
||||
#define XPAR_DCR_INTC_0_HIGHADDR 0xD0000FDF
|
||||
#define XPAR_DCR_INTC_0_DEVICE_ID 0
|
||||
#define XPAR_DCR_INTC_0_KIND_OF_INTR 0x00038000
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_DCR_INTC_0_MISC_LOGIC_0_PHY_MII_INT_INTR 0
|
||||
#define XPAR_DCR_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR 1
|
||||
#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_TEMP_CRIT_INTR 2
|
||||
#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_IRQ_INTR 3
|
||||
#define XPAR_DCR_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR 4
|
||||
#define XPAR_DCR_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR 5
|
||||
#define XPAR_DCR_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR 6
|
||||
#define XPAR_DCR_INTC_0_OPB_UART16550_1_IP2INTC_IRPT_INTR 7
|
||||
#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR 8
|
||||
#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR 9
|
||||
#define XPAR_DCR_INTC_0_OPB_SPI_0_IP2INTC_IRPT_INTR 10
|
||||
#define XPAR_DCR_INTC_0_OPB_TSD_REF_0_INTR_INTR 11
|
||||
#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_INTR 12
|
||||
#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_INTR 13
|
||||
#define XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR 14
|
||||
#define XPAR_DCR_INTC_0_PLB2OPB_BRIDGE_0_BUS_ERROR_DET_INTR 15
|
||||
#define XPAR_DCR_INTC_0_PLB_V34_0_BUS_ERROR_DET_INTR 16
|
||||
#define XPAR_DCR_INTC_0_OPB2PLB_BRIDGE_0_BUS_ERROR_DET_INTR 17
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XTFT_NUM_INSTANCES 1
|
||||
#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR 0xD0000200
|
||||
#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_HIGHADDR 0xD0000207
|
||||
#define XPAR_PLB_TFT_CNTLR_REF_0_DEVICE_ID 0
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_XSYSACE_MEM_WIDTH 8
|
||||
#define XPAR_XSYSACE_NUM_INSTANCES 1
|
||||
#define XPAR_OPB_SYSACE_0_BASEADDR 0xCF000000
|
||||
#define XPAR_OPB_SYSACE_0_HIGHADDR 0xCF0001FF
|
||||
#define XPAR_OPB_SYSACE_0_DEVICE_ID 0
|
||||
#define XPAR_OPB_SYSACE_0_MEM_WIDTH 8
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define STDIN_BASEADDRESS 0xA0000000
|
||||
#define STDOUT_BASEADDRESS 0xA0000000
|
||||
#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
/* U-Boot Redefines */
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
|
||||
#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
|
||||
#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
|
||||
#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
|
||||
#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
|
||||
#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
|
||||
#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
|
||||
#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
|
||||
#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
|
||||
#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
|
||||
#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
|
||||
#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
|
||||
#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
|
||||
|
||||
/******************************************************************/
|
||||
153
board/xilinx/xilinx_enet/emac_adapter.c
Normal file
153
board/xilinx/xilinx_enet/emac_adapter.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <configs/ml300.h>
|
||||
#include "xparameters.h"
|
||||
#include "xemac.h"
|
||||
|
||||
#if defined(XPAR_EMAC_0_DEVICE_ID)
|
||||
/*
|
||||
* ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
|
||||
* PKTSIZE and PKTSIZE_ALIGN (include/net.h)
|
||||
*/
|
||||
|
||||
#define ENET_MAX_MTU PKTSIZE
|
||||
#define ENET_MAX_MTU_ALIGNED PKTSIZE_ALIGN
|
||||
#define ENET_ADDR_LENGTH 6
|
||||
|
||||
static XEmac Emac;
|
||||
static char etherrxbuff[PKTSIZE_ALIGN]; /* Receive buffer */
|
||||
|
||||
/* hardcoded MAC address for the Xilinx EMAC Core */
|
||||
static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
void
|
||||
eth_halt(void)
|
||||
{
|
||||
if (initialized)
|
||||
(void) XEmac_Stop(&Emac);
|
||||
}
|
||||
|
||||
int
|
||||
eth_init(bd_t * bis)
|
||||
{
|
||||
u32 Options;
|
||||
XStatus Result;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("EMAC Initialization Started\n\r");
|
||||
#endif
|
||||
|
||||
Result = XEmac_Initialize(&Emac, XPAR_EMAC_0_DEVICE_ID);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* make sure the Emac is stopped before it is started */
|
||||
(void) XEmac_Stop(&Emac);
|
||||
|
||||
memcpy(bis->bi_enetaddr, EMACAddr, 6);
|
||||
Result = XEmac_SetMacAddress(&Emac, EMACAddr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Options =
|
||||
(XEM_POLLED_OPTION | XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION |
|
||||
XEM_FDUPLEX_OPTION | XEM_INSERT_FCS_OPTION |
|
||||
XEM_INSERT_PAD_OPTION);
|
||||
Result = XEmac_SetOptions(&Emac, Options);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result = XEmac_Start(&Emac);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("EMAC Initialization complete\n\r");
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------*/
|
||||
int
|
||||
eth_send(volatile void *ptr, int len)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
if (len > ENET_MAX_MTU)
|
||||
len = ENET_MAX_MTU;
|
||||
|
||||
Result = XEmac_PollSend(&Emac, (u8 *) ptr, len);
|
||||
if (Result == XST_SUCCESS) {
|
||||
return (1);
|
||||
} else {
|
||||
printf("Error while sending frame\n\r");
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
eth_rx(void)
|
||||
{
|
||||
u32 RecvFrameLength;
|
||||
XStatus Result;
|
||||
|
||||
RecvFrameLength = PKTSIZE;
|
||||
Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength);
|
||||
if (Result == XST_SUCCESS) {
|
||||
NetReceive(etherrxbuff, RecvFrameLength);
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
844
board/xilinx/xilinx_enet/xemac.c
Normal file
844
board/xilinx/xilinx_enet/xemac.c
Normal file
@@ -0,0 +1,844 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac.c
|
||||
*
|
||||
* The XEmac driver. Functions in this file are the minimum required functions
|
||||
* for this driver. See xemac.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00b rpm 07/23/02 Removed the PHY reset from Initialize()
|
||||
* 1.00b rmm 09/23/02 Removed commented code in Initialize(). Recycled as
|
||||
* XEmac_mPhyReset macro in xemac_l.h.
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* 1.00c rpm 12/12/02 Changed location of IsStarted assignment in XEmac_Start
|
||||
* to be sure the flag is set before the device and
|
||||
* interrupts are enabled.
|
||||
* 1.00c rpm 02/03/03 SelfTest was not clearing polled mode. Take driver out
|
||||
* of polled mode in XEmac_Reset() to fix this problem.
|
||||
* 1.00c rmm 05/13/03 Fixed diab compiler warnings relating to asserts.
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static XStatus ConfigureDma(XEmac * InstancePtr);
|
||||
static XStatus ConfigureFifo(XEmac * InstancePtr);
|
||||
static void StubFifoHandler(void *CallBackRef);
|
||||
static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode);
|
||||
static void StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr,
|
||||
u32 NumBds);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Initialize a specific XEmac instance/driver. The initialization entails:
|
||||
* - Initialize fields of the XEmac structure
|
||||
* - Clear the Ethernet statistics for this device
|
||||
* - Initialize the IPIF component with its register base address
|
||||
* - Configure the FIFO components with their register base addresses.
|
||||
* - If the device is configured with DMA, configure the DMA channel components
|
||||
* with their register base addresses. At some later time, memory pools for
|
||||
* the scatter-gather descriptor lists may be passed to the driver.
|
||||
* - Reset the Ethernet MAC
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param DeviceId is the unique id of the device controlled by this XEmac
|
||||
* instance. Passing in a device id associates the generic XEmac
|
||||
* instance to a specific device, as chosen by the caller or application
|
||||
* developer.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
* - XST_DEVICE_IS_STARTED if the device has already been started
|
||||
* - XST_DEVICE_NOT_FOUND if device configuration information was not found for
|
||||
* a device with the supplied device ID.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId)
|
||||
{
|
||||
XStatus Result;
|
||||
XEmac_Config *ConfigPtr; /* configuration information */
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* If the device is started, disallow the initialize and return a status
|
||||
* indicating it is started. This allows the user to stop the device
|
||||
* and reinitialize, but prevents a user from inadvertently initializing
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set some default values
|
||||
*/
|
||||
InstancePtr->IsReady = 0;
|
||||
InstancePtr->IsStarted = 0;
|
||||
InstancePtr->IpIfDmaConfig = ConfigPtr->IpIfDmaConfig;
|
||||
InstancePtr->HasMii = ConfigPtr->HasMii;
|
||||
InstancePtr->HasMulticastHash = FALSE;
|
||||
|
||||
/* Always default polled to false, let user configure this mode */
|
||||
InstancePtr->IsPolled = FALSE;
|
||||
InstancePtr->FifoRecvHandler = StubFifoHandler;
|
||||
InstancePtr->FifoSendHandler = StubFifoHandler;
|
||||
InstancePtr->ErrorHandler = StubErrorHandler;
|
||||
InstancePtr->SgRecvHandler = StubSgHandler;
|
||||
InstancePtr->SgSendHandler = StubSgHandler;
|
||||
|
||||
/*
|
||||
* Clear the statistics for this driver
|
||||
*/
|
||||
XEmac_mClearStruct((u8 *) & InstancePtr->Stats, sizeof (XEmac_Stats));
|
||||
|
||||
/*
|
||||
* Initialize the device register base addresses
|
||||
*/
|
||||
InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
|
||||
|
||||
/*
|
||||
* Configure the send and receive FIFOs in the MAC
|
||||
*/
|
||||
Result = ConfigureFifo(InstancePtr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is configured for DMA, configure the send and receive DMA
|
||||
* channels in the MAC.
|
||||
*/
|
||||
if (XEmac_mIsDma(InstancePtr)) {
|
||||
Result = ConfigureDma(InstancePtr);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate the component is now ready to use. Note that this is done before
|
||||
* we reset the device and the PHY below, which may seem a bit odd. The
|
||||
* choice was made to move it here rather than remove the asserts in various
|
||||
* functions (e.g., Reset() and all functions that it calls). Applications
|
||||
* that use multiple threads, one to initialize the XEmac driver and one
|
||||
* waiting on the IsReady condition could have a problem with this sequence.
|
||||
*/
|
||||
InstancePtr->IsReady = XCOMPONENT_IS_READY;
|
||||
|
||||
/*
|
||||
* Reset the MAC to get it into its initial state. It is expected that
|
||||
* device configuration by the user will take place after this
|
||||
* initialization is done, but before the device is started.
|
||||
*/
|
||||
XEmac_Reset(InstancePtr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Start the Ethernet controller as follows:
|
||||
* - If not in polled mode
|
||||
* - Set the internal interrupt enable registers appropriately
|
||||
* - Enable interrupts within the device itself. Note that connection of
|
||||
* the driver's interrupt handler to the interrupt source (typically
|
||||
* done using the interrupt controller component) is done by the higher
|
||||
* layer software.
|
||||
* - If the device is configured with scatter-gather DMA, start the DMA
|
||||
* channels if the descriptor lists are not empty
|
||||
* - Enable the transmitter
|
||||
* - Enable the receiver
|
||||
*
|
||||
* The PHY is enabled after driver initialization. We assume the upper layer
|
||||
* software has configured it and the EMAC appropriately before this function
|
||||
* is called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the device was started successfully
|
||||
* - XST_NO_CALLBACK if a callback function has not yet been registered using
|
||||
* the SetxxxHandler function. This is required if in interrupt mode.
|
||||
* - XST_DEVICE_IS_STARTED if the device is already started
|
||||
* - XST_DMA_SG_NO_LIST if configured for scatter-gather DMA and a descriptor
|
||||
* list has not yet been created for the send or receive channel.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* The driver tries to match the hardware configuration. So if the hardware
|
||||
* is configured with scatter-gather DMA, the driver expects to start the
|
||||
* scatter-gather channels and expects that the user has set up the buffer
|
||||
* descriptor lists already. If the user expects to use the driver in a mode
|
||||
* different than how the hardware is configured, the user should modify the
|
||||
* configuration table to reflect the mode to be used. Modifying the config
|
||||
* table is a workaround for now until we get some experience with how users
|
||||
* are intending to use the hardware in its different configurations. For
|
||||
* example, if the hardware is built with scatter-gather DMA but the user is
|
||||
* intending to use only simple DMA, the user either needs to modify the config
|
||||
* table as a workaround or rebuild the hardware with only simple DMA.
|
||||
*
|
||||
* This function makes use of internal resources that are shared between the
|
||||
* Start, Stop, and SetOptions functions. So if one task might be setting device
|
||||
* options while another is trying to start the device, the user is required to
|
||||
* provide protection of this shared data (typically using a semaphore).
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Start(XEmac * InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
XStatus Result;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* If it is already started, return a status indicating so
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not polled, enable interrupts
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
/*
|
||||
* Verify that the callbacks have been registered, then enable
|
||||
* interrupts
|
||||
*/
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
if ((InstancePtr->SgRecvHandler == StubSgHandler) ||
|
||||
(InstancePtr->SgSendHandler == StubSgHandler)) {
|
||||
return XST_NO_CALLBACK;
|
||||
}
|
||||
|
||||
/* Enable IPIF interrupts */
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
XEM_IPIF_DMA_DFT_MASK |
|
||||
XIIF_V123B_ERROR_MASK);
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
|
||||
XEM_EIR_DFT_SG_MASK);
|
||||
|
||||
/* Enable scatter-gather DMA interrupts */
|
||||
XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel,
|
||||
XEM_DMA_SG_INTR_MASK);
|
||||
XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel,
|
||||
XEM_DMA_SG_INTR_MASK);
|
||||
} else {
|
||||
if ((InstancePtr->FifoRecvHandler == StubFifoHandler) ||
|
||||
(InstancePtr->FifoSendHandler == StubFifoHandler)) {
|
||||
return XST_NO_CALLBACK;
|
||||
}
|
||||
|
||||
/* Enable IPIF interrupts (used by simple DMA also) */
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
XEM_IPIF_FIFO_DFT_MASK |
|
||||
XIIF_V123B_ERROR_MASK);
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
|
||||
XEM_EIR_DFT_FIFO_MASK);
|
||||
}
|
||||
|
||||
/* Enable the global IPIF interrupt output */
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate that the device is started before we enable the transmitter
|
||||
* or receiver. This needs to be done before because as soon as the
|
||||
* receiver is enabled we may get an interrupt, and there are functions
|
||||
* in the interrupt handling path that rely on the IsStarted flag.
|
||||
*/
|
||||
InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
|
||||
|
||||
/*
|
||||
* Enable the transmitter, and receiver (do a read/modify/write to preserve
|
||||
* current settings). There is no critical section here since this register
|
||||
* is not modified during interrupt context.
|
||||
*/
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
ControlReg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
|
||||
ControlReg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
|
||||
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
|
||||
|
||||
/*
|
||||
* If configured with scatter-gather DMA and not polled, restart the
|
||||
* DMA channels in case there are buffers ready to be sent or received into.
|
||||
* The DMA SgStart function uses data that can be modified during interrupt
|
||||
* context, so a critical section is required here.
|
||||
*/
|
||||
if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled)) {
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* The only error we care about is if the list has not yet been
|
||||
* created, or on receive, if no buffer descriptors have been
|
||||
* added yet (the list is empty). Other errors are benign at this point.
|
||||
*/
|
||||
Result = XDmaChannel_SgStart(&InstancePtr->RecvChannel);
|
||||
if ((Result == XST_DMA_SG_NO_LIST)
|
||||
|| (Result == XST_DMA_SG_LIST_EMPTY)) {
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XDmaChannel_SgStart(&InstancePtr->SendChannel);
|
||||
if (Result == XST_DMA_SG_NO_LIST) {
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
return Result;
|
||||
}
|
||||
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Stop the Ethernet MAC as follows:
|
||||
* - If the device is configured with scatter-gather DMA, stop the DMA
|
||||
* channels (wait for acknowledgment of stop)
|
||||
* - Disable the transmitter and receiver
|
||||
* - Disable interrupts if not in polled mode (the higher layer software is
|
||||
* responsible for disabling interrupts at the interrupt controller)
|
||||
*
|
||||
* The PHY is left enabled after a Stop is called.
|
||||
*
|
||||
* If the device is configured for scatter-gather DMA, the DMA engine stops at
|
||||
* the next buffer descriptor in its list. The remaining descriptors in the list
|
||||
* are not removed, so anything in the list will be transmitted or received when
|
||||
* the device is restarted. The side effect of doing this is that the last
|
||||
* buffer descriptor processed by the DMA engine before stopping may not be the
|
||||
* last descriptor in the Ethernet frame. So when the device is restarted, a
|
||||
* partial frame (i.e., a bad frame) may be transmitted/received. This is only a
|
||||
* concern if a frame can span multiple buffer descriptors, which is dependent
|
||||
* on the size of the network buffers.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the device was stopped successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device is already stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function makes use of internal resources that are shared between the
|
||||
* Start, Stop, and SetOptions functions. So if one task might be setting device
|
||||
* options while another is trying to start the device, the user is required to
|
||||
* provide protection of this shared data (typically using a semaphore).
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_Stop(XEmac * InstancePtr)
|
||||
{
|
||||
u32 ControlReg;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* If the device is already stopped, do nothing but return a status
|
||||
* indicating so
|
||||
*/
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If configured for scatter-gather DMA, stop the DMA channels. Ignore
|
||||
* the XST_DMA_SG_IS_STOPPED return code. There is a critical section
|
||||
* here between SgStart and SgStop, and SgStart can be called in interrupt
|
||||
* context, so disable interrupts while calling SgStop.
|
||||
*/
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
XBufDescriptor *BdTemp; /* temporary descriptor pointer */
|
||||
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
|
||||
(void) XDmaChannel_SgStop(&InstancePtr->SendChannel, &BdTemp);
|
||||
(void) XDmaChannel_SgStop(&InstancePtr->RecvChannel, &BdTemp);
|
||||
|
||||
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the transmitter and receiver. There is no critical section
|
||||
* here since this register is not modified during interrupt context.
|
||||
*/
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
ControlReg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
|
||||
|
||||
/*
|
||||
* If not in polled mode, disable interrupts for IPIF (includes MAC and
|
||||
* DMAs)
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
|
||||
}
|
||||
|
||||
InstancePtr->IsStarted = 0;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Reset the Ethernet MAC. This is a graceful reset in that the device is stopped
|
||||
* first. Resets the DMA channels, the FIFOs, the transmitter, and the receiver.
|
||||
* The PHY is not reset. Any frames in the scatter-gather descriptor lists will
|
||||
* remain in the lists. The side effect of doing this is that after a reset and
|
||||
* following a restart of the device, frames that were in the list before the
|
||||
* reset may be transmitted or received. Reset must only be called after the
|
||||
* driver has been initialized.
|
||||
*
|
||||
* The driver is also taken out of polled mode if polled mode was set. The user
|
||||
* is responsbile for re-configuring the driver into polled mode after the
|
||||
* reset if desired.
|
||||
*
|
||||
* The configuration after this reset is as follows:
|
||||
* - Half duplex
|
||||
* - Disabled transmitter and receiver
|
||||
* - Enabled PHY (the PHY is not reset)
|
||||
* - MAC transmitter does pad insertion, FCS insertion, and source address
|
||||
* overwrite.
|
||||
* - MAC receiver does not strip padding or FCS
|
||||
* - Interframe Gap as recommended by IEEE Std. 802.3 (96 bit times)
|
||||
* - Unicast addressing enabled
|
||||
* - Broadcast addressing enabled
|
||||
* - Multicast addressing disabled (addresses are preserved)
|
||||
* - Promiscuous addressing disabled
|
||||
* - Default packet threshold and packet wait bound register values for
|
||||
* scatter-gather DMA operation
|
||||
* - MAC address of all zeros
|
||||
* - Non-polled mode
|
||||
*
|
||||
* The upper layer software is responsible for re-configuring (if necessary)
|
||||
* and restarting the MAC after the reset. Note that the PHY is not reset. PHY
|
||||
* control is left to the upper layer software. Note also that driver statistics
|
||||
* are not cleared on reset. It is up to the upper layer software to clear the
|
||||
* statistics if needed.
|
||||
*
|
||||
* When a reset is required due to an internal error, the driver notifies the
|
||||
* upper layer software of this need through the ErrorHandler callback and
|
||||
* specific status codes. The upper layer software is responsible for calling
|
||||
* this Reset function and then re-configuring the device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The reset is accomplished by setting the IPIF reset register. This takes
|
||||
* care of resetting all hardware blocks, including the MAC.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_Reset(XEmac * InstancePtr)
|
||||
{
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Stop the device first
|
||||
*/
|
||||
(void) XEmac_Stop(InstancePtr);
|
||||
|
||||
/*
|
||||
* Take the driver out of polled mode
|
||||
*/
|
||||
InstancePtr->IsPolled = FALSE;
|
||||
|
||||
/*
|
||||
* Reset the entire IPIF at once. If we choose someday to reset each
|
||||
* hardware block separately, the reset should occur in the direction of
|
||||
* data flow. For example, for the send direction the reset order is DMA
|
||||
* first, then FIFO, then the MAC transmitter.
|
||||
*/
|
||||
XIIF_V123B_RESET(InstancePtr->BaseAddress);
|
||||
|
||||
if (XEmac_mIsSgDma(InstancePtr)) {
|
||||
/*
|
||||
* After reset, configure the scatter-gather DMA packet threshold and
|
||||
* packet wait bound registers to default values. Ignore the return
|
||||
* values of these functions since they only return error if the device
|
||||
* is not stopped.
|
||||
*/
|
||||
(void) XEmac_SetPktThreshold(InstancePtr, XEM_SEND,
|
||||
XEM_SGDMA_DFT_THRESHOLD);
|
||||
(void) XEmac_SetPktThreshold(InstancePtr, XEM_RECV,
|
||||
XEM_SGDMA_DFT_THRESHOLD);
|
||||
(void) XEmac_SetPktWaitBound(InstancePtr, XEM_SEND,
|
||||
XEM_SGDMA_DFT_WAITBOUND);
|
||||
(void) XEmac_SetPktWaitBound(InstancePtr, XEM_RECV,
|
||||
XEM_SGDMA_DFT_WAITBOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the MAC address for this driver/device. The address is a 48-bit value.
|
||||
* The device must be stopped before calling this function.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param AddressPtr is a pointer to a 6-byte MAC address.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the MAC address was set successfully
|
||||
* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr)
|
||||
{
|
||||
u32 MacAddr = 0;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(AddressPtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The device must be stopped before setting the MAC address
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the device station address high and low registers
|
||||
*/
|
||||
MacAddr = (AddressPtr[0] << 8) | AddressPtr[1];
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_SAH_OFFSET, MacAddr);
|
||||
|
||||
MacAddr = (AddressPtr[2] << 24) | (AddressPtr[3] << 16) |
|
||||
(AddressPtr[4] << 8) | AddressPtr[5];
|
||||
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_SAL_OFFSET, MacAddr);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the MAC address for this driver/device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufferPtr is an output parameter, and is a pointer to a buffer into
|
||||
* which the current MAC address will be copied. The buffer must be at
|
||||
* least 6 bytes.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr)
|
||||
{
|
||||
u32 MacAddrHi;
|
||||
u32 MacAddrLo;
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(BufferPtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);
|
||||
MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);
|
||||
|
||||
BufferPtr[0] = (u8) (MacAddrHi >> 8);
|
||||
BufferPtr[1] = (u8) MacAddrHi;
|
||||
BufferPtr[2] = (u8) (MacAddrLo >> 24);
|
||||
BufferPtr[3] = (u8) (MacAddrLo >> 16);
|
||||
BufferPtr[4] = (u8) (MacAddrLo >> 8);
|
||||
BufferPtr[5] = (u8) MacAddrLo;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Configure DMA capabilities.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if successful initialization of DMA
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XStatus
|
||||
ConfigureDma(XEmac * InstancePtr)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
/*
|
||||
* Initialize the DMA channels with their base addresses. We assume
|
||||
* scatter-gather DMA is the only possible configuration. Descriptor space
|
||||
* will need to be set later by the upper layer.
|
||||
*/
|
||||
Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_DMA_RECV_OFFSET);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XDmaChannel_Initialize(&InstancePtr->SendChannel,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_DMA_SEND_OFFSET);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Configure the send and receive FIFO components with their base addresses
|
||||
* and interrupt masks. Currently the base addresses are defined constants.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS if successful initialization of the packet FIFOs
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XStatus
|
||||
ConfigureFifo(XEmac * InstancePtr)
|
||||
{
|
||||
XStatus Result;
|
||||
|
||||
/*
|
||||
* Return status from the packet FIFOs initialization is ignored since
|
||||
* they always return success.
|
||||
*/
|
||||
Result = XPacketFifoV100b_Initialize(&InstancePtr->RecvFifo,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_RXREG_OFFSET,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_RXDATA_OFFSET);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result = XPacketFifoV100b_Initialize(&InstancePtr->SendFifo,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_TXREG_OFFSET,
|
||||
InstancePtr->BaseAddress +
|
||||
XEM_PFIFO_TXDATA_OFFSET);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the scatter-gather send and recv callbacks. The stub
|
||||
* is here in case the upper layers forget to set the handlers.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
* @param BdPtr is a pointer to the first buffer descriptor in a list
|
||||
* @param NumBds is the number of descriptors in the list.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the non-DMA send and recv callbacks. The stub is here in
|
||||
* case the upper layers forget to set the handlers.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubFifoHandler(void *CallBackRef)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This is a stub for the asynchronous error callback. The stub is here in
|
||||
* case the upper layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
* @param ErrorCode is the Xilinx error code, indicating the cause of the error
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void
|
||||
StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
|
||||
{
|
||||
XASSERT_VOID_ALWAYS();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Lookup the device configuration based on the unique device ID. The table
|
||||
* EmacConfigTable contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique device ID of the device being looked up.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A pointer to the configuration table entry corresponding to the given
|
||||
* device ID, or NULL if no match is found.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XEmac_Config *
|
||||
XEmac_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XEmac_Config *CfgPtr = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XPAR_XEMAC_NUM_INSTANCES; i++) {
|
||||
if (XEmac_ConfigTable[i].DeviceId == DeviceId) {
|
||||
CfgPtr = &XEmac_ConfigTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
||||
673
board/xilinx/xilinx_enet/xemac.h
Normal file
673
board/xilinx/xilinx_enet/xemac.h
Normal file
@@ -0,0 +1,673 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac.h
|
||||
*
|
||||
* The Xilinx Ethernet driver component. This component supports the Xilinx
|
||||
* Ethernet 10/100 MAC (EMAC).
|
||||
*
|
||||
* The Xilinx Ethernet 10/100 MAC supports the following features:
|
||||
* - Simple and scatter-gather DMA operations, as well as simple memory
|
||||
* mapped direct I/O interface (FIFOs).
|
||||
* - Media Independent Interface (MII) for connection to external
|
||||
* 10/100 Mbps PHY transceivers.
|
||||
* - MII management control reads and writes with MII PHYs
|
||||
* - Independent internal transmit and receive FIFOs
|
||||
* - CSMA/CD compliant operations for half-duplex modes
|
||||
* - Programmable PHY reset signal
|
||||
* - Unicast, broadcast, and promiscuous address filtering (no multicast yet)
|
||||
* - Internal loopback
|
||||
* - Automatic source address insertion or overwrite (programmable)
|
||||
* - Automatic FCS insertion and stripping (programmable)
|
||||
* - Automatic pad insertion and stripping (programmable)
|
||||
* - Pause frame (flow control) detection in full-duplex mode
|
||||
* - Programmable interframe gap
|
||||
* - VLAN frame support.
|
||||
* - Pause frame support
|
||||
*
|
||||
* The device driver supports all the features listed above.
|
||||
*
|
||||
* <b>Driver Description</b>
|
||||
*
|
||||
* The device driver enables higher layer software (e.g., an application) to
|
||||
* communicate to the EMAC. The driver handles transmission and reception of
|
||||
* Ethernet frames, as well as configuration of the controller. It does not
|
||||
* handle protocol stack functionality such as Link Layer Control (LLC) or the
|
||||
* Address Resolution Protocol (ARP). The protocol stack that makes use of the
|
||||
* driver handles this functionality. This implies that the driver is simply a
|
||||
* pass-through mechanism between a protocol stack and the EMAC. A single device
|
||||
* driver can support multiple EMACs.
|
||||
*
|
||||
* The driver is designed for a zero-copy buffer scheme. That is, the driver will
|
||||
* not copy buffers. This avoids potential throughput bottlenecks within the
|
||||
* driver.
|
||||
*
|
||||
* Since the driver is a simple pass-through mechanism between a protocol stack
|
||||
* and the EMAC, no assembly or disassembly of Ethernet frames is done at the
|
||||
* driver-level. This assumes that the protocol stack passes a correctly
|
||||
* formatted Ethernet frame to the driver for transmission, and that the driver
|
||||
* does not validate the contents of an incoming frame
|
||||
*
|
||||
* <b>PHY Communication</b>
|
||||
*
|
||||
* The driver provides rudimentary read and write functions to allow the higher
|
||||
* layer software to access the PHY. The EMAC provides MII registers for the
|
||||
* driver to access. This management interface can be parameterized away in the
|
||||
* FPGA implementation process. If this is the case, the PHY read and write
|
||||
* functions of the driver return XST_NO_FEATURE.
|
||||
*
|
||||
* External loopback is usually supported at the PHY. It is up to the user to
|
||||
* turn external loopback on or off at the PHY. The driver simply provides pass-
|
||||
* through functions for configuring the PHY. The driver does not read, write,
|
||||
* or reset the PHY on its own. All control of the PHY must be done by the user.
|
||||
*
|
||||
* <b>Asynchronous Callbacks</b>
|
||||
*
|
||||
* The driver services interrupts and passes Ethernet frames to the higher layer
|
||||
* software through asynchronous callback functions. When using the driver
|
||||
* directly (i.e., not with the RTOS protocol stack), the higher layer
|
||||
* software must register its callback functions during initialization. The
|
||||
* driver requires callback functions for received frames, for confirmation of
|
||||
* transmitted frames, and for asynchronous errors.
|
||||
*
|
||||
* <b>Interrupts</b>
|
||||
*
|
||||
* The driver has no dependencies on the interrupt controller. The driver
|
||||
* provides two interrupt handlers. XEmac_IntrHandlerDma() handles interrupts
|
||||
* when the EMAC is configured with scatter-gather DMA. XEmac_IntrHandlerFifo()
|
||||
* handles interrupts when the EMAC is configured for direct FIFO I/O or simple
|
||||
* DMA. Either of these routines can be connected to the system interrupt
|
||||
* controller by the user.
|
||||
*
|
||||
* <b>Interrupt Frequency</b>
|
||||
*
|
||||
* When the EMAC is configured with scatter-gather DMA, the frequency of
|
||||
* interrupts can be controlled with the interrupt coalescing features of the
|
||||
* scatter-gather DMA engine. The frequency of interrupts can be adjusted using
|
||||
* the driver API functions for setting the packet count threshold and the packet
|
||||
* wait bound values.
|
||||
*
|
||||
* The scatter-gather DMA engine only interrupts when the packet count threshold
|
||||
* is reached, instead of interrupting for each packet. A packet is a generic
|
||||
* term used by the scatter-gather DMA engine, and is equivalent to an Ethernet
|
||||
* frame in our case.
|
||||
*
|
||||
* The packet wait bound is a timer value used during interrupt coalescing to
|
||||
* trigger an interrupt when not enough packets have been received to reach the
|
||||
* packet count threshold.
|
||||
*
|
||||
* These values can be tuned by the user to meet their needs. If there appear to
|
||||
* be interrupt latency problems or delays in packet arrival that are longer than
|
||||
* might be expected, the user should verify that the packet count threshold is
|
||||
* set low enough to receive interrupts before the wait bound timer goes off.
|
||||
*
|
||||
* <b>Device Reset</b>
|
||||
*
|
||||
* Some errors that can occur in the device require a device reset. These errors
|
||||
* are listed in the XEmac_SetErrorHandler() function header. The user's error
|
||||
* handler is responsible for resetting the device and re-configuring it based on
|
||||
* its needs (the driver does not save the current configuration). When
|
||||
* integrating into an RTOS, these reset and re-configure obligations are
|
||||
* taken care of by the Xilinx adapter software if it exists for that RTOS.
|
||||
*
|
||||
* <b>Device Configuration</b>
|
||||
*
|
||||
* The device can be configured in various ways during the FPGA implementation
|
||||
* process. Configuration parameters are stored in the xemac_g.c files.
|
||||
* A table is defined where each entry contains configuration information
|
||||
* for an EMAC device. This information includes such things as the base address
|
||||
* of the memory-mapped device, the base addresses of IPIF, DMA, and FIFO modules
|
||||
* within the device, and whether the device has DMA, counter registers,
|
||||
* multicast support, MII support, and flow control.
|
||||
*
|
||||
* The driver tries to use the features built into the device. So if, for
|
||||
* example, the hardware is configured with scatter-gather DMA, the driver
|
||||
* expects to start the scatter-gather channels and expects that the user has set
|
||||
* up the buffer descriptor lists already. If the user expects to use the driver
|
||||
* in a mode different than how the hardware is configured, the user should
|
||||
* modify the configuration table to reflect the mode to be used. Modifying the
|
||||
* configuration table is a workaround for now until we get some experience with
|
||||
* how users are intending to use the hardware in its different configurations.
|
||||
* For example, if the hardware is built with scatter-gather DMA but the user is
|
||||
* intending to use only simple DMA, the user either needs to modify the config
|
||||
* table as a workaround or rebuild the hardware with only simple DMA. The
|
||||
* recommendation at this point is to build the hardware with the features you
|
||||
* intend to use. If you're inclined to modify the table, do so before the call
|
||||
* to XEmac_Initialize(). Here is a snippet of code that changes a device to
|
||||
* simple DMA (the hardware needs to have DMA for this to work of course):
|
||||
* <pre>
|
||||
* XEmac_Config *ConfigPtr;
|
||||
*
|
||||
* ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
* ConfigPtr->IpIfDmaConfig = XEM_CFG_SIMPLE_DMA;
|
||||
* </pre>
|
||||
*
|
||||
* <b>Simple DMA</b>
|
||||
*
|
||||
* Simple DMA is supported through the FIFO functions, FifoSend and FifoRecv, of
|
||||
* the driver (i.e., there is no separate interface for it). The driver makes use
|
||||
* of the DMA engine for a simple DMA transfer if the device is configured with
|
||||
* DMA, otherwise it uses the FIFOs directly. While the simple DMA interface is
|
||||
* therefore transparent to the user, the caching of network buffers is not.
|
||||
* If the device is configured with DMA and the FIFO interface is used, the user
|
||||
* must ensure that the network buffers are not cached or are cache coherent,
|
||||
* since DMA will be used to transfer to and from the Emac device. If the device
|
||||
* is configured with DMA and the user really wants to use the FIFOs directly,
|
||||
* the user should rebuild the hardware without DMA. If unable to do this, there
|
||||
* is a workaround (described above in Device Configuration) to modify the
|
||||
* configuration table of the driver to fake the driver into thinking the device
|
||||
* has no DMA. A code snippet follows:
|
||||
* <pre>
|
||||
* XEmac_Config *ConfigPtr;
|
||||
*
|
||||
* ConfigPtr = XEmac_LookupConfig(DeviceId);
|
||||
* ConfigPtr->IpIfDmaConfig = XEM_CFG_NO_DMA;
|
||||
* </pre>
|
||||
*
|
||||
* <b>Asserts</b>
|
||||
*
|
||||
* Asserts are used within all Xilinx drivers to enforce constraints on argument
|
||||
* values. Asserts can be turned off on a system-wide basis by defining, at
|
||||
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
|
||||
* is recommended that users leave asserts on during development.
|
||||
*
|
||||
* <b>Building the driver</b>
|
||||
*
|
||||
* The XEmac driver is composed of several source files. Why so many? This
|
||||
* allows the user to build and link only those parts of the driver that are
|
||||
* necessary. Since the EMAC hardware can be configured in various ways (e.g.,
|
||||
* with or without DMA), the driver too can be built with varying features.
|
||||
* For the most part, this means that besides always linking in xemac.c, you
|
||||
* link in only the driver functionality you want. Some of the choices you have
|
||||
* are polled vs. interrupt, interrupt with FIFOs only vs. interrupt with DMA,
|
||||
* self-test diagnostics, and driver statistics. Note that currently the DMA code
|
||||
* must be linked in, even if you don't have DMA in the device.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Xilinx drivers are typically composed of two components, one is the driver
|
||||
* and the other is the adapter. The driver is independent of OS and processor
|
||||
* and is intended to be highly portable. The adapter is OS-specific and
|
||||
* facilitates communication between the driver and an OS.
|
||||
* <br><br>
|
||||
* This driver is intended to be RTOS and processor independent. It works
|
||||
* with physical addresses only. Any needs for dynamic memory management,
|
||||
* threads or thread mutual exclusion, virtual memory, or cache control must
|
||||
* be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00b rpm 10/08/02 Replaced HasSgDma boolean with IpifDmaConfig enumerated
|
||||
* configuration parameter
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA and the delay
|
||||
* argument to SgSend
|
||||
* 1.00c rpm 02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
|
||||
* from SetPktThreshold in the internal DMA driver. Also
|
||||
* avoided compiler warnings by initializing Result in the
|
||||
* DMA interrupt service routines.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_H /* prevent circular inclusions */
|
||||
#define XEMAC_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xparameters.h"
|
||||
#include "xpacket_fifo_v1_00_b.h" /* Uses v1.00b of Packet Fifo */
|
||||
#include "xdma_channel.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Device information
|
||||
*/
|
||||
#define XEM_DEVICE_NAME "xemac"
|
||||
#define XEM_DEVICE_DESC "Xilinx Ethernet 10/100 MAC"
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* Device configuration options (see the XEmac_SetOptions() and
|
||||
* XEmac_GetOptions() for information on how to use these options)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* <pre>
|
||||
* XEM_BROADCAST_OPTION Broadcast addressing on or off (default is on)
|
||||
* XEM_UNICAST_OPTION Unicast addressing on or off (default is on)
|
||||
* XEM_PROMISC_OPTION Promiscuous addressing on or off (default is off)
|
||||
* XEM_FDUPLEX_OPTION Full duplex on or off (default is off)
|
||||
* XEM_POLLED_OPTION Polled mode on or off (default is off)
|
||||
* XEM_LOOPBACK_OPTION Internal loopback on or off (default is off)
|
||||
* XEM_FLOW_CONTROL_OPTION Interpret pause frames in full duplex mode
|
||||
* (default is off)
|
||||
* XEM_INSERT_PAD_OPTION Pad short frames on transmit (default is on)
|
||||
* XEM_INSERT_FCS_OPTION Insert FCS (CRC) on transmit (default is on)
|
||||
* XEM_INSERT_ADDR_OPTION Insert source address on transmit (default is on)
|
||||
* XEM_OVWRT_ADDR_OPTION Overwrite source address on transmit. This is
|
||||
* only used if source address insertion is on.
|
||||
* (default is on)
|
||||
* XEM_STRIP_PAD_FCS_OPTION Strip FCS and padding from received frames
|
||||
* (default is off)
|
||||
* </pre>
|
||||
*/
|
||||
#define XEM_UNICAST_OPTION 0x00000001UL
|
||||
#define XEM_BROADCAST_OPTION 0x00000002UL
|
||||
#define XEM_PROMISC_OPTION 0x00000004UL
|
||||
#define XEM_FDUPLEX_OPTION 0x00000008UL
|
||||
#define XEM_POLLED_OPTION 0x00000010UL
|
||||
#define XEM_LOOPBACK_OPTION 0x00000020UL
|
||||
#define XEM_FLOW_CONTROL_OPTION 0x00000080UL
|
||||
#define XEM_INSERT_PAD_OPTION 0x00000100UL
|
||||
#define XEM_INSERT_FCS_OPTION 0x00000200UL
|
||||
#define XEM_INSERT_ADDR_OPTION 0x00000400UL
|
||||
#define XEM_OVWRT_ADDR_OPTION 0x00000800UL
|
||||
#define XEM_STRIP_PAD_FCS_OPTION 0x00002000UL
|
||||
/*@}*/
|
||||
/*
|
||||
* Not supported yet:
|
||||
* XEM_MULTICAST_OPTION Multicast addressing on or off (default is off)
|
||||
*/
|
||||
/* NOT SUPPORTED YET... */
|
||||
#define XEM_MULTICAST_OPTION 0x00000040UL
|
||||
|
||||
/*
|
||||
* Some default values for interrupt coalescing within the scatter-gather
|
||||
* DMA engine.
|
||||
*/
|
||||
#define XEM_SGDMA_DFT_THRESHOLD 1 /* Default pkt threshold */
|
||||
#define XEM_SGDMA_MAX_THRESHOLD 255 /* Maximum pkt theshold */
|
||||
#define XEM_SGDMA_DFT_WAITBOUND 5 /* Default pkt wait bound (msec) */
|
||||
#define XEM_SGDMA_MAX_WAITBOUND 1023 /* Maximum pkt wait bound (msec) */
|
||||
|
||||
/*
|
||||
* Direction identifiers. These are used for setting values like packet
|
||||
* thresholds and wait bound for specific channels
|
||||
*/
|
||||
#define XEM_SEND 1
|
||||
#define XEM_RECV 2
|
||||
|
||||
/*
|
||||
* Arguments to SgSend function to indicate whether to hold off starting
|
||||
* the scatter-gather engine.
|
||||
*/
|
||||
#define XEM_SGDMA_NODELAY 0 /* start SG DMA immediately */
|
||||
#define XEM_SGDMA_DELAY 1 /* do not start SG DMA */
|
||||
|
||||
/*
|
||||
* Constants to determine the configuration of the hardware device. They are
|
||||
* used to allow the driver to verify it can operate with the hardware.
|
||||
*/
|
||||
#define XEM_CFG_NO_IPIF 0 /* Not supported by the driver */
|
||||
#define XEM_CFG_NO_DMA 1 /* No DMA */
|
||||
#define XEM_CFG_SIMPLE_DMA 2 /* Simple DMA */
|
||||
#define XEM_CFG_DMA_SG 3 /* DMA scatter gather */
|
||||
|
||||
/*
|
||||
* The next few constants help upper layers determine the size of memory
|
||||
* pools used for Ethernet buffers and descriptor lists.
|
||||
*/
|
||||
#define XEM_MAC_ADDR_SIZE 6 /* six-byte MAC address */
|
||||
#define XEM_MTU 1500 /* max size of Ethernet frame */
|
||||
#define XEM_HDR_SIZE 14 /* size of Ethernet header */
|
||||
#define XEM_HDR_VLAN_SIZE 18 /* size of Ethernet header with VLAN */
|
||||
#define XEM_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */
|
||||
#define XEM_MAX_FRAME_SIZE (XEM_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
|
||||
#define XEM_MAX_VLAN_FRAME_SIZE (XEM_MTU + XEM_HDR_VLAN_SIZE + XEM_TRL_SIZE)
|
||||
|
||||
/*
|
||||
* Define a default number of send and receive buffers
|
||||
*/
|
||||
#define XEM_MIN_RECV_BUFS 32 /* minimum # of recv buffers */
|
||||
#define XEM_DFT_RECV_BUFS 64 /* default # of recv buffers */
|
||||
|
||||
#define XEM_MIN_SEND_BUFS 16 /* minimum # of send buffers */
|
||||
#define XEM_DFT_SEND_BUFS 32 /* default # of send buffers */
|
||||
|
||||
#define XEM_MIN_BUFFERS (XEM_MIN_RECV_BUFS + XEM_MIN_SEND_BUFS)
|
||||
#define XEM_DFT_BUFFERS (XEM_DFT_RECV_BUFS + XEM_DFT_SEND_BUFS)
|
||||
|
||||
/*
|
||||
* Define the number of send and receive buffer descriptors, used for
|
||||
* scatter-gather DMA
|
||||
*/
|
||||
#define XEM_MIN_RECV_DESC 16 /* minimum # of recv descriptors */
|
||||
#define XEM_DFT_RECV_DESC 32 /* default # of recv descriptors */
|
||||
|
||||
#define XEM_MIN_SEND_DESC 8 /* minimum # of send descriptors */
|
||||
#define XEM_DFT_SEND_DESC 16 /* default # of send descriptors */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/**
|
||||
* Ethernet statistics (see XEmac_GetStats() and XEmac_ClearStats())
|
||||
*/
|
||||
typedef struct {
|
||||
u32 XmitFrames; /**< Number of frames transmitted */
|
||||
u32 XmitBytes; /**< Number of bytes transmitted */
|
||||
u32 XmitLateCollisionErrors;
|
||||
/**< Number of transmission failures
|
||||
due to late collisions */
|
||||
u32 XmitExcessDeferral; /**< Number of transmission failures
|
||||
due o excess collision deferrals */
|
||||
u32 XmitOverrunErrors; /**< Number of transmit overrun errors */
|
||||
u32 XmitUnderrunErrors; /**< Number of transmit underrun errors */
|
||||
u32 RecvFrames; /**< Number of frames received */
|
||||
u32 RecvBytes; /**< Number of bytes received */
|
||||
u32 RecvFcsErrors; /**< Number of frames discarded due
|
||||
to FCS errors */
|
||||
u32 RecvAlignmentErrors; /**< Number of frames received with
|
||||
alignment errors */
|
||||
u32 RecvOverrunErrors; /**< Number of frames discarded due
|
||||
to overrun errors */
|
||||
u32 RecvUnderrunErrors; /**< Number of recv underrun errors */
|
||||
u32 RecvMissedFrameErrors;
|
||||
/**< Number of frames missed by MAC */
|
||||
u32 RecvCollisionErrors; /**< Number of frames discarded due
|
||||
to collisions */
|
||||
u32 RecvLengthFieldErrors;
|
||||
/**< Number of frames discarded with
|
||||
invalid length field */
|
||||
u32 RecvShortErrors; /**< Number of short frames discarded */
|
||||
u32 RecvLongErrors; /**< Number of long frames discarded */
|
||||
u32 DmaErrors; /**< Number of DMA errors since init */
|
||||
u32 FifoErrors; /**< Number of FIFO errors since init */
|
||||
u32 RecvInterrupts; /**< Number of receive interrupts */
|
||||
u32 XmitInterrupts; /**< Number of transmit interrupts */
|
||||
u32 EmacInterrupts; /**< Number of MAC (device) interrupts */
|
||||
u32 TotalIntrs; /**< Total interrupts */
|
||||
} XEmac_Stats;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for a device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
u32 BaseAddress; /**< Register base address */
|
||||
u32 HasCounters; /**< Does device have counters? */
|
||||
u8 IpIfDmaConfig; /**< IPIF/DMA hardware configuration */
|
||||
u32 HasMii; /**< Does device support MII? */
|
||||
|
||||
} XEmac_Config;
|
||||
|
||||
/** @name Typedefs for callbacks
|
||||
* Callback functions.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Callback when data is sent or received with scatter-gather DMA.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper layer
|
||||
* when setting the callback functions, and passed back to the upper
|
||||
* layer when the callback is invoked.
|
||||
* @param BdPtr is a pointer to the first buffer descriptor in a list of
|
||||
* buffer descriptors.
|
||||
* @param NumBds is the number of buffer descriptors in the list pointed
|
||||
* to by BdPtr.
|
||||
*/
|
||||
typedef void (*XEmac_SgHandler) (void *CallBackRef, XBufDescriptor * BdPtr,
|
||||
u32 NumBds);
|
||||
|
||||
/**
|
||||
* Callback when data is sent or received with direct FIFO communication or
|
||||
* simple DMA. The user typically defines two callacks, one for send and one
|
||||
* for receive.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper layer
|
||||
* when setting the callback functions, and passed back to the upper
|
||||
* layer when the callback is invoked.
|
||||
*/
|
||||
typedef void (*XEmac_FifoHandler) (void *CallBackRef);
|
||||
|
||||
/**
|
||||
* Callback when an asynchronous error occurs.
|
||||
*
|
||||
* @param CallBackRef is a callback reference passed in by the upper layer
|
||||
* when setting the callback functions, and passed back to the upper
|
||||
* layer when the callback is invoked.
|
||||
* @param ErrorCode is a Xilinx error code defined in xstatus.h. Also see
|
||||
* XEmac_SetErrorHandler() for a description of possible errors.
|
||||
*/
|
||||
typedef void (*XEmac_ErrorHandler) (void *CallBackRef, XStatus ErrorCode);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* The XEmac driver instance data. The user is required to allocate a
|
||||
* variable of this type for every EMAC device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 BaseAddress; /* Base address (of IPIF) */
|
||||
u32 IsStarted; /* Device is currently started */
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
u32 IsPolled; /* Device is in polled mode */
|
||||
u8 IpIfDmaConfig; /* IPIF/DMA hardware configuration */
|
||||
u32 HasMii; /* Does device support MII? */
|
||||
u32 HasMulticastHash; /* Does device support multicast hash table? */
|
||||
|
||||
XEmac_Stats Stats;
|
||||
XPacketFifoV100b RecvFifo; /* FIFO used to receive frames */
|
||||
XPacketFifoV100b SendFifo; /* FIFO used to send frames */
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
*/
|
||||
XEmac_FifoHandler FifoRecvHandler; /* for non-DMA/simple DMA interrupts */
|
||||
void *FifoRecvRef;
|
||||
XEmac_FifoHandler FifoSendHandler; /* for non-DMA/simple DMA interrupts */
|
||||
void *FifoSendRef;
|
||||
XEmac_ErrorHandler ErrorHandler; /* for asynchronous errors */
|
||||
void *ErrorRef;
|
||||
|
||||
XDmaChannel RecvChannel; /* DMA receive channel driver */
|
||||
XDmaChannel SendChannel; /* DMA send channel driver */
|
||||
|
||||
XEmac_SgHandler SgRecvHandler; /* callback for scatter-gather DMA */
|
||||
void *SgRecvRef;
|
||||
XEmac_SgHandler SgSendHandler; /* callback for scatter-gather DMA */
|
||||
void *SgSendRef;
|
||||
} XEmac;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured for
|
||||
* scatter-gather DMA.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured for scatter-gather DMA, or FALSE
|
||||
* if it is not.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsSgDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsSgDma(InstancePtr) \
|
||||
((InstancePtr)->IpIfDmaConfig == XEM_CFG_DMA_SG)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured for simple DMA.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured for simple DMA, or FALSE otherwise
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsSimpleDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsSimpleDma(InstancePtr) \
|
||||
((InstancePtr)->IpIfDmaConfig == XEM_CFG_SIMPLE_DMA)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is currently configured with DMA (either
|
||||
* simple DMA or scatter-gather DMA)
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured with DMA, or FALSE otherwise
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmac_mIsDma(XEmac *InstancePtr)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mIsDma(InstancePtr) \
|
||||
(XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Initialization functions in xemac.c
|
||||
*/
|
||||
XStatus XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId);
|
||||
XStatus XEmac_Start(XEmac * InstancePtr);
|
||||
XStatus XEmac_Stop(XEmac * InstancePtr);
|
||||
void XEmac_Reset(XEmac * InstancePtr);
|
||||
XEmac_Config *XEmac_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Diagnostic functions in xemac_selftest.c
|
||||
*/
|
||||
XStatus XEmac_SelfTest(XEmac * InstancePtr);
|
||||
|
||||
/*
|
||||
* Polled functions in xemac_polled.c
|
||||
*/
|
||||
XStatus XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
|
||||
XStatus XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
|
||||
|
||||
/*
|
||||
* Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
|
||||
*/
|
||||
XStatus XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay);
|
||||
XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr);
|
||||
XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold);
|
||||
XStatus XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction,
|
||||
u8 * ThreshPtr);
|
||||
XStatus XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction,
|
||||
u32 TimerValue);
|
||||
XStatus XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction,
|
||||
u32 * WaitPtr);
|
||||
XStatus XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
|
||||
u32 ByteCount);
|
||||
XStatus XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
|
||||
u32 ByteCount);
|
||||
void XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_SgHandler FuncPtr);
|
||||
void XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_SgHandler FuncPtr);
|
||||
|
||||
void XEmac_IntrHandlerDma(void *InstancePtr); /* interrupt handler */
|
||||
|
||||
/*
|
||||
* Interrupts with direct FIFO functions in xemac_intr_fifo.c. Also used
|
||||
* for simple DMA.
|
||||
*/
|
||||
XStatus XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
|
||||
XStatus XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
|
||||
void XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_FifoHandler FuncPtr);
|
||||
void XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_FifoHandler FuncPtr);
|
||||
|
||||
void XEmac_IntrHandlerFifo(void *InstancePtr); /* interrupt handler */
|
||||
|
||||
/*
|
||||
* General interrupt-related functions in xemac_intr.c
|
||||
*/
|
||||
void XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_ErrorHandler FuncPtr);
|
||||
|
||||
/*
|
||||
* MAC configuration in xemac_options.c
|
||||
*/
|
||||
XStatus XEmac_SetOptions(XEmac * InstancePtr, u32 OptionFlag);
|
||||
u32 XEmac_GetOptions(XEmac * InstancePtr);
|
||||
XStatus XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr);
|
||||
void XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr);
|
||||
XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2);
|
||||
void XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr);
|
||||
|
||||
/*
|
||||
* Multicast functions in xemac_multicast.c (not supported by EMAC yet)
|
||||
*/
|
||||
XStatus XEmac_MulticastAdd(XEmac * InstancePtr, u8 * AddressPtr);
|
||||
XStatus XEmac_MulticastClear(XEmac * InstancePtr);
|
||||
|
||||
/*
|
||||
* PHY configuration in xemac_phy.c
|
||||
*/
|
||||
XStatus XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 * PhyDataPtr);
|
||||
XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 PhyData);
|
||||
|
||||
/*
|
||||
* Statistics in xemac_stats.c
|
||||
*/
|
||||
void XEmac_GetStats(XEmac * InstancePtr, XEmac_Stats * StatsPtr);
|
||||
void XEmac_ClearStats(XEmac * InstancePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
60
board/xilinx/xilinx_enet/xemac_g.c
Normal file
60
board/xilinx/xilinx_enet/xemac_g.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by libgen.
|
||||
* Version: Xilinx EDK 6.1.2 EDK_G.14
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xemac.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XEmac_Config XEmac_ConfigTable[] = {
|
||||
{
|
||||
XPAR_OPB_ETHERNET_0_DEVICE_ID,
|
||||
XPAR_OPB_ETHERNET_0_BASEADDR,
|
||||
XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST,
|
||||
XPAR_OPB_ETHERNET_0_DMA_PRESENT,
|
||||
XPAR_OPB_ETHERNET_0_MII_EXIST}
|
||||
};
|
||||
207
board/xilinx/xilinx_enet/xemac_i.h
Normal file
207
board/xilinx/xilinx_enet/xemac_i.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac_i.h
|
||||
*
|
||||
* This header file contains internal identifiers, which are those shared
|
||||
* between XEmac components. The identifiers in this file are not intended for
|
||||
* use external to the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00b rpm 04/29/02 Moved register definitions to xemac_l.h
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_I_H /* prevent circular inclusions */
|
||||
#define XEMAC_I_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemac.h"
|
||||
#include "xemac_l.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Default buffer descriptor control word masks. The default send BD control
|
||||
* is set for incrementing the source address by one for each byte transferred,
|
||||
* and specify that the destination address (FIFO) is local to the device. The
|
||||
* default receive BD control is set for incrementing the destination address
|
||||
* by one for each byte transferred, and specify that the source address is
|
||||
* local to the device.
|
||||
*/
|
||||
#define XEM_DFT_SEND_BD_MASK (XDC_DMACR_SOURCE_INCR_MASK | \
|
||||
XDC_DMACR_DEST_LOCAL_MASK)
|
||||
#define XEM_DFT_RECV_BD_MASK (XDC_DMACR_DEST_INCR_MASK | \
|
||||
XDC_DMACR_SOURCE_LOCAL_MASK)
|
||||
|
||||
/*
|
||||
* Masks for the IPIF Device Interrupt enable and status registers.
|
||||
*/
|
||||
#define XEM_IPIF_EMAC_MASK 0x00000004UL /* MAC interrupt */
|
||||
#define XEM_IPIF_SEND_DMA_MASK 0x00000008UL /* Send DMA interrupt */
|
||||
#define XEM_IPIF_RECV_DMA_MASK 0x00000010UL /* Receive DMA interrupt */
|
||||
#define XEM_IPIF_RECV_FIFO_MASK 0x00000020UL /* Receive FIFO interrupt */
|
||||
#define XEM_IPIF_SEND_FIFO_MASK 0x00000040UL /* Send FIFO interrupt */
|
||||
|
||||
/*
|
||||
* Default IPIF Device Interrupt mask when configured for DMA
|
||||
*/
|
||||
#define XEM_IPIF_DMA_DFT_MASK (XEM_IPIF_SEND_DMA_MASK | \
|
||||
XEM_IPIF_RECV_DMA_MASK | \
|
||||
XEM_IPIF_EMAC_MASK | \
|
||||
XEM_IPIF_SEND_FIFO_MASK | \
|
||||
XEM_IPIF_RECV_FIFO_MASK)
|
||||
|
||||
/*
|
||||
* Default IPIF Device Interrupt mask when configured without DMA
|
||||
*/
|
||||
#define XEM_IPIF_FIFO_DFT_MASK (XEM_IPIF_EMAC_MASK | \
|
||||
XEM_IPIF_SEND_FIFO_MASK | \
|
||||
XEM_IPIF_RECV_FIFO_MASK)
|
||||
|
||||
#define XEM_IPIF_DMA_DEV_INTR_COUNT 7 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_FIFO_DEV_INTR_COUNT 5 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_DEVICE_INTR_COUNT 7 /* Number of interrupt sources */
|
||||
#define XEM_IPIF_IP_INTR_COUNT 22 /* Number of MAC interrupts */
|
||||
|
||||
/* a mask for all transmit interrupts, used in polled mode */
|
||||
#define XEM_EIR_XMIT_ALL_MASK (XEM_EIR_XMIT_DONE_MASK | \
|
||||
XEM_EIR_XMIT_ERROR_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_EMPTY_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_FULL_MASK)
|
||||
|
||||
/* a mask for all receive interrupts, used in polled mode */
|
||||
#define XEM_EIR_RECV_ALL_MASK (XEM_EIR_RECV_DONE_MASK | \
|
||||
XEM_EIR_RECV_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_EMPTY_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_MISSED_FRAME_MASK | \
|
||||
XEM_EIR_RECV_COLLISION_MASK | \
|
||||
XEM_EIR_RECV_FCS_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LEN_ERROR_MASK | \
|
||||
XEM_EIR_RECV_SHORT_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LONG_ERROR_MASK | \
|
||||
XEM_EIR_RECV_ALIGN_ERROR_MASK)
|
||||
|
||||
/* a default interrupt mask for scatter-gather DMA operation */
|
||||
#define XEM_EIR_DFT_SG_MASK (XEM_EIR_RECV_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_OVER_MASK | \
|
||||
XEM_EIR_XMIT_SFIFO_UNDER_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK | \
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK | \
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK | \
|
||||
XEM_EIR_RECV_MISSED_FRAME_MASK | \
|
||||
XEM_EIR_RECV_COLLISION_MASK | \
|
||||
XEM_EIR_RECV_FCS_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LEN_ERROR_MASK | \
|
||||
XEM_EIR_RECV_SHORT_ERROR_MASK | \
|
||||
XEM_EIR_RECV_LONG_ERROR_MASK | \
|
||||
XEM_EIR_RECV_ALIGN_ERROR_MASK)
|
||||
|
||||
/* a default interrupt mask for non-DMA operation (direct FIFOs) */
|
||||
#define XEM_EIR_DFT_FIFO_MASK (XEM_EIR_XMIT_DONE_MASK | \
|
||||
XEM_EIR_RECV_DONE_MASK | \
|
||||
XEM_EIR_DFT_SG_MASK)
|
||||
|
||||
/*
|
||||
* Mask for the DMA interrupt enable and status registers when configured
|
||||
* for scatter-gather DMA.
|
||||
*/
|
||||
#define XEM_DMA_SG_INTR_MASK (XDC_IXR_DMA_ERROR_MASK | \
|
||||
XDC_IXR_PKT_THRESHOLD_MASK | \
|
||||
XDC_IXR_PKT_WAIT_BOUND_MASK | \
|
||||
XDC_IXR_SG_END_MASK)
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Clears a structure of given size, in bytes, by setting each byte to 0.
|
||||
*
|
||||
* @param StructPtr is a pointer to the structure to be cleared.
|
||||
* @param NumBytes is the number of bytes in the structure.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XEmac_mClearStruct(u8 *StructPtr, unsigned int NumBytes)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmac_mClearStruct(StructPtr, NumBytes) \
|
||||
{ \
|
||||
int i; \
|
||||
u8 *BytePtr = (u8 *)(StructPtr); \
|
||||
for (i=0; i < (unsigned int)(NumBytes); i++) \
|
||||
{ \
|
||||
*BytePtr++ = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XEmac_Config XEmac_ConfigTable[];
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus);
|
||||
void XEmac_CheckFifoRecvError(XEmac * InstancePtr);
|
||||
void XEmac_CheckFifoSendError(XEmac * InstancePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
402
board/xilinx/xilinx_enet/xemac_intr.c
Normal file
402
board/xilinx/xilinx_enet/xemac_intr.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac_intr.c
|
||||
*
|
||||
* This file contains general interrupt-related functions of the XEmac driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* 1.00c rpm 03/31/03 Added comment to indicate that no Receive Length FIFO
|
||||
* overrun interrupts occur in v1.00l and later of the EMAC
|
||||
* device. This avoids the need to reset the device on
|
||||
* receive overruns.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the callback function for handling asynchronous errors. The upper layer
|
||||
* software should call this function during initialization.
|
||||
*
|
||||
* The error callback is invoked by the driver within interrupt context, so it
|
||||
* needs to do its job quickly. If there are potentially slow operations within
|
||||
* the callback, these should be done at task-level.
|
||||
*
|
||||
* The Xilinx errors that must be handled by the callback are:
|
||||
* - XST_DMA_ERROR indicates an unrecoverable DMA error occurred. This is
|
||||
* typically a bus error or bus timeout. The handler must reset and
|
||||
* re-configure the device.
|
||||
* - XST_FIFO_ERROR indicates an unrecoverable FIFO error occurred. This is a
|
||||
* deadlock condition in the packet FIFO. The handler must reset and
|
||||
* re-configure the device.
|
||||
* - XST_RESET_ERROR indicates an unrecoverable MAC error occurred, usually an
|
||||
* overrun or underrun. The handler must reset and re-configure the device.
|
||||
* - XST_DMA_SG_NO_LIST indicates an attempt was made to access a scatter-gather
|
||||
* DMA list that has not yet been created.
|
||||
* - XST_DMA_SG_LIST_EMPTY indicates the driver tried to get a descriptor from
|
||||
* the receive descriptor list, but the list was empty.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param CallBackRef is a reference pointer to be passed back to the adapter in
|
||||
* the callback. This helps the adapter correlate the callback to a
|
||||
* particular driver.
|
||||
* @param FuncPtr is the pointer to the callback function.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
|
||||
XEmac_ErrorHandler FuncPtr)
|
||||
{
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(FuncPtr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
InstancePtr->ErrorHandler = FuncPtr;
|
||||
InstancePtr->ErrorRef = CallBackRef;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the interrupt status bits of the Ethernet MAC for errors. Errors
|
||||
* currently handled are:
|
||||
* - Receive length FIFO overrun. Indicates data was lost due to the receive
|
||||
* length FIFO becoming full during the reception of a packet. Only a device
|
||||
* reset clears this condition.
|
||||
* - Receive length FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit status FIFO overrun. Indicates data was lost due to the transmit
|
||||
* status FIFO becoming full following the transmission of a packet. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit status FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit length FIFO overrun. Indicates data was lost due to the transmit
|
||||
* length FIFO becoming full following the transmission of a packet. Only a
|
||||
* device reset clears this condition.
|
||||
* - Transmit length FIFO underrun. An attempt to read an empty FIFO. Only a
|
||||
* device reset clears this condition.
|
||||
* - Receive data FIFO overrun. Indicates data was lost due to the receive data
|
||||
* FIFO becoming full during the reception of a packet.
|
||||
* - Receive data errors:
|
||||
* - Receive missed frame error. Valid data was lost by the MAC.
|
||||
* - Receive collision error. Data was lost by the MAC due to a collision.
|
||||
* - Receive FCS error. Data was dicarded by the MAC due to FCS error.
|
||||
* - Receive length field error. Data was dicarded by the MAC due to an invalid
|
||||
* length field in the packet.
|
||||
* - Receive short error. Data was dicarded by the MAC because a packet was
|
||||
* shorter than allowed.
|
||||
* - Receive long error. Data was dicarded by the MAC because a packet was
|
||||
* longer than allowed.
|
||||
* - Receive alignment error. Data was truncated by the MAC because its length
|
||||
* was not byte-aligned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param IntrStatus is the contents of the interrupt status register to be checked
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus)
|
||||
{
|
||||
u32 ResetError = FALSE;
|
||||
|
||||
/*
|
||||
* First check for receive fifo overrun/underrun errors. Most require a
|
||||
* reset by the user to clear, but the data FIFO overrun error does not.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_DFIFO_OVER_MASK) {
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_OVER_MASK) {
|
||||
/*
|
||||
* Receive Length FIFO overrun interrupts no longer occur in v1.00l
|
||||
* and later of the EMAC device. Frames are just dropped by the EMAC
|
||||
* if the length FIFO is full. The user would notice the Receive Missed
|
||||
* Frame count incrementing without any other errors being reported.
|
||||
* This code is left here for backward compatibility with v1.00k and
|
||||
* older EMAC devices.
|
||||
*/
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE; /* requires a reset */
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
|
||||
InstancePtr->Stats.RecvUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE; /* requires a reset */
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check for general receive errors. Get the latest count where
|
||||
* available, otherwise just bump the statistic so we know the interrupt
|
||||
* occurred.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
|
||||
if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
|
||||
/*
|
||||
* Caused by length FIFO or data FIFO overruns on receive side
|
||||
*/
|
||||
InstancePtr->Stats.RecvMissedFrameErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RMFC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
|
||||
InstancePtr->Stats.RecvCollisionErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvFcsErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RFCSEC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLengthFieldErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvShortErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLongErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvAlignmentErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RAEC_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bump recv interrupts stats only if not scatter-gather DMA (this
|
||||
* stat gets bumped elsewhere in that case)
|
||||
*/
|
||||
if (!XEmac_mIsSgDma(InstancePtr)) {
|
||||
InstancePtr->Stats.RecvInterrupts++; /* TODO: double bump? */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for transmit errors. These apply to both DMA and non-DMA modes
|
||||
* of operation. The entire device should be reset after overruns or
|
||||
* underruns.
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE;
|
||||
}
|
||||
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
ResetError = TRUE;
|
||||
}
|
||||
|
||||
if (ResetError) {
|
||||
/*
|
||||
* If a reset error occurred, disable the EMAC interrupts since the
|
||||
* reset-causing interrupt(s) is latched in the EMAC - meaning it will
|
||||
* keep occurring until the device is reset. In order to give the higher
|
||||
* layer software time to reset the device, we have to disable the
|
||||
* overrun/underrun interrupts until that happens. We trust that the
|
||||
* higher layer resets the device. We are able to get away with disabling
|
||||
* all EMAC interrupts since the only interrupts it generates are for
|
||||
* error conditions, and we don't care about any more errors right now.
|
||||
*/
|
||||
XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
|
||||
|
||||
/*
|
||||
* Invoke the error handler callback, which should result in a reset
|
||||
* of the device by the upper layer software.
|
||||
*/
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_RESET_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the receive packet FIFO for errors. FIFO error interrupts are:
|
||||
* - Deadlock. See the XPacketFifo component for a description of deadlock on a
|
||||
* FIFO.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Although the function returns void, it can return an asynchronous error to the
|
||||
* application through the error handler. It can return XST_FIFO_ERROR if a FIFO
|
||||
* error occurred.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckFifoRecvError(XEmac * InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Although the deadlock is currently the only interrupt from a packet
|
||||
* FIFO, make sure it is deadlocked before taking action. There is no
|
||||
* need to clear this interrupt since it requires a reset of the device.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
|
||||
u32 IntrEnable;
|
||||
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
|
||||
/*
|
||||
* Invoke the error callback function, which should result in a reset
|
||||
* of the device by the upper layer software. We first need to disable
|
||||
* the FIFO interrupt, since otherwise the upper layer thread that
|
||||
* handles the reset may never run because this interrupt condition
|
||||
* doesn't go away until a reset occurs (there is no way to ack it).
|
||||
*/
|
||||
IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
IntrEnable & ~XEM_IPIF_RECV_FIFO_MASK);
|
||||
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_FIFO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Check the send packet FIFO for errors. FIFO error interrupts are:
|
||||
* - Deadlock. See the XPacketFifo component for a description of deadlock on a
|
||||
* FIFO.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Although the function returns void, it can return an asynchronous error to the
|
||||
* application through the error handler. It can return XST_FIFO_ERROR if a FIFO
|
||||
* error occurred.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is intended for internal use only.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_CheckFifoSendError(XEmac * InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Although the deadlock is currently the only interrupt from a packet
|
||||
* FIFO, make sure it is deadlocked before taking action. There is no
|
||||
* need to clear this interrupt since it requires a reset of the device.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
|
||||
u32 IntrEnable;
|
||||
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
|
||||
/*
|
||||
* Invoke the error callback function, which should result in a reset
|
||||
* of the device by the upper layer software. We first need to disable
|
||||
* the FIFO interrupt, since otherwise the upper layer thread that
|
||||
* handles the reset may never run because this interrupt condition
|
||||
* doesn't go away until a reset occurs (there is no way to ack it).
|
||||
*/
|
||||
IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
|
||||
IntrEnable & ~XEM_IPIF_SEND_FIFO_MASK);
|
||||
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XST_FIFO_ERROR);
|
||||
}
|
||||
}
|
||||
1344
board/xilinx/xilinx_enet/xemac_intr_dma.c
Normal file
1344
board/xilinx/xilinx_enet/xemac_intr_dma.c
Normal file
File diff suppressed because it is too large
Load Diff
462
board/xilinx/xilinx_enet/xemac_l.h
Normal file
462
board/xilinx/xilinx_enet/xemac_l.h
Normal file
@@ -0,0 +1,462 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac_l.h
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
* macros) that can be used to access the device. High-level driver functions
|
||||
* are defined in xemac.h.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00b rpm 04/26/02 First release
|
||||
* 1.00b rmm 09/23/02 Added XEmac_mPhyReset macro
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMAC_L_H /* prevent circular inclusions */
|
||||
#define XEMAC_L_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xio.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/* Offset of the MAC registers from the IPIF base address */
|
||||
#define XEM_REG_OFFSET 0x1100UL
|
||||
|
||||
/*
|
||||
* Register offsets for the Ethernet MAC. Each register is 32 bits.
|
||||
*/
|
||||
#define XEM_EMIR_OFFSET (XEM_REG_OFFSET + 0x0) /* EMAC Module ID */
|
||||
#define XEM_ECR_OFFSET (XEM_REG_OFFSET + 0x4) /* MAC Control */
|
||||
#define XEM_IFGP_OFFSET (XEM_REG_OFFSET + 0x8) /* Interframe Gap */
|
||||
#define XEM_SAH_OFFSET (XEM_REG_OFFSET + 0xC) /* Station addr, high */
|
||||
#define XEM_SAL_OFFSET (XEM_REG_OFFSET + 0x10) /* Station addr, low */
|
||||
#define XEM_MGTCR_OFFSET (XEM_REG_OFFSET + 0x14) /* MII mgmt control */
|
||||
#define XEM_MGTDR_OFFSET (XEM_REG_OFFSET + 0x18) /* MII mgmt data */
|
||||
#define XEM_RPLR_OFFSET (XEM_REG_OFFSET + 0x1C) /* Rx packet length */
|
||||
#define XEM_TPLR_OFFSET (XEM_REG_OFFSET + 0x20) /* Tx packet length */
|
||||
#define XEM_TSR_OFFSET (XEM_REG_OFFSET + 0x24) /* Tx status */
|
||||
#define XEM_RMFC_OFFSET (XEM_REG_OFFSET + 0x28) /* Rx missed frames */
|
||||
#define XEM_RCC_OFFSET (XEM_REG_OFFSET + 0x2C) /* Rx collisions */
|
||||
#define XEM_RFCSEC_OFFSET (XEM_REG_OFFSET + 0x30) /* Rx FCS errors */
|
||||
#define XEM_RAEC_OFFSET (XEM_REG_OFFSET + 0x34) /* Rx alignment errors */
|
||||
#define XEM_TEDC_OFFSET (XEM_REG_OFFSET + 0x38) /* Transmit excess
|
||||
* deferral cnt */
|
||||
|
||||
/*
|
||||
* Register offsets for the IPIF components
|
||||
*/
|
||||
#define XEM_ISR_OFFSET 0x20UL /* Interrupt status */
|
||||
|
||||
#define XEM_DMA_OFFSET 0x2300UL
|
||||
#define XEM_DMA_SEND_OFFSET (XEM_DMA_OFFSET + 0x0) /* DMA send channel */
|
||||
#define XEM_DMA_RECV_OFFSET (XEM_DMA_OFFSET + 0x40) /* DMA recv channel */
|
||||
|
||||
#define XEM_PFIFO_OFFSET 0x2000UL
|
||||
#define XEM_PFIFO_TXREG_OFFSET (XEM_PFIFO_OFFSET + 0x0) /* Tx registers */
|
||||
#define XEM_PFIFO_RXREG_OFFSET (XEM_PFIFO_OFFSET + 0x10) /* Rx registers */
|
||||
#define XEM_PFIFO_TXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x100) /* Tx keyhole */
|
||||
#define XEM_PFIFO_RXDATA_OFFSET (XEM_PFIFO_OFFSET + 0x200) /* Rx keyhole */
|
||||
|
||||
/*
|
||||
* EMAC Module Identification Register (EMIR)
|
||||
*/
|
||||
#define XEM_EMIR_VERSION_MASK 0xFFFF0000UL /* Device version */
|
||||
#define XEM_EMIR_TYPE_MASK 0x0000FF00UL /* Device type */
|
||||
|
||||
/*
|
||||
* EMAC Control Register (ECR)
|
||||
*/
|
||||
#define XEM_ECR_FULL_DUPLEX_MASK 0x80000000UL /* Full duplex mode */
|
||||
#define XEM_ECR_XMIT_RESET_MASK 0x40000000UL /* Reset transmitter */
|
||||
#define XEM_ECR_XMIT_ENABLE_MASK 0x20000000UL /* Enable transmitter */
|
||||
#define XEM_ECR_RECV_RESET_MASK 0x10000000UL /* Reset receiver */
|
||||
#define XEM_ECR_RECV_ENABLE_MASK 0x08000000UL /* Enable receiver */
|
||||
#define XEM_ECR_PHY_ENABLE_MASK 0x04000000UL /* Enable PHY */
|
||||
#define XEM_ECR_XMIT_PAD_ENABLE_MASK 0x02000000UL /* Enable xmit pad insert */
|
||||
#define XEM_ECR_XMIT_FCS_ENABLE_MASK 0x01000000UL /* Enable xmit FCS insert */
|
||||
#define XEM_ECR_XMIT_ADDR_INSERT_MASK 0x00800000UL /* Enable xmit source addr
|
||||
* insertion */
|
||||
#define XEM_ECR_XMIT_ERROR_INSERT_MASK 0x00400000UL /* Insert xmit error */
|
||||
#define XEM_ECR_XMIT_ADDR_OVWRT_MASK 0x00200000UL /* Enable xmit source addr
|
||||
* overwrite */
|
||||
#define XEM_ECR_LOOPBACK_MASK 0x00100000UL /* Enable internal
|
||||
* loopback */
|
||||
#define XEM_ECR_RECV_STRIP_ENABLE_MASK 0x00080000UL /* Enable recv pad/fcs strip */
|
||||
#define XEM_ECR_UNICAST_ENABLE_MASK 0x00020000UL /* Enable unicast addr */
|
||||
#define XEM_ECR_MULTI_ENABLE_MASK 0x00010000UL /* Enable multicast addr */
|
||||
#define XEM_ECR_BROAD_ENABLE_MASK 0x00008000UL /* Enable broadcast addr */
|
||||
#define XEM_ECR_PROMISC_ENABLE_MASK 0x00004000UL /* Enable promiscuous mode */
|
||||
#define XEM_ECR_RECV_ALL_MASK 0x00002000UL /* Receive all frames */
|
||||
#define XEM_ECR_RESERVED2_MASK 0x00001000UL /* Reserved */
|
||||
#define XEM_ECR_MULTI_HASH_ENABLE_MASK 0x00000800UL /* Enable multicast hash */
|
||||
#define XEM_ECR_PAUSE_FRAME_MASK 0x00000400UL /* Interpret pause frames */
|
||||
#define XEM_ECR_CLEAR_HASH_MASK 0x00000200UL /* Clear hash table */
|
||||
#define XEM_ECR_ADD_HASH_ADDR_MASK 0x00000100UL /* Add hash table address */
|
||||
|
||||
/*
|
||||
* Interframe Gap Register (IFGR)
|
||||
*/
|
||||
#define XEM_IFGP_PART1_MASK 0xF8000000UL /* Interframe Gap Part1 */
|
||||
#define XEM_IFGP_PART1_SHIFT 27
|
||||
#define XEM_IFGP_PART2_MASK 0x07C00000UL /* Interframe Gap Part2 */
|
||||
#define XEM_IFGP_PART2_SHIFT 22
|
||||
|
||||
/*
|
||||
* Station Address High Register (SAH)
|
||||
*/
|
||||
#define XEM_SAH_ADDR_MASK 0x0000FFFFUL /* Station address high bytes */
|
||||
|
||||
/*
|
||||
* Station Address Low Register (SAL)
|
||||
*/
|
||||
#define XEM_SAL_ADDR_MASK 0xFFFFFFFFUL /* Station address low bytes */
|
||||
|
||||
/*
|
||||
* MII Management Control Register (MGTCR)
|
||||
*/
|
||||
#define XEM_MGTCR_START_MASK 0x80000000UL /* Start/Busy */
|
||||
#define XEM_MGTCR_RW_NOT_MASK 0x40000000UL /* Read/Write Not (direction) */
|
||||
#define XEM_MGTCR_PHY_ADDR_MASK 0x3E000000UL /* PHY address */
|
||||
#define XEM_MGTCR_PHY_ADDR_SHIFT 25 /* PHY address shift */
|
||||
#define XEM_MGTCR_REG_ADDR_MASK 0x01F00000UL /* Register address */
|
||||
#define XEM_MGTCR_REG_ADDR_SHIFT 20 /* Register addr shift */
|
||||
#define XEM_MGTCR_MII_ENABLE_MASK 0x00080000UL /* Enable MII from EMAC */
|
||||
#define XEM_MGTCR_RD_ERROR_MASK 0x00040000UL /* MII mgmt read error */
|
||||
|
||||
/*
|
||||
* MII Management Data Register (MGTDR)
|
||||
*/
|
||||
#define XEM_MGTDR_DATA_MASK 0x0000FFFFUL /* MII data */
|
||||
|
||||
/*
|
||||
* Receive Packet Length Register (RPLR)
|
||||
*/
|
||||
#define XEM_RPLR_LENGTH_MASK 0x0000FFFFUL /* Receive packet length */
|
||||
|
||||
/*
|
||||
* Transmit Packet Length Register (TPLR)
|
||||
*/
|
||||
#define XEM_TPLR_LENGTH_MASK 0x0000FFFFUL /* Transmit packet length */
|
||||
|
||||
/*
|
||||
* Transmit Status Register (TSR)
|
||||
*/
|
||||
#define XEM_TSR_EXCESS_DEFERRAL_MASK 0x80000000UL /* Transmit excess deferral */
|
||||
#define XEM_TSR_FIFO_UNDERRUN_MASK 0x40000000UL /* Packet FIFO underrun */
|
||||
#define XEM_TSR_ATTEMPTS_MASK 0x3E000000UL /* Transmission attempts */
|
||||
#define XEM_TSR_LATE_COLLISION_MASK 0x01000000UL /* Transmit late collision */
|
||||
|
||||
/*
|
||||
* Receive Missed Frame Count (RMFC)
|
||||
*/
|
||||
#define XEM_RMFC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive Collision Count (RCC)
|
||||
*/
|
||||
#define XEM_RCC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive FCS Error Count (RFCSEC)
|
||||
*/
|
||||
#define XEM_RFCSEC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Receive Alignment Error Count (RALN)
|
||||
*/
|
||||
#define XEM_RAEC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* Transmit Excess Deferral Count (TEDC)
|
||||
*/
|
||||
#define XEM_TEDC_DATA_MASK 0x0000FFFFUL
|
||||
|
||||
/*
|
||||
* EMAC Interrupt Registers (Status and Enable) masks. These registers are
|
||||
* part of the IPIF IP Interrupt registers
|
||||
*/
|
||||
#define XEM_EIR_XMIT_DONE_MASK 0x00000001UL /* Xmit complete */
|
||||
#define XEM_EIR_RECV_DONE_MASK 0x00000002UL /* Recv complete */
|
||||
#define XEM_EIR_XMIT_ERROR_MASK 0x00000004UL /* Xmit error */
|
||||
#define XEM_EIR_RECV_ERROR_MASK 0x00000008UL /* Recv error */
|
||||
#define XEM_EIR_XMIT_SFIFO_EMPTY_MASK 0x00000010UL /* Xmit status fifo empty */
|
||||
#define XEM_EIR_RECV_LFIFO_EMPTY_MASK 0x00000020UL /* Recv length fifo empty */
|
||||
#define XEM_EIR_XMIT_LFIFO_FULL_MASK 0x00000040UL /* Xmit length fifo full */
|
||||
#define XEM_EIR_RECV_LFIFO_OVER_MASK 0x00000080UL /* Recv length fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_RECV_LFIFO_UNDER_MASK 0x00000100UL /* Recv length fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_SFIFO_OVER_MASK 0x00000200UL /* Xmit status fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_XMIT_SFIFO_UNDER_MASK 0x00000400UL /* Transmit status fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_LFIFO_OVER_MASK 0x00000800UL /* Transmit length fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_XMIT_LFIFO_UNDER_MASK 0x00001000UL /* Transmit length fifo
|
||||
* underrun */
|
||||
#define XEM_EIR_XMIT_PAUSE_MASK 0x00002000UL /* Transmit pause pkt
|
||||
* received */
|
||||
#define XEM_EIR_RECV_DFIFO_OVER_MASK 0x00004000UL /* Receive data fifo
|
||||
* overrun */
|
||||
#define XEM_EIR_RECV_MISSED_FRAME_MASK 0x00008000UL /* Receive missed frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_COLLISION_MASK 0x00010000UL /* Receive collision
|
||||
* error */
|
||||
#define XEM_EIR_RECV_FCS_ERROR_MASK 0x00020000UL /* Receive FCS error */
|
||||
#define XEM_EIR_RECV_LEN_ERROR_MASK 0x00040000UL /* Receive length field
|
||||
* error */
|
||||
#define XEM_EIR_RECV_SHORT_ERROR_MASK 0x00080000UL /* Receive short frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_LONG_ERROR_MASK 0x00100000UL /* Receive long frame
|
||||
* error */
|
||||
#define XEM_EIR_RECV_ALIGN_ERROR_MASK 0x00200000UL /* Receive alignment
|
||||
* error */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Low-level driver macros and functions. The list below provides signatures
|
||||
* to help the user use the macros.
|
||||
*
|
||||
* u32 XEmac_mReadReg(u32 BaseAddress, int RegOffset)
|
||||
* void XEmac_mWriteReg(u32 BaseAddress, int RegOffset, u32 Mask)
|
||||
*
|
||||
* void XEmac_mSetControlReg(u32 BaseAddress, u32 Mask)
|
||||
* void XEmac_mSetMacAddress(u32 BaseAddress, u8 *AddressPtr)
|
||||
*
|
||||
* void XEmac_mEnable(u32 BaseAddress)
|
||||
* void XEmac_mDisable(u32 BaseAddress)
|
||||
*
|
||||
* u32 XEmac_mIsTxDone(u32 BaseAddress)
|
||||
* u32 XEmac_mIsRxEmpty(u32 BaseAddress)
|
||||
*
|
||||
* void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size)
|
||||
* int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mReadReg(BaseAddress, RegOffset) \
|
||||
XIo_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mWriteReg(BaseAddress, RegOffset, Data) \
|
||||
XIo_Out32((BaseAddress) + (RegOffset), (Data))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the contents of the control register. Use the XEM_ECR_* constants
|
||||
* defined above to create the bit-mask to be written to the register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param Mask is the 16-bit value to write to the control register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mSetControlReg(BaseAddress, Mask) \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, (Mask))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the station address of the EMAC device.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param AddressPtr is a pointer to a 6-byte MAC address
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mSetMacAddress(BaseAddress, AddressPtr) \
|
||||
{ \
|
||||
u32 MacAddr; \
|
||||
\
|
||||
MacAddr = ((AddressPtr)[0] << 8) | (AddressPtr)[1]; \
|
||||
XIo_Out32((BaseAddress) + XEM_SAH_OFFSET, MacAddr); \
|
||||
\
|
||||
MacAddr = ((AddressPtr)[2] << 24) | ((AddressPtr)[3] << 16) | \
|
||||
((AddressPtr)[4] << 8) | (AddressPtr)[5]; \
|
||||
\
|
||||
XIo_Out32((BaseAddress) + XEM_SAL_OFFSET, MacAddr); \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable the transmitter and receiver. Preserve the contents of the control
|
||||
* register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mEnable(BaseAddress) \
|
||||
{ \
|
||||
u32 Control; \
|
||||
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
|
||||
Control &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK); \
|
||||
Control |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable the transmitter and receiver. Preserve the contents of the control
|
||||
* register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mDisable(BaseAddress) \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, \
|
||||
XIo_In32((BaseAddress) + XEM_ECR_OFFSET) & \
|
||||
~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Check to see if the transmission is complete.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return TRUE if it is done, or FALSE if it is not.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mIsTxDone(BaseAddress) \
|
||||
(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_XMIT_DONE_MASK)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Check to see if the receive FIFO is empty.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return TRUE if it is empty, or FALSE if it is not.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mIsRxEmpty(BaseAddress) \
|
||||
(!(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_RECV_DONE_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Reset MII compliant PHY
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmac_mPhyReset(BaseAddress) \
|
||||
{ \
|
||||
u32 Control; \
|
||||
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
|
||||
Control &= ~XEM_ECR_PHY_ENABLE_MASK; \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
Control |= XEM_ECR_PHY_ENABLE_MASK; \
|
||||
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XEmac_SendFrame(u32 BaseAddress, u8 * FramePtr, int Size);
|
||||
int XEmac_RecvFrame(u32 BaseAddress, u8 * FramePtr);
|
||||
|
||||
#endif /* end of protection macro */
|
||||
318
board/xilinx/xilinx_enet/xemac_options.c
Normal file
318
board/xilinx/xilinx_enet/xemac_options.c
Normal file
@@ -0,0 +1,318 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac_options.c
|
||||
*
|
||||
* Functions in this file handle configuration of the XEmac driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define XEM_MAX_IFG 32 /* Maximum Interframe gap value */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* A table of options and masks. This table maps the user-visible options with
|
||||
* the control register masks. It is used in Set/GetOptions as an alternative
|
||||
* to a series of if/else pairs. Note that the polled options does not have a
|
||||
* corresponding entry in the control register, so it does not exist in the
|
||||
* table.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Option;
|
||||
u32 Mask;
|
||||
} OptionMap;
|
||||
|
||||
static OptionMap OptionsTable[] = {
|
||||
{XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK},
|
||||
{XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK},
|
||||
{XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK},
|
||||
{XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK},
|
||||
{XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK},
|
||||
{XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK},
|
||||
{XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK},
|
||||
{XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK},
|
||||
{XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK},
|
||||
{XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK},
|
||||
{XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK},
|
||||
{XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK}
|
||||
};
|
||||
|
||||
#define XEM_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionMap))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set Ethernet driver/device options. The device must be stopped before
|
||||
* calling this function. The options are contained within a bit-mask with each
|
||||
* bit representing an option (i.e., you can OR the options together). A one (1)
|
||||
* in the bit-mask turns an option on, and a zero (0) turns the option off.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param OptionsFlag is a bit-mask representing the Ethernet options to turn on
|
||||
* or off. See xemac.h for a description of the available options.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the options were set successfully
|
||||
* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This function is not thread-safe and makes use of internal resources that are
|
||||
* shared between the Start, Stop, and SetOptions functions, so if one task
|
||||
* might be setting device options while another is trying to start the device,
|
||||
* protection of this shared data (typically using a semaphore) is required.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag)
|
||||
{
|
||||
u32 ControlReg;
|
||||
int Index;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
|
||||
/*
|
||||
* Loop through the options table, turning the option on or off
|
||||
* depending on whether the bit is set in the incoming options flag.
|
||||
*/
|
||||
for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
|
||||
if (OptionsFlag & OptionsTable[Index].Option) {
|
||||
ControlReg |= OptionsTable[Index].Mask; /* turn it on */
|
||||
} else {
|
||||
ControlReg &= ~OptionsTable[Index].Mask; /* turn it off */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: need to validate addr-overwrite only if addr-insert?
|
||||
*/
|
||||
|
||||
/*
|
||||
* Now write the control register. Leave it to the upper layers
|
||||
* to restart the device.
|
||||
*/
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
|
||||
|
||||
/*
|
||||
* Check the polled option
|
||||
*/
|
||||
if (OptionsFlag & XEM_POLLED_OPTION) {
|
||||
InstancePtr->IsPolled = TRUE;
|
||||
} else {
|
||||
InstancePtr->IsPolled = FALSE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get Ethernet driver/device options. The 32-bit value returned is a bit-mask
|
||||
* representing the options. A one (1) in the bit-mask means the option is on,
|
||||
* and a zero (0) means the option is off.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The 32-bit value of the Ethernet options. The value is a bit-mask
|
||||
* representing all options that are currently enabled. See xemac.h for a
|
||||
* description of the available options.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32
|
||||
XEmac_GetOptions(XEmac * InstancePtr)
|
||||
{
|
||||
u32 OptionsFlag = 0;
|
||||
u32 ControlReg;
|
||||
int Index;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Get the control register to determine which options are currently set.
|
||||
*/
|
||||
ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
|
||||
|
||||
/*
|
||||
* Loop through the options table to determine which options are set
|
||||
*/
|
||||
for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
|
||||
if (ControlReg & OptionsTable[Index].Mask) {
|
||||
OptionsFlag |= OptionsTable[Index].Option;
|
||||
}
|
||||
}
|
||||
|
||||
if (InstancePtr->IsPolled) {
|
||||
OptionsFlag |= XEM_POLLED_OPTION;
|
||||
}
|
||||
|
||||
return OptionsFlag;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Set the Interframe Gap (IFG), which is the time the MAC delays between
|
||||
* transmitting frames. There are two parts required. The total interframe gap
|
||||
* is the total of the two parts. The values provided for the Part1 and Part2
|
||||
* parameters are multiplied by 4 to obtain the bit-time interval. The first
|
||||
* part should be the first 2/3 of the total interframe gap. The MAC will reset
|
||||
* the interframe gap timer if carrier sense becomes true during the period
|
||||
* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
|
||||
* can be as small as zero. The second part should be the last 1/3 of the total
|
||||
* interframe gap, but can be as large as the total interframe gap. The MAC
|
||||
* will not reset the interframe gap timer if carrier sense becomes true during
|
||||
* the period defined by interframe gap Part2.
|
||||
*
|
||||
* The device must be stopped before setting the interframe gap.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
|
||||
* get the bit-time interval).
|
||||
* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
|
||||
* get the bit-time interval).
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the interframe gap was set successfully
|
||||
* - XST_DEVICE_IS_STARTED if the device has not been stopped
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
|
||||
{
|
||||
u32 Ifg;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(Part1 < XEM_MAX_IFG);
|
||||
XASSERT_NONVOID(Part2 < XEM_MAX_IFG);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Be sure device has been stopped
|
||||
*/
|
||||
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STARTED;
|
||||
}
|
||||
|
||||
Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
|
||||
Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the interframe gap, parts 1 and 2. See the description of interframe gap
|
||||
* above in XEmac_SetInterframeGap().
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap
|
||||
* part 1 value will be copied.
|
||||
* @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap
|
||||
* part 2 value will be copied.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None. The values of the interframe gap parts are copied into the
|
||||
* output parameters.
|
||||
*
|
||||
******************************************************************************/
|
||||
void
|
||||
XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr)
|
||||
{
|
||||
u32 Ifg;
|
||||
|
||||
XASSERT_VOID(InstancePtr != NULL);
|
||||
XASSERT_VOID(Part1Ptr != NULL);
|
||||
XASSERT_VOID(Part2Ptr != NULL);
|
||||
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
|
||||
*Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT;
|
||||
*Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT;
|
||||
}
|
||||
482
board/xilinx/xilinx_enet/xemac_polled.c
Normal file
482
board/xilinx/xilinx_enet/xemac_polled.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Author: Xilinx, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
|
||||
* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
|
||||
* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
|
||||
* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
|
||||
* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*
|
||||
* Xilinx hardware products are not intended for use in life support
|
||||
* appliances, devices, or systems. Use in such applications is
|
||||
* expressly prohibited.
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2002-2004 Xilinx Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemac_polled.c
|
||||
*
|
||||
* Contains functions used when the driver is in polled mode. Use the
|
||||
* XEmac_SetOptions() function to put the driver into polled mode.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a rpm 07/31/01 First release
|
||||
* 1.00b rpm 02/20/02 Repartitioned files and functions
|
||||
* 1.00c rpm 12/05/02 New version includes support for simple DMA
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xbasic_types.h"
|
||||
#include "xemac_i.h"
|
||||
#include "xio.h"
|
||||
#include "xipif_v1_23_b.h" /* Uses v1.23b of the IPIF */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Send an Ethernet frame in polled mode. The device/driver must be in polled
|
||||
* mode before calling this function. The driver writes the frame directly to
|
||||
* the MAC's packet FIFO, then enters a loop checking the device status for
|
||||
* completion or error. Statistics are updated if an error occurs. The buffer
|
||||
* to be sent must be word-aligned.
|
||||
*
|
||||
* It is assumed that the upper layer software supplies a correctly formatted
|
||||
* Ethernet frame, including the destination and source addresses, the
|
||||
* type/length field, and the data field. It is also assumed that upper layer
|
||||
* software does not append FCS at the end of the frame.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufPtr is a pointer to a word-aligned buffer containing the Ethernet
|
||||
* frame to be sent.
|
||||
* @param ByteCount is the size of the Ethernet frame.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the frame was sent successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device has not yet been started
|
||||
* - XST_NOT_POLLED if the device is not in polled mode
|
||||
* - XST_FIFO_NO_ROOM if there is no room in the EMAC's length FIFO for this frame
|
||||
* - XST_FIFO_ERROR if the FIFO was overrun or underrun. This error is critical
|
||||
* and requires the caller to reset the device.
|
||||
* - XST_EMAC_COLLISION if the send failed due to excess deferral or late
|
||||
* collision
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* There is the possibility that this function will not return if the hardware
|
||||
* is broken (i.e., it never sets the status bit indicating that transmission is
|
||||
* done). If this is of concern to the user, the user should provide protection
|
||||
* from this problem - perhaps by using a different timer thread to monitor the
|
||||
* PollSend thread. On a 10Mbps MAC, it takes about 1.21 msecs to transmit a
|
||||
* maximum size Ethernet frame (1518 bytes). On a 100Mbps MAC, it takes about
|
||||
* 121 usecs to transmit a maximum size Ethernet frame.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The EMAC uses FIFOs behind its length and status registers. For this reason,
|
||||
* it is important to keep the length, status, and data FIFOs in sync when
|
||||
* reading or writing to them.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount)
|
||||
{
|
||||
u32 IntrStatus;
|
||||
u32 XmitStatus;
|
||||
XStatus Result;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufPtr != NULL);
|
||||
XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE); /* send at least 1 byte */
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Be sure the device is configured for polled mode and it is started
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
return XST_NOT_POLLED;
|
||||
}
|
||||
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for overruns and underruns for the transmit status and length
|
||||
* FIFOs and make sure the send packet FIFO is not deadlocked. Any of these
|
||||
* conditions is bad enough that we do not want to continue. The upper layer
|
||||
* software should reset the device to resolve the error.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
|
||||
/*
|
||||
* Overrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Underrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Before writing to the data FIFO, make sure the length FIFO is not
|
||||
* full. The data FIFO might not be full yet even though the length FIFO
|
||||
* is. This avoids an overrun condition on the length FIFO and keeps the
|
||||
* FIFOs in sync.
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
|
||||
/*
|
||||
* Clear the latched LFIFO_FULL bit so next time around the most
|
||||
* current status is represented
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
XEM_EIR_XMIT_LFIFO_FULL_MASK);
|
||||
return XST_FIFO_NO_ROOM;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a non-blocking write. The packet FIFO returns an error if there
|
||||
* is not enough room in the FIFO for this frame.
|
||||
*/
|
||||
Result =
|
||||
XPacketFifoV100b_Write(&InstancePtr->SendFifo, BufPtr, ByteCount);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop on the MAC's status to wait for any pause to complete.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
|
||||
while ((IntrStatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
/*
|
||||
* Clear the pause status from the transmit status register
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_XMIT_PAUSE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the MAC's transmit packet length register to tell it to transmit
|
||||
*/
|
||||
XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);
|
||||
|
||||
/*
|
||||
* Loop on the MAC's status to wait for the transmit to complete. The
|
||||
* transmit status is in the FIFO when the XMIT_DONE bit is set.
|
||||
*/
|
||||
do {
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
}
|
||||
while ((IntrStatus & XEM_EIR_XMIT_DONE_MASK) == 0);
|
||||
|
||||
XmitStatus = XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET);
|
||||
|
||||
InstancePtr->Stats.XmitFrames++;
|
||||
InstancePtr->Stats.XmitBytes += ByteCount;
|
||||
|
||||
/*
|
||||
* Check for various errors, bump statistics, and return an error status.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Overrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.XmitOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Underrun errors
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
|
||||
XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
|
||||
InstancePtr->Stats.XmitUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the interrupt status register of transmit statuses
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_XMIT_ALL_MASK);
|
||||
|
||||
/*
|
||||
* Collision errors are stored in the transmit status register
|
||||
* instead of the interrupt status register
|
||||
*/
|
||||
if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) {
|
||||
InstancePtr->Stats.XmitExcessDeferral++;
|
||||
return XST_EMAC_COLLISION_ERROR;
|
||||
}
|
||||
|
||||
if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) {
|
||||
InstancePtr->Stats.XmitLateCollisionErrors++;
|
||||
return XST_EMAC_COLLISION_ERROR;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Receive an Ethernet frame in polled mode. The device/driver must be in polled
|
||||
* mode before calling this function. The driver receives the frame directly
|
||||
* from the MAC's packet FIFO. This is a non-blocking receive, in that if there
|
||||
* is no frame ready to be received at the device, the function returns with an
|
||||
* error. The MAC's error status is not checked, so statistics are not updated
|
||||
* for polled receive. The buffer into which the frame will be received must be
|
||||
* word-aligned.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
|
||||
* @param BufPtr is a pointer to a word-aligned buffer into which the received
|
||||
* Ethernet frame will be copied.
|
||||
* @param ByteCountPtr is both an input and an output parameter. It is a pointer
|
||||
* to a 32-bit word that contains the size of the buffer on entry into the
|
||||
* function and the size the received frame on return from the function.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the frame was sent successfully
|
||||
* - XST_DEVICE_IS_STOPPED if the device has not yet been started
|
||||
* - XST_NOT_POLLED if the device is not in polled mode
|
||||
* - XST_NO_DATA if there is no frame to be received from the FIFO
|
||||
* - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for
|
||||
* the frame waiting in the FIFO.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Input buffer must be big enough to hold the largest Ethernet frame. Buffer
|
||||
* must also be 32-bit aligned.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* The EMAC uses FIFOs behind its length and status registers. For this reason,
|
||||
* it is important to keep the length, status, and data FIFOs in sync when
|
||||
* reading or writing to them.
|
||||
*
|
||||
******************************************************************************/
|
||||
XStatus
|
||||
XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr)
|
||||
{
|
||||
XStatus Result;
|
||||
u32 PktLength;
|
||||
u32 IntrStatus;
|
||||
|
||||
XASSERT_NONVOID(InstancePtr != NULL);
|
||||
XASSERT_NONVOID(BufPtr != NULL);
|
||||
XASSERT_NONVOID(ByteCountPtr != NULL);
|
||||
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Be sure the device is configured for polled mode and it is started
|
||||
*/
|
||||
if (!InstancePtr->IsPolled) {
|
||||
return XST_NOT_POLLED;
|
||||
}
|
||||
|
||||
if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
|
||||
return XST_DEVICE_IS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the buffer is big enough to hold the maximum frame size.
|
||||
* We need to do this because as soon as we read the MAC's packet length
|
||||
* register, which is actually a FIFO, we remove that length from the
|
||||
* FIFO. We do not want to read the length FIFO without also reading the
|
||||
* data FIFO since this would get the FIFOs out of sync. So we have to
|
||||
* make this restriction.
|
||||
*/
|
||||
if (*ByteCountPtr < XEM_MAX_FRAME_SIZE) {
|
||||
return XST_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/*
|
||||
* First check for packet FIFO deadlock and return an error if it has
|
||||
* occurred. A reset by the caller is necessary to correct this problem.
|
||||
*/
|
||||
if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
return XST_FIFO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the interrupt status to know what happened (whether an error occurred
|
||||
* and/or whether frames have been received successfully). When clearing the
|
||||
* intr status register, clear only statuses that pertain to receive.
|
||||
*/
|
||||
IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
|
||||
IntrStatus & XEM_EIR_RECV_ALL_MASK);
|
||||
|
||||
/*
|
||||
* Check receive errors and bump statistics so the caller will have a clue
|
||||
* as to why data may not have been received. We continue on if an error
|
||||
* occurred since there still may be frames that were received successfully.
|
||||
*/
|
||||
if (IntrStatus & (XEM_EIR_RECV_LFIFO_OVER_MASK |
|
||||
XEM_EIR_RECV_DFIFO_OVER_MASK)) {
|
||||
InstancePtr->Stats.RecvOverrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
|
||||
InstancePtr->Stats.RecvUnderrunErrors++;
|
||||
InstancePtr->Stats.FifoErrors++;
|
||||
}
|
||||
|
||||
/*
|
||||
* General receive errors
|
||||
*/
|
||||
if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
|
||||
if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
|
||||
InstancePtr->Stats.RecvMissedFrameErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RMFC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
|
||||
InstancePtr->Stats.RecvCollisionErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvFcsErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RFCSEC_OFFSET);
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLengthFieldErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvShortErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvLongErrors++;
|
||||
}
|
||||
|
||||
if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
|
||||
InstancePtr->Stats.RecvAlignmentErrors =
|
||||
XIo_In32(InstancePtr->BaseAddress +
|
||||
XEM_RAEC_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Before reading from the length FIFO, make sure the length FIFO is not
|
||||
* empty. We could cause an underrun error if we try to read from an
|
||||
* empty FIFO.
|
||||
*/
|
||||
if ((IntrStatus & XEM_EIR_RECV_DONE_MASK) == 0) {
|
||||
return XST_NO_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine, from the MAC, the length of the next packet available
|
||||
* in the data FIFO (there should be a non-zero length here)
|
||||
*/
|
||||
PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);
|
||||
if (PktLength == 0) {
|
||||
return XST_NO_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the RECV_DONE bit in the status register to clear it. This bit
|
||||
* indicates the RPLR is non-empty, and we know it's set at this point.
|
||||
* We clear it so that subsequent entry into this routine will reflect the
|
||||
* current status. This is done because the non-empty bit is latched in the
|
||||
* IPIF, which means it may indicate a non-empty condition even though
|
||||
* there is something in the FIFO.
|
||||
*/
|
||||
XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK);
|
||||
|
||||
/*
|
||||
* We assume that the MAC never has a length bigger than the largest
|
||||
* Ethernet frame, so no need to make another check here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a non-blocking read. The FIFO returns an error if there is
|
||||
* not at least the requested amount of data in the FIFO.
|
||||
*/
|
||||
Result =
|
||||
XPacketFifoV100b_Read(&InstancePtr->RecvFifo, BufPtr, PktLength);
|
||||
if (Result != XST_SUCCESS) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
InstancePtr->Stats.RecvFrames++;
|
||||
InstancePtr->Stats.RecvBytes += PktLength;
|
||||
|
||||
*ByteCountPtr = PktLength;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
@@ -22,11 +22,9 @@
|
||||
#
|
||||
|
||||
#
|
||||
# esd ADCIOP boards
|
||||
# XES XPedite1000 PPC440GX
|
||||
#
|
||||
|
||||
#TEXT_BASE = 0xFFFE0000
|
||||
|
||||
ifeq ($(ramsym),1)
|
||||
TEXT_BASE = 0x07FD0000
|
||||
else
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
long int fixed_sdram (void);
|
||||
|
||||
int board_pre_init (void)
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
unsigned long sdrreg;
|
||||
/* TBS: Setup the GPIO access for the user LEDs */
|
||||
@@ -51,6 +51,8 @@ int board_pre_init (void)
|
||||
/* set the bus controller */
|
||||
mtebc (pb0ap, 0x04055200); /* FLASH/SRAM */
|
||||
mtebc (pb0cr, 0xfff18000); /* BAS=0xfff 1MB R/W 8-bit */
|
||||
mtebc (pb1ap, 0x04055200); /* FLASH/SRAM */
|
||||
mtebc (pb1cr, 0xfe098000); /* BAS=0xff8 16MB R/W 8-bit */
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Setup the interrupt controller polarities, triggers, etc.
|
||||
@@ -217,17 +219,18 @@ long int fixed_sdram (void)
|
||||
int pci_pre_init(struct pci_controller * hose )
|
||||
{
|
||||
unsigned long strap;
|
||||
|
||||
/*--------------------------------------------------------------------------+
|
||||
* TBS:
|
||||
* The xpedite1k is a PrPMC board, however for our purposes it is the host
|
||||
*--------------------------------------------------------------------------*/
|
||||
strap = mfdcr(cpc0_strp1);
|
||||
if( (strap & 0x00100000) == 0 ){
|
||||
printf("PCI: CPC0_STRP1[PAE] not set.\n");
|
||||
return 0;
|
||||
/* See if we're supposed to setup the pci */
|
||||
mfsdr(sdr_sdstp1, strap);
|
||||
if ((strap & 0x00010000) == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(CFG_PCI_FORCE_PCI_CONV)
|
||||
/* Setup System Device Register PCIX0_XCR */
|
||||
mfsdr(sdr_xcr, strap);
|
||||
strap &= 0x0f000000;
|
||||
mtsdr(sdr_xcr, strap);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
|
||||
@@ -292,9 +295,7 @@ void pci_target_init(struct pci_controller * hose )
|
||||
#if defined(CONFIG_PCI)
|
||||
int is_pci_host(struct pci_controller *hose)
|
||||
{
|
||||
/* The ebony board is always configured as host. */
|
||||
/* TBS: The xpedite1k is not necessarily the host, however for our purposes, it is. */
|
||||
return(1);
|
||||
return ((in32(CFG_GPIO_BASE + 0x1C) & 0x00000800) == 0);
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) */
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ LIB = libcommon.a
|
||||
AOBJS =
|
||||
|
||||
COBJS = main.o ACEX1K.o altera.o bedbug.o \
|
||||
cmd_autoscript.o \
|
||||
cmd_ace.o cmd_autoscript.o \
|
||||
cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
|
||||
cmd_cache.o cmd_console.o \
|
||||
cmd_date.o cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o \
|
||||
cmd_eeprom.o cmd_elf.o \
|
||||
cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
|
||||
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_jffs2.o \
|
||||
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
|
||||
cmd_load.o cmd_log.o \
|
||||
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
|
||||
cmd_nand.o cmd_net.o cmd_nvedit.o \
|
||||
@@ -44,10 +44,10 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o \
|
||||
environment.o env_common.o \
|
||||
env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
|
||||
flash.o fpga.o \
|
||||
hush.o kgdb.o lists.o lynxkdi.o miiphybb.o miiphyutil.o \
|
||||
hush.o kgdb.o lists.o lynxkdi.o memsize.o miiphybb.o miiphyutil.o \
|
||||
s_record.o soft_i2c.o soft_spi.o spartan2.o \
|
||||
usb.o usb_kbd.o usb_storage.o \
|
||||
virtex2.o xilinx.o memsize.o
|
||||
virtex2.o xilinx.o
|
||||
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
|
||||
198
common/cmd_ace.c
Normal file
198
common/cmd_ace.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Picture Elements, Inc.
|
||||
* Stephen Williams (XXXXXXXXXXXXXXXX)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id:$"
|
||||
|
||||
/*
|
||||
* The Xilinx SystemACE chip support is activated by defining
|
||||
* CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE
|
||||
* to set the base address of the device. This code currently
|
||||
* assumes that the chip is connected via a byte-wide bus.
|
||||
*
|
||||
* The CONFIG_SYSTEMACE also adds to fat support the device class
|
||||
* "ace" that allows the user to execute "fatls ace 0" and the
|
||||
* like. This works by making the systemace_get_dev function
|
||||
* available to cmd_fat.c:get_dev and filling in a block device
|
||||
* description that has all the bits needed for FAT support to
|
||||
* read sectors.
|
||||
*/
|
||||
|
||||
# include <common.h>
|
||||
# include <command.h>
|
||||
# include <systemace.h>
|
||||
# include <part.h>
|
||||
# include <asm/io.h>
|
||||
|
||||
#ifdef CONFIG_SYSTEMACE
|
||||
|
||||
/*
|
||||
* The ace_readw and writew functions read/write 16bit words, but the
|
||||
* offset value is the BYTE offset as most used in the Xilinx
|
||||
* datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined
|
||||
* to be the base address for the chip, usually in the local
|
||||
* peripheral bus.
|
||||
*/
|
||||
static unsigned ace_readw(unsigned offset)
|
||||
{
|
||||
return readw(CFG_SYSTEMACE_BASE+offset);
|
||||
}
|
||||
|
||||
static unsigned ace_writew(unsigned val, unsigned offset)
|
||||
{
|
||||
writew(val, CFG_SYSTEMACE_BASE+offset);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
static unsigned long systemace_read(int dev,
|
||||
unsigned long start,
|
||||
unsigned long blkcnt,
|
||||
unsigned long *buffer);
|
||||
|
||||
static block_dev_desc_t systemace_dev = {0};
|
||||
|
||||
static int get_cf_lock(void)
|
||||
{
|
||||
int retry = 10;
|
||||
|
||||
/* CONTROLREG = LOCKREG */
|
||||
ace_writew(0x0002, 0x18);
|
||||
|
||||
/* Wait for MPULOCK in STATUSREG[15:0] */
|
||||
while (! (ace_readw(0x04) & 0x0002)) {
|
||||
|
||||
if (retry < 0)
|
||||
return -1;
|
||||
|
||||
udelay(100000);
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release_cf_lock(void)
|
||||
{
|
||||
/* CONTROLREG = none */
|
||||
ace_writew(0x0000, 0x18);
|
||||
}
|
||||
|
||||
block_dev_desc_t * systemace_get_dev(int dev)
|
||||
{
|
||||
/* The first time through this, the systemace_dev object is
|
||||
not yet initialized. In that case, fill it in. */
|
||||
if (systemace_dev.blksz == 0) {
|
||||
systemace_dev.if_type = IF_TYPE_UNKNOWN;
|
||||
systemace_dev.part_type = PART_TYPE_UNKNOWN;
|
||||
systemace_dev.type = DEV_TYPE_HARDDISK;
|
||||
systemace_dev.blksz = 512;
|
||||
systemace_dev.removable = 1;
|
||||
systemace_dev.block_read = systemace_read;
|
||||
}
|
||||
|
||||
return &systemace_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called (by dereferencing the block_read pointer in
|
||||
* the dev_desc) to read blocks of data. The return value is the
|
||||
* number of blocks read. A zero return indicates an error.
|
||||
*/
|
||||
static unsigned long systemace_read(int dev,
|
||||
unsigned long start,
|
||||
unsigned long blkcnt,
|
||||
unsigned long *buffer)
|
||||
{
|
||||
unsigned val;
|
||||
int retry;
|
||||
unsigned char*dp = (unsigned char*)buffer;
|
||||
|
||||
if (get_cf_lock() < 0) {
|
||||
unsigned status = ace_readw(0x04);
|
||||
|
||||
/* If CFDETECT is false, card is missing. */
|
||||
if (! (status&0x0010)) {
|
||||
printf("** CompactFlash card not present. **\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("**** ACE locked away from me (STATUSREG=%04x)\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retry = 2000;
|
||||
for (;;) {
|
||||
unsigned val = ace_readw(0x04);
|
||||
|
||||
/* If CFDETECT is false, card is missing. */
|
||||
if (! (val & 0x0010)) {
|
||||
printf("**** ACE CompactFlash not found.\n");
|
||||
release_cf_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If RDYFORCMD, then we are ready to go. */
|
||||
if (val & 0x0100)
|
||||
break;
|
||||
|
||||
if (retry < 0) {
|
||||
printf("**** SystemACE not ready.\n");
|
||||
release_cf_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
/* Write LBA block address */
|
||||
ace_writew(start & 0xffff, 0x10);
|
||||
start >>= 16;
|
||||
ace_writew(start & 0xff, 0x12);
|
||||
|
||||
/* Write sector count | ReadMemCardData. */
|
||||
ace_writew(blkcnt | 0x0300, 0x14);
|
||||
|
||||
/* CONTROLREG = CFGRESET|LOCKREQ */
|
||||
ace_writew(0x0082, 0x18);
|
||||
|
||||
retry = blkcnt * 16;
|
||||
while (retry > 0) {
|
||||
int idx;
|
||||
|
||||
/* Wait for buffer to become ready. */
|
||||
while (! (ace_readw(0x04) & 0x0020)) {
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
/* Read 16 words of 2bytes from the sector buffer. */
|
||||
for (idx = 0 ; idx < 16 ; idx += 1) {
|
||||
unsigned short val = ace_readw(0x40);
|
||||
*dp++ = val & 0xff;
|
||||
*dp++ = (val>>8) & 0xff;
|
||||
}
|
||||
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
release_cf_lock();
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
#endif
|
||||
@@ -59,13 +59,13 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
print_num ("immr_base", bd->bi_immr_base );
|
||||
#endif
|
||||
print_num ("bootflags", bd->bi_bootflags );
|
||||
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP)
|
||||
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
|
||||
print_str ("procfreq", strmhz(buf, bd->bi_procfreq));
|
||||
print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq));
|
||||
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
|
||||
#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
|
||||
print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq));
|
||||
#endif
|
||||
#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP */
|
||||
#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
|
||||
#if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
|
||||
print_str ("vco", strmhz(buf, bd->bi_vco));
|
||||
print_str ("sccfreq", strmhz(buf, bd->bi_sccfreq));
|
||||
@@ -76,7 +76,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
print_str ("cpmfreq", strmhz(buf, bd->bi_cpmfreq));
|
||||
#endif
|
||||
print_str ("busfreq", strmhz(buf, bd->bi_busfreq));
|
||||
#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP */
|
||||
#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
|
||||
printf ("ethaddr =");
|
||||
for (i=0; i<6; ++i) {
|
||||
printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
|
||||
|
||||
@@ -575,10 +575,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
|
||||
kbd->bi_sccfreq /= 1000000L;
|
||||
kbd->bi_vco /= 1000000L;
|
||||
#endif /* CONFIG_8260 */
|
||||
#if defined(CONFIG_MPC5XXX)
|
||||
#if defined(CONFIG_MPC5xxx)
|
||||
kbd->bi_ipbfreq /= 1000000L;
|
||||
kbd->bi_pcifreq /= 1000000L;
|
||||
#endif /* CONFIG_MPC5XXX */
|
||||
#endif /* CONFIG_MPC5xxx */
|
||||
}
|
||||
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep;
|
||||
|
||||
@@ -62,6 +62,12 @@ block_dev_desc_t *get_dev (char* ifname, int dev)
|
||||
extern block_dev_desc_t * mmc_get_dev(int dev);
|
||||
return(mmc_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SYSTEMACE)
|
||||
if (strcmp(ifname,"ace")==0) {
|
||||
extern block_dev_desc_t * systemace_get_dev(int dev);
|
||||
return(systemace_get_dev(dev));
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
200
common/cmd_itest.c
Normal file
200
common/cmd_itest.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Tait Electronics Limited, Christchurch, New Zealand
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file provides a shell like 'test' function to return
|
||||
* true/false from an integer or string compare of two memory
|
||||
* locations or a location and a scalar/literal.
|
||||
* A few parts were lifted from bash 'test' command
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
#include <command.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_ITEST)
|
||||
|
||||
#define EQ 0
|
||||
#define NE 1
|
||||
#define LT 2
|
||||
#define GT 3
|
||||
#define LE 4
|
||||
#define GE 5
|
||||
|
||||
struct op_tbl_s {
|
||||
char *op; /* operator string */
|
||||
int opcode; /* internal representation of opcode */
|
||||
};
|
||||
|
||||
typedef struct op_tbl_s op_tbl_t;
|
||||
|
||||
op_tbl_t op_table [] = {
|
||||
{ "-lt", LT },
|
||||
{ "<" , LT },
|
||||
{ "-gt", GT },
|
||||
{ ">" , GT },
|
||||
{ "-eq", EQ },
|
||||
{ "==" , EQ },
|
||||
{ "-ne", NE },
|
||||
{ "!=" , NE },
|
||||
{ "<>" , NE },
|
||||
{ "-ge", GE },
|
||||
{ ">=" , GE },
|
||||
{ "-le", LE },
|
||||
{ "<=" , LE },
|
||||
};
|
||||
|
||||
#define op_tbl_size (sizeof(op_table)/sizeof(op_table[0]))
|
||||
|
||||
extern int cmd_get_data_size(char* arg, int default_size);
|
||||
|
||||
static long evalexp(char *s, int w)
|
||||
{
|
||||
long l, *p;
|
||||
|
||||
/* if the parameter starts with a * then assume is a pointer to the value we want */
|
||||
if (s[0] == '*') {
|
||||
p = (long *)simple_strtoul(&s[1], NULL, 16);
|
||||
l = *p;
|
||||
} else {
|
||||
l = simple_strtoul(s, NULL, 16);
|
||||
}
|
||||
|
||||
return (l & ((1 << (w * 8)) - 1));
|
||||
}
|
||||
|
||||
static char * evalstr(char *s)
|
||||
{
|
||||
/* if the parameter starts with a * then assume a string pointer else its a literal */
|
||||
if (s[0] == '*') {
|
||||
return (char *)simple_strtoul(&s[1], NULL, 16);
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static int stringcomp(char *s, char *t, int op)
|
||||
{
|
||||
int n, p;
|
||||
char *l, *r;
|
||||
|
||||
l = evalstr(s);
|
||||
r = evalstr(t);
|
||||
|
||||
/* we'll do a compare based on the length of the shortest string */
|
||||
n = min(strlen(l), strlen(r));
|
||||
|
||||
p = strncmp(l, r, n);
|
||||
switch (op) {
|
||||
case EQ: return (p == 0);
|
||||
case NE: return (p != 0);
|
||||
case LT: return (p < 0);
|
||||
case GT: return (p > 0);
|
||||
case LE: return (p <= 0);
|
||||
case GE: return (p >= 0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int arithcomp (char *s, char *t, int op, int w)
|
||||
{
|
||||
long l, r;
|
||||
|
||||
l = evalexp (s, w);
|
||||
r = evalexp (t, w);
|
||||
|
||||
switch (op) {
|
||||
case EQ: return (l == r);
|
||||
case NE: return (l != r);
|
||||
case LT: return (l < r);
|
||||
case GT: return (l > r);
|
||||
case LE: return (l <= r);
|
||||
case GE: return (l >= r);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int binary_test (char *op, char *arg1, char *arg2, int w)
|
||||
{
|
||||
int len, i;
|
||||
op_tbl_t *optp;
|
||||
|
||||
len = strlen(op);
|
||||
|
||||
for (optp = (op_tbl_t *)&op_table, i = 0;
|
||||
i < op_tbl_size;
|
||||
optp++, i++) {
|
||||
|
||||
if ((strncmp (op, optp->op, len) == 0) && (len == strlen (optp->op))) {
|
||||
if (w == 0) {
|
||||
return (stringcomp(arg1, arg2, optp->opcode));
|
||||
} else {
|
||||
return (arithcomp (arg1, arg2, optp->opcode, w));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Unknown operator '%s'\n", op);
|
||||
return 0; /* op code not found */
|
||||
}
|
||||
|
||||
/* command line interface to the shell test */
|
||||
int do_itest ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] )
|
||||
{
|
||||
int value, w;
|
||||
|
||||
/* Validate arguments */
|
||||
if ((argc != 4)){
|
||||
printf("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check for a data width specification.
|
||||
* Defaults to long (4) if no specification.
|
||||
* Uses -2 as 'width' for .s (string) so as not to upset existing code
|
||||
*/
|
||||
switch (w = cmd_get_data_size(argv[0], 4)) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
value = binary_test (argv[2], argv[1], argv[3], w);
|
||||
break;
|
||||
case -2:
|
||||
value = binary_test (argv[2], argv[1], argv[3], 0);
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
puts("Invalid data width specifier\n");
|
||||
value = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return !value;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
itest, 4, 0, do_itest,
|
||||
"itest - return true/false on integer compare\n",
|
||||
"[.b, .w, .l, .s] [*]value1 <op> [*]value2\n"
|
||||
);
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_ITEST */
|
||||
@@ -192,7 +192,7 @@ load_serial (ulong offset)
|
||||
"## Total Size = 0x%08lX = %ld Bytes\n",
|
||||
start_addr, end_addr, size, size
|
||||
);
|
||||
flush_cache (addr, size);
|
||||
flush_cache (start_addr, size);
|
||||
sprintf(buf, "%lX", size);
|
||||
setenv("filesize", buf);
|
||||
return (addr);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | \
|
||||
CFG_CMD_I2C | \
|
||||
CFG_CMD_ITEST | \
|
||||
CFG_CMD_PCI | \
|
||||
CMD_CMD_PORTIO ) )
|
||||
int cmd_get_data_size(char* arg, int default_size)
|
||||
@@ -53,6 +54,8 @@ int cmd_get_data_size(char* arg, int default_size)
|
||||
return 2;
|
||||
case 'l':
|
||||
return 4;
|
||||
case 's':
|
||||
return -2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,19 @@ U_BOOT_CMD(
|
||||
);
|
||||
#endif /* CFG_CMD_DHCP */
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
|
||||
int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
return netboot_common(NFS, cmdtp, argc, argv);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
nfs, 3, 1, do_nfs,
|
||||
"nfs - boot image via network using NFS protocol\n",
|
||||
"[loadAddress] [host ip addr:bootfilename]\n"
|
||||
);
|
||||
#endif /* CFG_CMD_NFS */
|
||||
|
||||
static void netboot_update_env(void)
|
||||
{
|
||||
char tmp[16] ;
|
||||
|
||||
@@ -2173,7 +2173,7 @@ static int set_local_var(const char *s, int flg_export)
|
||||
#ifdef __U_BOOT__
|
||||
if (getenv(name) != NULL) {
|
||||
printf ("ERROR: "
|
||||
"There is a global environmet variable with the same name.\n");
|
||||
"There is a global environment variable with the same name.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
37
common/usb.c
37
common/usb.c
@@ -25,7 +25,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* How it works:
|
||||
*
|
||||
@@ -47,7 +46,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#undef USB_DEBUG
|
||||
/* #define USB_DEBUG */
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#define USB_PRINTF(fmt,args...) printf (fmt ,##args)
|
||||
@@ -55,6 +54,8 @@
|
||||
#define USB_PRINTF(fmt,args...)
|
||||
#endif
|
||||
|
||||
#define USB_BUFSIZ 512
|
||||
|
||||
static struct usb_device usb_dev[USB_MAX_DEVICE];
|
||||
static int dev_index;
|
||||
static int running;
|
||||
@@ -387,6 +388,12 @@ int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cf
|
||||
}
|
||||
tmp=swap_16(config->wTotalLength);
|
||||
|
||||
if (tmp > USB_BUFSIZ) {
|
||||
USB_PRINTF("usb_get_configuration_no: failed to get descriptor - too long: %d\n",
|
||||
tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
|
||||
USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",cfgno,result,tmp);
|
||||
return result;
|
||||
@@ -516,8 +523,7 @@ int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char
|
||||
*/
|
||||
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
||||
{
|
||||
|
||||
unsigned char mybuf[256];
|
||||
unsigned char mybuf[USB_BUFSIZ];
|
||||
unsigned char *tbuf;
|
||||
int err;
|
||||
unsigned int u, idx;
|
||||
@@ -551,6 +557,12 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
||||
return err;
|
||||
u=tbuf[0];
|
||||
USB_PRINTF("Strn Len %d, index %d\n",u,index);
|
||||
|
||||
if (u > USB_BUFSIZ) {
|
||||
USB_PRINTF("usb_string: failed to get string - too long: %d\n", u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = usb_get_string(dev, dev->string_langid, index, tbuf, u);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@@ -619,7 +631,7 @@ int usb_new_device(struct usb_device *dev)
|
||||
{
|
||||
int addr, err;
|
||||
int tmp;
|
||||
unsigned char tmpbuf[256];
|
||||
unsigned char tmpbuf[USB_BUFSIZ];
|
||||
|
||||
dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
|
||||
dev->maxpacketsize = 0; /* Default to 8 byte max packet size */
|
||||
@@ -895,7 +907,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
|
||||
|
||||
int usb_hub_configure(struct usb_device *dev)
|
||||
{
|
||||
unsigned char buffer[256], *bitmap;
|
||||
unsigned char buffer[USB_BUFSIZ], *bitmap;
|
||||
struct usb_hub_descriptor *descriptor;
|
||||
struct usb_hub_status *hubsts;
|
||||
int i;
|
||||
@@ -912,6 +924,13 @@ int usb_hub_configure(struct usb_device *dev)
|
||||
return -1;
|
||||
}
|
||||
descriptor = (struct usb_hub_descriptor *)buffer;
|
||||
|
||||
if (descriptor->bLength > USB_BUFSIZ) {
|
||||
USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor - too long: %d\N",
|
||||
descriptor->bLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) {
|
||||
USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor 2nd giving up %lX\n",dev->status);
|
||||
return -1;
|
||||
@@ -968,6 +987,12 @@ int usb_hub_configure(struct usb_device *dev)
|
||||
for (i = 0; i < dev->maxchild; i++)
|
||||
USB_HUB_PRINTF("port %d is%s removable\n", i + 1,
|
||||
hub->desc.DeviceRemovable[(i + 1)/8] & (1 << ((i + 1)%8)) ? " not" : "");
|
||||
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
|
||||
USB_HUB_PRINTF("usb_hub_configure: failed to get Status - too long: %d\n",
|
||||
descriptor->bLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (usb_get_hub_status(dev, buffer) < 0) {
|
||||
USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",dev->status);
|
||||
return -1;
|
||||
|
||||
@@ -140,19 +140,18 @@ MachineCheckException(struct pt_regs *regs)
|
||||
printf("Machine check in kernel mode.\n");
|
||||
printf("Caused by (from msr): ");
|
||||
printf("regs %p ",regs);
|
||||
switch( regs->msr & 0x0000F000)
|
||||
{
|
||||
case (1<<12) :
|
||||
switch( regs->msr & 0x000F0000) {
|
||||
case (0x80000000>>12):
|
||||
printf("Machine check signal - probably due to mm fault\n"
|
||||
"with mmu off\n");
|
||||
break;
|
||||
case (1<<13) :
|
||||
case (0x80000000>>13):
|
||||
printf("Transfer error ack signal\n");
|
||||
break;
|
||||
case (1<<14) :
|
||||
case (0x80000000>>14):
|
||||
printf("Data parity signal\n");
|
||||
break;
|
||||
case (1<<15) :
|
||||
case (0x80000000>>15):
|
||||
printf("Address parity signal\n");
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
OBJS = serial.o interrupts.o cpu.o
|
||||
OBJS = serial.o serial_netarm.o interrupts.o cpu.o
|
||||
|
||||
all: .depend $(START) $(LIB)
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ int cleanup_before_linux (void)
|
||||
unsigned long i;
|
||||
|
||||
disable_interrupts ();
|
||||
|
||||
#ifdef CONFIG_NETARM
|
||||
return 0;
|
||||
#endif
|
||||
/* turn off I-cache */
|
||||
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
|
||||
i &= ~0x1000;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
@@ -30,14 +30,24 @@
|
||||
#include <clps7111.h>
|
||||
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
#ifdef CONFIG_NETARM
|
||||
#include <asm/arch/netarm_registers.h>
|
||||
#endif
|
||||
|
||||
extern void reset_cpu(ulong addr);
|
||||
|
||||
#ifndef CONFIG_NETARM
|
||||
/* we always count down the max. */
|
||||
#define TIMER_LOAD_VAL 0xffff
|
||||
|
||||
/* macro to read the 16 bit timer */
|
||||
#define READ_TIMER (IO_TC1D & 0xffff)
|
||||
#else
|
||||
#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE))
|
||||
#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL))
|
||||
#define TM2STAT (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_STATUS))
|
||||
#define TIMER_LOAD_VAL NETARM_GEN_TSTAT_CTC_MASK
|
||||
#define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* enable IRQ/FIQ interrupts */
|
||||
@@ -102,15 +112,15 @@ void show_regs (struct pt_regs *regs)
|
||||
|
||||
flags = condition_codes (regs);
|
||||
|
||||
printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
|
||||
"sp : %08lx ip : %08lx fp : %08lx\n",
|
||||
printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
|
||||
"sp : %08lx ip : %08lx fp : %08lx\n",
|
||||
instruction_pointer (regs),
|
||||
regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
|
||||
printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
|
||||
printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
|
||||
regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
|
||||
printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
|
||||
printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
|
||||
regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
|
||||
printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||
printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||
regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
|
||||
printf ("Flags: %c%c%c%c",
|
||||
flags & CC_N_BIT ? 'N' : 'n',
|
||||
@@ -177,6 +187,18 @@ static ulong lastdec;
|
||||
|
||||
int interrupt_init (void)
|
||||
{
|
||||
#ifdef CONFIG_NETARM
|
||||
/* disable all interrupts */
|
||||
IRQEN = 0;
|
||||
|
||||
/* operate timer 2 in non-prescale mode */
|
||||
TM2CTRL = ( NETARM_GEN_TIMER_SET_HZ(CFG_HZ) |
|
||||
NETARM_GEN_TCTL_ENABLE |
|
||||
NETARM_GEN_TCTL_INIT_COUNT(TIMER_LOAD_VAL));
|
||||
|
||||
/* set timer 2 counter */
|
||||
lastdec = TIMER_LOAD_VAL;
|
||||
#else
|
||||
/* disable all interrupts */
|
||||
IO_INTMR1 = 0;
|
||||
|
||||
@@ -188,6 +210,7 @@ int interrupt_init (void)
|
||||
|
||||
/* set timer 1 counter */
|
||||
lastdec = IO_TC1D = TIMER_LOAD_VAL;
|
||||
#endif
|
||||
timestamp = 0;
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <common.h>
|
||||
#include <clps7111.h>
|
||||
|
||||
#ifndef CONFIG_NETARM
|
||||
|
||||
void serial_setbrg (void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@@ -124,3 +126,5 @@ serial_puts (const char *s)
|
||||
serial_putc (*s++);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NETARM */
|
||||
|
||||
185
cpu/arm720t/serial_netarm.c
Normal file
185
cpu/arm720t/serial_netarm.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Serial Port stuff - taken from Linux
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* MAZeT GmbH <www.mazet.de>
|
||||
* Stephan Linz <linz@mazet.de>, <linz@li-pro.net>
|
||||
*
|
||||
* (c) 2004
|
||||
* IMMS gGmbH <www.imms.de>
|
||||
* Thomas Elste <info@elste.org>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/netarm_registers.h>
|
||||
|
||||
#ifdef CONFIG_NETARM
|
||||
|
||||
#define PORTA (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTA))
|
||||
#define PORTB (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTB))
|
||||
|
||||
/* wait until transmitter is ready for another character */
|
||||
#define TXWAITRDY(registers) \
|
||||
{ \
|
||||
ulong tmo = get_timer(0) + 1 * CFG_HZ; \
|
||||
while (((registers)->status_a & NETARM_SER_STATA_TX_RDY) == 0 ) { \
|
||||
if (get_timer(0) > tmo) \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
volatile netarm_serial_channel_t *serial_reg_ch1 = get_serial_channel(0);
|
||||
volatile netarm_serial_channel_t *serial_reg_ch2 = get_serial_channel(1);
|
||||
|
||||
extern void _netarm_led_FAIL1(void);
|
||||
|
||||
/*
|
||||
* Setup both serial i/f with given baudrate
|
||||
*/
|
||||
void serial_setbrg (void)
|
||||
{
|
||||
/* get the gd pointer */
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* set 0 ... make sure pins are configured for serial */
|
||||
PORTA = PORTB =
|
||||
NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0);
|
||||
|
||||
/* first turn em off */
|
||||
serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = 0;
|
||||
|
||||
/* clear match register, we don't need it */
|
||||
serial_reg_ch1->rx_match = serial_reg_ch2->rx_match = 0;
|
||||
|
||||
/* setup bit rate generator and rx buffer gap timer (1 byte only) */
|
||||
if ((gd->baudrate >= MIN_BAUD_RATE)
|
||||
&& (gd->baudrate <= MAX_BAUD_RATE)) {
|
||||
serial_reg_ch1->bitrate = serial_reg_ch2->bitrate =
|
||||
NETARM_SER_BR_X16 (gd->baudrate);
|
||||
serial_reg_ch1->rx_buf_timer = serial_reg_ch2->rx_buf_timer =
|
||||
0;
|
||||
serial_reg_ch1->rx_char_timer = serial_reg_ch2->rx_char_timer =
|
||||
NETARM_SER_RXGAP (gd->baudrate);
|
||||
} else {
|
||||
hang ();
|
||||
}
|
||||
|
||||
/* setup port mode */
|
||||
serial_reg_ch1->ctrl_b = serial_reg_ch2->ctrl_b =
|
||||
( NETARM_SER_CTLB_RCGT_EN |
|
||||
NETARM_SER_CTLB_UART_MODE);
|
||||
serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a =
|
||||
( NETARM_SER_CTLA_ENABLE |
|
||||
NETARM_SER_CTLA_P_NONE |
|
||||
/* see errata */
|
||||
NETARM_SER_CTLA_2STOP |
|
||||
NETARM_SER_CTLA_8BITS |
|
||||
NETARM_SER_CTLA_DTR_EN |
|
||||
NETARM_SER_CTLA_RTS_EN);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialise the serial port with the given baudrate. The settings
|
||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||
*/
|
||||
int serial_init (void)
|
||||
{
|
||||
serial_setbrg ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Output a single byte to the serial port.
|
||||
*/
|
||||
void serial_putc (const char c)
|
||||
{
|
||||
volatile unsigned char *fifo;
|
||||
|
||||
/* If \n, also do \r */
|
||||
if (c == '\n')
|
||||
serial_putc ('\r');
|
||||
|
||||
fifo = (volatile unsigned char *) &(serial_reg_ch1->fifo);
|
||||
TXWAITRDY (serial_reg_ch1);
|
||||
*fifo = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test of a single byte from the serial port. Returns 1 on success, 0
|
||||
* otherwise.
|
||||
*/
|
||||
int serial_tstc(void)
|
||||
{
|
||||
return serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a single byte from the serial port. Returns 1 on success, 0
|
||||
* otherwise.
|
||||
*/
|
||||
int serial_getc (void)
|
||||
{
|
||||
unsigned int ch_uint;
|
||||
volatile unsigned int *fifo;
|
||||
volatile unsigned char *fifo_char = NULL;
|
||||
int buf_count = 0;
|
||||
|
||||
while (!(serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY))
|
||||
/* NOP */ ;
|
||||
|
||||
fifo = (volatile unsigned int *) &(serial_reg_ch1->fifo);
|
||||
fifo_char = (unsigned char *) &ch_uint;
|
||||
ch_uint = *fifo;
|
||||
|
||||
buf_count = NETARM_SER_STATA_RXFDB (serial_reg_ch1->status_a);
|
||||
switch (buf_count) {
|
||||
case NETARM_SER_STATA_RXFDB_4BYTES:
|
||||
buf_count = 4;
|
||||
break;
|
||||
case NETARM_SER_STATA_RXFDB_3BYTES:
|
||||
buf_count = 3;
|
||||
break;
|
||||
case NETARM_SER_STATA_RXFDB_2BYTES:
|
||||
buf_count = 2;
|
||||
break;
|
||||
case NETARM_SER_STATA_RXFDB_1BYTES:
|
||||
buf_count = 1;
|
||||
break;
|
||||
default:
|
||||
/* panic, be never here */
|
||||
}
|
||||
|
||||
serial_reg_ch1->status_a |= NETARM_SER_STATA_RX_CLOSED;
|
||||
|
||||
return ch_uint & 0xff;
|
||||
}
|
||||
|
||||
void serial_puts (const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
serial_putc (*s++);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NETARM */
|
||||
@@ -26,7 +26,9 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
#ifdef CONFIG_NETARM
|
||||
#include <asm/arch/netarm_registers.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
@@ -195,6 +197,7 @@ SYSCON3: .word 0x80002200
|
||||
#define CLKCTL_73 0x6 /* 73.728 MHz */
|
||||
|
||||
cpu_init_crit:
|
||||
#ifndef CONFIG_NETARM
|
||||
/*
|
||||
* mask all IRQs by clearing all bits in the INTMRs
|
||||
*/
|
||||
@@ -221,6 +224,54 @@ cpu_init_crit:
|
||||
bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM)
|
||||
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
|
||||
mcr p15,0,r0,c1,c0
|
||||
#else /* CONFIG_NETARM */
|
||||
/*
|
||||
* prior to software reset : need to set pin PORTC4 to be *HRESET
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \
|
||||
NETARM_GEN_PORT_DIR(0x10))
|
||||
str r1, [r0, #+NETARM_GEN_PORTC]
|
||||
/*
|
||||
* software reset : see HW Ref. Guide 8.2.4 : Software Service register
|
||||
* for an explanation of this process
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
/*
|
||||
* setup PLL and System Config
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
|
||||
ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \
|
||||
NETARM_GEN_SYS_CFG_BUSFULL | \
|
||||
NETARM_GEN_SYS_CFG_USER_EN | \
|
||||
NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
|
||||
NETARM_GEN_SYS_CFG_BUSARB_INT | \
|
||||
NETARM_GEN_SYS_CFG_BUSMON_EN )
|
||||
|
||||
str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL]
|
||||
|
||||
ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \
|
||||
NETARM_GEN_PLL_CTL_POLTST_DEF | \
|
||||
NETARM_GEN_PLL_CTL_INDIV(1) | \
|
||||
NETARM_GEN_PLL_CTL_ICP_DEF | \
|
||||
NETARM_GEN_PLL_CTL_OUTDIV(2) )
|
||||
str r1, [r0, #+NETARM_GEN_PLL_CONTROL]
|
||||
/*
|
||||
* mask all IRQs by clearing all bits in the INTMRs
|
||||
*/
|
||||
mov r1, #0
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
str r1, [r0, #+NETARM_GEN_INTR_ENABLE]
|
||||
#endif /* CONFIG_NETARM */
|
||||
|
||||
#ifdef CONFIG_ARM7_REVD
|
||||
/* set clock speed */
|
||||
@@ -415,6 +466,7 @@ fiq:
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
#ifndef CONFIG_NETARM
|
||||
mov ip, #0
|
||||
mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
|
||||
mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
|
||||
@@ -423,3 +475,21 @@ reset_cpu:
|
||||
bic ip, ip, #0x2100 @ ..v....s........
|
||||
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
|
||||
mov pc, r0
|
||||
#else
|
||||
ldr r1, =NETARM_MEM_MODULE_BASE
|
||||
ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR]
|
||||
ldr r1, =0xFFFFF000
|
||||
and r0, r1, r0
|
||||
ldr r1, =(relocate-TEXT_BASE)
|
||||
add r0, r1, r0
|
||||
ldr r4, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
mov pc, r0
|
||||
#endif
|
||||
|
||||
@@ -237,7 +237,7 @@ void udelay (unsigned long usec)
|
||||
}
|
||||
|
||||
tmp = get_timer (0); /* get current timestamp */
|
||||
if( (tmo + tmp) < tmp ) /* if setting this fordward will roll time stamp */
|
||||
if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
|
||||
reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
|
||||
else
|
||||
tmo += tmp; /* else, set advancing stamp wake up time */
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments <www.ti.com>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
@@ -31,7 +34,6 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <arm925t.h>
|
||||
#include <configs/omap1510.h>
|
||||
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
|
||||
@@ -47,12 +49,14 @@ void enable_interrupts (void)
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__ __volatile__("mrs %0, cpsr\n"
|
||||
"bic %0, %0, #0x80\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp)
|
||||
: "memory");
|
||||
"bic %0, %0, #0x80\n"
|
||||
"msr cpsr_c, %0"
|
||||
: "=r" (temp)
|
||||
:
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* disable IRQ/FIQ interrupts
|
||||
* returns true if interrupts had been enabled before we disabled them
|
||||
@@ -61,10 +65,11 @@ int disable_interrupts (void)
|
||||
{
|
||||
unsigned long old,temp;
|
||||
__asm__ __volatile__("mrs %0, cpsr\n"
|
||||
"orr %1, %0, #0xc0\n"
|
||||
"msr cpsr_c, %1"
|
||||
: "=r" (old), "=r" (temp)
|
||||
: "memory");
|
||||
"orr %1, %0, #0xc0\n"
|
||||
"msr cpsr_c, %1"
|
||||
: "=r" (old), "=r" (temp)
|
||||
:
|
||||
: "memory");
|
||||
return (old & 0x80) == 0;
|
||||
}
|
||||
#else
|
||||
@@ -179,10 +184,14 @@ int interrupt_init (void)
|
||||
{
|
||||
int32_t val;
|
||||
|
||||
/* Start the decrementer ticking down from 0xffffffff */
|
||||
*((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL;
|
||||
val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE |
|
||||
(CFG_PVT << MPUTIM_PTV_BIT);
|
||||
val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT);
|
||||
*((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val;
|
||||
|
||||
/* init the timestamp and lastdec value */
|
||||
reset_timer_masked();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -205,44 +214,50 @@ void set_timer (ulong t)
|
||||
timestamp = t;
|
||||
}
|
||||
|
||||
/* very rough timer... */
|
||||
/* delay x useconds AND perserve advance timstamp value */
|
||||
void udelay (unsigned long usec)
|
||||
{
|
||||
#ifdef CONFIG_INNOVATOROMAP1610
|
||||
#define LOOPS_PER_MSEC 100 /* tuned on omap1610 */
|
||||
volatile int i, time_remaining = LOOPS_PER_MSEC * usec;
|
||||
ulong tmo, tmp;
|
||||
|
||||
for (i = time_remaining; i > 0; i--) {
|
||||
if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
|
||||
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
}else{ /* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CFG_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
#else
|
||||
|
||||
ulong tmo;
|
||||
tmo = usec / 1000;
|
||||
tmo *= CFG_HZ;
|
||||
tmo /= 1000;
|
||||
tmo += get_timer (0);
|
||||
while (get_timer_masked () < tmo)
|
||||
tmp = get_timer (0); /* get current timestamp */
|
||||
if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
|
||||
reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
|
||||
else
|
||||
tmo += tmp; /* else, set advancing stamp wake up time */
|
||||
|
||||
while (get_timer_masked () < tmo)/* loop till event */
|
||||
/*NOP*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_timer_masked (void)
|
||||
{
|
||||
/* reset time */
|
||||
lastdec = READ_TIMER;
|
||||
timestamp = 0;
|
||||
lastdec = READ_TIMER; /* capure current decrementer value time */
|
||||
timestamp = 0; /* start "advancing" time stamp from 0 */
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
ulong now = READ_TIMER; /* current tick value */
|
||||
|
||||
if (lastdec >= now) { /* did I roll (rem decrementer) */
|
||||
if (lastdec >= now) { /* normal mode (non roll) */
|
||||
/* normal mode */
|
||||
/* record amount of time since last check */
|
||||
timestamp += lastdec - now;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
|
||||
} else { /* we have overflow of the count down timer */
|
||||
/* nts = ts + ld + (TLV - now)
|
||||
* ts=old stamp, ld=time that passed before passing through -1
|
||||
* (TLV-now) amount of time after passing though -1
|
||||
* nts = new "advancing time stamp"...it could also roll and cause problems.
|
||||
*/
|
||||
timestamp += lastdec + TIMER_LOAD_VAL - now;
|
||||
}
|
||||
lastdec = now;
|
||||
@@ -250,25 +265,24 @@ ulong get_timer_masked (void)
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/* waits specified delay value and resets timestamp */
|
||||
void udelay_masked (unsigned long usec)
|
||||
{
|
||||
#ifdef CONFIG_INNOVATOROMAP1610
|
||||
#define LOOPS_PER_MSEC 100 /* tuned on omap1610 */
|
||||
volatile int i, time_remaining = LOOPS_PER_MSEC*usec;
|
||||
for (i=time_remaining; i>0; i--) { }
|
||||
#else
|
||||
ulong tmo, tmp;
|
||||
|
||||
ulong tmo;
|
||||
if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
|
||||
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
}else{ /* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CFG_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
tmo = usec / 1000;
|
||||
tmo *= CFG_HZ;
|
||||
tmo /= 1000;
|
||||
reset_timer_masked (); /* set "advancing" timestamp to 0, set lastdec vaule */
|
||||
|
||||
reset_timer_masked ();
|
||||
|
||||
while (get_timer_masked () < tmo)
|
||||
while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
|
||||
/*NOP*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -287,6 +301,7 @@ unsigned long long get_ticks(void)
|
||||
ulong get_tbclk (void)
|
||||
{
|
||||
ulong tbclk;
|
||||
|
||||
tbclk = CFG_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
|
||||
@@ -310,8 +310,9 @@ static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
|
||||
unsigned short *pInput)
|
||||
{
|
||||
p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
|
||||
(AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) |
|
||||
(RegisterAddress << 18);
|
||||
(AT91C_EMAC_RW_R) |
|
||||
(RegisterAddress << 18) |
|
||||
(AT91C_EMAC_CODE_802_3);
|
||||
|
||||
udelay (10000);
|
||||
|
||||
@@ -421,8 +422,14 @@ int eth_init (bd_t * bd)
|
||||
|
||||
p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
|
||||
p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII)
|
||||
|
||||
p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC)
|
||||
& ~AT91C_EMAC_CLK;
|
||||
|
||||
#ifdef CONFIG_AT91C_USE_RMII
|
||||
p_mac->EMAC_CFG |= AT91C_EMAC_RMII;
|
||||
#endif
|
||||
|
||||
p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
|
||||
|
||||
return 0;
|
||||
@@ -462,5 +469,25 @@ int eth_rx (void)
|
||||
void eth_halt (void)
|
||||
{
|
||||
};
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_MII)
|
||||
int miiphy_read(unsigned char addr, unsigned char reg, unsigned short * value)
|
||||
{
|
||||
at91rm9200_EmacEnableMDIO (p_mac);
|
||||
at91rm9200_EmacReadPhy (p_mac, reg, value);
|
||||
at91rm9200_EmacDisableMDIO (p_mac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
|
||||
{
|
||||
at91rm9200_EmacEnableMDIO (p_mac);
|
||||
at91rm9200_EmacWritePhy (p_mac, reg, &value);
|
||||
at91rm9200_EmacDisableMDIO (p_mac);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_MII */
|
||||
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
|
||||
|
||||
#endif /* CONFIG_DRIVER_ETHER */
|
||||
|
||||
@@ -139,18 +139,17 @@ void MachineCheckException(struct pt_regs *regs)
|
||||
printf("Machine check in kernel mode.\n");
|
||||
printf("Caused by (from msr): ");
|
||||
printf("regs %p ",regs);
|
||||
switch( regs->msr & 0x0000F000)
|
||||
{
|
||||
case (1<<12) :
|
||||
switch( regs->msr & 0x000F0000) {
|
||||
case (0x80000000>>12):
|
||||
printf("Machine check signal\n");
|
||||
break;
|
||||
case (1<<13) :
|
||||
case (0x80000000>>13):
|
||||
printf("Transfer error ack signal\n");
|
||||
break;
|
||||
case (1<<14) :
|
||||
case (0x80000000>>14):
|
||||
printf("Data parity signal\n");
|
||||
break;
|
||||
case (1<<15) :
|
||||
case (0x80000000>>15):
|
||||
printf("Address parity signal\n");
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
|
||||
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_MPC5XXX -ffixed-r2 -ffixed-r29 \
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 -ffixed-r29 \
|
||||
-mstring -mcpu=603e -mmultiple
|
||||
|
||||
@@ -183,7 +183,7 @@ int cpu_init_r (void)
|
||||
/* route critical ints to normal ints */
|
||||
*(vu_long *)MPC5XXX_ICTL_EXT |= 0x00000001;
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC5XXX_FEC)
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC5xxx_FEC)
|
||||
/* load FEC microcode */
|
||||
loadtask(0, 2);
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/* #define DEBUG 0x28 */
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
|
||||
defined(CONFIG_MPC5XXX_FEC)
|
||||
defined(CONFIG_MPC5xxx_FEC)
|
||||
|
||||
#if (DEBUG & 0x60)
|
||||
static void tfifo_print(mpc5xxx_fec_priv *fec);
|
||||
@@ -980,4 +980,4 @@ static uint32 local_crc32(char *string, unsigned int crc_value, int len)
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* CONFIG_MPC5XXX_FEC */
|
||||
#endif /* CONFIG_MPC5xxx_FEC */
|
||||
|
||||
@@ -115,7 +115,7 @@ void pci_mpc5xxx_init (struct pci_controller *hose)
|
||||
|
||||
/* Map MBAR to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR0 = CFG_MBAR;
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR1 = CFG_MBAR | 1;
|
||||
*(vu_long *)MPC5XXX_PCI_TBATR0 = CFG_MBAR | 1;
|
||||
|
||||
/* Map RAM to PCI space */
|
||||
*(vu_long *)MPC5XXX_PCI_BAR1 = CONFIG_PCI_MEMORY_BUS | (1 << 3);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <mpc5xxx.h>
|
||||
#include <version.h>
|
||||
|
||||
#define CONFIG_MPC5XXX 1 /* needed for Linux kernel header files */
|
||||
#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */
|
||||
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
|
||||
|
||||
#include <ppc_asm.tmpl>
|
||||
@@ -145,6 +145,8 @@ lowboot_reentry:
|
||||
lis r3, CFG_MBAR@h
|
||||
ori r3, r3, CFG_MBAR@l
|
||||
#if defined(CONFIG_MPC5200)
|
||||
/* MBAR is mirrored into the MBAR SPR */
|
||||
mtspr MBAR,r3
|
||||
rlwinm r3, r3, 16, 16, 31
|
||||
#endif
|
||||
#if defined(CONFIG_MGT5100)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*
|
||||
* Modified by Cort Dougan (cort@cs.nmt.edu)
|
||||
* and Paul Mackerras (paulus@cs.anu.edu.au)
|
||||
* fixed Machine Check Reasons by Reinhard Meyer (r.meyer@emk-elektronik.de)
|
||||
*
|
||||
* (C) Copyright 2000-2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
@@ -130,19 +131,20 @@ MachineCheckException(struct pt_regs *regs)
|
||||
printf("Machine check in kernel mode.\n");
|
||||
printf("Caused by (from msr): ");
|
||||
printf("regs %p ",regs);
|
||||
switch( regs->msr & 0x0000F000)
|
||||
/* refer to 603e Manual (MPC603EUM/AD), chapter 4.5.2.1 */
|
||||
switch( regs->msr & 0x000F0000)
|
||||
{
|
||||
case (1<<12) :
|
||||
case (0x80000000>>12) :
|
||||
printf("Machine check signal - probably due to mm fault\n"
|
||||
"with mmu off\n");
|
||||
break;
|
||||
case (1<<13) :
|
||||
case (0x80000000>>13) :
|
||||
printf("Transfer error ack signal\n");
|
||||
break;
|
||||
case (1<<14) :
|
||||
case (0x80000000>>14) :
|
||||
printf("Data parity signal\n");
|
||||
break;
|
||||
case (1<<15) :
|
||||
case (0x80000000>>15) :
|
||||
printf("Address parity signal\n");
|
||||
break;
|
||||
default:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user