summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2008-04-04 18:16:06 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2008-04-04 18:16:06 +0200
commitae6cc2d36baec9dee3a82d5542354fcac6b7679c (patch)
tree7078ba7beefa5b61fd9c38f76c8449d4fee1bd67 /arch
parent35497c757ce705f4c2a19662e9b2f130583b673b (diff)
downloadbarebox-ae6cc2d36baec9dee3a82d5542354fcac6b7679c.tar.gz
barebox-ae6cc2d36baec9dee3a82d5542354fcac6b7679c.tar.xz
[m68k] Add Freescale Coldfire V4E Architecture support
- Added m68k vector, exception & interrupt handlers - Added m68k macros to access m68k movec registers - Added Coldfire support code (MultiChannelDMA) - Added board support for phytec phyCore-MCF baseboard - Added board support for konzeptpark MCB2 prototype Signed-off-by: Carsten Schlote <schlote@vahanus.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68k/Kconfig178
-rw-r--r--arch/m68k/Makefile105
-rw-r--r--arch/m68k/configs/phycore_kpukdr1_5475num_defconfig196
-rw-r--r--arch/m68k/configs/phycore_mcf54xx_defconfig196
-rw-r--r--arch/m68k/cpu/Makefile41
-rw-r--r--arch/m68k/cpu/cpu.c185
-rw-r--r--arch/m68k/cpu/cw_console_io.c116
-rw-r--r--arch/m68k/cpu/early_init_support.c41
-rw-r--r--arch/m68k/cpu/interrupts.c246
-rw-r--r--arch/m68k/cpu/start-mcfv4e.S677
-rw-r--r--arch/m68k/lib/Makefile31
-rw-r--r--arch/m68k/lib/m68k-linuxboot.c176
-rw-r--r--arch/m68k/lib/m68k-meminit.c42
-rw-r--r--arch/m68k/lib/m68k-module.c110
-rw-r--r--arch/m68k/lib/u-boot.lds.S92
-rw-r--r--arch/m68k/mach-mcfv4e.dox39
-rw-r--r--arch/m68k/mach-mcfv4e/Kconfig18
-rw-r--r--arch/m68k/mach-mcfv4e/Makefile19
-rw-r--r--arch/m68k/mach-mcfv4e/dma_utils.c502
-rw-r--r--arch/m68k/mach-mcfv4e/fec.c1440
-rw-r--r--arch/m68k/mach-mcfv4e/fecbd.c232
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c907
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox10
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c2449
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c225
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/Makefile26
-rw-r--r--arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt27
-rw-r--r--arch/m68k/mach-mcfv4e/mcf_clocksource.c138
-rw-r--r--arch/m68k/mach-mcfv4e/mcf_reset_cpu.c45
-rw-r--r--arch/m68k/mach-mcfv4e/multichannel_dma.c51
-rw-r--r--arch/m68k/mach-mcfv4e/net/Makefile26
-rw-r--r--arch/m68k/mach-mcfv4e/net/nbuf.c239
-rw-r--r--arch/m68k/mach-mcfv4e/net/net.c156
-rw-r--r--arch/m68k/mach-mcfv4e/net/queue.c128
34 files changed, 9109 insertions, 0 deletions
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
new file mode 100644
index 0000000000..07cf431dbe
--- /dev/null
+++ b/arch/m68k/Kconfig
@@ -0,0 +1,178 @@
+#
+# Default location of link U-Boot Image on M68k/Coldfire
+#
+config ARCH_TEXT_BASE
+ hex
+ default 0x07f00000 if MACH_MCF54xx
+ default 0x07f00000 if MACH_MCF5445x
+ help
+ Vector table for M68k and U-Boot Link Address
+
+ On M68k/Coldfire cores all exceptions and interrupts are routed through
+ a vector array. This vector is by default at address 0x0000_0000, but
+ can be moved to any other 1MB aligned address.
+
+ We take advantage of this to move U-Boot out of low memory. Some BDM
+ debuggers won't like a moved vector base and might need tweaking to
+ work.
+
+ Note: Respect alignment restrictions for TEXT_BASE, which must be
+ 1MB aligned (VBR register constrain).
+
+#
+# Internal configurations
+#
+config BOARDINFO
+ default "konzeptpark UKD Prototype with Phycore MCF5485" if MACH_KPUKDR1
+ default "konzeptpark UKD Prototype with Phycore MCF5475 NUM" if MACH_KPUKDR1_NUM
+ default "konzeptpark UKD Revision 2 with Phycore MCF5485" if MACH_KPUKDR2
+ default "konzeptpark UKD Revision 2 with Phycore MCF5475 NUM" if MACH_KPUKDR2_NUM
+ default "Phytec Baseboard with Phycore MCF5485" if MACH_PCM982_5485
+ default "Phytec Baseboard with Phycore MCF5475" if MACH_PCM982_5475
+ default "Phytec Baseboard with Phycore MCF5475 NUM" if MACH_PCM982_5475_NUM
+ default "Phytec Baseboard with Phycore MCF54455" if MACH_PCM982_54455
+ default "!No boardinfo string set!"
+
+config HAS_EARLY_INIT
+ bool
+ default n
+
+config BOARD_LINKER_SCRIPT
+ bool
+ default n
+
+config GENERIC_LINKER_SCRIPT
+ bool
+ default y
+ depends on !BOARD_LINKER_SCRIPT
+
+config M68K
+ bool
+ select HAS_KALLSYMS
+ select HAS_MODULES
+ default y
+
+config MCFV4E
+ bool
+
+config MCFV4M
+ bool
+
+config ARCH_MCF54xx
+ bool
+ select MCFV4E
+
+config ARCH_MCF5445x
+ bool
+ select MCFV4M
+
+#
+# Board selection
+#
+choice
+ prompt "Select your board"
+
+config MACH_KPUKDR1
+ bool "konzeptpark UKD R1 + phyCore MCF5485"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the konzeptpark UKD R1 with a
+ Phytec Phycore PCM-024 equipped with a Freescale MC5485 Processor
+
+config MACH_KPUKDR1_NUM
+ bool "konzeptpark UKD R1 + phyCore MCF5475 NUM"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the konzeptpark UKD R1 with a
+ Phytec Phycore PCM-024-NUM equipped with a Freescale MC5475 Processor
+
+config MACH_KPUKDR2
+ bool "konzeptpark UKD R2 + phyCore MCF5485"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the konzeptpark UKD R2 with a
+ Phytec Phycore PCM-024 equipped with a Freescale MC5485 Processor
+
+config MACH_KPUKDR2_NUM
+ bool "konzeptpark UKD R2 + phyCore MCF5475 NUM"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the konzeptpark UKD R2 with a
+ Phytec Phycore PCM-024-NUM equipped with a Freescale MC5475 Processor
+
+config MACH_PCM982_5485
+ bool "Phytec pcm982 + phyCore MCF5485"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the Phytec Phycore PCM-024 equipped
+ with a Freescale MC5485 Processor
+
+config MACH_PCM982_5475
+ bool "Phytec pcm982 + phyCore MCF5475"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the Phytec Phycore PCM-024 equipped
+ with a Freescale MC5475 Processor
+
+config MACH_PCM982_5475_NUM
+ bool "Phytec pcm982 + phyCore MCF5475 NUM"
+ select HAS_CFI
+ select ARCH_MCF54xx
+ help
+ Say Y here if you are using the Phytec Phycore PCM-024 equipped
+ with a Freescale MC5475 Processor (NUM Variant)
+
+config MACH_PCM982_54455
+ bool "Phytec pcm982 + phyCore MCF54455 (experimental)"
+ select HAS_CFI
+ select ARCH_MCF5445x
+ help
+ Say Y here if you are using the Phytec Phycore PCM-mcf54455 equipped
+ with a Freescale MC54455 Processor (experimental)
+
+endchoice
+
+#
+# M68k/Coldfire Subarch Configuration
+#
+source arch/m68k/mach-mcfv4e/Kconfig
+
+menu "M68k/Coldfire specific Linux boot settings"
+
+config CMDLINE_TAG
+ bool "Send commandline to kernel"
+ default y
+ help
+ If you want to start a 2.6 kernel say y here.
+
+config SETUP_MEMORY_TAGS
+ bool "send memory definition to kernel"
+ default y
+ help
+ If you want to start a 2.6 kernel say y here.
+
+config INITRD_TAG
+ bool "send initrd params to kernel"
+ default n
+ help
+ If you want to start a 2.6 kernel and use an
+ initrd image say y here.
+
+endmenu
+
+#
+# Common U-Boot options
+#
+
+source common/Kconfig
+source commands/Kconfig
+source net/Kconfig
+source drivers/Kconfig
+source fs/Kconfig
+source lib/Kconfig
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
new file mode 100644
index 0000000000..e376354a45
--- /dev/null
+++ b/arch/m68k/Makefile
@@ -0,0 +1,105 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+CPPFLAGS += -fno-builtin -ffreestanding -nostdinc -Wall \
+ -isystem $(gccincdir) -pipe -D __M68K__ \
+ -fno-strict-aliasing
+
+
+machine-$(CONFIG_ARCH_MCF54xx) := mcfv4e
+board-$(CONFIG_MACH_KPUKDR1) := kp_ukd_r1
+board-$(CONFIG_MACH_KPUKDR1_NUM) := kp_ukd_r1_num
+board-$(CONFIG_MACH_KPUKDR2) := kp_ukd_r2
+board-$(CONFIG_MACH_KPUKDR2_NUM) := kp_ukd_r2_num
+board-$(CONFIG_MACH_PCM982_5485) := phycore_mcf54xx
+board-$(CONFIG_MACH_PCM982_5475) := phycore_mcf54xx
+board-$(CONFIG_MACH_PCM982_5475_NUM) := phycore_mcf54xx_num
+board-$(CONFIG_MACH_PCM982_54455) := phycore_mcf5445x
+
+cpu-$(CONFIG_MCFV4E) := mcfv4e
+cpu-$(CONFIG_MCFV4M) := mcfv4m
+
+TEXT_BASE = $(CONFIG_TEXT_BASE)
+
+CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -P
+AFLAGS += -gdwarf-2 -save-temps
+# FIXME - remove overide
+CFLAGS := -Wall -Wundef -Wstrict-prototypes \
+ -msoft-float -mcfv4e -gdwarf-2 -feliminate-unused-debug-types \
+ -fmerge-all-constants -Os
+# Incompatible code in U-Boot for -std=c99
+LDFLAGS_uboot :=-L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
+# --verbose --stats
+
+ifeq ($(incdir-y),)
+incdir-y := $(machine-y)
+endif
+INCDIR := arch-$(incdir-y)
+
+# Update machine arch and proc symlinks if something which affects
+# them changed. We use .arch to indicate when they were updated
+# last, otherwise make uses the target directory mtime.
+
+include/asm-m68k/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf
+ @echo ' SYMLINK include/asm-m68k/arch -> include/asm-m68k/$(INCDIR)'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p include/asm-m68k
+ $(Q)ln -fsn $(srctree)/include/asm-m68k/$(INCDIR) include/asm-m68k/arch
+else
+ $(Q)ln -fsn $(INCDIR) include/asm-m68k/arch
+endif
+ @echo ' SYMLINK include/asm-m68k/proc -> include/asm-m68k/proc-mcfv4e'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p include/asm-m68k
+ $(Q)ln -fsn $(srctree)/include/asm-m68k/proc-mcfv4e include/asm-m68k/proc
+else
+ $(Q)ln -fsn proc-mcfv4e include/asm-m68k/proc
+endif
+ @touch $@
+
+
+all: $(KBUILD_IMAGE)
+
+archprepare: maketools
+
+PHONY += maketools
+maketools: include/asm-m68k/.arch
+
+
+ifneq ($(board-y),)
+BOARD := board/$(board-y)/
+else
+BOARD :=
+endif
+
+ifneq ($(machine-y),)
+MACH := arch/m68k/mach-$(machine-y)/
+else
+MACH :=
+endif
+
+common-y += $(BOARD) $(MACH)
+common-y += arch/m68k/lib/ arch/m68k/cpu/
+
+lds-$(CONFIG_GENERIC_LINKER_SCRIPT) := arch/m68k/lib/u-boot.lds
+lds-$(CONFIG_BOARD_LINKER_SCRIPT) := $(BOARD)/u-boot.lds
+
+CLEAN_FILES += arch/m68k/lib/u-boot.lds
+MRPROPER_FILES += include/asm-m68k/arch include/asm-m68k/proc
diff --git a/arch/m68k/configs/phycore_kpukdr1_5475num_defconfig b/arch/m68k/configs/phycore_kpukdr1_5475num_defconfig
new file mode 100644
index 0000000000..f867e511da
--- /dev/null
+++ b/arch/m68k/configs/phycore_kpukdr1_5475num_defconfig
@@ -0,0 +1,196 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.0.0-rc4-git
+# Tue Feb 19 13:41:25 2008
+#
+CONFIG_BOARDINFO="konzeptpark UKD Prototype with Phycore MCF5475 NUM"
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_M68K=y
+CONFIG_MCFV4E=y
+CONFIG_ARCH_MCF54xx=y
+# CONFIG_MACH_KPUKDR1 is not set
+CONFIG_MACH_KPUKDR1_NUM=y
+# CONFIG_MACH_KPUKDR2 is not set
+# CONFIG_MACH_KPUKDR2_NUM is not set
+# CONFIG_MACH_PCM982_5485 is not set
+# CONFIG_MACH_PCM982_5475 is not set
+# CONFIG_MACH_PCM982_5475_NUM is not set
+# CONFIG_MACH_PCM982_54455 is not set
+
+#
+# M68k/Coldfire V4E specific settings
+#
+CONFIG_COPY_LOWMEM_VECTORS=y
+# CONFIG_USE_LOWMEM_VECTORS is not set
+CONFIG_CMD_REGDUMP_V4E=y
+CONFIG_CMD_PCI_V4E=y
+
+#
+# M68k/Coldfire specific Linux boot settings
+#
+CONFIG_CMDLINE_TAG=y
+CONFIG_SETUP_MEMORY_TAGS=y
+CONFIG_INITRD_TAG=y
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+
+#
+# General Settings
+#
+CONFIG_TEXT_BASE=0x07f00000
+CONFIG_BROKEN=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_MODULES is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HAS_EARLY_INIT=y
+CONFIG_EARLY_INITDATA_RAM_ADDR=0x20000000
+CONFIG_EARLY_INITDATA_RAM_SIZE=0x1f00
+CONFIG_EARLY_INITDATA_SIZE=0x100
+CONFIG_DEBUG_INITCALLS=y
+CONFIG_USE_IRQ=y
+CONFIG_PROMPT="uboot:"
+CONFIG_BAUDRATE=115200
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+CONFIG_EARLY_CONSOLE_PORT="psc0"
+CONFIG_EARLY_CONSOLE_BAUDRATE=115200
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="board/kp_ukd_r1_num/env/"
+
+#
+# Debugging
+#
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+CONFIG_ENABLE_DEVICE_NOISE=y
+
+#
+# Commands
+#
+
+#
+# scripting
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_READLINE=y
+
+#
+# file commands
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_SPLASH is not set
+
+#
+# memory
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash
+#
+CONFIG_CMD_FLASH=y
+
+#
+# booting
+#
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_NET=y
+CONFIG_NET_BOOTP=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_RARP=y
+# CONFIG_NET_SNTP is not set
+# CONFIG_NET_NFS is not set
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+
+#
+# Drivers
+#
+
+#
+# serial drivers
+#
+CONFIG_DRIVER_SERIAL_MCFV4E=y
+CONFIG_MIIPHY=y
+
+#
+# Network drivers
+#
+CONFIG_DRIVER_NET_MCF54XX=y
+# CONFIG_DRIVER_NET_MCF54XX_DEBUG is not set
+
+#
+# SPI drivers
+#
+CONFIG_SPI=y
+# CONFIG_DRIVER_SPI_MC13783 is not set
+
+#
+# flash drivers
+#
+CONFIG_HAS_CFI=y
+CONFIG_DRIVER_CFI=y
+# CONFIG_DRIVER_CFI_NEW is not set
+CONFIG_DRIVER_CFI_OLD=y
+CONFIG_CFI_BUFFER_WRITE=y
+# CONFIG_NAND is not set
+
+#
+# Filesystem support
+#
+CONFIG_FS_CRAMFS=y
+CONFIG_ZLIB=y
+CONFIG_BZLIB=y
+CONFIG_CRC32=y
diff --git a/arch/m68k/configs/phycore_mcf54xx_defconfig b/arch/m68k/configs/phycore_mcf54xx_defconfig
new file mode 100644
index 0000000000..7670c2095a
--- /dev/null
+++ b/arch/m68k/configs/phycore_mcf54xx_defconfig
@@ -0,0 +1,196 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.0.1-csc
+# Thu Mar 27 14:02:15 2008
+#
+CONFIG_BOARDINFO="Phytec Baseboard with Phycore MCF5485"
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_M68K=y
+CONFIG_MCFV4E=y
+CONFIG_ARCH_MCF54xx=y
+# CONFIG_MACH_KPUKDR1 is not set
+# CONFIG_MACH_KPUKDR1_NUM is not set
+# CONFIG_MACH_KPUKDR2 is not set
+# CONFIG_MACH_KPUKDR2_NUM is not set
+CONFIG_MACH_PCM982_5485=y
+# CONFIG_MACH_PCM982_5475 is not set
+# CONFIG_MACH_PCM982_5475_NUM is not set
+# CONFIG_MACH_PCM982_54455 is not set
+
+#
+# M68k/Coldfire V4E specific settings
+#
+CONFIG_COPY_LOWMEM_VECTORS=y
+# CONFIG_USE_LOWMEM_VECTORS is not set
+CONFIG_CMD_REGDUMP_V4E=y
+CONFIG_CMD_PCI_V4E=y
+
+#
+# M68k/Coldfire specific Linux boot settings
+#
+CONFIG_CMDLINE_TAG=y
+CONFIG_SETUP_MEMORY_TAGS=y
+CONFIG_INITRD_TAG=y
+CONFIG_GREGORIAN_CALENDER=y
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+
+#
+# General Settings
+#
+CONFIG_TEXT_BASE=0x07f00000
+CONFIG_BROKEN=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_MODULES is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HAS_EARLY_INIT=y
+CONFIG_EARLY_INITDATA_RAM_ADDR=0x20000000
+CONFIG_EARLY_INITDATA_RAM_SIZE=0x1f00
+CONFIG_EARLY_INITDATA_SIZE=0x100
+CONFIG_DEBUG_INITCALLS=y
+CONFIG_USE_IRQ=y
+CONFIG_PROMPT="uboot:"
+CONFIG_BAUDRATE=115200
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_GLOB is not set
+CONFIG_PROMPT_HUSH_PS2="> "
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+CONFIG_TIMESTAMP=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+CONFIG_EARLY_CONSOLE_PORT="psc0"
+CONFIG_EARLY_CONSOLE_BAUDRATE=115200
+# CONFIG_OF_FLAT_TREE is not set
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="board/phycore_mcf54xx/env"
+
+#
+# Debugging
+#
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+CONFIG_ENABLE_DEVICE_NOISE=y
+
+#
+# Commands
+#
+
+#
+# scripting
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_READLINE=y
+
+#
+# file commands
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+
+#
+# console
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_SPLASH is not set
+
+#
+# memory
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+
+#
+# flash
+#
+CONFIG_CMD_FLASH=y
+
+#
+# booting
+#
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_NET=y
+CONFIG_NET_BOOTP=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_RARP=y
+# CONFIG_NET_SNTP is not set
+# CONFIG_NET_NFS is not set
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+
+#
+# Drivers
+#
+
+#
+# serial drivers
+#
+CONFIG_DRIVER_SERIAL_MCFV4E=y
+CONFIG_MIIPHY=y
+
+#
+# Network drivers
+#
+CONFIG_DRIVER_NET_MCF54XX=y
+# CONFIG_DRIVER_NET_MCF54XX_DEBUG is not set
+
+#
+# SPI drivers
+#
+CONFIG_SPI=y
+# CONFIG_DRIVER_SPI_MC13783 is not set
+
+#
+# flash drivers
+#
+CONFIG_HAS_CFI=y
+CONFIG_DRIVER_CFI=y
+# CONFIG_DRIVER_CFI_NEW is not set
+CONFIG_DRIVER_CFI_OLD=y
+CONFIG_CFI_BUFFER_WRITE=y
+# CONFIG_NAND is not set
+
+#
+# Filesystem support
+#
+CONFIG_FS_CRAMFS=y
+CONFIG_ZLIB=y
+CONFIG_BZLIB=y
+CONFIG_CRC32=y
diff --git a/arch/m68k/cpu/Makefile b/arch/m68k/cpu/Makefile
new file mode 100644
index 0000000000..4653534e47
--- /dev/null
+++ b/arch/m68k/cpu/Makefile
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+obj-y += cpu.o
+obj-y += interrupts.o
+
+#
+# Support code for early IO over BDM wigglers
+#
+
+# obj-y += early_init_support.o
+
+#
+# Support for relocated early initdata
+#
+obj-$(CONFIG_HAS_EARLY_INIT) += early_init_support.o
+
+#
+# Startup codes - try to merge them into single file!
+#
+obj-$(CONFIG_ARCH_MCF54xx) += start-mcfv4e.o
+obj-$(CONFIG_ARCH_MCF5445x) += start-mcfv4m.o
+
+start-mcfv4e.o : start-mcfv4e.s \ No newline at end of file
diff --git a/arch/m68k/cpu/cpu.c b/arch/m68k/cpu/cpu.c
new file mode 100644
index 0000000000..5c48add8d9
--- /dev/null
+++ b/arch/m68k/cpu/cpu.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * A few helper functions for M6kK/Coldfire
+ */
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <asm/proc/processor.h> // FIXME -stup place
+#include <asm/arch/mcf54xx-regs.h>
+
+static uint32_t CACR_shadow = MCF5XXX_CACR_BEC;
+
+/*
+ * Reset init value := 0x010C0100
+ * MCF5XXX_CACR_DCINVA
+ * MCF5XXX_CACR_BEC
+ * MCF5XXX_CACR_BCINVA
+ * MCF5XXX_CACR_ICINVA
+ */
+
+/**
+ * Enable processor's instruction cache
+ */
+void icache_enable (void)
+{
+ CACR_shadow |= MCF5XXX_CACR_IEC;
+ mcf5xxx_wr_cacr( CACR_shadow );
+}
+
+/**
+ * Disable processor's instruction cache
+ */
+void icache_disable (void)
+{
+ CACR_shadow &= ~MCF5XXX_CACR_IEC;
+ mcf5xxx_wr_cacr( CACR_shadow );
+}
+
+/**
+ * Detect processor's current instruction cache status
+ * @return 0=disabled, 1=enabled
+ */
+int icache_status (void)
+{
+ return (CACR_shadow & MCF5XXX_CACR_IEC)?1:0;
+}
+
+/**
+ * Enable processor's data cache
+ */
+void dcache_enable (void)
+{
+ CACR_shadow |= MCF5XXX_CACR_DEC;
+ mcf5xxx_wr_cacr( CACR_shadow );
+}
+
+/**
+ * Disable processor's data cache
+ */
+void dcache_disable (void)
+{
+ CACR_shadow &= ~MCF5XXX_CACR_DEC;
+ mcf5xxx_wr_cacr( CACR_shadow );
+}
+
+/**
+ * Detect processor's current instruction cache status
+ * @return 0=disabled, 1=enabled
+ */
+int dcache_status (void)
+{
+ return (CACR_shadow & MCF5XXX_CACR_DEC)?1:0;
+}
+
+/**
+ * Flush CPU caches to memory
+ */
+void cpu_cache_flush(void)
+{
+ uint32_t way, set;
+ void *addr;
+
+ for ( way=0; way < 4; way++ ) {
+ addr = (void*)way;
+ for ( set=0; set < 512; set++ ) {
+ mcf5xxx_cpushl_bc ( addr );
+ addr += 0x10;
+ }
+ }
+}
+
+/**
+ * Flush CPU caches to memory and disable them.
+ */
+void cpu_cache_disable(void)
+{
+ uint32_t lastipl;
+
+ lastipl = asm_set_ipl( 7 );
+
+ cpu_cache_flush();
+ mcf5xxx_wr_acr0( 0 );
+ mcf5xxx_wr_acr1( 0 );
+ mcf5xxx_wr_acr2( 0 );
+ mcf5xxx_wr_acr3( 0 );
+
+ CACR_shadow &= ~MCF5XXX_CACR_IEC;
+ CACR_shadow &= ~MCF5XXX_CACR_DEC;
+ mcf5xxx_wr_cacr( CACR_shadow | (MCF5XXX_CACR_DCINVA|MCF5XXX_CACR_ICINVA));
+
+ lastipl = asm_set_ipl( lastipl );
+}
+
+/**
+ * Prepare a "clean" CPU for Linux to run
+ * @return 0 (always)
+ *
+ * This function is called by the generic U-Boot part just before we call
+ * Linux. It prepares the processor for Linux.
+ */
+int cleanup_before_linux (void)
+{
+ /*
+ * we never enable dcache so we do not need to disable
+ * it. Linux can be called with icache enabled, so just
+ * do nothing here
+ */
+
+ /* flush I/D-cache */
+ cpu_cache_disable();
+
+ /* reenable icache */
+ icache_enable();
+ return (0);
+}
+/** @page m68k_boot_preparation Linux Preparation on M68k/Coldfire
+ *
+ * For M68K we never enable data cache so we do not need to disable it again.
+ *
+ * Linux can be called with instruction cache enabled. As this is the
+ * default setting we are running in U-Boot, there's no special preparation
+ * required.
+ */
+
+
+/** Early init of Coldfire V4E CPU
+ */
+static int cpu_init (void)
+{
+ /* Enable ICache - branch cache is already on */
+ icache_enable();
+
+ /*
+ * setup up stacks if necessary
+ * setup other CPU specifics here to prepare
+ * handling of exceptions and interrupts
+ */
+#ifdef CONFIG_USE_IRQ
+ printf("Prepare CPU interrupts for handlers\n");
+ mcf_interrupts_initialize();
+#endif
+
+ return 0;
+}
+
+core_initcall(cpu_init);
diff --git a/arch/m68k/cpu/cw_console_io.c b/arch/m68k/cpu/cw_console_io.c
new file mode 100644
index 0000000000..b0575e4c8a
--- /dev/null
+++ b/arch/m68k/cpu/cw_console_io.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Debug output stubs over BDM for Codewarrior
+ */
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <reloc.h>
+#include <init.h>
+
+#ifdef CONFIG_HAS_EARLY_INIT
+
+
+#if 0 // FIXME - make a CW debug port serial driver for u-boot
+
+/*
+ * The result of an I/O command can be any one of the following.
+ */
+typedef enum DSIOResult
+{
+ kDSIONoError = 0x00,
+ kDSIOError = 0x01,
+ kDSIOEOF = 0x02
+} DSIOResult;
+
+/*
+ * MessageCommandID
+ */
+typedef enum MessageCommandID
+{
+ /*
+ * target->host support commands
+ */
+
+ kDSWriteFile = 0xD0, /* L2 L3 */
+ kDSReadFile = 0xD1 /* L2 L3 */
+
+} MessageCommandID;
+
+
+enum DSIOResult TransferData(
+ MessageCommandID msg,
+ unsigned char *buffer, int size,
+ int * txsize
+)
+{
+ enum DSIOResult iores = kDSIOError;
+ unsigned long sized2=0;
+
+ /* -- Call codewarrior stub -- */
+ __asm__ __volatile__ (
+" move.l %[cmd],%%d0 \n"
+" move.l #0,%%d1 \n"
+" move.l %[size],%%d2 \n"
+" move.l %[buffer],%%d3 \n"
+" trap #14 \n"
+" move.l %%d1,%[txsize] \n"
+" move.l %%d0,%[res] \n"
+ : [res] "=r" (iores), [txsize] "=g" (sized2)
+ : [cmd] "g" (msg), [size] "g" (size), [buffer] "g" (buffer)
+ : "d2","d3" );
+
+ if (txsize!=NULL) *txsize=sized2;
+ return iores;
+}
+
+void *get_early_console_base(const char *name)
+{
+ return (void*)0xdeadbeef;
+}
+
+static unsigned char early_iobuffer[80];
+static int early_iobuffer_cnt;
+
+void early_console_putc(void *base, char c)
+{
+ early_iobuffer[early_iobuffer_cnt++] = c;
+ if ( ( early_iobuffer_cnt >= sizeof(early_iobuffer)) ||
+ (c == '\n') )
+ {
+ TransferData(kDSWriteFile,early_iobuffer,early_iobuffer_cnt, NULL);
+ early_iobuffer_cnt = 0;
+ }
+}
+
+void early_console_init(void *base, int baudrate)
+{
+ early_iobuffer_cnt = 0;
+}
+
+//void early_console_start(const char *name, int baudrate)
+//{
+//}
+
+#endif
+
+#endif
diff --git a/arch/m68k/cpu/early_init_support.c b/arch/m68k/cpu/early_init_support.c
new file mode 100644
index 0000000000..2f6be43539
--- /dev/null
+++ b/arch/m68k/cpu/early_init_support.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Early InitData support routines
+ */
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <reloc.h>
+#include <init.h>
+
+#ifdef CONFIG_HAS_EARLY_INIT
+
+/** Returns relocation offset to early init data
+ */
+unsigned long reloc_offset(void)
+{
+ //extern char __early_init_data_begin[];
+ //FIXME: return (unsigned long)init_data_ptr - (unsigned long)__early_init_data_begin;
+ return 0;
+}
+
+#endif
diff --git a/arch/m68k/cpu/interrupts.c b/arch/m68k/cpu/interrupts.c
new file mode 100644
index 0000000000..16aac38ad5
--- /dev/null
+++ b/arch/m68k/cpu/interrupts.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Interrupt routines and supporting code for Coldfire V4E
+ */
+#include <common.h>
+#include <asm/ptrace.h>
+#include <asm/arch/mcf54xx-regs.h>
+
+#ifdef CONFIG_USE_IRQ
+void enable_interrupts(void)
+{
+ asm_set_ipl(0);
+}
+
+int disable_interrupts(void)
+{
+ return asm_set_ipl(7) ? 1 : 0;
+}
+#endif
+
+/**
+ */
+static void mcf_bad_mode (void)
+{
+ panic ("Resetting CPU ...\n");
+ mdelay(3000);
+ reset_cpu (0);
+}
+
+/**
+ */
+static void mcf_show_regs (struct pt_regs *regs)
+{
+ unsigned long flags;
+ flags = condition_codes (regs);
+
+ printf ("pc : [<%08lx>]\n"
+ "sp : %08lx fp : %08lx\n",
+ instruction_pointer (regs),
+ regs->M68K_sp, regs->M68K_a6);
+
+ printf ("d0-d3 : %08lx %08lx %08lx %08lx\n",
+ regs->M68K_d0, regs->M68K_d1, regs->M68K_d2, regs->M68K_d3);
+ printf ("d3-d7 : %08lx %08lx %08lx %08lx\n",
+ regs->M68K_d3, regs->M68K_d4, regs->M68K_d5, regs->M68K_d6);
+
+ printf ("a0-d3 : %08lx %08lx %08lx %08lx\n",
+ regs->M68K_a0, regs->M68K_a1, regs->M68K_a2, regs->M68K_a3);
+ printf ("a3-d7 : %08lx %08lx %08lx %08lx\n",
+ regs->M68K_a3, regs->M68K_a4, regs->M68K_a5, regs->M68K_a6);
+
+ printf ("fp0 : %08lx%08lx fp1 : %08lx%08lx\n",
+ regs->M68K_fp0+1, regs->M68K_fp0, regs->M68K_fp1+1, regs->M68K_fp1);
+ printf ("fp2 : %08lx%08lx fp3 : %08lx%08lx\n",
+ regs->M68K_fp2+1, regs->M68K_fp2, regs->M68K_fp3+1, regs->M68K_fp3);
+ printf ("fp4 : %08lx%08lx fp5 : %08lx%08lx\n",
+ regs->M68K_fp4+1, regs->M68K_fp4, regs->M68K_fp5+1, regs->M68K_fp5);
+ printf ("fp6 : %08lx%08lx fp7 : %08lx%08lx\n",
+ regs->M68K_fp6+1, regs->M68K_fp6, regs->M68K_fp7+1, regs->M68K_fp7);
+
+ printf ("Flags: %c%c%c%c",
+ flags & CC_X_BIT ? 'X' : 'x',
+ flags & CC_N_BIT ? 'N' : 'n',
+ flags & CC_Z_BIT ? 'Z' : 'z',
+ flags & CC_V_BIT ? 'V' : 'v',
+ flags & CC_C_BIT ? 'C' : 'c' );
+
+ printf (" IRQs %s (%0x) Mode %s\n",
+ interrupts_enabled (regs) ? "on" : "off", interrupts_enabled (regs),
+ user_mode (regs) ? "user" : "supervisor");
+}
+
+void mcf_execute_exception_handler (struct pt_regs *pt_regs)
+{
+ printf ("unhandled exception\n");
+ mcf_show_regs (pt_regs);
+ mcf_bad_mode ();
+}
+
+#ifndef CONFIG_USE_IRQ
+
+void mcf_execute_irq_handler (struct pt_regs *pt_regs, int vector)
+{
+ printf ("interrupt request\n");
+ mcf_show_regs (pt_regs);
+ mcf_bad_mode ();
+}
+
+#else
+
+#ifndef CONFIG_MAX_ISR_HANDLERS
+#define CONFIG_MAX_ISR_HANDLERS (20)
+#endif
+
+typedef struct
+{
+ int vector;
+ int (*handler)(void *, void *);
+ void *hdev;
+ void *harg;
+}
+mcfv4e_irq_handler_s;
+
+mcfv4e_irq_handler_s irq_handler_table[CONFIG_MAX_ISR_HANDLERS];
+
+/** Initialize an empty interrupt handler list
+ */
+void mcf_interrupts_initialize (void)
+{
+ int index;
+ for (index = 0; index < CONFIG_MAX_ISR_HANDLERS; index++)
+ {
+ irq_handler_table[index].vector = 0;
+ irq_handler_table[index].handler = 0;
+ irq_handler_table[index].hdev = 0;
+ irq_handler_table[index].harg = 0;
+ }
+}
+
+/** Add an interrupt handler to the handler list
+ *
+ * @param vector : M68k exception/interrupt vector number
+ * @param handler : Pointer to handler function
+ * @param hdev : Handler specific data
+ * @param harg : Handler specific arg
+ */
+int mcf_interrupts_register_handler(
+ int vector,
+ int (*handler)(void *, void *), void *hdev, void *harg)
+{
+ /*
+ * This function places an interrupt handler in the ISR table,
+ * thereby registering it so that the low-level handler may call it.
+ *
+ * The two parameters are intended for the first arg to be a
+ * pointer to the device itself, and the second a pointer to a data
+ * structure used by the device driver for that particular device.
+ */
+ int index;
+
+ if ((vector == 0) || (handler == NULL))
+ {
+ return 0;
+ }
+
+ for (index = 0; index < CONFIG_MAX_ISR_HANDLERS; index++)
+ {
+ if (irq_handler_table[index].vector == vector)
+ {
+ /* only one entry of each type per vector */
+ return 0;
+ }
+
+ if (irq_handler_table[index].vector == 0)
+ {
+ irq_handler_table[index].vector = vector;
+ irq_handler_table[index].handler = handler;
+ irq_handler_table[index].hdev = hdev;
+ irq_handler_table[index].harg = harg;
+ return 1;
+ }
+ }
+ return 0; /* no available slots */
+}
+
+/** Remove an interrupt handler from the handler list
+ *
+ * @param type : FIXME
+ * @param handler : Pointer of handler function to remove.
+ */
+void mcf_interrupts_remove_handler (int type ,int (*handler)(void *, void *))
+{
+ /*
+ * This routine removes from the ISR table all
+ * entries that matches 'handler'.
+ */
+ int index;
+
+ for (index = 0; index < CONFIG_MAX_ISR_HANDLERS; index++)
+ {
+ if (irq_handler_table[index].handler == handler)
+ {
+ irq_handler_table[index].vector = 0;
+ irq_handler_table[index].handler = 0;
+ irq_handler_table[index].hdev = 0;
+ irq_handler_table[index].harg = 0;
+ }
+ }
+}
+
+/** Traverse list of registered interrupts and call matching handlers.
+ *
+ * @param pt_regs : Pointer to saved register context
+ * @param vector : M68k exception/interrupt vector number
+ */
+int mcf_execute_irq_handler (struct pt_regs *pt_regs, int vector)
+{
+ /*
+ * This routine searches the ISR table for an entry that matches
+ * 'vector'. If one is found, then 'handler' is executed.
+ */
+ int index, retval = 0;
+
+ /*
+ * Try to locate a user-registered Interrupt Service Routine handler.
+ */
+ for (index = 0; index < CONFIG_MAX_ISR_HANDLERS; index++)
+ {
+ if (irq_handler_table[index].handler == NULL)
+ {
+ printf("\nFault: No handler for IRQ vector %ld found.\n", vector);
+ break;
+ }
+ if (irq_handler_table[index].vector == vector)
+ {
+ if (irq_handler_table[index].handler(irq_handler_table[index].hdev,irq_handler_table[index].harg))
+ {
+ retval = 1;
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+#endif
diff --git a/arch/m68k/cpu/start-mcfv4e.S b/arch/m68k/cpu/start-mcfv4e.S
new file mode 100644
index 0000000000..c77fe676bb
--- /dev/null
+++ b/arch/m68k/cpu/start-mcfv4e.S
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Resetcode and exception/interrupt shells for Coldfire V4E
+ *
+ * This file contains the common startup code for use on at least Coldfire
+ * V4E cores:
+ * - MCF547x
+ * - MCF548x
+ */
+#include <config.h>
+
+ .section ".vectors","a"
+
+/*
+ * Define some addresses from your board configuration file
+ */
+ .equ __MBAR,CFG_MBAR_ADDRESS
+ .globl __MBAR
+
+ .equ __CORE_SRAM0,CFG_CORE0_SRAM_ADDRESS
+ .equ __CORE_SRAM0_SIZE,CFG_CORE0_SRAM_SIZE
+
+ .equ __CORE_SRAM1,CFG_CORE1_SRAM_ADDRESS
+ .equ __CORE_SRAM1_SIZE,CFG_CORE1_SRAM_SIZE
+
+ /*
+ * Preload stack pointer with end of Core SRAM - useable _after_ you have
+ * setup the MBR register in reset code!
+ *
+ * The upper 4 LW of the Core SRAM are left spare - it can be used as
+ * fixed address temporay storage in the code below (ok, well also to
+ * fix up stack traces in the debugger)
+ *
+ * So we have a stack usable for C code, before we even started SDRAM!
+ */
+ .equ ___SP_INIT,__CORE_SRAM1+__CORE_SRAM1_SIZE-16
+
+/*
+ * Vector table for M68k and U-Boot Link Address
+ *
+ * On M68k/Coldfire cores all exceptions and interrupts are routed through
+ * a vector array. This vector is by default at address 0x0000_0000, but
+ * can be moved to any other 1MB aligned address.
+ *
+ * We take advantage of this to move U-Boot out of low memory. Some BDM
+ * debuggers won't like a moved vector base and might need tweaking to
+ * work.
+ *
+ * Note: Respect alignment restrictions for TEXT_BASE, which must be
+ * 1MB aligned.
+ */
+
+ .globl _u_boot_start
+_u_boot_start:
+
+VECTOR_TABLE:
+_VECTOR_TABLE:
+INITSP: .long ___SP_INIT /* Initial SP */
+INITPC: .long 0x410 /* Initial PC */
+vector02: .long _asm_exception_handler /* Access Error */
+vector03: .long _asm_exception_handler /* Address Error */
+vector04: .long _asm_exception_handler /* Illegal Instruction */
+vector05: .long _asm_exception_handler /* Divide by Zero */
+vector06: .long _asm_exception_handler /* Reserved */
+vector07: .long _asm_exception_handler /* Reserved */
+vector08: .long _asm_exception_handler /* Privilege Violation */
+vector09: .long _asm_exception_handler /* Trace */
+vector0A: .long _asm_exception_handler /* Unimplemented A-Line */
+vector0B: .long _asm_exception_handler /* Unimplemented F-Line */
+vector0C: .long _asm_exception_handler /* Non-PC Brkpt Debug Int */
+vector0D: .long _asm_exception_handler /* PC Brkpt Debug Int */
+vector0E: .long _asm_exception_handler /* Format Error */
+vector0F: .long _asm_exception_handler /* Unitialized Int */
+vector10: .long _asm_exception_handler /* Reserved */
+vector11: .long _asm_exception_handler /* Reserved */
+vector12: .long _asm_exception_handler /* Reserved */
+vector13: .long _asm_exception_handler /* Reserved */
+vector14: .long _asm_exception_handler /* Reserved */
+vector15: .long _asm_exception_handler /* Reserved */
+vector16: .long _asm_exception_handler /* Reserved */
+vector17: .long _asm_exception_handler /* Reserved */
+vector18: .long _asm_exception_handler /* Spurious Interrupt */
+vector19: .long _asm_isr_handler /* Autovector Level 1 */
+vector1A: .long _asm_isr_handler /* Autovector Level 2 */
+vector1B: .long _asm_isr_handler /* Autovector Level 3 */
+vector1C: .long _asm_isr_handler /* Autovector Level 4 */
+vector1D: .long _asm_isr_handler /* Autovector Level 5 */
+vector1E: .long _asm_isr_handler /* Autovector Level 6 */
+vector1F: .long _asm_isr_handler /* Autovector Level 7 */
+vector20: .long _asm_exception_handler /* TRAP #0 */
+vector21: .long _asm_exception_handler /* TRAP #1 */
+vector22: .long _asm_exception_handler /* TRAP #2 */
+vector23: .long _asm_exception_handler /* TRAP #3 */
+vector24: .long _asm_exception_handler /* TRAP #4 */
+vector25: .long _asm_exception_handler /* TRAP #5 */
+vector26: .long _asm_exception_handler /* TRAP #6 */
+vector27: .long _asm_exception_handler /* TRAP #7 */
+vector28: .long _asm_exception_handler /* TRAP #8 */
+vector29: .long _asm_exception_handler /* TRAP #9 */
+vector2A: .long _asm_exception_handler /* TRAP #10 */
+vector2B: .long _asm_exception_handler /* TRAP #11 */
+vector2C: .long _asm_exception_handler /* TRAP #12 */
+vector2D: .long _asm_exception_handler /* TRAP #13 */
+vector2E: .long _asm_exception_handler /* TRAP #14 */
+vector2F: .long _dbug_sc_handler /* TRAP #15 - System Call */
+vector30: .long _asm_exception_handler /* Reserved */
+vector31: .long _asm_exception_handler /* Reserved */
+vector32: .long _asm_exception_handler /* Reserved */
+vector33: .long _asm_exception_handler /* Reserved */
+vector34: .long _asm_exception_handler /* Reserved */
+vector35: .long _asm_exception_handler /* Reserved */
+vector36: .long _asm_exception_handler /* Reserved */
+vector37: .long _asm_exception_handler /* Reserved */
+vector38: .long _asm_exception_handler /* Reserved */
+vector39: .long _asm_exception_handler /* Reserved */
+vector3A: .long _asm_exception_handler /* Reserved */
+vector3B: .long _asm_exception_handler /* Reserved */
+vector3C: .long _asm_exception_handler /* Reserved */
+vector3D: .long _asm_exception_handler /* Unsupported Instruction */
+vector3E: .long _asm_exception_handler /* Reserved */
+vector3F: .long _asm_exception_handler /* Reserved */
+vector40: .long _asm_isr_handler /* User Defined Interrupts */
+vector41: .long _asm_isr_handler
+vector42: .long _asm_isr_handler
+vector43: .long _asm_isr_handler
+vector44: .long _asm_isr_handler
+vector45: .long _asm_isr_handler
+vector46: .long _asm_isr_handler
+vector47: .long _asm_isr_handler
+vector48: .long _asm_isr_handler
+vector49: .long _asm_isr_handler
+vector4A: .long _asm_isr_handler
+vector4B: .long _asm_isr_handler
+vector4C: .long _asm_isr_handler
+vector4D: .long _asm_isr_handler
+vector4E: .long _asm_isr_handler
+vector4F: .long _asm_isr_handler
+vector50: .long _asm_isr_handler
+vector51: .long _asm_isr_handler
+vector52: .long _asm_isr_handler
+vector53: .long _asm_isr_handler
+vector54: .long _asm_isr_handler
+vector55: .long _asm_isr_handler
+vector56: .long _asm_isr_handler
+vector57: .long _asm_isr_handler
+vector58: .long _asm_isr_handler
+vector59: .long _asm_isr_handler
+vector5A: .long _asm_isr_handler
+vector5B: .long _asm_isr_handler
+vector5C: .long _asm_isr_handler
+vector5D: .long _asm_isr_handler
+vector5E: .long _asm_isr_handler
+vector5F: .long _asm_isr_handler
+vector60: .long _asm_isr_handler
+vector61: .long _asm_isr_handler
+vector62: .long _asm_isr_handler
+vector63: .long _asm_isr_handler
+vector64: .long _asm_isr_handler
+vector65: .long _asm_isr_handler
+vector66: .long _asm_isr_handler
+vector67: .long _asm_isr_handler
+vector68: .long _asm_isr_handler
+vector69: .long _asm_isr_handler
+vector6A: .long _asm_isr_handler
+vector6B: .long _asm_isr_handler
+vector6C: .long _asm_isr_handler
+vector6D: .long _asm_isr_handler
+vector6E: .long _asm_isr_handler
+vector6F: .long _asm_isr_handler
+vector70: .long _asm_isr_handler
+vector71: .long _asm_isr_handler
+vector72: .long _asm_isr_handler
+vector73: .long _asm_isr_handler
+vector74: .long _asm_isr_handler
+vector75: .long _asm_isr_handler
+vector76: .long _asm_isr_handler
+vector77: .long _asm_isr_handler
+vector78: .long _asm_isr_handler
+vector79: .long _asm_isr_handler
+vector7A: .long _asm_isr_handler
+vector7B: .long _asm_isr_handler
+vector7C: .long _asm_isr_handler
+vector7D: .long _asm_isr_handler
+vector7E: .long _asm_isr_handler
+vector7F: .long _asm_isr_handler
+vector80: .long _asm_isr_handler
+vector81: .long _asm_isr_handler
+vector82: .long _asm_isr_handler
+vector83: .long _asm_isr_handler
+vector84: .long _asm_isr_handler
+vector85: .long _asm_isr_handler
+vector86: .long _asm_isr_handler
+vector87: .long _asm_isr_handler
+vector88: .long _asm_isr_handler
+vector89: .long _asm_isr_handler
+vector8A: .long _asm_isr_handler
+vector8B: .long _asm_isr_handler
+vector8C: .long _asm_isr_handler
+vector8D: .long _asm_isr_handler
+vector8E: .long _asm_isr_handler
+vector8F: .long _asm_isr_handler
+vector90: .long _asm_isr_handler
+vector91: .long _asm_isr_handler
+vector92: .long _asm_isr_handler
+vector93: .long _asm_isr_handler
+vector94: .long _asm_isr_handler
+vector95: .long _asm_isr_handler
+vector96: .long _asm_isr_handler
+vector97: .long _asm_isr_handler
+vector98: .long _asm_isr_handler
+vector99: .long _asm_isr_handler
+vector9A: .long _asm_isr_handler
+vector9B: .long _asm_isr_handler
+vector9C: .long _asm_isr_handler
+vector9D: .long _asm_isr_handler
+vector9E: .long _asm_isr_handler
+vector9F: .long _asm_isr_handler
+vectorA0: .long _asm_isr_handler
+vectorA1: .long _asm_isr_handler
+vectorA2: .long _asm_isr_handler
+vectorA3: .long _asm_isr_handler
+vectorA4: .long _asm_isr_handler
+vectorA5: .long _asm_isr_handler
+vectorA6: .long _asm_isr_handler
+vectorA7: .long _asm_isr_handler
+vectorA8: .long _asm_isr_handler
+vectorA9: .long _asm_isr_handler
+vectorAA: .long _asm_isr_handler
+vectorAB: .long _asm_isr_handler
+vectorAC: .long _asm_isr_handler
+vectorAD: .long _asm_isr_handler
+vectorAE: .long _asm_isr_handler
+vectorAF: .long _asm_isr_handler
+vectorB0: .long _asm_isr_handler
+vectorB1: .long _asm_isr_handler
+vectorB2: .long _asm_isr_handler
+vectorB3: .long _asm_isr_handler
+vectorB4: .long _asm_isr_handler
+vectorB5: .long _asm_isr_handler
+vectorB6: .long _asm_isr_handler
+vectorB7: .long _asm_isr_handler
+vectorB8: .long _asm_isr_handler
+vectorB9: .long _asm_isr_handler
+vectorBA: .long _asm_isr_handler
+vectorBB: .long _asm_isr_handler
+vectorBC: .long _asm_isr_handler
+vectorBD: .long _asm_isr_handler
+vectorBE: .long _asm_isr_handler
+vectorBF: .long _asm_isr_handler
+vectorC0: .long _asm_isr_handler
+vectorC1: .long _asm_isr_handler
+vectorC2: .long _asm_isr_handler
+vectorC3: .long _asm_isr_handler
+vectorC4: .long _asm_isr_handler
+vectorC5: .long _asm_isr_handler
+vectorC6: .long _asm_isr_handler
+vectorC7: .long _asm_isr_handler
+vectorC8: .long _asm_isr_handler
+vectorC9: .long _asm_isr_handler
+vectorCA: .long _asm_isr_handler
+vectorCB: .long _asm_isr_handler
+vectorCC: .long _asm_isr_handler
+vectorCD: .long _asm_isr_handler
+vectorCE: .long _asm_isr_handler
+vectorCF: .long _asm_isr_handler
+vectorD0: .long _asm_isr_handler
+vectorD1: .long _asm_isr_handler
+vectorD2: .long _asm_isr_handler
+vectorD3: .long _asm_isr_handler
+vectorD4: .long _asm_isr_handler
+vectorD5: .long _asm_isr_handler
+vectorD6: .long _asm_isr_handler
+vectorD7: .long _asm_isr_handler
+vectorD8: .long _asm_isr_handler
+vectorD9: .long _asm_isr_handler
+vectorDA: .long _asm_isr_handler
+vectorDB: .long _asm_isr_handler
+vectorDC: .long _asm_isr_handler
+vectorDD: .long _asm_isr_handler
+vectorDE: .long _asm_isr_handler
+vectorDF: .long _asm_isr_handler
+vectorE0: .long _asm_isr_handler
+vectorE1: .long _asm_isr_handler
+vectorE2: .long _asm_isr_handler
+vectorE3: .long _asm_isr_handler
+vectorE4: .long _asm_isr_handler
+vectorE5: .long _asm_isr_handler
+vectorE6: .long _asm_isr_handler
+vectorE7: .long _asm_isr_handler
+vectorE8: .long _asm_isr_handler
+vectorE9: .long _asm_isr_handler
+vectorEA: .long _asm_isr_handler
+vectorEB: .long _asm_isr_handler
+vectorEC: .long _asm_isr_handler
+vectorED: .long _asm_isr_handler
+vectorEE: .long _asm_isr_handler
+vectorEF: .long _asm_isr_handler
+vectorF0: .long _asm_isr_handler
+vectorF1: .long _asm_isr_handler
+vectorF2: .long _asm_isr_handler
+vectorF3: .long _asm_isr_handler
+vectorF4: .long _asm_isr_handler
+vectorF5: .long _asm_isr_handler
+vectorF6: .long _asm_isr_handler
+vectorF7: .long _asm_isr_handler
+vectorF8: .long _asm_isr_handler
+vectorF9: .long _asm_isr_handler
+vectorFA: .long _asm_isr_handler
+vectorFB: .long _asm_isr_handler
+vectorFC: .long _asm_isr_handler
+vectorFD: .long _asm_isr_handler
+vectorFE: .long _asm_isr_handler
+vectorFF: .long _asm_isr_handler
+
+/*
+ * Leave some bytes spare here for CW debugger (console IO stuff)
+ */
+ .rept 4
+ .long 0xdeadbeef
+ .endr
+
+/** @func reset Startup Code (reset vector)
+ *
+ * The vector array is mapped to address 0 at reset and SP and PC are
+ * fetched from adress 0 and 4.
+ *
+ * For debugger uploads this image will reside in the middle of RAM, leaving
+ * as much memory for other stuff in low memory available, e.g. Linux and
+ * an init ramdisk.
+ *
+ * For real system resets, the boot rom is mapped to all addresses in
+ * system, as long as somebody sets up the CS. Now the trick part until
+ * relocation to RAM is that we must code at the start of your bootrom
+ * - all link addresses are wrong, so we need the reloc.h stuff to find the
+ * right address.
+ *
+ * The following things happen here:
+ * * do important init, like SDRAM, only if we don't start from memory!
+ * * setup Memory and board specific bits prior to relocation.
+ * * Setup stack
+ * * relocate U-Boot to ram
+ *
+ */
+ .globl _start
+_start:
+ .global reset
+reset:
+ /* Mask all IRQs */
+ move.w #0x2700,%sr
+
+ /* Initialize MBAR - keep D0/D1 registers */
+ move.l #__MBAR,%d2
+ movec %d2,%MBAR
+ nop
+
+ /* Initialize RAMBAR0 - locate it on the data bus */
+ move.l #__CORE_SRAM0,%d2
+ add.l #0x21,%d2
+ movec %d2,%RAMBAR0
+ nop
+
+ /* Initialize RAMBAR1 - locate it on the data bus */
+ move.l #__CORE_SRAM1,%d2
+ add.l #0x21,%d2
+ movec %d2,%RAMBAR1
+ nop
+
+ /* Point Stack Pointer into Core SRAM temporarily */
+ move.l #___SP_INIT,%d2
+ move.l %d2,%sp
+ nop
+
+ /* Invalidate the data, instruction, and branch caches */
+ /* Turn on the branch cache */
+ move.l #0x010C0100,%d2
+ movec %d2,%cacr
+ nop
+
+ /* Prepare stack top */
+ clr.l %sp@(0)
+ move.l %d0,%sp@(4)
+ move.l %d1,%sp@(8)
+ clr.l %sp@(12)
+
+ /*
+ * This call is intended to give all developers a chance to use a
+ * standard reset vector file, but also do some special things
+ * required only on their specific CPU.
+ */
+#ifdef ARCH_HAS_INIT_LOWLEVEL
+ bsr.l arch_init_lowlevel
+ nop
+#endif
+ /*
+ * If the code vector table is not at TEXT_BASE and so this code
+ * as well, jump to the address mirror at FLASH ROM start address
+ *
+ * So load your image to TEXT_BASE for debugging or flash a binary
+ * image to your bootflash - code below will take proper action.
+ */
+ lea.l %pc@(VECTOR_TABLE),%a0
+ move.l #TEXT_BASE,%a1
+ cmp.l %a0,%a1
+ beq.s saveland
+
+ /*
+ * Execution is not at TEXT_BASE. We assume entry to this code by
+ * a hardware reset and change execution to address of _FLASH_ rom.
+ */
+ lea.l %pc@(saveland),%a0 // Effective ! Address of label below
+ move.l %a0,%d0
+ and.l #0x00ffffff,%d0 // Cut away address high byte
+ move.l #CFG_FLASH_ADDRESS,%d1 // Get flash address
+ and.l #0xff000000,%d1 // and just take base for CS0
+ or.l %d1,%d0 // Compose new address
+ move.l %d0,%a0
+ jmp %a0@ // Jump to flash rom address!
+ nop
+
+ /* We now either in SDRAM or FLASH START addresses, save to
+ change chip selects */
+saveland:
+ nop
+
+ /*
+ * Before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.[c|S] in your board directory.
+ *
+ * Do not jump/call other u-boot code here!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bsr.l board_init_lowlevel
+ nop
+#endif
+
+ /*
+ * relocate U-Boot Code to RAM (including copy of vectors)
+ */
+relocate:
+ lea.l %pc@(VECTOR_TABLE),%a0
+ move.l #TEXT_BASE,%a1
+ move.l #__bss_start,%a3
+ cmp.l %a0,%a1
+ beq.s skip_relocate
+
+ /*
+ * Calculate number of long words, and copy them to RAM
+ */
+ move.l %a3,%d2
+ sub.l %a1,%d2
+ asr.l #2,%d2
+copy_loop:
+ move.l %a0@+,%a1@+
+ subq.l #1,%d2
+ bne.s copy_loop
+
+skip_relocate:
+
+ /* Clear BSS segment in RAM */
+clear_bss:
+ move.l #__bss_end,%a4
+ moveq.l #0,%d2
+clear_loop:
+ move.l %d2,%a3@+
+ cmp.l %a4,%a3
+ ble.s clear_loop
+
+ /*
+ * Relocate Vectors to memory start (address 0)
+ *
+ * NOTE: It could be at other places, but debuggers expect
+ * this table to be at address 0.
+ */
+#ifdef CONFIG_COPY_LOWMEM_VECTORS
+reloc_vectors:
+ lea.l %pc@(VECTOR_TABLE),%a0
+ move.l #0,%a1
+ cmp.l %a0,%a1
+ beq.s skip_copy_vectors
+
+ move.l #0x100,%d2
+copy_loop_vectors:
+ move.l %a0@+,%a1@+
+ subq.l #1,%d2
+ bne.s copy_loop_vectors
+skip_copy_vectors:
+#endif
+
+#ifndef CONFIG_USE_LOWMEM_VECTORS
+ move.l #TEXT_BASE,%d0
+ movec %d0,%vbr
+ nop
+#endif
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /*
+ * Call other half of initcode in relocated code
+ *
+ * You allowed to call other U-Boot code from here
+ */
+ jsr.l board_init_highlevel
+ nop
+#endif
+ /*
+ * Now jump to real link address and U-Boot entry point
+ */
+ nop
+ jmp.l start_uboot
+ nop
+ nop
+
+/*
+ * Interrupt handling
+ */
+
+/*
+ * IRQ stack frame.
+ */
+#define S_FRAME_SIZE 148
+
+#define S_SP S_A7
+#define S_SR 144
+#define S_PC 140
+
+#define S_FPIAR 136
+#define S_FPSR 132
+#define S_FPCR 128
+
+#define S_FP7 120
+#define S_FP6 112
+#define S_FP5 104
+#define S_FP4 96
+#define S_FP3 88
+#define S_FP2 80
+#define S_FP1 72
+#define S_FP0 64
+
+#define S_A7 60
+#define S_A6 56
+#define S_A5 52
+#define S_A4 48
+#define S_A3 44
+#define S_A2 40
+#define S_A1 36
+#define S_A0 32
+
+#define S_D7 28
+#define S_D6 24
+#define S_D5 20
+#define S_D4 16
+#define S_D3 12
+#define S_D2 8
+#define S_D1 4
+#define S_D0 0
+
+
+/*
+ * exception handlers
+ */
+#ifdef CONFIG_USE_IRQ
+ .global _dbug_sc_handler
+_dbug_sc_handler:
+ .global _asm_exception_handler
+_asm_exception_handler:
+ move.w #0x2700,%sr /* Disable IRQs */
+
+ move.l %sp,___SP_INIT /* Remember on top of stack */
+ move.l #___SP_INIT,%sp /* Set stack to known area */
+
+ move.l %a0,%sp@-
+ lea _asm_context,%a0
+
+ movem.l %d0-%d7/%a0-%a7,%a0@
+
+ fmovem %fp0-%fp7,%a0@(S_FP0)
+ fmove.l %fpcr,%a0@(S_FPCR)
+ fmove.l %fpsr,%a0@(S_FPSR)
+ fmove.l %fpiar,%a0@(S_FPIAR)
+
+ move.l %sp@+,%a0@(S_A0)
+ move.l %sp@,%a1
+ move.l %a1,%a0@(S_SP)
+ move.l %a1@(4),%a0@(S_PC)
+ move.w %a1@(2),%a0@(S_SR)
+
+ jsr cpu_cache_flush
+ nop
+
+ move.l %a1,%sp@-
+ jsr mcf_execute_exception_handler
+
+
+ lea _asm_context,%a0
+ move.l %a0@(S_SP),%sp
+
+ move.l %a0@(S_D1),%d1
+ move.l %a0@(S_D0),%d0
+ move.l %a0@(S_A1),%a1
+ move.l %a0@(S_A0),%a0
+
+ rte
+ nop
+ nop
+
+ .global _asm_isr_handler
+_asm_isr_handler:
+ link %a6,#-16
+ movem.l %d0-%d1/%a0-%a1,%sp@
+
+ move.w %a6@(4),%d0
+ lsr.l #2,%d0
+ andi.l #0x0000FF,%d0
+ move.l %d0,%sp@-
+ move.l #0,%a0
+ move.l %a0,%sp@-
+ jsr mcf_execute_irq_handler
+ lea %sp@(8),%sp
+ cmpi.l #1,%d0
+ beq handled
+
+nothandled:
+ movem.l %sp@,%d0-%d1/%a0-%a1
+ unlk %a6
+ jmp _asm_exception_handler
+ nop
+
+handled:
+ movem.l %sp@,%d0-%d1/%a0-%a1
+ unlk %a6
+ rte
+ nop
+ nop
+
+#else
+
+ .global _dbug_sc_handler
+_dbug_sc_handler:
+ .global _asm_exception_handler
+_asm_exception_handler:
+ nop
+ // FIXME - do something useful here
+ rte
+
+ .global _asm_isr_handler
+_asm_isr_handler:
+ nop
+ // FIXME - do something useful here
+ rte
+
+#endif
+
+ .data
+_asm_context:
+ .space S_FRAME_SIZE,0x55
+
+
+ .end
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
new file mode 100644
index 0000000000..52ea7e9542
--- /dev/null
+++ b/arch/m68k/lib/Makefile
@@ -0,0 +1,31 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Architecture dependant stubs and callbacks
+#
+
+obj-y += m68k-meminit.o
+
+obj-$(CONFIG_CMD_BOOTM) += m68k-linuxboot.o
+
+obj-$(CONFIG_MODULES) += m68k-module.o
+
+extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += u-boot.lds
diff --git a/arch/m68k/lib/m68k-linuxboot.c b/arch/m68k/lib/m68k-linuxboot.c
new file mode 100644
index 0000000000..63b0cc134d
--- /dev/null
+++ b/arch/m68k/lib/m68k-linuxboot.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file Linux boot preparation code.
+ *
+ * This file is responsible to start a linux kernel on
+ * Coldfire targets.
+ *
+ * @note Only Colilo mode supported yet.
+ */
+#include <common.h>
+#include <command.h>
+#include <driver.h>
+#include <image.h>
+#include <zlib.h>
+#include <init.h>
+
+#include <asm/byteorder.h>
+#include <asm/setup.h>
+#include <environment.h>
+#include <boot.h>
+#include <asm/u-boot-m68k.h>
+#include <asm/bootinfo.h>
+
+
+static int m68k_architecture = MACH_TYPE_GENERIC;
+
+
+/*
+ * Setup M68k/Coldfire bootrecord info
+ */
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+ defined (CONFIG_CMDLINE_TAG) || \
+ defined (CONFIG_INITRD_TAG)
+
+
+static void setup_boot_record(char* start_boot_rec, const char* command_line)
+{
+ struct bi_record* record;
+
+ *start_boot_rec++ = 'C';
+ *start_boot_rec++ = 'o';
+ *start_boot_rec++ = 'L';
+ *start_boot_rec++ = 'i';
+ *start_boot_rec++ = 'L';
+ *start_boot_rec++ = 'o';
+
+ record = (struct bi_record*) start_boot_rec;
+
+ /* specify memory layout */
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+ record->tag = BI_MEMCHUNK;
+ record->data[0] = 0;
+ record->data[1] = 64 * 1024 * 1024; // TODO: to be changed for different boards
+ record->size = sizeof (record->tag) + sizeof (record->size)
+ + sizeof (record->data[0]) + sizeof (record->data[0]);
+ record = (struct bi_record *) ((void *) record + record->size);
+#endif
+
+ /* add a kernel command line */
+#ifdef CONFIG_CMDLINE_TAG
+ record->tag = BI_COMMAND_LINE;
+ strcpy ((char *) &record->data, command_line);
+ record->size = sizeof (record->tag) + sizeof (record->size)
+ + max (sizeof (record->data[0]), strlen (command_line)+1);
+ record = (struct bi_record *) ((void *) record + record->size);
+#endif
+
+ /* Add reference to initrd */
+#ifdef CONFIG_INITRD_TAG
+#endif
+
+ /* Mark end of tags */
+ record->tag = 0;
+ record->data[0] = 0;
+ record->data[1] = 0;
+ record->size = sizeof(record->tag) + sizeof (record->size)
+ + sizeof (record->data[0]) + sizeof (record->data[0]);
+}
+
+#else
+#define setup_boot_record(start_boot_rec,command_line) while (0) { }
+
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+
+
+static int do_bootm_linux(struct image_data *data)
+{
+ image_header_t *os_header = &data->os->header;
+ void (*theKernel)(int zero, int arch, uint params);
+ const char *commandline = getenv ("bootargs");
+ uint32_t loadaddr,loadsize;
+
+ if (os_header->ih_type == IH_TYPE_MULTI) {
+ printf("Multifile images not handled at the moment\n");
+ return -1;
+ }
+
+ printf("commandline: %s\n", commandline);
+
+ theKernel = (void (*)(int,int,uint))ntohl((os_header->ih_ep));
+
+ debug ("## Transferring control to Linux (at address %08lx) ...\n",
+ (ulong) theKernel);
+
+ loadaddr = (uint32_t)ntohl(os_header->ih_load);
+ loadsize = (uint32_t)ntohl(os_header->ih_size);
+ setup_boot_record( (char*)(loadaddr+loadsize),(char*)commandline);
+
+ if (relocate_image(data->os, (void *)loadaddr))
+ return -1;
+
+ /* we assume that the kernel is in place */
+ printf ("\nStarting kernel image at 0x%08x size 0x%08x eentry 0x%08x\n\n",
+ loadaddr, loadsize, (ulong) theKernel);
+
+ /* Bring board into inactive post-reset state again */
+ cleanup_before_linux ();
+
+ /* Jump to kernel entry point */
+ theKernel (0, m68k_architecture, 0xdeadbeaf);
+
+ enable_interrupts();
+ printf("Error: Loaded kernel returned. Probably it couldn't\n"
+ "find it's bootrecord.\n");
+ return -1;
+}
+
+/*
+ * Register handler for m68k Kernel Images
+ */
+static int image_handle_cmdline_parse(struct image_data *data, int opt, char *optarg)
+{
+ switch (opt)
+ {
+ case 'a':
+ m68k_architecture = simple_strtoul(optarg, NULL, 0);
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static struct image_handler handler =
+{
+ .cmdline_options = "a:",
+ .cmdline_parse = image_handle_cmdline_parse,
+ .help_string = " -a <arch> use architecture number <arch>",
+
+ .bootm = do_bootm_linux,
+ .image_type = IH_OS_LINUX,
+};
+
+static int m68klinux_register_image_handler(void)
+{
+ return register_image_handler(&handler);
+}
+
+late_initcall(m68klinux_register_image_handler);
diff --git a/arch/m68k/lib/m68k-meminit.c b/arch/m68k/lib/m68k-meminit.c
new file mode 100644
index 0000000000..b7905c2851
--- /dev/null
+++ b/arch/m68k/lib/m68k-meminit.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Init for memory allocator on m68k/Coldfire
+ */
+#include <common.h>
+#include <init.h>
+#include <mem_malloc.h>
+#include <asm/u-boot-m68k.h>
+#include <reloc.h>
+
+/** Initialize mem allocator on M68k/Coldfire
+ */
+int m68k_mem_malloc_init(void)
+{
+ /* Pass start and end address of managed memory */
+
+ mem_malloc_init((void *)(&_u_boot_start - CFG_MALLOC_LEN),
+ (void *)&_u_boot_start);
+
+ return 0;
+}
+
+core_initcall(m68k_mem_malloc_init);
diff --git a/arch/m68k/lib/m68k-module.c b/arch/m68k/lib/m68k-module.c
new file mode 100644
index 0000000000..e1fe461a3a
--- /dev/null
+++ b/arch/m68k/lib/m68k-module.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Moduleloader Subsystem
+ *
+ * These relocation stubs are taken from Linux 2.6.10 They are used by the
+ * higher level ELF loader code to place ELF files to arbitrary addresses.
+ */
+#include <common.h>
+#include <elf.h>
+#include <module.h>
+#include <errno.h>
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ unsigned int i;
+ Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location;
+
+ DEBUGP("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+ case R_68K_32:
+ /* We add the value into the location given */
+ *location += sym->st_value;
+ break;
+ case R_68K_PC32:
+ /* Add the value, subtract its postition */
+ *location += sym->st_value - (uint32_t)location;
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+ me->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ unsigned int i;
+ Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location;
+
+ DEBUGP("Applying relocate_add section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+ case R_68K_32:
+ /* We add the value into the location given */
+ *location = rel[i].r_addend + sym->st_value;
+ break;
+ case R_68K_PC32:
+ /* Add the value, subtract its postition */
+ *location = rel[i].r_addend + sym->st_value - (uint32_t)location;
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+ me->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
diff --git a/arch/m68k/lib/u-boot.lds.S b/arch/m68k/lib/u-boot.lds.S
new file mode 100644
index 0000000000..823e17a9de
--- /dev/null
+++ b/arch/m68k/lib/u-boot.lds.S
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Generic Linker file for M68k targets
+ */
+#include <asm-generic/u-boot.lds.h>
+
+OUTPUT_FORMAT("elf32-m68k", "elf32-m68k",
+ "elf32-m68k")
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+SECTIONS
+{
+ . = TEXT_BASE;
+ . = ALIGN(4);
+
+ /* Start of vector, text and rodata section */
+ _stext = .;
+ _text = .;
+
+ /* M68k/CF style vector table */
+ .vectors :
+ {
+ *(.vectors)
+ }
+
+ .text :
+ {
+ *(.text .stub .text.*)
+ } =0x4e754e75
+
+ . = ALIGN(4);
+ .rodata :
+ {
+ *(.rodata .rodata.*)
+ } =0xdeadbeef
+
+ . = ALIGN(4);
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { U_BOOT_CMDS }
+ __u_boot_cmd_end = .;
+
+ __u_boot_initcalls_start = .;
+ .u_boot_initcalls : { INITCALLS }
+ __u_boot_initcalls_end = .;
+
+ __usymtab_start = .;
+ __usymtab : { U_BOOT_SYMS }
+ __usymtab_end = .;
+
+ /* End of text and rodata section */
+ . = ALIGN(4);
+ _etext = .;
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+ . = ALIGN(4);
+
+ . = ALIGN(4);
+ __early_init_data_begin = .;
+ .early_init_data : { *(.early_init_data) }
+ __early_init_data_end = .;
+
+ .data : { *(.data .data.*) }
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss (NOLOAD) : { *(.bss .bass.*) }
+ __bss_end =.;
+ _end = .;
+
+ . = ALIGN(4);
+ _u_boot_heap_start = .;
+}
diff --git a/arch/m68k/mach-mcfv4e.dox b/arch/m68k/mach-mcfv4e.dox
new file mode 100644
index 0000000000..0ecfbc2c9d
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e.dox
@@ -0,0 +1,39 @@
+/* This document is intended to provide the developer with information
+ * how to integrate a new CPU (MACH) into this part of the U-Boot tree
+ */
+
+/** @page dev_m68k_mach M68k/Coldfire based CPU (MACH) into the tree
+
+FIXME - fill in further info about Coldfire and so on. Check code
+ for compliance with the specs given below - move code otherwise.
+
+@par What's happens when the reset signal is gone
+
+@note Code running immediately after reset runs at an address it is not linked
+ to: "runtime address != link address". You should only use branches and
+ do not refer to fixed data. This implies the use of assembler code only.
+
+The M68k CPU starts at lable \<reset\> in one of the corresponding start-*.S
+files. After some basic hardware setup it can call a function
+\<arch_init_lowlevel\> if not disabled. This call is intended to give all
+developers a chance to use a standard reset vector file, but also do some
+special things required only on their specific CPU.
+
+After handling some MMU, Stack or similiar issues, \<board_init_lowlevel\> can
+be called (if not disabled). This is a board specific function for SDRAM setup
+for example. As its board specific, your can do whatever you need to bring
+your board up. As stack is already set to internal core RAM, this routine can
+be C.
+
+@note: You are not allowed to call other code here, because we are not running
+ at link address.
+
+When \<board_init_lowlevel\> returns it will be assumed that there is now
+working RAM that can be used for all further steps.
+
+Next step is relocation of U-Boot itself. It gets copied to the end of
+available RAM and the last assembly instruction is a jump to \<start_uboot\>.
+
+At this point of time: "runtime address == link address".
+
+*/
diff --git a/arch/m68k/mach-mcfv4e/Kconfig b/arch/m68k/mach-mcfv4e/Kconfig
new file mode 100644
index 0000000000..aaba27e5e8
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/Kconfig
@@ -0,0 +1,18 @@
+
+menu "M68k/Coldfire V4E specific settings"
+
+config COPY_LOWMEM_VECTORS
+ bool "Copy vectors to SDRAM address 0"
+ default y
+ help
+ This copies the vector table to SDRAM address 0 (default address)
+
+config USE_LOWMEM_VECTORS
+ bool "Use vectors at SDRAM address 0"
+ default n
+ depends on COPY_LOWMEM_VECTORS
+ help
+ This copies the vector table to SDRAM address 0 (default address) and
+ also uses this vector location
+
+endmenu
diff --git a/arch/m68k/mach-mcfv4e/Makefile b/arch/m68k/mach-mcfv4e/Makefile
new file mode 100644
index 0000000000..f75834be54
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/Makefile
@@ -0,0 +1,19 @@
+#
+# Generic code for Coldfire V4E targets (MCF547x/MCF548x)
+#
+obj-y += mcf_clocksource.o
+obj-y += mcf_reset_cpu.o
+
+#
+# FEC support
+#
+obj-y += multichannel_dma.o
+obj-y += dma_utils.o
+obj-y += fec.o
+obj-y += fecbd.o
+
+#
+# FreeScale MultiDMA Library
+#
+obj-y += mcdapi/
+obj-y += net/
diff --git a/arch/m68k/mach-mcfv4e/dma_utils.c b/arch/m68k/mach-mcfv4e/dma_utils.c
new file mode 100644
index 0000000000..15b520abc2
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/dma_utils.c
@@ -0,0 +1,502 @@
+/*
+ * File: dma_utils.c
+ * Purpose: General purpose utilities for the multi-channel DMA
+ *
+ * Notes: The methodology used in these utilities assumes that
+ * no single initiator will be tied to more than one
+ * task/channel
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/types.h>
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+
+#include <asm/proc/dma_utils.h>
+
+/*
+ * This global keeps track of which initiators have been
+ * used of the available assignments. Initiators 0-15 are
+ * hardwired. Initiators 16-31 are multiplexed and controlled
+ * via the Initiatior Mux Control Registe (IMCR). The
+ * assigned requestor is stored with the associated initiator
+ * number.
+ */
+static int8_t used_reqs[32] =
+{
+ DMA_ALWAYS, DMA_DSPI_RX, DMA_DSPI_TX, DMA_DREQ0,
+ DMA_PSC0_RX, DMA_PSC0_TX, DMA_USBEP0, DMA_USBEP1,
+ DMA_USBEP2, DMA_USBEP3, DMA_PCI_TX, DMA_PCI_RX,
+ DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+/*
+ * This global keeps track of which channels have been assigned
+ * to tasks. This methology assumes that no single initiator
+ * will be tied to more than one task/channel
+ */
+typedef struct
+{
+ int req;
+ void (*handler)(void);
+} DMA_CHANNEL_STRUCT;
+
+static DMA_CHANNEL_STRUCT dma_channel[NCHANNELS] =
+{
+ {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL},
+ {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL},
+ {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL},
+ {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL}
+};
+
+/*
+ * Enable all DMA interrupts
+ *
+ * Parameters:
+ * pri Interrupt Priority
+ * lvl Interrupt Level
+ */
+void
+dma_irq_enable(uint8_t lvl, uint8_t pri)
+{
+//FIXME ASSERT(lvl > 0 && lvl < 8);
+//FIXME ASSERT(pri < 8);
+
+ /* Setup the DMA ICR (#48) */
+ MCF_INTC_ICR48 = 0
+ | MCF_INTC_ICRn_IP(pri)
+ | MCF_INTC_ICRn_IL(lvl);
+
+ /* Unmask all task interrupts */
+ MCF_DMA_DIMR = 0;
+
+ /* Clear the interrupt pending register */
+ MCF_DMA_DIPR = 0;
+
+ /* Unmask the DMA interrupt in the interrupt controller */
+ MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK48;
+}
+
+/*
+ * Disable all DMA interrupts
+ */
+void
+dma_irq_disable(void)
+{
+ /* Mask all task interrupts */
+ MCF_DMA_DIMR = (uint32_t)~0;
+
+ /* Clear any pending task interrupts */
+ MCF_DMA_DIPR = (uint32_t)~0;
+
+ /* Mask the DMA interrupt in the interrupt controller */
+ MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK48;
+}
+
+/*
+ * Attempt to enable the provided Initiator in the Initiator
+ * Mux Control Register
+ *
+ * Parameters:
+ * initiator Initiator identifier
+ *
+ * Return Value:
+ * 1 if unable to make the assignment
+ * 0 successful
+ */
+int
+dma_set_initiator(int initiator)
+{
+ switch (initiator)
+ {
+ /* These initiators are always active */
+ case DMA_ALWAYS:
+ case DMA_DSPI_RX:
+ case DMA_DSPI_TX:
+ case DMA_DREQ0:
+ case DMA_PSC0_RX:
+ case DMA_PSC0_TX:
+ case DMA_USBEP0:
+ case DMA_USBEP1:
+ case DMA_USBEP2:
+ case DMA_USBEP3:
+ case DMA_PCI_TX:
+ case DMA_PCI_RX:
+ case DMA_PSC1_RX:
+ case DMA_PSC1_TX:
+ case DMA_I2C_RX:
+ case DMA_I2C_TX:
+ break;
+ case DMA_FEC0_RX:
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC16(3))
+ | MCF_DMA_IMCR_SRC16_FEC0RX;
+ used_reqs[16] = DMA_FEC0_RX;
+ break;
+ case DMA_FEC0_TX:
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC17(3))
+ | MCF_DMA_IMCR_SRC17_FEC0TX;
+ used_reqs[17] = DMA_FEC0_TX;
+ break;
+ case DMA_FEC1_RX:
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC20(3))
+ | MCF_DMA_IMCR_SRC20_FEC1RX;
+ used_reqs[20] = DMA_FEC1_RX;
+ break;
+ case DMA_FEC1_TX:
+ if (used_reqs[21] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3))
+ | MCF_DMA_IMCR_SRC21_FEC1TX;
+ used_reqs[21] = DMA_FEC1_TX;
+ }
+ else if (used_reqs[25] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3))
+ | MCF_DMA_IMCR_SRC25_FEC1TX;
+ used_reqs[25] = DMA_FEC1_TX;
+ }
+ else if (used_reqs[31] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
+ | MCF_DMA_IMCR_SRC31_FEC1TX;
+ used_reqs[31] = DMA_FEC1_TX;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_DREQ1:
+ if (used_reqs[29] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
+ | MCF_DMA_IMCR_SRC29_DREQ1;
+ used_reqs[29] = DMA_DREQ1;
+ }
+ else if (used_reqs[21] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3))
+ | MCF_DMA_IMCR_SRC21_DREQ1;
+ used_reqs[21] = DMA_DREQ1;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM0:
+ if (used_reqs[24] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC24(3))
+ | MCF_DMA_IMCR_SRC24_CTM0;
+ used_reqs[24] = DMA_CTM0;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM1:
+ if (used_reqs[25] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3))
+ | MCF_DMA_IMCR_SRC25_CTM1;
+ used_reqs[25] = DMA_CTM1;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM2:
+ if (used_reqs[26] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3))
+ | MCF_DMA_IMCR_SRC26_CTM2;
+ used_reqs[26] = DMA_CTM2;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM3:
+ if (used_reqs[27] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3))
+ | MCF_DMA_IMCR_SRC27_CTM3;
+ used_reqs[27] = DMA_CTM3;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM4:
+ if (used_reqs[28] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
+ | MCF_DMA_IMCR_SRC28_CTM4;
+ used_reqs[28] = DMA_CTM4;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM5:
+ if (used_reqs[29] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
+ | MCF_DMA_IMCR_SRC29_CTM5;
+ used_reqs[29] = DMA_CTM5;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM6:
+ if (used_reqs[30] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3))
+ | MCF_DMA_IMCR_SRC30_CTM6;
+ used_reqs[30] = DMA_CTM6;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_CTM7:
+ if (used_reqs[31] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
+ | MCF_DMA_IMCR_SRC31_CTM7;
+ used_reqs[31] = DMA_CTM7;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_USBEP4:
+ if (used_reqs[26] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3))
+ | MCF_DMA_IMCR_SRC26_USBEP4;
+ used_reqs[26] = DMA_USBEP4;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_USBEP5:
+ if (used_reqs[27] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3))
+ | MCF_DMA_IMCR_SRC27_USBEP5;
+ used_reqs[27] = DMA_USBEP5;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_USBEP6:
+ if (used_reqs[28] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
+ | MCF_DMA_IMCR_SRC28_USBEP6;
+ used_reqs[28] = DMA_USBEP6;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_PSC2_RX:
+ if (used_reqs[28] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
+ | MCF_DMA_IMCR_SRC28_PSC2RX;
+ used_reqs[28] = DMA_PSC2_RX;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_PSC2_TX:
+ if (used_reqs[29] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
+ | MCF_DMA_IMCR_SRC29_PSC2TX;
+ used_reqs[29] = DMA_PSC2_TX;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_PSC3_RX:
+ if (used_reqs[30] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3))
+ | MCF_DMA_IMCR_SRC30_PSC3RX;
+ used_reqs[30] = DMA_PSC3_RX;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ case DMA_PSC3_TX:
+ if (used_reqs[31] == 0)
+ {
+ MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
+ | MCF_DMA_IMCR_SRC31_PSC3TX;
+ used_reqs[31] = DMA_PSC3_TX;
+ }
+ else /* No empty slots */
+ return 1;
+ break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Return the initiator number for the given requestor
+ *
+ * Parameters:
+ * requestor Initiator/Requestor identifier
+ *
+ * Return Value:
+ * The initiator number (0-31) if initiator has been assigned
+ * 0 (always initiator) otherwise
+ */
+uint32_t
+dma_get_initiator(int requestor)
+{
+ uint32_t i;
+
+ for (i=0; i<sizeof(used_reqs); ++i)
+ {
+ if (used_reqs[i] == requestor)
+ return i;
+ }
+ return 0;
+}
+
+/*
+ * Remove the given initiator from the active list
+ *
+ * Parameters:
+ * requestor Initiator/Requestor identifier
+ */
+void
+dma_free_initiator(int requestor)
+{
+ uint32_t i;
+
+ for (i=16; i<sizeof(used_reqs); ++i)
+ {
+ if (used_reqs[i] == requestor)
+ {
+ used_reqs[i] = 0;
+ break;
+ }
+ }
+}
+
+/*
+ * Attempt to find an available channel and mark it as used
+ *
+ * Parameters:
+ * requestor Initiator/Requestor identifier
+ *
+ * Return Value:
+ * First available channel or -1 if they are all occupied
+ */
+int
+dma_set_channel(int requestor, void (*handler)(void))
+{
+ int i;
+
+ /* Check to see if this requestor is already assigned to a channel */
+ if ((i = dma_get_channel(requestor)) != -1)
+ return i;
+
+ for (i=0; i<NCHANNELS; ++i)
+ {
+ if (dma_channel[i].req == -1)
+ {
+ dma_channel[i].req = requestor;
+ dma_channel[i].handler = handler;
+ return i;
+ }
+ }
+
+ /* All channels taken */
+ return -1;
+}
+
+/*
+ * Return the channel being initiated by the given requestor
+ *
+ * Parameters:
+ * requestor Initiator/Requestor identifier
+ *
+ * Return Value:
+ * Channel that the requestor is controlling or -1 if hasn't been
+ * activated
+ */
+int
+dma_get_channel(int requestor)
+{
+ uint32_t i;
+
+ for (i=0; i<NCHANNELS; ++i)
+ {
+ if (dma_channel[i].req == requestor)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Remove the channel being initiated by the given requestor from
+ * the active list
+ *
+ * Parameters:
+ * requestor Initiator/Requestor identifier
+ */
+void
+dma_free_channel(int requestor)
+{
+ uint32_t i;
+
+ for (i=0; i<NCHANNELS; ++i)
+ {
+ if (dma_channel[i].req == requestor)
+ {
+ dma_channel[i].req = -1;
+ dma_channel[i].handler = NULL;
+ break;
+ }
+ }
+}
+
+/*
+ * This is the catch-all interrupt handler for the mult-channel DMA
+ */
+int
+dma_interrupt_handler (void *arg1, void *arg2)
+{
+ uint32_t i, interrupts;
+ (void)arg1;
+ (void)arg2;
+
+ disable_interrupts(); // was: board_irq_disable();
+
+ /*
+ * Determine which interrupt(s) triggered by AND'ing the
+ * pending interrupts with those that aren't masked.
+ */
+ interrupts = MCF_DMA_DIPR & ~MCF_DMA_DIMR;
+
+ /* Make sure we are here for a reason */
+// ASSERT(interrupts != 0);
+
+ /* Clear the interrupt in the pending register */
+ MCF_DMA_DIPR = interrupts;
+
+ for (i=0; i<16; ++i, interrupts>>=1)
+ {
+ if (interrupts & 0x1)
+ {
+ /* If there is a handler, call it */
+ if (dma_channel[i].handler != NULL)
+ dma_channel[i].handler();
+ }
+ }
+
+ enable_interrupts(); // board_irq_enable();
+ return 1;
+}
diff --git a/arch/m68k/mach-mcfv4e/fec.c b/arch/m68k/mach-mcfv4e/fec.c
new file mode 100644
index 0000000000..551f00f005
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/fec.c
@@ -0,0 +1,1440 @@
+/*
+ * File: fec.c
+ * Purpose: Driver for the Fast Ethernet Controller (FEC)
+ *
+ * Notes:
+ */
+#include <common.h>
+#include <linux/types.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/net/net.h>
+#include <asm/proc/fecbd.h>
+#include <asm/proc/fec.h>
+#include <asm/proc/dma_utils.h>
+
+
+#define TRUE 1
+#define FALSE 0
+#define ASSERT(x) if (!(x)) hang();
+#define nop() __asm__ __volatile__("nop\n")
+
+
+FEC_EVENT_LOG fec_log[2];
+
+/*
+ * Write a value to a PHY's MII register.
+ *
+ * Parameters:
+ * ch FEC channel
+ * phy_addr Address of the PHY.
+ * reg_addr Address of the register in the PHY.
+ * data Data to be written to the PHY register.
+ *
+ * Return Values:
+ * 1 on failure
+ * 0 on success.
+ *
+ * Please refer to your PHY manual for registers and their meanings.
+ * mii_write() polls for the FEC's MII interrupt event (which should
+ * be masked from the interrupt handler) and clears it. If after a
+ * suitable amount of time the event isn't triggered, a value of 0
+ * is returned.
+ */
+int
+fec_mii_write(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
+{
+ int timeout;
+ uint32_t eimr;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Clear the MII interrupt bit
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII;
+
+ /*
+ * Write to the MII Management Frame Register to kick-off
+ * the MII write
+ */
+ MCF_FEC_MMFR(ch) = 0
+ | MCF_FEC_MMFR_ST_01
+ | MCF_FEC_MMFR_OP_WRITE
+ | MCF_FEC_MMFR_PA(phy_addr)
+ | MCF_FEC_MMFR_RA(reg_addr)
+ | MCF_FEC_MMFR_TA_10
+ | MCF_FEC_MMFR_DATA(data);
+
+ /*
+ * Mask the MII interrupt
+ */
+ eimr = MCF_FEC_EIMR(ch);
+ MCF_FEC_EIMR(ch) &= ~MCF_FEC_EIMR_MII;
+
+ /*
+ * Poll for the MII interrupt (interrupt should be masked)
+ */
+ for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
+ {
+ if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
+ break;
+ }
+ if(timeout == FEC_MII_TIMEOUT)
+ return 1;
+
+ /*
+ * Clear the MII interrupt bit
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII;
+
+ /*
+ * Restore the EIMR
+ */
+ MCF_FEC_EIMR(ch) = eimr;
+
+ return 0;
+}
+
+/*
+ * Read a value from a PHY's MII register.
+ *
+ * Parameters:
+ * ch FEC channel
+ * phy_addr Address of the PHY.
+ * reg_addr Address of the register in the PHY.
+ * data Pointer to storage for the Data to be read
+ * from the PHY register (passed by reference)
+ *
+ * Return Values:
+ * 1 on failure
+ * 0 on success.
+ *
+ * Please refer to your PHY manual for registers and their meanings.
+ * mii_read() polls for the FEC's MII interrupt event (which should
+ * be masked from the interrupt handler) and clears it. If after a
+ * suitable amount of time the event isn't triggered, a value of 0
+ * is returned.
+ */
+int
+fec_mii_read(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
+{
+ int timeout;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Clear the MII interrupt bit
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII;
+
+ /*
+ * Write to the MII Management Frame Register to kick-off
+ * the MII read
+ */
+ MCF_FEC_MMFR(ch) = 0
+ | MCF_FEC_MMFR_ST_01
+ | MCF_FEC_MMFR_OP_READ
+ | MCF_FEC_MMFR_PA(phy_addr)
+ | MCF_FEC_MMFR_RA(reg_addr)
+ | MCF_FEC_MMFR_TA_10;
+
+ /*
+ * Poll for the MII interrupt (interrupt should be masked)
+ */
+ for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
+ {
+ if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
+ break;
+ }
+
+ if(timeout == FEC_MII_TIMEOUT)
+ return 1;
+
+ /*
+ * Clear the MII interrupt bit
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII;
+
+ *data = (uint16_t)(MCF_FEC_MMFR(ch) & 0x0000FFFF);
+
+ return 0;
+}
+
+/*
+ * Initialize the MII interface controller
+ *
+ * Parameters:
+ * ch FEC channel
+ * sys_clk System Clock Frequency (in MHz)
+ */
+void
+fec_mii_init(uint8_t ch, uint32_t sys_clk)
+{
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Initialize the MII clock (EMDC) frequency
+ *
+ * Desired MII clock is 2.5MHz
+ * MII Speed Setting = System_Clock / (2.5MHz * 2)
+ * (plus 1 to make sure we round up)
+ */
+ MCF_FEC_MSCR(ch) = MCF_FEC_MSCR_MII_SPEED((sys_clk/5)+1);
+}
+
+/* Initialize the MIB counters
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_mib_init(uint8_t ch)
+{
+ ASSERT(ch == 0 || ch == 1);
+//To do
+}
+
+/* Display the MIB counters
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_mib_dump(uint8_t ch)
+{
+ ASSERT(ch == 0 || ch == 1);
+//To do
+}
+
+/* Initialize the FEC log
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_log_init(uint8_t ch)
+{
+ ASSERT(ch == 0 || ch == 1);
+ memset(&fec_log[ch],0,sizeof(FEC_EVENT_LOG));
+}
+
+/* Display the FEC log
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_log_dump(uint8_t ch)
+{
+ ASSERT(ch == 0 || ch == 1);
+ printf("\n FEC%d Log\n---------------\n",ch);
+ printf("Total: %4d\n",fec_log[ch].total);
+ printf("hberr: %4d\n",fec_log[ch].hberr);
+ printf("babr: %4d\n",fec_log[ch].babr);
+ printf("babt: %4d\n",fec_log[ch].babt);
+ printf("gra: %4d\n",fec_log[ch].gra);
+ printf("txf: %4d\n",fec_log[ch].txf);
+ printf("mii: %4d\n",fec_log[ch].mii);
+ printf("lc: %4d\n",fec_log[ch].lc);
+ printf("rl: %4d\n",fec_log[ch].rl);
+ printf("xfun: %4d\n",fec_log[ch].xfun);
+ printf("xferr: %4d\n",fec_log[ch].xferr);
+ printf("rferr: %4d\n",fec_log[ch].rferr);
+ printf("dtxf: %4d\n",fec_log[ch].dtxf);
+ printf("drxf: %4d\n",fec_log[ch].drxf);
+ printf("\nRFSW:\n");
+ printf("inv: %4d\n",fec_log[ch].rfsw_inv);
+ printf("m: %4d\n",fec_log[ch].rfsw_m);
+ printf("bc: %4d\n",fec_log[ch].rfsw_bc);
+ printf("mc: %4d\n",fec_log[ch].rfsw_mc);
+ printf("lg: %4d\n",fec_log[ch].rfsw_lg);
+ printf("no: %4d\n",fec_log[ch].rfsw_no);
+ printf("cr: %4d\n",fec_log[ch].rfsw_cr);
+ printf("ov: %4d\n",fec_log[ch].rfsw_ov);
+ printf("tr: %4d\n",fec_log[ch].rfsw_tr);
+ printf("---------------\n\n");
+}
+
+/*
+ * Display some of the registers for debugging
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_debug_dump(uint8_t ch)
+{
+ printf("\n------------- FEC%d -------------\n",ch);
+ printf("EIR %08x \n",MCF_FEC_EIR(ch));
+ printf("EIMR %08x \n",MCF_FEC_EIMR(ch));
+ printf("ECR %08x \n",MCF_FEC_ECR(ch));
+ printf("RCR %08x \n",MCF_FEC_RCR(ch));
+ printf("R_HASH %08x \n",MCF_FEC_R_HASH(ch));
+ printf("TCR %08x \n",MCF_FEC_TCR(ch));
+ printf("FECTFWR %08x \n",MCF_FEC_FECTFWR(ch));
+ printf("FECRFSR %08x \n",MCF_FEC_FECRFSR(ch));
+ printf("FECRFCR %08x \n",MCF_FEC_FECRFCR(ch));
+ printf("FECRLRFP %08x \n",MCF_FEC_FECRLRFP(ch));
+ printf("FECRLWFP %08x \n",MCF_FEC_FECRLWFP(ch));
+ printf("FECRFAR %08x \n",MCF_FEC_FECRFAR(ch));
+ printf("FECRFRP %08x \n",MCF_FEC_FECRFRP(ch));
+ printf("FECRFWP %08x \n",MCF_FEC_FECRFWP(ch));
+ printf("FECTFSR %08x \n",MCF_FEC_FECTFSR(ch));
+ printf("FECTFCR %08x \n",MCF_FEC_FECTFCR(ch));
+ printf("FECTLRFP %08x \n",MCF_FEC_FECTLRFP(ch));
+ printf("FECTLWFP %08x \n",MCF_FEC_FECTLWFP(ch));
+ printf("FECTFAR %08x \n",MCF_FEC_FECTFAR(ch));
+ printf("FECTFRP %08x \n",MCF_FEC_FECTFRP(ch));
+ printf("FECTFWP %08x \n",MCF_FEC_FECTFWP(ch));
+ printf("FRST %08x \n",MCF_FEC_FRST(ch));
+ printf("--------------------------------\n\n");
+}
+
+/*
+ * Set the duplex on the selected FEC controller
+ *
+ * Parameters:
+ * ch FEC channel
+ * duplex FEC_MII_FULL_DUPLEX or FEC_MII_HALF_DUPLEX
+ */
+void
+fec_duplex (uint8_t ch, uint8_t duplex)
+{
+ ASSERT(ch == 0 || ch == 1);
+
+ switch (duplex)
+ {
+ case FEC_MII_HALF_DUPLEX:
+ MCF_FEC_RCR(ch) |= MCF_FEC_RCR_DRT;
+ MCF_FEC_TCR(ch) &= (uint32_t)~MCF_FEC_TCR_FDEN;
+ break;
+ case FEC_MII_FULL_DUPLEX:
+ default:
+ MCF_FEC_RCR(ch) &= (uint32_t)~MCF_FEC_RCR_DRT;
+ MCF_FEC_TCR(ch) |= MCF_FEC_TCR_FDEN;
+ break;
+ }
+}
+
+/*
+ * Generate the hash table settings for the given address
+ *
+ * Parameters:
+ * addr 48-bit (6 byte) Address to generate the hash for
+ *
+ * Return Value:
+ * The 6 most significant bits of the 32-bit CRC result
+ */
+uint8_t
+fec_hash_address(const uint8_t *addr)
+{
+ uint32_t crc;
+ uint8_t byte;
+ int i, j;
+
+ crc = 0xFFFFFFFF;
+ for(i=0; i<6; ++i)
+ {
+ byte = addr[i];
+ for(j=0; j<8; ++j)
+ {
+ if((byte & 0x01)^(crc & 0x01))
+ {
+ crc >>= 1;
+ crc = crc ^ 0xEDB88320;
+ }
+ else
+ crc >>= 1;
+ byte >>= 1;
+ }
+ }
+ return (uint8_t)(crc >> 26);
+}
+
+/*
+ * Set the Physical (Hardware) Address and the Individual Address
+ * Hash in the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ * pa Physical (Hardware) Address for the selected FEC
+ */
+void
+fec_set_address (uint8_t ch, const uint8_t *pa)
+{
+ uint8_t crc;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Set the Physical Address
+ */
+ MCF_FEC_PALR(ch) = (uint32_t)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]);
+ MCF_FEC_PAUR(ch) = (uint32_t)((pa[4]<<24) | (pa[5]<<16));
+
+ /*
+ * Calculate and set the hash for given Physical Address
+ * in the Individual Address Hash registers
+ */
+ crc = fec_hash_address(pa);
+ if(crc >= 32)
+ MCF_FEC_IAUR(ch) |= (uint32_t)(1 << (crc - 32));
+ else
+ MCF_FEC_IALR(ch) |= (uint32_t)(1 << crc);
+}
+
+/*
+ * Reset the selected FEC controller
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_reset (uint8_t ch)
+{
+ int i;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /* Clear any events in the FIFO status registers */
+ MCF_FEC_FECRFSR(ch) = (0
+ | MCF_FEC_FECRFSR_OF
+ | MCF_FEC_FECRFSR_UF
+ | MCF_FEC_FECRFSR_RXW
+ | MCF_FEC_FECRFSR_FAE
+ | MCF_FEC_FECRFSR_IP);
+ MCF_FEC_FECTFSR(ch) = (0
+ | MCF_FEC_FECRFSR_OF
+ | MCF_FEC_FECRFSR_UF
+ | MCF_FEC_FECRFSR_RXW
+ | MCF_FEC_FECRFSR_FAE
+ | MCF_FEC_FECRFSR_IP);
+
+ /* Reset the FIFOs */
+ MCF_FEC_FRST(ch) |= MCF_FEC_FRST_SW_RST;
+ MCF_FEC_FRST(ch) &= ~MCF_FEC_FRST_SW_RST;
+
+ /* Set the Reset bit and clear the Enable bit */
+ MCF_FEC_ECR(ch) = MCF_FEC_ECR_RESET;
+
+ /* Wait at least 8 clock cycles */
+ for (i=0; i<10; ++i)
+ nop();
+}
+
+/*
+ * Initialize the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ * mode External interface mode (MII, 7-wire, or internal loopback)
+ * pa Physical (Hardware) Address for the selected FEC
+ */
+void
+fec_init (uint8_t ch, uint8_t mode, const uint8_t *pa)
+{
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Enable all the external interface signals
+ */
+ if (mode == FEC_MODE_7WIRE)
+ {
+ if (ch == 1)
+ MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E17;
+ else
+ MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E07;
+ }
+ else if (mode == FEC_MODE_MII)
+ {
+ if (ch == 1)
+ MCF_GPIO_PAR_FECI2CIRQ |= 0
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MII
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E17;
+ else
+ MCF_GPIO_PAR_FECI2CIRQ |= 0
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII
+ | MCF_GPIO_PAR_FECI2CIRQ_PAR_E07;
+ }
+
+ /*
+ * Clear the Individual and Group Address Hash registers
+ */
+ MCF_FEC_IALR(ch) = 0;
+ MCF_FEC_IAUR(ch) = 0;
+ MCF_FEC_GALR(ch) = 0;
+ MCF_FEC_GAUR(ch) = 0;
+
+ /*
+ * Set the Physical Address for the selected FEC
+ */
+ fec_set_address(ch, pa);
+
+ /*
+ * Mask all FEC interrupts
+ */
+ MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL;
+
+ /*
+ * Clear all FEC interrupt events
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL;
+
+ /*
+ * Initialize the Receive Control Register
+ */
+ MCF_FEC_RCR(ch) = 0
+ | MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM)
+ #ifdef FEC_PROMISCUOUS
+ | MCF_FEC_RCR_PROM
+ #endif
+ | MCF_FEC_RCR_FCE;
+
+ if (mode == FEC_MODE_MII)
+ MCF_FEC_RCR(ch) |= MCF_FEC_RCR_MII_MODE;
+
+ else if (mode == FEC_MODE_LOOPBACK)
+ MCF_FEC_RCR(ch) |= MCF_FEC_RCR_LOOP;
+
+ /*
+ * Initialize the Transmit Control Register
+ */
+ MCF_FEC_TCR(ch) = MCF_FEC_TCR_FDEN;
+
+ /*
+ * Set Rx FIFO alarm and granularity
+ */
+ MCF_FEC_FECRFCR(ch) = 0
+ | MCF_FEC_FECRFCR_FRM
+ | MCF_FEC_FECRFCR_RXW_MSK
+ | MCF_FEC_FECRFCR_GR(7);
+ MCF_FEC_FECRFAR(ch) = MCF_FEC_FECRFAR_ALARM(768);
+
+ /*
+ * Set Tx FIFO watermark, alarm and granularity
+ */
+ MCF_FEC_FECTFCR(ch) = 0
+ | MCF_FEC_FECTFCR_FRM
+ | MCF_FEC_FECTFCR_TXW_MSK
+ | MCF_FEC_FECTFCR_GR(7);
+ MCF_FEC_FECTFAR(ch) = MCF_FEC_FECTFAR_ALARM(256);
+ MCF_FEC_FECTFWR(ch) = MCF_FEC_FECTFWR_X_WMRK_256;
+
+ /*
+ * Enable the transmitter to append the CRC
+ */
+ MCF_FEC_CTCWR(ch) = 0
+ | MCF_FEC_CTCWR_TFCW
+ | MCF_FEC_CTCWR_CRC;
+}
+
+/*
+ * Start the FEC Rx DMA task
+ *
+ * Parameters:
+ * ch FEC channel
+ * rxbd First Rx buffer descriptor in the chain
+ */
+void
+fec_rx_start(uint8_t ch, int8_t *rxbd)
+{
+ uint32_t initiator;
+ int channel, result;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Make the initiator assignment
+ */
+ result = dma_set_initiator(DMA_FEC_RX(ch));
+ ASSERT(result == 0);
+
+ /*
+ * Grab the initiator number
+ */
+ initiator = dma_get_initiator(DMA_FEC_RX(ch));
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_set_channel(DMA_FEC_RX(ch),
+ (ch == 0) ? fec0_rx_frame : fec1_rx_frame);
+ ASSERT(channel != -1);
+
+ /*
+ * Start the Rx DMA task
+ */
+ /*
+ * Start the Rx DMA task
+ */
+ MCD_startDma(channel,
+ (s8*)rxbd,
+ 0,
+ (s8*)MCF_FEC_FECRFDR_ADDR(ch),
+ 0,
+ RX_BUF_SZ,
+ 0,
+ initiator,
+ FECRX_DMA_PRI(ch),
+ 0
+ | MCD_FECRX_DMA
+ | MCD_INTERRUPT
+ | MCD_TT_FLAGS_CW
+ | MCD_TT_FLAGS_RL
+ | MCD_TT_FLAGS_SP
+ ,
+ 0
+ | MCD_NO_CSUM
+ | MCD_NO_BYTE_SWAP
+ );
+}
+
+/*
+ * Continue the Rx DMA task
+ *
+ * This routine is called after the DMA task has halted after
+ * encountering an Rx buffer descriptor that wasn't marked as
+ * ready. There is no harm in calling the DMA continue routine
+ * if the DMA is not halted.
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_rx_continue(uint8_t ch)
+{
+ int channel;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_get_channel(DMA_FEC_RX(ch));
+ ASSERT(channel != -1);
+
+ /*
+ * Continue/restart the DMA task
+ */
+ MCD_continDma(channel);
+}
+
+/*
+ * Stop all frame receptions on the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_rx_stop (uint8_t ch)
+{
+ uint32_t mask;
+ int channel;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /* Save off the EIMR value */
+ mask = MCF_FEC_EIMR(ch);
+
+ /* Mask all interrupts */
+ MCF_FEC_EIMR(ch) = 0;
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_get_channel(DMA_FEC_RX(ch));
+ ASSERT(channel != -1);
+
+ /* Kill the FEC Rx DMA task */
+ MCD_killDma(channel);
+
+ /*
+ * Free up the FEC requestor from the software maintained
+ * initiator list
+ */
+ dma_free_initiator(DMA_FEC_RX(ch));
+
+ /* Free up the DMA channel */
+ dma_free_channel(DMA_FEC_RX(ch));
+
+ /* Restore the interrupt mask register value */
+ MCF_FEC_EIMR(ch) = mask;
+}
+
+/*
+ * Receive Frame interrupt handler - this handler is called by the
+ * DMA interrupt handler indicating that a packet was successfully
+ * transferred out of the Rx FIFO.
+ *
+ * Parameters:
+ * nif Pointer to Network Interface structure
+ * ch FEC channel
+ */
+NBUF *
+fec_rx_frame(uint8_t ch, NIF *nif)
+{
+// ETH_HDR *eth_hdr;
+ FECBD *pRxBD;
+ NBUF *cur_nbuf, *new_nbuf;
+ int keep;
+
+ while ((pRxBD = fecbd_rx_alloc(ch)) != NULL)
+ {
+ fec_log[ch].drxf++;
+ keep = TRUE;
+
+ /*
+ * Check the Receive Frame Status Word for errors
+ * - The L bit should always be set
+ * - No undefined bits should be set
+ * - The upper 5 bits of the length should be cleared
+ */
+ if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608)
+ || (pRxBD->length & 0xF800))
+ {
+ keep = FALSE;
+ fec_log[ch].rfsw_inv++;
+ }
+ else if (pRxBD->status & RX_BD_ERROR)
+ {
+ keep = FALSE;
+ if (pRxBD->status & RX_BD_NO)
+ fec_log[ch].rfsw_no++;
+ if (pRxBD->status & RX_BD_CR)
+ fec_log[ch].rfsw_cr++;
+ if (pRxBD->status & RX_BD_OV)
+ fec_log[ch].rfsw_ov++;
+ if (pRxBD->status & RX_BD_TR)
+ fec_log[ch].rfsw_tr++;
+ }
+ else
+ {
+ if (pRxBD->status & RX_BD_LG)
+ fec_log[ch].rfsw_lg++;
+ if (pRxBD->status & RX_BD_M)
+ fec_log[ch].rfsw_m++;
+ if (pRxBD->status & RX_BD_BC)
+ fec_log[ch].rfsw_bc++;
+ if (pRxBD->status & RX_BD_MC)
+ fec_log[ch].rfsw_mc++;
+ }
+
+ if (keep)
+ {
+ /*
+ * Pull the network buffer off the Rx ring queue
+ */
+ cur_nbuf = nbuf_remove(NBUF_RX_RING);
+ ASSERT(cur_nbuf);
+ ASSERT(cur_nbuf->data == pRxBD->data);
+
+ /*
+ * Copy the buffer descriptor information to the network buffer
+ */
+// cur_nbuf->length = (pRxBD->length - (ETH_HDR_LEN + ETH_CRC_LEN));
+// cur_nbuf->offset = ETH_HDR_LEN;
+ cur_nbuf->length = (pRxBD->length - (ETH_CRC_LEN));
+ cur_nbuf->offset = 0;
+
+ /*
+ * Get a new buffer pointer for this buffer descriptor
+ */
+ new_nbuf = nbuf_alloc();
+ if (new_nbuf == NULL)
+ {
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("nbuf_alloc() failed\n");
+ #endif
+ /*
+ * Can't allocate a new network buffer, so we
+ * have to trash the received data and reuse the buffer
+ * hoping that some buffers will free up in the system
+ * and this frame will be re-transmitted by the host
+ */
+ pRxBD->length = RX_BUF_SZ;
+ pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT);
+ pRxBD->status |= RX_BD_E;
+ nbuf_add(NBUF_RX_RING, cur_nbuf);
+ fec_rx_continue(ch);
+ continue;
+ }
+
+ /*
+ * Add the new network buffer to the Rx ring queue
+ */
+ nbuf_add(NBUF_RX_RING, new_nbuf);
+
+ /*
+ * Re-initialize the buffer descriptor - pointing it
+ * to the new data buffer. The previous data buffer
+ * will be passed up the stack
+ */
+ pRxBD->data = new_nbuf->data;
+ pRxBD->length = RX_BUF_SZ;
+ pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT);
+ pRxBD->status |= RX_BD_E;
+
+
+ /*
+ * Let the DMA know that there is a new Rx BD (in case the
+ * ring was full and the DMA was waiting for an empty one)
+ */
+ fec_rx_continue(ch);
+
+ /*
+ * Get pointer to the frame data inside the network buffer
+ */
+// eth_hdr = (ETH_HDR *)cur_nbuf->data;
+
+ /*
+ * Pass the received packet up the network stack if the
+ * protocol is supported in our network interface (NIF)
+ */
+//FIXME if (nif_protocol_exist(nif,eth_hdr->type))
+// {
+// nif_protocol_handler(nif, eth_hdr->type, cur_nbuf);
+// }
+// else
+// nbuf_free(cur_nbuf);
+ return(cur_nbuf);
+ }
+ else
+ {
+ /*
+ * This frame isn't a keeper
+ * Reset the status and length, but don't need to get another
+ * buffer since we are trashing the data in the current one
+ */
+ pRxBD->length = RX_BUF_SZ;
+ pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT);
+ pRxBD->status |= RX_BD_E;
+
+ /*
+ * Move the current buffer from the beginning to the end of the
+ * Rx ring queue
+ */
+ cur_nbuf = nbuf_remove(NBUF_RX_RING);
+ nbuf_add(NBUF_RX_RING, cur_nbuf);
+
+ /*
+ * Let the DMA know that there are new Rx BDs (in case
+ * it is waiting for an empty one)
+ */
+ fec_rx_continue(ch);
+ }
+ }
+ return NULL;
+}
+
+void
+fec0_rx_frame(void)
+{
+// extern NIF nif1;
+// fec_rx_frame(0, 0);
+}
+
+void
+fec1_rx_frame(void)
+{
+// extern NIF nif1;
+// fec_rx_frame(1, 0);
+}
+
+/*
+ * Start the FEC Tx DMA task
+ *
+ * Parameters:
+ * ch FEC channel
+ * txbd First Tx buffer descriptor in the chain
+ */
+void
+fec_tx_start(uint8_t ch, int8_t *txbd)
+{
+ uint32_t initiator;
+ int channel, result;
+ void fec0_tx_frame(void);
+ void fec1_tx_frame(void);
+
+ /*
+ * Make the initiator assignment
+ */
+ result = dma_set_initiator(DMA_FEC_TX(ch));
+ ASSERT(result == 0);
+
+ /*
+ * Grab the initiator number
+ */
+ initiator = dma_get_initiator(DMA_FEC_TX(ch));
+ ASSERT(initiator != 0);
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_set_channel(DMA_FEC_TX(ch),
+ (ch == 0) ? fec0_tx_frame : fec1_tx_frame);
+ ASSERT(channel != -1);
+
+ /*
+ * Start the Tx DMA task
+ */
+ MCD_startDma(channel,
+ (s8*)txbd,
+ 0,
+ (s8*)MCF_FEC_FECTFDR_ADDR(ch),
+ 0,
+ ETH_MTU,
+ 0,
+ initiator,
+ FECTX_DMA_PRI(ch),
+ 0
+ | MCD_FECTX_DMA
+ | MCD_INTERRUPT
+ | MCD_TT_FLAGS_CW
+ | MCD_TT_FLAGS_RL
+ | MCD_TT_FLAGS_SP
+ ,
+ 0
+ | MCD_NO_CSUM
+ | MCD_NO_BYTE_SWAP
+ );
+}
+
+/*
+ * Continue the Tx DMA task
+ *
+ * This routine is called after the DMA task has halted after
+ * encountering an Tx buffer descriptor that wasn't marked as
+ * ready. There is no harm in calling the continue DMA routine
+ * if the DMA was not paused.
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_tx_continue(uint8_t ch)
+{
+ int channel;
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_get_channel(DMA_FEC_TX(ch));
+ ASSERT(channel > 0);
+
+ /*
+ * Continue/restart the DMA task
+ */
+ MCD_continDma((int)channel);
+}
+
+/*
+ * Stop all transmissions on the selected FEC and kill the DMA task
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_tx_stop (uint8_t ch)
+{
+ uint32_t mask;
+ int channel;
+
+ ASSERT(ch == 0 || ch == 1);
+
+ /* Save off the EIMR value */
+ mask = MCF_FEC_EIMR(ch);
+
+ /* Mask all interrupts */
+ MCF_FEC_EIMR(ch) = 0;
+
+ /* If the Ethernet is still enabled... */
+ if (MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN)
+ {
+ /* Issue the Graceful Transmit Stop */
+ MCF_FEC_TCR(ch) |= MCF_FEC_TCR_GTS;
+
+ /* Wait for the Graceful Stop Complete interrupt */
+ while(!(MCF_FEC_EIR(ch) & MCF_FEC_EIR_GRA))
+ {
+ if (!(MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN))
+ break;
+ }
+
+ /* Clear the Graceful Stop Complete interrupt */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_GRA;
+ }
+
+ /*
+ * Determine the DMA channel running the task for the
+ * selected FEC
+ */
+ channel = dma_get_channel(DMA_FEC_TX(ch));
+ ASSERT(channel > 0);
+
+ /* Kill the FEC Tx DMA task */
+ MCD_killDma(channel);
+
+ /*
+ * Free up the FEC requestor from the software maintained
+ * initiator list
+ */
+ dma_free_initiator(DMA_FEC_TX(ch));
+
+ /* Free up the DMA channel */
+ dma_free_channel(DMA_FEC_TX(ch));
+
+ /* Restore the interrupt mask register value */
+ MCF_FEC_EIMR(ch) = mask;
+}
+
+/*
+ * Trasmit Frame interrupt handler - this handler is called by the
+ * DMA interrupt handler indicating that a packet was successfully
+ * transferred to the Tx FIFO.
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_tx_frame(uint8_t ch)
+{
+ FECBD *pTxBD;
+ NBUF *pNbuf;
+
+ while ((pTxBD = fecbd_tx_free(ch)) != NULL)
+ {
+ fec_log[ch].dtxf++;
+
+ /*
+ * Grab the network buffer associated with this buffer descriptor
+ */
+ pNbuf = nbuf_remove(NBUF_TX_RING);
+ ASSERT(pNbuf);
+ ASSERT(pNbuf->data == pTxBD->data);
+
+ /*
+ * Free up the network buffer that was just transmitted
+ */
+ nbuf_free(pNbuf);
+
+ /*
+ * Re-initialize the Tx BD
+ */
+ pTxBD->data = NULL;
+ pTxBD->length = 0;
+ }
+}
+
+void
+fec0_tx_frame(void)
+{
+ fec_tx_frame(0);
+}
+
+void
+fec1_tx_frame(void)
+{
+ fec_tx_frame(1);
+}
+
+/*
+ * Send a packet out the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ * nif Pointer to Network Interface (NIF) structure
+ * dst Destination MAC Address
+ * src Source MAC Address
+ * type Ethernet Frame Type
+ * length Number of bytes to be transmitted (doesn't include type,
+ * src, or dest byte count)
+ * pkt Pointer packet network buffer
+ *
+ * Return Value:
+ * 1 success
+ * 0 otherwise
+ */
+int
+fec_send (uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf)
+{
+ FECBD *pTxBD;
+ ASSERT(ch == 0 || ch == 1);
+
+ /* Check the length */
+ if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU)
+ return 0;
+
+ /*
+ * Copy the destination address, source address, and Ethernet
+ * type into the packet
+ */
+// memcpy(&nbuf->data[0], dst, 6);
+// memcpy(&nbuf->data[6], src, 6);
+// memcpy(&nbuf->data[12], &type, 2);
+
+ /*
+ * Grab the next available Tx Buffer Descriptor
+ */
+ while ((pTxBD = fecbd_tx_alloc(ch)) == NULL) {};
+
+ /*
+ * Put the network buffer into the Tx waiting queue
+ */
+ nbuf_add(NBUF_TX_RING, nbuf);
+
+ /*
+ * Setup the buffer descriptor for transmission
+ */
+ pTxBD->data = nbuf->data;
+ pTxBD->length = nbuf->length; // + ETH_HDR_LEN;
+ pTxBD->status |= (TX_BD_R | TX_BD_L);
+
+ /*
+ * Continue the Tx DMA task (in case it was waiting for a new
+ * TxBD to be ready
+ */
+ fec_tx_continue(ch);
+
+ return 1;
+}
+
+int
+fec0_send(NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf)
+{
+ return fec_send(0, nif, dst, src, type, nbuf);
+}
+
+int
+fec1_send(NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf)
+{
+ return fec_send(1, nif, dst, src, type, nbuf);
+}
+
+/*
+ * Enable interrupts on the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ * pri Interrupt Priority
+ * lvl Interrupt Level
+ */
+void
+fec_irq_enable(uint8_t ch, uint8_t lvl, uint8_t pri)
+{
+ ASSERT(ch == 0 || ch == 1);
+ ASSERT(lvl > 0 && lvl < 8);
+ ASSERT(pri < 8);
+
+ /*
+ * Setup the appropriate ICR
+ */
+ MCF_INTC_ICRn((ch == 0) ? 39 : 38) = (uint8_t)(0
+ | MCF_INTC_ICRn_IP(pri)
+ | MCF_INTC_ICRn_IL(lvl));
+
+ /*
+ * Clear any pending FEC interrupt events
+ */
+ MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL;
+
+ /*
+ * Unmask all FEC interrupts
+ */
+ MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_UNMASK_ALL;
+
+ /*
+ * Unmask the FEC interrupt in the interrupt controller
+ */
+ if (ch == 0)
+ MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK39;
+ else
+ MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK38;
+}
+
+/*
+ * Disable interrupts on the selected FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_irq_disable(uint8_t ch)
+{
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Mask all FEC interrupts
+ */
+ MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL;
+
+ /*
+ * Mask the FEC interrupt in the interrupt controller
+ */
+ if (ch == 0)
+ MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK39;
+ else
+ MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK38;
+}
+
+/*
+ * FEC interrupt handler
+ * All interrupts are multiplexed into a single vector for each
+ * FEC module. The lower level interrupt handler passes in the
+ * channel to this handler. Note that the receive interrupt is
+ * generated by the Multi-channel DMA FEC Rx task.
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+static void
+fec_irq_handler(uint8_t ch)
+{
+ uint32_t event, eir;
+
+ /*
+ * Determine which interrupt(s) asserted by AND'ing the
+ * pending interrupts with those that aren't masked.
+ */
+ eir = MCF_FEC_EIR(ch);
+ event = eir & MCF_FEC_EIMR(ch);
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ if (event != eir)
+ printf("Pending but not enabled: 0x%08X\n",(event ^ eir));
+ #endif
+
+ /*
+ * Clear the event(s) in the EIR immediately
+ */
+ MCF_FEC_EIR(ch) = event;
+
+ if (event & MCF_FEC_EIR_RFERR)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].rferr++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("RFERR\n");
+ printf("FECRFSR%d = 0x%08x\n",ch,MCF_FEC_FECRFSR(ch));
+ fec_eth_stop(ch);
+ #endif
+ }
+ if (event & MCF_FEC_EIR_XFERR)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].xferr++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("XFERR\n");
+ #endif
+ }
+ if (event & MCF_FEC_EIR_XFUN)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].xfun++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("XFUN\n");
+ fec_eth_stop(ch);
+ #endif
+ }
+ if (event & MCF_FEC_EIR_RL)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].rl++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("RL\n");
+ #endif
+ }
+ if (event & MCF_FEC_EIR_LC)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].lc++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("LC\n");
+ #endif
+ }
+ if (event & MCF_FEC_EIR_MII)
+ {
+ fec_log[ch].mii++;
+ }
+ if (event & MCF_FEC_EIR_TXF)
+ {
+ fec_log[ch].txf++;
+ }
+ if (event & MCF_FEC_EIR_GRA)
+ {
+ fec_log[ch].gra++;
+ }
+ if (event & MCF_FEC_EIR_BABT)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].babt++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("BABT\n");
+ #endif
+ }
+ if (event & MCF_FEC_EIR_BABR)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].babr++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("BABR\n");
+ #endif
+ }
+ if (event & MCF_FEC_EIR_HBERR)
+ {
+ fec_log[ch].total++;
+ fec_log[ch].hberr++;
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("HBERR\n");
+ #endif
+ }
+}
+
+int
+fec0_interrupt_handler(void* arg1, void* arg2)
+{
+ (void) arg1;
+ (void) arg2;
+ fec_irq_handler(0);
+ return 1;
+}
+
+int
+fec1_interrupt_handler(void* arg1, void* arg2)
+{
+ (void) arg1;
+ (void) arg2;
+ fec_irq_handler(1);
+ return 1;
+}
+
+/*
+ * Configure the selected Ethernet port and enable all operations
+ *
+ * Parameters:
+ * ch FEC channel
+ * trcvr Transceiver mode (MII, 7-Wire or internal loopback)
+ * speed Maximum operating speed (MII only)
+ * duplex Full or Half-duplex (MII only)
+ * mac Physical (MAC) Address
+ */
+void
+fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, const uint8_t *mac)
+{
+ ASSERT(ch == 0 || ch == 1);
+
+ /*
+ * Disable FEC interrupts
+ */
+ fec_irq_disable(ch);
+
+ /*
+ * Initialize the event log
+ */
+ fec_log_init(ch);
+
+ /*
+ * Initialize the network buffers and fec buffer descriptors
+ */
+ nbuf_init();
+ fecbd_init(ch);
+
+ /*
+ * Initialize the FEC
+ */
+ fec_reset(ch);
+ fec_init(ch,trcvr,mac);
+
+ if (trcvr == FEC_MODE_MII)
+ {
+ /*
+ * Initialize the MII interface
+ */
+ fec_mii_init(ch, CFG_SYSTEM_CORE_CLOCK);
+ }
+
+ /*
+ * Initialize and enable FEC interrupts
+ */
+ fec_irq_enable(ch, FEC_INTC_LVL(ch), FEC_INTC_PRI(ch));
+
+ /*
+ * Enable the multi-channel DMA tasks
+ */
+ fec_rx_start(ch, (int8_t*)fecbd_get_start(ch,Rx));
+ fec_tx_start(ch, (int8_t*)fecbd_get_start(ch,Tx));
+
+ /*
+ * Enable the FEC channel
+ */
+ MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN;
+}
+/*
+ * Reset the selected Ethernet port
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_eth_reset(uint8_t ch)
+{
+// To do
+}
+
+/*
+ * Stop the selected Ethernet port
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fec_eth_stop(uint8_t ch)
+{
+ int level;
+
+ /*
+ * Disable interrupts
+ */
+ level = asm_set_ipl(7);
+
+ /*
+ * Gracefully disable the receiver and transmitter
+ */
+ fec_tx_stop(ch);
+ fec_rx_stop(ch);
+
+ /*
+ * Disable FEC interrupts
+ */
+ fec_irq_disable(ch);
+
+ /*
+ * Disable the FEC channel
+ */
+ MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN;
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ nbuf_debug_dump();
+ fec_log_dump(ch);
+ #endif
+
+ /*
+ * Flush the network buffers
+ */
+ nbuf_flush();
+
+ /*
+ * Restore interrupt level
+ */
+ asm_set_ipl(level);
+}
diff --git a/arch/m68k/mach-mcfv4e/fecbd.c b/arch/m68k/mach-mcfv4e/fecbd.c
new file mode 100644
index 0000000000..26fb16d98d
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/fecbd.c
@@ -0,0 +1,232 @@
+/*
+ * File: fecbd.c
+ * Purpose: Provide a simple buffer management driver
+ *
+ * Notes:
+ */
+#include <common.h>
+#include <linux/types.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/net/net.h>
+#include <asm/proc/fecbd.h>
+#include <asm/proc/fec.h>
+#include <asm/proc/dma_utils.h>
+
+#define ASSERT(x) if (!(x)) hang();
+
+/*
+ * This implements a simple static buffer descriptor
+ * ring for each channel and each direction
+ *
+ * FEC Buffer Descriptors need to be aligned to a 4-byte boundary.
+ * In order to accomplish this, data is over-allocated and manually
+ * aligned at runtime
+ *
+ * Enough space is allocated for each of the two FEC channels to have
+ * NRXBD Rx BDs and NTXBD Tx BDs
+ *
+ */
+FECBD unaligned_bds[(2 * NRXBD) + (2 * NTXBD) + 1];
+
+/*
+ * These pointers are used to reference into the chunck of data set
+ * aside for buffer descriptors
+ */
+FECBD *RxBD;
+FECBD *TxBD;
+
+/*
+ * Macros to easier access to the BD ring
+ */
+#define RxBD(ch,i) RxBD[(ch * NRXBD) + i]
+#define TxBD(ch,i) TxBD[(ch * NTXBD) + i]
+
+/*
+ * Buffer descriptor indexes
+ */
+static int iTxbd_new;
+static int iTxbd_old;
+static int iRxbd;
+
+/*
+ * Initialize the FEC Buffer Descriptor ring
+ * Buffer Descriptor format is defined by the MCDAPI
+ *
+ * Parameters:
+ * ch FEC channel
+ */
+void
+fecbd_init(uint8_t ch)
+{
+ NBUF *nbuf;
+ int i;
+
+ /*
+ * Align Buffer Descriptors to 4-byte boundary
+ */
+ RxBD = (FECBD *)(((int)unaligned_bds + 3) & 0xFFFFFFFC);
+ TxBD = (FECBD *)((int)RxBD + (sizeof(FECBD) * 2 * NRXBD));
+
+ /*
+ * Initialize the Rx Buffer Descriptor ring
+ */
+ for (i = 0; i < NRXBD; ++i)
+ {
+ /* Grab a network buffer from the free list */
+ nbuf = nbuf_alloc();
+ ASSERT(nbuf);
+
+ /* Initialize the BD */
+ RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT;
+ RxBD(ch,i).length = RX_BUF_SZ;
+ RxBD(ch,i).data = nbuf->data;
+
+ /* Add the network buffer to the Rx queue */
+ nbuf_add(NBUF_RX_RING, nbuf);
+ }
+
+ /*
+ * Set the WRAP bit on the last one
+ */
+ RxBD(ch,i-1).status |= RX_BD_W;
+
+ /*
+ * Initialize the Tx Buffer Descriptor ring
+ */
+ for (i = 0; i < NTXBD; ++i)
+ {
+ TxBD(ch,i).status = TX_BD_INTERRUPT;
+ TxBD(ch,i).length = 0;
+ TxBD(ch,i).data = NULL;
+ }
+
+ /*
+ * Set the WRAP bit on the last one
+ */
+ TxBD(ch,i-1).status |= TX_BD_W;
+
+ /*
+ * Initialize the buffer descriptor indexes
+ */
+ iTxbd_new = iTxbd_old = iRxbd = 0;
+}
+
+void
+fecbd_dump(uint8_t ch)
+{
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ int i;
+
+ printf("\n------------ FEC%d BDs -----------\n",ch);
+ printf("RxBD Ring\n");
+ for (i=0; i<NRXBD; i++)
+ {
+ printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
+ i, &RxBD(ch,i),
+ RxBD(ch,i).status,
+ RxBD(ch,i).length,
+ RxBD(ch,i).data);
+ }
+ printf("TxBD Ring\n");
+ for (i=0; i<NTXBD; i++)
+ {
+ printf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
+ i, &TxBD(ch,i),
+ TxBD(ch,i).status,
+ TxBD(ch,i).length,
+ TxBD(ch,i).data);
+ }
+ printf("--------------------------------\n\n");
+ #endif
+}
+
+/*
+ * Return the address of the first buffer descriptor in the ring.
+ *
+ * Parameters:
+ * ch FEC channel
+ * direction Rx or Tx Macro
+ *
+ * Return Value:
+ * The start address of the selected Buffer Descriptor ring
+ */
+uint32_t
+fecbd_get_start(uint8_t ch, uint8_t direction)
+{
+ switch (direction)
+ {
+ case Rx:
+ return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD));
+ case Tx:
+ default:
+ return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD));
+ }
+}
+
+FECBD *
+fecbd_rx_alloc(uint8_t ch)
+{
+ int i = iRxbd;
+
+ /* Check to see if the ring of BDs is full */
+ if (RxBD(ch,i).status & RX_BD_E)
+ return NULL;
+
+ /* Increment the circular index */
+ iRxbd = (uint8_t)((iRxbd + 1) % NRXBD);
+
+ return &RxBD(ch,i);
+}
+
+/*
+ * This function keeps track of the next available Tx BD in the ring
+ *
+ * Parameters:
+ * ch FEC channel
+ *
+ * Return Value:
+ * Pointer to next available buffer descriptor.
+ * NULL if the BD ring is full
+ */
+FECBD *
+fecbd_tx_alloc(uint8_t ch)
+{
+ int i = iTxbd_new;
+
+ /* Check to see if the ring of BDs is full */
+ if (TxBD(ch,i).status & TX_BD_R)
+ return NULL;
+
+ /* Increment the circular index */
+ iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD);
+
+ return &TxBD(ch,i);
+}
+
+/*
+ * This function keeps track of the Tx BDs that have already been
+ * processed by the FEC
+ *
+ * Parameters:
+ * ch FEC channel
+ *
+ * Return Value:
+ * Pointer to the oldest buffer descriptor that has already been sent
+ * by the FEC, NULL if the BD ring is empty
+ */
+FECBD *
+fecbd_tx_free(uint8_t ch)
+{
+ int i = iTxbd_old;
+
+ /* Check to see if the ring of BDs is empty */
+ if ((TxBD(ch,i).data == NULL) || (TxBD(ch,i).status & TX_BD_R))
+ return NULL;
+
+ /* Increment the circular index */
+ iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD);
+
+ return &TxBD(ch,i);
+}
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c b/arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c
new file mode 100644
index 0000000000..b4d7f28470
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c
@@ -0,0 +1,907 @@
+/*
+ * File: MCD_dmaApi.c
+ * Purpose: Main C file for multi-channel DMA API.
+ *
+ * Notes:
+ */
+
+#include <asm/types.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/mcdapi/MCD_tasksInit.h>
+#include <asm/proc/mcdapi/MCD_progCheck.h>
+
+/*
+ * This is an API-internal pointer to the DMA's registers
+ */
+dmaRegs *MCD_dmaBar;
+
+/*
+ * These are the real and model task tables as generated by the
+ * build process
+ */
+extern TaskTableEntry MCD_realTaskTableSrc[NCHANNELS];
+extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS];
+
+/*
+ * However, this (usually) gets relocated to on-chip SRAM, at which
+ * point we access them as these tables
+ */
+volatile TaskTableEntry *MCD_taskTable;
+TaskTableEntry *MCD_modelTaskTable;
+
+
+/*
+ * MCD_chStatus[] is an array of status indicators for remembering
+ * whether a DMA has ever been attempted on each channel, pausing
+ * status, etc.
+ */
+static int MCD_chStatus[NCHANNELS] =
+{
+ MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
+ MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
+ MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
+ MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA
+};
+
+/*
+ * Prototypes for local functions
+ */
+static void MCD_memcpy (int *dest, int *src, u32 size);
+static void MCD_resmActions (int channel);
+
+/*
+ * Buffer descriptors used for storage of progress info for single Dmas
+ * Also used as storage for the DMA for CRCs for single DMAs
+ * Otherwise, the DMA does not parse these buffer descriptors
+ */
+#ifdef MCD_INCLUDE_EU
+extern MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
+#else
+MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
+#endif
+MCD_bufDesc *MCD_relocBuffDesc;
+
+
+/*
+ * Defines for the debug control register's functions
+ */
+#define DBG_CTL_COMP1_TASK (0x00002000) /* have comparator 1 look for a task # */
+#define DBG_CTL_ENABLE (DBG_CTL_AUTO_ARM | \
+ DBG_CTL_BREAK | \
+ DBG_CTL_INT_BREAK | \
+ DBG_CTL_COMP1_TASK)
+#define DBG_CTL_DISABLE (DBG_CTL_AUTO_ARM | \
+ DBG_CTL_INT_BREAK | \
+ DBG_CTL_COMP1_TASK)
+#define DBG_KILL_ALL_STAT (0xFFFFFFFF)
+
+/*
+ * Offset to context save area where progress info is stored
+ */
+#define CSAVE_OFFSET 10
+
+/*
+ * Defines for Byte Swapping
+ */
+#define MCD_BYTE_SWAP_KILLER 0xFFF8888F
+#define MCD_NO_BYTE_SWAP_ATALL 0x00040000
+
+/*
+ * Execution Unit Identifiers
+ */
+#define MAC 0 /* legacy - not used */
+#define LUAC 1 /* legacy - not used */
+#define CRC 2 /* legacy - not used */
+#define LURC 3 /* Logic Unit with CRC */
+
+/*
+ * Task Identifiers
+ */
+#define TASK_CHAINNOEU 0
+#define TASK_SINGLENOEU 1
+#ifdef MCD_INCLUDE_EU
+#define TASK_CHAINEU 2
+#define TASK_SINGLEEU 3
+#define TASK_FECRX 4
+#define TASK_FECTX 5
+#else
+#define TASK_CHAINEU 0
+#define TASK_SINGLEEU 1
+#define TASK_FECRX 2
+#define TASK_FECTX 3
+#endif
+
+/*
+ * Structure to remember which variant is on which channel
+ * TBD- need this?
+ */
+typedef struct MCD_remVariants_struct MCD_remVariant;
+struct MCD_remVariants_struct
+{
+ int remDestRsdIncr[NCHANNELS]; /* -1,0,1 */
+ int remSrcRsdIncr[NCHANNELS]; /* -1,0,1 */
+ s16 remDestIncr[NCHANNELS]; /* DestIncr */
+ s16 remSrcIncr[NCHANNELS]; /* srcIncr */
+ u32 remXferSize[NCHANNELS]; /* xferSize */
+};
+
+/*
+ * Structure to remember the startDma parameters for each channel
+ */
+MCD_remVariant MCD_remVariants;
+
+/*
+ * Function: MCD_initDma
+ * Purpose: Initializes the DMA API by setting up a pointer to the DMA
+ * registers, relocating and creating the appropriate task
+ * structures, and setting up some global settings
+ * Arguments:
+ * dmaBarAddr - pointer to the multichannel DMA registers
+ * taskTableDest - location to move DMA task code and structs to
+ * flags - operational parameters
+ * Return Value:
+ * MCD_TABLE_UNALIGNED if taskTableDest is not 512-byte aligned
+ * MCD_OK otherwise
+ */
+extern u32 MCD_funcDescTab0[];
+
+int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
+{
+ int i;
+ TaskTableEntry *entryPtr;
+
+ /* setup the local pointer to register set */
+ MCD_dmaBar = dmaBarAddr;
+
+ /* do we need to move/create a task table */
+ if ((flags & MCD_RELOC_TASKS) != 0)
+ {
+ int fixedSize;
+ u32 *fixedPtr;
+ /*int *tablePtr = taskTableDest;TBD*/
+ int varTabsOffset, funcDescTabsOffset, contextSavesOffset;
+ int taskDescTabsOffset;
+ int taskTableSize, varTabsSize, funcDescTabsSize, contextSavesSize;
+ int taskDescTabSize;
+
+ int i;
+
+ /* check if physical address is aligned on 512 byte boundary */
+ if (((u32)taskTableDest & 0x000001ff) != 0)
+ return(MCD_TABLE_UNALIGNED);
+
+ MCD_taskTable = taskTableDest; /* set up local pointer to task Table */
+
+ /*
+ * Create a task table:
+ * - compute aligned base offsets for variable tables and
+ * function descriptor tables, then
+ * - loop through the task table and setup the pointers
+ * - copy over model task table with the the actual task descriptor
+ * tables
+ */
+
+ taskTableSize = NCHANNELS * sizeof(TaskTableEntry);
+ /* align variable tables to size */
+ varTabsOffset = taskTableSize + (u32)taskTableDest;
+ if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0)
+ varTabsOffset = (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE);
+ /* align function descriptor tables */
+ varTabsSize = NCHANNELS * VAR_TAB_SIZE;
+ funcDescTabsOffset = varTabsOffset + varTabsSize;
+
+ if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0)
+ funcDescTabsOffset = (funcDescTabsOffset + FUNCDESC_TAB_SIZE) &
+ (~FUNCDESC_TAB_SIZE);
+
+ funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE;
+ contextSavesOffset = funcDescTabsOffset + funcDescTabsSize;
+ contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE);
+ fixedSize = taskTableSize + varTabsSize + funcDescTabsSize +
+ contextSavesSize;
+
+ /* zero the thing out */
+ fixedPtr = (u32 *)taskTableDest;
+ for (i = 0;i<(fixedSize/4);i++)
+ fixedPtr[i] = 0;
+
+ entryPtr = (TaskTableEntry*)MCD_taskTable;
+ /* set up fixed pointers */
+ for (i = 0; i < NCHANNELS; i++)
+ {
+ entryPtr[i].varTab = (u32)varTabsOffset; /* update ptr to local value */
+ entryPtr[i].FDTandFlags = (u32)funcDescTabsOffset | MCD_TT_FLAGS_DEF;
+ entryPtr[i].contextSaveSpace = (u32)contextSavesOffset;
+ varTabsOffset += VAR_TAB_SIZE;
+#ifdef MCD_INCLUDE_EU /* if not there is only one, just point to the same one */
+ funcDescTabsOffset += FUNCDESC_TAB_SIZE;
+#endif
+ contextSavesOffset += CONTEXT_SAVE_SIZE;
+ }
+ /* copy over the function descriptor table */
+ for ( i = 0; i < FUNCDESC_TAB_NUM; i++)
+ {
+ MCD_memcpy((void*)(entryPtr[i].FDTandFlags & ~MCD_TT_FLAGS_MASK),
+ (void*)MCD_funcDescTab0, FUNCDESC_TAB_SIZE);
+ }
+
+ /* copy model task table to where the context saves stuff leaves off*/
+ MCD_modelTaskTable = (TaskTableEntry*)contextSavesOffset;
+
+ MCD_memcpy ((void*)MCD_modelTaskTable, (void*)MCD_modelTaskTableSrc,
+ NUMOFVARIANTS * sizeof(TaskTableEntry));
+
+ entryPtr = MCD_modelTaskTable; /* point to local version of
+ model task table */
+ taskDescTabsOffset = (u32)MCD_modelTaskTable +
+ (NUMOFVARIANTS * sizeof(TaskTableEntry));
+
+ /* copy actual task code and update TDT ptrs in local model task table */
+ for (i = 0; i < NUMOFVARIANTS; i++)
+ {
+ taskDescTabSize = entryPtr[i].TDTend - entryPtr[i].TDTstart + 4;
+ MCD_memcpy ((void*)taskDescTabsOffset, (void*)entryPtr[i].TDTstart, taskDescTabSize);
+ entryPtr[i].TDTstart = (u32)taskDescTabsOffset;
+ taskDescTabsOffset += taskDescTabSize;
+ entryPtr[i].TDTend = (u32)taskDescTabsOffset - 4;
+ }
+#ifdef MCD_INCLUDE_EU /* Tack single DMA BDs onto end of code so API controls
+ where they are since DMA might write to them */
+ MCD_relocBuffDesc = (MCD_bufDesc*)(entryPtr[NUMOFVARIANTS - 1].TDTend + 4);
+#else /* DMA does not touch them so they can be wherever and we don't need to
+ waste SRAM on them */
+ MCD_relocBuffDesc = MCD_singleBufDescs;
+#endif
+ }
+ else
+ {
+ /* point the would-be relocated task tables and the
+ buffer descriptors to the ones the linker generated */
+
+ if (((u32)MCD_realTaskTableSrc & 0x000001ff) != 0)
+ return(MCD_TABLE_UNALIGNED);
+
+ /* need to add code to make sure that every thing else is aligned properly TBD*/
+ /* this is problematic if we init more than once or after running tasks,
+ need to add variable to see if we have aleady init'd */
+ entryPtr = MCD_realTaskTableSrc;
+ for (i = 0; i < NCHANNELS; i++)
+ {
+ if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0) ||
+ ((entryPtr[i].FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0))
+ return(MCD_TABLE_UNALIGNED);
+ }
+
+ MCD_taskTable = MCD_realTaskTableSrc;
+ MCD_modelTaskTable = MCD_modelTaskTableSrc;
+ MCD_relocBuffDesc = MCD_singleBufDescs;
+ }
+
+
+ /* Make all channels as totally inactive, and remember them as such: */
+
+ MCD_dmaBar->taskbar = (u32) MCD_taskTable;
+ for (i = 0; i < NCHANNELS; i++)
+ {
+ MCD_dmaBar->taskControl[i] = 0x0;
+ MCD_chStatus[i] = MCD_NO_DMA;
+ }
+
+ /* Set up pausing mechanism to inactive state: */
+ MCD_dmaBar->debugComp1 = 0; /* no particular values yet for either comparator registers */
+ MCD_dmaBar->debugComp2 = 0;
+ MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
+ MCD_dmaBar->debugStatus = DBG_KILL_ALL_STAT;
+
+ /* enable or disable commbus prefetch, really need an ifdef or
+ something to keep from trying to set this in the 8220 */
+ if ((flags & MCD_COMM_PREFETCH_EN) != 0)
+ MCD_dmaBar->ptdControl &= ~PTD_CTL_COMM_PREFETCH;
+ else
+ MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH;
+
+ return(MCD_OK);
+}
+
+/* Function: MCD_dmaStatus
+ * Purpose: Returns the status of the DMA on the requested channel
+ * Arguments: channel - channel number
+ * Returns: Predefined status indicators
+ */
+int MCD_dmaStatus (int channel)
+{
+ u16 tcrValue;
+
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ tcrValue = MCD_dmaBar->taskControl[channel];
+ if ((tcrValue & TASK_CTL_EN) == 0)
+ { /* nothing running */
+ /* if last reported with task enabled */
+ if ( MCD_chStatus[channel] == MCD_RUNNING
+ || MCD_chStatus[channel] == MCD_IDLE)
+ MCD_chStatus[channel] = MCD_DONE;
+ }
+ else /* something is running */
+ {
+ /* There are three possibilities: paused, running or idle. */
+ if ( MCD_chStatus[channel] == MCD_RUNNING
+ || MCD_chStatus[channel] == MCD_IDLE)
+ {
+ MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
+ /* This register is selected to know which initiator is
+ actually asserted. */
+ if ((MCD_dmaBar->ptdDebug >> channel ) & 0x1 )
+ MCD_chStatus[channel] = MCD_RUNNING;
+ else
+ MCD_chStatus[channel] = MCD_IDLE;
+ /* do not change the status if it is already paused. */
+ }
+ }
+ return MCD_chStatus[channel];
+}
+
+/* Function: MCD_startDma
+ * Ppurpose: Starts a particular kind of DMA
+ * Arguments: see below
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ */
+
+int MCD_startDma (
+ int channel, /* the channel on which to run the DMA */
+ s8 *srcAddr, /* the address to move data from, or physical buffer-descriptor address */
+ s16 srcIncr, /* the amount to increment the source address per transfer */
+ s8 *destAddr, /* the address to move data to */
+ s16 destIncr, /* the amount to increment the destination address per transfer */
+ u32 dmaSize, /* the number of bytes to transfer independent of the transfer size */
+ u32 xferSize, /* the number bytes in of each data movement (1, 2, or 4) */
+ u32 initiator, /* what device initiates the DMA */
+ int priority, /* priority of the DMA */
+ u32 flags, /* flags describing the DMA */
+ u32 funcDesc /* a description of byte swapping, bit swapping, and CRC actions */
+#ifdef MCD_NEED_ADDR_TRANS
+ s8 *srcAddrVirt /* virtual buffer descriptor address TBD*/
+#endif
+)
+{
+ int srcRsdIncr, destRsdIncr;
+ int *cSave;
+ short xferSizeIncr;
+ int tcrCount = 0;
+#ifdef MCD_INCLUDE_EU
+ u32 *realFuncArray;
+#endif
+
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ /* tbd - need to determine the proper response to a bad funcDesc when not
+ including EU functions, for now, assign a benign funcDesc, but maybe
+ should return an error */
+#ifndef MCD_INCLUDE_EU
+ funcDesc = MCD_FUNC_NOEU1;
+#endif
+
+#ifdef MCD_DEBUG
+printf("startDma:Setting up params\n");
+#endif
+ /* Set us up for task-wise priority. We don't technically need to do this on every start, but
+ since the register involved is in the same longword as other registers that users are in control
+ of, setting it more than once is probably preferable. That since the documentation doesn't seem
+ to be completely consistent about the nature of the PTD control register. */
+ MCD_dmaBar->ptdControl |= (u16) 0x8000;
+#if 1 /* Not sure what we need to keep here rtm TBD */
+ /* Calculate additional parameters to the regular DMA calls. */
+ srcRsdIncr = srcIncr < 0 ? -1 : (srcIncr > 0 ? 1 : 0);
+ destRsdIncr = destIncr < 0 ? -1 : (destIncr > 0 ? 1 : 0);
+
+ xferSizeIncr = (xferSize & 0xffff) | 0x20000000;
+
+ /* Remember for each channel which variant is running. */
+ MCD_remVariants.remSrcRsdIncr[channel] = srcRsdIncr;
+ MCD_remVariants.remDestRsdIncr[channel] = destRsdIncr;
+ MCD_remVariants.remDestIncr[channel] = destIncr;
+ MCD_remVariants.remSrcIncr[channel] = srcIncr;
+ MCD_remVariants.remXferSize[channel] = xferSize;
+#endif
+
+ cSave = (int*)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET + CURRBD;
+
+#ifdef MCD_INCLUDE_EU /* may move this to EU specific calls */
+ realFuncArray = (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00);
+ /* Modify the LURC's normal and byte-residue-loop functions according to parameter. */
+ realFuncArray[(LURC*16)] = xferSize == 4 ?
+ funcDesc : xferSize == 2 ?
+ funcDesc & 0xfffff00f : funcDesc & 0xffff000f;
+ realFuncArray[(LURC*16+1)] = (funcDesc & MCD_BYTE_SWAP_KILLER) | MCD_NO_BYTE_SWAP_ATALL;
+#endif
+ /* Write the initiator field in the TCR, and also set the initiator-hold
+ bit. Note that,due to a hardware quirk, this could collide with an
+ MDE access to the initiator-register file, so we have to verify that the write
+ reads back correctly. */
+
+ MCD_dmaBar->taskControl[channel] =
+ (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
+
+ while(((MCD_dmaBar->taskControl[channel] & 0x1fff) !=
+ ((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM)) &&
+ (tcrCount < 1000))
+ {
+ tcrCount++;
+ /*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020;*/
+ MCD_dmaBar->taskControl[channel] =
+ (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
+ }
+
+ MCD_dmaBar->priority[channel] = (u8)priority & PRIORITY_PRI_MASK;
+ /* should be albe to handle this stuff with only one write to ts reg - tbd */
+ if (channel < 8 && channel >= 0)
+ {
+ MCD_dmaBar->taskSize0 &= ~(0xf << (7-channel)*4);
+ MCD_dmaBar->taskSize0 |= (xferSize & 3) << (((7 - channel)*4) + 2);
+ MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel)*4);
+ }
+ else
+ {
+ MCD_dmaBar->taskSize1 &= ~(0xf << (15-channel)*4);
+ MCD_dmaBar->taskSize1 |= (xferSize & 3) << (((15 - channel)*4) + 2);
+ MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel)*4);
+ }
+
+ /* setup task table flags/options which mostly control the line buffers */
+ MCD_taskTable[channel].FDTandFlags &= ~MCD_TT_FLAGS_MASK;
+ MCD_taskTable[channel].FDTandFlags |= (MCD_TT_FLAGS_MASK & flags);
+
+ if (flags & MCD_FECTX_DMA)
+ {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECTX].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECTX].TDTend;
+ MCD_startDmaENetXmit(srcAddr, srcAddr, destAddr, MCD_taskTable, channel);
+ }
+ else if (flags & MCD_FECRX_DMA)
+ {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECRX].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECRX].TDTend;
+ MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr, MCD_taskTable, channel);
+ }
+ else if(flags & MCD_SINGLE_DMA)
+ {
+ /* this buffer descriptor is used for storing off initial parameters for later
+ progress query calculation and for the DMA to write the resulting checksum
+ The DMA does not use this to determine how to operate, that info is passed
+ with the init routine*/
+ MCD_relocBuffDesc[channel].srcAddr = srcAddr;
+ MCD_relocBuffDesc[channel].destAddr = destAddr;
+ MCD_relocBuffDesc[channel].lastDestAddr = destAddr; /* definitely not its final value */
+ MCD_relocBuffDesc[channel].dmaSize = dmaSize;
+ MCD_relocBuffDesc[channel].flags = 0; /* not used */
+ MCD_relocBuffDesc[channel].csumResult = 0; /* not used */
+ MCD_relocBuffDesc[channel].next = 0; /* not used */
+
+ /* Initialize the progress-querying stuff to show no progress:*/
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET] = (int)srcAddr;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET] = (int)destAddr;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] =
+ (u32) &(MCD_relocBuffDesc[channel]);
+ /* tbd - need to keep the user from trying to call the EU routine
+ when MCD_INCLUDE_EU is not defined */
+ if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
+ {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLENOEU].TDTend;
+ MCD_startDmaSingleNoEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize,
+ xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave,
+ MCD_taskTable, channel);
+ }
+ else
+ {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
+ MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize,
+ xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave,
+ MCD_taskTable, channel);
+ }
+ }
+ else
+ { /* chained DMAS */
+ /* Initialize the progress-querying stuff to show no progress:*/
+#if 1 /* (!defined(MCD_NEED_ADDR_TRANS)) */
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
+ = (int)((MCD_bufDesc*) srcAddr)->srcAddr;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
+ = (int)((MCD_bufDesc*) srcAddr)->destAddr;
+#else /* if using address translation, need the virtual addr of the first buffdesc */
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
+ = (int)((MCD_bufDesc*) srcAddrVirt)->srcAddr;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
+ = (int)((MCD_bufDesc*) srcAddrVirt)->destAddr;
+#endif
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
+ ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] = (u32) srcAddr;
+
+ if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2)
+ {
+ /*TDTStart and TDTEnd*/
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINNOEU].TDTend;
+ MCD_startDmaChainNoEu((int *)srcAddr, srcIncr, destIncr, xferSize,
+ xferSizeIncr, cSave, MCD_taskTable, channel);
+ }
+ else
+ {
+ /*TDTStart and TDTEnd*/
+ MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINEU].TDTstart;
+ MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINEU].TDTend;
+ MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr, xferSize,
+ xferSizeIncr, cSave, MCD_taskTable, channel);
+ }
+ }
+ MCD_chStatus[channel] = MCD_IDLE;
+ return(MCD_OK);
+}
+
+/* Function: MCD_XferProgrQuery
+ * Purpose: Returns progress of DMA on requested channel
+ * Arguments: channel - channel to retrieve progress for
+ * progRep - pointer to user supplied MCD_XferProg struct
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ *
+ * Notes:
+ * MCD_XferProgrQuery() upon completing or after aborting a DMA, or
+ * while the DMA is in progress, this function returns the first
+ * DMA-destination address not (or not yet) used in the DMA. When
+ * encountering a non-ready buffer descriptor, the information for
+ * the last completed descriptor is returned.
+ *
+ * MCD_XferProgQuery() has to avoid the possibility of getting
+ * partially-updated information in the event that we should happen
+ * to query DMA progress just as the DMA is updating it. It does that
+ * by taking advantage of the fact context is not saved frequently for
+ * the most part. We therefore read it at least twice until we get the
+ * same information twice in a row.
+ *
+ * Because a small, but not insignificant, amount of time is required
+ * to write out the progress-query information, especially upon
+ * completion of the DMA, it would be wise to guarantee some time lag
+ * between successive readings of the progress-query information.
+ */
+
+/*
+ * How many iterations of the loop below to execute to stabilize values
+ */
+#define STABTIME 0
+
+int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep)
+{
+ MCD_XferProg prevRep;
+ int again; /* true if we are to try again to get consistent results */
+ int i; /* used as a time-waste counter */
+ int destDiffBytes; /* Total number of bytes that we think actually got xfered. */
+ int numIterations; /* number of iterations */
+ int bytesNotXfered; /* bytes that did not get xfered. */
+ s8 *LWAlignedInitDestAddr, *LWAlignedCurrDestAddr;
+ int subModVal, addModVal; /* Mode values to added and subtracted from the
+ final destAddr */
+
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ /* Read a trial value for the progress-reporting values*/
+ prevRep.lastSrcAddr =
+ (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
+ prevRep.lastDestAddr =
+ (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
+ prevRep.dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
+ prevRep.currBufDesc =
+ (MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
+ /* Repeatedly reread those values until they match previous values: */
+ do {
+ /* Waste a little bit of time to ensure stability: */
+ for (i = 0; i < STABTIME; i++)
+ i += i >> 2; /* make sure this loop does something so that it doesn't get optimized out */
+ /* Check them again: */
+ progRep->lastSrcAddr =
+ (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
+ progRep->lastDestAddr =
+ (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
+ progRep->dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
+ progRep->currBufDesc =
+ (MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
+ /* See if they match: */
+ if ( prevRep.lastSrcAddr != progRep->lastSrcAddr
+ || prevRep.lastDestAddr != progRep->lastDestAddr
+ || prevRep.dmaSize != progRep->dmaSize
+ || prevRep.currBufDesc != progRep->currBufDesc)
+ {
+ /* If they don't match, remember previous values and try again:*/
+ prevRep.lastSrcAddr = progRep->lastSrcAddr;
+ prevRep.lastDestAddr = progRep->lastDestAddr;
+ prevRep.dmaSize = progRep->dmaSize;
+ prevRep.currBufDesc = progRep->currBufDesc;
+ again = MCD_TRUE;
+ }
+ else
+ again = MCD_FALSE;
+ } while (again == MCD_TRUE);
+
+
+ /* Update the dCount, srcAddr and destAddr */
+ /* To calculate dmaCount, we consider destination address. C
+ overs M1,P1,Z for destination */
+ switch(MCD_remVariants.remDestRsdIncr[channel]) {
+ case MINUS1:
+ subModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
+ addModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
+ LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - addModVal;
+ LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
+ destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
+ bytesNotXfered = (destDiffBytes/MCD_remVariants.remDestIncr[channel]) *
+ ( MCD_remVariants.remDestIncr[channel]
+ + MCD_remVariants.remXferSize[channel]);
+ progRep->dmaSize = destDiffBytes - bytesNotXfered + addModVal - subModVal;
+ break;
+ case ZERO:
+ progRep->lastDestAddr = progRep->currBufDesc->destAddr;
+ break;
+ case PLUS1:
+ /* This value has to be subtracted from the final calculated dCount. */
+ subModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
+ /* These bytes are already in lastDestAddr. */
+ addModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
+ LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - subModVal;
+ LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
+ destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
+ numIterations = ( LWAlignedCurrDestAddr - LWAlignedInitDestAddr)/MCD_remVariants.remDestIncr[channel];
+ bytesNotXfered = numIterations *
+ ( MCD_remVariants.remDestIncr[channel]
+ - MCD_remVariants.remXferSize[channel]);
+ progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
+ break;
+ default:
+ break;
+ }
+
+ /* This covers M1,P1,Z for source */
+ switch(MCD_remVariants.remSrcRsdIncr[channel]) {
+ case MINUS1:
+ progRep->lastSrcAddr =
+ progRep->currBufDesc->srcAddr +
+ ( MCD_remVariants.remSrcIncr[channel] *
+ (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
+ break;
+ case ZERO:
+ progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
+ break;
+ case PLUS1:
+ progRep->lastSrcAddr =
+ progRep->currBufDesc->srcAddr +
+ ( MCD_remVariants.remSrcIncr[channel] *
+ (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
+ break;
+ default: break;
+ }
+
+ return(MCD_OK);
+}
+
+/* MCD_resmActions() does the majority of the actions of a DMA resume.
+ * It is called from MCD_killDma() and MCD_resumeDma(). It has to be
+ * a separate function because the kill function has to negate the task
+ * enable before resuming it, but the resume function has to do nothing
+ * if there is no DMA on that channel (i.e., if the enable bit is 0).
+ */
+static void MCD_resmActions (int channel)
+{
+ MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
+ MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
+ MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; /* This register is selected to know
+ which initiator is actually asserted. */
+ if((MCD_dmaBar->ptdDebug >> channel ) & 0x1)
+ MCD_chStatus[channel] = MCD_RUNNING;
+ else
+ MCD_chStatus[channel] = MCD_IDLE;
+}
+
+/* Function: MCD_killDma
+ * Purpose: Halt the DMA on the requested channel, without any
+ * intention of resuming the DMA.
+ * Arguments: channel - requested channel
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ *
+ * Notes:
+ * A DMA may be killed from any state, including paused state, and it
+ * always goes to the MCD_HALTED state even if it is killed while in
+ * the MCD_NO_DMA or MCD_IDLE states.
+ */
+int MCD_killDma (int channel)
+{
+ /* MCD_XferProg progRep; */
+
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ MCD_dmaBar->taskControl[channel] = 0x0;
+ MCD_resumeDma (channel);
+ /*
+ * This must be after the write to the TCR so that the task doesn't
+ * start up again momentarily, and before the status assignment so
+ * as to override whatever MCD_resumeDma() may do to the channel
+ * status.
+ */
+ MCD_chStatus[channel] = MCD_HALTED;
+
+ /*
+ * Update the current buffer descriptor's lastDestAddr field
+ *
+ * MCD_XferProgrQuery (channel, &progRep);
+ * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
+ */
+ return(MCD_OK);
+}
+
+/* Function: MCD_continDma
+ * Purpose: Continue a DMA which as stopped due to encountering an
+ * unready buffer descriptor.
+ * Arguments: channel - channel to continue the DMA on
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ *
+ * Notes:
+ * This routine does not check to see if there is a task which can
+ * be continued. Also this routine should not be used with single DMAs.
+ */
+int MCD_continDma (int channel)
+{
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
+ MCD_chStatus[channel] = MCD_RUNNING;
+
+ return(MCD_OK);
+}
+
+/*
+ * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit
+ * to freeze a task and resume it. We freeze a task by breakpointing
+ * on the stated task. That is, not any specific place in the task,
+ * but any time that task executes. In particular, when that task
+ * executes, we want to freeze that task and only that task.
+ *
+ * The bits of the debug control register influence interrupts vs.
+ * breakpoints as follows:
+ * - Bits 14 and 0 enable or disable debug functions. If enabled, you
+ * will get the interrupt but you may or may not get a breakpoint.
+ * - Bits 2 and 1 decide whether you also get a breakpoint in addition
+ * to an interrupt.
+ *
+ * The debug unit can do these actions in response to either internally
+ * detected breakpoint conditions from the comparators, or in response
+ * to the external breakpoint pin, or both.
+ * - Bits 14 and 1 perform the above-described functions for
+ * internally-generated conditions, i.e., the debug comparators.
+ * - Bits 0 and 2 perform the above-described functions for external
+ * conditions, i.e., the breakpoint external pin.
+ *
+ * Note that, although you "always" get the interrupt when you turn
+ * the debug functions, the interrupt can nevertheless, if desired, be
+ * masked by the corresponding bit in the PTD's IMR. Note also that
+ * this means that bits 14 and 0 must enable debug functions before
+ * bits 1 and 2, respectively, have any effect.
+ *
+ * NOTE: It's extremely important to not pause more than one DMA channel
+ * at a time.
+ ********************************************************************/
+
+/* Function: MCD_pauseDma
+ * Purpose: Pauses the DMA on a given channel (if any DMA is running
+ * on that channel).
+ * Arguments: channel
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ */
+int MCD_pauseDma (int channel)
+{
+ /* MCD_XferProg progRep; */
+
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
+ {
+ MCD_dmaBar->debugComp1 = channel;
+ MCD_dmaBar->debugControl = DBG_CTL_ENABLE | (1 << (channel + 16));
+ MCD_chStatus[channel] = MCD_PAUSED;
+
+ /*
+ * Update the current buffer descriptor's lastDestAddr field
+ *
+ * MCD_XferProgrQuery (channel, &progRep);
+ * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
+ */
+ }
+ return(MCD_OK);
+}
+
+/* Function: MCD_resumeDma
+ * Purpose: Resumes the DMA on a given channel (if any DMA is
+ * running on that channel).
+ * Arguments: channel - channel on which to resume DMA
+ * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
+ */
+int MCD_resumeDma (int channel)
+{
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
+ MCD_resmActions (channel);
+
+ return(MCD_OK);
+}
+
+/* Function: MCD_csumQuery
+ * Purpose: Provide the checksum after performing a non-chained DMA
+ * Arguments: channel - channel to report on
+ * csum - pointer to where to write the checksum/CRC
+ * Returns: MCD_ERROR if the channel is invalid, else MCD_OK
+ *
+ * Notes:
+ *
+ */
+int MCD_csumQuery (int channel, u32 *csum)
+{
+#ifdef MCD_INCLUDE_EU
+ if((channel < 0) || (channel >= NCHANNELS))
+ return(MCD_CHANNEL_INVALID);
+
+ *csum = MCD_relocBuffDesc[channel].csumResult;
+ return(MCD_OK);
+#else
+ return(MCD_ERROR);
+#endif
+}
+
+/* Function: MCD_getCodeSize
+ * Purpose: Provide the size requirements of the microcoded tasks
+ * Returns: Size in bytes
+ */
+int MCD_getCodeSize(void)
+{
+#ifdef MCD_INCLUDE_EU
+ return(0x2b5c);
+#else
+ return(0x173c);
+#endif
+}
+
+/* Function: MCD_getVersion
+ * Purpose: Provide the version string and number
+ * Arguments: longVersion - user supplied pointer to a pointer to a char
+ * which points to the version string
+ * Returns: Version number and version string (by reference)
+ */
+char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)";
+#define MCD_REV_MAJOR 0x00
+#define MCD_REV_MINOR 0x03
+
+int MCD_getVersion(char **longVersion)
+{
+ *longVersion = MCD_versionString;
+ return((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);
+}
+
+/* Private version of memcpy()
+ * Note that everything this is used for is longword-aligned.
+ */
+static void MCD_memcpy (int *dest, int *src, u32 size)
+{
+ u32 i;
+
+ for (i = 0; i < size; i += sizeof(int), dest++, src++)
+ *dest = *src;
+}
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox b/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox
new file mode 100644
index 0000000000..ec3a730730
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox
@@ -0,0 +1,10 @@
+/** @page mcfv4e_MCDlib MultiChannelDMA library for Coldfire V4e
+ *
+ * The MCD library is taken as is from sources publically available from
+ * FreeScale Semiconductors az http://www.freescale.com
+ *
+ * It is slight reformatted and cleaned up, but otherwise unchanged to support
+ * later merged with updated MCD library releases.
+ *
+ * See the PDF document supplied with the library for API documentation
+ */
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c
new file mode 100644
index 0000000000..3bfed232d7
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c
@@ -0,0 +1,2449 @@
+/*
+ * File: MCD_tasks.c
+ * Purpose: Contains task code and structures for Multi-channel DMA
+ *
+ * Notes:
+ */
+#include <asm/types.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+
+u32 MCD_varTab0[];
+u32 MCD_varTab1[];
+u32 MCD_varTab2[];
+u32 MCD_varTab3[];
+u32 MCD_varTab4[];
+u32 MCD_varTab5[];
+u32 MCD_varTab6[];
+u32 MCD_varTab7[];
+u32 MCD_varTab8[];
+u32 MCD_varTab9[];
+u32 MCD_varTab10[];
+u32 MCD_varTab11[];
+u32 MCD_varTab12[];
+u32 MCD_varTab13[];
+u32 MCD_varTab14[];
+u32 MCD_varTab15[];
+
+u32 MCD_funcDescTab0[];
+#ifdef MCD_INCLUDE_EU
+u32 MCD_funcDescTab1[];
+u32 MCD_funcDescTab2[];
+u32 MCD_funcDescTab3[];
+u32 MCD_funcDescTab4[];
+u32 MCD_funcDescTab5[];
+u32 MCD_funcDescTab6[];
+u32 MCD_funcDescTab7[];
+u32 MCD_funcDescTab8[];
+u32 MCD_funcDescTab9[];
+u32 MCD_funcDescTab10[];
+u32 MCD_funcDescTab11[];
+u32 MCD_funcDescTab12[];
+u32 MCD_funcDescTab13[];
+u32 MCD_funcDescTab14[];
+u32 MCD_funcDescTab15[];
+#endif
+
+u32 MCD_contextSave0[];
+u32 MCD_contextSave1[];
+u32 MCD_contextSave2[];
+u32 MCD_contextSave3[];
+u32 MCD_contextSave4[];
+u32 MCD_contextSave5[];
+u32 MCD_contextSave6[];
+u32 MCD_contextSave7[];
+u32 MCD_contextSave8[];
+u32 MCD_contextSave9[];
+u32 MCD_contextSave10[];
+u32 MCD_contextSave11[];
+u32 MCD_contextSave12[];
+u32 MCD_contextSave13[];
+u32 MCD_contextSave14[];
+u32 MCD_contextSave15[];
+
+u32 MCD_realTaskTableSrc[] =
+{
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab0, /* Task 0 Variable Table */
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave0, /* Task 0 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab1, /* Task 1 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab1, /* Task 1 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave1, /* Task 1 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab2, /* Task 2 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab2, /* Task 2 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave2, /* Task 2 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab3, /* Task 3 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab3, /* Task 3 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave3, /* Task 3 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab4, /* Task 4 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab4, /* Task 4 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave4, /* Task 4 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab5, /* Task 5 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab5, /* Task 5 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave5, /* Task 5 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab6, /* Task 6 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab6, /* Task 6 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave6, /* Task 6 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab7, /* Task 7 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab7, /* Task 7 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave7, /* Task 7 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab8, /* Task 8 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab8, /* Task 8 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave8, /* Task 8 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab9, /* Task 9 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab9, /* Task 9 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave9, /* Task 9 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab10, /* Task 10 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab10, /* Task 10 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave10, /* Task 10 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab11, /* Task 11 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab11, /* Task 11 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave11, /* Task 11 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab12, /* Task 12 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab12, /* Task 12 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave12, /* Task 12 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab13, /* Task 13 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab13, /* Task 13 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave13, /* Task 13 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab14, /* Task 14 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab14, /* Task 14 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave14, /* Task 14 context save space */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_varTab15, /* Task 15 Variable Table */
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_funcDescTab15, /* Task 15 Function Descriptor Table & Flags */
+#else
+ (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */
+#endif
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_contextSave15, /* Task 15 context save space */
+ 0x00000000,
+};
+
+
+u32 MCD_varTab0[] =
+{ /* Task 0 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+
+u32 MCD_varTab1[] =
+{ /* Task 1 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab2[]=
+{ /* Task 2 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab3[]=
+{ /* Task 3 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab4[]=
+{ /* Task 4 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab5[]=
+{ /* Task 5 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab6[]=
+{ /* Task 6 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab7[]=
+{ /* Task 7 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab8[]=
+{ /* Task 8 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab9[]=
+{ /* Task 9 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab10[]=
+{ /* Task 10 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab11[]=
+{ /* Task 11 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab12[]=
+{ /* Task 12 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab13[]=
+{ /* Task 13 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab14[]=
+{ /* Task 14 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_varTab15[]=
+{ /* Task 15 Variable Table */
+ 0x00000000, /* var[0] */
+ 0x00000000, /* var[1] */
+ 0x00000000, /* var[2] */
+ 0x00000000, /* var[3] */
+ 0x00000000, /* var[4] */
+ 0x00000000, /* var[5] */
+ 0x00000000, /* var[6] */
+ 0x00000000, /* var[7] */
+ 0x00000000, /* var[8] */
+ 0x00000000, /* var[9] */
+ 0x00000000, /* var[10] */
+ 0x00000000, /* var[11] */
+ 0x00000000, /* var[12] */
+ 0x00000000, /* var[13] */
+ 0x00000000, /* var[14] */
+ 0x00000000, /* var[15] */
+ 0x00000000, /* var[16] */
+ 0x00000000, /* var[17] */
+ 0x00000000, /* var[18] */
+ 0x00000000, /* var[19] */
+ 0x00000000, /* var[20] */
+ 0x00000000, /* var[21] */
+ 0x00000000, /* var[22] */
+ 0x00000000, /* var[23] */
+ 0xe0000000, /* inc[0] */
+ 0x20000000, /* inc[1] */
+ 0x2000ffff, /* inc[2] */
+ 0x00000000, /* inc[3] */
+ 0x00000000, /* inc[4] */
+ 0x00000000, /* inc[5] */
+ 0x00000000, /* inc[6] */
+ 0x00000000, /* inc[7] */
+};
+
+u32 MCD_funcDescTab0[]=
+{ /* Task 0 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+#ifdef MCD_INCLUDE_EU
+u32 MCD_funcDescTab1[]=
+{ /* Task 1 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab2[]=
+{ /* Task 2 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab3[]=
+{ /* Task 3 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab4[]=
+{ /* Task 4 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab5[]=
+{ /* Task 5 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab6[]=
+{ /* Task 6 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab7[]=
+{ /* Task 7 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab8[]=
+{ /* Task 8 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab9[]=
+{ /* Task 9 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab10[]=
+{ /* Task 10 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab11[]=
+{ /* Task 11 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab12[]=
+{ /* Task 12 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab13[]=
+{ /* Task 13 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab14[]=
+{ /* Task 14 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+
+u32 MCD_funcDescTab15[]=
+{ /* Task 15 Function Descriptor Table */
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0xa0045670, /* mainFunc(), EU# 3 */
+ 0xa0000000, /* rsduFunc(), EU# 3 */
+ 0xa0000000, /* crcAccumVal(), EU# 3 */
+ 0x20000000, /* setCrcAccum(), EU# 3 */
+ 0x21800000, /* and(), EU# 3 */
+ 0x21e00000, /* or(), EU# 3 */
+ 0x20400000, /* add(), EU# 3 */
+ 0x20500000, /* sub(), EU# 3 */
+ 0x205a0000, /* andNot(), EU# 3 */
+ 0x20a00000, /* shiftR(), EU# 3 */
+ 0x202fa000, /* andReadyBit(), EU# 3 */
+ 0x202f9000, /* andNotReadyBit(), EU# 3 */
+ 0x202ea000, /* andWrapBit(), EU# 3 */
+ 0x202da000, /* andLastBit(), EU# 3 */
+ 0x202e2000, /* andInterruptBit(), EU# 3 */
+ 0x202f2000, /* andCrcRestartBit(), EU# 3 */
+};
+#endif /*MCD_INCLUDE_EU*/
+
+u32 MCD_contextSave0[128]; /* Task 0 context save space */
+u32 MCD_contextSave1[128]; /* Task 1 context save space */
+u32 MCD_contextSave2[128]; /* Task 2 context save space */
+u32 MCD_contextSave3[128]; /* Task 3 context save space */
+u32 MCD_contextSave4[128]; /* Task 4 context save space */
+u32 MCD_contextSave5[128]; /* Task 5 context save space */
+u32 MCD_contextSave6[128]; /* Task 6 context save space */
+u32 MCD_contextSave7[128]; /* Task 7 context save space */
+u32 MCD_contextSave8[128]; /* Task 8 context save space */
+u32 MCD_contextSave9[128]; /* Task 9 context save space */
+u32 MCD_contextSave10[128]; /* Task 10 context save space */
+u32 MCD_contextSave11[128]; /* Task 11 context save space */
+u32 MCD_contextSave12[128]; /* Task 12 context save space */
+u32 MCD_contextSave13[128]; /* Task 13 context save space */
+u32 MCD_contextSave14[128]; /* Task 14 context save space */
+u32 MCD_contextSave15[128]; /* Task 15 context save space */
+
+
+u32 MCD_ChainNoEu_TDT[];
+u32 MCD_SingleNoEu_TDT[];
+#ifdef MCD_INCLUDE_EU
+u32 MCD_ChainEu_TDT[];
+u32 MCD_SingleEu_TDT[];
+#endif
+u32 MCD_ENetRcv_TDT[];
+u32 MCD_ENetXmit_TDT[];
+
+u32 MCD_modelTaskTableSrc[]=
+{
+ (u32)MCD_ChainNoEu_TDT,
+ (u32)&((u8*)MCD_ChainNoEu_TDT)[0x0000016c],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_SingleNoEu_TDT,
+ (u32)&((u8*)MCD_SingleNoEu_TDT)[0x000000d4],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+#ifdef MCD_INCLUDE_EU
+ (u32)MCD_ChainEu_TDT,
+ (u32)&((u8*)MCD_ChainEu_TDT)[0x000001b4],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_SingleEu_TDT,
+ (u32)&((u8*)MCD_SingleEu_TDT)[0x00000124],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+#endif
+ (u32)MCD_ENetRcv_TDT,
+ (u32)&((u8*)MCD_ENetRcv_TDT)[0x0000009c],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ (u32)MCD_ENetXmit_TDT,
+ (u32)&((u8*)MCD_ENetXmit_TDT)[0x000000d0],
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+};
+u32 MCD_ChainNoEu_TDT[]=
+{
+ 0x80004000, /* 0000(:370): LCDEXT: idx0 = 0x00000000; ; */
+ 0x8118801b, /* 0004(:370): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */
+ 0xb8c60018, /* 0008(:371): LCD: idx2 = *(idx1 + var12); idx2 once var0; idx2 += inc3 */
+ 0x10002b10, /* 000C(:372): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x7000000d, /* 0010(:373): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x018cf89f, /* 0014(:373): DRD2B1: var6 = EU3(); EU3(idx2) */
+ 0x6000000a, /* 0018(:374): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf89f, /* 001C(:374): DRD2B1: idx0 = EU3(); EU3(idx2) */
+ 0x000001f8, /* 0020(:0): NOP */
+ 0x98180364, /* 0024(:378): LCD: idx0 = idx0; idx0 == var13; idx0 += inc4 */
+ 0x8118801b, /* 0028(:380): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */
+ 0xf8c6001a, /* 002C(:381): LCDEXT: idx2 = *(idx1 + var12 + 8); idx2 once var0; idx2 += inc3 */
+ 0xb8c6601b, /* 0030(:382): LCD: idx3 = *(idx1 + var12 + 12); ; idx3 += inc3 */
+ 0x10002710, /* 0034(:384): DRD1A: var9 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x00000f18, /* 0038(:385): DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
+ 0xb8c6001d, /* 003C(:387): LCD: idx2 = *(idx1 + var12 + 20); idx2 once var0; idx2 += inc3 */
+ 0x10001310, /* 0040(:388): DRD1A: var4 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60000007, /* 0044(:389): DRD2A: EU0=0 EU1=0 EU2=0 EU3=7 EXT init=0 WS=0 RS=0 */
+ 0x014cf88b, /* 0048(:389): DRD2B1: var5 = EU3(); EU3(idx2,var11) */
+ 0x98c6001c, /* 004C(:391): LCD: idx2 = idx1 + var12 + 4; idx2 once var0; idx2 += inc3 */
+ 0x00000710, /* 0050(:392): DRD1A: var1 = idx2; FN=0 init=0 WS=0 RS=0 */
+ 0x98c70018, /* 0054(:393): LCD: idx2 = idx1 + var14; idx2 once var0; idx2 += inc3 */
+ 0x10001f10, /* 0058(:394): DRD1A: var7 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c818, /* 005C(:395): DRD1A: *idx2 = var3; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0060(:0): NOP */
+ 0xc1476018, /* 0064(:399): LCDEXT: idx1 = var2 + var14; ; idx1 += inc3 */
+ 0xc003231d, /* 0068(:399): LCDEXT: idx2 = var0, idx3 = var6; idx3 == var12; idx2 += inc3, idx3 += inc5 */
+ 0x811a601b, /* 006C(:400): LCD: idx4 = var2; ; idx4 += inc3 */
+ 0xc1862102, /* 0070(:403): LCDEXT: idx5 = var3, idx6 = var12; idx6 < var4; idx5 += inc0, idx6 += inc2 */
+ 0x849be009, /* 0074(:403): LCD: idx7 = var9; ; idx7 += inc1 */
+ 0x03fed7b8, /* 0078(:406): DRD1A: *idx7; FN=0 init=31 WS=3 RS=3 */
+ 0xda9b001b, /* 007C(:408): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 0080(:408): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x1000cb20, /* 0084(:409): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0088(:410): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 008C(:410): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb28, /* 0090(:411): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0094(:412): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 0098(:412): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb30, /* 009C(:413): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00A0(:414): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 00A4(:414): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb38, /* 00A8(:415): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c728, /* 00AC(:416): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 00B0(:0): NOP */
+ 0xc1476018, /* 00B4(:420): LCDEXT: idx1 = var2 + var14; ; idx1 += inc3 */
+ 0xc003241d, /* 00B8(:420): LCDEXT: idx2 = var0, idx3 = var6; idx3 == var16; idx2 += inc3, idx3 += inc5 */
+ 0x811a601b, /* 00BC(:421): LCD: idx4 = var2; ; idx4 += inc3 */
+ 0xda9b001b, /* 00C0(:424): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00C4(:424): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x0000d3a0, /* 00C8(:425): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */
+ 0xc1862102, /* 00CC(:427): LCDEXT: idx5 = var3, idx6 = var12; idx6 < var4; idx5 += inc0, idx6 += inc2 */
+ 0x849be009, /* 00D0(:427): LCD: idx7 = var9; ; idx7 += inc1 */
+ 0x0bfed7b8, /* 00D4(:430): DRD1A: *idx7; FN=0 TFD init=31 WS=3 RS=3 */
+ 0xda9b001b, /* 00D8(:432): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00DC(:432): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x1000cb20, /* 00E0(:433): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00E4(:434): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 00E8(:434): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb28, /* 00EC(:435): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00F0(:436): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 00F4(:436): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb30, /* 00F8(:437): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00FC(:438): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88f, /* 0100(:438): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */
+ 0x1000cb38, /* 0104(:439): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c728, /* 0108(:440): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 010C(:0): NOP */
+ 0x8118801b, /* 0110(:444): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */
+ 0xd8c60018, /* 0114(:446): LCDEXT: idx2 = idx1 + var12; idx2 once var0; idx2 += inc3 */
+ 0x98c6601c, /* 0118(:446): LCD: idx3 = idx1 + var12 + 4; ; idx3 += inc3 */
+ 0x6000000b, /* 011C(:447): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */
+ 0x0c8cfc9f, /* 0120(:447): DRD2B1: *idx2 = EU3(); EU3(*idx2) */
+ 0x000001f8, /* 0124(:0): NOP */
+ 0xa146001e, /* 0128(:450): LCD: idx1 = *(var2 + var12 + 24); idx1 once var0; idx1 += inc3 */
+ 0x10000b08, /* 012C(:451): DRD1A: var2 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x10002050, /* 0130(:452): DRD1A: var8 = var10; FN=0 MORE init=0 WS=0 RS=0 */
+ 0xb8c60018, /* 0134(:453): LCD: idx2 = *(idx1 + var12); idx2 once var0; idx2 += inc3 */
+ 0x10002b10, /* 0138(:454): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x7000000a, /* 013C(:455): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT MORE init=0 WS=0 RS=0 */
+ 0x080cf89f, /* 0140(:455): DRD2B1: idx0 = EU3(); EU3(idx2) */
+ 0x6000000d, /* 0144(:456): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT init=0 WS=0 RS=0 */
+ 0x018cf89f, /* 0148(:456): DRD2B1: var6 = EU3(); EU3(idx2) */
+ 0x000001f8, /* 014C(:0): NOP */
+ 0x8618801b, /* 0150(:462): LCD: idx1 = var12; idx1 once var0; idx1 += inc3 */
+ 0x7000000e, /* 0154(:463): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */
+ 0x084cf21f, /* 0158(:463): DRD2B1: idx1 = EU3(); EU3(var8) */
+ 0xd8990336, /* 015C(:464): LCDEXT: idx2 = idx1; idx2 > var12; idx2 += inc6 */
+ 0x8019801b, /* 0160(:464): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */
+ 0x040001f8, /* 0164(:465): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0168(:0): NOP */
+ 0x000001f8, /* 016C(:0): NOP */
+};
+u32 MCD_SingleNoEu_TDT[]=
+{
+ 0x8198001b, /* 0000(:657): LCD: idx0 = var3; idx0 once var0; idx0 += inc3 */
+ 0x7000000d, /* 0004(:658): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x080cf81f, /* 0008(:658): DRD2B1: idx0 = EU3(); EU3(idx0) */
+ 0x8198801b, /* 000C(:659): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */
+ 0x6000000e, /* 0010(:660): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */
+ 0x084cf85f, /* 0014(:660): DRD2B1: idx1 = EU3(); EU3(idx1) */
+ 0x000001f8, /* 0018(:0): NOP */
+ 0x8298001b, /* 001C(:664): LCD: idx0 = var5; idx0 once var0; idx0 += inc3 */
+ 0x7000000d, /* 0020(:665): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x010cf81f, /* 0024(:665): DRD2B1: var4 = EU3(); EU3(idx0) */
+ 0x6000000e, /* 0028(:666): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */
+ 0x018cf81f, /* 002C(:666): DRD2B1: var6 = EU3(); EU3(idx0) */
+ 0xc202601b, /* 0030(:669): LCDEXT: idx0 = var4, idx1 = var4; ; idx0 += inc3, idx1 += inc3 */
+ 0xc002221c, /* 0034(:669): LCDEXT: idx2 = var0, idx3 = var4; idx3 == var8; idx2 += inc3, idx3 += inc4 */
+ 0x809a601b, /* 0038(:670): LCD: idx4 = var1; ; idx4 += inc3 */
+ 0xc10420c2, /* 003C(:673): LCDEXT: idx5 = var2, idx6 = var8; idx6 < var3; idx5 += inc0, idx6 += inc2 */
+ 0x839be009, /* 0040(:673): LCD: idx7 = var7; ; idx7 += inc1 */
+ 0x03fed7b8, /* 0044(:676): DRD1A: *idx7; FN=0 init=31 WS=3 RS=3 */
+ 0xda9b001b, /* 0048(:678): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 004C(:678): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000006, /* 0050(:680): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 0054(:680): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x1000cb28, /* 0058(:681): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 005C(:682): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 0060(:682): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x1000cb30, /* 0064(:683): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0068(:684): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 006C(:684): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x0000cb38, /* 0070(:685): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0074(:0): NOP */
+ 0xc202601b, /* 0078(:689): LCDEXT: idx0 = var4, idx1 = var4; ; idx0 += inc3, idx1 += inc3 */
+ 0xc002229c, /* 007C(:689): LCDEXT: idx2 = var0, idx3 = var4; idx3 == var10; idx2 += inc3, idx3 += inc4 */
+ 0x809a601b, /* 0080(:690): LCD: idx4 = var1; ; idx4 += inc3 */
+ 0xda9b001b, /* 0084(:693): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 0088(:693): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x0000d3a0, /* 008C(:694): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */
+ 0xc10420c2, /* 0090(:696): LCDEXT: idx5 = var2, idx6 = var8; idx6 < var3; idx5 += inc0, idx6 += inc2 */
+ 0x839be009, /* 0094(:696): LCD: idx7 = var7; ; idx7 += inc1 */
+ 0x0bfed7b8, /* 0098(:699): DRD1A: *idx7; FN=0 TFD init=31 WS=3 RS=3 */
+ 0xda9b001b, /* 009C(:701): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00A0(:701): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000006, /* 00A4(:703): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 00A8(:703): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x1000cb28, /* 00AC(:704): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00B0(:705): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 00B4(:705): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x1000cb30, /* 00B8(:706): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00BC(:707): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf889, /* 00C0(:707): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */
+ 0x0000cb38, /* 00C4(:708): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 00C8(:0): NOP */
+ 0xc318022d, /* 00CC(:712): LCDEXT: idx0 = var6; idx0 > var8; idx0 += inc5 */
+ 0x8018801b, /* 00D0(:712): LCD: idx1 = var0; idx1 once var0; idx1 += inc3 */
+ 0x040001f8, /* 00D4(:713): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+};
+#ifdef MCD_INCLUDE_EU
+u32 MCD_ChainEu_TDT[]=
+{
+ 0x80004000, /* 0000(:947): LCDEXT: idx0 = 0x00000000; ; */
+ 0x8198801b, /* 0004(:947): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */
+ 0xb8c68018, /* 0008(:948): LCD: idx2 = *(idx1 + var13); idx2 once var0; idx2 += inc3 */
+ 0x10002f10, /* 000C(:949): DRD1A: var11 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x7000000d, /* 0010(:950): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x01ccf89f, /* 0014(:950): DRD2B1: var7 = EU3(); EU3(idx2) */
+ 0x6000000a, /* 0018(:951): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf89f, /* 001C(:951): DRD2B1: idx0 = EU3(); EU3(idx2) */
+ 0x000001f8, /* 0020(:0): NOP */
+ 0x981803a4, /* 0024(:955): LCD: idx0 = idx0; idx0 == var14; idx0 += inc4 */
+ 0x8198801b, /* 0028(:957): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */
+ 0xf8c6801a, /* 002C(:958): LCDEXT: idx2 = *(idx1 + var13 + 8); idx2 once var0; idx2 += inc3 */
+ 0xb8c6e01b, /* 0030(:959): LCD: idx3 = *(idx1 + var13 + 12); ; idx3 += inc3 */
+ 0x10002b10, /* 0034(:961): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x00001318, /* 0038(:962): DRD1A: var4 = idx3; FN=0 init=0 WS=0 RS=0 */
+ 0xb8c6801d, /* 003C(:964): LCD: idx2 = *(idx1 + var13 + 20); idx2 once var0; idx2 += inc3 */
+ 0x10001710, /* 0040(:965): DRD1A: var5 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60000007, /* 0044(:966): DRD2A: EU0=0 EU1=0 EU2=0 EU3=7 EXT init=0 WS=0 RS=0 */
+ 0x018cf88c, /* 0048(:966): DRD2B1: var6 = EU3(); EU3(idx2,var12) */
+ 0x98c6801c, /* 004C(:968): LCD: idx2 = idx1 + var13 + 4; idx2 once var0; idx2 += inc3 */
+ 0x00000b10, /* 0050(:969): DRD1A: var2 = idx2; FN=0 init=0 WS=0 RS=0 */
+ 0x98c78018, /* 0054(:970): LCD: idx2 = idx1 + var15; idx2 once var0; idx2 += inc3 */
+ 0x10002310, /* 0058(:971): DRD1A: var8 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c820, /* 005C(:972): DRD1A: *idx2 = var4; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0060(:0): NOP */
+ 0x8698801b, /* 0064(:976): LCD: idx1 = var13; idx1 once var0; idx1 += inc3 */
+ 0x7000000f, /* 0068(:977): DRD2A: EU0=0 EU1=0 EU2=0 EU3=15 EXT MORE init=0 WS=0 RS=0 */
+ 0x084cf2df, /* 006C(:977): DRD2B1: idx1 = EU3(); EU3(var11) */
+ 0xd899042d, /* 0070(:978): LCDEXT: idx2 = idx1; idx2 >= var16; idx2 += inc5 */
+ 0x8019801b, /* 0074(:978): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */
+ 0x60000003, /* 0078(:979): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+ 0x2cd7c7df, /* 007C(:979): DRD2B2: EU3(var13) */
+ 0xd8990364, /* 0080(:980): LCDEXT: idx2 = idx1; idx2 == var13; idx2 += inc4 */
+ 0x8019801b, /* 0084(:980): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */
+ 0x60000003, /* 0088(:981): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+ 0x2c17c7df, /* 008C(:981): DRD2B2: EU3(var1) */
+ 0x000001f8, /* 0090(:0): NOP */
+ 0xc1c7e018, /* 0094(:984): LCDEXT: idx1 = var3 + var15; ; idx1 += inc3 */
+ 0xc003a35e, /* 0098(:984): LCDEXT: idx2 = var0, idx3 = var7; idx3 == var13; idx2 += inc3, idx3 += inc6 */
+ 0x819a601b, /* 009C(:985): LCD: idx4 = var3; ; idx4 += inc3 */
+ 0xc206a142, /* 00A0(:988): LCDEXT: idx5 = var4, idx6 = var13; idx6 < var5; idx5 += inc0, idx6 += inc2 */
+ 0x851be009, /* 00A4(:988): LCD: idx7 = var10; ; idx7 += inc1 */
+ 0x63fe0000, /* 00A8(:991): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=31 WS=3 RS=3 */
+ 0x0d4cfddf, /* 00AC(:991): DRD2B1: *idx5 = EU3(); EU3(*idx7) */
+ 0xda9b001b, /* 00B0(:993): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00B4(:993): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000002, /* 00B8(:994): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x004cf81f, /* 00BC(:994): DRD2B1: var1 = EU3(); EU3(idx0) */
+ 0x1000cb20, /* 00C0(:995): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00C4(:996): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 00C8(:996): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb28, /* 00CC(:997): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00D0(:998): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 00D4(:998): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb30, /* 00D8(:999): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00DC(:1000): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 00E0(:1000): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb38, /* 00E4(:1001): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c728, /* 00E8(:1002): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 00EC(:0): NOP */
+ 0xc1c7e018, /* 00F0(:1006): LCDEXT: idx1 = var3 + var15; ; idx1 += inc3 */
+ 0xc003a49e, /* 00F4(:1006): LCDEXT: idx2 = var0, idx3 = var7; idx3 == var18; idx2 += inc3, idx3 += inc6 */
+ 0x819a601b, /* 00F8(:1007): LCD: idx4 = var3; ; idx4 += inc3 */
+ 0xda9b001b, /* 00FC(:1010): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 0100(:1010): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x0000d3a0, /* 0104(:1011): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */
+ 0xc206a142, /* 0108(:1013): LCDEXT: idx5 = var4, idx6 = var13; idx6 < var5; idx5 += inc0, idx6 += inc2 */
+ 0x851be009, /* 010C(:1013): LCD: idx7 = var10; ; idx7 += inc1 */
+ 0x6bfe0000, /* 0110(:1016): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 TFD EXT init=31 WS=3 RS=3 */
+ 0x0d4cfddf, /* 0114(:1016): DRD2B1: *idx5 = EU3(); EU3(*idx7) */
+ 0xda9b001b, /* 0118(:1018): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 011C(:1018): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000002, /* 0120(:1019): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x004cf81f, /* 0124(:1019): DRD2B1: var1 = EU3(); EU3(idx0) */
+ 0x1000cb20, /* 0128(:1020): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 012C(:1021): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 0130(:1021): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb28, /* 0134(:1022): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0138(:1023): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 013C(:1023): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb30, /* 0140(:1024): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0144(:1025): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf891, /* 0148(:1025): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */
+ 0x1000cb38, /* 014C(:1026): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x0000c728, /* 0150(:1027): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0154(:0): NOP */
+ 0x8198801b, /* 0158(:1031): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */
+ 0xd8c68018, /* 015C(:1033): LCDEXT: idx2 = idx1 + var13; idx2 once var0; idx2 += inc3 */
+ 0x98c6e01c, /* 0160(:1033): LCD: idx3 = idx1 + var13 + 4; ; idx3 += inc3 */
+ 0x6000000b, /* 0164(:1034): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */
+ 0x0c8cfc9f, /* 0168(:1034): DRD2B1: *idx2 = EU3(); EU3(*idx2) */
+ 0x0000cc08, /* 016C(:1035): DRD1A: *idx3 = var1; FN=0 init=0 WS=0 RS=0 */
+ 0xa1c6801e, /* 0170(:1038): LCD: idx1 = *(var3 + var13 + 24); idx1 once var0; idx1 += inc3 */
+ 0x10000f08, /* 0174(:1039): DRD1A: var3 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x10002458, /* 0178(:1040): DRD1A: var9 = var11; FN=0 MORE init=0 WS=0 RS=0 */
+ 0xb8c68018, /* 017C(:1041): LCD: idx2 = *(idx1 + var13); idx2 once var0; idx2 += inc3 */
+ 0x10002f10, /* 0180(:1042): DRD1A: var11 = idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x7000000a, /* 0184(:1043): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT MORE init=0 WS=0 RS=0 */
+ 0x080cf89f, /* 0188(:1043): DRD2B1: idx0 = EU3(); EU3(idx2) */
+ 0x6000000d, /* 018C(:1044): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT init=0 WS=0 RS=0 */
+ 0x01ccf89f, /* 0190(:1044): DRD2B1: var7 = EU3(); EU3(idx2) */
+ 0x000001f8, /* 0194(:0): NOP */
+ 0x8698801b, /* 0198(:1050): LCD: idx1 = var13; idx1 once var0; idx1 += inc3 */
+ 0x7000000e, /* 019C(:1051): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */
+ 0x084cf25f, /* 01A0(:1051): DRD2B1: idx1 = EU3(); EU3(var9) */
+ 0xd899037f, /* 01A4(:1052): LCDEXT: idx2 = idx1; idx2 > var13; idx2 += inc7 */
+ 0x8019801b, /* 01A8(:1052): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */
+ 0x040001f8, /* 01AC(:1053): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+ 0x000001f8, /* 01B0(:0): NOP */
+ 0x000001f8, /* 01B4(:0): NOP */
+};
+u32 MCD_SingleEu_TDT[]=
+{
+ 0x8218001b, /* 0000(:1248): LCD: idx0 = var4; idx0 once var0; idx0 += inc3 */
+ 0x7000000d, /* 0004(:1249): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x080cf81f, /* 0008(:1249): DRD2B1: idx0 = EU3(); EU3(idx0) */
+ 0x8218801b, /* 000C(:1250): LCD: idx1 = var4; idx1 once var0; idx1 += inc3 */
+ 0x6000000e, /* 0010(:1251): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */
+ 0x084cf85f, /* 0014(:1251): DRD2B1: idx1 = EU3(); EU3(idx1) */
+ 0x000001f8, /* 0018(:0): NOP */
+ 0x8318001b, /* 001C(:1255): LCD: idx0 = var6; idx0 once var0; idx0 += inc3 */
+ 0x7000000d, /* 0020(:1256): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x014cf81f, /* 0024(:1256): DRD2B1: var5 = EU3(); EU3(idx0) */
+ 0x6000000e, /* 0028(:1257): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */
+ 0x01ccf81f, /* 002C(:1257): DRD2B1: var7 = EU3(); EU3(idx0) */
+ 0x8498001b, /* 0030(:1260): LCD: idx0 = var9; idx0 once var0; idx0 += inc3 */
+ 0x7000000f, /* 0034(:1261): DRD2A: EU0=0 EU1=0 EU2=0 EU3=15 EXT MORE init=0 WS=0 RS=0 */
+ 0x080cf19f, /* 0038(:1261): DRD2B1: idx0 = EU3(); EU3(var6) */
+ 0xd81882a4, /* 003C(:1262): LCDEXT: idx1 = idx0; idx1 >= var10; idx1 += inc4 */
+ 0x8019001b, /* 0040(:1262): LCD: idx2 = var0; idx2 once var0; idx2 += inc3 */
+ 0x60000003, /* 0044(:1263): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+ 0x2c97c7df, /* 0048(:1263): DRD2B2: EU3(var9) */
+ 0xd818826d, /* 004C(:1264): LCDEXT: idx1 = idx0; idx1 == var9; idx1 += inc5 */
+ 0x8019001b, /* 0050(:1264): LCD: idx2 = var0; idx2 once var0; idx2 += inc3 */
+ 0x60000003, /* 0054(:1265): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+ 0x2c17c7df, /* 0058(:1265): DRD2B2: EU3(var1) */
+ 0x000001f8, /* 005C(:0): NOP */
+ 0xc282e01b, /* 0060(:1268): LCDEXT: idx0 = var5, idx1 = var5; ; idx0 += inc3, idx1 += inc3 */
+ 0xc002a25e, /* 0064(:1268): LCDEXT: idx2 = var0, idx3 = var5; idx3 == var9; idx2 += inc3, idx3 += inc6 */
+ 0x811a601b, /* 0068(:1269): LCD: idx4 = var2; ; idx4 += inc3 */
+ 0xc184a102, /* 006C(:1272): LCDEXT: idx5 = var3, idx6 = var9; idx6 < var4; idx5 += inc0, idx6 += inc2 */
+ 0x841be009, /* 0070(:1272): LCD: idx7 = var8; ; idx7 += inc1 */
+ 0x63fe0000, /* 0074(:1275): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=31 WS=3 RS=3 */
+ 0x0d4cfddf, /* 0078(:1275): DRD2B1: *idx5 = EU3(); EU3(*idx7) */
+ 0xda9b001b, /* 007C(:1277): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 0080(:1277): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000002, /* 0084(:1279): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x004cf99f, /* 0088(:1279): DRD2B1: var1 = EU3(); EU3(idx6) */
+ 0x70000006, /* 008C(:1280): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 0090(:1280): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x1000cb28, /* 0094(:1281): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0098(:1282): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 009C(:1282): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x1000cb30, /* 00A0(:1283): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00A4(:1284): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 00A8(:1284): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x0000cb38, /* 00AC(:1285): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 00B0(:0): NOP */
+ 0xc282e01b, /* 00B4(:1289): LCDEXT: idx0 = var5, idx1 = var5; ; idx0 += inc3, idx1 += inc3 */
+ 0xc002a31e, /* 00B8(:1289): LCDEXT: idx2 = var0, idx3 = var5; idx3 == var12; idx2 += inc3, idx3 += inc6 */
+ 0x811a601b, /* 00BC(:1290): LCD: idx4 = var2; ; idx4 += inc3 */
+ 0xda9b001b, /* 00C0(:1293): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00C4(:1293): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x0000d3a0, /* 00C8(:1294): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */
+ 0xc184a102, /* 00CC(:1296): LCDEXT: idx5 = var3, idx6 = var9; idx6 < var4; idx5 += inc0, idx6 += inc2 */
+ 0x841be009, /* 00D0(:1296): LCD: idx7 = var8; ; idx7 += inc1 */
+ 0x6bfe0000, /* 00D4(:1299): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 TFD EXT init=31 WS=3 RS=3 */
+ 0x0d4cfddf, /* 00D8(:1299): DRD2B1: *idx5 = EU3(); EU3(*idx7) */
+ 0xda9b001b, /* 00DC(:1301): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */
+ 0x9b9be01b, /* 00E0(:1301): LCD: idx7 = idx7; ; idx7 += inc3 */
+ 0x70000002, /* 00E4(:1303): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x004cf99f, /* 00E8(:1303): DRD2B1: var1 = EU3(); EU3(idx6) */
+ 0x70000006, /* 00EC(:1304): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 00F0(:1304): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x1000cb28, /* 00F4(:1305): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 00F8(:1306): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 00FC(:1306): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x1000cb30, /* 0100(:1307): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x70000006, /* 0104(:1308): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf88b, /* 0108(:1308): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */
+ 0x0000cb38, /* 010C(:1309): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */
+ 0x000001f8, /* 0110(:0): NOP */
+ 0x8144801c, /* 0114(:1312): LCD: idx0 = var2 + var9 + 4; idx0 once var0; idx0 += inc3 */
+ 0x0000c008, /* 0118(:1313): DRD1A: *idx0 = var1; FN=0 init=0 WS=0 RS=0 */
+ 0xc398027f, /* 011C(:1315): LCDEXT: idx0 = var7; idx0 > var9; idx0 += inc7 */
+ 0x8018801b, /* 0120(:1315): LCD: idx1 = var0; idx1 once var0; idx1 += inc3 */
+ 0x040001f8, /* 0124(:1316): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+};
+#endif
+u32 MCD_ENetRcv_TDT[]=
+{
+ 0x80004000, /* 0000(:1389): LCDEXT: idx0 = 0x00000000; ; */
+ 0x81988000, /* 0004(:1389): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+ 0x10000788, /* 0008(:1390): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x6000000a, /* 000C(:1391): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf05f, /* 0010(:1391): DRD2B1: idx0 = EU3(); EU3(var1) */
+ 0x98180209, /* 0014(:1394): LCD: idx0 = idx0; idx0 != var8; idx0 += inc1 */
+ 0x81c40004, /* 0018(:1396): LCD: idx1 = var3 + var8 + 4; idx1 once var0; idx1 += inc0 */
+ 0x7000000e, /* 001C(:1397): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */
+ 0x010cf05f, /* 0020(:1397): DRD2B1: var4 = EU3(); EU3(var1) */
+ 0x7000000c, /* 0024(:1398): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT MORE init=0 WS=0 RS=0 */
+ 0x01ccf05f, /* 0028(:1398): DRD2B1: var7 = EU3(); EU3(var1) */
+ 0x70000004, /* 002C(:1399): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */
+ 0x014cf049, /* 0030(:1399): DRD2B1: var5 = EU3(); EU3(var1,var9) */
+ 0x70000004, /* 0034(:1400): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */
+ 0x004cf04a, /* 0038(:1400): DRD2B1: var1 = EU3(); EU3(var1,var10) */
+ 0x00000b88, /* 003C(:1403): DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */
+ 0xc4030150, /* 0040(:1406): LCDEXT: idx1 = var8, idx2 = var6; idx1 < var5; idx1 += inc2, idx2 += inc0 */
+ 0x8119e012, /* 0044(:1406): LCD: idx3 = var2; ; idx3 += inc2 */
+ 0x03e0cf90, /* 0048(:1409): DRD1A: *idx3 = *idx2; FN=0 init=31 WS=0 RS=0 */
+ 0x81188000, /* 004C(:1412): LCD: idx1 = var2; idx1 once var0; idx1 += inc0 */
+ 0x000ac788, /* 0050(:1413): DRD1A: *idx1 = *idx1; FN=0 init=0 WS=1 RS=1 */
+ 0xc4030000, /* 0054(:1415): LCDEXT: idx1 = var8, idx2 = var6; idx1 once var0; idx1 += inc0, idx2 += inc0 */
+ 0x8199e000, /* 0058(:1415): LCD: idx3 = var3; ; idx3 += inc0 */
+ 0x70000004, /* 005C(:1421): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */
+ 0x084cfc8b, /* 0060(:1421): DRD2B1: idx1 = EU3(); EU3(*idx2,var11) */
+ 0x60000005, /* 0064(:1422): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+ 0x0cccf841, /* 0068(:1422): DRD2B1: *idx3 = EU3(); EU3(idx1,var1) */
+ 0x81c60000, /* 006C(:1428): LCD: idx1 = var3 + var12; idx1 once var0; idx1 += inc0 */
+ 0xc399021b, /* 0070(:1430): LCDEXT: idx2 = var7; idx2 > var8; idx2 += inc3 */
+ 0x80198000, /* 0074(:1430): LCD: idx3 = var0; idx3 once var0; idx3 += inc0 */
+ 0x00008400, /* 0078(:1431): DRD1A: idx1 = var0; FN=0 init=0 WS=0 RS=0 */
+ 0x00000f08, /* 007C(:1432): DRD1A: var3 = idx1; FN=0 init=0 WS=0 RS=0 */
+ 0x81988000, /* 0080(:1435): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+ 0x10000788, /* 0084(:1436): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x6000000a, /* 0088(:1437): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf05f, /* 008C(:1437): DRD2B1: idx0 = EU3(); EU3(var1) */
+ 0xc2188209, /* 0090(:1440): LCDEXT: idx1 = var4; idx1 != var8; idx1 += inc1 */
+ 0x80190000, /* 0094(:1440): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
+ 0x040001f8, /* 0098(:1441): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+ 0x000001f8, /* 009C(:0): NOP */
+};
+u32 MCD_ENetXmit_TDT[]=
+{
+ 0x80004000, /* 0000(:1516): LCDEXT: idx0 = 0x00000000; ; */
+ 0x81988000, /* 0004(:1516): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+ 0x10000788, /* 0008(:1517): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x6000000a, /* 000C(:1518): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf05f, /* 0010(:1518): DRD2B1: idx0 = EU3(); EU3(var1) */
+ 0x98180309, /* 0014(:1521): LCD: idx0 = idx0; idx0 != var12; idx0 += inc1 */
+ 0x80004003, /* 0018(:1523): LCDEXT: idx1 = 0x00000003; ; */
+ 0x81c60004, /* 001C(:1523): LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */
+ 0x7000000e, /* 0020(:1524): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */
+ 0x014cf05f, /* 0024(:1524): DRD2B1: var5 = EU3(); EU3(var1) */
+ 0x7000000c, /* 0028(:1525): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT MORE init=0 WS=0 RS=0 */
+ 0x028cf05f, /* 002C(:1525): DRD2B1: var10 = EU3(); EU3(var1) */
+ 0x7000000d, /* 0030(:1526): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */
+ 0x018cf05f, /* 0034(:1526): DRD2B1: var6 = EU3(); EU3(var1) */
+ 0x70000004, /* 0038(:1527): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */
+ 0x01ccf04d, /* 003C(:1527): DRD2B1: var7 = EU3(); EU3(var1,var13) */
+ 0x10000b90, /* 0040(:1528): DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60000004, /* 0044(:1529): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT init=0 WS=0 RS=0 */
+ 0x020cf0a1, /* 0048(:1529): DRD2B1: var8 = EU3(); EU3(var2,idx1) */
+ 0xc3188312, /* 004C(:1532): LCDEXT: idx1 = var6; idx1 > var12; idx1 += inc2 */
+ 0x83c70000, /* 0050(:1532): LCD: idx2 = var7 + var14; idx2 once var0; idx2 += inc0 */
+ 0x00001f10, /* 0054(:1533): DRD1A: var7 = idx2; FN=0 init=0 WS=0 RS=0 */
+ 0xc583a3c3, /* 0058(:1535): LCDEXT: idx1 = var11, idx2 = var7; idx2 >= var15; idx1 += inc0, idx2 += inc3 */
+ 0x81042325, /* 005C(:1535): LCD: idx3 = var2, idx4 = var8; idx4 == var12; idx3 += inc4, idx4 += inc5 */
+ 0x03e0c798, /* 0060(:1540): DRD1A: *idx1 = *idx3; FN=0 init=31 WS=0 RS=0 */
+ 0xd8990000, /* 0064(:1543): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */
+ 0x9999e000, /* 0068(:1543): LCD: idx3 = idx3; ; idx3 += inc0 */
+ 0x000acf98, /* 006C(:1544): DRD1A: *idx3 = *idx3; FN=0 init=0 WS=1 RS=1 */
+ 0xd8992306, /* 0070(:1546): LCDEXT: idx1 = idx1, idx2 = idx2; idx2 > var12; idx1 += inc0, idx2 += inc6 */
+ 0x9999e03f, /* 0074(:1546): LCD: idx3 = idx3; ; idx3 += inc7 */
+ 0x03eac798, /* 0078(:1549): DRD1A: *idx1 = *idx3; FN=0 init=31 WS=1 RS=1 */
+ 0xd8990000, /* 007C(:1552): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */
+ 0x9999e000, /* 0080(:1552): LCD: idx3 = idx3; ; idx3 += inc0 */
+ 0x000acf98, /* 0084(:1553): DRD1A: *idx3 = *idx3; FN=0 init=0 WS=1 RS=1 */
+ 0xd8990000, /* 0088(:1555): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */
+ 0x99832302, /* 008C(:1555): LCD: idx3 = idx3, idx4 = var6; idx4 > var12; idx3 += inc0, idx4 += inc2 */
+ 0x0beac798, /* 0090(:1558): DRD1A: *idx1 = *idx3; FN=0 TFD init=31 WS=1 RS=1 */
+ 0x81988000, /* 0094(:1560): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+ 0x6000000b, /* 0098(:1561): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */
+ 0x0c4cfc5f, /* 009C(:1561): DRD2B1: *idx1 = EU3(); EU3(*idx1) */
+ 0x81c80000, /* 00A0(:1563): LCD: idx1 = var3 + var16; idx1 once var0; idx1 += inc0 */
+ 0xc5190312, /* 00A4(:1565): LCDEXT: idx2 = var10; idx2 > var12; idx2 += inc2 */
+ 0x80198000, /* 00A8(:1565): LCD: idx3 = var0; idx3 once var0; idx3 += inc0 */
+ 0x00008400, /* 00AC(:1566): DRD1A: idx1 = var0; FN=0 init=0 WS=0 RS=0 */
+ 0x00000f08, /* 00B0(:1567): DRD1A: var3 = idx1; FN=0 init=0 WS=0 RS=0 */
+ 0x81988000, /* 00B4(:1570): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
+ 0x10000788, /* 00B8(:1571): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x6000000a, /* 00BC(:1572): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */
+ 0x080cf05f, /* 00C0(:1572): DRD2B1: idx0 = EU3(); EU3(var1) */
+ 0xc2988309, /* 00C4(:1575): LCDEXT: idx1 = var5; idx1 != var12; idx1 += inc1 */
+ 0x80190000, /* 00C8(:1575): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
+ 0x040001f8, /* 00CC(:1576): DRD1A: FN=0 INT init=0 WS=0 RS=0 */
+ 0x000001f8, /* 00D0(:0): NOP */
+};
+
+#ifdef MCD_INCLUDE_EU
+MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
+#endif
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c
new file mode 100644
index 0000000000..14104f7185
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c
@@ -0,0 +1,225 @@
+/*
+ * File: MCD_tasksInit.c
+ * Purpose: Functions for initializing variable tables of different
+ * types of tasks.
+ *
+ * Notes:
+ */
+
+/*
+ * Do not edit!
+ */
+
+#include <asm/types.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+
+extern dmaRegs *MCD_dmaBar;
+
+
+/*
+ * Task 0
+ */
+
+void MCD_startDmaChainNoEu(int *currBD, short srcIncr, short destIncr, int xferSize, short xferSizeIncr, int *cSave, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 2, (u32)currBD); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 11, (u32)xferSize); /* var[11] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 3, (u32)0x00000000); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000000); /* var[12] */
+ MCD_SET_VAR(taskTable+channel, 13, (u32)0x80000000); /* var[13] */
+ MCD_SET_VAR(taskTable+channel, 14, (u32)0x00000010); /* var[14] */
+ MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000004); /* var[15] */
+ MCD_SET_VAR(taskTable+channel, 16, (u32)0x08000000); /* var[16] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */
+ MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000000); /* inc[4] */
+ MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000001); /* inc[5] */
+ MCD_SET_VAR(taskTable+channel, 30, (u32)0x40000000); /* inc[6] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
+
+
+/*
+ * Task 1
+ */
+
+void MCD_startDmaSingleNoEu(char *srcAddr, short srcIncr, char *destAddr, short destIncr, int dmaSize, short xferSizeIncr, int flags, int *currBD, int *cSave, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 7, (u32)srcAddr); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 2, (u32)destAddr); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 3, (u32)dmaSize); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)flags); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)currBD); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000004); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x08000000); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */
+ MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000001); /* inc[4] */
+ MCD_SET_VAR(taskTable+channel, 29, (u32)0x40000000); /* inc[5] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
+
+
+/*
+ * Task 2
+ */
+
+void MCD_startDmaChainEu(int *currBD, short srcIncr, short destIncr, int xferSize, short xferSizeIncr, int *cSave, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 12, (u32)xferSize); /* var[12] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 11, (u32)0x00000000); /* var[11] */
+ MCD_SET_VAR(taskTable+channel, 13, (u32)0x00000000); /* var[13] */
+ MCD_SET_VAR(taskTable+channel, 14, (u32)0x80000000); /* var[14] */
+ MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000010); /* var[15] */
+ MCD_SET_VAR(taskTable+channel, 16, (u32)0x00000001); /* var[16] */
+ MCD_SET_VAR(taskTable+channel, 17, (u32)0x00000004); /* var[17] */
+ MCD_SET_VAR(taskTable+channel, 18, (u32)0x08000000); /* var[18] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */
+ MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000000); /* inc[4] */
+ MCD_SET_VAR(taskTable+channel, 29, (u32)0xc0000000); /* inc[5] */
+ MCD_SET_VAR(taskTable+channel, 30, (u32)0x80000001); /* inc[6] */
+ MCD_SET_VAR(taskTable+channel, 31, (u32)0x40000000); /* inc[7] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
+
+
+/*
+ * Task 3
+ */
+
+void MCD_startDmaSingleEu(char *srcAddr, short srcIncr, char *destAddr, short destIncr, int dmaSize, short xferSizeIncr, int flags, int *currBD, int *cSave, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 8, (u32)srcAddr); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 3, (u32)destAddr); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)dmaSize); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)flags); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 2, (u32)currBD); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000001); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 11, (u32)0x00000004); /* var[11] */
+ MCD_SET_VAR(taskTable+channel, 12, (u32)0x08000000); /* var[12] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */
+ MCD_SET_VAR(taskTable+channel, 28, (u32)0xc0000000); /* inc[4] */
+ MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000000); /* inc[5] */
+ MCD_SET_VAR(taskTable+channel, 30, (u32)0x80000001); /* inc[6] */
+ MCD_SET_VAR(taskTable+channel, 31, (u32)0x40000000); /* inc[7] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
+
+
+/*
+ * Task 4
+ */
+
+void MCD_startDmaENetRcv(char *bDBase, char *currBD, char *rcvFifoPtr, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 0, (u32)bDBase); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)rcvFifoPtr); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x0000ffff); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x30000000); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 11, (u32)0x0fffffff); /* var[11] */
+ MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000008); /* var[12] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)0x00000000); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)0x60000000); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)0x20000004); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0x40000000); /* inc[3] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
+
+
+/*
+ * Task 5
+ */
+
+void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, volatile TaskTableEntry *taskTable, int channel)
+{
+
+ MCD_SET_VAR(taskTable+channel, 0, (u32)bDBase); /* var[0] */
+ MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */
+ MCD_SET_VAR(taskTable+channel, 11, (u32)xmitFifoPtr); /* var[11] */
+ MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */
+ MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */
+ MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */
+ MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */
+ MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */
+ MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */
+ MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */
+ MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */
+ MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */
+ MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000000); /* var[12] */
+ MCD_SET_VAR(taskTable+channel, 13, (u32)0x0000ffff); /* var[13] */
+ MCD_SET_VAR(taskTable+channel, 14, (u32)0xffffffff); /* var[14] */
+ MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000004); /* var[15] */
+ MCD_SET_VAR(taskTable+channel, 16, (u32)0x00000008); /* var[16] */
+ MCD_SET_VAR(taskTable+channel, 24, (u32)0x00000000); /* inc[0] */
+ MCD_SET_VAR(taskTable+channel, 25, (u32)0x60000000); /* inc[1] */
+ MCD_SET_VAR(taskTable+channel, 26, (u32)0x40000000); /* inc[2] */
+ MCD_SET_VAR(taskTable+channel, 27, (u32)0xc000fffc); /* inc[3] */
+ MCD_SET_VAR(taskTable+channel, 28, (u32)0xe0000004); /* inc[4] */
+ MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000000); /* inc[5] */
+ MCD_SET_VAR(taskTable+channel, 30, (u32)0x4000ffff); /* inc[6] */
+ MCD_SET_VAR(taskTable+channel, 31, (u32)0xe0000001); /* inc[7] */
+
+ /* Set the task's Enable bit in its Task Control Register */
+ MCD_dmaBar->taskControl[channel] |= (u16)0x8000;
+}
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/Makefile b/arch/m68k/mach-mcfv4e/mcdapi/Makefile
new file mode 100644
index 0000000000..7e2d5ab466
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/Makefile
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# FreeScale MultiDMA Library
+#
+obj-y += MCD_dmaApi.o MCD_tasks.o MCD_tasksInit.o
+
+
diff --git a/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt b/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt
new file mode 100644
index 0000000000..bc10e713f9
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt
@@ -0,0 +1,27 @@
+
+Multi-channel DMA API Release Notes
+
+Version 0.3
+
+* MCD_INCLUDE_EU functionality supported(microcode changes for all tasks
+except ethernet).
+* Fixed bug when using MCD_END_FRAME which would cause the DMA to transfer
+zero bytes and then complete.
+* Code cleanup.
+
+
+Version 0.2 (Slight Update)
+
+* Modified casts and task table implementations that were causing
+warnings (and even errors on certain compilers)
+* Cosmetic changes to clean up MCD_dmaApi.c and MCD_dma.h
+* Fixed table declarations so that MCD_tasks.c will compile if
+ MCD_INCLUDE_EU is defined (Note: EU functionality still not supported)
+
+Version 0.1 (Initial release)
+
+Alpha version
+MCD_INCLUDE_EU functionality not supported.
+MCD_INCLUDE_JBIG not supported.
+
+
diff --git a/arch/m68k/mach-mcfv4e/mcf_clocksource.c b/arch/m68k/mach-mcfv4e/mcf_clocksource.c
new file mode 100644
index 0000000000..1278bf83ec
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcf_clocksource.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implements the clocksource for Coldfire V4E
+ */
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/arch/clocks.h>
+#include <asm/proc/processor.h> //FIXME - move to other file
+
+#ifdef CONFIG_USE_IRQ
+
+static uint32_t mcf_sltirq_hits; // FIXME: test code
+
+static int slt_timer_default_isr(void *not_used, void *t)
+{
+ struct mcf5xxx_slt *slt = MCF_SLT_Address(0);
+ if ( MCF_INTC_IPRH | MCF_INTC_IPRH_INT54 )
+ {
+ if (slt->SSR & MCF_SLT_SSR_ST)
+ {
+ slt->SSR = 0UL
+ | MCF_SLT_SSR_ST;
+ }
+ mcf_sltirq_hits++;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+
+static uint64_t mcf_clocksource_read(void)
+{
+ struct mcf5xxx_slt *slt = MCF_SLT_Address(0);
+ uint32_t sltcnt;
+ uint64_t rc = 0;
+
+ if (slt->SSR & MCF_SLT_SSR_ST)
+ {
+#ifndef CONFIG_USE_IRQ
+ slt->SSR = 0UL
+ | MCF_SLT_SSR_ST;
+#endif
+
+ rc = 0xffffffffULL + 1;
+ }
+
+ sltcnt = 0xffffffffUL - slt->SCNT;
+
+ rc += sltcnt;
+
+ return rc;
+}
+
+
+static struct clocksource cs = {
+ .read = mcf_clocksource_read,
+ .mask = 0xffffffff,
+ .mult = 1,
+ .shift = 0,
+};
+
+static int clocksource_init (void)
+{
+ struct mcf5xxx_slt *slt = MCF_SLT_Address(0);
+ uint32_t sltclk = mcfv4e_get_bus_clk() * 1000000;
+
+ /* Setup a slice timer terminal count */
+ slt->STCNT = 0xffffffff;
+
+ /* Reset status bits */
+ slt->SSR = 0UL
+ | MCF_SLT_SSR_ST
+ | MCF_SLT_SSR_BE;
+
+ /* Start timer to run continously */
+ slt->SCR = 0UL
+ | MCF_SLT_SCR_TEN
+ | MCF_SLT_SCR_RUN
+ | MCF_SLT_SCR_IEN; // FIXME - add irq handler
+
+ /* Setup up multiplier */
+ cs.mult = clocksource_hz2mult(sltclk, cs.shift);
+
+ /*
+ * Register the timer interrupt handler
+ */
+ init_clock(&cs);
+
+ return 0;
+}
+
+core_initcall(clocksource_init);
+
+#ifdef CONFIG_USE_IRQ
+
+static int clocksource_irq_init(void)
+{
+ if (!mcf_interrupts_register_handler(
+ 118, // FIXME!
+ (int (*)(void*,void*))slt_timer_default_isr,
+ NULL,
+ NULL)
+ )
+ {
+ return 1;
+ }
+ // Setup ICR
+ MCF_INTC_ICR54 = MCF_INTC_ICRn_IL(1) | MCF_INTC_ICRn_IP(0);
+ // Enable IRQ source
+ MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK54;
+ return 0;
+}
+
+postcore_initcall(clocksource_irq_init);
+
+#endif
diff --git a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
new file mode 100644
index 0000000000..5a3368f901
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implements a watchdog triggered reset for V4e Coldfire cores
+ */
+#include <common.h>
+#include <asm/arch/mcf54xx-regs.h>
+
+/**
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ */
+void reset_cpu (ulong ignored)
+{
+ while ( ignored ) { ; };
+
+ /* Disable watchdog and set Time-Out field to minimum timeout value */
+ MCF_GPT_GMS0 = 0;
+ MCF_GPT_GCIR0 = MCF_GPT_GCIR_PRE(1) | MCF_GPT_GCIR_CNT(0xffff);
+
+ /* Enable watchdog */
+ MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS_GPIO;
+
+ while (1);
+ /*NOTREACHED*/
+}
+EXPORT_SYMBOL(reset_cpu);
+
diff --git a/arch/m68k/mach-mcfv4e/multichannel_dma.c b/arch/m68k/mach-mcfv4e/multichannel_dma.c
new file mode 100644
index 0000000000..11aceeb9b9
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/multichannel_dma.c
@@ -0,0 +1,51 @@
+/*
+ * U-Boot Header File
+ *
+ * Generic Clocksource for V4E
+ *
+ * Copyright (c) 2007 Carsten Schlote <c.schlote\@konzeptpark.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 <init.h>
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/dma_utils.h>
+
+
+static int mcdapi_init(void)
+{
+ /*
+ * Initialize the Multi-channel DMA
+ */
+ MCD_initDma ((dmaRegs*)(__MBAR+0x8000),
+ (void *)CFG_SYS_SRAM_ADDRESS,
+ MCD_COMM_PREFETCH_EN | MCD_RELOC_TASKS);
+
+ /*
+ * Enable interrupts in DMA and INTC
+ */
+ dma_irq_enable(DMA_INTC_LVL, DMA_INTC_PRI);
+
+ return 0;
+}
+
+postcore_initcall(mcdapi_init);
+
diff --git a/arch/m68k/mach-mcfv4e/net/Makefile b/arch/m68k/mach-mcfv4e/net/Makefile
new file mode 100644
index 0000000000..45badfaaac
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/Makefile
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Support code for current FEC driver code - must be eliminated later...
+#
+obj-y += nbuf.o queue.o net.o
+
+
diff --git a/arch/m68k/mach-mcfv4e/net/nbuf.c b/arch/m68k/mach-mcfv4e/net/nbuf.c
new file mode 100644
index 0000000000..d7ae921bed
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/nbuf.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implementation of network buffer scheme.
+ * @todo Obsolete this file
+ */
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+
+#include <asm/proc/net/queue.h>
+#include <asm/proc/net/net.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+
+
+#define ASSERT(x)
+
+/**
+ * Queues used for network buffer storage
+ */
+QUEUE nbuf_queue[NBUF_MAXQ];
+
+/*
+ * Some devices require line-aligned buffers. In order to accomplish
+ * this, the nbuf data is over-allocated and adjusted. The following
+ * array keeps track of the original data pointer returned by malloc
+ */
+ADDRESS unaligned_buffers[NBUF_MAX];
+
+/**
+ * Initialize all the network buffer queues
+ *
+ * Return Value:
+ * 0 success
+ * 1 failure
+ */
+int
+nbuf_init(void)
+{
+ int i;
+ NBUF *nbuf;
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ /* Initialize all the queues */
+ queue_init(&nbuf_queue[i]);
+ }
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("Creating %d net buffers of %d bytes\n",NBUF_MAX,NBUF_SZ);
+ #endif
+
+ for (i=0; i<NBUF_MAX; ++i)
+ {
+ /* Allocate memory for the network buffer structure */
+ nbuf = (NBUF *)malloc(sizeof(NBUF));
+ if (!nbuf)
+ {
+ ASSERT(nbuf);
+ return 1;
+ }
+
+ /* Allocate memory for the actual data */
+ unaligned_buffers[i] = (ADDRESS)malloc(NBUF_SZ + 16);
+ nbuf->data = (uint8_t *)((uint32_t)(unaligned_buffers[i] + 15) & 0xFFFFFFF0);
+ if (!nbuf->data)
+ {
+ ASSERT(nbuf->data);
+ return 1;
+ }
+
+ /* Initialize the network buffer */
+ nbuf->offset = 0;
+ nbuf->length = 0;
+
+ /* Add the network buffer to the free list */
+ queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf);
+ }
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("NBUF allocation complete\n");
+ nbuf_debug_dump();
+ #endif
+
+ return 0;
+}
+/**
+ * Return all the allocated memory to the heap
+ */
+void
+nbuf_flush(void)
+{
+ NBUF *nbuf;
+ int i, level = asm_set_ipl(7);
+ int n = 0;
+
+ for (i=0; i<NBUF_MAX; ++i)
+ free((uint8_t*)unaligned_buffers[i]);
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ while ((nbuf = (NBUF *)queue_remove(&nbuf_queue[i])) != NULL)
+ {
+ free(nbuf);
+ ++n;
+ }
+ }
+ ASSERT(n == NBUF_MAX);
+ asm_set_ipl(level);
+}
+/**
+ * Allocate a network buffer from the free list
+ *
+ * Return Value:
+ * Pointer to a free network buffer
+ * NULL if none are available
+ */
+NBUF *
+nbuf_alloc(void)
+{
+ NBUF *nbuf;
+ int level = asm_set_ipl(7);
+
+ nbuf = (NBUF *)queue_remove(&nbuf_queue[NBUF_FREE]);
+ asm_set_ipl(level);
+ return nbuf;
+}
+/**
+ * Add the specified network buffer back to the free list
+ *
+ * Parameters:
+ * nbuf Buffer to add back to the free list
+ */
+void
+nbuf_free(NBUF *nbuf)
+{
+ int level = asm_set_ipl(7);
+
+ nbuf->offset = 0;
+ nbuf->length = NBUF_SZ;
+ queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf);
+
+ asm_set_ipl(level);
+}
+/**
+ * Remove a network buffer from the specified queue
+ *
+ * Parameters:
+ * q The index that identifies the queue to pull the buffer from
+ */
+NBUF *
+nbuf_remove(int q)
+{
+ NBUF *nbuf;
+ int level = asm_set_ipl(7);
+
+ nbuf = (NBUF *)queue_remove(&nbuf_queue[q]);
+ asm_set_ipl(level);
+ return nbuf;
+}
+/**
+ * Add a network buffer to the specified queue
+ *
+ * Parameters:
+ * q The index that identifies the queue to add the buffer to
+ */
+void
+nbuf_add(int q, NBUF *nbuf)
+{
+ int level = asm_set_ipl(7);
+ queue_add(&nbuf_queue[q],(QNODE *)nbuf);
+ asm_set_ipl(level);
+}
+/**
+ * Put all the network buffers back into the free list
+ */
+void
+nbuf_reset(void)
+{
+ NBUF *nbuf;
+ int i, level = asm_set_ipl(7);
+
+ for (i=1; i<NBUF_MAXQ; ++i)
+ {
+ while ((nbuf = nbuf_remove(i)) != NULL)
+ nbuf_free(nbuf);
+ }
+ asm_set_ipl(level);
+}
+/**
+ * Display all the nbuf queues
+ */
+void
+nbuf_debug_dump(void)
+{
+#ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ NBUF *nbuf;
+ int i, j, level;
+
+ level = asm_set_ipl(7);
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ printf("\n\nQueue #%d\n\n",i);
+ printf("\tBuffer Location\tOffset\tLength\n");
+ printf("--------------------------------------\n");
+ j = 0;
+ nbuf = (NBUF *)queue_peek(&nbuf_queue[i]);
+ while (nbuf != NULL)
+ {
+ printf("%d\t 0x%08x\t0x%04x\t0x%04x\n",j++,nbuf->data,
+ nbuf->offset,
+ nbuf->length);
+ nbuf = (NBUF *)nbuf->node.next;
+ }
+ }
+
+ asm_set_ipl(level);
+#endif
+}
diff --git a/arch/m68k/mach-mcfv4e/net/net.c b/arch/m68k/mach-mcfv4e/net/net.c
new file mode 100644
index 0000000000..76e28531b6
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/net.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Network initialization for MCF V4E FEC support code
+ * @todo Obsolete this file
+ */
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/net/net.h>
+#include <asm/proc/fecbd.h>
+#include <asm/proc/fec.h>
+#include <asm/proc/dma_utils.h>
+
+#include <asm/proc/processor.h> //FIXME - move to other file
+
+int netif_init(int channel)
+{
+ uint8_t* board_get_ethaddr(uint8_t*);
+
+#ifdef CONFIG_USE_IRQ
+ int vector;
+ int (*handler)(void *, void *);
+
+ disable_interrupts();
+
+ /*
+ * Register the FEC0 interrupt handler
+ */
+ handler = (channel == 0) ? fec0_interrupt_handler
+ : fec1_interrupt_handler;
+ vector = (channel == 0) ? 103 : 102;
+
+ if (!mcf_interrupts_register_handler(
+ vector,handler, NULL,(void *)0xdeadbeef))
+ {
+ printf("Error: Unable to register handler\n");
+ return 0;
+ }
+
+ /*
+ * Register the DMA interrupt handler
+ */
+ handler = dma_interrupt_handler;
+ vector = 112;
+
+ if (!mcf_interrupts_register_handler(
+ vector,handler, NULL,NULL))
+ {
+ printf("Error: Unable to register handler\n");
+ return 0;
+ }
+#endif
+ /*
+ * Enable interrupts
+ */
+ enable_interrupts();
+
+ return 1;
+}
+
+int netif_setup(int channel)
+{
+ uint8_t mac[6];
+ /*
+ * Get user programmed MAC address
+ */
+// board_get_ethaddr(mac);
+
+
+ /*
+ * Initialize the network interface structure
+ */
+// nif_init(&nif1);
+// nif1.mtu = ETH_MTU;
+// nif1.send = (DBUG_ETHERNET_PORT == 0) ? fec0_send : fec1_send;
+
+ /*
+ * Initialize the dBUG Ethernet port
+ */
+ fec_eth_setup(channel, /* Which FEC to use */
+ FEC_MODE_MII, /* Use MII mode */
+ FEC_MII_100BASE_TX, /* Allow 10 and 100Mbps */
+ FEC_MII_FULL_DUPLEX, /* Allow Full and Half Duplex */
+ mac);
+
+ /*
+ * Copy the Ethernet address to the NIF structure
+ */
+// memcpy(nif1.hwa, mac, 6);
+
+ #ifdef DEBUG
+ printf("Ethernet Address is %02X:%02X:%02X:%02X:%02X:%02X\n",\
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ #endif
+
+ return 1;
+}
+
+int netif_done(int channel)
+{
+ /*
+ * Download complete, clean up
+ */
+#ifdef CONFIG_USE_IRQ
+ int (*handler)(void *, void *);
+#endif
+ /*
+ * Disable interrupts
+ */
+ disable_interrupts();
+
+ /*
+ * Disable the Instruction Cache
+ */
+ mcf5xxx_wr_cacr(MCF5XXX_CACR_ICINVA);
+
+ /*
+ * Disable the dBUG Ethernet port
+ */
+ fec_eth_stop(channel);
+
+ /*
+ * Remove the interrupt handlers
+ */
+#ifdef CONFIG_USE_IRQ
+ handler = (channel == 0) ? fec0_interrupt_handler
+ : fec1_interrupt_handler;
+ mcf_interrupts_remove_handler(handler);
+ mcf_interrupts_remove_handler(dma_interrupt_handler);
+#endif
+ return 1;
+}
+
+
diff --git a/arch/m68k/mach-mcfv4e/net/queue.c b/arch/m68k/mach-mcfv4e/net/queue.c
new file mode 100644
index 0000000000..55f938af3e
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/queue.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implements a first in, first out linked list
+ *
+ * @note Simple selfcontaining basic code
+ * @todo Replace by u-boot standard list functions
+ */
+#include <linux/types.h>
+#include <asm/proc/net/queue.h>
+
+/** Initialize the specified queue to an empty state
+ *
+ * @param[in]
+ * q Pointer to queue structure
+ */
+void queue_init(QUEUE *q)
+{
+ q->head = NULL;
+}
+
+/**
+ * Check for an empty queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * 1 if Queue is empty
+ * 0 otherwise
+ */
+int
+queue_isempty(QUEUE *q)
+{
+ return (q->head == NULL);
+}
+
+/**
+ * Add an item to the end of the queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @param[in] node New node to add to the queue
+ */
+void queue_add(QUEUE *q, QNODE *node)
+{
+ if (queue_isempty(q))
+ {
+ q->head = q->tail = node;
+ }
+ else
+ {
+ q->tail->next = node;
+ q->tail = node;
+ }
+
+ node->next = NULL;
+}
+
+/** Remove and return first (oldest) entry from the specified queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * Node at head of queue - NULL if queue is empty
+ */
+QNODE*
+queue_remove(QUEUE *q)
+{
+ QNODE *oldest;
+
+ if (queue_isempty(q))
+ return NULL;
+
+ oldest = q->head;
+ q->head = oldest->next;
+ return oldest;
+}
+
+/** Peek into the queue and return pointer to first (oldest) entry.
+ *
+ * The queue is not modified
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * Node at head of queue - NULL if queue is empty
+ */
+QNODE*
+queue_peek(QUEUE *q)
+{
+ return q->head;
+}
+
+/** Move entire contents of one queue to the other
+ *
+ * @param[in] src Pointer to source queue
+ * @param[in] dst Pointer to destination queue
+ */
+void
+queue_move(QUEUE *dst, QUEUE *src)
+{
+ if (queue_isempty(src))
+ return;
+
+ if (queue_isempty(dst))
+ dst->head = src->head;
+ else
+ dst->tail->next = src->head;
+
+ dst->tail = src->tail;
+ src->head = NULL;
+ return;
+}
+