diff options
author | Ralf Corsepius <ralf.corsepius@rtems.org> | 2005-12-31 05:09:26 +0000 |
---|---|---|
committer | Ralf Corsepius <ralf.corsepius@rtems.org> | 2005-12-31 05:09:26 +0000 |
commit | ca680bc5890abe0d6bfe7eb4a40a0229f1b6bd36 (patch) | |
tree | 805a5ddce1250235d6133376ddabb5543eb2cf82 /c/src/lib/libbsp/powerpc | |
parent | Add BuildRoot. (diff) | |
download | rtems-ca680bc5890abe0d6bfe7eb4a40a0229f1b6bd36.tar.bz2 |
New (CVS import Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>'s
submission).
Diffstat (limited to 'c/src/lib/libbsp/powerpc')
82 files changed, 23211 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen5200/.cvsignore b/c/src/lib/libbsp/powerpc/gen5200/.cvsignore new file mode 100644 index 0000000000..849c802af6 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.cache +config.log +config.status +configure diff --git a/c/src/lib/libbsp/powerpc/gen5200/ChangeLog b/c/src/lib/libbsp/powerpc/gen5200/ChangeLog new file mode 100644 index 0000000000..8b5159e0f1 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/ChangeLog @@ -0,0 +1,40 @@ +2005-12-31 Ralf Corsepius <ralf.corsepius@rtems.org> + + * Makefile.am, README, bsp_specs, configure.ac, + bestcomm/bestcomm_api.c, bestcomm/bestcomm_api.h, + bestcomm/bestcomm_glue.c, bestcomm/bestcomm_glue.h, + bestcomm/bestcomm_priv.h, bestcomm/dma_image.c, + bestcomm/dma_image.capi.h, bestcomm/dma_image.h, + bestcomm/dma_image.reloc.c, bestcomm/load_task.c, + bestcomm/tasksetup_ata.c, bestcomm/tasksetup_bdtable.c, + bestcomm/tasksetup_crc16_dp_0.c, bestcomm/tasksetup_crc16_dp_1.c, + bestcomm/tasksetup_fec_rx_bd.c, bestcomm/tasksetup_fec_tx_bd.c, + bestcomm/tasksetup_gen_dp_0.c, bestcomm/tasksetup_gen_dp_1.c, + bestcomm/tasksetup_gen_dp_2.c, bestcomm/tasksetup_gen_dp_3.c, + bestcomm/tasksetup_gen_dp_bd_0.c, bestcomm/tasksetup_gen_dp_bd_1.c, + bestcomm/tasksetup_gen_rx_bd.c, bestcomm/tasksetup_gen_tx_bd.c, + bestcomm/tasksetup_lpc.c, bestcomm/tasksetup_pci_rx.c, + bestcomm/tasksetup_pci_tx.c, bestcomm/include/mgt5200/mgt5200.h, + bestcomm/include/mgt5200/sdma.h, + bestcomm/task_api/bestcomm_api_mem.h, + bestcomm/task_api/bestcomm_cntrl.h, + bestcomm/task_api/tasksetup_bdtable.h, + bestcomm/task_api/tasksetup_general.h, clock/clock.c, + console/console.c, i2c/i2c.c, i2c/i2cdrv.c, i2c/mpc5200mbus.c, + i2c/mpc5200mbus.h, ide/idecfg.c, ide/pcmcia_ide.c, ide/pcmcia_ide.h, + include/bsp.h, include/coverhd.h, include/i2c.h, include/i2cdrv.h, + include/mpc5200.h, include/raw_exception.h, include/tm27.h, + include/u-boot.h, irq/irq.c, irq/irq.h, irq/irq_asm.S, + irq/irq_init.c, mscan/mscan.c, mscan/mscan.h, + network_5200/network.c, nvram/m93cxx.h, nvram/nvram.c, + nvram/nvram.h, slicetimer/slicetimer.c, slicetimer/slicetimer.h, + start/start.S, startup/bspstart.c, startup/cpuinit.c, + startup/linkcmds, startup/linkcmds.pm520, tod/pcf8563.c, + tod/pcf8563.h, tod/todcfg.c, vectors/asm_utils.S, + vectors/raw_exception.c, vectors/vectors.S, vectors/vectors.h, + vectors/vectors_init.c: New (CVS import submission by + Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>) + +2005-12-09 Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> + + * Integrated gen5200 BSP to source tree diff --git a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am new file mode 100644 index 0000000000..d6ad3fdfce --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am @@ -0,0 +1,328 @@ +## +## $Id$ +## + +ACLOCAL_AMFLAGS = -I ../../../../aclocal + +include $(top_srcdir)/../../../../automake/compile.am +include $(top_srcdir)/../../bsp.am + +dist_project_lib_DATA = bsp_specs + +include_HEADERS = include/bsp.h include/i2cdrv.h include/u-boot.h \ + include/i2c.h include/mpc5200.h +include_HEADERS += include/tm27.h + +nodist_include_HEADERS = include/bspopts.h +DISTCLEANFILES = include/bspopts.h + +noinst_PROGRAMS = + +include_bspdir = $(includedir)/bsp + +include_HEADERS += include/coverhd.h + +nodist_include_HEADERS += ../../shared/tod.h + +EXTRA_DIST = start/start.S +start.$(OBJEXT): start/start.S + $(CPPASCOMPILE) -DASM -o $@ -c $< +project_lib_DATA = start.$(OBJEXT) + +dist_project_lib_DATA += startup/linkcmds startup/linkcmds.pm520 + +noinst_PROGRAMS += bestcomm.rel +bestcomm_rel_SOURCES = ./bestcomm/bestcomm_api.c\ + ./bestcomm/bestcomm_glue.c\ + ./bestcomm/dma_image.c\ + ./bestcomm/dma_image.reloc.c\ + ./bestcomm/load_task.c\ + ./bestcomm/tasksetup_ata.c\ + ./bestcomm/tasksetup_bdtable.c\ + ./bestcomm/tasksetup_crc16_dp_0.c\ + ./bestcomm/tasksetup_crc16_dp_1.c\ + ./bestcomm/tasksetup_fec_rx_bd.c\ + ./bestcomm/tasksetup_fec_tx_bd.c\ + ./bestcomm/tasksetup_gen_dp_0.c\ + ./bestcomm/tasksetup_gen_dp_1.c\ + ./bestcomm/tasksetup_gen_dp_2.c\ + ./bestcomm/tasksetup_gen_dp_3.c\ + ./bestcomm/tasksetup_gen_dp_bd_0.c\ + ./bestcomm/tasksetup_gen_dp_bd_1.c\ + ./bestcomm/tasksetup_gen_rx_bd.c\ + ./bestcomm/tasksetup_gen_tx_bd.c\ + ./bestcomm/tasksetup_lpc.c\ + ./bestcomm/tasksetup_pci_rx.c\ + ./bestcomm/tasksetup_pci_tx.c +bestcomm_rel_CPPFLAGS = $(AM_CPPFLAGS) +bestcomm_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += clock.rel +clock_rel_SOURCES = clock/clock.c +clock_rel_CPPFLAGS = $(AM_CPPFLAGS) +clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += console.rel +console_rel_SOURCES = console/console.c +console_rel_CPPFLAGS = $(AM_CPPFLAGS) +console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += i2c.rel +i2c_rel_SOURCES = ./i2c/i2c.c \ + ./i2c/i2cdrv.c \ + ./i2c/mpc5200mbus.c +i2c_rel_CPPFLAGS = $(AM_CPPFLAGS) +i2c_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += ide.rel +ide_rel_SOURCES = ./ide/idecfg.c ./ide/pcmcia_ide.c +ide_rel_CPPFLAGS = $(AM_CPPFLAGS) +ide_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_bsp_HEADERS = irq/irq.h include/i2cdrv.h include/mpc5200.h include/i2c.h include/u-boot.h + +noinst_PROGRAMS += irq.rel +irq_rel_SOURCES = irq/irq.c irq/irq_init.c irq/irq.h irq/irq_asm.S +irq_rel_CPPFLAGS = $(AM_CPPFLAGS) +irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + + +noinst_PROGRAMS += mscan.rel +mscan_rel_SOURCES = ./mscan/mscan.c +mscan_rel_CPPFLAGS = $(AM_CPPFLAGS) +mscan_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +include_bsp_HEADERS += mscan/mscan.h + +noinst_PROGRAMS += nvram.rel +nvram_rel_SOURCES = ./nvram/nvram.c +nvram_rel_CPPFLAGS = $(AM_CPPFLAGS) +nvram_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += slicetimer.rel +slicetimer_rel_SOURCES = ./slicetimer/slicetimer.c +slicetimer_rel_CPPFLAGS = $(AM_CPPFLAGS) +slicetimer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += tod.rel +tod_rel_SOURCES = ./tod/todcfg.c ./tod/pcf8563.c ../../shared/tod.c +tod_rel_CPPFLAGS = $(AM_CPPFLAGS) +tod_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_bsp_HEADERS += vectors/vectors.h + +noinst_PROGRAMS += startup.rel +startup_rel_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \ + ../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \ + ../../shared/main.c ../../shared/sbrk.c \ + ../../shared/gnatinstallhandler.c startup/cpuinit.c +startup_rel_CPPFLAGS = $(AM_CPPFLAGS) +startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += vectors.rel +vectors_rel_SOURCES = vectors/vectors_init.c vectors/vectors.h \ + vectors/vectors.S +vectors_rel_CPPFLAGS = $(AM_CPPFLAGS) +vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +if HAS_NETWORKING +network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ +network_CPPFLAGS += -D__BSD_VISIBLE +noinst_PROGRAMS += network.rel +network_rel_SOURCES = network_5200/network.c +network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS) +network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +endif + +noinst_LIBRARIES = libbsp.a +libbsp_a_SOURCES = +libbsp_a_LIBADD = bestcomm.rel clock.rel console.rel i2c.rel ide.rel irq.rel \ + mscan.rel nvram.rel slicetimer.rel tod.rel startup.rel \ + vectors.rel +if HAS_NETWORKING +libbsp_a_LIBADD += network.rel +endif +libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \ + ../../../libcpu/@RTEMS_CPU@/shared/cache.rel \ + ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \ + ../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \ + ../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel \ + ../../../libcpu/@RTEMS_CPU@/mpc6xx/exceptions.rel + +all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES) + +EXTRA_DIST += times + +PREINSTALL_DIRS = +PREINSTALL_FILES = +TMPINSTALL_FILES = + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(mkdir_p) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/$(dirstamp): $(PROJECT_INCLUDE)/$(dirstamp) + @$(mkdir_p) $(PROJECT_INCLUDE)/bsp + @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp): $(PROJECT_INCLUDE)/bsp/$(dirstamp) + @$(mkdir_p) $(PROJECT_INCLUDE)/bsp/bestcomm + @: > $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp): $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + @$(mkdir_p) $(PROJECT_INCLUDE)/bsp/bestcomm/include + @: > $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/$(dirstamp): $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) + @$(mkdir_p) $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200 + @: > $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp): $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + @$(mkdir_p) $(PROJECT_INCLUDE)/bsp/bestcomm/task_api + @: > $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) + +$(PROJECT_LIB)/$(dirstamp): + @$(mkdir_p) $(PROJECT_LIB) + @: > $(PROJECT_LIB)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp) + +$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs +PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs + +$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h + +$(PROJECT_INCLUDE)/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2c.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2c.h + +$(PROJECT_INCLUDE)/i2cdrv.h: include/i2cdrv.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2cdrv.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cdrv.h + +$(PROJECT_INCLUDE)/u-boot.h: include/u-boot.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/u-boot.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/u-boot.h + +$(PROJECT_INCLUDE)/mpc5200.h: include/mpc5200.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc5200.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc5200.h + +$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h + +$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h + +$(PROJECT_INCLUDE)/coverhd.h: include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h + +$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT) +TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT) + +$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds + +$(PROJECT_INCLUDE)/bsp/irq.h: irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h + +$(PROJECT_INCLUDE)/bsp/vectors.h: vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/ppctypes.h: bestcomm/include/ppctypes.h $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/include/ppctypes.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/ppctypes.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_api.h: bestcomm/bestcomm_api.h $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_api.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_api.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_glue.h: bestcomm/bestcomm_glue.h $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_glue.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_glue.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_priv.h: bestcomm/bestcomm_priv.h $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_priv.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/bestcomm_priv.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.capi.h: bestcomm/dma_image.capi.h $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.capi.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.capi.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.h: bestcomm/dma_image.h $(PROJECT_INCLUDE)/bsp/bestcomm/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/dma_image.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/mgt5200.h: bestcomm/include/mgt5200/mgt5200.h $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/mgt5200.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/mgt5200.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/sdma.h: bestcomm/include/mgt5200/sdma.h $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/sdma.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/include/mgt5200/sdma.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/include/ppctypes.h: bestcomm/include/ppctypes.h $(PROJECT_INCLUDE)/bsp/bestcomm/include/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/include/ppctypes.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/include/ppctypes.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_api_mem.h: bestcomm/task_api/bestcomm_api_mem.h $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_api_mem.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_api_mem.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_cntrl.h: bestcomm/task_api/bestcomm_cntrl.h $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_cntrl.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/bestcomm_cntrl.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_bdtable.h: bestcomm/task_api/tasksetup_bdtable.h $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_bdtable.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_bdtable.h + +$(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_general.h: bestcomm/task_api/tasksetup_general.h $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_general.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bestcomm/task_api/tasksetup_general.h + +$(PROJECT_INCLUDE)/bsp/pcmcia_ide.h: ide/pcmcia_ide.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pcmcia_ide.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pcmcia_ide.h + +$(PROJECT_INCLUDE)/bsp/mscan.h: mscan/mscan.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/mscan.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/mscan.h + +$(PROJECT_INCLUDE)/bsp/m93cxx.h: nvram/m93cxx.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/m93cxx.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/m93cxx.h + +$(PROJECT_INCLUDE)/bsp/nvram.h: nvram/nvram.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/nvram.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/nvram.h + +$(PROJECT_INCLUDE)/bsp/slicetimer.h: slicetimer/slicetimer.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/slicetimer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/slicetimer.h + +$(PROJECT_INCLUDE)/bsp/pcf8563.h: tod/pcf8563.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pcf8563.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pcf8563.h + + +CLEANFILES = $(PREINSTALL_FILES) +DISTCLEANFILES += $(PREINSTALL_DIRS) +CLEANFILES += $(TMPINSTALL_FILES) + +include $(top_srcdir)/../../../../automake/subdirs.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/gen5200/README b/c/src/lib/libbsp/powerpc/gen5200/README new file mode 100644 index 0000000000..f2faf4706d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/README @@ -0,0 +1,65 @@ +# +# README,v 1.1 2001/10/22 14:45:58 joel Exp +# + +BSP NAME: gen5200 +BOARD: various boards based on MPC5200 Controller: + MicroSys PM520 with Carrier board CR825 +BUS: N/A +CPU FAMILY: ppc +CPU: PowerPC MPC5200 +COPROCESSORS: Hardware FPU +MODE: 32 bit mode, I and D cache enabled +DEBUG MONITOR: None + +PERIPHERALS +=========== +TIMERS: GPT +SERIAL PORTS: 3 PSCs + 2 CAN IFs + 1 I2C IF +REAL-TIME CLOCK: PCF8563 +DMA: for Ethernet and CompactFlash +VIDEO: none +SCSI: none +IDE: 1 CompactFlash Slot supported +NETWORKING: 1 FEC Fast Ethernet + +DRIVER INFORMATION +================== +CLOCK DRIVER: using one GPT +IOSUPP DRIVER: none +SHMSUPP: none +TIMER DRIVER: Timebase register (lower 32 bits only) + +STDIO +===== +PORT: PSC1 +ELECTRICAL: RS-232 +BAUD: 9600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + +NOTES +===== +On-chip resources: + PSC1 /dev/console /dev/tty00 + PSC2 /dev/tty01 + PSC3 /dev/tty02 + + +Board description +----------------- + +Clock rate: external clock: 33MHz +Bus width: 32 bit Flash, 32 bit SDRAM +FLASH: 8MByte +RAM: 64MByte SDRAM + + +Debugging/ Code loading: +------------------------ + +Tested using the Lauterbach TRACE32 ICD debugger. + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.c new file mode 100644 index 0000000000..ad7471cdbb --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.c @@ -0,0 +1,512 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/*! + * \mainpage Introduction + * + * \author Motorola Semiconductor Products Sector + * \date 2 Apr 2004 + */ + +/*! + * \file bestcomm_api.c + * + * Bestcomm_api.c implements most of the BestComm C API. The + * TaskSetup() function is generated by the BestComm Task API tools + * in capi/task_api/tasksetup_general.h as configured and included by + * code_dma/image_rtos?/task_capi/(*).c. Other functions are defined as + * inline in capi/bestcomm_api.h. + */ + +#include "../bestcomm/include/ppctypes.h" +#include "../bestcomm/bestcomm_api.h" +#include "../bestcomm/task_api/bestcomm_cntrl.h" +#include "../bestcomm/task_api/bestcomm_api_mem.h" +#include "../bestcomm/task_api/tasksetup_bdtable.h" + +/*********************************************************************** + */ +static const char* const TaskVersionString = "BestComm API v2.2 20041209"; + +/* + * Hidden API data per task. + */ + +static BDIdx BDHead[MAX_TASKS]; +static BDIdx BDTail[MAX_TASKS]; + +/* + * Virtual memory location of the MBAR. System registers and SRAM are + * offset from this address. + */ +uint8 *MBarGlobal; + +/* + * Offset from MBarGlobal to get the physical memory address of the + * MBAR. This will be zero for systems that do not use virtual memory in + * their device driver model. + */ +sint64 MBarPhysOffsetGlobal; + +/* + * Offset to free space in SRAM after task code and buffer descriptors. + */ +uint32 SramOffsetGlobal = 0; + +/* + * This flag is false when TaskStart() has not yet been called on a + * task newly configured by TaskSetup() or TaskStop() has been called. + * Otherwise it is true. It is possible that a task disabled itself + * (transfer complete or BD ring empty) which will not show up in this + * flag. + * + * It is really only useful for BD tasks that assign buffers (via + * TaskBDAssign()) before TaskStart() or after TaskStop() are called. + */ +int TaskRunning[MAX_TASKS]; + +/*! + * \brief Get a string containing API version information. + * \returns Pointer to the API version string + */ +const char *TaskVersion(void) +{ + return TaskVersionString; +} + +/*! + * \brief Initialize the API. + * \param MBarRef Reference pointer to the device register memory + * map. + * + * \returns TASK_ERR_NO_ERR on successful initialization. + * or TASK_ERR_API_ALREADY_INITIALIZED. + * + * This function is only used with physical addresses. + * + * This function will also initialize API internal variables. The return + * value TASK_ERR_API_ALREADY_INITIALIZED is intended to help determine if + * another process has already instantiated a version of the API. + */ +int TasksInitAPI(uint8 *MBarRef) +{ + /* + * Copy pointer of register space to global variable. + * for use by other functions. + */ + MBarGlobal = MBarRef; + + /* + * The offset is 0 if physical and virtual are the same. + */ + MBarPhysOffsetGlobal = 0; + + /* + * IF API has not been initialized yet then... + * Make sure all BestComm interrupts are disabled and not pending. + * Make sure all tasks are disabled. + * This feature can only be put in after a way has been found to + * communicaticate with other processes. + */ + return TASK_ERR_NO_ERR; +} + +/*! + * \brief Initialize the API when virtual memory is used. + * \param MBarRef Reference pointer to the device register memory + * map. + * \param MBarPhys Actual physical location of MBAR device register + * memory map. + * + * \returns TASK_ERR_NO_ERR on successful initialization. + * or TASK_ERR_API_ALREADY_INITIALIZED. + * + * This function allows using virtual memory addresses as well as physical + * addresses. All device registers are offset to the address supplied here, + * so the virtual memory space should include enough space for the entire + * register set of the device to include the SRAM space. + * + * This function will also initialize API internal variables. The return + * value TASK_ERR_API_ALREADY_INITIALIZED is intended to help determine if + * another process has already instantiated a version of the API. + */ +int TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys) +{ + /* + * Copy pointer of register space to global variable. + * for use by other functions. + */ + MBarGlobal = MBarRef; + MBarPhysOffsetGlobal = MBarPhys - MBarRef; + + /* + * If API has not been initialized yet then... + * Make sure all BestComm interrupts are disabled and not pending. + * Make sure all tasks are disabled. + * This feature can only be put in after a way has been found to + * communicaticate with other processes. + */ + return TASK_ERR_NO_ERR; +} + +/*! + * \brief \em Deprecated + * \param sdma Base address of the BestComm register set + * + * \returns TASK_ERR_NO_ERR + * + * Use of this function is no longer necessary. It is retained for + * compatibility with previous versions of the API. + */ +int TasksAttachImage(sdma_regs *sdma) +{ + return TASK_ERR_NO_ERR; +} + +/*! + * \brief This function returns the value of the internal variable + * used to keep track of used space in SRAM. + * + * \returns The number of bytes from the beginning of SRAM to the end + * used space in the SRAM. + * + * This function will return the offset to free space in the SRAM + * not used by the CAPI. \b Note: The returned value is based + * on what is in TasksSetSramOffset. This function can + * not determine what SRAM space was used by another process. There must + * be some way external to the CAPI to keep track of SRAM space. This + * function only returns the internal variable used to keep track of buffer + * descriptors. + */ +uint32 TasksGetSramOffset(void) +{ + return SramOffsetGlobal; +} + +/*! + * \brief This function stores the number of bytes from the + * beginning of SRAM to the end of the used space. + * + * \param sram_offset Number of bytes until the beginning of + * free space in the SRAM. + * + * This function sets the free space offset in SRAM. It must be called + * before setup in multi-task environments. It is the application's + * job to determine where the free space in SRAM is. This sets the + * base offset for the buffer descriptor variables during setup, so to + * deallocate buffers that have already been set this function should be + * called with a new offset. + */ +void TasksSetSramOffset(uint32 sram_offset) +{ + /* + * Set the SramOffsetGlobal variable to be used by TaskSetup_BDTable + */ + SramOffsetGlobal = sram_offset; +} + +/*! + * \brief Start an initialized task running. + * \param taskId Task handle passed back from a successful TaskSetup() + * \param autoStartEnable Boolean for whether autostart bit is enabled. + * If this is set then the parameter autoStartTask + * defines the task to auto start. + * \param autoStartTask TaskId for task to autostart. If autoStartEnable + * is not set then this parameter is a don't care. + * \param intrEnable Boolean for interrupt enable for this task. + * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId + * is invalid. + */ +int TaskStart(TaskId taskId, uint32 autoStartEnable, TaskId autoStartTask, + uint32 intrEnable) +{ + if (intrEnable) { + SDMA_INT_ENABLE(SDMA_INT_MASK, taskId); + } else { + SDMA_INT_DISABLE(SDMA_INT_MASK, taskId); + } + SDMA_TASK_AUTO_START(SDMA_TCR, taskId, autoStartEnable, autoStartTask) + SDMA_TASK_ENABLE(SDMA_TCR, taskId); + + TaskRunning[taskId] = 1; + return TASK_ERR_NO_ERR; +} + +/*! + * \brief Stop a running task. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns TASK_ERR_NO_ERR on success or TASK_ERR_INVALID_ARG if taskId + * is invalid. + * + * \em Note: Stopping a polling buffer descriptor task is a catastrophic + * operation. It does not merely pause execution. Context is not + * saved. The task's pointer into the BD ring is reset back to the + * beginning. + * + * \em Note: This is not the case for the new "fall-through" BD tasks. + * They save the BD ring pointer across stop/start boundaries. The + * previous polling tasks are considered deprecated. + */ +int TaskStop(TaskId taskId) +{ + SDMA_INT_DISABLE(SDMA_INT_MASK, taskId); + SDMA_TASK_DISABLE(SDMA_TCR, taskId); + + TaskRunning[taskId] = 0; + return TASK_ERR_NO_ERR; +} + +/*! + * \brief Assign a buffer to a buffer descriptor. + * \param taskId Task handle passed back from a successful TaskSetup() + * \param buffer0 A buffer to send data from or receive data into a device + * \param buffer1 A second buffer to send data from or receive data into + * a device for use with double-buffer tasks. + * \param size Size of the buffer in bytes. + * \param bdFlags Buffer descriptor flags to set. Used by ethernet BD tasks. + * \returns Handle to the buffer descriptor used by this DMA transfer. + * Error is indicated by a negative return value (see TaskErr_t). + * + * This function is used for both transmit and receive buffer descriptor + * tasks. The buffer may be freed by the TaskBDRelease() function. + * In the case of tasks with a buffer descriptor with two buffer pointers + * this function uses both buffer0 and buffer1 where buffer0 is a source + * and buffer1 is a destination. When the buffer descriptor is a single + * pointer type, the buffer0 is the only pointer used and buffer1 is ignored. + * + * Using this function on non-buffer descriptor tasks will produce + * unpredictable results. + */ +BDIdx TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1, int size, uint32 bdFlags) +{ + BDIdx *bdHead; + TaskBD_t *bd; + BDIdx r = TASK_ERR_NO_ERR; + + if (TaskBDIdxTable[taskId].currBDInUse == TaskBDIdxTable[taskId].numBD) { + /* + * The buffer ring is full. + */ + r = TASK_ERR_BD_RING_FULL; + + } else if ( (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) + && ((uint32)size & (uint32)(~SDMA_DRD_MASK_LENGTH))) { + r = TASK_ERR_SIZE_TOO_LARGE; + + } else if ( !(TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) + && ((uint32)size & (uint32)(0xffffffff<<SDMA_BD_BIT_READY))) { + r = TASK_ERR_SIZE_TOO_LARGE; + + } else { + bdHead = &BDHead[taskId]; + + /* + * Increase Buffer Descriptor in-use variable. + */ + ++TaskBDIdxTable[taskId].currBDInUse; + + /* + * Get a generic TaskBD_t pointer to the BD to be assigned. + * Assign the buffer pointers. + */ + bd = TaskBDIdxTable[taskId].BDTablePtr; + if (TaskBDIdxTable[taskId].numPtr == 1) { + bd = (TaskBD_t *)&(((TaskBD1_t *)bd)[*bdHead]); + + ((TaskBD1_t *)bd)->DataPtr[0] = (uint32)buffer0; + } else { + bd = (TaskBD_t *)&(((TaskBD2_t *)bd)[*bdHead]); + + ((TaskBD2_t *)bd)->DataPtr[0] = (uint32)buffer0; + ((TaskBD2_t *)bd)->DataPtr[1] = (uint32)buffer1; + } + + + if (bd->Status & SDMA_BD_MASK_READY) { + /* + * This BD is in use. + */ + r = TASK_ERR_BD_BUSY; + + } else { + + /* + * Set status bits and length. As soon as Status is written, the + * BestComm may perform the transfer. + */ + if (TaskBDIdxTable[taskId].apiConfig & API_CONFIG_BD_FLAG) { + bd->Status = ( ((uint32)SDMA_DRD_MASK_FLAGS & bdFlags) + | ((uint32)SDMA_DRD_MASK_LENGTH & (uint32)size) + | ((uint32)SDMA_BD_MASK_READY)); + } else { + bd->Status = ( ((uint32)SDMA_BD_MASK_SIGN & (uint32)size) + | ((uint32)SDMA_BD_MASK_READY)); + } + + /* + * Return the current BD index and increment. + */ + r = *bdHead; + *bdHead = (BDIdx)((*bdHead + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD); + } + } + + /* + * Reenable a fall-through BD tasks that might have exited. + */ + if (TaskRunning[taskId]) { + SDMA_TASK_ENABLE(SDMA_TCR, taskId); + } + return r; +} + +/*! + * \brief Release last buffer in the buffer descriptor ring. + * \param taskId Task handle passed back from a successful TaskSetup() + * + * \returns Buffer descriptor index of next buffer index that will be released + * by another call of this function. + * TASK_ERR_BD_RING_EMPTY is returned if the ring is already empty. + * + * This function allows the system to reallocate the memory used by + * the buffer. It also cleans up the structure in the BD ring by + * removing the tail buffer in the ring. The buffer descriptor tasks + * are designed around this. Non-BD tasks do not use this function. + * + * Using this function on non-buffer descriptor tasks will produce + * unpredictable results. + */ +BDIdx TaskBDRelease(TaskId taskId) +{ + BDIdx *bdTail; + TaskBD_t *bd; + + bdTail = &BDTail[taskId]; + + if (TaskBDIdxTable[taskId].currBDInUse == 0) { + /* + * Buffer Descriptor ring is empty, Can't Release! + */ + return TASK_ERR_BD_RING_EMPTY; + } + + /* + * Get a generic TaskBD_t pointer to the next BD to be released. + */ + bd = TaskGetBD(taskId, *bdTail); + + /* + * Verify the ready bit is clear. + */ + if (bd->Status & SDMA_BD_MASK_READY) { + return TASK_ERR_BD_BUSY; + } + + /* + * Increment the tail pointer around the ring, decrement in-use. + */ + *bdTail = (BDIdx)((*bdTail + 1) % (BDIdx)TaskBDIdxTable[taskId].numBD); + --TaskBDIdxTable[taskId].currBDInUse; + + return *bdTail; +} + + +/*! + * \brief Release all buffers. + * \param taskId Task handle passed back from a successful TaskSetup() + * + * \returns Buffer descriptor index of next buffer that will be + * assigned by TaskBDAssign() which will also be the first + * released by the next call to TaskBDRelease() or + * TASK_ERR_TASK_RUNNING if the task has not been stopped. + * + * This function is similar to TaskBDRelease() except that it releases + * all assigned buffers including those not yet processed by the BestComm + * task; i.e. SDMA_BD_MASK_READY is set. + * Non-BD tasks do not use this + * function. + * + * The task should not be running. Call TaskStop() first. + * + * \em Note: Partially transmitted buffers are up to the user to handle. + * + * Using this function on non-buffer descriptor tasks will produce + * unpredictable results. + */ +BDIdx TaskBDReset(TaskId taskId) +{ + BDIdx i; + TaskBD_t *bd, *bdTab; + + if (TaskRunning[taskId]) { + return TASK_ERR_TASK_RUNNING; + } + + bdTab = TaskBDIdxTable[taskId].BDTablePtr; + + for (i = (BDIdx)TaskBDIdxTable[taskId].numBD - 1; i >= 0; --i) { + + if (TaskBDIdxTable[taskId].numPtr == 1) { + bd = (TaskBD_t *)&(((TaskBD1_t *)bdTab)[i]); + } else { + bd = (TaskBD_t *)&(((TaskBD2_t *)bdTab)[i]); + } + + bd->Status = 0x0; + } + + TaskBDIdxTable[taskId].currBDInUse = 0; + *TaskBDIdxTable[taskId].BDStartPtr = + (volatile uint32)((volatile uint32)TaskBDIdxTable[taskId].BDTablePtr + + MBarPhysOffsetGlobal); + return BDHead[taskId] = BDTail[taskId] = 0; +} + + +/*! + * \brief Return BestComm debug information. + * \param taskId Task handle passed back from a successful TaskSetup() + * \param paramSet TBD + * \returns TBD + * + * The implementation of this function is yet to be determined. + */ +int TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet) +{ + if ((taskId < 0) || (taskId >= MAX_TASKS)) { + return TASK_ERR_INVALID_ARG; + } + if (paramSet == NULL) { + return TASK_ERR_INVALID_ARG; + } + + return TASK_ERR_NO_ERR; +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.h new file mode 100644 index 0000000000..3aacf14f8f --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_api.h @@ -0,0 +1,457 @@ +#ifndef __BESTCOMM_API_H +#define __BESTCOMM_API_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/*! + * \file bestcomm_api.h + * + * Bestcomm_api.h is the only header necessary for inclusion by user + * code. The include path the C compiler searches to find .h files + * should contain bestcomm/capi and one of bestcomm/code_dma/image_*. + * This second entry selects which set of BestComm tasks will be used. + * Of course the appropriate files in image_* must also be compiled and + * linked. + */ + +#include "../bestcomm/include/ppctypes.h" +#include "../bestcomm/include/mgt5200/sdma.h" +#include "../bestcomm/task_api/tasksetup_bdtable.h" +#include "../bestcomm/task_api/bestcomm_cntrl.h" +#include "../bestcomm/task_api/bestcomm_api_mem.h" + +/*! + * \brief TaskSetup() debugging + * + * Define this macro as follows for debugging printf()s to see + * what the API receives and sets from the TaskSetupParamSet_t + * struct. Implemented in capi/task_api/tasksetup_general.h. + * + * \verbatim + * >0 : print basic debug messages + * >=10: also print C-API interface variables + * >=20: also print task API interface variables + * else: do nothing + * \endverbatim + */ +#define DEBUG_BESTCOMM_API 0 + +/*! + * \brief Maximum number of tasks in the system. + * This number is hardware-dependent and not user configuration. + */ +#define MAX_TASKS 16 + +/* + * This may need to be removed in certain implementations. + */ +#ifndef NULL +# define NULL ((void *)0) +#endif /* NULL */ + +typedef sint8 TaskId; +typedef sint32 BDIdx; + +/* + * Special "task IDs" for interrupt handling API functions + */ +/*! \brief Debug interrupt "task ID" */ +#define DEBUG_INTR_ID SDMA_INT_BIT_DBG + +/*! \brief TEA interrupt "task ID" */ +#define TEA_INTR_ID SDMA_INT_BIT_TEA + +/*! \brief Task start autostart enable */ +#define TASK_AUTOSTART_ENABLE 1 + +/*! \brief Task start autostart disable */ +#define TASK_AUTOSTART_DISABLE 0 + +/*! \brief Task start interrupt enable */ +#define TASK_INTERRUPT_ENABLE 1 + +/*! \brief Task start interrupt disable */ +#define TASK_INTERRUPT_DISABLE 0 + +/* + * Buffer descriptor flags to pass to TaskBDAssign(). + */ +/*! \brief Transmit frame done */ +#define TASK_BD_TFD (1 << SDMA_DRD_BIT_TFD) + +/*! \brief Interrupt on frame done */ +#define TASK_BD_INT (1 << SDMA_DRD_BIT_INT) + +/*! + * \brief Data transfer size + */ +typedef enum { + SZ_FLEX = 3, /*!< invalid for TaskSetupParamSet_t */ + SZ_UINT8 = 1, /*!< 1-byte */ + SZ_UINT16 = 2, /*!< 2-byte */ + SZ_UINT32 = 4 /*!< 4-byte */ +} Sz_t; + +/*! + * \brief API error codes + */ +typedef enum { + TASK_ERR_NO_ERR = -1, /*!< No error */ + TASK_ERR_NO_INTR = TASK_ERR_NO_ERR, + /*!< No interrupt */ + TASK_ERR_INVALID_ARG = -2, /*!< Invalid function argument */ + TASK_ERR_BD_RING_FULL = -3, /*!< Buffer descriptor ring full*/ + TASK_ERR_API_ALREADY_INITIALIZED + = -4, /*!< API has already been initialized */ + TASK_ERR_SIZE_TOO_LARGE = -5, /*!< Buffer descriptor cannot support size parameter */ + TASK_ERR_BD_RING_EMPTY = -6, /*!< Buffer descriptor ring is empty*/ + TASK_ERR_BD_BUSY = -7, /*!< The buffer descriptor is in use + by the BestComm */ + TASK_ERR_TASK_RUNNING = -8 /*!< The task is running. */ + +} TaskErr_t; + +/*! + * \brief BestComm initiators + * + * These are assigned by TaskSetup(). + */ +typedef enum { + + INITIATOR_ALWAYS = 0, + INITIATOR_SCTMR_0 = 1, + INITIATOR_SCTMR_1 = 2, + INITIATOR_FEC_RX = 3, + INITIATOR_FEC_TX = 4, + INITIATOR_ATA_RX = 5, + INITIATOR_ATA_TX = 6, + INITIATOR_SCPCI_RX = 7, + INITIATOR_SCPCI_TX = 8, + INITIATOR_PSC3_RX = 9, + INITIATOR_PSC3_TX = 10, + INITIATOR_PSC2_RX = 11, + INITIATOR_PSC2_TX = 12, + INITIATOR_PSC1_RX = 13, + INITIATOR_PSC1_TX = 14, + INITIATOR_SCTMR_2 = 15, + + INITIATOR_SCLPC = 16, + INITIATOR_PSC5_RX = 17, + INITIATOR_PSC5_TX = 18, + INITIATOR_PSC4_RX = 19, + INITIATOR_PSC4_TX = 20, + INITIATOR_I2C2_RX = 21, + INITIATOR_I2C2_TX = 22, + INITIATOR_I2C1_RX = 23, + INITIATOR_I2C1_TX = 24, + INITIATOR_PSC6_RX = 25, + INITIATOR_PSC6_TX = 26, + INITIATOR_IRDA_RX = 25, + INITIATOR_IRDA_TX = 26, + INITIATOR_SCTMR_3 = 27, + INITIATOR_SCTMR_4 = 28, + INITIATOR_SCTMR_5 = 29, + INITIATOR_SCTMR_6 = 30, + INITIATOR_SCTMR_7 = 31 + +} MPC5200Initiator_t; + +/*! + * \brief Parameters for TaskSetup() + * + * All parameters can be hard-coded by the task API. Hard-coded values + * will be changed in the struct passed to TaskSetup() for the user to + * examine later. + */ +typedef struct { + uint32 NumBD; /*!< Number of buffer descriptors */ + + union { + uint32 MaxBuf; /*!< Maximum buffer size */ + uint32 NumBytes; /*!< Number of bytes to transfer */ + } Size; /*!< Buffer size union for BD and non-BD tasks */ + + MPC5200Initiator_t + Initiator; /*!< BestComm initiator (ignored if hard-wired) */ + uint32 StartAddrSrc; /*!< Address of the DMA source (e.g. a FIFO) */ + sint16 IncrSrc; /*!< Amount to increment source pointer */ + Sz_t SzSrc; /*!< Size of source data access */ + uint32 StartAddrDst; /*!< Address of the DMA destination (e.g. a FIFO) */ + sint16 IncrDst; /*!< Amount to increment data pointer */ + Sz_t SzDst; /*!< Size of destination data access */ +} TaskSetupParamSet_t; + +/*! + * \brief Parameters for TaskDebug() + * + * TaskDebug() and the contents of this data structure are yet to be + * determined. + */ +typedef struct { + int dummy; /* Some compilers don't like empty struct typedefs */ +} TaskDebugParamSet_t; + +/*! + * \brief Generic buffer descriptor. + * + * It is generally used as a pointer which should be cast to one of the + * other BD types based on the number of buffers per descriptor. + */ +typedef struct { + uint32 Status; /*!< Status and length bits */ +} TaskBD_t; + +/*! + * \brief Single buffer descriptor. + */ +typedef struct { + uint32 Status; /*!< Status and length bits */ + uint32 DataPtr[1]; /*!< Pointer to data buffer */ +} TaskBD1_t; + +/*! + * \brief Dual buffer descriptor. + */ +typedef struct { + uint32 Status; /*!< Status and length bits */ + uint32 DataPtr[2]; /*!< Pointer to data buffers */ +} TaskBD2_t; + + + +/*************************** + * Start of API Prototypes + ***************************/ + +#include "../bestcomm/bestcomm_priv.h" +#include "../bestcomm/dma_image.capi.h" + +/*! + * \brief Initialize a single task. + * \param TaskName Type of task to initialize. E.g. PCI transmit, + * ethernet receive, general purpose dual-pointer. + * Values expected can be found in the TaskName_t + * enum defined in dma_image.capi.h. + * \param TaskSetupParams Task-specific parameters. The user must fill out + * the pertinent parts of a TaskSetupParamSet_t + * data structure. + * \returns TaskId task identification token which is a required + * parameter for most other API functions. + * + * This function returns a task identification token which is a required + * parameter for most other API functions. + * + * Certain values of the structure pointed to by TaskParams are set + * as a side-effect based on task type. These may be examined after + * a successful call to TaskSetup(). User-specified values may be + * overridden. + * + * TaskId TaskSetup( TaskName_t TaskName, + * TaskSetupParamSet_t *TaskSetupParams ); + */ +#define TaskSetup(TaskName, TaskSetupParams) \ + TaskSetup_ ## TaskName (TaskName ## _api, TaskSetupParams) + +const char *TaskVersion(void); + +int TasksInitAPI(uint8 *MBarRef); + +int TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys); + +void TasksLoadImage(sdma_regs *sdma); +int TasksAttachImage(sdma_regs *sdma); + +uint32 TasksGetSramOffset(void); +void TasksSetSramOffset(uint32 sram_offset); + +int TaskStart(TaskId taskId, uint32 autoStartEnable, + TaskId autoStartTask, uint32 intrEnable); +int TaskStop(TaskId taskId); +static int TaskStatus(TaskId taskId); +BDIdx TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1, + int size, uint32 bdFlags); +BDIdx TaskBDRelease(TaskId taskId); +BDIdx TaskBDReset(TaskId taskId); +static TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd); +static TaskBD_t *TaskGetBDRing(TaskId taskId); +int TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet); +static int TaskIntClear(TaskId taskId); +static TaskId TaskIntStatus(TaskId taskId); +static int TaskIntPending(TaskId taskId); +static TaskId TaskIntSource(void); +static uint16 TaskBDInUse(TaskId taskId); + + +/*! + * \brief Get the enable/disable status of a task. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns Boolean true indicates enabled or false indicates disabled + * or invalid taskId. + */ +static inline int TaskStatus(TaskId taskId) +{ + return SDMA_TASK_STATUS(SDMA_TCR, taskId) & 0x8000; +} + +/*! + * \brief Return a pointer to a buffer descriptor at index BDIdx + * \param taskId Task handle passed back from a successful TaskSetup() + * \param bd Buffer descriptor handle returned by + * TaskBDAssign() or TaskBDRelease(). + * \returns Pointer to the requested buffer descriptor or NULL on error. + * + * The returned pointer should be cast to the appropriate buffer + * descriptor type, TaskBD1_t or TaskBD2_t. + */ +static inline TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd) +{ + TaskBD_t *bdTab; + + bdTab = TaskBDIdxTable[taskId].BDTablePtr; + if (TaskBDIdxTable[taskId].numPtr == 1) { + return (TaskBD_t *)&(((TaskBD1_t *)bdTab)[bd]); + } else { + return (TaskBD_t *)&(((TaskBD2_t *)bdTab)[bd]); + } +} + +/*! + * \brief Return a pointer to the first buffer descriptor in the ring. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns Pointer to the array of buffer descriptors making up the + * ring or NULL on error. + * + * A device driver author may choose to use this in lieu of + * TaskBDAssign()/TaskBDRelease() to get direct access to the + * BD ring with the warning that the underlying data structure may change. + * Use at one's own discretion. + */ +static inline TaskBD_t *TaskGetBDRing(TaskId taskId) +{ + return TaskBDIdxTable[taskId].BDTablePtr; +} + +/*! + * \brief Clear the interrupt for a given BestComm task. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns TASK_ERR_NO_ERR (which is not really an error) for success + */ +static inline int TaskIntClear(TaskId taskId) +{ + SDMA_CLEAR_IEVENT(SDMA_INT_PEND, taskId); + return TASK_ERR_NO_ERR; /* success */ +} + +/*! + * \brief Get the interrupt status for a given task. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt + * pending, taskId for a regular interrupt, DEBUG_INTR_ID for + * a debug interrupt and TEA_INTR_ID for a TEA interrupt. + * \b Note: TaskIntStatus() may return 0, but this means that that + * taskId 0 is interrupt pending. + */ +static inline TaskId TaskIntStatus(TaskId taskId) +{ + uint32 pending; + + pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); + + if (SDMA_INT_TEST(pending, taskId)) { + return taskId; + } else if (SDMA_INT_TEST(pending, DEBUG_INTR_ID)) { + return DEBUG_INTR_ID; + } else if (SDMA_INT_TEST(pending, TEA_INTR_ID)) { + return TEA_INTR_ID; + } + + return TASK_ERR_NO_INTR; +} + +/*! + * \brief Get the interrupt pending status for a given task. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns 0 if task does not have a pending interrupt. 1 if the task + * has an interrupt pending. + */ +static inline int TaskIntPending(TaskId taskId) +{ + uint32 pending; + + pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); + if (SDMA_INT_TEST(pending, taskId)) { + return 1; + } else { + return 0; + } +} + +/*! + * \brief Returns the task ID of an interrupting BestComm task. + * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt + * pending or the taskId of the interrupting task. + * + * The user must query TaskIntStatus() to discover if this is a debug + * or TEA interrupt. This function is designed for use by an operating + * system interrupt handler. + */ +static inline TaskId TaskIntSource(void) +{ + uint32 pending; + uint32 mask = 1 << (MAX_TASKS - 1); + TaskId i; + + pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); + + if (SDMA_INT_TEST(pending, SDMA_INT_BIT_TEA)) { + return (TaskId)SDMA_TEA_SOURCE(SDMA_INT_PEND); + } + + for (i = (MAX_TASKS - 1); i >= 0; --i, mask >>= 1) { + if (pending & mask) { + return i; + } + } + + return TASK_ERR_NO_INTR; +} + +/*! + * \brief Get a count of in-use buffer descriptors. + * \param taskId Task handle passed back from a successful TaskSetup() + * \returns Count of the current number of BDs in use by the given task. + */ +static inline uint16 TaskBDInUse(TaskId taskId) +{ + return TaskBDIdxTable[taskId].currBDInUse; +} + +#endif /* __BESTCOMM_API_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c new file mode 100644 index 0000000000..05205e7b13 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c @@ -0,0 +1,279 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: bestcomm_glue.c ++-----------------------------------------------------------------+ +| Copyright (c) 2004-2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains glue functions to the Freescale BestComm API | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.10 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.9 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.8 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +#include <rtems.h> +#include <rtems/error.h> +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include "../bestcomm/include/ppctypes.h" /* uint32, et. al. */ +#include "../bestcomm/dma_image.h" +#include "../bestcomm/task_api/bestcomm_cntrl.h" +#include "../bestcomm/bestcomm_api.h" +#include "../bestcomm/bestcomm_glue.h" +#include "../bestcomm/include/mgt5200/sdma.h" + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_enable +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| enable interrupt for given task number | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno /* task number to enable */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ +{ + if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) { + /* + * valid task number + * enable interrupt in bestcomm mask + */ + SDMA_INT_ENABLE(&mpc5200.IntMask,bestcomm_taskno); + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_disable +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| disable interrupt for given task number | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno /* task number to disable */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ +{ + if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) { + /* + * valid task number + * disable interrupt in bestcomm mask + */ + SDMA_INT_DISABLE(&mpc5200.IntMask,bestcomm_taskno); + } +} + +typedef struct { + void (*the_handler)(rtems_irq_hdl_param); + rtems_irq_hdl_param the_param; +} bestcomm_glue_irq_handlers_t; + +bestcomm_glue_irq_handlers_t bestcomm_glue_irq_handlers[32]; + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_install +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| install given function as bestcomm interrupt handler | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno, /* task number for handler */ + void (*the_handler)(rtems_irq_hdl_param), /* function to call */ + rtems_irq_hdl_param the_param +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ +{ + if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) { + /* + * valid task number + * install handler + */ + bestcomm_glue_irq_handlers[bestcomm_taskno].the_handler = the_handler; + bestcomm_glue_irq_handlers[bestcomm_taskno].the_param = the_param; + } +} + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_dispatcher +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| general bestcomm interrupt handler/dispatcher | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + rtems_irq_hdl_param handle /* irq specific handle (not used) */ + +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ +{ + uint32_t pending; + int curr_taskno; + + pending = mpc5200.IntPend & ~mpc5200.IntMask; + curr_taskno = 0; + while (pending != 0) { + if ((pending & (1UL<<curr_taskno)) != 0) { + if (bestcomm_glue_irq_handlers[curr_taskno].the_handler == NULL) { + /* + * This should never happen. we have a pending IRQ but no handler + * let's clear this pending bit + */ + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,curr_taskno); + } + else { + /* + * call proper handler + */ + bestcomm_glue_irq_handlers[curr_taskno].the_handler + (bestcomm_glue_irq_handlers[curr_taskno].the_param); + } + /* + * clear this bit in our pending copy + * and go to next bit + */ + pending &= ~(1<<curr_taskno); + } + curr_taskno++; + } +} + +void bestcomm_glue_on(const rtems_irq_connect_data* ptr) + { + } + + +void bestcomm_glue_isOn(const rtems_irq_connect_data* ptr) + { + /*return BSP_irq_enabled_at_cpm(ptr->name);*/ + } + + +void bestcomm_glue_off(const rtems_irq_connect_data* ptr) + { + } + +static rtems_irq_connect_data bestcomm_glue_irq_data = + { + + BSP_SIU_IRQ_SMARTCOMM, + (rtems_irq_hdl) bestcomm_glue_irq_dispatcher, + (rtems_irq_hdl_param) NULL, + (rtems_irq_enable) bestcomm_glue_on, + (rtems_irq_disable) bestcomm_glue_off, + (rtems_irq_is_enabled) bestcomm_glue_isOn + }; + +static boolean bestcomm_glue_is_initialized = FALSE; +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_init +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| initialize the bestcomm module (if not yet done): | +| - load code | +| - initialize registers | +| - initialize bus arbiter | +| - initialize interrupt control | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + void /* none */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ +{ + if (!bestcomm_glue_is_initialized) { + bestcomm_glue_is_initialized = TRUE; + /* + * Set task bar to begin of sram + */ + mpc5200.taskBar = (uint32_t)(&(mpc5200.sram[0])); + +#if 0 + /* + * Set core and BestComm XLB priority the same. + */ + mpc5200.priority_enable |= 0x5; + mpc5200.priority = 0x77777171; +#endif + + /* + * Turn off COMM bus prefetch. This affects all data movements on + * the COMM bus. (Yes, _PE -- prefetch enable -- should probably be + * named _PD.) + */ + mpc5200.PtdCntrl |= SDMA_PTDCNTRL_PE; + + TasksInitAPI((uint8*)&mpc5200); + + TasksLoadImage( (void *)&(mpc5200.taskBar)); + + /* + * FIXME: initialize interrupt dispatcher + */ + if(!BSP_install_rtems_irq_handler (&bestcomm_glue_irq_data)) { + rtems_panic ("Can't attach MPC5x00 BestComm interrupt handler\n"); + } + + } +} + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.h new file mode 100644 index 0000000000..1bd68cf143 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.h @@ -0,0 +1,122 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: bestcomm_glue.h ++-----------------------------------------------------------------+ +| Copyright (c) 2004-2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file declares glue functions to the Freescale BestComm API | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.3 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +#ifndef _BESTCOMM_GLUE_H +#define _BESTCOMM_GLUE_H + +#include <rtems.h> + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_enable +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| enable interrupt for given task number | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno /* task number to enable */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_disable +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| disable interrupt for given task number | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno /* task number to disable */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_irq_install +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| install given function as bestcomm interrupt handler | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + int bestcomm_taskno, /* task number for handler */ + void (*the_handler)(rtems_irq_hdl_param), /* function to call */ + rtems_irq_hdl_param the_param + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void bestcomm_glue_init +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| initialize the bestcomm module (if not yet done): | +| - load code | +| - initialize registers | +| - initialize bus arbiter | +| - initialize interrupt control | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + void /* none */ + ); +/*-------------------------------------------------------------------------*\ +| Return Value: | +| none | +\*=========================================================================*/ + +#endif /* _BESTCOMM_GLUE_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_priv.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_priv.h new file mode 100644 index 0000000000..f26ffdfa26 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_priv.h @@ -0,0 +1,45 @@ +#ifndef __BESTCOMM_PRIV_H +#define __BESTCOMM_PRIV_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/* + * Global variables necessitated by the TaskSetup_*() location in + * separate files from the main code and the inline functions. These are + * private data structures that should not be manipulated by API users. + */ + +extern uint32 SramOffsetGlobal; +extern TaskBDIdxTable_t TaskBDIdxTable[MAX_TASKS]; +extern int TaskRunning[MAX_TASKS]; +extern sint64 MBarPhysOffsetGlobal; + +#endif /* __BESTCOMM_PRIV_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.c new file mode 100644 index 0000000000..7c1f55b3d6 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.c @@ -0,0 +1,624 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +******************************************************************************/ + +#include "../bestcomm/dma_image.h" + +TASK_PCI_TX_api_t TASK_PCI_TX_storage; +TASK_PCI_TX_api_t *TASK_PCI_TX_api=&TASK_PCI_TX_storage; + +TASK_PCI_RX_api_t TASK_PCI_RX_storage; +TASK_PCI_RX_api_t *TASK_PCI_RX_api=&TASK_PCI_RX_storage; + +TASK_FEC_TX_api_t TASK_FEC_TX_storage; +TASK_FEC_TX_api_t *TASK_FEC_TX_api=&TASK_FEC_TX_storage; + +TASK_FEC_RX_api_t TASK_FEC_RX_storage; +TASK_FEC_RX_api_t *TASK_FEC_RX_api=&TASK_FEC_RX_storage; + +TASK_LPC_api_t TASK_LPC_storage; +TASK_LPC_api_t *TASK_LPC_api=&TASK_LPC_storage; + +TASK_ATA_api_t TASK_ATA_storage; +TASK_ATA_api_t *TASK_ATA_api=&TASK_ATA_storage; + +TASK_CRC16_DP_0_api_t TASK_CRC16_DP_0_storage; +TASK_CRC16_DP_0_api_t *TASK_CRC16_DP_0_api=&TASK_CRC16_DP_0_storage; + +TASK_CRC16_DP_1_api_t TASK_CRC16_DP_1_storage; +TASK_CRC16_DP_1_api_t *TASK_CRC16_DP_1_api=&TASK_CRC16_DP_1_storage; + +TASK_GEN_DP_0_api_t TASK_GEN_DP_0_storage; +TASK_GEN_DP_0_api_t *TASK_GEN_DP_0_api=&TASK_GEN_DP_0_storage; + +TASK_GEN_DP_1_api_t TASK_GEN_DP_1_storage; +TASK_GEN_DP_1_api_t *TASK_GEN_DP_1_api=&TASK_GEN_DP_1_storage; + +TASK_GEN_DP_2_api_t TASK_GEN_DP_2_storage; +TASK_GEN_DP_2_api_t *TASK_GEN_DP_2_api=&TASK_GEN_DP_2_storage; + +TASK_GEN_DP_3_api_t TASK_GEN_DP_3_storage; +TASK_GEN_DP_3_api_t *TASK_GEN_DP_3_api=&TASK_GEN_DP_3_storage; + +TASK_GEN_TX_BD_api_t TASK_GEN_TX_BD_storage; +TASK_GEN_TX_BD_api_t *TASK_GEN_TX_BD_api=&TASK_GEN_TX_BD_storage; + +TASK_GEN_RX_BD_api_t TASK_GEN_RX_BD_storage; +TASK_GEN_RX_BD_api_t *TASK_GEN_RX_BD_api=&TASK_GEN_RX_BD_storage; + +TASK_GEN_DP_BD_0_api_t TASK_GEN_DP_BD_0_storage; +TASK_GEN_DP_BD_0_api_t *TASK_GEN_DP_BD_0_api=&TASK_GEN_DP_BD_0_storage; + +TASK_GEN_DP_BD_1_api_t TASK_GEN_DP_BD_1_storage; +TASK_GEN_DP_BD_1_api_t *TASK_GEN_DP_BD_1_api=&TASK_GEN_DP_BD_1_storage; + + + + +void init_dma_image_TASK_PCI_TX(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_PCI_TX_api->TaskNum = 0; + TASK_PCI_TX_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0000UL); + TASK_PCI_TX_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0004UL); + TASK_PCI_TX_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0008UL); + TASK_PCI_TX_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x000cUL); + TASK_PCI_TX_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0018UL); + TASK_PCI_TX_api->TaskPragma = (volatile uint8 *)(TASK_PCI_TX_api->PtrFDT)+3; + TASK_PCI_TX_api->NumDRD = 7; + TASK_PCI_TX_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0008UL - vMemOffset); + TASK_PCI_TX_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_PCI_TX_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_PCI_TX_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_PCI_TX_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_PCI_TX_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_PCI_TX_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrStartTDT) + 0x0038UL - vMemOffset); + TASK_PCI_TX_api->NumVar = 12; + TASK_PCI_TX_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrVarTab) - vMemOffset); + TASK_PCI_TX_api->NumInc = 5; + TASK_PCI_TX_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_TX_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_PCI_TX_api->AddrDstFIFO = &(TASK_PCI_TX_api->var[0]); + TASK_PCI_TX_api->IncrBytes = (volatile sint16 *)&(TASK_PCI_TX_api->inc[0])+1; + TASK_PCI_TX_api->AddrPktSizeReg = &(TASK_PCI_TX_api->var[1]); + TASK_PCI_TX_api->IncrSrc = (volatile sint16 *)&(TASK_PCI_TX_api->inc[1])+1; + TASK_PCI_TX_api->AddrSCStatusReg = &(TASK_PCI_TX_api->var[2]); + TASK_PCI_TX_api->Bytes = &(TASK_PCI_TX_api->var[3]); + TASK_PCI_TX_api->IterExtra = &(TASK_PCI_TX_api->var[4]); + TASK_PCI_TX_api->StartAddrSrc = &(TASK_PCI_TX_api->var[7]); +} + + +void init_dma_image_TASK_PCI_RX(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_PCI_RX_api->TaskNum = 1; + TASK_PCI_RX_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0020UL); + TASK_PCI_RX_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0024UL); + TASK_PCI_RX_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0028UL); + TASK_PCI_RX_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x002cUL); + TASK_PCI_RX_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0038UL); + TASK_PCI_RX_api->TaskPragma = (volatile uint8 *)(TASK_PCI_RX_api->PtrFDT)+3; + TASK_PCI_RX_api->NumDRD = 5; + TASK_PCI_RX_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrStartTDT) + 0x0008UL - vMemOffset); + TASK_PCI_RX_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_PCI_RX_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_PCI_RX_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_PCI_RX_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_PCI_RX_api->NumVar = 9; + TASK_PCI_RX_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrVarTab) - vMemOffset); + TASK_PCI_RX_api->NumInc = 4; + TASK_PCI_RX_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_PCI_RX_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_PCI_RX_api->AddrPktSizeReg = &(TASK_PCI_RX_api->var[0]); + TASK_PCI_RX_api->IncrBytes = (volatile sint16 *)&(TASK_PCI_RX_api->inc[0])+1; + TASK_PCI_RX_api->AddrSrcFIFO = &(TASK_PCI_RX_api->var[1]); + TASK_PCI_RX_api->IncrDst = (volatile sint16 *)&(TASK_PCI_RX_api->inc[1])+1; + TASK_PCI_RX_api->Bytes = &(TASK_PCI_RX_api->var[2]); + TASK_PCI_RX_api->IterExtra = &(TASK_PCI_RX_api->var[3]); + TASK_PCI_RX_api->StartAddrDst = &(TASK_PCI_RX_api->var[6]); +} + + +void init_dma_image_TASK_FEC_TX(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_FEC_TX_api->TaskNum = 2; + TASK_FEC_TX_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0040UL); + TASK_FEC_TX_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0044UL); + TASK_FEC_TX_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0048UL); + TASK_FEC_TX_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x004cUL); + TASK_FEC_TX_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0058UL); + TASK_FEC_TX_api->TaskPragma = (volatile uint8 *)(TASK_FEC_TX_api->PtrFDT)+3; + TASK_FEC_TX_api->NumDRD = 22; + TASK_FEC_TX_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_FEC_TX_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0008UL - vMemOffset); + TASK_FEC_TX_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_FEC_TX_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x001cUL - vMemOffset); + TASK_FEC_TX_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_FEC_TX_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_FEC_TX_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_FEC_TX_api->DRD[7] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0030UL - vMemOffset); + TASK_FEC_TX_api->DRD[8] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0034UL - vMemOffset); + TASK_FEC_TX_api->DRD[9] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0038UL - vMemOffset); + TASK_FEC_TX_api->DRD[10] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0044UL - vMemOffset); + TASK_FEC_TX_api->DRD[11] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0048UL - vMemOffset); + TASK_FEC_TX_api->DRD[12] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x004cUL - vMemOffset); + TASK_FEC_TX_api->DRD[13] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0054UL - vMemOffset); + TASK_FEC_TX_api->DRD[14] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0060UL - vMemOffset); + TASK_FEC_TX_api->DRD[15] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0064UL - vMemOffset); + TASK_FEC_TX_api->DRD[16] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0068UL - vMemOffset); + TASK_FEC_TX_api->DRD[17] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x006cUL - vMemOffset); + TASK_FEC_TX_api->DRD[18] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0074UL - vMemOffset); + TASK_FEC_TX_api->DRD[19] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x007cUL - vMemOffset); + TASK_FEC_TX_api->DRD[20] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0084UL - vMemOffset); + TASK_FEC_TX_api->DRD[21] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrStartTDT) + 0x0088UL - vMemOffset); + TASK_FEC_TX_api->NumVar = 20; + TASK_FEC_TX_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrVarTab) - vMemOffset); + TASK_FEC_TX_api->NumInc = 7; + TASK_FEC_TX_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_TX_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_FEC_TX_api->AddrDRD = &(TASK_FEC_TX_api->var[0]); + TASK_FEC_TX_api->AddrDRDIdx = 19; + *TASK_FEC_TX_api->AddrDRD = (volatile uint32)(TASK_FEC_TX_api->DRD[19]); + TASK_FEC_TX_api->IncrBytes = (volatile sint16 *)&(TASK_FEC_TX_api->inc[0])+1; + TASK_FEC_TX_api->AddrDstFIFO = &(TASK_FEC_TX_api->var[1]); + TASK_FEC_TX_api->IncrSrc = (volatile sint16 *)&(TASK_FEC_TX_api->inc[1])+1; + TASK_FEC_TX_api->AddrEnable = &(TASK_FEC_TX_api->var[2]); + TASK_FEC_TX_api->IncrSrcMA = (volatile sint16 *)&(TASK_FEC_TX_api->inc[2])+1; + TASK_FEC_TX_api->BDTableBase = &(TASK_FEC_TX_api->var[3]); + TASK_FEC_TX_api->BDTableLast = &(TASK_FEC_TX_api->var[4]); + TASK_FEC_TX_api->BDTableStart = &(TASK_FEC_TX_api->var[5]); + TASK_FEC_TX_api->Bytes = &(TASK_FEC_TX_api->var[6]); +} + + +void init_dma_image_TASK_FEC_RX(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_FEC_RX_api->TaskNum = 3; + TASK_FEC_RX_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0060UL); + TASK_FEC_RX_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0064UL); + TASK_FEC_RX_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0068UL); + TASK_FEC_RX_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x006cUL); + TASK_FEC_RX_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0078UL); + TASK_FEC_RX_api->TaskPragma = (volatile uint8 *)(TASK_FEC_RX_api->PtrFDT)+3; + TASK_FEC_RX_api->NumDRD = 13; + TASK_FEC_RX_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_FEC_RX_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_FEC_RX_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_FEC_RX_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_FEC_RX_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_FEC_RX_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_FEC_RX_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_FEC_RX_api->DRD[7] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0038UL - vMemOffset); + TASK_FEC_RX_api->DRD[8] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x003cUL - vMemOffset); + TASK_FEC_RX_api->DRD[9] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0040UL - vMemOffset); + TASK_FEC_RX_api->DRD[10] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0048UL - vMemOffset); + TASK_FEC_RX_api->DRD[11] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0050UL - vMemOffset); + TASK_FEC_RX_api->DRD[12] = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrStartTDT) + 0x0058UL - vMemOffset); + TASK_FEC_RX_api->NumVar = 15; + TASK_FEC_RX_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrVarTab) - vMemOffset); + TASK_FEC_RX_api->NumInc = 7; + TASK_FEC_RX_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_FEC_RX_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_FEC_RX_api->AddrEnable = &(TASK_FEC_RX_api->var[0]); + TASK_FEC_RX_api->IncrBytes = (volatile sint16 *)&(TASK_FEC_RX_api->inc[0])+1; + TASK_FEC_RX_api->AddrSrcFIFO = &(TASK_FEC_RX_api->var[1]); + TASK_FEC_RX_api->IncrDst = (volatile sint16 *)&(TASK_FEC_RX_api->inc[1])+1; + TASK_FEC_RX_api->BDTableBase = &(TASK_FEC_RX_api->var[2]); + TASK_FEC_RX_api->IncrDstMA = (volatile sint16 *)&(TASK_FEC_RX_api->inc[2])+1; + TASK_FEC_RX_api->BDTableLast = &(TASK_FEC_RX_api->var[3]); + TASK_FEC_RX_api->BDTableStart = &(TASK_FEC_RX_api->var[4]); + TASK_FEC_RX_api->Bytes = &(TASK_FEC_RX_api->var[5]); +} + + +void init_dma_image_TASK_LPC(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_LPC_api->TaskNum = 4; + TASK_LPC_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0080UL); + TASK_LPC_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0084UL); + TASK_LPC_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0088UL); + TASK_LPC_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x008cUL); + TASK_LPC_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0098UL); + TASK_LPC_api->TaskPragma = (volatile uint8 *)(TASK_LPC_api->PtrFDT)+3; + TASK_LPC_api->NumDRD = 4; + TASK_LPC_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_LPC_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_LPC_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_LPC_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_LPC_api->NumVar = 9; + TASK_LPC_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrVarTab) - vMemOffset); + TASK_LPC_api->NumInc = 8; + TASK_LPC_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_LPC_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_LPC_api->Bytes = &(TASK_LPC_api->var[0]); + TASK_LPC_api->IncrBytes = (volatile sint16 *)&(TASK_LPC_api->inc[0])+1; + TASK_LPC_api->IterExtra = &(TASK_LPC_api->var[1]); + TASK_LPC_api->IncrDst = (volatile sint16 *)&(TASK_LPC_api->inc[1])+1; + TASK_LPC_api->IncrDstMA = (volatile sint16 *)&(TASK_LPC_api->inc[2])+1; + TASK_LPC_api->IncrSrc = (volatile sint16 *)&(TASK_LPC_api->inc[3])+1; + TASK_LPC_api->StartAddrDst = &(TASK_LPC_api->var[4]); + TASK_LPC_api->IncrSrcMA = (volatile sint16 *)&(TASK_LPC_api->inc[4])+1; + TASK_LPC_api->StartAddrSrc = &(TASK_LPC_api->var[5]); +} + + +void init_dma_image_TASK_ATA(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_ATA_api->TaskNum = 5; + TASK_ATA_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x00a0UL); + TASK_ATA_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x00a4UL); + TASK_ATA_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x00a8UL); + TASK_ATA_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x00acUL); + TASK_ATA_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x00b8UL); + TASK_ATA_api->TaskPragma = (volatile uint8 *)(TASK_ATA_api->PtrFDT)+3; + TASK_ATA_api->NumDRD = 7; + TASK_ATA_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_ATA_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_ATA_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_ATA_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_ATA_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_ATA_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_ATA_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrStartTDT) + 0x0030UL - vMemOffset); + TASK_ATA_api->NumVar = 12; + TASK_ATA_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrVarTab) - vMemOffset); + TASK_ATA_api->NumInc = 6; + TASK_ATA_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_ATA_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_ATA_api->AddrEnable = &(TASK_ATA_api->var[0]); + TASK_ATA_api->IncrBytes = (volatile sint16 *)&(TASK_ATA_api->inc[0])+1; + TASK_ATA_api->BDTableBase = &(TASK_ATA_api->var[1]); + TASK_ATA_api->IncrDst = (volatile sint16 *)&(TASK_ATA_api->inc[1])+1; + TASK_ATA_api->BDTableLast = &(TASK_ATA_api->var[2]); + TASK_ATA_api->IncrSrc = (volatile sint16 *)&(TASK_ATA_api->inc[2])+1; + TASK_ATA_api->BDTableStart = &(TASK_ATA_api->var[3]); + TASK_ATA_api->Bytes = &(TASK_ATA_api->var[4]); +} + + +void init_dma_image_TASK_CRC16_DP_0(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_CRC16_DP_0_api->TaskNum = 6; + TASK_CRC16_DP_0_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x00c0UL); + TASK_CRC16_DP_0_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x00c4UL); + TASK_CRC16_DP_0_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x00c8UL); + TASK_CRC16_DP_0_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x00ccUL); + TASK_CRC16_DP_0_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x00d8UL); + TASK_CRC16_DP_0_api->TaskPragma = (volatile uint8 *)(TASK_CRC16_DP_0_api->PtrFDT)+3; + TASK_CRC16_DP_0_api->NumDRD = 9; + TASK_CRC16_DP_0_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0008UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0028UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0034UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[7] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0038UL - vMemOffset); + TASK_CRC16_DP_0_api->DRD[8] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrStartTDT) + 0x0040UL - vMemOffset); + TASK_CRC16_DP_0_api->NumVar = 10; + TASK_CRC16_DP_0_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrVarTab) - vMemOffset); + TASK_CRC16_DP_0_api->NumInc = 8; + TASK_CRC16_DP_0_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_0_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_CRC16_DP_0_api->Bytes = &(TASK_CRC16_DP_0_api->var[0]); + TASK_CRC16_DP_0_api->IncrBytes = (volatile sint16 *)&(TASK_CRC16_DP_0_api->inc[0])+1; + TASK_CRC16_DP_0_api->IterExtra = &(TASK_CRC16_DP_0_api->var[1]); + TASK_CRC16_DP_0_api->IncrDst = (volatile sint16 *)&(TASK_CRC16_DP_0_api->inc[1])+1; + TASK_CRC16_DP_0_api->IncrDstMA = (volatile sint16 *)&(TASK_CRC16_DP_0_api->inc[2])+1; + TASK_CRC16_DP_0_api->IncrSrc = (volatile sint16 *)&(TASK_CRC16_DP_0_api->inc[3])+1; + TASK_CRC16_DP_0_api->StartAddrDst = &(TASK_CRC16_DP_0_api->var[4]); + TASK_CRC16_DP_0_api->IncrSrcMA = (volatile sint16 *)&(TASK_CRC16_DP_0_api->inc[4])+1; + TASK_CRC16_DP_0_api->StartAddrSrc = &(TASK_CRC16_DP_0_api->var[5]); +} + + +void init_dma_image_TASK_CRC16_DP_1(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_CRC16_DP_1_api->TaskNum = 7; + TASK_CRC16_DP_1_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x00e0UL); + TASK_CRC16_DP_1_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x00e4UL); + TASK_CRC16_DP_1_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x00e8UL); + TASK_CRC16_DP_1_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x00ecUL); + TASK_CRC16_DP_1_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x00f8UL); + TASK_CRC16_DP_1_api->TaskPragma = (volatile uint8 *)(TASK_CRC16_DP_1_api->PtrFDT)+3; + TASK_CRC16_DP_1_api->NumDRD = 9; + TASK_CRC16_DP_1_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0008UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0028UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0034UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[7] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0038UL - vMemOffset); + TASK_CRC16_DP_1_api->DRD[8] = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrStartTDT) + 0x0040UL - vMemOffset); + TASK_CRC16_DP_1_api->NumVar = 10; + TASK_CRC16_DP_1_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrVarTab) - vMemOffset); + TASK_CRC16_DP_1_api->NumInc = 8; + TASK_CRC16_DP_1_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_CRC16_DP_1_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_CRC16_DP_1_api->Bytes = &(TASK_CRC16_DP_1_api->var[0]); + TASK_CRC16_DP_1_api->IncrBytes = (volatile sint16 *)&(TASK_CRC16_DP_1_api->inc[0])+1; + TASK_CRC16_DP_1_api->IterExtra = &(TASK_CRC16_DP_1_api->var[1]); + TASK_CRC16_DP_1_api->IncrDst = (volatile sint16 *)&(TASK_CRC16_DP_1_api->inc[1])+1; + TASK_CRC16_DP_1_api->IncrDstMA = (volatile sint16 *)&(TASK_CRC16_DP_1_api->inc[2])+1; + TASK_CRC16_DP_1_api->IncrSrc = (volatile sint16 *)&(TASK_CRC16_DP_1_api->inc[3])+1; + TASK_CRC16_DP_1_api->StartAddrDst = &(TASK_CRC16_DP_1_api->var[4]); + TASK_CRC16_DP_1_api->IncrSrcMA = (volatile sint16 *)&(TASK_CRC16_DP_1_api->inc[4])+1; + TASK_CRC16_DP_1_api->StartAddrSrc = &(TASK_CRC16_DP_1_api->var[5]); +} + + +void init_dma_image_TASK_GEN_DP_0(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_0_api->TaskNum = 8; + TASK_GEN_DP_0_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0100UL); + TASK_GEN_DP_0_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0104UL); + TASK_GEN_DP_0_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0108UL); + TASK_GEN_DP_0_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x010cUL); + TASK_GEN_DP_0_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0118UL); + TASK_GEN_DP_0_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_0_api->PtrFDT)+3; + TASK_GEN_DP_0_api->NumDRD = 4; + TASK_GEN_DP_0_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_0_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_GEN_DP_0_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_0_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_0_api->NumVar = 9; + TASK_GEN_DP_0_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_0_api->NumInc = 8; + TASK_GEN_DP_0_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_0_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_0_api->Bytes = &(TASK_GEN_DP_0_api->var[0]); + TASK_GEN_DP_0_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_0_api->inc[0])+1; + TASK_GEN_DP_0_api->IterExtra = &(TASK_GEN_DP_0_api->var[1]); + TASK_GEN_DP_0_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_0_api->inc[1])+1; + TASK_GEN_DP_0_api->IncrDstMA = (volatile sint16 *)&(TASK_GEN_DP_0_api->inc[2])+1; + TASK_GEN_DP_0_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_0_api->inc[3])+1; + TASK_GEN_DP_0_api->StartAddrDst = &(TASK_GEN_DP_0_api->var[4]); + TASK_GEN_DP_0_api->IncrSrcMA = (volatile sint16 *)&(TASK_GEN_DP_0_api->inc[4])+1; + TASK_GEN_DP_0_api->StartAddrSrc = &(TASK_GEN_DP_0_api->var[5]); +} + + +void init_dma_image_TASK_GEN_DP_1(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_1_api->TaskNum = 9; + TASK_GEN_DP_1_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0120UL); + TASK_GEN_DP_1_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0124UL); + TASK_GEN_DP_1_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0128UL); + TASK_GEN_DP_1_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x012cUL); + TASK_GEN_DP_1_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0138UL); + TASK_GEN_DP_1_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_1_api->PtrFDT)+3; + TASK_GEN_DP_1_api->NumDRD = 4; + TASK_GEN_DP_1_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_1_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_GEN_DP_1_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_1_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_1_api->NumVar = 9; + TASK_GEN_DP_1_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_1_api->NumInc = 8; + TASK_GEN_DP_1_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_1_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_1_api->Bytes = &(TASK_GEN_DP_1_api->var[0]); + TASK_GEN_DP_1_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_1_api->inc[0])+1; + TASK_GEN_DP_1_api->IterExtra = &(TASK_GEN_DP_1_api->var[1]); + TASK_GEN_DP_1_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_1_api->inc[1])+1; + TASK_GEN_DP_1_api->IncrDstMA = (volatile sint16 *)&(TASK_GEN_DP_1_api->inc[2])+1; + TASK_GEN_DP_1_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_1_api->inc[3])+1; + TASK_GEN_DP_1_api->StartAddrDst = &(TASK_GEN_DP_1_api->var[4]); + TASK_GEN_DP_1_api->IncrSrcMA = (volatile sint16 *)&(TASK_GEN_DP_1_api->inc[4])+1; + TASK_GEN_DP_1_api->StartAddrSrc = &(TASK_GEN_DP_1_api->var[5]); +} + + +void init_dma_image_TASK_GEN_DP_2(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_2_api->TaskNum = 10; + TASK_GEN_DP_2_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0140UL); + TASK_GEN_DP_2_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0144UL); + TASK_GEN_DP_2_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0148UL); + TASK_GEN_DP_2_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x014cUL); + TASK_GEN_DP_2_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0158UL); + TASK_GEN_DP_2_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_2_api->PtrFDT)+3; + TASK_GEN_DP_2_api->NumDRD = 4; + TASK_GEN_DP_2_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_2_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_GEN_DP_2_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_2_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_2_api->NumVar = 9; + TASK_GEN_DP_2_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_2_api->NumInc = 8; + TASK_GEN_DP_2_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_2_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_2_api->Bytes = &(TASK_GEN_DP_2_api->var[0]); + TASK_GEN_DP_2_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_2_api->inc[0])+1; + TASK_GEN_DP_2_api->IterExtra = &(TASK_GEN_DP_2_api->var[1]); + TASK_GEN_DP_2_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_2_api->inc[1])+1; + TASK_GEN_DP_2_api->IncrDstMA = (volatile sint16 *)&(TASK_GEN_DP_2_api->inc[2])+1; + TASK_GEN_DP_2_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_2_api->inc[3])+1; + TASK_GEN_DP_2_api->StartAddrDst = &(TASK_GEN_DP_2_api->var[4]); + TASK_GEN_DP_2_api->IncrSrcMA = (volatile sint16 *)&(TASK_GEN_DP_2_api->inc[4])+1; + TASK_GEN_DP_2_api->StartAddrSrc = &(TASK_GEN_DP_2_api->var[5]); +} + + +void init_dma_image_TASK_GEN_DP_3(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_3_api->TaskNum = 11; + TASK_GEN_DP_3_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0160UL); + TASK_GEN_DP_3_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0164UL); + TASK_GEN_DP_3_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0168UL); + TASK_GEN_DP_3_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x016cUL); + TASK_GEN_DP_3_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0178UL); + TASK_GEN_DP_3_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_3_api->PtrFDT)+3; + TASK_GEN_DP_3_api->NumDRD = 4; + TASK_GEN_DP_3_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_3_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrStartTDT) + 0x0018UL - vMemOffset); + TASK_GEN_DP_3_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_3_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_3_api->NumVar = 9; + TASK_GEN_DP_3_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_3_api->NumInc = 8; + TASK_GEN_DP_3_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_3_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_3_api->Bytes = &(TASK_GEN_DP_3_api->var[0]); + TASK_GEN_DP_3_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_3_api->inc[0])+1; + TASK_GEN_DP_3_api->IterExtra = &(TASK_GEN_DP_3_api->var[1]); + TASK_GEN_DP_3_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_3_api->inc[1])+1; + TASK_GEN_DP_3_api->IncrDstMA = (volatile sint16 *)&(TASK_GEN_DP_3_api->inc[2])+1; + TASK_GEN_DP_3_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_3_api->inc[3])+1; + TASK_GEN_DP_3_api->StartAddrDst = &(TASK_GEN_DP_3_api->var[4]); + TASK_GEN_DP_3_api->IncrSrcMA = (volatile sint16 *)&(TASK_GEN_DP_3_api->inc[4])+1; + TASK_GEN_DP_3_api->StartAddrSrc = &(TASK_GEN_DP_3_api->var[5]); +} + + +void init_dma_image_TASK_GEN_TX_BD(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_TX_BD_api->TaskNum = 12; + TASK_GEN_TX_BD_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x0180UL); + TASK_GEN_TX_BD_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x0184UL); + TASK_GEN_TX_BD_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x0188UL); + TASK_GEN_TX_BD_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x018cUL); + TASK_GEN_TX_BD_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x0198UL); + TASK_GEN_TX_BD_api->TaskPragma = (volatile uint8 *)(TASK_GEN_TX_BD_api->PtrFDT)+3; + TASK_GEN_TX_BD_api->NumDRD = 8; + TASK_GEN_TX_BD_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0028UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0030UL - vMemOffset); + TASK_GEN_TX_BD_api->DRD[7] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrStartTDT) + 0x0034UL - vMemOffset); + TASK_GEN_TX_BD_api->NumVar = 13; + TASK_GEN_TX_BD_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrVarTab) - vMemOffset); + TASK_GEN_TX_BD_api->NumInc = 7; + TASK_GEN_TX_BD_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_TX_BD_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_TX_BD_api->AddrDstFIFO = &(TASK_GEN_TX_BD_api->var[0]); + TASK_GEN_TX_BD_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_TX_BD_api->inc[0])+1; + TASK_GEN_TX_BD_api->AddrEnable = &(TASK_GEN_TX_BD_api->var[1]); + TASK_GEN_TX_BD_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_TX_BD_api->inc[1])+1; + TASK_GEN_TX_BD_api->BDTableBase = &(TASK_GEN_TX_BD_api->var[2]); + TASK_GEN_TX_BD_api->IncrSrcMA = (volatile sint16 *)&(TASK_GEN_TX_BD_api->inc[2])+1; + TASK_GEN_TX_BD_api->BDTableLast = &(TASK_GEN_TX_BD_api->var[3]); + TASK_GEN_TX_BD_api->BDTableStart = &(TASK_GEN_TX_BD_api->var[4]); + TASK_GEN_TX_BD_api->Bytes = &(TASK_GEN_TX_BD_api->var[5]); +} + + +void init_dma_image_TASK_GEN_RX_BD(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_RX_BD_api->TaskNum = 13; + TASK_GEN_RX_BD_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x01a0UL); + TASK_GEN_RX_BD_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x01a4UL); + TASK_GEN_RX_BD_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x01a8UL); + TASK_GEN_RX_BD_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x01acUL); + TASK_GEN_RX_BD_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x01b8UL); + TASK_GEN_RX_BD_api->TaskPragma = (volatile uint8 *)(TASK_GEN_RX_BD_api->PtrFDT)+3; + TASK_GEN_RX_BD_api->NumDRD = 7; + TASK_GEN_RX_BD_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x0020UL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x0028UL - vMemOffset); + TASK_GEN_RX_BD_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_RX_BD_api->NumVar = 12; + TASK_GEN_RX_BD_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrVarTab) - vMemOffset); + TASK_GEN_RX_BD_api->NumInc = 5; + TASK_GEN_RX_BD_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_RX_BD_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_RX_BD_api->AddrEnable = &(TASK_GEN_RX_BD_api->var[0]); + TASK_GEN_RX_BD_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_RX_BD_api->inc[0])+1; + TASK_GEN_RX_BD_api->AddrSrcFIFO = &(TASK_GEN_RX_BD_api->var[1]); + TASK_GEN_RX_BD_api->IncrDst = (volatile sint16 *)&(TASK_GEN_RX_BD_api->inc[1])+1; + TASK_GEN_RX_BD_api->BDTableBase = &(TASK_GEN_RX_BD_api->var[2]); + TASK_GEN_RX_BD_api->BDTableLast = &(TASK_GEN_RX_BD_api->var[3]); + TASK_GEN_RX_BD_api->BDTableStart = &(TASK_GEN_RX_BD_api->var[4]); + TASK_GEN_RX_BD_api->Bytes = &(TASK_GEN_RX_BD_api->var[5]); +} + + +void init_dma_image_TASK_GEN_DP_BD_0(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_BD_0_api->TaskNum = 14; + TASK_GEN_DP_BD_0_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x01c0UL); + TASK_GEN_DP_BD_0_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x01c4UL); + TASK_GEN_DP_BD_0_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x01c8UL); + TASK_GEN_DP_BD_0_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x01ccUL); + TASK_GEN_DP_BD_0_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x01d8UL); + TASK_GEN_DP_BD_0_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_BD_0_api->PtrFDT)+3; + TASK_GEN_DP_BD_0_api->NumDRD = 7; + TASK_GEN_DP_BD_0_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_BD_0_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrStartTDT) + 0x0030UL - vMemOffset); + TASK_GEN_DP_BD_0_api->NumVar = 12; + TASK_GEN_DP_BD_0_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_BD_0_api->NumInc = 6; + TASK_GEN_DP_BD_0_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_0_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_BD_0_api->AddrEnable = &(TASK_GEN_DP_BD_0_api->var[0]); + TASK_GEN_DP_BD_0_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_BD_0_api->inc[0])+1; + TASK_GEN_DP_BD_0_api->BDTableBase = &(TASK_GEN_DP_BD_0_api->var[1]); + TASK_GEN_DP_BD_0_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_BD_0_api->inc[1])+1; + TASK_GEN_DP_BD_0_api->BDTableLast = &(TASK_GEN_DP_BD_0_api->var[2]); + TASK_GEN_DP_BD_0_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_BD_0_api->inc[2])+1; + TASK_GEN_DP_BD_0_api->BDTableStart = &(TASK_GEN_DP_BD_0_api->var[3]); + TASK_GEN_DP_BD_0_api->Bytes = &(TASK_GEN_DP_BD_0_api->var[4]); +} + + +void init_dma_image_TASK_GEN_DP_BD_1(uint8 *taskBar, sint64 vMemOffset) +{ + uint8 *vMem_taskBar = (taskBar - vMemOffset); + TASK_GEN_DP_BD_1_api->TaskNum = 15; + TASK_GEN_DP_BD_1_api->PtrStartTDT = (volatile uint32 *)(vMem_taskBar + 0x01e0UL); + TASK_GEN_DP_BD_1_api->PtrEndTDT = (volatile uint32 *)(vMem_taskBar + 0x01e4UL); + TASK_GEN_DP_BD_1_api->PtrVarTab = (volatile uint32 *)(vMem_taskBar + 0x01e8UL); + TASK_GEN_DP_BD_1_api->PtrFDT = (volatile uint32 *)(vMem_taskBar + 0x01ecUL); + TASK_GEN_DP_BD_1_api->PtrCSave = (volatile uint32 *)(vMem_taskBar + 0x01f8UL); + TASK_GEN_DP_BD_1_api->TaskPragma = (volatile uint8 *)(TASK_GEN_DP_BD_1_api->PtrFDT)+3; + TASK_GEN_DP_BD_1_api->NumDRD = 7; + TASK_GEN_DP_BD_1_api->DRD[0] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x0004UL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[1] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x000cUL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[2] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x0010UL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[3] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x0014UL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[4] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x0024UL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[5] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x002cUL - vMemOffset); + TASK_GEN_DP_BD_1_api->DRD[6] = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrStartTDT) + 0x0030UL - vMemOffset); + TASK_GEN_DP_BD_1_api->NumVar = 12; + TASK_GEN_DP_BD_1_api->var = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrVarTab) - vMemOffset); + TASK_GEN_DP_BD_1_api->NumInc = 6; + TASK_GEN_DP_BD_1_api->inc = (volatile uint32 *)(volatile uint32)(*(TASK_GEN_DP_BD_1_api->PtrVarTab) + (4*24) - vMemOffset); + TASK_GEN_DP_BD_1_api->AddrEnable = &(TASK_GEN_DP_BD_1_api->var[0]); + TASK_GEN_DP_BD_1_api->IncrBytes = (volatile sint16 *)&(TASK_GEN_DP_BD_1_api->inc[0])+1; + TASK_GEN_DP_BD_1_api->BDTableBase = &(TASK_GEN_DP_BD_1_api->var[1]); + TASK_GEN_DP_BD_1_api->IncrDst = (volatile sint16 *)&(TASK_GEN_DP_BD_1_api->inc[1])+1; + TASK_GEN_DP_BD_1_api->BDTableLast = &(TASK_GEN_DP_BD_1_api->var[2]); + TASK_GEN_DP_BD_1_api->IncrSrc = (volatile sint16 *)&(TASK_GEN_DP_BD_1_api->inc[2])+1; + TASK_GEN_DP_BD_1_api->BDTableStart = &(TASK_GEN_DP_BD_1_api->var[3]); + TASK_GEN_DP_BD_1_api->Bytes = &(TASK_GEN_DP_BD_1_api->var[4]); +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.capi.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.capi.h new file mode 100644 index 0000000000..18a64b7138 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.capi.h @@ -0,0 +1,84 @@ +#ifndef __DMA_IMAGE_CAPI_H +#define __DMA_IMAGE_CAPI_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +******************************************************************************/ + + +#include "../bestcomm/dma_image.h" + +typedef enum { + TASK_PCI_TX, + TASK_PCI_RX, + TASK_FEC_TX, + TASK_FEC_RX, + TASK_LPC, + TASK_ATA, + TASK_CRC16_DP_0, + TASK_CRC16_DP_1, + TASK_GEN_DP_0, + TASK_GEN_DP_1, + TASK_GEN_DP_2, + TASK_GEN_DP_3, + TASK_GEN_TX_BD, + TASK_GEN_RX_BD, + TASK_GEN_DP_BD_0, + TASK_GEN_DP_BD_1 +} TaskName_t; + +TaskId TaskSetup_TASK_PCI_TX (TASK_PCI_TX_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_PCI_RX (TASK_PCI_RX_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_FEC_TX (TASK_FEC_TX_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_FEC_RX (TASK_FEC_RX_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_LPC (TASK_LPC_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_ATA (TASK_ATA_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_CRC16_DP_0(TASK_CRC16_DP_0_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_CRC16_DP_1(TASK_CRC16_DP_1_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_0 (TASK_GEN_DP_0_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_1 (TASK_GEN_DP_1_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_2 (TASK_GEN_DP_2_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_3 (TASK_GEN_DP_3_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_TX_BD (TASK_GEN_TX_BD_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_RX_BD (TASK_GEN_RX_BD_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_BD_0(TASK_GEN_DP_BD_0_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); +TaskId TaskSetup_TASK_GEN_DP_BD_1(TASK_GEN_DP_BD_1_api_t *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams); + +#endif /* __DMA_IMAGE_CAPI_H */ + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.h new file mode 100644 index 0000000000..f7c8aaf4ae --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.h @@ -0,0 +1,472 @@ +#ifndef __DMA_IMAGE_H +#define __DMA_IMAGE_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +******************************************************************************/ + + +#include "../bestcomm/include/ppctypes.h" + +void init_dma_image_TASK_PCI_TX(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_PCI_RX(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_FEC_TX(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_FEC_RX(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_LPC(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_ATA(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_CRC16_DP_0(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_CRC16_DP_1(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_0(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_1(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_2(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_3(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_TX_BD(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_RX_BD(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_BD_0(uint8 *vMem_taskBar, sint64 vMemOffset); +void init_dma_image_TASK_GEN_DP_BD_1(uint8 *vMem_taskBar, sint64 vMemOffset); + +/* MBAR_TASK_TABLE is the first address of task table */ +#ifndef MBAR_TASK_TABLE +#define MBAR_TASK_TABLE 0xf0008000UL +#endif + +/* MBAR_DMA_FREE is the first free address after task table */ +#define MBAR_DMA_FREE MBAR_TASK_TABLE + 0x00001500UL + +/* TASK_BAR is the first address of the Entry table */ +#define TASK_BAR MBAR_TASK_TABLE + 0x00000000UL +#define TASK_BAR_OFFSET 0x00000000UL + +typedef struct task_info0 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[7]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrDstFIFO; + volatile sint16 *IncrBytes; + volatile uint32 *AddrPktSizeReg; + volatile sint16 *IncrSrc; + volatile uint32 *AddrSCStatusReg; + volatile uint32 *Bytes; + volatile uint32 *IterExtra; + volatile uint32 *StartAddrSrc; +} TASK_PCI_TX_api_t; +extern TASK_PCI_TX_api_t *TASK_PCI_TX_api; + +typedef struct task_info1 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[5]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrPktSizeReg; + volatile sint16 *IncrBytes; + volatile uint32 *AddrSrcFIFO; + volatile sint16 *IncrDst; + volatile uint32 *Bytes; + volatile uint32 *IterExtra; + volatile uint32 *StartAddrDst; +} TASK_PCI_RX_api_t; +extern TASK_PCI_RX_api_t *TASK_PCI_RX_api; + +typedef struct task_info2 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[22]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrDRD; + volatile uint32 AddrDRDIdx; + volatile sint16 *IncrBytes; + volatile uint32 *AddrDstFIFO; + volatile sint16 *IncrSrc; + volatile uint32 *AddrEnable; + volatile sint16 *IncrSrcMA; + volatile uint32 *BDTableBase; + volatile uint32 *BDTableLast; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_FEC_TX_api_t; +extern TASK_FEC_TX_api_t *TASK_FEC_TX_api; + +typedef struct task_info3 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[13]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrEnable; + volatile sint16 *IncrBytes; + volatile uint32 *AddrSrcFIFO; + volatile sint16 *IncrDst; + volatile uint32 *BDTableBase; + volatile sint16 *IncrDstMA; + volatile uint32 *BDTableLast; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_FEC_RX_api_t; +extern TASK_FEC_RX_api_t *TASK_FEC_RX_api; + +typedef struct task_info4 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[4]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_LPC_api_t; +extern TASK_LPC_api_t *TASK_LPC_api; + +typedef struct task_info5 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[7]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrEnable; + volatile sint16 *IncrBytes; + volatile uint32 *BDTableBase; + volatile sint16 *IncrDst; + volatile uint32 *BDTableLast; + volatile sint16 *IncrSrc; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_ATA_api_t; +extern TASK_ATA_api_t *TASK_ATA_api; + +typedef struct task_info6 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[9]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_CRC16_DP_0_api_t; +extern TASK_CRC16_DP_0_api_t *TASK_CRC16_DP_0_api; + +typedef struct task_info7 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[9]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_CRC16_DP_1_api_t; +extern TASK_CRC16_DP_1_api_t *TASK_CRC16_DP_1_api; + +typedef struct task_info8 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[4]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_GEN_DP_0_api_t; +extern TASK_GEN_DP_0_api_t *TASK_GEN_DP_0_api; + +typedef struct task_info9 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[4]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_GEN_DP_1_api_t; +extern TASK_GEN_DP_1_api_t *TASK_GEN_DP_1_api; + +typedef struct task_info10 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[4]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_GEN_DP_2_api_t; +extern TASK_GEN_DP_2_api_t *TASK_GEN_DP_2_api; + +typedef struct task_info11 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[4]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *Bytes; + volatile sint16 *IncrBytes; + volatile uint32 *IterExtra; + volatile sint16 *IncrDst; + volatile sint16 *IncrDstMA; + volatile sint16 *IncrSrc; + volatile uint32 *StartAddrDst; + volatile sint16 *IncrSrcMA; + volatile uint32 *StartAddrSrc; +} TASK_GEN_DP_3_api_t; +extern TASK_GEN_DP_3_api_t *TASK_GEN_DP_3_api; + +typedef struct task_info12 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[8]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrDstFIFO; + volatile sint16 *IncrBytes; + volatile uint32 *AddrEnable; + volatile sint16 *IncrSrc; + volatile uint32 *BDTableBase; + volatile sint16 *IncrSrcMA; + volatile uint32 *BDTableLast; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_GEN_TX_BD_api_t; +extern TASK_GEN_TX_BD_api_t *TASK_GEN_TX_BD_api; + +typedef struct task_info13 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[7]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrEnable; + volatile sint16 *IncrBytes; + volatile uint32 *AddrSrcFIFO; + volatile sint16 *IncrDst; + volatile uint32 *BDTableBase; + volatile uint32 *BDTableLast; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_GEN_RX_BD_api_t; +extern TASK_GEN_RX_BD_api_t *TASK_GEN_RX_BD_api; + +typedef struct task_info14 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[7]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrEnable; + volatile sint16 *IncrBytes; + volatile uint32 *BDTableBase; + volatile sint16 *IncrDst; + volatile uint32 *BDTableLast; + volatile sint16 *IncrSrc; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_GEN_DP_BD_0_api_t; +extern TASK_GEN_DP_BD_0_api_t *TASK_GEN_DP_BD_0_api; + +typedef struct task_info15 { + volatile uint32 TaskNum; + volatile uint32 *PtrStartTDT; + volatile uint32 *PtrEndTDT; + volatile uint32 *PtrVarTab; + volatile uint32 *PtrFDT; + volatile uint32 *PtrCSave; + volatile uint32 NumDRD; + volatile uint32 *DRD[7]; + volatile uint32 NumVar; + volatile uint32 *var; + volatile uint32 NumInc; + volatile uint32 *inc; + volatile uint8 *TaskPragma; + volatile uint32 *AddrEnable; + volatile sint16 *IncrBytes; + volatile uint32 *BDTableBase; + volatile sint16 *IncrDst; + volatile uint32 *BDTableLast; + volatile sint16 *IncrSrc; + volatile uint32 *BDTableStart; + volatile uint32 *Bytes; +} TASK_GEN_DP_BD_1_api_t; +extern TASK_GEN_DP_BD_1_api_t *TASK_GEN_DP_BD_1_api; + + +#endif /* __DMA_IMAGE_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.reloc.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.reloc.c new file mode 100644 index 0000000000..b2feac7cf3 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/dma_image.reloc.c @@ -0,0 +1,1453 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +******************************************************************************/ + + +#include "../bestcomm/include/ppctypes.h" + +uint32 taskTableBytes = 0x00001500; /* Number of bytes in image */ + +uint32 taskTableTasks = 0x00000010; /* Number of tasks in image */ + +uint32 offsetEntry = 0x00000000; /* Offset to Entry section */ + +uint32 taskTable[] = { + +/* SmartDMA image contains 5376 bytes (578 bytes unused) */ + +/* Task0(TASK_PCI_TX): Start of Entry -> 0xf0008000 */ +0x00000200, /* Task 0 Descriptor Table */ +0x00000238, +0x00000700, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x00001000, /* Task 0 context save space */ +0x00000000, +/* Task1(TASK_PCI_RX): Start of Entry -> 0xf0008020 */ +0x0000023c, /* Task 0 Descriptor Table */ +0x00000268, +0x00000780, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x00001050, /* Task 0 context save space */ +0x00000000, +/* Task2(TASK_FEC_TX): Start of Entry -> 0xf0008040 */ +0x0000026c, /* Task 0 Descriptor Table */ +0x000002f8, +0x00000800, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x000010a0, /* Task 0 context save space */ +0x00000000, +/* Task3(TASK_FEC_RX): Start of Entry -> 0xf0008060 */ +0x000002fc, /* Task 0 Descriptor Table */ +0x00000358, +0x00000880, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x000010f0, /* Task 0 context save space */ +0x00000000, +/* Task4(TASK_LPC): Start of Entry -> 0xf0008080 */ +0x0000035c, /* Task 0 Descriptor Table */ +0x0000038c, +0x00000900, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x00001140, /* Task 0 context save space */ +0x00000000, +/* Task5(TASK_ATA): Start of Entry -> 0xf00080a0 */ +0x00000390, /* Task 0 Descriptor Table */ +0x000003c4, +0x00000980, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x00001190, /* Task 0 context save space */ +0x00000000, +/* Task6(TASK_CRC16_DP_0): Start of Entry -> 0xf00080c0 */ +0x000003c8, /* Task 0 Descriptor Table */ +0x0000040c, +0x00000a00, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x000011e0, /* Task 0 context save space */ +0x00000000, +/* Task7(TASK_CRC16_DP_1): Start of Entry -> 0xf00080e0 */ +0x00000410, /* Task 0 Descriptor Table */ +0x00000454, +0x00000a80, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x00001230, /* Task 0 context save space */ +0x00000000, +/* Task8(TASK_GEN_DP_0): Start of Entry -> 0xf0008100 */ +0x00000458, /* Task 0 Descriptor Table */ +0x00000488, +0x00000b00, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x00001280, /* Task 0 context save space */ +0x00000000, +/* Task9(TASK_GEN_DP_1): Start of Entry -> 0xf0008120 */ +0x0000048c, /* Task 0 Descriptor Table */ +0x000004bc, +0x00000b80, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x000012d0, /* Task 0 context save space */ +0x00000000, +/* Task10(TASK_GEN_DP_2): Start of Entry -> 0xf0008140 */ +0x000004c0, /* Task 0 Descriptor Table */ +0x000004f0, +0x00000c00, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x00001320, /* Task 0 context save space */ +0x00000000, +/* Task11(TASK_GEN_DP_3): Start of Entry -> 0xf0008160 */ +0x000004f4, /* Task 0 Descriptor Table */ +0x00000524, +0x00000c80, /* Task 0 Variable Table */ +0x00000027, /* No FDT */ +0x00000000, +0x00000000, +0x00001370, /* Task 0 context save space */ +0x00000000, +/* Task12(TASK_GEN_TX_BD): Start of Entry -> 0xf0008180 */ +0x00000528, /* Task 0 Descriptor Table */ +0x00000560, +0x00000d00, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x000013c0, /* Task 0 context save space */ +0x00000000, +/* Task13(TASK_GEN_RX_BD): Start of Entry -> 0xf00081a0 */ +0x00000564, /* Task 0 Descriptor Table */ +0x00000594, +0x00000d80, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x00001410, /* Task 0 context save space */ +0x00000000, +/* Task14(TASK_GEN_DP_BD_0): Start of Entry -> 0xf00081c0 */ +0x00000598, /* Task 0 Descriptor Table */ +0x000005cc, +0x00000e00, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x00001460, /* Task 0 context save space */ +0x00000000, +/* Task15(TASK_GEN_DP_BD_1): Start of Entry -> 0xf00081e0 */ +0x000005d0, /* Task 0 Descriptor Table */ +0x00000604, +0x00000e80, /* Task 0 Variable Table */ +0x00000f27, /* Task 0 Function Descriptor Table & Flags */ +0x00000000, +0x00000000, +0x000014b0, /* Task 0 context save space */ +0x00000000, + +/* Task0(TASK_PCI_TX): Start of TDT -> 0xf0008200 */ +0xc080601b, /* 0000(../LIB_incl/hdplx.sc:167): LCDEXT: idx0 = var1, idx1 = var0; ; idx0 += inc3, idx1 += inc3 */ +0x82190292, /* 0004(../LIB_incl/hdplx.sc:177): LCD: idx2 = var4; idx2 >= var10; idx2 += inc2 */ +0x1004c018, /* 0008(../LIB_incl/hdplx.sc:179): DRD1A: *idx0 = var3; FN=0 MORE init=0 WS=2 RS=0 */ +0x8381a288, /* 000C(../LIB_incl/hdplx.sc:183): LCD: idx3 = var7, idx4 = var3; idx4 > var10; idx3 += inc1, idx4 += inc0 */ +0x011ec798, /* 0010(../LIB_incl/hdplx.sc:200): DRD1A: *idx1 = *idx3; FN=0 init=8 WS=3 RS=3 */ +0x999a001b, /* 0014(../LIB_incl/hdplx.sc:249): LCD: idx3 = idx3, idx4 = idx4; idx3 once var0; idx3 += inc3, idx4 += inc3 */ +0x00001f18, /* 0018(../LIB_incl/hdplx.sc:258): DRD1A: var7 = idx3; FN=0 init=0 WS=0 RS=0 */ +0x850102e3, /* 001C(../LIB_incl/hdplx.sc:281): LCD: idx3 = var10, idx4 = var2; idx3 != var11; idx3 += inc4, idx4 += inc3 */ +0x60080002, /* 0020(../LIB_incl/hdplx.sc:281): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=1 */ +0x08ccfd0b, /* 0024(../LIB_incl/hdplx.sc:281): DRD2B1: idx3 = EU3(); EU3(*idx4,var11) */ +0x9a19801b, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx3 = idx4; idx3 once var0; idx3 += inc3 */ +0x0002cc58, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: *idx3 = var11; FN=0 init=0 WS=1 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +0x8018001b, /* 0034(../LIB_incl/hdplx.sc:285): LCD: idx0 = var0; idx0 once var0; idx0 += inc3 */ +0x040001f8, /* 0038(../LIB_incl/hdplx.sc:285): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +/* Task1(TASK_PCI_RX): Start of TDT -> 0xf000823c */ +0xc000e01b, /* 0000(../LIB_incl/hdplx.sc:167): LCDEXT: idx0 = var0, idx1 = var1; ; idx0 += inc3, idx1 += inc3 */ +0x81990212, /* 0004(../LIB_incl/hdplx.sc:177): LCD: idx2 = var3; idx2 >= var8; idx2 += inc2 */ +0x1004c010, /* 0008(../LIB_incl/hdplx.sc:179): DRD1A: *idx0 = var2; FN=0 MORE init=0 WS=2 RS=0 */ +0x83012208, /* 000C(../LIB_incl/hdplx.sc:186): LCD: idx3 = var6, idx4 = var2; idx4 > var8; idx3 += inc1, idx4 += inc0 */ +0x00fecf88, /* 0010(../LIB_incl/hdplx.sc:200): DRD1A: *idx3 = *idx1; FN=0 init=7 WS=3 RS=3 */ +0x999a001b, /* 0014(../LIB_incl/hdplx.sc:252): LCD: idx3 = idx3, idx4 = idx4; idx3 once var0; idx3 += inc3, idx4 += inc3 */ +0x00001b18, /* 0018(../LIB_incl/hdplx.sc:261): DRD1A: var6 = idx3; FN=0 init=0 WS=0 RS=0 */ +0x8019801b, /* 001C(../LIB_incl/hdplx.sc:281): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */ +0x040001f8, /* 0020(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0024(:0): NOP */ +0x8018001b, /* 0028(../LIB_incl/hdplx.sc:285): LCD: idx0 = var0; idx0 once var0; idx0 += inc3 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:285): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +/* Task2(TASK_FEC_TX): Start of TDT -> 0xf000826c */ +0x8018001b, /* 0000(../LIB_incl/bd_hdplx.sc:303): LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */ +0x60000005, /* 0004(../LIB_incl/bd_hdplx.sc:307): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ +0x01ccfc0d, /* 0008(../LIB_incl/bd_hdplx.sc:307): DRD2B1: var7 = EU3(); EU3(*idx0,var13) */ +0x8082a123, /* 000C(../LIB_incl/bd_hdplx.sc:316): LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */ +0x10801418, /* 0010(../LIB_incl/bd_hdplx.sc:343): DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */ +0xf88103a4, /* 0014(../LIB_incl/bd_hdplx.sc:347): LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */ +0x801a6024, /* 0018(../LIB_incl/bd_hdplx.sc:351): LCD: idx4 = var0; ; idx4 += inc4 */ +0x10001708, /* 001C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0020(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0cccfccf, /* 0024(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx3 = EU3(); EU3(*idx3,var15) */ +0x991a002c, /* 0028(../LIB_incl/bd_hdplx.sc:373): LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */ +0x70000002, /* 002C(../LIB_incl/bd_hdplx.sc:377): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ +0x024cfc4d, /* 0030(../LIB_incl/bd_hdplx.sc:377): DRD2B1: var9 = EU3(); EU3(*idx1,var13) */ +0x60000003, /* 0034(../LIB_incl/bd_hdplx.sc:378): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */ +0x0cccf247, /* 0038(../LIB_incl/bd_hdplx.sc:378): DRD2B1: *idx3 = EU3(); EU3(var9,var7) */ +0x80004000, /* 003C(../LIB_incl/bd_hdplx.sc:390): LCDEXT: idx2 = 0x00000000; ; */ +0xb8c80029, /* 0040(../LIB_incl/bd_hdplx.sc:390): LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */ +0x70000002, /* 0044(../LIB_incl/bd_hdplx.sc:401): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ +0x088cf8d1, /* 0048(../LIB_incl/bd_hdplx.sc:401): DRD2B1: idx2 = EU3(); EU3(idx3,var17) */ +0x00002f10, /* 004C(../LIB_incl/bd_hdplx.sc:404): DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */ +0x99198432, /* 0050(../LIB_incl/bd_hdplx.sc:411): LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */ +0x008ac398, /* 0054(../LIB_incl/bd_hdplx.sc:428): DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */ +0x80004000, /* 0058(../LIB_incl/bd_hdplx.sc:434): LCDEXT: idx2 = 0x00000000; ; */ +0x9999802d, /* 005C(../LIB_incl/bd_hdplx.sc:439): LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */ +0x70000002, /* 0060(../LIB_incl/bd_hdplx.sc:446): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ +0x048cfc53, /* 0064(../LIB_incl/bd_hdplx.sc:446): DRD2B1: var18 = EU3(); EU3(*idx1,var19) */ +0x60000008, /* 0068(../LIB_incl/bd_hdplx.sc:450): DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */ +0x088cf48b, /* 006C(../LIB_incl/bd_hdplx.sc:450): DRD2B1: idx2 = EU3(); EU3(var18,var11) */ +0x99198481, /* 0070(../LIB_incl/bd_hdplx.sc:461): LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */ +0x009ec398, /* 0074(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */ +0x991983b2, /* 0078(../LIB_incl/bd_hdplx.sc:513): LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */ +0x088ac398, /* 007C(../LIB_incl/bd_hdplx.sc:530): DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */ +0x9919002d, /* 0080(../LIB_incl/bd_hdplx.sc:554): LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */ +0x60000005, /* 0084(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ +0x0c4cf88e, /* 0088(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx1 = EU3(); EU3(idx2,var14) */ +0x000001f8, /* 008C(:0): NOP */ +/* Task3(TASK_FEC_RX): Start of TDT -> 0xf00082fc */ +0x808220e3, /* 0000(../LIB_incl/bd_hdplx.sc:313): LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */ +0x10601010, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */ +0xb8800264, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */ +0x10001308, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0cccfcca, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */ +0x80004000, /* 0018(../LIB_incl/bd_hdplx.sc:393): LCDEXT: idx2 = 0x00000000; ; */ +0xb8c58029, /* 001C(../LIB_incl/bd_hdplx.sc:393): LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */ +0x60000002, /* 0020(../LIB_incl/bd_hdplx.sc:398): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */ +0x088cf8cc, /* 0024(../LIB_incl/bd_hdplx.sc:398): DRD2B1: idx2 = EU3(); EU3(idx3,var12) */ +0x991982f2, /* 0028(../LIB_incl/bd_hdplx.sc:414): LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */ +0x006acf80, /* 002C(../LIB_incl/bd_hdplx.sc:428): DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */ +0x80004000, /* 0030(../LIB_incl/bd_hdplx.sc:437): LCDEXT: idx2 = 0x00000000; ; */ +0x9999802d, /* 0034(../LIB_incl/bd_hdplx.sc:439): LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */ +0x70000002, /* 0038(../LIB_incl/bd_hdplx.sc:446): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ +0x034cfc4e, /* 003C(../LIB_incl/bd_hdplx.sc:446): DRD2B1: var13 = EU3(); EU3(*idx1,var14) */ +0x00008868, /* 0040(../LIB_incl/bd_hdplx.sc:448): DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */ +0x99198341, /* 0044(../LIB_incl/bd_hdplx.sc:464): LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */ +0x007ecf80, /* 0048(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */ +0x99198272, /* 004C(../LIB_incl/bd_hdplx.sc:516): LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */ +0x046acf80, /* 0050(../LIB_incl/bd_hdplx.sc:530): DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */ +0x9819002d, /* 0054(../LIB_incl/bd_hdplx.sc:550): LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */ +0x0060c790, /* 0058(../LIB_incl/bd_hdplx.sc:551): DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */ +0x000001f8, /* 005C(:0): NOP */ +/* Task4(TASK_LPC): Start of TDT -> 0xf000835c */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0xc2826019, /* 0004(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198200, /* 0008(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var8; idx3 += inc0 */ +0x03fecb88, /* 000C(../LIB_incl/hdplx.sc:200): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8990019, /* 0010(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0014(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x03fecb88, /* 0018(../LIB_incl/hdplx.sc:218): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8996022, /* 001C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0020(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x0beacb88, /* 0024(../LIB_incl/hdplx.sc:241): DRD1A: *idx2 = *idx1; FN=0 TFD init=31 WS=1 RS=1 */ +0x8018803f, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx1 = var0; idx1 once var0; idx1 += inc7 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +/* Task5(TASK_ATA): Start of TDT -> 0xf0008390 */ +0x8198009b, /* 0000(../LIB_incl/bd_hdplx.sc:321): LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */ +0x13e00c08, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */ +0xb8000264, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */ +0x10000f00, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0c8cfc8a, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */ +0xd8988240, /* 0018(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */ +0xf845e011, /* 001C(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */ +0xb845e00a, /* 0020(../LIB_incl/bd_hdplx.sc:472): LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */ +0x0bfecf90, /* 0024(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */ +0x9898802d, /* 0028(../LIB_incl/bd_hdplx.sc:554): LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */ +0x64000005, /* 002C(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */ +0x0c0cf849, /* 0030(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */ +0x000001f8, /* 0034(:0): NOP */ +/* Task6(TASK_CRC16_DP_0): Start of TDT -> 0xf00083c8 */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0x70000000, /* 0004(../LIB_incl/hdplx.sc:179): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ +0x2c87c7df, /* 0008(../LIB_incl/hdplx.sc:179): DRD2B2: EU3(var8) */ +0xc2826019, /* 000C(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198240, /* 0010(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var9; idx3 += inc0 */ +0x63fe000c, /* 0014(../LIB_incl/hdplx.sc:200): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT init=31 WS=3 RS=3 */ +0x0c8cfc5f, /* 0018(../LIB_incl/hdplx.sc:200): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0xd8990019, /* 001C(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0020(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x63fe000c, /* 0024(../LIB_incl/hdplx.sc:218): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT init=31 WS=3 RS=3 */ +0x0c8cfc5f, /* 0028(../LIB_incl/hdplx.sc:218): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0xd8996022, /* 002C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0030(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x6bea000c, /* 0034(../LIB_incl/hdplx.sc:241): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 TFD EXT init=31 WS=1 RS=1 */ +0x0c8cfc5f, /* 0038(../LIB_incl/hdplx.sc:241): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0x9918803f, /* 003C(../LIB_incl/hdplx.sc:281): LCD: idx1 = idx2; idx1 once var0; idx1 += inc7 */ +0x0404c599, /* 0040(../LIB_incl/hdplx.sc:281): DRD1A: *idx1 = EU3(); FN=1 INT init=0 WS=2 RS=0 */ +0x000001f8, /* 0044(:0): NOP */ +/* Task7(TASK_CRC16_DP_1): Start of TDT -> 0xf0008410 */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0x70000000, /* 0004(../LIB_incl/hdplx.sc:179): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ +0x2c87c7df, /* 0008(../LIB_incl/hdplx.sc:179): DRD2B2: EU3(var8) */ +0xc2826019, /* 000C(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198240, /* 0010(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var9; idx3 += inc0 */ +0x63fe000c, /* 0014(../LIB_incl/hdplx.sc:200): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT init=31 WS=3 RS=3 */ +0x0c8cfc5f, /* 0018(../LIB_incl/hdplx.sc:200): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0xd8990019, /* 001C(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0020(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x63fe000c, /* 0024(../LIB_incl/hdplx.sc:218): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT init=31 WS=3 RS=3 */ +0x0c8cfc5f, /* 0028(../LIB_incl/hdplx.sc:218): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0xd8996022, /* 002C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0030(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x6bea000c, /* 0034(../LIB_incl/hdplx.sc:241): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 TFD EXT init=31 WS=1 RS=1 */ +0x0c8cfc5f, /* 0038(../LIB_incl/hdplx.sc:241): DRD2B1: *idx2 = EU3(); EU3(*idx1) */ +0x9918803f, /* 003C(../LIB_incl/hdplx.sc:281): LCD: idx1 = idx2; idx1 once var0; idx1 += inc7 */ +0x0404c599, /* 0040(../LIB_incl/hdplx.sc:281): DRD1A: *idx1 = EU3(); FN=1 INT init=0 WS=2 RS=0 */ +0x000001f8, /* 0044(:0): NOP */ +/* Task8(TASK_GEN_DP_0): Start of TDT -> 0xf0008458 */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0xc2826019, /* 0004(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198200, /* 0008(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var8; idx3 += inc0 */ +0x03fecb88, /* 000C(../LIB_incl/hdplx.sc:200): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8990019, /* 0010(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0014(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x03fecb88, /* 0018(../LIB_incl/hdplx.sc:218): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8996022, /* 001C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0020(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x0beacb88, /* 0024(../LIB_incl/hdplx.sc:241): DRD1A: *idx2 = *idx1; FN=0 TFD init=31 WS=1 RS=1 */ +0x8018803f, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx1 = var0; idx1 once var0; idx1 += inc7 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +/* Task9(TASK_GEN_DP_1): Start of TDT -> 0xf000848c */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0xc2826019, /* 0004(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198200, /* 0008(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var8; idx3 += inc0 */ +0x03fecb88, /* 000C(../LIB_incl/hdplx.sc:200): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8990019, /* 0010(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0014(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x03fecb88, /* 0018(../LIB_incl/hdplx.sc:218): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8996022, /* 001C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0020(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x0beacb88, /* 0024(../LIB_incl/hdplx.sc:241): DRD1A: *idx2 = *idx1; FN=0 TFD init=31 WS=1 RS=1 */ +0x8018803f, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx1 = var0; idx1 once var0; idx1 += inc7 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +/* Task10(TASK_GEN_DP_2): Start of TDT -> 0xf00084c0 */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0xc2826019, /* 0004(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198200, /* 0008(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var8; idx3 += inc0 */ +0x03fecb88, /* 000C(../LIB_incl/hdplx.sc:200): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8990019, /* 0010(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0014(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x03fecb88, /* 0018(../LIB_incl/hdplx.sc:218): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8996022, /* 001C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0020(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x0beacb88, /* 0024(../LIB_incl/hdplx.sc:241): DRD1A: *idx2 = *idx1; FN=0 TFD init=31 WS=1 RS=1 */ +0x8018803f, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx1 = var0; idx1 once var0; idx1 += inc7 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +/* Task11(TASK_GEN_DP_3): Start of TDT -> 0xf00084f4 */ +0x809801ed, /* 0000(../LIB_incl/hdplx.sc:177): LCD: idx0 = var1; idx0 >= var7; idx0 += inc5 */ +0xc2826019, /* 0004(../LIB_incl/hdplx.sc:183): LCDEXT: idx1 = var5, idx2 = var4; ; idx1 += inc3, idx2 += inc1 */ +0x80198200, /* 0008(../LIB_incl/hdplx.sc:188): LCD: idx3 = var0; idx3 > var8; idx3 += inc0 */ +0x03fecb88, /* 000C(../LIB_incl/hdplx.sc:200): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8990019, /* 0010(../LIB_incl/hdplx.sc:208): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc3, idx2 += inc1 */ +0x9999e000, /* 0014(../LIB_incl/hdplx.sc:211): LCD: idx3 = idx3; ; idx3 += inc0 */ +0x03fecb88, /* 0018(../LIB_incl/hdplx.sc:218): DRD1A: *idx2 = *idx1; FN=0 init=31 WS=3 RS=3 */ +0xd8996022, /* 001C(../LIB_incl/hdplx.sc:224): LCDEXT: idx1 = idx1, idx2 = idx2; ; idx1 += inc4, idx2 += inc2 */ +0x999981f6, /* 0020(../LIB_incl/hdplx.sc:229): LCD: idx3 = idx3; idx3 > var7; idx3 += inc6 */ +0x0beacb88, /* 0024(../LIB_incl/hdplx.sc:241): DRD1A: *idx2 = *idx1; FN=0 TFD init=31 WS=1 RS=1 */ +0x8018803f, /* 0028(../LIB_incl/hdplx.sc:281): LCD: idx1 = var0; idx1 once var0; idx1 += inc7 */ +0x040001f8, /* 002C(../LIB_incl/hdplx.sc:281): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +0x000001f8, /* 0030(:0): NOP */ +/* Task12(TASK_GEN_TX_BD): Start of TDT -> 0xf0008528 */ +0x800220e3, /* 0000(../LIB_incl/bd_hdplx.sc:316): LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */ +0x13e01010, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */ +0xb8808264, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */ +0x10001308, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0cccfcca, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */ +0xd9190300, /* 0018(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */ +0xb8c5e009, /* 001C(../LIB_incl/bd_hdplx.sc:469): LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */ +0x03fec398, /* 0020(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx0 = *idx3; FN=0 init=31 WS=3 RS=3 */ +0x9919826a, /* 0024(../LIB_incl/bd_hdplx.sc:513): LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */ +0x0feac398, /* 0028(../LIB_incl/bd_hdplx.sc:530): DRD1A: *idx0 = *idx3; FN=0 TFD INT init=31 WS=1 RS=1 */ +0x99190036, /* 002C(../LIB_incl/bd_hdplx.sc:554): LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */ +0x60000005, /* 0030(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ +0x0c4cf889, /* 0034(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */ +0x000001f8, /* 0038(:0): NOP */ +/* Task13(TASK_GEN_RX_BD): Start of TDT -> 0xf0008564 */ +0x808220da, /* 0000(../LIB_incl/bd_hdplx.sc:313): LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc3, idx1 += inc2 */ +0x13e01010, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */ +0xb880025b, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc3, idx3 += inc3 */ +0x10001308, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0cccfcca, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */ +0xd9190240, /* 0018(../LIB_incl/bd_hdplx.sc:472): LCDEXT: idx2 = idx2; idx2 > var9; idx2 += inc0 */ +0xb8c5e009, /* 001C(../LIB_incl/bd_hdplx.sc:472): LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */ +0x07fecf80, /* 0020(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx3 = *idx0; FN=0 INT init=31 WS=3 RS=3 */ +0x99190024, /* 0024(../LIB_incl/bd_hdplx.sc:554): LCD: idx2 = idx2; idx2 once var0; idx2 += inc4 */ +0x60000005, /* 0028(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ +0x0c4cf889, /* 002C(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */ +0x000001f8, /* 0030(:0): NOP */ +/* Task14(TASK_GEN_DP_BD_0): Start of TDT -> 0xf0008598 */ +0x8198009b, /* 0000(../LIB_incl/bd_hdplx.sc:321): LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */ +0x13e00c08, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */ +0xb8000264, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */ +0x10000f00, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0c8cfc8a, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */ +0xd8988240, /* 0018(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */ +0xf845e011, /* 001C(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */ +0xb845e00a, /* 0020(../LIB_incl/bd_hdplx.sc:472): LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */ +0x0bfecf90, /* 0024(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */ +0x9898802d, /* 0028(../LIB_incl/bd_hdplx.sc:554): LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */ +0x64000005, /* 002C(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */ +0x0c0cf849, /* 0030(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */ +0x000001f8, /* 0034(:0): NOP */ +/* Task15(TASK_GEN_DP_BD_1): Start of TDT -> 0xf00085d0 */ +0x8198009b, /* 0000(../LIB_incl/bd_hdplx.sc:321): LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */ +0x13e00c08, /* 0004(../LIB_incl/bd_hdplx.sc:343): DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */ +0xb8000264, /* 0008(../LIB_incl/bd_hdplx.sc:347): LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */ +0x10000f00, /* 000C(../LIB_incl/bd_hdplx.sc:353): DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */ +0x60140002, /* 0010(../LIB_incl/bd_hdplx.sc:356): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ +0x0c8cfc8a, /* 0014(../LIB_incl/bd_hdplx.sc:356): DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */ +0xd8988240, /* 0018(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */ +0xf845e011, /* 001C(../LIB_incl/bd_hdplx.sc:469): LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */ +0xb845e00a, /* 0020(../LIB_incl/bd_hdplx.sc:472): LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */ +0x0bfecf90, /* 0024(../LIB_incl/bd_hdplx.sc:486): DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */ +0x9898802d, /* 0028(../LIB_incl/bd_hdplx.sc:554): LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */ +0x64000005, /* 002C(../LIB_incl/bd_hdplx.sc:556): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */ +0x0c0cf849, /* 0030(../LIB_incl/bd_hdplx.sc:556): DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */ +0x000001f8, /* 0034(:0): NOP */ + +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +0x00000000, /* alignment */ +/* Task0(TASK_PCI_TX): Start of VarTab -> 0xf0008700 */ +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] */ +0x00000001, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xc000ffff, /* inc[2] */ +0x00000000, /* inc[3] */ +0x60000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task1(TASK_PCI_RX): Start of VarTab -> 0xf0008780 */ +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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xc000ffff, /* inc[2] */ +0x00000000, /* inc[3] */ +0x00000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task2(TASK_FEC_TX): Start of VarTab -> 0xf0008800 */ +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] */ +0x0c000000, /* var[13] */ +0x40000000, /* var[14] */ +0x7fff7fff, /* var[15] */ +0x00000000, /* var[16] */ +0x00000003, /* var[17] */ +0x40000004, /* var[18] */ +0x43ffffff, /* var[19] */ +0x00000000, /* var[20] */ +0x00000000, /* var[21] */ +0x00000000, /* var[22] */ +0x00000000, /* var[23] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa0000008, /* inc[3] */ +0x20000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task3(TASK_FEC_RX): Start of VarTab -> 0xf0008880 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* var[10] */ +0x00000000, /* var[11] */ +0x00000003, /* var[12] */ +0x40000008, /* var[13] */ +0x43ffffff, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa0000008, /* inc[3] */ +0x20000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task4(TASK_LPC): Start of VarTab -> 0xf0008900 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task5(TASK_ATA): Start of VarTab -> 0xf0008980 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa000000c, /* inc[3] */ +0x20000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task6(TASK_CRC16_DP_0): Start of VarTab -> 0xf0008a00 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000001, /* var[8] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task7(TASK_CRC16_DP_1): Start of VarTab -> 0xf0008a80 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000001, /* var[8] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task8(TASK_GEN_DP_0): Start of VarTab -> 0xf0008b00 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task9(TASK_GEN_DP_1): Start of VarTab -> 0xf0008b80 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task10(TASK_GEN_DP_2): Start of VarTab -> 0xf0008c00 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task11(TASK_GEN_DP_3): Start of VarTab -> 0xf0008c80 */ +0x00000000, /* var[0] */ +0x00000000, /* var[1] */ +0x00000000, /* var[2] */ +0x00000000, /* var[3] */ +0x00000000, /* var[4] */ +0x00000000, /* var[5] */ +0x00000000, /* var[6] */ +0x00000000, /* var[7] */ +0x00000008, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0x00000000, /* inc[3] */ +0xe0000000, /* inc[4] */ +0xc000ffff, /* inc[5] */ +0x4000ffff, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task12(TASK_GEN_TX_BD): Start of VarTab -> 0xf0008d00 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* var[10] */ +0x00000000, /* var[11] */ +0x40000004, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa0000008, /* inc[3] */ +0x20000000, /* inc[4] */ +0x4000ffff, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task13(TASK_GEN_RX_BD): Start of VarTab -> 0xf0008d80 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xa0000008, /* inc[2] */ +0x20000000, /* inc[3] */ +0x00000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task14(TASK_GEN_DP_BD_0): Start of VarTab -> 0xf0008e00 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa000000c, /* inc[3] */ +0x20000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ +/* Task15(TASK_GEN_DP_BD_1): Start of VarTab -> 0xf0008e80 */ +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] */ +0x40000000, /* var[9] */ +0x7fff7fff, /* 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] */ +0x40000000, /* inc[0] */ +0xe0000000, /* inc[1] */ +0xe0000000, /* inc[2] */ +0xa000000c, /* inc[3] */ +0x20000000, /* inc[4] */ +0x00000000, /* inc[5] */ +0x00000000, /* inc[6] */ +0x00000000, /* inc[7] */ + +/* Task0(TASK_PCI_TX): Start of FDT -> 0xf0008f00 */ +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +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, /* load_acc(), EU# 3 */ +0x80045670, /* unload_acc(), EU# 3 */ +0x21800000, /* and(), EU# 3 */ +0x21e00000, /* or(), EU# 3 */ +0x21500000, /* xor(), EU# 3 */ +0x21400000, /* andn(), EU# 3 */ +0x21500000, /* not(), EU# 3 */ +0x20400000, /* add(), EU# 3 */ +0x20500000, /* sub(), EU# 3 */ +0x20800000, /* lsh(), EU# 3 */ +0x20a00000, /* rsh(), EU# 3 */ +0xc0170000, /* crc8(), EU# 3 */ +0xc0145670, /* crc16(), EU# 3 */ +0xc0345670, /* crc32(), EU# 3 */ +0xa0076540, /* endian32(), EU# 3 */ +0xa0000760, /* endian16(), EU# 3 */ + +/* Task0(TASK_PCI_TX): Start of CSave -> 0xf0009000 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task1(TASK_PCI_RX): Start of CSave -> 0xf0009050 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task2(TASK_FEC_TX): Start of CSave -> 0xf00090a0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task3(TASK_FEC_RX): Start of CSave -> 0xf00090f0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task4(TASK_LPC): Start of CSave -> 0xf0009140 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task5(TASK_ATA): Start of CSave -> 0xf0009190 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task6(TASK_CRC16_DP_0): Start of CSave -> 0xf00091e0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task7(TASK_CRC16_DP_1): Start of CSave -> 0xf0009230 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task8(TASK_GEN_DP_0): Start of CSave -> 0xf0009280 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task9(TASK_GEN_DP_1): Start of CSave -> 0xf00092d0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task10(TASK_GEN_DP_2): Start of CSave -> 0xf0009320 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task11(TASK_GEN_DP_3): Start of CSave -> 0xf0009370 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task12(TASK_GEN_TX_BD): Start of CSave -> 0xf00093c0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task13(TASK_GEN_RX_BD): Start of CSave -> 0xf0009410 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task14(TASK_GEN_DP_BD_0): Start of CSave -> 0xf0009460 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Task15(TASK_GEN_DP_BD_1): Start of CSave -> 0xf00094b0 */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +0x00000000, /* reserve */ +/* Start of free code space -> f0009500 */ + +}; diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/mgt5200.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/mgt5200.h new file mode 100644 index 0000000000..c23a9268fd --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/mgt5200.h @@ -0,0 +1,67 @@ +#ifndef __MGT5200_MGT5200_H +#define __MGT5200_MGT5200_H + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +#define MBAR_CS 0x0000 +#define MBAR_SDRAM 0x0100 +#define MBAR_CDM 0x0200 +#define MBAR_LPC 0x0300 +#define MBAR_SCTMR 0x0400 +#define MBAR_INT_CTRL 0x0500 +#define MBAR_GPTIMER 0x0600 +#define MBAR_SLTIMER 0x0700 +#define MBAR_RTCLOCK 0x0800 +#define MBAR_MSCAN 0x0900 +#define MBAR_GPIO_STD 0x0B00 +#define MBAR_GPIO_WKUP 0x0C00 +#define MBAR_XCPCI 0x0D00 +#define MBAR_SPI 0x0F00 +#define MBAR_USB 0x1000 +#define MBAR_SDMA 0x1200 +#define MBAR_BDLC 0x1300 +#define MBAR_IR 0x1400 +#define MBAR_XLB_ARB 0x1F00 +#define MBAR_PSC1 0x2000 +#define MBAR_PSC2 0x2200 +#define MBAR_PSC3 0x2400 +#define MBAR_PSC4 0x2600 +#define MBAR_PSC5 0x2800 +#define MBAR_PSC6 0x2C00 +#define MBAR_IRDA 0x2C00 +#define MBAR_ETHERNET 0x3000 +#define MBAR_SCPCI 0x3800 +#define MBAR_ATA 0x3A00 +#define MBAR_SCLPC 0x3C00 +#define MBAR_I2C 0x3D00 +#define MBAR_SRAM 0x8000 + +#endif /* __MGT5200_MGT5200_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/sdma.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/sdma.h new file mode 100644 index 0000000000..2412160cca --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/include/mgt5200/sdma.h @@ -0,0 +1,159 @@ +#ifndef __MGT5200_SDMA_H +#define __MGT5200_SDMA_H + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +typedef struct sdma_register_set { + volatile uint32 taskBar; /* MBAR_SDMA + 0x00 sdTpb */ + volatile uint32 currentPointer; /* MBAR_SDMA + 0x04 sdMdeComplex */ + volatile uint32 endPointer; /* MBAR_SDMA + 0x08 sdMdeComplex */ + volatile uint32 variablePointer; /* MBAR_SDMA + 0x0c sdMdeComplex */ + + volatile uint8 IntVect1; /* MBAR_SDMA + 0x10 sdPtd */ + volatile uint8 IntVect2; /* MBAR_SDMA + 0x11 sdPtd */ + volatile uint16 PtdCntrl; /* MBAR_SDMA + 0x12 sdPtd */ + + volatile uint32 IntPend; /* MBAR_SDMA + 0x14 sdPtd */ + volatile uint32 IntMask; /* MBAR_SDMA + 0x18 sdPtd */ + + volatile uint32 TCR01; /* MBAR_SDMA + 0x1c sdPtd */ + volatile uint32 TCR23; /* MBAR_SDMA + 0x20 sdPtd */ + volatile uint32 TCR45; /* MBAR_SDMA + 0x24 sdPtd */ + volatile uint32 TCR67; /* MBAR_SDMA + 0x28 sdPtd */ + volatile uint32 TCR89; /* MBAR_SDMA + 0x2c sdPtd */ + volatile uint32 TCRAB; /* MBAR_SDMA + 0x30 sdPtd */ + volatile uint32 TCRCD; /* MBAR_SDMA + 0x34 sdPtd */ + volatile uint32 TCREF; /* MBAR_SDMA + 0x38 sdPtd */ + + volatile uint8 IPR0; /* MBAR_SDMA + 0x3c sdPtd */ + volatile uint8 IPR1; /* MBAR_SDMA + 0x3d sdPtd */ + volatile uint8 IPR2; /* MBAR_SDMA + 0x3e sdPtd */ + volatile uint8 IPR3; /* MBAR_SDMA + 0x3f sdPtd */ + volatile uint8 IPR4; /* MBAR_SDMA + 0x40 sdPtd */ + volatile uint8 IPR5; /* MBAR_SDMA + 0x41 sdPtd */ + volatile uint8 IPR6; /* MBAR_SDMA + 0x42 sdPtd */ + volatile uint8 IPR7; /* MBAR_SDMA + 0x43 sdPtd */ + volatile uint8 IPR8; /* MBAR_SDMA + 0x44 sdPtd */ + volatile uint8 IPR9; /* MBAR_SDMA + 0x45 sdPtd */ + volatile uint8 IPR10; /* MBAR_SDMA + 0x46 sdPtd */ + volatile uint8 IPR11; /* MBAR_SDMA + 0x47 sdPtd */ + volatile uint8 IPR12; /* MBAR_SDMA + 0x48 sdPtd */ + volatile uint8 IPR13; /* MBAR_SDMA + 0x49 sdPtd */ + volatile uint8 IPR14; /* MBAR_SDMA + 0x4a sdPtd */ + volatile uint8 IPR15; /* MBAR_SDMA + 0x4b sdPtd */ + volatile uint8 IPR16; /* MBAR_SDMA + 0x4c sdPtd */ + volatile uint8 IPR17; /* MBAR_SDMA + 0x4d sdPtd */ + volatile uint8 IPR18; /* MBAR_SDMA + 0x4e sdPtd */ + volatile uint8 IPR19; /* MBAR_SDMA + 0x4f sdPtd */ + volatile uint8 IPR20; /* MBAR_SDMA + 0x50 sdPtd */ + volatile uint8 IPR21; /* MBAR_SDMA + 0x51 sdPtd */ + volatile uint8 IPR22; /* MBAR_SDMA + 0x52 sdPtd */ + volatile uint8 IPR23; /* MBAR_SDMA + 0x53 sdPtd */ + volatile uint8 IPR24; /* MBAR_SDMA + 0x54 sdPtd */ + volatile uint8 IPR25; /* MBAR_SDMA + 0x55 sdPtd */ + volatile uint8 IPR26; /* MBAR_SDMA + 0x56 sdPtd */ + volatile uint8 IPR27; /* MBAR_SDMA + 0x57 sdPtd */ + volatile uint8 IPR28; /* MBAR_SDMA + 0x58 sdPtd */ + volatile uint8 IPR29; /* MBAR_SDMA + 0x59 sdPtd */ + volatile uint8 IPR30; /* MBAR_SDMA + 0x5a sdPtd */ + volatile uint8 IPR31; /* MBAR_SDMA + 0x5b sdPtd */ + + volatile uint32 cReqSelect; /* MBAR_SDMA + 0x5c sdPtd */ + volatile uint32 taskSize0; /* MBAR_SDMA + 0x60 sdPtd */ + volatile uint32 taskSize1; /* MBAR_SDMA + 0x64 sdPtd */ + volatile uint32 MDEDebug; /* MBAR_SDMA + 0x68 sdMdeComplex */ + volatile uint32 ADSDebug; /* MBAR_SDMA + 0x6c sdAdsTop */ + volatile uint32 Value1; /* MBAR_SDMA + 0x70 sdDbg */ + volatile uint32 Value2; /* MBAR_SDMA + 0x74 sdDbg */ + volatile uint32 Control; /* MBAR_SDMA + 0x78 sdDbg */ + volatile uint32 Status; /* MBAR_SDMA + 0x7c sdDbg */ + volatile uint32 PTDDebug; /* MBAR_SDMA + 0x80 sdPtd */ +} sdma_regs; + +#define SDMA_PTDCNTRL_TI 0x8000 +#define SDMA_PTDCNTRL_TEA 0x4000 +#define SDMA_PTDCNTRL_HE 0x2000 +#define SDMA_PTDCNTRL_PE 0x0001 + +#define SDMA_CREQSELECT_REQ31_MASK (~0xC0000000UL) +#define SDMA_CREQSELECT_REQ30_MASK (~0x30000000UL) +#define SDMA_CREQSELECT_REQ29_MASK (~0x0C000000UL) +#define SDMA_CREQSELECT_REQ28_MASK (~0x03000000UL) +#define SDMA_CREQSELECT_REQ27_MASK (~0x00C00000UL) +#define SDMA_CREQSELECT_REQ26_MASK (~0x00300000UL) +#define SDMA_CREQSELECT_REQ25_MASK (~0x000C0000UL) +#define SDMA_CREQSELECT_REQ24_MASK (~0x00030000UL) +#define SDMA_CREQSELECT_REQ23_MASK (~0x0000C000UL) +#define SDMA_CREQSELECT_REQ22_MASK (~0x00003000UL) +#define SDMA_CREQSELECT_REQ21_MASK (~0x00000C00UL) +#define SDMA_CREQSELECT_REQ20_MASK (~0x00000300UL) +#define SDMA_CREQSELECT_REQ19_MASK (~0x000000C0UL) +#define SDMA_CREQSELECT_REQ18_MASK (~0x00000030UL) +#define SDMA_CREQSELECT_REQ17_MASK (~0x0000000CUL) +#define SDMA_CREQSELECT_REQ16_MASK (~0x00000003UL) + +#define SDMA_CREQSELECT_REQ31_ALWAYS31 0xC0000000UL +#define SDMA_CREQSELECT_REQ30_ALWAYS30 0x30000000UL +#define SDMA_CREQSELECT_REQ29_ALWAYS29 0x0C000000UL +#define SDMA_CREQSELECT_REQ28_ALWAYS28 0x03000000UL +#define SDMA_CREQSELECT_REQ27_ALWAYS27 0x00C00000UL +#define SDMA_CREQSELECT_REQ26_ALWAYS26 0x00300000UL +#define SDMA_CREQSELECT_REQ25_ALWAYS25 0x000C0000UL +#define SDMA_CREQSELECT_REQ24_ALWAYS24 0x00030000UL +#define SDMA_CREQSELECT_REQ23_ALWAYS23 0x0000C000UL +#define SDMA_CREQSELECT_REQ22_ALWAYS22 0x00003000UL +#define SDMA_CREQSELECT_REQ21_ALWAYS21 0x00000C00UL +#define SDMA_CREQSELECT_REQ20_ALWAYS20 0x00000300UL +#define SDMA_CREQSELECT_REQ19_ALWAYS19 0x000000C0UL +#define SDMA_CREQSELECT_REQ18_ALWAYS18 0x00000030UL +#define SDMA_CREQSELECT_REQ17_ALWAYS17 0x0000000CUL +#define SDMA_CREQSELECT_REQ16_ALWAYS16 0x00000003UL + +#define SDMA_CREQSELECT_REQ31_SCTIMER7 0x00000000UL +#define SDMA_CREQSELECT_REQ30_SCTIMER6 0x00000000UL +#define SDMA_CREQSELECT_REQ29_SCTIMER5 0x00000000UL +#define SDMA_CREQSELECT_REQ28_SCTIMER4 0x00000000UL +#define SDMA_CREQSELECT_REQ27_SCTIMER3 0x00000000UL +#define SDMA_CREQSELECT_REQ26_PSC6_TX 0x00000000UL +#define SDMA_CREQSELECT_REQ25_PSC6_RX 0x00000000UL +#define SDMA_CREQSELECT_REQ24_I2C1_TX 0x00000000UL +#define SDMA_CREQSELECT_REQ23_I2C1_RX 0x00000000UL +#define SDMA_CREQSELECT_REQ22_I2C2_TX 0x00000000UL +#define SDMA_CREQSELECT_REQ21_I2C2_RX 0x00000000UL +#define SDMA_CREQSELECT_REQ20_PSC4_TX 0x00000000UL +#define SDMA_CREQSELECT_REQ19_PSC4_RX 0x00000000UL +#define SDMA_CREQSELECT_REQ18_PSC5_TX 0x00000000UL +#define SDMA_CREQSELECT_REQ17_PSC5_RX 0x00000000UL +#define SDMA_CREQSELECT_REQ16_LP 0x00000000UL + +#define SDMA_CREQSELECT_ALWAYS30 0xC0000000UL + +#endif /* __MGT5200_SDMA_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/load_task.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/load_task.c new file mode 100644 index 0000000000..839ade604d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/load_task.c @@ -0,0 +1,92 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +#ifdef MPC5200_BAPI_LIBC_HEADERS +#include <string.h> +#endif + +#include "../bestcomm/include/ppctypes.h" +#include "../bestcomm/include/mgt5200/sdma.h" +#include "../bestcomm/include/mgt5200/mgt5200.h" + +#include "../bestcomm/dma_image.h" +#include "../bestcomm/bestcomm_api.h" + +#ifdef __MWERKS__ +__declspec(section ".text") extern const uint32 taskTable; +__declspec(section ".text") extern const uint32 taskTableBytes; +__declspec(section ".text") extern const uint32 taskTableTasks; +__declspec(section ".text") extern const uint32 offsetEntry; +#else +extern const uint32 taskTable; +extern const uint32 taskTableBytes; +extern const uint32 taskTableTasks; +extern const uint32 offsetEntry; +#endif + +typedef struct SCTDT { + uint32 start; + uint32 stop; + uint32 var; + uint32 fdt; + uint32 rsvd1; + uint32 rsvd2; + uint32 context; + uint32 litbase; +} SCTDT_T; + + +/*! + * \brief Load BestComm tasks into SRAM. + * \param sdma Base address of the BestComm register set + * + * The BestComm tasks must be loaded before any task can be setup, + * enabled, etc. This might be called as part of a boot sequence before + * any BestComm drivers are required. + */ +void TasksLoadImage(sdma_regs *sdma) +{ + uint32 i; + SCTDT_T *tt; + + /* copy task table from source to destination */ + memcpy((void *)((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal), (void *) &taskTable, (unsigned long) taskTableBytes); + /* adjust addresses in task table */ + for (i=0; i < (uint32) taskTableTasks; i++) { + tt = (SCTDT_T *)(((uint8 *)(sdma->taskBar) - MBarPhysOffsetGlobal) + (uint32) offsetEntry + (i * sizeof (SCTDT_T))); + tt->start += sdma->taskBar; + tt->stop += sdma->taskBar; + tt->var += sdma->taskBar; + tt->fdt = (sdma->taskBar & 0xFFFFFF00) + tt->fdt; + tt->context += sdma->taskBar; + } + + SramOffsetGlobal = taskTableBytes; +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_api_mem.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_api_mem.h new file mode 100644 index 0000000000..3865780d90 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_api_mem.h @@ -0,0 +1,73 @@ +#ifndef __TASK_API_BESTCOMM_API_MEM_H +#define __TASK_API_BESTCOMM_API_MEM_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +#include "../include/mgt5200/mgt5200.h" + +/* + * An extern global variable is used here for the MBAR since it must + * be passed into the API for processes that use virtual memory. + */ +extern uint8 *MBarGlobal; + +#define SDMA_TASK_BAR (MBarGlobal+MBAR_SDMA+0x000) +#define SDMA_INT_PEND (MBarGlobal+MBAR_SDMA+0x014) +#define SDMA_INT_MASK (MBarGlobal+MBAR_SDMA+0x018) +#define SDMA_TCR (MBarGlobal+MBAR_SDMA+0x01C) +#define SDMA_TASK_SIZE (MBarGlobal+MBAR_SDMA+0x060) + +#define PCI_TX_PKT_SIZE (MBarGlobal+MBAR_SCPCI+0x000) +#define PCI_TX_NTBIT (MBarGlobal+MBAR_SCPCI+0x01C) +#define PCI_TX_FIFO (MBarGlobal+MBAR_SCPCI+0x040) +#define PCI_TX_FIFO_STAT (MBarGlobal+MBAR_SCPCI+0x045) +#define PCI_TX_FIFO_GRAN (MBarGlobal+MBAR_SCPCI+0x048) +#define PCI_TX_FIFO_ALARM (MBarGlobal+MBAR_SCPCI+0x04E) + +#define PCI_RX_PKT_SIZE (MBarGlobal+MBAR_SCPCI+0x080) +#define PCI_RX_NTBIT (MBarGlobal+MBAR_SCPCI+0x09C) +#define PCI_RX_FIFO (MBarGlobal+MBAR_SCPCI+0x0C0) +#define PCI_RX_FIFO_STAT (MBarGlobal+MBAR_SCPCI+0x0C5) +#define PCI_RX_FIFO_GRAN (MBarGlobal+MBAR_SCPCI+0x0C8) +#define PCI_RX_FIFO_ALARM (MBarGlobal+MBAR_SCPCI+0x0CE) + + +#define FEC_RX_FIFO (MBarGlobal+MBAR_ETHERNET+0x184) +#define FEC_RX_FIFO_STAT (MBarGlobal+MBAR_ETHERNET+0x188) +#define FEC_RX_FIFO_GRAN (MBarGlobal+MBAR_ETHERNET+0x18C) +#define FEC_RX_FIFO_ALARM (MBarGlobal+MBAR_ETHERNET+0x198) + +#define FEC_TX_FIFO (MBarGlobal+MBAR_ETHERNET+0x1A4) +#define FEC_TX_FIFO_STAT (MBarGlobal+MBAR_ETHERNET+0x1A8) +#define FEC_TX_FIFO_GRAN (MBarGlobal+MBAR_ETHERNET+0x1AC) +#define FEC_TX_FIFO_ALARM (MBarGlobal+MBAR_ETHERNET+0x1B8) + +#endif /* __TASK_API_BESTCOMM_API_MEM_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_cntrl.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_cntrl.h new file mode 100644 index 0000000000..9aeba6f758 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/bestcomm_cntrl.h @@ -0,0 +1,280 @@ +#ifndef __TASK_API_BESTCOMM_CNTRL_H +#define __TASK_API_BESTCOMM_CNTRL_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/******************************************************************************* + * Defines to control SmartDMA and its tasks. These defines are used for the + * task build process to minimize disconnects at the task/driver interface. + ******************************************************************************/ + +#define SDMA_INT_BIT_DBG 31 /* debug interrupt bit */ +#define SDMA_INT_BIT_TEA 28 /* TEA interrupt bit */ +#define SDMA_INT_BIT_TEA_TASK 24 /* lsb for TEA task number */ +#define SDMA_INT_BIT_IMPL 0x9000FFFF + +#define SDMA_PTDCTRL_BIT_TEA 14 /* TEA detection enable bit */ + +#define SDMA_TCR_BIT_AUTO 15 /* auto start bit */ +#define SDMA_TCR_BIT_HOLD 5 /* hold initiator bit */ + +#define SDMA_STAT_BIT_ALARM 17 +#define SDMA_FIFO_ALARM_MASK 0x0020000 + +#define SDMA_DRD_BIT_TFD 27 /* mark last buffer of frame */ +#define SDMA_DRD_BIT_INT 26 /* interrupt after buffer processed */ +#define SDMA_DRD_BIT_INIT 21 /* lsb position of initiator */ +#define SDMA_DRD_MASK_FLAGS 0x0C000000 /* BD_FLAGS flag bits */ +#define SDMA_DRD_MASK_LENGTH 0x03FFFFFF /* BD_FLAGS length mask */ +#define SDMA_BD_BIT_READY 30 /* Status BD ready bit */ +#ifdef SAS_COMPILE + #define SDMA_BD_MASK_READY constant(1<<SDMA_BD_BIT_READY) +#else + #define SDMA_BD_MASK_READY (1<<SDMA_BD_BIT_READY) +#endif +#define SDMA_BD_MASK_SIGN 0x7FFFFFFF /* task code needs Status>0 */ + +#define SDMA_PRAGMA_BIT_RSV 7 /* reserved pragma bit */ +#define SDMA_PRAGMA_BIT_PRECISE_INC 6 /* increment 0=when possible, 1=iter end */ +#define SDMA_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on task enable */ +#define SDMA_PRAGMA_BIT_PACK 4 /* pack data enable */ +#define SDMA_PRAGMA_BIT_INTEGER 3 /* data alignment 0=frac(msb), 1=int(lsb) */ +#define SDMA_PRAGMA_BIT_SPECREAD 2 /* XLB speculative read enable */ +#define SDMA_PRAGMA_BIT_CW 1 /* write line buffer enable */ +#define SDMA_PRAGMA_BIT_RL 0 /* read line buffer enable */ + +#define SDMA_TASK_ENTRY_BYTES 32 /* Bytes per task in entry table */ +#define SDMA_TASK_GROUP_NUM 16 /* Number of tasks per task group */ +#define SDMA_TASK_GROUP_BYTES (SDMA_TASK_ENTRY_BYTES*SDMA_TASK_GROUP_NUM) + + +/******************************************************************************* + * Task group control macros, use when TaskNum > 15 + ******************************************************************************/ +#define SDMA_TASKNUM_EXT(OldTaskNum) (OldTaskNum%16) + +#define SDMA_TASKBAR_CHANGE(sdma, OldTaskNum) { \ + sdma->taskBar += (((int)(OldTaskNum/SDMA_TASK_GROUP_NUM))*SDMA_TASK_GROUP_BYTES); \ +} + +#define SDMA_TASKBAR_RESTORE(sdma, OldTaskNum) { \ + sdma->taskBar -= (((int)(OldTaskNum/SDMA_TASK_GROUP_NUM))*SDMA_TASK_GROUP_BYTES); \ +} + + +/******************************************************************************* + * Task control macros + ******************************************************************************/ +#define SDMA_TASK_CFG(RegAddr, TaskNum, AutoStart, AutoStartNum) { \ + *(((uint16 *)RegAddr)+TaskNum) = (uint16)(0x0000 | \ + ((AutoStart!=0)<<7) | \ + (AutoStartNum&0xF) ); \ +} + +#define SDMA_TASK_AUTO_START(RegAddr, TaskNum, AutoStart, AutoStartNum) { \ + *(((uint16 *)RegAddr)+TaskNum) = (uint16)((*(((uint16 *)RegAddr)+TaskNum) & \ + (uint16) 0xff30) | ((uint16)(0x0000 | \ + ((AutoStart!=0)<<7) | \ + (AutoStartNum&0xF)) )); \ +} + +#define SDMA_TASK_ENABLE(RegAddr, TaskNum) { \ + *(((uint16 *)RegAddr)+TaskNum) |= (uint16)0x8000; \ +} + +#define SDMA_TASK_DISABLE(RegAddr, TaskNum) { \ + *(((uint16 *)RegAddr)+TaskNum) &= ~(uint16)0x8000; \ +} + +#define SDMA_TASK_STATUS(RegAddr, TaskNum) \ + *(((uint16 *)RegAddr)+TaskNum) + + +/******************************************************************************* + * Interrupt control macros + ******************************************************************************/ +#define SDMA_INT_ENABLE(RegAddr, Bit) { \ + *((uint32 *)RegAddr) &= ~((uint32)(1<<Bit)); \ +} + +#define SDMA_INT_DISABLE(RegAddr, Bit) { \ + *((uint32 *)(RegAddr)) |= ((uint32)(1<<Bit)); \ +} + +#define SDMA_INT_SOURCE(RegPend, RegMask) \ + (*((uint32 *)(RegPend)) & (~*((uint32 *)(RegMask))) & (uint32)SDMA_INT_BIT_IMPL) + +#define SDMA_INT_PENDING(RegPend, RegMask) \ + (*((uint32 *)(RegPend)) & (~*((uint32 *)(RegMask)))) + +#define SDMA_INT_TEST(IntSource, Bit) \ + (((uint32)IntSource) & ((uint32)(1<<Bit))) + +/* + * define SDMA_INT_FIND to get int bit rather than scan all bits use + * cntlzw + */ + +/* Clear the IntPend bit */ +#define SDMA_CLEAR_IEVENT(RegAddr, Bit) { \ + *((uint32 *)RegAddr) = ((uint32)(1<<Bit)); \ +} + +#define SDMA_GET_PENDINGBIT(sdma, Bit) \ + (sdma->IntPend & (uint32)(1<<Bit)) + +#define SDMA_GET_MASKBIT(sdma, Bit) \ + (sdma->IntMask & (uint32)(1<<Bit)) + + +/******************************************************************************* + * SmartDMA FIFO control macros + ******************************************************************************/ + +/******************************************************************************* + * SmartDMA TEA detection control macros + ******************************************************************************/ +/* Enable SmartDMA TEA detection and TEA interrupt */ +#define SDMA_TEA_ENABLE(sdma) { \ + SDMA_INT_ENABLE(sdma, SDMA_INT_BIT_TEA); \ + sdma->PtdCntrl &= ~((uint32)(1<<SDMA_PTDCTRL_BIT_TEA)); \ +} + +/* Disable SmartDMA TEA detection and TEA interrupt */ +#define SDMA_TEA_DISABLE(sdma) { \ + SDMA_INT_DISABLE(sdma, SDMA_INT_BIT_TEA); \ + sdma->PtdCntrl |= ((uint32)(1<<SDMA_PTDCTRL_BIT_TEA)); \ +} + +/* Clear the TEA interrupt */ +#define SDMA_TEA_CLEAR(sdma) { \ + sdma->IntPend = ((uint32)(0x1F<<SDMA_INT_BIT_TEA_TASK)); \ +} + +/* Determine which task caused a TEA on the XLB */ +#define SDMA_TEA_SOURCE(RegPend) \ + (uint32)(((*(uint32 *)RegPend)>>SDMA_INT_BIT_TEA_TASK) & 0xF) + + +/******************************************************************************* + * SmartDMA debug control macros + ******************************************************************************/ +/* Enable the SmartDMA debug unit and DBG interrupt */ +/* add sdma->dbg_regs setup? */ +#define SDMA_DBG_ENABLE(sdma) { \ + SDMA_INT_ENABLE(sdma, SDMA_INT_BIT_DBG); \ +} + +#define SDMA_DBG_DISABLE(sdma) { \ + SDMA_INT_DISABLE(sdma, SDMA_INT_BIT_DBG); \ +} + +/* Clear the debug interrupt */ +#define SDMA_DBG_CLEAR(sdma) { \ + SDMA_CLEAR_IEVENT(sdma, SDMA_INT_BIT_DBG); \ +} + +#define SDMA_DBG_MDE(dst, sdma, addr) { \ + sdma->MDEDebug = addr; \ + dst = sdma->MDEDebug; \ +} + +#define SDMA_DBG_ADS(dst, sdma, addr) { \ + sdma->ADSDebug = addr; \ + dst = sdma->ADSDebug; \ +} + +#define SDMA_DBG_PTD(dst, sdma, addr) { \ + sdma->PTDDebug = addr; \ + dst = sdma->PTDDebug; \ +} + + +/******************************************************************************* + * Initiator control macros + ******************************************************************************/ + +/* This macro may not work, getting compile errors */ +/* Set the Transfer Size */ +/* Note that masking the size w/ 0x3 gives the desired value for uint32 */ +/* (expressed as 4), namely 0. */ +#define SDMA_SET_SIZE(RegAddr, TaskNum, SrcSize, DstSize) \ + *(((uint8 *)RegAddr)+((uint32)(TaskNum/2))) = \ + (uint8)((*(((uint8 *)RegAddr)+((uint32)(TaskNum/2))) & \ + ((TaskNum%2) ? 0xf0 : 0x0f)) | \ + ((uint8)(((SrcSize & 0x3)<<2) | \ + ( DstSize & 0x3 ) ) <<(4*((int)(1-(TaskNum%2)))))); + +/* This macro may not work */ +/* Set the Initiator in TCR */ +#define SDMA_SET_INIT(RegAddr, TaskNum, Initiator) \ +{ \ + *(((uint16 *)RegAddr)+TaskNum) &= (uint16)0xE0FF; \ + *(((uint16 *)RegAddr)+TaskNum) |= (((0x01F & Initiator)<<8) | \ + (0<<SDMA_TCR_BIT_HOLD)); \ +} + +/* Change DRD initiator number */ +#define SDMA_INIT_CHANGE(task, oldInitiator, newInitiator) { \ + int i; \ + for (i=0; i<task->NumDRD; i++) { \ + if (SDMA_INIT_READ(task->DRD[i]) == (uint32)oldInitiator) { \ + SDMA_INIT_WRITE(task->DRD[i],newInitiator); \ + } \ + } \ +} + +/* Set the Initiator Priority */ +#define SDMA_SET_INITIATOR_PRIORITY(sdma, initiator, priority) \ + *(((uint8 *)&sdma->IPR0)+initiator) = priority; + + +/* Read DRD initiator number */ +#define SDMA_INIT_READ(PtrDRD) \ + (((*(uint32 *)PtrDRD)>>SDMA_DRD_BIT_INIT) & (uint32)0x1F) + +/* Write DRD initiator number */ +#define SDMA_INIT_WRITE(PtrDRD, Initiator) { \ + *(uint32 *)PtrDRD = ((*(uint32 *)PtrDRD) & 0xFC1FFFFF) | \ + (Initiator<<SDMA_DRD_BIT_INIT); \ +} + +/* Change DRD initiator number */ +#define SDMA_INIT_CHANGE(task, oldInitiator, newInitiator) { \ + int i; \ + for (i=0; i<task->NumDRD; i++) { \ + if (SDMA_INIT_READ(task->DRD[i]) == (uint32)oldInitiator) { \ + SDMA_INIT_WRITE(task->DRD[i],newInitiator); \ + } \ + } \ +} + +#endif /* __TASK_API_BESTCOMM_CNTRL_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_bdtable.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_bdtable.h new file mode 100644 index 0000000000..0d09f8da87 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_bdtable.h @@ -0,0 +1,92 @@ +#ifndef __TASK_API_TASKSETUP_BDTABLE_H +#define __TASK_API_TASKSETUP_BDTABLE_H 1 + +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/* + * Table of BD rings for all BestComm tasks indexed by task ID. + * + * +-----+------+--------------+ +------+-------+ + * 0: |numBD|numPtr|BDTablePtr ---|--->|status|dataPtr| + * +-----+------+--------------+ +------+-------+ + * 1: |numBD|numPtr|BDTablePtr | |status|dataPtr| + * +-----+------+--------------+ . . . + * 2: |numBD|numPtr|BDTablePtr ---|-+ . . . + * . . . | . . . + * . . . | |status|dataPtr| + * . . . | +------+-------+ + * 15:|numBD|numPtr|BDTablePtr | | + * +-----+------+--------------+ | + * | + * V + * +------+--------+--------+ + * |status|dataPtr0|dataPtr1| + * +------+--------+--------+ + * |status|dataPtr0|dataPtr1| + * . . . . + * . . . . + * . . . . + * |status|dataPtr0|dataPtr1| + * +------+--------+--------+ + */ +typedef struct { + uint16 numBD; /* Size of BD ring */ + uint8 numPtr; /* Number of data buffer pointers per BD */ + uint8 apiConfig; /* API configuration flags */ + void *BDTablePtr; /* Pointer to BD tables, must be cast to TaskBD1_t */ + /* or TaskBD2_t */ + volatile uint32 + *BDStartPtr; /* Task's current BD pointer. This pointer is + * used to set a task's BD pointer upon startup. + * It is only valid for BD tasks and only after + * TaskSetup() or TaskBDReset() are called. You + * cannot use this to track a task's BD pointer. + */ + uint16 currBDInUse; /* Current number of buffer descriptors assigned but*/ + /* not released yet. */ +} TaskBDIdxTable_t; + +typedef enum { + API_CONFIG_NONE = 0x00, + API_CONFIG_BD_FLAG = 0x01 +} ApiConfig_t; + +/* + * Allocates BD table if needed and updates the BD index table. + * Do we want to hide this from the C API since it operates on task API? + */ +void TaskSetup_BDTable(volatile uint32 *BasePtr, + volatile uint32 *LastPtr, + volatile uint32 *StartPtr, + int TaskNum, uint32 NumBD, uint16 MaxBD, + uint8 NumPtr, ApiConfig_t ApiConfig, uint32 Status ); + +#endif /* __TASK_API_TASKSETUP_BDTABLE_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_general.h b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_general.h new file mode 100644 index 0000000000..f3b29a0e78 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/task_api/tasksetup_general.h @@ -0,0 +1,628 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +/* + * Task builder generates a set #defines per configured task to + * condition this templete file. + */ + +/********************************************************** + * + * Required #defines: + * ------------------ + * TASKSETUP_NAME: + * TaskSetup function name, set to TaskSetup_<TASK_NAME> + * TASK_API: + * task API defined in dma_image.h + * MAX_BD: + * <=0 : non-BD task + * else: number of BD in BD table + * BD_FLAG: + * 0 : no flag implemented for BD + * else: flags can be passed on a per BD basis + * MISALIGNED: + * 0 : task API supports Bytes%IncrBytes==0 + * else: task API supports any parameter settings + * AUTO_START: + * <-1 : do not start a task after task completion + * -1 : auto start the task after task completion + * <MAX_TASKS: auto start task with the TaskID = AUTO_START + * else : do not start a task after task completion + * INITIATOR_DATA: + * <0 : runtime configurable + * else: assume INITATOR_DATA equal hard-coded task initiator + * TYPE_SRC: (needs to be consistent with Task API) + * FLEX_T : Task API TYPE_SRC = flex, SzSrc defines size + * UINT8_T : Task API TYPE_SRC = char + * UINT16_T: Task API TASK_SRC = short + * UINT32_T: Task API TASK_SRC = int + * INCR_TYPE_SRC: + * 0 : FIFO address, do not implement data pointer + * 1 : automatic, set INCR_SRC based on SzSrc parameter + * 2 : runtime, set INCR_SRC to IncrSrc parameter + * else: used hard-coded INCR_SRC + * INCR_SRC: + * INCR_TYPE_SRC=0: force INCR_SRC=0 + * else : use for src pointer increment + * TYPE_DST: (needs to be consistent with Task API) + * FLEX_T : Task API TYPE_DST = flex, SzDst defines size + * UINT8_T : Task API TYPE_DST = char + * UINT16_T: Task API TASK_DST = short + * UINT32_T: Task API TASK_DST = int + * INCR_TYPE_DST: + * 0 : FIFO address, do not implement data pointer + * 1 : automatic, set INCR_DST based on SzDst parameter + * 2 : runtime, set INCR_DST to IncrDst parameter + * else: used hard-coded INCR_DST + * INCR_DST: + * INCR_TYPE_DST=0: force INCR_DST=0 + * else : use for dst pointer increment + * PRECISE_INCREMENT: + * 0 : increment when possible + * else: increment at end of iteration + * NO_ERROR_RESET: + * 0 : reset error flags on task enable + * else: leave error flags unmodified on task enable + * PACK_DATA: + * 0 : do not pack data + * else: pack data based on data type + * INTEGER_MODE: + * 0 : type conversions handle as fixed point numbers + * else: type conversions handle as integers + * WRITE_LINE_BUFFER: + * 0 : do not use write line buffers + * else: enable write line buffers + * READ_LINE_BUFFER: + * 0 : do not use read line buffers + * else: enable read line buffers + * SPEC_READS: + * 0 : do not speculatively read + * else: speculatively read data ahead of DMA engine + * + * Optional #defines: + * ------------------ + * MAX_TASKS: + * 1 : #define MAX_TASKS>0 + * else: 16 + * ITERATIONS: + * 1 : #define ITERATIONS>0 + * else: 1 + * INCR_BYTES: + * This macro is defined based on following priority: + * 1 : INCR_SRC != 0 + * 2 : DST_TYPE != 0 + * 3 : #defined INCR_BYTES<0 + * else: -4 (SZ_UINT32) + * DEBUG_BESTCOMM_API: + * >0 : print basic debug messages + * >=10: also print C-API interface variables + * >=20: also print task API interface variables + * else: do nothing + * + **********************************************************/ + +#ifdef MPC5200_BAPI_LIBC_HEADERS +#include <stdlib.h> +#endif + +#include "../dma_image.h" + +#include "../bestcomm_api.h" +#include "tasksetup_bdtable.h" + +#include "bestcomm_api_mem.h" +#include "bestcomm_cntrl.h" + +#ifndef DEBUG_BESTCOMM_API + #define DEBUG_BESTCOMM_API 0 +#endif + +#ifdef FLEX_T + #undef FLEX_T +#endif +#define FLEX_T SZ_FLEX + +#ifdef UINT8_T + #undef UINT8_T +#endif +#define UINT8_T SZ_UINT8 + +#ifdef UINT16_T + #undef UINT16_T +#endif +#define UINT16_T SZ_UINT16 + +#ifdef UINT32_T + #undef UINT32_T +#endif +#define UINT32_T SZ_UINT32 + +#if (INCR_TYPE_SRC==0) /* FIFO address, no data pointer */ + #undef INCR_SRC + #define INCR_SRC 0 +#endif + +#if (INCR_TYPE_DST==0) /* FIFO address, no data pointer */ + #undef INCR_DST + #define INCR_DST 0 +#endif + +#ifndef MAX_TASKS + #define MAX_TASKS 16 +#else + #if (MAX_TASKS<=0) + #undef MAX_TASKS + #define MAX_TASKS 16 + #endif +#endif + +#ifndef ITERATIONS + #define ITERATIONS 1 +#else + #if (ITERATIONS<=0) + #undef ITERATIONS + #define ITERATIONS 1 + #endif +#endif + +#ifndef INCR_BYTES + #define INCR_BYTES -4 +#else + #if (INCR_BYTES>=0) + #undef INCR_BYTES + #define INCR_BYTES -4 + #endif +#endif + +/* + * These ifndefs will go away when support in task_capi wrappers + * in the image directories + */ +#ifndef PRECISE_INCREMENT + #define PRECISE_INCREMENT 0 /* bit=6 SAS->1, increment 0=when possible, 1=at the end of interation */ +#endif +#ifndef NO_ERROR_RESET + #define NO_ERROR_RESET 0 /* bit=5 SAS->0, do not reset error codes on task enable */ +#endif +#ifndef PACK_DATA + #define PACK_DATA 0 /* bit=4 SAS->0, pack data enable */ +#endif +#ifndef INTEGER_MODE + #define INTEGER_MODE 0 /* bit=3 SAS->0, 0=fractional(msb aligned), 1=integer(lsb aligned) */ +#endif +#ifndef SPEC_READS + #define SPEC_READS 1 /* bit=2 SAS->0, XLB speculative read enable */ +#endif +#ifndef WRITE_LINE_BUFFER + #define WRITE_LINE_BUFFER 1 /* bit=1 SAS->0, write line buffer enable */ +#endif +#ifndef READ_LINE_BUFFER + #define READ_LINE_BUFFER 1 /* bit=0 SAS->0, read line buffer enable */ +#endif +#define SDMA_PRAGMA (0 <<SDMA_PRAGMA_BIT_RSV ) | \ + (PRECISE_INCREMENT<<SDMA_PRAGMA_BIT_PRECISE_INC ) | \ + (NO_ERROR_RESET <<SDMA_PRAGMA_BIT_RST_ERROR_NO) | \ + (PACK_DATA <<SDMA_PRAGMA_BIT_PACK ) | \ + (INTEGER_MODE <<SDMA_PRAGMA_BIT_INTEGER ) | \ + (SPEC_READS <<SDMA_PRAGMA_BIT_SPECREAD ) | \ + (WRITE_LINE_BUFFER<<SDMA_PRAGMA_BIT_CW ) | \ + (READ_LINE_BUFFER <<SDMA_PRAGMA_BIT_RL ) + +#ifndef TASKSETUP_NAME + #define PREPEND_TASKSETUP(name) TaskSetup_ ## name + #define FUNC_PREPEND_TASKSETUP(name) PREPEND_TASKSETUP(name) + #define TASKSETUP_NAME FUNC_PREPEND_TASKSETUP(TASK_BASE) +#endif + +#ifndef TASK_API + #define APPEND_API(name) name ## _api_t + #define FUNC_APPEND_API(name) APPEND_API(name) + #define TASK_API FUNC_APPEND_API(TASK_BASE) +#endif + +#ifndef INIT_DMA_IMAGE + #define PREPEND_INITDMA(name) init_dma_image_ ## name + #define FUNC_PREPEND_INITDMA(name) PREPEND_INITDMA(name) + #define INIT_DMA_IMAGE FUNC_PREPEND_INITDMA(TASK_BASE) +#endif + +#define DRD_INIT_MASK 0xfc1fffff +#define DRD_EXT_FLAG 0x40000000 +#define DRD_INIT_OFFSET 21 + +TaskId TASKSETUP_NAME(TASK_API *TaskAPI, + TaskSetupParamSet_t *TaskSetupParams) +{ + TaskId TaskNum; + uint32 Status = 0; +#if ((INCR_TYPE_SRC!=0)||(INCR_TYPE_DST!=0)||(DEBUG_BESTCOMM_API>0)) + uint8 NumPtr = 0; +#endif +#if (INITIATOR_DATA<0) /* runtime configurable */ + uint32 i, ext; +#endif + + INIT_DMA_IMAGE((uint8 *)(((sdma_regs *)(SDMA_TASK_BAR))->taskBar), MBarPhysOffsetGlobal); + + TaskNum = (TaskId)SDMA_TASKNUM_EXT(TaskAPI->TaskNum); + + TaskRunning[TaskNum] = 0; + +#if (DEBUG_BESTCOMM_API>0) + printf("\nBestComm API Debug Display Mode Enabled\n\n"); + printf("TaskSetup: TaskID=%d\n", TaskNum); + if (Status!=0) { + printf("TaskSetup: Rx task\n"); + } else { + printf("TaskSetup: Tx or DP task\n"); + } +#endif + + /* Set the task pragma settings */ + *(TaskAPI->TaskPragma)= (uint8) SDMA_PRAGMA; + +#if (MAX_BD>0) /* Buffer Descriptors */ + + #if (INCR_TYPE_SRC!=0) + ++NumPtr; + #endif + #if (INCR_TYPE_DST!=0) + ++NumPtr; + #endif + + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Using %d buffer descriptors, each with %d data pointers\n", MAX_BD, NumPtr); + #endif + + /* Allocate BD table SRAM storage, + * and pass addresses to task API */ + + TaskSetup_BDTable(TaskAPI->BDTableBase, + TaskAPI->BDTableLast, + TaskAPI->BDTableStart, + TaskNum, + TaskSetupParams->NumBD, + MAX_BD, NumPtr, + BD_FLAG, Status); + + *TaskAPI->AddrEnable = (uint32)((uint32)(((uint16 *)SDMA_TCR)+TaskNum) + MBarPhysOffsetGlobal); + + #if BD_FLAG + + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Buffer descriptor flags are enabled\n"); + #endif + + /* always assume 2nd to last DRD */ + *((TaskAPI->AddrDRD)) = (uint32)((uint32)TaskAPI->DRD[TaskAPI->AddrDRDIdx] + MBarPhysOffsetGlobal); + #endif /* #if BD_FLAG */ + +#else /* No Buffer Descriptors */ + +/* #error ATA should not be non-BD */ + + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Task will complete %d iterations before disabling\n"); + #endif + + *((TaskAPI->IterExtra)) = (uint32)(ITERATIONS-1); +#endif /* #if (MAX_BD>0) */ + +/* Setup auto start */ +#if (AUTO_START <= -2 ) /* do not start a task */ + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Auto task start disabled\n"); + #endif + SDMA_TASK_CFG(SDMA_TCR, TaskNum, 0, TaskNum); +#elif (AUTO_START <= -1 ) /* restart task */ + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Auto start task\n"); + #endif + SDMA_TASK_CFG(SDMA_TCR, TaskNum, 1, TaskNum); +#elif (AUTO_START < MAX_TASKS) /* start specific task */ + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Auto start task with TaskID=%d\n", AUTO_START); + #endif + SDMA_TASK_CFG(SDMA_TCR, TaskNum, 1, AUTO_START); +#else /* do not start a task */ + #if (DEBUG_BESTCOMM_API>0) + printf("TaskSetup: Auto task start disabled\n"); + #endif + SDMA_TASK_CFG(SDMA_TCR, TaskNum, 0, TaskNum); +#endif + +#if (INITIATOR_DATA<0) /* runtime configurable */ + SDMA_SET_INIT(SDMA_TCR, TaskNum, TaskSetupParams->Initiator); + + /* + * Hard-code the task initiator in the DRD to avoid a problem w/ the + * hold initiator bit in the TCR. + */ + ext = 0; + for (i = 0; i < TaskAPI->NumDRD; i++) { + if (ext == 0) + { +#if (DEBUG_BESTCOMM_API>=10) + printf("TaskSetup: DRD[%d] initiator = %d\n", i, ((*(TaskAPI->DRD[i]) & ~DRD_INIT_MASK) >> DRD_INIT_OFFSET)); +#endif + if (((*(TaskAPI->DRD[i]) & ~DRD_INIT_MASK) >> DRD_INIT_OFFSET) != INITIATOR_ALWAYS) { +#if (DEBUG_BESTCOMM_API>=10) + printf("TaskSetup: Replacing DRD[%d] initiator with %d\n", i, TaskSetupParams->Initiator); +#endif + *(TaskAPI->DRD[i]) = (*(TaskAPI->DRD[i]) & DRD_INIT_MASK) + | (TaskSetupParams->Initiator << DRD_INIT_OFFSET); + } + + if ((*(TaskAPI->DRD[i]) & DRD_EXT_FLAG) != 0) + { + ext = 1; + } + } + else + { + if ((*(TaskAPI->DRD[i]) & DRD_EXT_FLAG) == 0) + { + ext = 0; + } + } + } + +#else /* INITIATOR_DATA >= 0 */ + TaskSetupParams->Initiator = INITIATOR_DATA; +#endif + +#if (DEBUG_BESTCOMM_API>=10) + printf("\nTaskSetup: C-API Parameter Settings Passed to TaskSetup:\n"); + printf("TaskSetup: NumBD = %d\n", TaskSetupParams->NumBD); + #if (MAX_BD>0) + printf("TaskSetup: MaxBuf = %d\n", TaskSetupParams->Size.MaxBuf); + #else + printf("TaskSetup: NumBytes = %d\n", TaskSetupParams->Size.NumBytes); + #endif + printf("TaskSetup: Initiator = %d\n", TaskSetupParams->Initiator); + printf("TaskSetup: StartAddrSrc = 0x%08X\n", TaskSetupParams->StartAddrSrc); + printf("TaskSetup: IncrSrc = %d\n", TaskSetupParams->IncrSrc); + printf("TaskSetup: SzSrc = %d\n", TaskSetupParams->SzSrc); + printf("TaskSetup: StartAddrDst = 0x%08X\n", TaskSetupParams->StartAddrDst); + printf("TaskSetup: IncrDst = %d\n", TaskSetupParams->IncrDst); + printf("TaskSetup: SzDst = %d\n", TaskSetupParams->SzDst); +#endif + +#if (DEBUG_BESTCOMM_API>=20) + printf("\nTaskSetup: Task-API Parameter Settings Before TaskSetup Initialization:\n"); + printf("TaskSetup: TaskNum = %d\n", (TaskAPI->TaskNum)); + printf("TaskSetup: TaskPragma = 0x%02X\n", *((TaskAPI->TaskPragma))); + printf("TaskSetup: TCR = 0x%04x\n", SDMA_TASK_STATUS(SDMA_TCR, TaskNum)); + + #if (MAX_BD>0) + printf("TaskSetup: BDTableBase = 0x%08X\n", *((TaskAPI->BDTableBase))); + printf("TaskSetup: BDTableLast = 0x%08X\n", *((TaskAPI->BDTableLast))); + printf("TaskSetup: BDTableStart = 0x%08X\n", *((TaskAPI->BDTableStart))); + printf("TaskSetup: AddrEnable = 0x%08X\n", *((TaskAPI->AddrEnable))); + #if (INCR_TYPE_SRC==0) + printf("TaskSetup: AddrSrcFIFO = 0x%08X\n", *((TaskAPI->AddrSrcFIFO))); + #endif + #if (INCR_TYPE_DST==0) + printf("TaskSetup: AddrDstFIFO = 0x%08X\n", *((TaskAPI->AddrDstFIFO))); + #endif + #if (BD_FLAG) + printf("TaskSetup: AddrDRD = 0x%08X\n", *((TaskAPI->AddrDRD))); + printf("TaskSetup: AddrDRDIdx = %d\n", ((TaskAPI->AddrDRDIdx))); + #endif + #else + printf("TaskSetup: IterExtra = %d\n", *((TaskAPI->IterExtra))); + #if (INCR_TYPE_SRC==0) + printf("TaskSetup: AddrSrcFIFO = 0x%08X\n", *((TaskAPI->AddrSrcFIFO))); + #else + printf("TaskSetup: StartAddrSrc = 0x%08X\n", *((TaskAPI->StartAddrSrc))); + #endif + #if (INCR_TYPE_DST==0) + printf("TaskSetup: AddrDstFIFO = 0x%08X\n", *((TaskAPI->AddrDstFIFO))); + #else + printf("TaskSetup: StartAddrDst = 0x%08X\n", *((TaskAPI->StartAddrDst))); + #endif + #endif + #if (INCR_TYPE_SRC!=0) + printf("TaskSetup: IncrSrc = 0x%04X\n", *((TaskAPI->IncrSrc))); + #if (MISALIGNED | MISALIGNED_START) + printf("TaskSetup: IncrSrcMA = 0x%04X\n", *((TaskAPI->IncrSrcMA))); + #endif + #endif + #if (INCR_TYPE_DST!=0) + printf("TaskSetup: IncrDst = 0x%04X\n", *((TaskAPI->IncrDst))); + #if (MISALIGNED | MISALIGNED_START) + printf("TaskSetup: IncrDstMA = 0x%04X\n", *((TaskAPI->IncrDstMA))); + #endif + #endif + printf("TaskSetup: Bytes = %d\n", *((TaskAPI->Bytes))); + printf("TaskSetup: IncrBytes = %d\n", *((TaskAPI->IncrBytes))); +#endif + + + *((TaskAPI->Bytes)) = (uint32)TaskSetupParams->Size.MaxBuf; + + +#if (TYPE_SRC!=FLEX_T) /* size fixed in task code */ + TaskSetupParams->SzSrc = TYPE_SRC; +#endif + +#if (INCR_TYPE_SRC==0) /* no data pointer */ + TaskSetupParams->IncrSrc = (sint16)0; + *((TaskAPI->AddrSrcFIFO)) = (uint32)TaskSetupParams->StartAddrSrc; +#else + + #if (INCR_TYPE_SRC==1) /* automatic */ + if (TaskSetupParams->IncrSrc!=0) { + TaskSetupParams->IncrSrc = (sint16)+TaskSetupParams->SzSrc; + } else { + TaskSetupParams->IncrSrc = (sint16)+TaskSetupParams->IncrSrc; + } + #elif (INCR_TYPE_SRC!=2) /* hard-coded */ + TaskSetupParams->IncrSrc = (sint16)INCR_SRC; + #endif + *((TaskAPI->IncrSrc)) = (sint16)TaskSetupParams->IncrSrc; + + #if (MAX_BD>0) /* pointer in BD Table */ + /* pass back address of first BD */ + TaskSetupParams->StartAddrSrc = (uint32)TaskGetBDRing(TaskNum); + #else + *((TaskAPI->StartAddrSrc)) = (uint32)TaskSetupParams->StartAddrSrc; + #endif + + #if MISALIGNED | MISALIGNED_START + if (TaskSetupParams->IncrSrc < 0) { + *((TaskAPI->IncrSrcMA)) = (sint16)-1; + } else if (TaskSetupParams->IncrSrc > 0) { + *((TaskAPI->IncrSrcMA)) = (sint16)+1; + } else { + *((TaskAPI->IncrSrcMA)) = (sint16)0; + } + #endif +#endif + + +#if (TYPE_DST!=FLEX_T) /* size fixed in task code */ + TaskSetupParams->SzDst = TYPE_DST; +#endif + +#if (INCR_TYPE_DST==0) /* no data pointer */ + TaskSetupParams->IncrDst = (sint16)0; + *((TaskAPI->AddrDstFIFO)) = (uint32)TaskSetupParams->StartAddrDst; +#else + #if (INCR_TYPE_DST==1) /* automatic */ + if (TaskSetupParams->IncrDst!=0) { + TaskSetupParams->IncrDst = (sint16)+TaskSetupParams->SzDst; + } else { + TaskSetupParams->IncrDst = (sint16)+TaskSetupParams->IncrDst; + } + #elif (INCR_TYPE_DST!=2) /* hard-coded */ + TaskSetupParams->IncrDst = (sint16)INCR_DST; + #endif + *((TaskAPI->IncrDst)) = (sint16)TaskSetupParams->IncrDst; + + #if (MAX_BD>0) + /* pass back address of first BD */ + TaskSetupParams->StartAddrDst = (uint32)TaskGetBDRing(TaskNum); + #else + *((TaskAPI->StartAddrDst)) = (uint32)TaskSetupParams->StartAddrDst; + #endif + + #if MISALIGNED | MISALIGNED_START + if (TaskSetupParams->IncrDst < 0) { + *((TaskAPI->IncrDstMA)) = (sint16)-1; + } else if (TaskSetupParams->IncrDst > 0) { + *((TaskAPI->IncrDstMA)) = (sint16)+1; + } else { + *((TaskAPI->IncrDstMA)) = (sint16)0; + } + #endif +#endif + +/* always use macro, only affect code with #define TYPE_? flex */ + SDMA_SET_SIZE(SDMA_TASK_SIZE, TaskNum, TaskSetupParams->SzSrc, TaskSetupParams->SzDst); + + + if (TaskSetupParams->IncrSrc != 0) { + *((TaskAPI->IncrBytes)) = (sint16)-abs(TaskSetupParams->IncrSrc); + } else if (TaskSetupParams->IncrDst != 0) { + *((TaskAPI->IncrBytes)) = (sint16)-abs(TaskSetupParams->IncrDst); + } else { + *((TaskAPI->IncrBytes)) = (sint16)-abs(INCR_BYTES); + } + + +#if (DEBUG_BESTCOMM_API>=10) + printf("\nTaskSetup: C-API Parameter Settings Returned from TaskSetup:\n"); + printf("TaskSetup: NumBD = %d\n", TaskSetupParams->NumBD); + #if (MAX_BD>0) + printf("TaskSetup: MaxBuf = %d\n", TaskSetupParams->Size.MaxBuf); + #else + printf("TaskSetup: NumBytes = %d\n", TaskSetupParams->Size.NumBytes); + #endif + printf("TaskSetup: Initiator = %d\n", TaskSetupParams->Initiator); + printf("TaskSetup: StartAddrSrc = 0x%08X\n", TaskSetupParams->StartAddrSrc); + printf("TaskSetup: IncrSrc = %d\n", TaskSetupParams->IncrSrc); + printf("TaskSetup: SzSrc = %d\n", TaskSetupParams->SzSrc); + printf("TaskSetup: StartAddrDst = 0x%08X\n", TaskSetupParams->StartAddrDst); + printf("TaskSetup: IncrDst = %d\n", TaskSetupParams->IncrDst); + printf("TaskSetup: SzDst = %d\n", TaskSetupParams->SzDst); +#endif + +#if (DEBUG_BESTCOMM_API>=20) + printf("\nTaskSetup: Task-API Parameter Settings After TaskSetup Initialization:\n"); + printf("TaskSetup: TaskNum = %d\n", ((TaskAPI->TaskNum))); + printf("TaskSetup: TaskPragma = 0x%02X\n", *((TaskAPI->TaskPragma))); + + #if (MAX_BD>0) + printf("TaskSetup: BDTableBase = 0x%08X\n", *((TaskAPI->BDTableBase))); + printf("TaskSetup: BDTableLast = 0x%08X\n", *((TaskAPI->BDTableLast))); + printf("TaskSetup: BDTableStart = 0x%08X\n", *((TaskAPI->BDTableStart))); + printf("TaskSetup: AddrEnable = 0x%08X\n", *((TaskAPI->AddrEnable))); + #if (INCR_TYPE_SRC==0) + printf("TaskSetup: AddrSrcFIFO = 0x%08X\n", *((TaskAPI->AddrSrcFIFO))); + #endif + #if (INCR_TYPE_DST==0) + printf("TaskSetup: AddrDstFIFO = 0x%08X\n", *((TaskAPI->AddrDstFIFO))); + #endif + #if (BD_FLAG) + printf("TaskSetup: AddrDRD = 0x%08X\n", *((TaskAPI->AddrDRD))); + printf("TaskSetup: AddrDRDIdx = %d\n", ((TaskAPI->AddrDRDIdx))); + #endif + #else + printf("TaskSetup: IterExtra = %d\n", *((TaskAPI->IterExtra))); + #if (INCR_TYPE_SRC==0) + printf("TaskSetup: AddrSrcFIFO = 0x%08X\n", *((TaskAPI->AddrSrcFIFO))); + #else + printf("TaskSetup: StartAddrSrc = 0x%08X\n", *((TaskAPI->StartAddrSrc))); + #endif + #if (INCR_TYPE_DST==0) + printf("TaskSetup: AddrDstFIFO = 0x%08X\n", *((TaskAPI->AddrDstFIFO))); + #else + printf("TaskSetup: StartAddrDst = 0x%08X\n", *((TaskAPI->StartAddrDst))); + #endif + #endif + #if (INCR_TYPE_SRC!=0) + printf("TaskSetup: IncrSrc = 0x%04X\n", *((TaskAPI->IncrSrc))); + #if (MISALIGNED | MISALIGNED_START) + printf("TaskSetup: IncrSrcMA = 0x%04X\n", *((TaskAPI->IncrSrcMA))); + #endif + #endif + #if (INCR_TYPE_DST!=0) + printf("TaskSetup: IncrDst = 0x%04X\n", *((TaskAPI->IncrDst))); + #if (MISALIGNED | MISALIGNED_START) + printf("TaskSetup: IncrDstMA = 0x%04X\n", *((TaskAPI->IncrDstMA))); + #endif + #endif + printf("TaskSetup: Bytes = %d\n", *((TaskAPI->Bytes))); + printf("TaskSetup: IncrBytes = %d\n", *((TaskAPI->IncrBytes))); +#endif + + return TaskNum; +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_ata.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_ata.c new file mode 100644 index 0000000000..d9f76b2a02 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_ata.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_ATA +#define TASK_API TASK_ATA_api_t +#define TASKSETUP_NAME TaskSetup_TASK_ATA + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA -1 + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 4 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_bdtable.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_bdtable.c new file mode 100644 index 0000000000..0966f2985f --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_bdtable.c @@ -0,0 +1,126 @@ +/****************************************************************************** +* +* Copyright (c) 2004 Freescale Semiconductor, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Filename: $Source$ +* Author: $Author$ +* Locker: $Locker$ +* State: $State$ +* Revision: $Revision$ +* +******************************************************************************/ + +#include "../bestcomm/bestcomm_api.h" +#include "../bestcomm/task_api/tasksetup_bdtable.h" +#include "../bestcomm/include/mgt5200/mgt5200.h" + +#ifdef __MWERKS__ +__declspec(section ".text") extern const uint32 taskTable; +__declspec(section ".text") extern const uint32 taskTableBytes; +__declspec(section ".text") extern const uint32 taskTableTasks; +__declspec(section ".text") extern const uint32 offsetEntry; +#else +extern const uint32 taskTable; +extern const uint32 taskTableBytes; +extern const uint32 taskTableTasks; +extern const uint32 offsetEntry; +#endif + +TaskBDIdxTable_t TaskBDIdxTable[MAX_TASKS]; + +static uint8 *TaskTableFree = 0; + +void TaskSetup_BDTable(volatile uint32 *BasePtr, volatile uint32 *LastPtr, volatile uint32 *StartPtr, + int TaskNum, uint32 NumBD, uint16 MaxBD, + uint8 NumPtr, ApiConfig_t ApiConfig, uint32 Status) +{ + int i, j; + uint32 *ptr; + + /* + * If another process has not used SRAM already, then the start value + * will have to be passed in using the TasksSetSramOffset() function. + */ + if (SramOffsetGlobal == 0) { + SramOffsetGlobal = taskTableBytes; + } + + TaskTableFree = MBarGlobal + MBAR_SRAM + SramOffsetGlobal; + + /* + * First time through the Buffer Descriptor table configuration + * set the buffer descriptor table with parameters that will not + * change since they are determined by the task itself. The + * SramOffsetGlobal variable must be updated to reflect the new SRAM + * space used by the buffer descriptor table. The next time through + * this function (i.e. TaskSetup called again) the only parameters + * that should be changed are the LastPtr pointers and the NumBD part + * of the table. + */ + if (TaskBDIdxTable[TaskNum].BDTablePtr == 0) { + TaskBDIdxTable[TaskNum].BDTablePtr = TaskTableFree; + TaskBDIdxTable[TaskNum].numPtr = NumPtr; + TaskBDIdxTable[TaskNum].apiConfig = ApiConfig; + TaskBDIdxTable[TaskNum].BDStartPtr = StartPtr; + + *StartPtr = *BasePtr = (uint32)((uint32)TaskBDIdxTable[TaskNum].BDTablePtr + + MBarPhysOffsetGlobal); + + switch (NumPtr) { + case 1: + SramOffsetGlobal += MaxBD*sizeof(TaskBD1_t); + break; + case 2: + SramOffsetGlobal += MaxBD*sizeof(TaskBD2_t); + break; + default: + /* error */ + break; + } + } + + TaskBDIdxTable[TaskNum].currBDInUse = 0; + TaskBDIdxTable[TaskNum].numBD = (uint16)NumBD; + switch (NumPtr) { + case 1: + *LastPtr = (uint32)(*BasePtr + sizeof(TaskBD1_t) * (NumBD - 1)); + break; + case 2: + *LastPtr = (uint32)(*BasePtr + sizeof(TaskBD2_t) * (NumBD - 1)); + break; + default: + /* error */ + break; + } + + /* + * Set the status bits. Clear the data pointers. + */ + if (MaxBD > 0) { + ptr = TaskBDIdxTable[TaskNum].BDTablePtr; + for (i = 0; i < NumBD; i++) { + *(ptr++) = Status; + for (j = 0; j < NumPtr; j++) { + *(ptr++) = 0x0; + } + } + } +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_0.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_0.c new file mode 100644 index 0000000000..9ff3b6f25b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_0.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_CRC16_DP_0 +#define TASK_API TASK_CRC16_DP_0_api_t +#define TASKSETUP_NAME TaskSetup_TASK_CRC16_DP_0 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_1.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_1.c new file mode 100644 index 0000000000..5796309ce1 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_crc16_dp_1.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_CRC16_DP_1 +#define TASK_API TASK_CRC16_DP_1_api_t +#define TASKSETUP_NAME TaskSetup_TASK_CRC16_DP_1 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_rx_bd.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_rx_bd.c new file mode 100644 index 0000000000..870917b5d5 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_rx_bd.c @@ -0,0 +1,39 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_FEC_RX +#define TASK_API TASK_FEC_RX_api_t +#define TASKSETUP_NAME TaskSetup_TASK_FEC_RX + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 +#define MISALIGNED_START 1 + +#define INITIATOR_DATA INITIATOR_FEC_RX + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 256 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 0 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_tx_bd.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_tx_bd.c new file mode 100644 index 0000000000..37395b03b2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_fec_tx_bd.c @@ -0,0 +1,39 @@ + + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_FEC_TX +#define TASK_API TASK_FEC_TX_api_t +#define TASKSETUP_NAME TaskSetup_TASK_FEC_TX + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 +#define MISALIGNED_START 1 + +#define INITIATOR_DATA INITIATOR_FEC_TX + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 256 +#define BD_FLAG 1 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 0 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_0.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_0.c new file mode 100644 index 0000000000..16334e9a22 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_0.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_0 +#define TASK_API TASK_GEN_DP_0_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_0 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_1.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_1.c new file mode 100644 index 0000000000..a77dbc1b63 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_1.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_1 +#define TASK_API TASK_GEN_DP_1_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_1 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_2.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_2.c new file mode 100644 index 0000000000..7dc90a6c8c --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_2.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_2 +#define TASK_API TASK_GEN_DP_2_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_2 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_3.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_3.c new file mode 100644 index 0000000000..ba0b491bed --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_3.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_3 +#define TASK_API TASK_GEN_DP_3_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_3 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_0.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_0.c new file mode 100644 index 0000000000..68de50be8c --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_0.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_BD_0 +#define TASK_API TASK_GEN_DP_BD_0_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_BD_0 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA -1 + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 128 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_1.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_1.c new file mode 100644 index 0000000000..c7f8c6266b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_dp_bd_1.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_DP_BD_1 +#define TASK_API TASK_GEN_DP_BD_1_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_DP_BD_1 + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA -1 + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 32 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_rx_bd.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_rx_bd.c new file mode 100644 index 0000000000..c1aa434416 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_rx_bd.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_RX_BD +#define TASK_API TASK_GEN_RX_BD_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_RX_BD + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA -1 + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 64 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 0 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_tx_bd.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_tx_bd.c new file mode 100644 index 0000000000..d97b6b78e4 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_gen_tx_bd.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_GEN_TX_BD +#define TASK_API TASK_GEN_TX_BD_api_t +#define TASKSETUP_NAME TaskSetup_TASK_GEN_TX_BD + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -1 +#define ITERATIONS -1 + +#define MAX_BD 64 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 0 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_lpc.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_lpc.c new file mode 100644 index 0000000000..28cc0c4ed0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_lpc.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_LPC +#define TASK_API TASK_LPC_api_t +#define TASKSETUP_NAME TaskSetup_TASK_LPC + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 0 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 1 + +#define INITIATOR_DATA -1 + +#define AUTO_START -2 +#define ITERATIONS 1 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_rx.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_rx.c new file mode 100644 index 0000000000..48fa25ab6f --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_rx.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_PCI_RX +#define TASK_API TASK_PCI_RX_api_t +#define TASKSETUP_NAME TaskSetup_TASK_PCI_RX + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 1 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA INITIATOR_SCPCI_RX + +#define AUTO_START -2 +#define ITERATIONS 0 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 0 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 1 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_tx.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_tx.c new file mode 100644 index 0000000000..0fde9d9225 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/tasksetup_pci_tx.c @@ -0,0 +1,38 @@ + +/* + * Generated by GUI, one per configured tasks. + */ + +#define TASK_BASE TASK_PCI_TX +#define TASK_API TASK_PCI_TX_api_t +#define TASKSETUP_NAME TaskSetup_TASK_PCI_TX + +/* Pragma settings */ +#define PRECISE_INC 0 +#define NO_ERROR_RST 0 +#define PACK_DATA 0 +#define INTEGER_MODE 1 +#define SPEC_READS 1 +#define WRITE_LINE_BUFFER 1 +#define READ_LINE_BUFFER 1 + +#define MISALIGNED 0 + +#define INITIATOR_DATA INITIATOR_SCPCI_TX + +#define AUTO_START -2 +#define ITERATIONS 0 + +#define MAX_BD 0 +#define BD_FLAG 0 + +#define INCR_TYPE_SRC 1 +#define INCR_SRC 0 +#define TYPE_SRC FLEX_T + +#define INCR_TYPE_DST 0 +#define INCR_DST 0 +#define TYPE_DST FLEX_T + +#include "../bestcomm/task_api/tasksetup_general.h" + diff --git a/c/src/lib/libbsp/powerpc/gen5200/bsp_specs b/c/src/lib/libbsp/powerpc/gen5200/bsp_specs new file mode 100644 index 0000000000..b4986a9368 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/bsp_specs @@ -0,0 +1,22 @@ +%rename lib old_lib +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*lib: +%{!qrtems: %(old_lib)} %{!nostdlib: %{qrtems: --start-group \ +%{!qrtems_debug: -lrtemsbsp -lrtemscpu} %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \ +-lc -lgcc --end-group \ +%{!qnolinkcmds: -T linkcmds%s}}} + +*startfile: +%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: ecrti%O%s \ +%{!qrtems_debug: start.o%s} \ +%{qrtems_debug: start_g.o%s}}} + +*endfile: +%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start} + diff --git a/c/src/lib/libbsp/powerpc/gen5200/clock/clock.c b/c/src/lib/libbsp/powerpc/gen5200/clock/clock.c new file mode 100644 index 0000000000..2ef30514a8 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/clock/clock.c @@ -0,0 +1,474 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: clock.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the clock driver functions | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.9 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.8 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.7 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: clock.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 clock driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: Use one of the GPTs for time base generation */ +/* instead of the decrementer. The routine initializes */ +/* the General Purpose Timer GPT6 on the MPC5x00. */ +/* The tick frequency is specified by the bsp. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: Clock driver for PPC403 */ +/* Module: clock.c */ +/* Project: RTEMS 4.6.0pre1 / PPC403 BSP */ +/* Version 1.16 */ +/* Date: 2002/11/01 */ +/* Author(s) / Copyright(s): */ +/* */ +/* Author: Jay Monkman (jmonkman@frasca.com) */ +/* Copyright (C) 1998 by Frasca International, Inc. */ +/* */ +/* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c: */ +/* */ +/* Author: Andrew Bray <andy@i-cubed.co.uk> */ +/* */ +/* COPYRIGHT (c) 1995 by i-cubed ltd. */ +/* */ +/* To anyone who acknowledges that this file is provided "AS IS" */ +/* without any express or implied warranty: */ +/* permission to use, copy, modify, and distribute this file */ +/* for any purpose is hereby granted without fee, provided that */ +/* the above copyright notice and this notice appears in all */ +/* copies, and that the name of i-cubed limited not be used in */ +/* advertising or publicity pertaining to distribution of the */ +/* software without specific, written prior permission. */ +/* i-cubed limited makes no representations about the suitability */ +/* of this software for any purpose. */ +/* */ +/* Derived from c/src/lib/libcpu/hppa1.1/clock/clock.c: */ +/* */ +/* Modifications for deriving timer clock from cpu system clock by */ +/* Thomas Doerfler <td@imd.m.isar.de> */ +/* for these modifications: */ +/* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany. */ +/* */ +/* COPYRIGHT (c) 1989-1999. */ +/* On-Line Applications Research Corporation (OAR). */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/* Modifications for PPC405GP by Dennis Ehlin */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include <rtems/bspIo.h> +/*#include "../irq/irq.h"*/ +#include "../irq/irq.h" + +#include <rtems.h> +#include <rtems/clockdrv.h> +#include <rtems/libio.h> + +#include <stdlib.h> /* for atexit() */ +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" + +volatile uint32_t Clock_driver_ticks; + +void Clock_exit(void); + +uint32_t counter_value; + +volatile int ClockInitialized = 0; + + +/* + * These are set by clock driver during its init + */ +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + + +/* + * ISR Handlers + */ +void mpc5200_gpt_clock_isr(rtems_irq_hdl_param handle) + { + uint32_t status; + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)handle; + + status = gpt->status; + + + if(ClockInitialized && (status & GPT_STATUS_TEXP)) + { + + gpt->status |= GPT_STATUS_TEXP; + + + Clock_driver_ticks++; + rtems_clock_tick(); + + } + + } + + +/* + * Initialize MPC5x00 GPT + */ +void mpc5200_init_gpt(uint32_t gpt_no) + { + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]); + + gpt->status = GPT_STATUS_RESET; + gpt->emsel = GPT_EMSEL_CE | GPT_EMSEL_ST_CONT | GPT_EMSEL_INTEN | GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO; + + } + + +/* + * Set MPC5x00 GPT counter + */ +void mpc5200_set_gpt_count(uint32_t counter_value, uint32_t gpt_no) + { + uint32_t prescaler_value = 1; + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]); + + /* Calculate counter/prescaler value, e.g. IPB_Clock=33MHz -> Int. every 0,3 nsecs. - 130 secs.*/ + while((counter_value >= (1 << 16)) && (prescaler_value < (1 << 16))) + { + + prescaler_value++; + counter_value /= prescaler_value; + + } + + counter_value = (uint16_t)counter_value; + + gpt->count_in = (prescaler_value << 16) + counter_value; + + } + + +/* + * Enable MPC5x00 GPT interrupt + */ +void mpc5200_enable_gpt_int(uint32_t gpt_no) + { + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]); + + gpt->emsel |= GPT_EMSEL_CE | GPT_EMSEL_INTEN; + + } + + +/* + * Disable MPC5x00 GPT interrupt + */ +void mpc5200_disable_gpt_int(uint32_t gpt_no) + { + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]); + + gpt->emsel &= ~(GPT_EMSEL_CE | GPT_EMSEL_INTEN); + + } + + +/* + * Check MPC5x00 GPT status + */ +uint32_t mpc5200_check_gpt_status(uint32_t gpt_no) + { + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]); + + return ((gpt->emsel) & (GPT_EMSEL_CE | GPT_EMSEL_INTEN)); + + } + + +void clockOn(const rtems_irq_connect_data* irq) + { + uint32_t gpt_no; + + + gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name); + + counter_value = rtems_configuration_get_microseconds_per_tick() * + rtems_cpu_configuration_get_clicks_per_usec(); + + mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no); + mpc5200_enable_gpt_int((uint32_t)gpt_no); + + Clock_driver_ticks = 0; + ClockInitialized = 1; + + } + + +void clockOff(const rtems_irq_connect_data* irq) + { + uint32_t gpt_no; + + gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name); + + mpc5200_disable_gpt_int((uint32_t)gpt_no); + + ClockInitialized = 0; + + } + + +int clockIsOn(const rtems_irq_connect_data* irq) + { + uint32_t gpt_no; + + gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name); + + if(mpc5200_check_gpt_status(gpt_no) && ClockInitialized) + return ClockInitialized; + else + return 0; + } + + +int BSP_get_clock_irq_level() + { + + /* + * Caution : if you change this, you must change the + * definition of BSP_PERIODIC_TIMER accordingly + */ + return BSP_PERIODIC_TIMER; + } + + +int BSP_disconnect_clock_handler (void) + { + rtems_irq_connect_data clockIrqData; + clockIrqData.name = BSP_PERIODIC_TIMER; + + + if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) + { + + printk("Unable to stop system clock\n"); + rtems_fatal_error_occurred(1); + + } + + return BSP_remove_rtems_irq_handler (&clockIrqData); + + } + + +int BSP_connect_clock_handler (uint32_t gpt_no) + { + + rtems_irq_hdl hdl = 0; + rtems_irq_connect_data clockIrqData; + + + /* + * Reinit structure + */ + + clockIrqData.name = BSP_PERIODIC_TIMER; + + if(!BSP_get_current_rtems_irq_handler(&clockIrqData)) + { + + printk("Unable to get system clock handler\n"); + rtems_fatal_error_occurred(1); + + } + + if(!BSP_remove_rtems_irq_handler (&clockIrqData)) + { + + printk("Unable to remove current system clock handler\n"); + rtems_fatal_error_occurred(1); + + } + + if ((gpt_no >= GPT0) || + (gpt_no <= GPT7)) { + hdl = (rtems_irq_hdl_param )&mpc5200.gpt[gpt_no]; + } + else { + printk("Unable to set system clock handler\n"); + rtems_fatal_error_occurred(1); + } + + clockIrqData.hdl = mpc5200_gpt_clock_isr; + clockIrqData.handle = (rtems_irq_hdl_param) hdl; + clockIrqData.on = clockOn; + clockIrqData.off = clockOff; + clockIrqData.isOn = clockIsOn; + + return BSP_install_rtems_irq_handler (&clockIrqData); + + } + + +/* + * Called via atexit() + * Remove the clock interrupt handler by setting handler to NULL + */ +void Clock_exit(void) + { + + (void) BSP_disconnect_clock_handler (); + + } + + +void Install_clock(rtems_device_minor_number gpt_no) + { + + Clock_driver_ticks = 0; + + counter_value = rtems_configuration_get_microseconds_per_tick() * + rtems_cpu_configuration_get_clicks_per_usec(); + + mpc5200_init_gpt((uint32_t)gpt_no); + mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no); + + + BSP_connect_clock_handler(gpt_no); + + ClockInitialized = 1; + + atexit(Clock_exit); + + } + +void ReInstall_clock(uint32_t gpt_no) + { + + BSP_connect_clock_handler(gpt_no); + + } + + +rtems_device_driver Clock_initialize + ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp + ) + { + /* force minor according to definitions in irq.h */ + minor = BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0; + + Install_clock((uint32_t)minor); + + /* + * make major/minor avail to others such as shared memory driver + */ + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; + + } + +rtems_device_driver Clock_control + ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp + ) { + + rtems_libio_ioctl_args_t *args = pargp; + + /* forec minor according to definitions in irq.h */ + minor = BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0; + + if(args != 0) { + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + if(args->command == rtems_build_name('I', 'S', 'R', ' ')) { + if ((minor >= GPT0) || + (minor <= GPT7)) { + mpc5200_gpt_clock_isr((rtems_irq_hdl_param )&mpc5200.gpt[minor]); + } + else { + printk("Unable to call system clock handler\n"); + rtems_fatal_error_occurred(1); + } + } + else if(args->command == rtems_build_name('N', 'E', 'W', ' ')) { + ReInstall_clock((uint32_t)minor); + } + } + return RTEMS_SUCCESSFUL; + +} + diff --git a/c/src/lib/libbsp/powerpc/gen5200/configure.ac b/c/src/lib/libbsp/powerpc/gen5200/configure.ac new file mode 100644 index 0000000000..dd1672331c --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/configure.ac @@ -0,0 +1,36 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ + +AC_PREREQ(2.59) +AC_INIT([rtems-c-src-lib-libbsp-powerpc-gen5200],[_RTEMS_VERSION],[rtems-bugs@rtems.com]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.9]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm]) +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_BSPOPTS_SET([DATA_CACHE_ENABLE],[*],[1]) +RTEMS_BSPOPTS_HELP([DATA_CACHE_ENABLE], +[If defined, the data cache will be enabled after address translation + is turned on.]) + +RTEMS_BSPOPTS_SET([INSTRUCTION_CACHE_ENABLE],[*],[1]) +RTEMS_BSPOPTS_HELP([INSTRUCTION_CACHE_ENABLE], +[If defined, the instruction cache will be enabled after address translation + is turned on.]) + +RTEMS_CHECK_NETWORKING +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile]) + +RTEMS_PPC_EXCEPTIONS + +AC_OUTPUT diff --git a/c/src/lib/libbsp/powerpc/gen5200/console/console.c b/c/src/lib/libbsp/powerpc/gen5200/console/console.c new file mode 100644 index 0000000000..7fc4e3b1a2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/console/console.c @@ -0,0 +1,851 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: console.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the console driver functions | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.11 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: console.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 console driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: */ +/* */ +/* The PSCs of mpc5200 are assigned as follows */ +/* */ +/* Channel Device Minor Note */ +/* PSC1 /dev/tty0 0 */ +/* PSC2 /dev/tty1 1 */ +/* PSC3 /dev/tty2 2 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: Serial driver for MPC8260ads */ +/* Module: console-generic.c */ +/* Project: RTEMS 4.6.0pre1 / MPC8260ads BSP */ +/* Version 1.3 */ +/* Date: 2002/11/04 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Author: Jay Monkman (jmonkman@frasca.com) */ +/* Copyright (C) 1998 by Frasca International, Inc. */ +/* */ +/* Derived from c/src/lib/libbsp/m68k/gen360/console/console.c */ +/* written by: */ +/* W. Eric Norum */ +/* Saskatchewan Accelerator Laboratory */ +/* University of Saskatchewan */ +/* Saskatoon, Saskatchewan, CANADA */ +/* eric@skatter.usask.ca */ +/* */ +/* COPYRIGHT (c) 1989-1998. */ +/* On-Line Applications Research Corporation (OAR). */ +/* */ +/* Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca> */ +/* and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca> */ +/* Copyright (c) 1999, National Research Council of Canada */ +/* */ +/* Modifications by Andy Dachs <a.dachs@sstl.co.uk> to add MPC8260 */ +/* support. */ +/* Copyright (c) 2001, Surrey Satellite Technology Ltd */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include <rtems.h> +#include "../include/mpc5200.h" +#include "../include/bsp.h" +#include "../irq/irq.h" + +#include <rtems/bspIo.h> +#include <rtems/libio.h> +#include <string.h> + + +#define NUM_PORTS MPC5200_PSC_NO + +#define PSC1_MINOR 0 +#define PSC2_MINOR 1 +#define PSC3_MINOR 2 +#define PSC4_MINOR 3 +#define PSC5_MINOR 4 +#define PSC6_MINOR 5 + +uint32_t mpc5200_uart_avail_mask = GEN5200_UART_AVAIL_MASK; + +uint8_t psc_minor_to_irqname[NUM_PORTS] = + {BSP_SIU_IRQ_PSC1, + BSP_SIU_IRQ_PSC2, + BSP_SIU_IRQ_PSC3, + BSP_SIU_IRQ_PSC4, + BSP_SIU_IRQ_PSC5, + BSP_SIU_IRQ_PSC6}; +static int mpc5200_psc_irqname_to_minor(int name) +{ + int minor; + uint8_t *chrptr; + + chrptr = memchr(psc_minor_to_irqname, + name, + sizeof(psc_minor_to_irqname)); + if (chrptr != NULL) { + minor = chrptr - psc_minor_to_irqname; + } + else { + minor = -1; + } + return minor; +} + +static void A_BSP_output_char(char c); +BSP_output_char_function_type BSP_output_char = A_BSP_output_char; + +/* Used to handle premature outputs of printk */ +uint32_t console_initialized = FALSE; + +/* per channel info structure */ +struct per_channel_info + { + uint16_t shadow_imr; + uint8_t shadow_mode1; + uint8_t shadow_mode2; + int cur_tx_len; + int rx_interrupts; + int tx_interrupts; + int rx_characters; + int tx_characters; + int breaks_detected; + int framing_errors; + int parity_errors; + int overrun_errors; + }; + +/* Used to handle more than one channel */ +struct per_channel_info channel_info[NUM_PORTS]; + + /* + * XXX: there are only 6 PSCs, but PSC6 has an extra register gap + * from PSC5, therefore we instantiate seven(!) PSC register sets + */ +uint8_t psc_minor_to_regset[MPC5200_PSC_NO] = {0,1,2,3,4,6}; + +/* Used to track termios private data for callbacks */ +struct rtems_termios_tty *ttyp[NUM_PORTS]; + +int mpc5200_psc_setAttributes(int minor, const struct termios *t) + { + int baud; + uint8_t csize=0, cstopb, parenb, parodd; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* Baud rate */ + switch(t->c_cflag & CBAUD) + { + default: baud = -1; break; + case B50: baud = 50; break; + case B75: baud = 75; break; + case B110: baud = 110; break; + case B134: baud = 134; break; + case B150: baud = 150; break; + case B200: baud = 200; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + } + + if(baud > 0) + { + + /* + * Calculate baud rate + */ + baud = IPB_CLOCK / (baud * 32); + + } + + /* Number of data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: csize = 0x00; break; + case CS6: csize = 0x01; break; + case CS7: csize = 0x02; break; + case CS8: csize = 0x03; break; + } + + /* Stop bits */ + if(csize == 0) + { + + if(t->c_cflag & CSTOPB) + cstopb = 0x0F; /* Two stop bits */ + else + cstopb = 0x00; /* One stop bit */ + + } + else + { + + if(t->c_cflag & CSTOPB) + cstopb = 0x0F; /* Two stop bits */ + else + cstopb = 0x07; /* One stop bit */ + + } + + /* Parity */ + if (t->c_cflag & PARENB) + parenb = 0x00; /* Parity enabled on Tx and Rx */ + else + parenb = 0x10; /* No parity on Tx and Rx */ + + if (t->c_cflag & PARODD) + parodd = 0x04; /* Odd parity */ + else + parodd = 0x00; + + /* + * Set upper timer counter + */ + psc->ctur = (uint16_t)(baud >> 16); + + /* + * Set lower timer counter + */ + psc->ctlr = (uint16_t)(baud & 0x0000FFFF); + + /* + * Reset mode pointer + */ + psc->cr = ((1 << 4) << 8); + + /* + * Set mode1 register + */ + channel_info[minor].shadow_mode1 &= ~(0x1F); + psc->mr = channel_info[minor].shadow_mode1 | (csize | parenb | parodd); + + /* + * Set mode2 register + */ + channel_info[minor].shadow_mode2 &= ~(0x0F); + psc->mr = channel_info[minor].shadow_mode2 | cstopb; + + return 0; + + } + + +int mpc5200_uart_setAttributes(int minor, const struct termios *t) + { + + + /* + * Check that port number is valid + */ + if( (minor < PSC1_MINOR) || (minor > NUM_PORTS-1) ) + return 0; + + return mpc5200_psc_setAttributes(minor, t); + + } + + +#ifdef UARTS_USE_TERMIOS_INT +/* + * Interrupt handlers + */ +static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle) + { + unsigned char c; + uint16_t isr; + int nb_overflow; + int minor = (int)handle; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* + * get content of psc interrupt status + */ + isr = psc->isr_imr; + + /* + * Character received? + */ + if(isr & ISR_RX_RDY_FULL) + { + + channel_info[minor].rx_interrupts++; + + +#ifndef SINGLE_CHAR_MODE + while(psc->rfnum) + { +#endif + + /* + * get the character + */ + c = (psc->rb_tb >> 24); + + nb_overflow = rtems_termios_enqueue_raw_characters((void *)ttyp[minor], (char *)&c, (int)1); + + channel_info[minor].rx_characters++; + +#ifndef SINGLE_CHAR_MODE + } +#endif + + } + + /* + * Character transmitted ? + */ + if(isr & ISR_TX_RDY & channel_info[minor].shadow_imr) + { + + channel_info[minor].tx_interrupts++; + + /* + * mask interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY); + +#ifndef SINGLE_CHAR_MODE + rtems_termios_dequeue_characters((void *)ttyp[minor], channel_info[minor].cur_tx_len); + + channel_info[minor].tx_characters += channel_info[minor].cur_tx_len; +#else + rtems_termios_dequeue_characters((void *)ttyp[minor], (int)1); + + channel_info[minor].tx_characters++; +#endif + + } + + if(isr & ISR_ERROR) + { + + if(isr & ISR_RB) + channel_info[minor].breaks_detected++; + + if(isr & ISR_FE) + channel_info[minor].framing_errors++; + + if(isr & ISR_PE) + channel_info[minor].parity_errors++; + + if(isr & ISR_PE) + channel_info[minor].overrun_errors++; + + /* + * Reset error status + */ + psc->cr = ((4 << 4) << 8); + + } + + } + +void mpc5200_psc_enable(const rtems_irq_connect_data* ptr) { + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + psc->isr_imr = channel_info[minor].shadow_imr |= + (IMR_RX_RDY_FULL | IMR_TX_RDY); + } +} + + +void mpc5200_psc_disable(const rtems_irq_connect_data* ptr) { + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + psc->isr_imr = channel_info[minor].shadow_imr &= + ~(IMR_RX_RDY_FULL | IMR_TX_RDY); + } +} + + +int mpc5200_psc_isOn(const rtems_irq_connect_data* ptr) { + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + return ((psc->isr_imr & IMR_RX_RDY_FULL) & (psc->isr_imr & IMR_TX_RDY)); + } + else { + return FALSE; + } +} + + +static rtems_irq_connect_data consoleIrqData; +#endif + +void mpc5200_uart_psc_initialize(int minor) { + uint32_t baud_divider; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* + * Check that minor number is valid + */ + if((minor < PSC1_MINOR) || (minor >= (PSC1_MINOR + NUM_PORTS))) + return; + + /* + * Clear per channel info + */ + memset((void *)&channel_info[minor], 0, sizeof(struct per_channel_info)); + + + /* + * Reset receiver and transmitter + */ + psc->cr = ((2 << 4) << 8); + psc->cr = ((3 << 4) << 8); + + /* + * Reset mode pointer + */ + psc->cr = ((1 << 4) << 8); + + /* + * Set clock select register + */ + psc->sr_csr = 0; + + /* + * Set mode1 register + */ + psc->mr = channel_info[minor].shadow_mode1 = 0x33; /* 8Bit / no parity */ + + /* + * Set mode2 register + */ + psc->mr = channel_info[minor].shadow_mode2 = 7; /* 1 stop bit */ + + /* + * Set rx FIFO alarm + */ + psc->rfalarm = RX_FIFO_SIZE - 1; + + /* + * Set tx FIFO alarm + */ + psc->tfalarm = 1; + + baud_divider = IPB_CLOCK / (9600 * 32); + /* + * Set upper timer counter + */ + psc->ctur = baud_divider >> 16; + + + /* + * Set lower timer counter + */ + + psc->ctlr = baud_divider & 0x0000ffff; + + /* + * Disable Frame mode / set granularity 0 + */ + psc->tfcntl = 0; + +#ifdef UARTS_USE_TERMIOS_INT + /* + * Tie interrupt dependent routines + */ + consoleIrqData.on = mpc5200_psc_enable; + consoleIrqData.off = mpc5200_psc_disable; + consoleIrqData.isOn = mpc5200_psc_isOn; + consoleIrqData.handle = (rtems_irq_hdl_param)minor; + consoleIrqData.hdl = (rtems_irq_hdl)mpc5200_psc_interrupt_handler; + + /* + * Tie interrupt handler + */ + consoleIrqData.name = psc_minor_to_irqname[minor]; + + /* + * Install rtems irq handler + */ + if(!BSP_install_rtems_irq_handler (&consoleIrqData)) + { + + printk("Unable to connect PSC Irq handler\n"); + rtems_fatal_error_occurred(1); + + } +#endif + + /* + * Reset rx fifo errors Error/UF/OF + */ + psc->rfstat |= 0x70; + + /* + * Reset tx fifo errors Error/UF/OF + */ + psc->tfstat |= 0x70; + +#ifdef UARTS_USE_TERMIOS_INT + /* + * Unmask receive interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr = IMR_RX_RDY_FULL; +#endif + + /* + * Enable receiver + */ + psc->cr = ((1 << 0) << 8); + + /* + * Enable transmitter + */ + psc->cr = ((1 << 2) << 8); + + } + + +int mpc5200_uart_pollRead(int minor) + { + unsigned char c; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + if(psc->sr_csr & (1 << 8)) + c = (psc->rb_tb >> 24); + else + return -1; + + return c; + + } + + +int mpc5200_uart_pollWrite(int minor, const char *buf, int len) + { + const char *tmp_buf = buf; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + while(len--) + { + + while(!(psc->sr_csr & (1 << 11))) + continue; + + /*rtems_cache_flush_multiple_data_lines( (void *)buf, 1);*/ + + psc->rb_tb = (*tmp_buf << 24); + + tmp_buf++; + + } + + return 0; + + } + + +int mpc5200_uart_write(int minor, const char *buf, int len) + { + int frame_len = len; + const char *frame_buf = buf; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* + * Check tx fifo space + */ + if(len > (TX_FIFO_SIZE - psc->tfnum)) + frame_len = TX_FIFO_SIZE - psc->tfnum; + +#ifndef SINGLE_CHAR_MODE + channel_info[minor].cur_tx_len = frame_len; +#else + frame_len = 1; +#endif + + /*rtems_cache_flush_multiple_data_lines( (void *)frame_buf, frame_len);*/ + + while(frame_len--) + /* perform byte write to avoid extra NUL characters */ + (* (volatile char *)&(psc->rb_tb)) = *frame_buf++; + + /* + * unmask interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr |= IMR_TX_RDY; + + return 0; + + } + +/* + * Print functions prototyped in bspIo.h + */ +static void A_BSP_output_char( char c ) + { + char cr = '\r'; + + + if(console_initialized == TRUE) + { + +#define PRINTK_WRITE mpc5200_uart_pollWrite + + PRINTK_WRITE(PRINTK_MINOR, &c, 1 ); + + if( c == '\n' ) + PRINTK_WRITE( PRINTK_MINOR, &cr, 1 ); + + } + + } + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + + rtems_status_code status; + rtems_device_minor_number console_minor; + char dev_name[] = "/dev/ttyx"; + /* + * Always use and set up TERMIOS + */ + console_minor = PSC1_MINOR; + rtems_termios_initialize(); + + for (console_minor = PSC1_MINOR; + console_minor < PSC1_MINOR + NUM_PORTS; + console_minor++) { + /* + * check, whether UART is available for this board + */ + if (0 != ((1 << console_minor) & (mpc5200_uart_avail_mask))) { + /* + * Do device-specific initialization and registration for Motorola IceCube + */ + mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */ + dev_name[8] = '0' + console_minor - PSC1_MINOR; + status = rtems_io_register_name (dev_name, major, console_minor); + + if(status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + } + } + /* Now register the RTEMS console */ + status = rtems_io_register_name ("/dev/console", major, PSC1_MINOR); + + if(status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + console_initialized = TRUE; + return RTEMS_SUCCESSFUL; + + } + + +/* + * Open the device + */ +rtems_device_driver console_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { +#ifdef UARTS_USE_TERMIOS_INT + rtems_libio_open_close_args_t *args = arg; +#endif + rtems_status_code sc; + +#ifdef UARTS_USE_TERMIOS_INT + static const rtems_termios_callbacks intrCallbacks = + { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + mpc5200_uart_write, /* write */ + mpc5200_uart_setAttributes, /* setAttributes */ + NULL, + NULL, + 1 /* outputUsesInterrupts */ + }; +#else + static const rtems_termios_callbacks pollCallbacks = + { + NULL, /* firstOpen */ + NULL, /* lastClose */ + mpc5200_uart_pollRead, /* pollRead */ + mpc5200_uart_pollWrite, /* write */ + mpc5200_uart_setAttributes, /* setAttributes */ + NULL, + NULL, + 0 /* output don't use Interrupts */ + }; +#endif + + if(minor > NUM_PORTS - 1) + return RTEMS_INVALID_NUMBER; + +#ifdef UARTS_USE_TERMIOS_INT + sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); + ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ +#else /* RTEMS polled I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); +#endif + + return sc; + + } + + +/* + * Close the device + */ +rtems_device_driver console_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_close( arg ); + + return 0; + + } + + +/* + * Read from the device + */ +rtems_device_driver console_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + + if(minor > NUM_PORTS-1) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_read(arg); + + return 0; + + } + + +/* + * Write to the device + */ +rtems_device_driver console_write(rtems_device_major_number major,rtems_device_minor_number minor,void *arg) + { + + if( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_write(arg); + + return 0; + } + + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control(rtems_device_major_number major,rtems_device_minor_number minor,void *arg) + { + + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_ioctl(arg); + + return 0; + + } diff --git a/c/src/lib/libbsp/powerpc/gen5200/i2c/i2c.c b/c/src/lib/libbsp/powerpc/gen5200/i2c/i2c.c new file mode 100644 index 0000000000..f5ddb56703 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/i2c/i2c.c @@ -0,0 +1,315 @@ +/* I2C bus common (driver-independent) primitives implementation. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) i2c.c,v 1.5 2004/04/21 16:01:34 ralf Exp + */ + +#include "../include/bsp.h" +#include "../include/i2c.h" + +/* i2c_transfer_sema_done_func -- + * This function called from I2C driver layer to signal that I2C + * transfer is finished. This function resumes of task execution which + * has invoked blocking I2C primitive. + * + * PARAMETERS: + * arg - done function argument; it is RTEMS semaphore ID. + */ +static void +i2c_transfer_sema_done_func(uint32_t arg) +{ + rtems_id sema = (rtems_id)arg; + rtems_semaphore_release(sema); +} + +/* i2c_transfer_poll_done_func -- + * This function called from I2C driver layer to signal that I2C + * transfer is finished. This function set the flag polled by waiting + * function. + * + * PARAMETERS: + * arg - done function argument; address of poll_done_flag + */ +static void +i2c_transfer_poll_done_func(uint32_t arg) +{ + rtems_boolean *poll_done_flag = (rtems_boolean *)arg; + *poll_done_flag = 1; +} + +/* i2c_transfer_wait_sema -- + * Initiate I2C bus transfer and block on temporary created semaphore + * until this transfer will be finished. + * + * PARAMETERS: + * bus - I2C bus number + * msg - pointer to transfer messages array + * nmsg - number of messages in transfer + * + * RETURNS: + * RTEMS_SUCCESSFUL, if tranfer finished successfully, + * or RTEMS status code if semaphore operations has failed. + */ +static i2c_message_status +i2c_transfer_wait_sema(i2c_bus_number bus, i2c_message *msg, int nmsg) +{ + rtems_status_code sc; + rtems_id sema; + sc = rtems_semaphore_create( + rtems_build_name('I', '2', 'C', 'S'), + 0, + RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | + RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, + 0, + &sema + ); + if (sc != RTEMS_SUCCESSFUL) + return I2C_RESOURCE_NOT_AVAILABLE; + sc = i2c_transfer(bus, nmsg, msg, i2c_transfer_sema_done_func, sema); + if (sc != RTEMS_SUCCESSFUL) + { + rtems_semaphore_delete(sema); + return sc; + } + rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + sc = rtems_semaphore_delete(sema); + return sc; +} + +/* i2c_transfer_wait_poll -- + * Initiate I2C bus transfer and wait by poll transaction done flag until + * this transfer will be finished. + * + * PARAMETERS: + * bus - I2C bus number + * msg - pointer to transfer messages array + * nmsg - number of messages in transfer + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +static rtems_status_code +i2c_transfer_wait_poll(i2c_bus_number bus, i2c_message *msg, int nmsg) +{ + volatile rtems_boolean poll_done_flag; + rtems_status_code sc; + poll_done_flag = 0; + sc = i2c_transfer(bus, nmsg, msg, i2c_transfer_poll_done_func, + (uint32_t)&poll_done_flag); + if (sc != RTEMS_SUCCESSFUL) + return sc; + while (poll_done_flag == 0) + { + i2c_poll(bus); + } + return RTEMS_SUCCESSFUL; +} + +/* i2c_transfer_wait -- + * Initiate I2C bus transfer and block until this transfer will be + * finished. This function wait the semaphore if system in + * SYSTEM_STATE_UP state, or poll done flag in other states. + * + * PARAMETERS: + * bus - I2C bus number + * msg - pointer to transfer messages array + * nmsg - number of messages in transfer + * + * RETURNS: + * I2C_SUCCESSFUL, if tranfer finished successfully, + * I2C_RESOURCE_NOT_AVAILABLE, if semaphore operations has failed, + * value of status field of first error-finished message in transfer, + * if something wrong. + */ +i2c_message_status +i2c_transfer_wait(i2c_bus_number bus, i2c_message *msg, int nmsg) +{ + rtems_status_code sc; + int i; + if (_System_state_Is_up(_System_state_Get())) + { + sc = i2c_transfer_wait_sema(bus, msg, nmsg); + } + else + { + sc = i2c_transfer_wait_poll(bus, msg, nmsg); + } + + if (sc != RTEMS_SUCCESSFUL) + return I2C_RESOURCE_NOT_AVAILABLE; + + for (i = 0; i < nmsg; i++) + { + if (msg[i].status != I2C_SUCCESSFUL) + { + return msg[i].status; + } + } + return I2C_SUCCESSFUL; +} + +/* i2c_write -- + * Send single message over specified I2C bus to addressed device and + * wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * buf - data to be sent to device + * size - data buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_write(i2c_bus_number bus, i2c_address addr, void *buf, int size) +{ + i2c_message msg; + msg.addr = addr; + msg.flags = I2C_MSG_WR; + if (addr > 0xff) + msg.flags |= I2C_MSG_ADDR_10; + msg.status = 0; + msg.len = size; + msg.buf = buf; + return i2c_transfer_wait(bus, &msg, 1); +} + +/* i2c_wrbyte -- + * Send single one-byte long message over specified I2C bus to + * addressed device and wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * cmd - byte message to be sent to device + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wrbyte(i2c_bus_number bus, i2c_address addr, uint8_t cmd) +{ + i2c_message msg; + uint8_t data = cmd; + msg.addr = addr; + msg.flags = I2C_MSG_WR; + if (addr > 0xff) + msg.flags |= I2C_MSG_ADDR_10; + msg.status = 0; + msg.len = sizeof(data); + msg.buf = &data; + return i2c_transfer_wait(bus, &msg, 1); +} + +/* i2c_read -- + * receive single message over specified I2C bus from addressed device. + * This call will wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * buf - buffer for received message + * size - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_read(i2c_bus_number bus, i2c_address addr, void *buf, int size) +{ + i2c_message msg; + msg.addr = addr; + msg.flags = 0; + if (addr > 0xff) + msg.flags |= I2C_MSG_ADDR_10; + msg.status = 0; + msg.len = size; + msg.buf = buf; + return i2c_transfer_wait(bus, &msg, 1); +} + +/* i2c_wrrd -- + * Send message over I2C bus to specified device and receive message + * from the same device during single transfer. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * bufw - data to be sent to device + * sizew - send data buffer size + * bufr - buffer for received message + * sizer - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wrrd(i2c_bus_number bus, i2c_address addr, void *bufw, int sizew, + void *bufr, int sizer) +{ + i2c_message msg[2]; + msg[0].addr = addr; + msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP; + if (addr > 0xff) + msg[0].flags |= I2C_MSG_ADDR_10; + msg[0].status = 0; + msg[0].len = sizew; + msg[0].buf = bufw; + + msg[1].addr = addr; + msg[1].flags = 0; + if (addr > 0xff) + msg[1].flags |= I2C_MSG_ADDR_10; + msg[1].status = 0; + msg[1].len = sizer; + msg[1].buf = bufr; + + return i2c_transfer_wait(bus, msg, 2); +} + +/* i2c_wbrd -- + * Send one-byte message over I2C bus to specified device and receive + * message from the same device during single transfer. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * cmd - one-byte message to be sent over I2C bus + * bufr - buffer for received message + * sizer - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wbrd(i2c_bus_number bus, i2c_address addr, uint8_t cmd, + void *bufr, int sizer) +{ + i2c_message msg[2]; + uint8_t bufw = cmd; + msg[0].addr = addr; + msg[0].flags = I2C_MSG_WR | I2C_MSG_ERRSKIP; + if (addr > 0xff) + msg[0].flags |= I2C_MSG_ADDR_10; + msg[0].status = 0; + msg[0].len = sizeof(bufw); + msg[0].buf = &bufw; + + msg[1].addr = addr; + msg[1].flags = I2C_MSG_ERRSKIP; + if (addr > 0xff) + msg[1].flags |= I2C_MSG_ADDR_10; + msg[1].status = 0; + msg[1].len = sizer; + msg[1].buf = bufr; + + return i2c_transfer_wait(bus, msg, 2); +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/i2c/i2cdrv.c b/c/src/lib/libbsp/powerpc/gen5200/i2c/i2cdrv.c new file mode 100644 index 0000000000..023b37fd78 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/i2c/i2cdrv.c @@ -0,0 +1,309 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: i2cdrv.c ++-----------------------------------------------------------------+ +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| I2C driver for MPC5200 | ++-----------------------------------------------------------------+ +| This file has been adapted from an existing source code file, | +| see the original file header below for reference | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.8 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.7 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ + +/* I2C driver for MCF5206eLITE board. I2C bus accessed through on-chip + * MCF5206e MBUS controller. + * + * The purpose of this module is to perform I2C driver initialization + * and serialize I2C transfers. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) i2cdrv.c,v 1.6 2004/04/21 16:01:34 ralf Exp + */ + +#include "../include/bsp.h" +#include <stdlib.h> +#include <string.h> + +#include "../include/i2c.h" +#include "../include/i2cdrv.h" +#include "mpc5200mbus.h" + +#ifndef I2C_NUMBER_OF_BUSES +#define I2C_NUMBER_OF_BUSES (2) +#endif + +#ifndef I2C_SELECT_BUS +#define I2C_SELECT_BUS(bus) +#endif + +/* + * Few I2C transfers may be posted simultaneously, but MBUS driver is able + * to process it one-by-one. To serialize transfers, function i2c_transfer + * put transfer information to the queue and initiate new transfers if MBUS + * driver is not busy. When driver is busy, next transfer is dequeued + * when current active transfer is finished. + */ + +/* + * i2c_qel - I2C transfers queue element; contain information about + * delayed transfer + */ +typedef struct i2c_qel { + i2c_bus_number bus; /* I2C bus number */ + i2c_message *msg; /* pointer to the transfer' messages array */ + int nmsg; /* number of messages in transfer */ + i2c_transfer_done done; /* transfer done callback function */ + uint32_t done_arg; /* arbitrary argument to done callback */ +} i2c_qel; + +/* Memory for I2C transfer queue. This queue represented like a ring buffer */ +static i2c_qel *tqueue; + +/* Maximum number of elements in transfer queue */ +static int tqueue_size; + +/* Position of next free element in a ring buffer */ +static volatile int tqueue_head; + +/* Position of the first element in transfer queue */ +static volatile int tqueue_tail; + +/* MBus I2C bus controller busy flag */ +static volatile rtems_boolean mbus_busy; + +/* MBus I2C bus controller descriptor */ +static mpc5200mbus mbus[I2C_NUMBER_OF_BUSES]; + +/* Clock rate selected for each of bus */ +static int i2cdrv_bus_clock_div[I2C_NUMBER_OF_BUSES]; + +/* Currently selected I2C bus clock rate */ +static int i2cdrv_bus_clock_div_current; + +/* Forward function declaration */ +static void i2cdrv_unload(void); + +/* i2cdrv_done -- + * Callback function which is called from MBus low-level driver when + * transfer is finished. + */ +static void +i2cdrv_done(uint32_t arg) +{ + rtems_interrupt_level level; + i2c_qel *qel = tqueue + tqueue_tail; + qel->done(qel->done_arg); + rtems_interrupt_disable(level); + tqueue_tail = (tqueue_tail + 1) % tqueue_size; + mbus_busy = 0; + rtems_interrupt_enable(level); + i2cdrv_unload(); +} + +/* i2cdrv_unload -- + * If MBUS controller is not busy and transfer waiting in a queue, + * initiate processing of the next transfer in queue. + */ +static void +i2cdrv_unload(void) +{ + rtems_interrupt_level level; + i2c_qel *qel; + rtems_status_code sc; + rtems_interrupt_disable(level); + if (!mbus_busy && (tqueue_head != tqueue_tail)) + { + mbus_busy = 1; + rtems_interrupt_enable(level); + qel = tqueue + tqueue_tail; + + I2C_SELECT_BUS(qel->bus); + if (i2cdrv_bus_clock_div[qel->bus] != i2cdrv_bus_clock_div_current) + { + i2cdrv_bus_clock_div_current = i2cdrv_bus_clock_div[qel->bus]; + mpc5200mbus_select_clock_divider(&mbus[qel->bus], i2cdrv_bus_clock_div_current); + } + sc = mpc5200mbus_i2c_transfer(&mbus[qel->bus], qel->nmsg, qel->msg, i2cdrv_done, + (uint32_t)qel); + if (sc != RTEMS_SUCCESSFUL) + { + int i; + for (i = 0; i < qel->nmsg; i++) + { + qel->msg[i].status = I2C_RESOURCE_NOT_AVAILABLE; + } + i2cdrv_done((uint32_t)qel); + } + } + else + { + rtems_interrupt_enable(level); + } +} + +/* i2c_transfer -- + * Initiate multiple-messages transfer over specified I2C bus or + * put request into queue if bus or some other resource is busy. (This + * is non-blocking function). + * + * PARAMETERS: + * bus - I2C bus number + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code if something failed. + */ +rtems_status_code +i2c_transfer(i2c_bus_number bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, uint32_t done_arg) +{ + i2c_qel qel; + rtems_interrupt_level level; + + if (bus >= I2C_NUMBER_OF_BUSES) + { + return RTEMS_INVALID_NUMBER; + } + + if (msg == NULL) + { + return RTEMS_INVALID_ADDRESS; + } + + qel.bus = bus; + qel.msg = msg; + qel.nmsg = nmsg; + qel.done = done; + qel.done_arg = done_arg; + rtems_interrupt_disable(level); + if ((tqueue_head + 1) % tqueue_size == tqueue_tail) + { + rtems_interrupt_enable(level); + return RTEMS_TOO_MANY; + } + memcpy(tqueue + tqueue_head, &qel, sizeof(qel)); + tqueue_head = (tqueue_head + 1) % tqueue_size; + rtems_interrupt_enable(level); + i2cdrv_unload(); + return RTEMS_SUCCESSFUL; +} + +/* i2cdrv_initialize -- + * I2C driver initialization (rtems I/O driver primitive) + */ +rtems_device_driver +i2cdrv_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + int i; + rtems_status_code sc; + mbus_busy = 0; + tqueue_tail = tqueue_head = 0; + tqueue_size = 32; + tqueue = calloc(tqueue_size, sizeof(i2c_qel)); + + for (i = 0; i < I2C_NUMBER_OF_BUSES; i++) + { + mbus[i].bus_idx = i; + sc = mpc5200mbus_initialize(&mbus[i]); + if (sc != RTEMS_SUCCESSFUL) + return sc; + } + + for (i = 0; i < I2C_NUMBER_OF_BUSES; i++) + { + sc = i2c_select_clock_rate(i, 100000); + if (sc != RTEMS_SUCCESSFUL) + return sc; + } + i2cdrv_bus_clock_div_current = -1; + return RTEMS_SUCCESSFUL; +} + +/* i2c_select_clock_rate -- + * select I2C bus clock rate for specified bus. Some bus controller do not + * allow to select arbitrary clock rate; in this case nearest possible + * slower clock rate is selected. + * + * PARAMETERS: + * bus - I2C bus number + * bps - data transfer rate for this bytes in bits per second + * + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, + * RTEMS_INVALID_NUMBER, if wrong bus number is specified, + * RTEMS_UNSATISFIED, if bus do not support data transfer rate selection + * or specified data transfer rate could not be used. + */ +rtems_status_code +i2c_select_clock_rate(i2c_bus_number bus, int bps) +{ + int div; + if (bus >= I2C_NUMBER_OF_BUSES) + return RTEMS_INVALID_NUMBER; + + if (bps == 0) + return RTEMS_UNSATISFIED; + + div = IPB_CLOCK / bps; + i2cdrv_bus_clock_div[bus] = div; + return RTEMS_SUCCESSFUL; +} + +/* i2c_poll -- + * Poll I2C bus controller for events and hanle it. This function is + * used when I2C driver operates in poll-driven mode. + * + * PARAMETERS: + * bus - bus number to be polled + * + * RETURNS: + * none + */ +void +i2c_poll(i2c_bus_number bus) +{ + mpc5200mbus_poll(&mbus[bus]); +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.c b/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.c new file mode 100644 index 0000000000..74c74e1a79 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.c @@ -0,0 +1,698 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: mpc5200mbus.c ++-----------------------------------------------------------------+ +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| MBUS module (I2C bus) driver | ++-----------------------------------------------------------------+ +| This file has been adapted from an existing source code file, | +| see the original file header below for reference | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.7 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.6 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.5 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ + +/* MCF5206e MBUS module (I2C bus) driver + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) mcfmbus.c,v 1.4 2004/03/31 01:59:32 ralf Exp + */ +#include "mpc5200mbus.h" +#include "../include/mpc5200.h" +#include "../irq/irq.h" +#include "../include/i2c.h" + +/* Events of I2C machine */ +typedef enum i2c_event { + EVENT_NONE, /* Spurious event */ + EVENT_TRANSFER, /* Start new transfer */ + EVENT_NEXTMSG, /* Start processing of next message in transfer */ + EVENT_ACK, /* Sending finished with ACK */ + EVENT_NACK, /* Sending finished with NACK */ + EVENT_TIMEOUT, /* Timeout occured */ + EVENT_DATA_RECV, /* Data received */ + EVENT_ARB_LOST, /* Arbitration lost */ + EVENT_SLAVE /* Addressed as a slave */ +} i2c_event; + +/*** Auxillary primitives ***/ + +/* Change state of finite state machine */ +#define next_state(bus,new_state) \ + do { \ + (bus)->state = (new_state); \ + } while (0) + +/* Initiate start condition on the I2C bus */ +#define mpc5200mbus_start(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_MSTA; \ + } while (0) + +/* Initiate stop condition on the I2C bus */ +#define mpc5200mbus_stop(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MSTA; \ + } while (0) + +/* Initiate repeat start condition on the I2C bus */ +#define mpc5200mbus_rstart(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_RSTA; \ + } while (0) + +/* Send byte to the bus */ +#define mpc5200mbus_send(bus,byte) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mdr = (byte); \ + } while (0) + +/* Set transmit mode */ +#define mpc5200mbus_tx_mode(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_MTX; \ + } while (0) + +/* Set receive mode */ +#define mpc5200mbus_rx_mode(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MTX; \ + (void)mpc5200.i2c_regs[bus->bus_idx].mdr; \ + } while (0) + + +/* Transmit acknowledge when byte received */ +#define mpc5200mbus_send_ack(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_TXAK; \ + } while (0) + +/* DO NOT transmit acknowledge when byte received */ +#define mpc5200mbus_send_nack(bus) \ + do { \ + mpc5200.i2c_regs[bus->bus_idx].mcr |= MPC5200_I2C_MCR_TXAK; \ + } while (0) + +#define mpc5200mbus_error(bus,err_status) \ + do { \ + do { \ + (bus)->cmsg->status = (err_status); \ + (bus)->cmsg++; \ + } while (((bus)->cmsg - (bus)->msg < (bus)->nmsg) && \ + ((bus)->cmsg->flags & I2C_MSG_ERRSKIP)); \ + bus->cmsg--; \ + } while (0) + +/* mpc5200mbus_get_event -- + * Read MBUS module status register, determine interrupt reason and + * return appropriate event. + * + * PARAMETERS: + * bus - pointer to MBUS module descriptor structure + * + * RETURNS: + * event code + */ +static i2c_event +mpc5200mbus_get_event(mpc5200mbus *bus) +{ + i2c_event event; + uint8_t status, control; + rtems_interrupt_level level; + rtems_interrupt_disable(level); + status = mpc5200.i2c_regs[bus->bus_idx].msr; + control = mpc5200.i2c_regs[bus->bus_idx].mcr; + if (status & MPC5200_I2C_MSR_MIF) /* Interrupt occured */ + { + if (status & MPC5200_I2C_MSR_MAAS) + { + event = EVENT_SLAVE; + mpc5200.i2c_regs[bus->bus_idx].mcr = control; /* To clear Addressed As Slave + condition */ + } + else if (status & MPC5200_I2C_MSR_MAL) /* Arbitration lost */ + { + mpc5200.i2c_regs[bus->bus_idx].msr = status & ~MPC5200_I2C_MSR_MAL; + event = EVENT_ARB_LOST; + } + else if (control & MPC5200_I2C_MCR_MTX) /* Trasmit mode */ + { + if (status & MPC5200_I2C_MSR_RXAK) + event = EVENT_NACK; + else + event = EVENT_ACK; + } + else /* Received */ + { + event = EVENT_DATA_RECV; + } + + /* Clear interrupt condition */ + mpc5200.i2c_regs[bus->bus_idx].msr &= ~MPC5200_I2C_MSR_MIF; + } + else + { + event = EVENT_NONE; + } + rtems_interrupt_enable(level); + return event; +} + +static void +mpc5200mbus_machine_error(mpc5200mbus *bus, i2c_event event) +{ + return; +} + +/* mpc5200mbus_machine -- + * finite state machine for I2C bus protocol + * + * PARAMETERS: + * bus - pointer to ColdFire MBUS descriptor structure + * event - I2C event + * + * RETURNS: + * none + */ +static void +mpc5200mbus_machine(mpc5200mbus *bus, i2c_event event) +{ + uint8_t b; + switch (bus->state) + { + + case STATE_UNINITIALIZED: + /* this should never happen. */ + mpc5200mbus_machine_error(bus, event); + break; + case STATE_IDLE: + switch (event) + { + case EVENT_NEXTMSG: /* Start new message processing */ + bus->cmsg++; + /* FALLTHRU */ + + case EVENT_TRANSFER: /* Initiate new transfer */ + if (bus->cmsg - bus->msg >= bus->nmsg) + { + mpc5200mbus_stop(bus); + next_state(bus, STATE_IDLE); + bus->msg = bus->cmsg = NULL; + bus->nmsg = bus->byte = 0; + bus->done(bus->done_arg); + break; + } + + /* Initiate START or REPEATED START condition on the bus */ + if (event == EVENT_TRANSFER) + { + mpc5200mbus_start(bus); + } + else /* (event == EVENT_NEXTMSG) */ + { + mpc5200mbus_rstart(bus); + } + + bus->byte = 0; + mpc5200mbus_tx_mode(bus); + + /* Initiate slave address sending */ + if (bus->cmsg->flags & I2C_MSG_ADDR_10) + { + i2c_address a = bus->cmsg->addr; + b = 0xf0 | (((a >> 8) & 0x03) << 1); + if (bus->cmsg->flags & I2C_MSG_WR) + { + mpc5200mbus_send(bus, b); + next_state(bus, STATE_ADDR_1_W); + } + else + { + mpc5200mbus_send(bus, b | 1); + next_state(bus, STATE_ADDR_1_R); + } + } + else + { + b = (bus->cmsg->addr & ~0x01); + + if (bus->cmsg->flags & I2C_MSG_WR) + { + next_state(bus, STATE_SENDING); + } + else + { + next_state(bus, STATE_ADDR_7); + b |= 1; + } + + mpc5200mbus_send(bus, b); + } + break; + + default: + mpc5200mbus_machine_error(bus, event); + break; + } + break; + + case STATE_ADDR_7: + switch (event) + { + case EVENT_ACK: + mpc5200mbus_rx_mode(bus); + if (bus->cmsg->len <= 1) + mpc5200mbus_send_nack(bus); + else + mpc5200mbus_send_ack(bus); + next_state(bus, STATE_RECEIVING); + break; + + case EVENT_NACK: + mpc5200mbus_error(bus, I2C_NO_DEVICE); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mpc5200mbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mpc5200mbus_machine_error(bus, event); + break; + } + break; + + case STATE_ADDR_1_R: + case STATE_ADDR_1_W: + switch (event) + { + case EVENT_ACK: + { + uint8_t b = (bus->cmsg->addr & 0xff); + mpc5200mbus_send(bus, b); + if (bus->state == STATE_ADDR_1_W) + { + next_state(bus, STATE_SENDING); + } + else + { + i2c_address a; + mpc5200mbus_rstart(bus); + mpc5200mbus_tx_mode(bus); + a = bus->cmsg->addr; + b = 0xf0 | (((a >> 8) & 0x03) << 1) | 1; + mpc5200mbus_send(bus, b); + next_state(bus, STATE_ADDR_7); + } + break; + } + + case EVENT_NACK: + mpc5200mbus_error(bus, I2C_NO_DEVICE); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mpc5200mbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mpc5200mbus_machine_error(bus, event); + break; + } + break; + + case STATE_SENDING: + switch (event) + { + case EVENT_ACK: + if (bus->byte == bus->cmsg->len) + { + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + } + else + { + mpc5200mbus_send(bus, bus->cmsg->buf[bus->byte++]); + next_state(bus, STATE_SENDING); + } + break; + + case EVENT_NACK: + if (bus->byte == 0) + { + mpc5200mbus_error(bus, I2C_NO_DEVICE); + } + else + { + mpc5200mbus_error(bus, I2C_NO_ACKNOWLEDGE); + } + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + case EVENT_ARB_LOST: + mpc5200mbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mpc5200mbus_machine_error(bus, event); + break; + + } + break; + + case STATE_RECEIVING: + switch (event) + { + case EVENT_DATA_RECV: + if (bus->cmsg->len - bus->byte <= 2) + { + mpc5200mbus_send_nack(bus); + if (bus->cmsg->len - bus->byte <= 1) + { + if (bus->cmsg - bus->msg + 1 == bus->nmsg) + mpc5200mbus_stop(bus); + else + mpc5200mbus_rstart(bus); + } + } + else + { + mpc5200mbus_send_ack(bus); + } + bus->cmsg->buf[bus->byte++] = mpc5200.i2c_regs[bus->bus_idx].mdr; + if (bus->cmsg->len == bus->byte) + { + next_state(bus,STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + } + else + { + next_state(bus,STATE_RECEIVING); + } + break; + + case EVENT_ARB_LOST: + mpc5200mbus_error(bus, I2C_ARBITRATION_LOST); + next_state(bus, STATE_IDLE); + mpc5200mbus_machine(bus, EVENT_NEXTMSG); + break; + + default: + mpc5200mbus_machine_error(bus, event); + break; + } + break; + } +} + +/* mpc5200mbus_interrupt_handler -- + * MBUS module interrupt handler routine + * + * PARAMETERS: + * handle: pointer to mbus structure + * + * RETURNS: + * none + */ +void mpc5200mbus_interrupt_handler(rtems_irq_hdl_param handle) +{ + i2c_event event; + mpc5200mbus *bus = handle; + + event = mpc5200mbus_get_event(bus); + /* + * clear interrupt bit + */ + mpc5200.i2c_regs[bus->bus_idx].msr &= ~MPC5200_I2C_MSR_MIF; + + mpc5200mbus_machine(bus, event); +} + +/* + * mpc5200_mbus_irq_enable + * enable irq for mbus + */ +void mpc5200mbus_irq_enable(const rtems_irq_connect_data* ptr) +{ + int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx; + + mpc5200.i2c_regs[minor].mcr |= MPC5200_I2C_MCR_MIEN; +} + +/* + * mpc5200_mbus_irq_disable + * enable irq for mbus + */ +void mpc5200mbus_irq_disable(const rtems_irq_connect_data* ptr) +{ + int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx; + + mpc5200.i2c_regs[minor].mcr &= ~MPC5200_I2C_MCR_MIEN; +} + +/* + * mpc5200_mbus_isOn + * check, whether irq is enabled + */ +int mpc5200mbus_irq_isOn(const rtems_irq_connect_data* ptr) +{ + int minor = ((mpc5200mbus*)(ptr->handle))->bus_idx; + + return (0 != (mpc5200.i2c_regs[minor].mcr & MPC5200_I2C_MCR_MIEN)); +} + +/* mpc5200mbus_poll -- + * MBUS module poll routine; used to poll events when I2C driver + * operates in poll-driven mode. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void +mpc5200mbus_poll(mpc5200mbus *bus) +{ + i2c_event event; + event = mpc5200mbus_get_event(bus); + if (event != EVENT_NONE) + mpc5200mbus_machine(bus, event); +} + +/* mpc5200mbus_select_clock_divider -- + * Select divider for system clock which is used for I2C bus clock + * generation. Not each divider can be selected for I2C bus; this + * function select nearest larger or equal divider. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * divider - system frequency divider for I2C serial clock. + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, or + * RTEMS error code when failed. + */ +rtems_status_code +mpc5200mbus_select_clock_divider(mpc5200mbus *bus, int divider) +{ + int i; + int mbc; + struct { + int divider; + int mbc; + } dividers[] ={ + { 20, 0x20 }, { 22, 0x21 }, { 24, 0x22 }, { 26, 0x23 }, + { 28, 0x00 }, { 30, 0x01 }, { 32, 0x25 }, { 34, 0x02 }, + { 36, 0x26 }, { 40, 0x03 }, { 44, 0x04 }, { 48, 0x05 }, + { 56, 0x06 }, { 64, 0x2a }, { 68, 0x07 }, { 72, 0x2B }, + { 80, 0x08 }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, + { 112, 0x2E }, { 128, 0x0B }, { 144, 0x0C }, { 160, 0x0D }, + { 192, 0x0E }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, + { 288, 0x10 }, { 320, 0x11 }, { 384, 0x12 }, { 448, 0x36 }, + { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x15 }, + { 768, 0x16 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, + { 1152, 0x18 }, { 1280, 0x19 }, { 1536, 0x1A }, { 1792, 0x3E }, + { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, + { 3072, 0x1E }, { 3840, 0x1F } + }; + + if (bus == NULL) + return RTEMS_INVALID_ADDRESS; + + for (i = 0, mbc = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) + { + mbc = dividers[i].mbc; + if (dividers[i].divider >= divider) + { + break; + } + } + mpc5200.i2c_regs[bus->bus_idx].mfdr = mbc; + return RTEMS_SUCCESSFUL; +} + +/* mpc5200mbus_initialize -- + * Initialize MPC5200 MBUS I2C bus controller. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed. + */ +rtems_status_code +mpc5200mbus_initialize(mpc5200mbus *i2c_bus) +{ + rtems_interrupt_level level; + rtems_status_code sc; + rtems_irq_connect_data mbusIrqData; + + if (i2c_bus == NULL) + return RTEMS_INVALID_ADDRESS; + + if (i2c_bus->state != STATE_UNINITIALIZED) /* Check if already initialized */ + return RTEMS_RESOURCE_IN_USE; + + i2c_bus->state = STATE_IDLE; + i2c_bus->msg = NULL; + i2c_bus->cmsg = NULL; + i2c_bus->nmsg = 0; + i2c_bus->byte = 0; + + /* + * install interrupt handler + */ + mbusIrqData.on = mpc5200mbus_irq_enable; + mbusIrqData.off = mpc5200mbus_irq_disable; + mbusIrqData.isOn = mpc5200mbus_irq_isOn; + mbusIrqData.handle = (rtems_irq_hdl_param)i2c_bus; + mbusIrqData.hdl = mpc5200mbus_interrupt_handler; + switch(i2c_bus->bus_idx) { + case 0: + mbusIrqData.name = BSP_SIU_IRQ_I2C1; + break; + case 1: + mbusIrqData.name = BSP_SIU_IRQ_I2C2; + break; + } + if (!BSP_install_rtems_irq_handler (&mbusIrqData)) { + sc = RTEMS_UNSATISFIED; + return sc; + } + + rtems_interrupt_disable(level); + + mpc5200.i2c_regs[i2c_bus->bus_idx].mcr &= ~MPC5200_I2C_MCR_MEN; + mpc5200.i2c_regs[i2c_bus->bus_idx].msr = 0; + mpc5200.i2c_regs[i2c_bus->bus_idx].mdr = 0x1F; /* Maximum possible divider is 3840 */ + mpc5200.i2c_regs[i2c_bus->bus_idx].mcr |= MPC5200_I2C_MCR_MEN; + + rtems_interrupt_enable(level); + + return RTEMS_SUCCESSFUL; +} + +/* mpc5200mbus_i2c_transfer -- + * Initiate multiple-messages transfer over I2C bus via ColdFire MBUS + * controller. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mpc5200mbus_i2c_transfer(mpc5200mbus *bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, uint32_t done_arg) +{ + if (bus->state == STATE_UNINITIALIZED) + return RTEMS_NOT_CONFIGURED; + + bus->done = done; + bus->done_arg = done_arg; + bus->cmsg = bus->msg = msg; + bus->nmsg = nmsg; + bus->byte = 0; + bus->state = STATE_IDLE; + mpc5200mbus_machine(bus, EVENT_TRANSFER); + return RTEMS_SUCCESSFUL; +} + + +/* mpc5200mbus_i2c_done -- + * Close ColdFire MBUS I2C bus controller and release all resources. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * + * RETURNS: + * RTEMS_SUCCESSFUL, if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mpc5200mbus_i2c_done(mpc5200mbus *i2c_bus) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + if (i2c_bus->state == STATE_UNINITIALIZED) + return RTEMS_NOT_CONFIGURED; + + mpc5200.i2c_regs[i2c_bus->bus_idx].mcr = 0; + + return sc; +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.h b/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.h new file mode 100644 index 0000000000..78975d66d8 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/i2c/mpc5200mbus.h @@ -0,0 +1,171 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: mpc5200mbus.h ++-----------------------------------------------------------------+ +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| MBUS module (I2C bus) definitions | ++-----------------------------------------------------------------+ +| This file has been adapted from an existing source code file, | +| see the original file header below for reference | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.5 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.4 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/* + * MCF5206e MBUS module (I2C bus) driver header file + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) mcfmbus.h,v 1.3 2004/03/31 01:59:32 ralf Exp + */ + +#ifndef __MPC5200BSP_MPC5200MBUS_H__ +#define __MPC5200BSP_MPC5200MBUS_H__ + +#include "../include/mpc5200.h" +#include "../include/i2c.h" + +/* States of I2C machine */ +typedef enum mpc5200mbus_i2c_state { + STATE_UNINITIALIZED, + STATE_IDLE, + STATE_ADDR_7, + STATE_ADDR_1_W, + STATE_ADDR_1_R, + STATE_SENDING, + STATE_RECEIVING +} mpc5200mbus_i2c_state; + +typedef struct mpc5200_mbus { + enum mpc5200mbus_i2c_state state;/* State of I2C machine */ + i2c_message *msg; /* Pointer to the first message in transfer */ + int nmsg; /* Number of messages in transfer */ + i2c_message *cmsg; /* Current message */ + int byte; /* Byte number in current message */ + rtems_id sema; /* MBUS semaphore */ + i2c_transfer_done done; /* Transfer done function */ + uint32_t done_arg; /* Done function argument */ + int bus_idx; /* bus index: 0 or 1 */ +} mpc5200mbus; + +/* mpc5200mbus_initialize -- + * Initialize ColdFire MBUS I2C bus controller. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed. + */ +rtems_status_code +mpc5200mbus_initialize(mpc5200mbus *i2c_bus); + +/* mpc5200mbus_select_clock_divider -- + * Select divider for system clock which is used for I2C bus clock + * generation. Not each divider can be selected for I2C bus; this + * function select nearest larger or equal divider, or maximum + * possible divider, if passed value greater. + * + * PARAMETERS: + * i2c_bus - pointer to the bus descriptor structure + * divider - system frequency divider for I2C serial clock. + * + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, or + * RTEMS error code when failed. + */ +rtems_status_code +mpc5200mbus_select_clock_divider(mpc5200mbus *i2c_bus, int divider); + +/* mpc5200mbus_i2c_transfer -- + * Initiate multiple-messages transfer over I2C bus via ColdFire MBUS + * controller. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mpc5200mbus_i2c_transfer(mpc5200mbus *bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, uint32_t done_arg); + +/* mpc5200mbus_i2c_done -- + * Close ColdFire MBUS I2C bus controller and release all resources. + * + * PARAMETERS: + * bus - pointer to MBUS controller descriptor + * + * RETURNS: + * RTEMS_SUCCESSFUL, if transfer initiated successfully, or error + * code when failed. + */ +rtems_status_code +mpc5200mbus_i2c_done(mpc5200mbus *i2c_bus); + +/* mpc5200mbus_i2c_interrupt_handler -- + * ColdFire MBUS I2C bus controller interrupt handler. This function + * called from real interrupt handler, and pointer to MBUS descriptor + * structure passed to this function. + * + * PARAMETERS: + * bus - pointert to the bus descriptor structure + * + * RETURNS: + * none + */ +void mpc5200mbus_i2c_interrupt_handler(mpc5200mbus *bus); + +/* mpc5200mbus_poll -- + * MBUS module poll routine; used to poll events when I2C driver + * operates in poll-driven mode. + * + * PARAMETERS: + * none + * + * RETURNS: + * none + */ +void mpc5200mbus_poll(mpc5200mbus *bus); + +#endif /* __MPC5200BSP_MPC5200MBUS_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/ide/idecfg.c b/c/src/lib/libbsp/powerpc/gen5200/ide/idecfg.c new file mode 100644 index 0000000000..f4cdc5aeaa --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/ide/idecfg.c @@ -0,0 +1,123 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: idecfg.c ++-----------------------------------------------------------------+ +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the IDE configuration | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.5 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.4 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.3 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +#include <rtems.h> +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include "./pcmcia_ide.h" + +#include <libchip/ide_ctrl.h> +#include <libchip/ide_ctrl_cfg.h> +#include <libchip/ide_ctrl_io.h> + +/* + * The following table configures the IDE driver used in this BSP. + */ +extern ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns; + +volatile uint32_t * mpc5200_ata_drive_regs[] = + { + (uint32_t *)&(mpc5200.ata_ddr), /* data (offset 0x00) */ + (uint32_t *)&(mpc5200.ata_dfr_der), /* features / error (offset 0x01) */ + (uint32_t *)&(mpc5200.ata_dscr), /* sector count (offset 0x02) */ + (uint32_t *)&(mpc5200.ata_dsnr), /* sector no. / lba0 (offset 0x03) */ + (uint32_t *)&(mpc5200.ata_dclr), /* cylinder low / lba1 (offset 0x04) */ + (uint32_t *)&(mpc5200.ata_dchr), /* cylinder high/ lba2 (offset 0x05) */ + (uint32_t *)&(mpc5200.ata_ddhr), /* device head / lba3 (offset 0x06) */ + (uint32_t *)&(mpc5200.ata_dcr_dsr), /* command /status (offset 0x07) */ + + (uint32_t *)&(mpc5200.ata_dctr_dasr), /* device control / alternate status (offset 0x08) */ + (uint32_t *)&(mpc5200.ata_ddr), /* (offset 0x09) */ + (uint32_t *)&(mpc5200.ata_ddr), /* (offset 0x0A) */ + NULL, /* (offset 0x0B) */ + NULL, /* (offset 0x0C) */ + NULL, /* (offset 0x0D) */ + NULL, /* (offset 0x0E) */ + NULL /* (offset 0x0F) */ + }; + +/* IDE controllers Table */ +ide_controller_bsp_table_t IDE_Controller_Table[] = + { + { + "/dev/idepcmcia", + IDE_CUSTOM, /* PCMCIA Flash cards emulate custom IDE controller */ + &mpc5200_pcmciaide_ctrl_fns, /* pointer to function set used for IDE drivers in this BSP */ + NULL, /* no BSP dependent probe needed */ + FALSE, /* not (yet) initialized */ + (uint32_t)0, /* no port address but custom reg.set in params is used */ +#ifdef ATA_USE_INT + TRUE, /* interrupt driven */ +#else + FALSE, /* non interrupt driven */ +#endif + BSP_SIU_IRQ_ATA, /* interrupt vector */ + NULL /* no additional parameters */ + } +}; + +/* Number of rows in IDE_Controller_Table */ +unsigned long IDE_Controller_Count = sizeof(IDE_Controller_Table)/sizeof(IDE_Controller_Table[0]); + +uint32_t ata_pio_timings[2][6] = + { + /* PIO3 timings in nanosconds */ + { + 180, /* t0 cycle time */ + 80, /* t2 DIOR-/DIOW pulse width 8 bit */ + 80, /* t1 DIOR-/DIOW pulse width 16 bit */ + 10, /* t4 DIOW- data hold */ + 30, /* t1 Addr.valid to DIOR-/DIOW setup */ + 35, /* ta IORDY setup time */ + }, + /* PIO4 timings in nanosconds */ + { + 120, /* t0 cycle time */ + 70, /* t1 DIOR-/DIOW pulse width 8 bit */ + 70, /* t1 DIOR-/DIOW pulse width 16 bit */ + 10, /* t4 DIOW- data hold */ + 25, /* t1 Addr.valid to DIOR-/DIOW setup */ + 35, /* ta IORDY setup time */ + } + }; + + diff --git a/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c b/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c new file mode 100644 index 0000000000..04fd6e62d0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c @@ -0,0 +1,691 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: pcmcia_ide.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the PCMCIA IDE access functions | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.10 2005/12/09 09:05:16 thomas +|* changed names of board variations +|* +|* Revision 1.9 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.8 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.7 2005/12/06 14:11:11 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: pcmcia_ide.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 PCMCIA IDE harddisk driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: RTEMS MBX8xx PCMCIA IDE harddisc driver */ +/* Module: pcmcia_ide.c */ +/* Project: RTEMS 4.6.0pre1 / Mbx8xx BSP */ +/* Version */ +/* Date: 01/14/2003 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Copyright (c) 2003 IMD */ +/* Ingenieurbuero fuer Microcomputertechnik Th. Doerfler */ +/* <Thomas.Doerfler@imd-systems.de> */ +/* all rights reserved */ +/* */ +/* this file contains the BSP layer for PCMCIA IDE access below the */ +/* libchip IDE harddisc driver based on a board specific driver from */ +/* Eugeny S. Mints, Oktet */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include <rtems.h> +#include <rtems/error.h> +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include "./pcmcia_ide.h" + +#include <libchip/ide_ctrl.h> +#include <libchip/ide_ctrl_cfg.h> +#include <libchip/ide_ctrl_io.h> +#include <string.h> + +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif +#define IDE_DMA_TEST FALSE +#define IDE_USE_INT TRUE +#define IDE_READ_USE_DMA TRUE +#define IDE_USE_READ_PIO_OPT FALSE +#define IDE_WRITE_USE_DMA TRUE +#define IDE_USE_WRITE_PIO_OPT TRUE +/* #define IDE_USE_DMA (IDE_READ_USE_DMA||IDE_WRITE_USE_DMA) */ +#define IDE_USE_DMA TRUE +#define IDE_USE_STATISTICS TRUE + +#if IDE_USE_DMA +#define PCMCIA_IDE_DMA_WR_BD_CNT 2 +#define PCMCIA_IDE_DMA_RD_BD_CNT 2 +#define PCMCIA_IDE_INTERRUPT_EVENT RTEMS_EVENT_2 +/* Task number assignment */ +#include "../bestcomm/bestcomm_glue.h" +#include "../bestcomm/bestcomm_api.h" +#include "../bestcomm/task_api/bestcomm_cntrl.h" +#include "../bestcomm/task_api/tasksetup_bdtable.h" + +#define IDE_RECV_TASK_NO TASK_GEN_DP_BD_0 +#define TASK_GEN_DP_BD_1 TASK_GEN_DP_BD_1 +static TaskId pcmcia_ide_rxTaskId; /* SDMA RX task ID */ +static TaskId pcmcia_ide_txTaskId; /* SDMA TX task ID */ +#define PCMCIA_IDE_RD_SECTOR_SIZE 512 /* FIXME: make this better... */ +#define PCMCIA_IDE_WR_SECTOR_SIZE 512 /* FIXME: make this better... */ + +boolean mpc5200_dma_task_started[2] = {FALSE,FALSE}; +#endif /* IDE_USE_DMA */ + +#if IDE_USE_STATISTICS +uint32_t mpc5200_pcmciaide_write_block_call_cnt = 0; +uint32_t mpc5200_pcmciaide_write_block_block_cnt = 0; +uint32_t mpc5200_pcmciaide_read_block_call_cnt = 0; +uint32_t mpc5200_pcmciaide_read_block_block_cnt = 0; +#endif + +extern volatile uint32_t * mpc5200_ata_drive_regs[]; +extern uint32_t ata_pio_timings[2][6]; + +/* + * support functions for PCMCIA IDE IF + */ +boolean mpc5200_pcmciaide_probe(int minor) + { + boolean ide_card_plugged = FALSE; /* assume: we don't have a card plugged in */ + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT2]); + + /* enable card detection on GPT2 */ + gpt->emsel = (GPT_EMSEL_GPIO_IN | GPT_EMSEL_TIMER_MS_GPIO); + +#if defined (BRS5L) + /* Check for card detection (-CD0) */ + if((gpt->status) & GPT_STATUS_PIN) + ide_card_plugged = FALSE; + else +#endif + ide_card_plugged = TRUE; + + return ide_card_plugged; + + } + + +rtems_status_code mpc5200_pcmciaide_config_io_speed(int minor, uint16_t modes_avail) + { + uint8_t pio_t0, pio_t2_8, pio_t2_16, pio_t4, pio_t1, pio_ta; + + if((modes_avail & ATA_MODES_PIO4) != 0) + { + + pio_t0 = ata_pio_timings[PIO_4][T0]; + pio_t2_8 = ata_pio_timings[PIO_4][T2_8]; + pio_t2_16 = ata_pio_timings[PIO_4][T2_16]; + pio_t4 = ata_pio_timings[PIO_4][T4]; + pio_t1 = ata_pio_timings[PIO_4][T1]; + pio_ta = ata_pio_timings[PIO_4][TA]; + + } + else + { + + pio_t0 = ata_pio_timings[PIO_3][T0]; + pio_t2_8 = ata_pio_timings[PIO_3][T2_8]; + pio_t2_16 = ata_pio_timings[PIO_3][T2_16]; + pio_t4 = ata_pio_timings[PIO_3][T4]; + pio_t1 = ata_pio_timings[PIO_3][T1]; + pio_ta = ata_pio_timings[PIO_3][TA]; + + } + + /* set timings according according to selected ATA mode */ + mpc5200.ata_pio1 = ATA_PIO_TIMING_1(pio_t0, pio_t2_8, pio_t2_16); + mpc5200.ata_pio2 = ATA_PIO_TIMING_2(pio_t4, pio_t1, pio_ta); + + return RTEMS_SUCCESSFUL; + + } + + + +void mpc5200_pcmciaide_read_reg(int minor, int reg, uint16_t *value) + { + volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg]; + + if(reg == IDE_REGISTER_DATA_WORD) + *value = *(volatile uint16_t *)(ata_reg); + else + *value = *(volatile uint8_t *)(ata_reg); + } + + +void mpc5200_pcmciaide_write_reg(int minor, int reg, uint16_t value) + { + volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[reg]; + + if(reg == IDE_REGISTER_DATA_WORD) + *(volatile uint16_t *)(ata_reg) = value; + else + *(volatile uint8_t *)(ata_reg) = value; + } + +#if IDE_USE_DMA + + +uint32_t pcmcia_ide_rxInterrupts; +uint32_t pcmcia_ide_txInterrupts; +volatile rtems_id pcmcia_ide_hdl_task = 0; +/* + * MPC5200 BestComm interrupt handlers + */ +static void pcmcia_ide_recv_dmairq_hdl(rtems_irq_hdl_param unused) +{ + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,TASK_GEN_DP_BD_0); + +/*Disable receive ints*/ + bestcomm_glue_irq_disable(TASK_GEN_DP_BD_0); + + pcmcia_ide_rxInterrupts++; /* Rx int has occurred */ + + if (pcmcia_ide_hdl_task != 0) { + rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT); + } +} + +static void pcmcia_ide_xmit_dmairq_hdl(rtems_irq_hdl_param unused) +{ + + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,TASK_GEN_DP_BD_1); + + /*Disable transmit ints*/ + bestcomm_glue_irq_disable(TASK_GEN_DP_BD_1); + + pcmcia_ide_txInterrupts++; /* Tx int has occurred */ + + if (pcmcia_ide_hdl_task != 0) { + rtems_event_send(pcmcia_ide_hdl_task,PCMCIA_IDE_INTERRUPT_EVENT); + } +} + + +void mpc5200_pcmciaide_dma_init(int minor) +{ + TaskSetupParamSet_t rxParam; /* RX task setup parameters */ + TaskSetupParamSet_t txParam; /* TX task setup parameters */ + /* + * Init Bestcomm system + */ + bestcomm_glue_init(); + /* + * Setup the SDMA RX task. + */ + rxParam.NumBD = PCMCIA_IDE_DMA_RD_BD_CNT; + rxParam.Size.MaxBuf = PCMCIA_IDE_RD_SECTOR_SIZE; + rxParam.Initiator = INITIATOR_ALWAYS; + rxParam.StartAddrSrc = + (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD]; + rxParam.IncrSrc = 0; + rxParam.SzSrc = sizeof(uint16_t); + rxParam.StartAddrDst = (uint32)NULL; + rxParam.IncrDst = sizeof(uint16_t); + rxParam.SzDst = sizeof(uint16_t); /* XXX: set this to 32 bit? */ + + pcmcia_ide_rxTaskId = TaskSetup(TASK_GEN_DP_BD_0,&rxParam ); + + /* + * Setup the TX task. + */ + txParam.NumBD = PCMCIA_IDE_DMA_WR_BD_CNT; + txParam.Size.MaxBuf = PCMCIA_IDE_WR_SECTOR_SIZE; + txParam.Initiator = INITIATOR_ALWAYS; + txParam.StartAddrSrc = (uint32)NULL; + txParam.IncrSrc = sizeof(uint16_t); + txParam.SzSrc = sizeof(uint16_t); /* do not set this to 32 bit! */ + txParam.StartAddrDst = + (uint32)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD]; + txParam.IncrDst = 0; + txParam.SzDst = sizeof(uint16_t); + + pcmcia_ide_txTaskId = TaskSetup( TASK_GEN_DP_BD_1, &txParam ); + /* + * FIXME: Init BD rings + */ + /* + * Enable the SmartDMA transmit/receive task. + * do not enable interrupts to CPU + */ + /* + * connect interrupt handlers + */ + bestcomm_glue_irq_install(TASK_GEN_DP_BD_1,pcmcia_ide_xmit_dmairq_hdl,NULL); + bestcomm_glue_irq_install(TASK_GEN_DP_BD_0,pcmcia_ide_recv_dmairq_hdl,NULL); +} + +void mpc5200_pcmciaide_dma_blockop(boolean is_write, + int minor, + uint16_t block_size, + blkdev_sg_buffer *bufs, + uint32_t *cbuf, + uint32_t *pos) + +{ + /* + * Nameing: + * - a block is one unit of data on disk (multiple sectors) + * - a buffer is a contignuous chunk of data in memory + * a block on disk may be filled with data from several buffers + */ + uint32_t buf_idx,bufs_from_dma, bufs_to_dma,bufs_total; + uint32_t bds_free; + uint32_t llength; + rtems_status_code rc = RTEMS_SUCCESSFUL; + rtems_event_set events; + BDIdx nxt_bd_idx; + boolean use_irq = (_System_state_Current == SYSTEM_STATE_UP); + /* + * determine number of blocks + */ + llength = 0; + buf_idx = 0; + bufs += *cbuf; /* *cbuf is the index of the next buffer to send in this transaction */ + while (llength < block_size) { + llength += bufs[buf_idx++].length; + } + bufs_from_dma = 0; + bufs_to_dma = 0; + bufs_total = buf_idx; + /* + * here all BDs should be unused + */ + bds_free = is_write ? PCMCIA_IDE_DMA_WR_BD_CNT : PCMCIA_IDE_DMA_RD_BD_CNT; + /* + * repeat, until all bufs are transferred + */ + while ((rc == RTEMS_SUCCESSFUL) && + (bufs_from_dma < bufs_total)) { + + while ((rc == RTEMS_SUCCESSFUL) && + (bufs_to_dma < bufs_total) && + (bds_free > 0)) { + /* + * fill in BD, set interrupt if needed + */ + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,(is_write + ? TASK_GEN_DP_BD_1 + : TASK_GEN_DP_BD_0)); + if (is_write) { + TaskBDAssign(pcmcia_ide_txTaskId , + (void *)bufs[bufs_to_dma].buffer, + (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD], + bufs[bufs_to_dma].length, + 0/* flags */); +#if IDE_USE_STATISTICS + mpc5200_pcmciaide_write_block_block_cnt++; +#endif + } + else { + TaskBDAssign(pcmcia_ide_rxTaskId , + (void *)mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD], + (void *)bufs[bufs_to_dma].buffer, + bufs[bufs_to_dma].length, + 0/* flags */); +#if IDE_USE_STATISTICS + mpc5200_pcmciaide_read_block_block_cnt++; +#endif + } + bufs_to_dma ++; + bds_free --; + } + if (is_write) { + TaskStart( pcmcia_ide_txTaskId, TASK_AUTOSTART_DISABLE, + pcmcia_ide_txTaskId, TASK_INTERRUPT_DISABLE ); + } + else { + TaskStart( pcmcia_ide_rxTaskId, TASK_AUTOSTART_DISABLE, + pcmcia_ide_rxTaskId, TASK_INTERRUPT_DISABLE ); + } + if (use_irq) { + + /* + * enable interrupts, wait for interrupt event + */ + rtems_task_ident(RTEMS_SELF,0,(rtems_id *)&pcmcia_ide_hdl_task); + bestcomm_glue_irq_enable((is_write + ? TASK_GEN_DP_BD_1 + : TASK_GEN_DP_BD_0)); + + rtems_event_receive(PCMCIA_IDE_INTERRUPT_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + + pcmcia_ide_hdl_task = 0; + } + else { + /* + * HACK: just wait some time... + */ + /* + * FIXME: poll, until SDMA is finished + */ + volatile int32_t i; + for (i = 0;i < 10000;i++) {}; + } + + do { + nxt_bd_idx = TaskBDRelease(is_write + ? pcmcia_ide_txTaskId + : pcmcia_ide_rxTaskId); + if ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) && + (nxt_bd_idx != TASK_ERR_BD_BUSY)) { + (*cbuf)++; + (*pos) += bufs[bufs_from_dma].length; + bufs_from_dma++; + } + } while ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) && + (nxt_bd_idx != TASK_ERR_BD_BUSY) && + (bufs_from_dma < bufs_to_dma)); + } +} +#endif /* IDE_USE_DMA */ + + +void mpc5200_pcmciaide_read_block(int minor, uint16_t block_size, blkdev_sg_buffer *bufs, + uint32_t *cbuf, uint32_t *pos) +{ + + volatile uint32_t *ata_reg=mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD]; + uint16_t cnt = 0; + uint16_t *lbuf = (uint16_t*)((uint8_t*)(bufs[(*cbuf)].buffer)+(*pos)); + uint32_t llength = bufs[(*cbuf)].length; + boolean use_dma; + +#if IDE_USE_STATISTICS + mpc5200_pcmciaide_read_block_call_cnt++; +#endif +#if IDE_READ_USE_DMA + /* + * FIXME: walk through buffer list. If any buffer has other size than default, + * then do not use DMA + * Is this needed? + */ + use_dma = TRUE; + /* use_dma = FALSE; */ +#else + use_dma = FALSE; +#endif + if (use_dma) { + /* + * FIXME: wait for DRQ ready + * check, that once DRQ is ready, we really can send ALL data for this + * type of transfer mode + */ + while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t) + (mpc5200.ata_dctr_dasr)) & + IDE_REGISTER_STATUS_DRQ) == 0); + /* + * translate (part of) buffer list into DMA BDs + * only last (available) DMA BD sends interrupt + * DMA BDs may get ready as soon as possible + */ + mpc5200_pcmciaide_dma_blockop(FALSE, /* read operation */ + minor, + block_size,bufs,cbuf,pos); + } + else { +#if IDE_USE_READ_PIO_OPT + while(cnt < block_size) { + + *lbuf++ = GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*(volatile uint32_t *)(ata_reg)); /* only 16 bit data port */ + cnt += 2; + (*pos) += 2; + + if((*pos) == llength) { + + (*pos) = 0; + (*cbuf)++; + lbuf = bufs[(*cbuf)].buffer; + llength = bufs[(*cbuf)].length; + + } + } +#else + + while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) & IDE_REGISTER_STATUS_DRQ) && (cnt < block_size)) { + + *lbuf++ = *(volatile uint16_t *)(ata_reg); /* only 16 bit data port */ + cnt += 2; + (*pos) += 2; + + if((*pos) == llength) { + (*pos) = 0; + (*cbuf)++; + lbuf = bufs[(*cbuf)].buffer; + llength = bufs[(*cbuf)].length; + } + } +#endif + while (cnt < block_size) { + *lbuf++ = 0; /* fill buffer with dummy data */ + cnt += 2; + (*pos) += 2; + + if((*pos) == llength) { + (*pos) = 0; + (*cbuf)++; + lbuf = bufs[(*cbuf)].buffer; + llength = bufs[(*cbuf)].length; + } + } + } +} + +void mpc5200_pcmciaide_write_block(int minor, uint16_t block_size, + blkdev_sg_buffer *bufs, uint32_t *cbuf, + uint32_t *pos) + +{ + + + volatile uint32_t *ata_reg = mpc5200_ata_drive_regs[IDE_REGISTER_DATA_WORD]; + uint16_t cnt = 0; + uint16_t *lbuf = (uint16_t *)((uint8_t *)(bufs[(*cbuf)].buffer) + (*pos)); + uint32_t llength = bufs[(*cbuf)].length; + boolean use_dma; + +#if IDE_USE_STATISTICS + mpc5200_pcmciaide_write_block_call_cnt++; +#endif +#if IDE_WRITE_USE_DMA + /* + * FIXME: walk through buffer list. If any buffer has other size than default, + * then do not use DMA + * Is this needed? + */ + use_dma = TRUE; +#else + use_dma = FALSE; +#endif + + if (use_dma) { + /* + * wait for DRQ ready + * FIXME: check, that once DRQ is ready, we really can send ALL data for this + * type of transfer mode + */ + while ((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t) + (mpc5200.ata_dctr_dasr)) & + IDE_REGISTER_STATUS_DRQ) == 0); + /* + * translate (part of) buffer list into DMA BDs + * only last (available) DMA BD sends interrupt + * DMA BDs may get ready as soon as possible + */ + mpc5200_pcmciaide_dma_blockop(TRUE, /* write opeartion */ + minor, + block_size,bufs,cbuf,pos); + } + else { +#if IDE_USE_WRITE_PIO_OPT + while(cnt < block_size) { + int32_t loop_cnt,loop_max; + +#if IDE_USE_STATISTICS + mpc5200_pcmciaide_write_block_block_cnt++; +#endif + + loop_max = llength - (*pos) ; + if (loop_max > (block_size - cnt)) { + loop_max = (block_size - cnt); + } + for (loop_cnt = loop_max/2;loop_cnt > 0;loop_cnt--) { + *(volatile uint32_t *)(ata_reg) = + SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(*lbuf++); /* only 16 bit data port */ + } + cnt += loop_max; + (*pos) += loop_max; + + if((*pos) == llength) { + + (*pos) = 0; + (*cbuf)++; + lbuf = bufs[(*cbuf)].buffer; + llength = bufs[(*cbuf)].length; + } + } +#else + while((GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG((volatile uint32_t)(mpc5200.ata_dctr_dasr)) + & IDE_REGISTER_STATUS_DRQ) + && (cnt < block_size)) { + *(volatile uint16_t *)(ata_reg) = *lbuf++; /* only 16 bit data port */ + cnt += 2; + (*pos) += 2; + + if((*pos) == llength) { + (*pos) = 0; + (*cbuf)++; + lbuf = bufs[(*cbuf)].buffer; + llength = bufs[(*cbuf)].length; + } + } +#endif + } +} + +int mpc5200_pcmciaide_control(int minor, uint32_t cmd, void * arg) + { + return RTEMS_SUCCESSFUL; + } + +void mpc5200_pcmciaide_initialize(int minor) + { +#if defined (BRS5L) + struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT7]); + + /* invert ATA reset on GPT7 */ + gpt->emsel = (GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO); +#endif + /* reset ata host contr. and FIFO */ + mpc5200.ata_hcfg |= (ATA_HCFG_SMR | ATA_HCFG_FR); + mpc5200.ata_hcfg &= ~(ATA_HCFG_SMR | ATA_HCFG_FR); + + /* for the first access set lowest performance transfer mode to PIO3 */ + mpc5200_pcmciaide_config_io_speed(minor, ATA_MODES_PIO3); + + /* enable PIO operations (PIO 3/4) */ + mpc5200.ata_hcfg |= ATA_HCFG_IORDY; + +#ifdef IDE_USE_INT + mpc5200.ata_hcfg |= ATA_HCFG_IE ; +#endif + +#if IDE_USE_DMA + mpc5200_pcmciaide_dma_init(minor); +#endif + } + + +/* + * The following table configures the functions used for IDE drivers + * in this BSP. + */ +ide_ctrl_fns_t mpc5200_pcmciaide_ctrl_fns = + { + mpc5200_pcmciaide_probe, + mpc5200_pcmciaide_initialize, + mpc5200_pcmciaide_control, + mpc5200_pcmciaide_read_reg, + mpc5200_pcmciaide_write_reg, + mpc5200_pcmciaide_read_block, + mpc5200_pcmciaide_write_block, + mpc5200_pcmciaide_config_io_speed + }; + diff --git a/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.h b/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.h new file mode 100644 index 0000000000..82bba33614 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.h @@ -0,0 +1,124 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: pcmcia_ide.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains declarations for the PCMCIA IDE Interface | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.5 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.4 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: pcmcia_ide.h */ +/* Date: 17/07/2003 */ +/* Purpose: RTEMS MPC5x00 PCMCIA IDE harddisk header file */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: none */ +/* Module: */ +/* Project: */ +/* Version */ +/* Date: */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#ifndef __PCMCIA_IDE_h +#define __PCMCIA_IDE_h + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" + +#define GPIOPCR_ATA_CS_4_5 (1 << 24) + +/*#define DEBUG_OUT*/ +#define GET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val32) ((uint16_t)((val32) >> 24)) +#define SET_UP_BYTE_OF_MPC5200_ATA_DRIVE_REG(val8) ((uint32_t)((val8) << 24)) +#define GET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val32) ((uint16_t)((val32) >> 16)) +#define SET_UP_WORD_OF_MPC5200_ATA_DRIVE_REG(val16) ((uint32_t)((val16) << 16)) + +#define ATA_HCFG_SMR (1 << 31) +#define ATA_HCFG_FR (1 << 30) +#define ATA_HCFG_IORDY (1 << 24) +#define ATA_HCFG_IE (1 << 25) + +#if 0 +#define COUNT_VAL(nsec) (((nsec)%(IPB_CLOCK/1000000)) ? (((nsec)/(IPB_CLOCK/1000000)) + 1) : ((nsec)/(IPB_CLOCK/1000000))) +#else +#define COUNT_VAL(nsec) (((nsec)*(IPB_CLOCK/1000000)/1000) + 1) +#endif + +#define PIO_3 0 +#define PIO_4 1 + +#define T0 0 +#define T2_8 1 +#define T2_16 2 +#define T4 3 +#define T1 4 +#define TA 5 + +#define ATA_PIO_TIMING_1(t0,t2_8,t2_16) (((COUNT_VAL(t0)) << 24) | ((COUNT_VAL(t2_8)) << 16) | ((COUNT_VAL(t2_16)) << 8)) +#define ATA_PIO_TIMING_2(t4,t1,ta) (((COUNT_VAL(t4)) << 24) | ((COUNT_VAL(t1)) << 16) | ((COUNT_VAL(ta)) << 8)) + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/.cvsignore b/c/src/lib/libbsp/powerpc/gen5200/include/.cvsignore new file mode 100644 index 0000000000..96adc7390b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/.cvsignore @@ -0,0 +1 @@ +bspopts.h diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h b/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h new file mode 100644 index 0000000000..7b80905e20 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h @@ -0,0 +1,245 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: bsp.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains board specific definitions | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.11 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.10 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ + +#ifndef __GEN5200_BSP_h +#define __GEN5200_BSP_h + +/* + * distinguish board characteristics + */ +/* + * for PM520 mdule on a ZE30 carrier + */ +#if defined(PM520_ZE30) +#define PM520 +#define GPIOPCR_INITMASK 0x337F3F77 +#define GPIOPCR_INITVAL 0x01552114 +/* we have PSC1/4/5/6 */ +/* #define GEN5200_UART_AVAIL_MASK 0x39 */ +#define GEN5200_UART_AVAIL_MASK 0x39 +#endif +/* + * for PM520 mdule on a CR825 carrier + */ +#if defined(PM520_CR825) +#define PM520 +#define GPIOPCR_INITMASK 0x330F0F77 +#define GPIOPCR_INITVAL 0x01050444 +/* we have PSC1/2/3*/ +#define GEN5200_UART_AVAIL_MASK 0x07 +#endif + +#if defined(BRS5L) +/* + * IMD Custom Board BRS5L + */ +#define GPIOPCR_INITMASK 0xb30F0F77 +#define GPIOPCR_INITVAL 0x91050444 +/* we have PSC1/2/3 */ +#define GEN5200_UART_AVAIL_MASK 0x07 +/* + * address range definitions + */ +/* ROM definitions (2 MB) */ +#define ROM_START 0xFFE00000 +#define ROM_END 0xFFFFFFFF +#define BOOT_START ROM_START +#define BOOT_END ROM_END + +/* SDRAM definitions (256 MB) */ +#define RAM_START 0x00000000 +#define RAM_END 0x0FFFFFFF + +/* DPRAM definitions (64 KB) */ +#define DPRAM_START 0xFF000000 +#define DPRAM_END 0xFF0003FF + +/* internal memory map definitions (64 KB) */ +#define MBAR 0xF0000000 + +/* we need the low level initialization in start.S*/ +#define NEED_LOW_LEVEL_INIT + +#define HAS_NVRAM_93CXX +#elif defined (PM520) + +/* + * MicroSys PM520 internal memory map definitions + */ +#define MBAR 0xF0000000 +#define HAS_UBOOT + +#else +#error "board type not defined" +#endif + +#ifndef ASM + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bspopts.h" + +#include <rtems.h> +#include <rtems/console.h> +#include <rtems/clockdrv.h> +#include <i2cdrv.h> + +#if defined(HAS_UBOOT) +#define CONFIG_MPC5xxx +#include <u-boot.h> +extern bd_t *uboot_bdinfo_ptr; +extern bd_t uboot_bdinfo_copy; +#endif + +/* + * Network driver configuration + */ +struct rtems_bsdnet_ifconfig; +extern int rtems_mpc5200_fec_driver_attach_detach (struct rtems_bsdnet_ifconfig *config, int attaching); +#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth1" +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_mpc5200_fec_driver_attach_detach + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; +/* + * We need to decide how much memory will be non-cacheable. This + * will mainly be memory that will be used in DMA (network and serial + * buffers). + */ +/* +#define NOCACHE_MEM_SIZE 512*1024 +*/ + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Stuff for Time Test 27 + */ +#define MUST_WAIT_FOR_INTERRUPT 0 + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +#ifdef HAS_NVRAM_93CXX +#define NVRAM_DRIVER_TABLE_ENTRY \ + { nvram_driver_initialize, nvram_driver_open, nvram_driver_close, \ + nvram_driver_read, nvram_driver_write, NULL } +#endif + +#define RTC_DRIVER_TABLE_ENTRY \ + { rtc_initialize, NULL, NULL, NULL, NULL, NULL } +extern rtems_device_driver rtc_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/* + * indicate, that BSP has IDE driver + */ +#define RTEMS_BSP_HAS_IDE_DRIVER + +/* + * How many libio files we want + */ +#define BSP_LIBIO_MAX_FDS 20 + +/* functions */ + +void bsp_cleanup(void); + +/* console modes (only termios) */ +#ifdef PRINTK_MINOR +#undef PRINTK_MINOR +#endif +#define PRINTK_MINOR PSC1_MINOR + +#define SINGLE_CHAR_MODE +#define UARTS_USE_TERMIOS_INT 1 + +/* ata modes */ +#undef ATA_USE_INT + +/* clock settings */ +#if defined(HAS_UBOOT) +#define IPB_CLOCK (uboot_bdinfo_ptr->bi_ipbfreq) +#define XLB_CLOCK (uboot_bdinfo_ptr->bi_busfreq) +#define G2_CLOCK (uboot_bdinfo_ptr->bi_intfreq) +#else +#define IPB_CLOCK 33000000 /* 33 MHz */ +#define XLB_CLOCK 66000000 /* 66 MHz */ +#define G2_CLOCK 231000000 /* 231 MHz */ +#endif + +/* slicetimer settings */ +#define USE_SLICETIMER_0 TRUE +#define USE_SLICETIMER_1 FALSE + +#ifdef __cplusplus +} +#endif + +#endif /* ASM */ + +#endif /* GEN5200 */ +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/coverhd.h b/c/src/lib/libbsp/powerpc/gen5200/include/coverhd.h new file mode 100644 index 0000000000..298a23a15d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/coverhd.h @@ -0,0 +1,114 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include + * all calling overhead including passing of arguments. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * coverhd.h,v 1.2 2003/09/04 18:52:27 joel Exp + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 2 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 2 +#define CALLING_OVERHEAD_CLOCK_SET 2 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 2 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/i2c.h b/c/src/lib/libbsp/powerpc/gen5200/include/i2c.h new file mode 100644 index 0000000000..ec9e9a85a3 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/i2c.h @@ -0,0 +1,245 @@ +/* + * Generic I2C bus interface for RTEMS + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) i2c.h,v 1.4 2004/04/21 10:42:52 ralf Exp + */ + +#ifndef __RTEMS__I2C_H__ +#define __RTEMS__I2C_H__ + +#include <rtems.h> +#include "../include/bsp.h" +/* This header file define the generic interface to i2c buses available in + * system. This interface may be used by user applications or i2c-device + * drivers (like RTC, NVRAM, etc). + * + * Functions i2c_initialize and i2c_transfer declared in this header usually + * implemented in particular board support package. Usually this + * implementation is a simple wrapper or multiplexor to I2C controller + * driver which is available in system. It may be generic "software + * controller" I2C driver which control SDA and SCL signals directly (if SDA + * and SCL is general-purpose I/O pins), or driver for hardware I2C + * controller (standalone or integrated with processors: MBus controller in + * ColdFire processors, I2C controller in PowerQUICC and so on). + * + * i2c_transfer is a very generic low-level function. Higher-level function + * i2c_write, i2c_read, i2c_wrrd, i2c_wbrd is defined here too. + */ + +/* I2C Bus Number type */ +typedef uint32_t i2c_bus_number; + +/* I2C device address */ +typedef uint16_t i2c_address; + +/* I2C error codes generated during message transfer */ +typedef enum i2c_message_status { + I2C_SUCCESSFUL = 0, + I2C_TIMEOUT, + I2C_NO_DEVICE, + I2C_ARBITRATION_LOST, + I2C_NO_ACKNOWLEDGE, + I2C_NO_DATA, + I2C_RESOURCE_NOT_AVAILABLE +} i2c_message_status; + +/* I2C Message */ +typedef struct i2c_message { + i2c_address addr; /* I2C slave device address */ + uint16_t flags; /* message flags (see below) */ + i2c_message_status status; /* message transfer status code */ + uint16_t len; /* Number of bytes to read or write */ + uint8_t *buf; /* pointer to data array */ +} i2c_message; + +/* I2C message flag */ +#define I2C_MSG_ADDR_10 (0x01) /* 10-bit address */ +#define I2C_MSG_WR (0x02) /* transfer direction for this message + from master to slave */ +#define I2C_MSG_ERRSKIP (0x04) /* Skip message if last transfered message + is failed */ +/* Type for function which is called when transfer over I2C bus is finished */ +typedef void (*i2c_transfer_done) (uint32_t arg); + +/* i2c_initialize -- + * I2C driver initialization. This function usually called on device + * driver initialization state, before initialization task. All I2C + * buses are initialized; reasonable slow data transfer rate is + * selected for each bus. + * + * PARAMETERS: + * major - I2C device major number + * minor - I2C device minor number + * arg - RTEMS driver initialization argument + * + * RETURNS: + * RTEMS status code + */ +rtems_device_driver +i2c_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +/* i2c_select_clock_rate -- + * select I2C bus clock rate for specified bus. Some bus controller do not + * allow to select arbitrary clock rate; in this case nearest possible + * slower clock rate is selected. + * + * PARAMETERS: + * bus - I2C bus number + * bps - data transfer rate for this bytes in bits per second + * + * RETURNS: + * RTEMS_SUCCESSFUL, if operation performed successfully, + * RTEMS_INVALID_NUMBER, if wrong bus number is specified, + * RTEMS_UNSATISFIED, if bus do not support data transfer rate selection + * or specified data transfer rate could not be used. + */ +rtems_status_code +i2c_select_clock_rate(i2c_bus_number bus, int bps); + +/* i2c_transfer -- + * Initiate multiple-messages transfer over specified I2C bus or + * put request into queue if bus or some other resource is busy. (This + * is non-blocking function). + * + * PARAMETERS: + * bus - I2C bus number + * nmsg - number of messages + * msg - pointer to messages array + * done - function which is called when transfer is finished + * done_arg - arbitrary argument passed to done funciton + * + * RETURNS: + * RTEMS_SUCCESSFUL if transfer initiated successfully, or error + * code if something failed. + */ +rtems_status_code +i2c_transfer(i2c_bus_number bus, int nmsg, i2c_message *msg, + i2c_transfer_done done, uint32_t done_arg); + +/* i2c_transfer_wait -- + * Initiate I2C bus transfer and block until this transfer will be + * finished. This function wait the semaphore if system in + * SYSTEM_STATE_UP state, or poll done flag in other states. + * + * PARAMETERS: + * bus - I2C bus number + * msg - pointer to transfer messages array + * nmsg - number of messages in transfer + * + * RETURNS: + * I2C_SUCCESSFUL, if tranfer finished successfully, + * I2C_RESOURCE_NOT_AVAILABLE, if semaphore operations has failed, + * value of status field of first error-finished message in transfer, + * if something wrong. + */ +i2c_message_status +i2c_transfer_wait(i2c_bus_number bus, i2c_message *msg, int nmsg); + +/* i2c_poll -- + * Poll I2C bus controller for events and hanle it. This function is + * used when I2C driver operates in poll-driven mode. + * + * PARAMETERS: + * bus - bus number to be polled + * + * RETURNS: + * none + */ +void +i2c_poll(i2c_bus_number bus); + +/* i2c_write -- + * Send single message over specified I2C bus to addressed device and + * wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * buf - data to be sent to device + * size - data buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_write(i2c_bus_number bus, i2c_address addr, void *buf, int size); + +/* i2c_wrbyte -- + * Send single one-byte long message over specified I2C bus to + * addressed device and wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * cmd - byte message to be sent to device + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wrbyte(i2c_bus_number bus, i2c_address addr, uint8_t cmd); + +/* i2c_read -- + * receive single message over specified I2C bus from addressed device. + * This call will wait while transfer is finished. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * buf - buffer for received message + * size - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_read(i2c_bus_number bus, i2c_address addr, void *buf, int size); + +/* i2c_wrrd -- + * Send message over I2C bus to specified device and receive message + * from the same device during single transfer. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * bufw - data to be sent to device + * sizew - send data buffer size + * bufr - buffer for received message + * sizer - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wrrd(i2c_bus_number bus, i2c_address addr, void *bufw, int sizew, + void *bufr, int sizer); + +/* i2c_wbrd -- + * Send one-byte message over I2C bus to specified device and receive + * message from the same device during single transfer. + * + * PARAMETERS: + * bus - I2C bus number + * addr - address of I2C device + * cmd - one-byte message to be sent over I2C bus + * bufr - buffer for received message + * sizer - receive buffer size + * + * RETURNS: + * transfer status + */ +i2c_message_status +i2c_wbrd(i2c_bus_number bus, i2c_address addr, uint8_t cmd, + void *bufr, int sizer); + +#endif diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/i2cdrv.h b/c/src/lib/libbsp/powerpc/gen5200/include/i2cdrv.h new file mode 100644 index 0000000000..c3213e7aaa --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/i2cdrv.h @@ -0,0 +1,37 @@ +/* + * i2cdrv.h -- I2C bus driver prototype and definitions + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) i2cdrv.h,v 1.3 2004/04/21 10:42:52 ralf Exp + */ + +#ifndef __I2CDRV_H__ +#define __I2CDRV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2C_DRIVER_TABLE_ENTRY \ + { i2cdrv_initialize, NULL, NULL, NULL, NULL, NULL } + +/* i2cdrv_initialize -- + * I2C driver initialization (rtems I/O driver primitive) + */ +rtems_device_driver +i2cdrv_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +#ifdef __cplusplus +} +#endif + +#endif /* __I2CDRV_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h b/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h new file mode 100644 index 0000000000..b93916672b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h @@ -0,0 +1,1107 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: mpc5200.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains definitions for the mpc5200 hw registers | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.3 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.2 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ + +#ifndef __MPC5200_h__ +#define __MPC5200_h__ + +/* Additional Harpo Core SPR definitions (603le only) */ +#define CSRR0 58 /* Critical Interrupt SRR0 */ +#define CSRR1 59 /* Critical Interrupt SRR1 */ +#define SPRG4 276 /* Special Purpose Register 4 */ +#define SPRG5 277 /* Special Purpose Register 5 */ +#define SPRG6 278 /* Special Purpose Register 6 */ +#define SPRG7 279 /* Special Purpose Register 7 */ +#define IBAT4U 560 /* Instruction BAT #0 Upper/Lower */ +#define IBAT4L 561 +#define IBAT5U 562 /* Instruction BAT #1 Upper/Lower */ +#define IBAT5L 563 +#define IBAT6U 564 /* Instruction BAT #2 Upper/Lower */ +#define IBAT6L 565 +#define IBAT7U 566 /* Instruction BAT #3 Upper/Lower */ +#define IBAT7L 567 +#define DBAT4U 568 /* Data BAT #0 Upper/Lower */ +#define DBAT4L 569 +#define DBAT5U 570 /* Data BAT #1 Upper/Lower */ +#define DBAT5L 571 +#define DBAT6U 572 /* Data BAT #2 Upper/Lower */ +#define DBAT6L 573 +#define DBAT7U 574 /* Data BAT #3 Upper/Lower */ +#define DBAT7L 575 +#define DABR2 1000 /* Data Address Breakpoint #2 */ +#define DBCR 1001 /* Data Address Breakpoint Control */ +#define IBCR 1002 /* Instruction Breakpoint Control */ +#define HID1 1009 /* Hardware Implementation 1 */ +#define HID2 1011 /* Hardware Implementation 2 */ +#define DABR 1013 /* Data Address Breakpoint */ +#define IABR2 1018 /* Instruction Breakpoint #2 */ + +/* + * Initial post-reset location of MGT5100 module base address register (MBAR) + */ +#define MBAR_RESET 0x80000000 + +/* + * Location and size of onchip SRAM (relative to MBAR) + */ +#define ONCHIP_SRAM_OFFSET 0x8000 +#define ONCHIP_SRAM_SIZE 0x4000 + +#ifndef ASM +#include <rtems.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define MPC5200_CAN_NO 2 +#define MPC5200_PSC_NO 6 + /* XXX: there are only 6 PSCs, but PSC6 has an extra register gap + * from PSC5, therefore we instantiate seven(!) PSC register sets + */ +#define MPC5200_PSC_REG_SETS 7 + +#define MPC5200_GPT_NO 8 +#define MPC5200_SLT_NO 2 + +/* + * Bit fields for FEC interrupts, ievent and imask above. + */ +#define FEC_INTR_HBERR 0x80000000 /* heartbeat error */ +#define FEC_INTR_BABR 0x40000000 /* babbling receive error */ +#define FEC_INTR_BABT 0x20000000 /* babbling transmit error */ +#define FEC_INTR_GRA 0x10000000 /* graceful stop complete */ +#define FEC_INTR_TFINT 0x08000000 /* transmit frame interrupt */ +/* 0x04000000 reserved */ +/* 0x02000000 reserved */ +/* 0x01000000 reserved */ +#define FEC_INTR_MII 0x00800000 /* MII interrupt */ +/* 0x00400000 reserved */ +#define FEC_INTR_LATE_COL 0x00200000 /* late collision */ +#define FEC_INTR_COL_RETRY 0x00100000 /* collision retry limit */ +#define FEC_INTR_XFIFO_UN 0x00080000 /* transmit FIFO error */ +#define FEC_INTR_XFIFO_ERR 0x00040000 /* transmit FIFO error */ +#define FEC_INTR_RFIFO_ERR 0x00020000 /* receive FIFO error */ +/* 0x00010000 reserved */ +/* 0x0000ffff reserved */ +#define FEC_INTR_HBEEN FEC_INTR_HBERR +#define FEC_INTR_BREN FEC_INTR_BABR +#define FEC_INTR_BTEN FEC_INTR_BABT +#define FEC_INTR_GRAEN FEC_INTR_GRA +#define FEC_INTR_TFINTEN FEC_INTR_TFINT +#define FEC_INTR_MIIEN FEC_INTR_MII +#define FEC_INTR_LCEN FEC_INTR_LATE_COL +#define FEC_INTR_CRLEN FEC_INTR_COL_RETRY +#define FEC_INTR_XFUNEN FEC_INTR_XFIFO_UN +#define FEC_INTR_XFERREN FEC_INTR_XFIFO_ERR +#define FEC_INTR_RFERREN FEC_INTR_RFIFO_ERR +#define FEC_INTR_CLEAR_ALL 0xffffffff /* clear all interrupt events */ +#define FEC_INTR_MASK_ALL 0x00000000 /* mask all interrupt events */ + +/* + * Bit fields for FEC ethernet control, ecntrl above. + */ +#define FEC_ECNTRL_TAG 0xf0000000 /* TBUS tag bits */ +/* 0x08000000 reserved */ +#define FEC_ECNTRL_TESTMD 0x04000000 /* test mode */ +/* 0x03fffff8 reserved */ +#define FEC_ECNTRL_OE 0x00000004 /* FEC output enable */ +#define FEC_ECNTRL_EN 0x00000002 /* ethernet enable */ +#define FEC_ECNTRL_RESET 0x00000001 /* ethernet controller reset */ + +/* + * Bit fields for FEC receive control, r_cntrl above. + */ +/* 0xf1000000 reserved */ +#define FEC_RCNTRL_MAX_FL 0x07ff0000 /* maximum frame length */ +#define FEC_RCNTRL_MAX_FL_SHIFT 16 +/* 0x0000ffc0 reserved */ +#define FEC_RCNTRL_FCE 0x00000020 /* flow control enable */ +#define FEC_RCNTRL_BC_REJ 0x00000010 /* broadcast frame reject */ +#define FEC_RCNTRL_PROM 0x00000008 /* promiscuous mode */ +#define FEC_RCNTRL_MII_MODE 0x00000004 /* select 18-wire (MII) mode */ +#define FEC_RCNTRL_DRT 0x00000002 /* disable receive on transmit */ +#define FEC_RCNTRL_LOOP 0x00000001 /* internal loopback */ + +/* + * Bit fields for FEC transmit control, x_cntrl above. + */ +/* 0xffffffe0 reserved */ +#define FEC_XCNTRL_RFC_PAUS 0x00000010 /* FDX flow control pause rx */ +#define FEC_XCNTRL_TFC_PAUS 0x00000008 /* assert a PAUSE frame */ +#define FEC_XCNTRL_FDEN 0x00000004 /* full duplex enable */ +#define FEC_XCNTRL_HBC 0x00000002 /* heartbeat control */ +#define FEC_XCNTRL_GTS 0x00000001 /* graceful transmit stop */ + +/* + * Bit fields for FEC transmit status, x_status above. + */ +/* 0xfc000000 reserved */ +#define FEC_XSTAT_DEF 0x02000000 /* defer */ +#define FEC_XSTAT_HB 0x01000000 /* heartbeat error */ +#define FEC_XSTAT_LC 0x00800000 /* late collision */ +#define FEC_XSTAT_RL 0x00400000 /* retry limit */ +#define FEC_XSTAT_RC 0x003c0000 /* retry count */ +#define FEC_XSTAT_UN 0x00020000 /* underrun */ +#define FEX_XSTAT_CSL 0x00010000 /* carrier sense lost */ +/* 0x0000ffff reserved */ + +/* + * Bit fields for FEC transmit FIFO watermark, x_wmrk above. + */ +#define FEC_XWMRK_64 0x00000000 /* 64 bytes written to TxFIFO */ +#define FEC_XWMRK_128 0x00000001 /* 128 bytes written to TxFIFO */ +#define FEC_XWMRK_192 0x00000002 /* 192 bytes written to TxFIFO */ +#define FEC_XWMRK_256 0x00000003 /* 256 bytes written to TxFIFO */ +#define FEC_XWMRK_320 0x00000004 /* 320 bytes written to TxFIFO */ +#define FEC_XWMRK_384 0x00000005 /* 384 bytes written to TxFIFO */ +#define FEC_XWMRK_448 0x00000006 /* 448 bytes written to TxFIFO */ +#define FEC_XWMRK_512 0x00000007 /* 512 bytes written to TxFIFO */ +#define FEC_XWMRK_576 0x00000008 /* 576 bytes written to TxFIFO */ +#define FEC_XWMRK_640 0x00000009 /* 640 bytes written to TxFIFO */ +#define FEC_XWMRK_704 0x0000000a /* 704 bytes written to TxFIFO */ +#define FEC_XWMRK_768 0x0000000b /* 768 bytes written to TxFIFO */ +#define FEC_XWMRK_832 0x0000000c /* 832 bytes written to TxFIFO */ +#define FEC_XWMRK_896 0x0000000d /* 896 bytes written to TxFIFO */ +#define FEC_XWMRK_960 0x0000000e /* 960 bytes written to TxFIFO */ +#define FEC_XWMRK_1024 0x0000000f /* 1024 bytes written to TxFIFO */ + +/* + * Bit fields for FEC transmit finite state machine. + */ +/* 0xfc000000 reserved */ +#define FEC_FSM_CRC 0x02000000 /* append CRC (typical use) */ +#define FEC_FSM_ENFSM 0x01000000 /* enable CRC FSM (typical use) */ +/* 0x00ffffff reserved */ + +/* + * Bit fields for FEC FIFOs, rfifo_status, rfifo_cntrl, tfifo_status + * and tfifo_cntrl. + */ +#define FEC_FIFO_STAT_IP 0x80000000 /* illegal pointer, sticky */ +/* 0x70000000 reserved */ +#define FEC_FIFO_STAT_FRAME 0x0f000000 /* frame indicator */ +#define FEC_FIFO_STAT_FAE 0x00800000 /* frame accept error */ +#define FEC_FIFO_STAT_RXW 0x00400000 /* receive wait condition */ +#define FEC_FIFO_STAT_UF 0x00200000 /* underflow */ +#define FEC_FIFO_STAT_OF 0x00100000 /* overflow */ +#define FEC_FIFO_STAT_FR 0x00080000 /* frame ready, read-only */ +#define FEC_FIFO_STAT_FULL 0x00040000 /* full alarm, read-only */ +#define FEC_FIFO_STAT_ALARM 0x00020000 /* fifo alarm */ +#define FEC_FIFO_STAT_EMPTY 0x00010000 /* empty, read-only */ +/* 0x0000ffff reserved */ +#define FEC_FIFO_STAT_ERROR ( FEC_FIFO_STAT_IP \ + | FEC_FIFO_STAT_FAE \ + | FEC_FIFO_STAT_RXW \ + | FEC_FIFO_STAT_UF \ + | FEC_FIFO_STAT_OF \ + ) + +/* 0x80000000 reserved */ +#define FEC_FIFO_CNTRL_WCTL 0x40000000 /* write control */ +#define FEC_FIFO_CNTRL_WFR 0x20000000 /* write frame */ +/* 0x10000000 reserved */ +#define FEC_FIFO_CNTRL_FRAME 0x08000000 /* frame mode enable */ +#define FEC_FIFO_CNTRL_GR 0x07000000 /* last transfer granularity */ +#define FEC_FIFO_CNTRL_GR_SHIFT 24 +#define FEC_FIFO_CNTRL_IP_MASK 0x00800000 /* illegal pointer mask */ +#define FEC_FIFO_CNTRL_FAE_MASK 0x00400000 /* frame accept mask */ +#define FEC_FIFO_CNTRL_RXW_MASK 0x00200000 /* receive wait mask */ +#define FEC_FIFO_CNTRL_UF_MASK 0x00100000 /* underflow mask */ +#define FEC_FIFO_CNTRL_OF_MASK 0x00080000 /* overflow mask */ +/* 0x0007ffff reserved */ + +/* +************************************************************************* +* MPC5x00 internal register memory map * +************************************************************************* +*/ +typedef struct mpc5200_ + { + /* + * memory map registers (MBAR + 0) + */ + volatile uint8_t mm[0x80]; + + /* + * arbiter registers (processor bus) (MBAR + 0x80) + */ + volatile uint8_t arb[0x80]; + + /* + * SDRAM memory controller registers (MBAR + 0x100) + */ + volatile uint8_t mc[0x100]; + + /* + * clock distribution module registers (MBAR + 0x200) + */ + volatile uint8_t cdm[0x100]; + + /* + * chip selct controller registers(MBAR + 0x300) + */ + volatile uint8_t csc[0x100]; + + /* + * SmartComm timer registers (MBAR + 0x400) + */ + volatile uint8_t sct[0x100]; + + /* + * interrupt controller registers (MBAR + 0x500) + */ + volatile uint32_t per_mask; /* + 0x00 */ + volatile uint32_t per_pri_1; /* + 0x04 */ + volatile uint32_t per_pri_2; /* + 0x08 */ + volatile uint32_t per_pri_3; /* + 0x0C */ + volatile uint32_t ext_en_type; /* + 0x10 */ + volatile uint32_t crit_pri_main_mask;/* + 0x14 */ + volatile uint32_t main_pri_1; /* + 0x18 */ + volatile uint32_t main_pri_2; /* + 0x1C */ + volatile uint32_t res1; /* + 0x20 */ + volatile uint32_t pmce; /* + 0x24 */ + volatile uint32_t csa; /* + 0x28 */ + volatile uint32_t msa; /* + 0x2C */ + volatile uint32_t psa; /* + 0x30 */ + volatile uint32_t res2; /* + 0x34 */ + volatile uint32_t psa_be; /* + 0x38 */ + volatile uint8_t res3[0xC4]; /* + 0x3C */ + + /* + * general pupose timer registers (MBAR + 0x600/+0x610/+0x620/+0x630/+0x640/+0x650/+0x660/+0x670) + */ + struct mpc5200_gpt + { + volatile uint32_t emsel; /* + 0x00 */ + volatile uint32_t count_in; /* + 0x04 */ + volatile uint32_t pwm_conf; /* + 0x08 */ + volatile uint32_t status; /* + 0x0C */ + } gpt[MPC5200_GPT_NO]; + +#define GPT_STATUS_RESET 0x0000000F +#define GPT_STATUS_TEXP (1 << 3) +#define GPT_STATUS_PIN (1 << 8) +#define GPT_EMSEL_GPIO_OUT_HIGH (3 << 4) +#define GPT_EMSEL_TIMER_MS_GPIO (4 << 0) +#define GPT_EMSEL_GPIO_IN (0 << 0) +#define GPT_EMSEL_CE (1 << 12) +#define GPT_EMSEL_ST_CONT (1 << 10) +#define GPT_EMSEL_INTEN (1 << 8) + +#define GPT0 0 +#define GPT1 1 +#define GPT2 2 +#define GPT3 3 +#define GPT4 4 +#define GPT5 5 +#define GPT6 6 +#define GPT7 7 + + volatile uint8_t gpt_res[0x80]; + + /* + * slice time registers (MBAR + 0x700/+0x710) + */ + struct mpc5200_slt + { + volatile uint32_t tcr; /* + 0x00 */ + volatile uint32_t cntrl; /* + 0x04 */ + volatile uint32_t cvr; /* + 0x08 */ + volatile uint32_t tsr; /* + 0x0C */ + } slt[MPC5200_SLT_NO]; + + volatile uint8_t slt_res[0xE0]; + + /* + * real time clock registers (MBAR + 0x800) + */ + volatile uint8_t rtc[0x100]; + + + /* + * MSCAN registers (MBAR + 0x900 /+0x980) + */ + struct mpc5200_mscan + { + volatile uint8_t ctl0; /* + 0x0 */ + volatile uint8_t ctl1; /* + 0x1 */ + volatile uint8_t res1; /* + 0x2 */ + volatile uint8_t res2; /* + 0x3 */ + volatile uint8_t btr0; /* + 0x4 */ + volatile uint8_t btr1; /* + 0x5 */ + volatile uint8_t res3; /* + 0x6 */ + volatile uint8_t res4; /* + 0x7 */ + volatile uint8_t rflg; /* + 0x8 */ + volatile uint8_t rier; /* + 0x9 */ + volatile uint8_t res5; /* + 0xA */ + volatile uint8_t res6; /* + 0xB */ + volatile uint8_t tflg; /* + 0xC */ + volatile uint8_t tier; /* + 0xD */ + volatile uint8_t res7; /* + 0xE */ + volatile uint8_t res8; /* + 0xF */ + volatile uint8_t tarq; /* + 0x10 */ + volatile uint8_t taak; /* + 0x11 */ + volatile uint8_t res9; /* + 0x12 */ + volatile uint8_t res10; /* + 0x13 */ + volatile uint8_t bsel; /* + 0x14 */ + volatile uint8_t idac; /* + 0x15 */ + volatile uint8_t res11; /* + 0x16 */ + volatile uint8_t res12; /* + 0x17 */ + volatile uint8_t res13; /* + 0x18 */ + volatile uint8_t res14; /* + 0x19 */ + volatile uint8_t res15; /* + 0x1A */ + volatile uint8_t res16; /* + 0x1B */ + volatile uint8_t rxerr; /* + 0x1C */ + volatile uint8_t txerr; /* + 0x1D */ + volatile uint8_t res17; /* + 0x1E */ + volatile uint8_t res18; /* + 0x1F */ + volatile uint8_t idar0; /* + 0x20 */ + volatile uint8_t idar1; /* + 0x21 */ + volatile uint8_t res19; /* + 0x22 */ + volatile uint8_t res20; /* + 0x23 */ + volatile uint8_t idar2; /* + 0x24 */ + volatile uint8_t idar3; /* + 0x25 */ + volatile uint8_t res21; /* + 0x26 */ + volatile uint8_t res22; /* + 0x27 */ + volatile uint8_t idmr0; /* + 0x28 */ + volatile uint8_t idmr1; /* + 0x29 */ + volatile uint8_t res23; /* + 0x2A */ + volatile uint8_t res24; /* + 0x2B */ + volatile uint8_t idmr2; /* + 0x2C */ + volatile uint8_t idmr3; /* + 0x2D */ + volatile uint8_t res25; /* + 0x2E */ + volatile uint8_t res26; /* + 0x2F */ + volatile uint8_t idar4; /* + 0x30 */ + volatile uint8_t idar5; /* + 0x31 */ + volatile uint8_t res27; /* + 0x32 */ + volatile uint8_t res28; /* + 0x33 */ + volatile uint8_t idar6; /* + 0x34 */ + volatile uint8_t idar7; /* + 0x35 */ + volatile uint8_t res29; /* + 0x36 */ + volatile uint8_t res30; /* + 0x37 */ + volatile uint8_t idmr4; /* + 0x38 */ + volatile uint8_t idmr5; /* + 0x39 */ + volatile uint8_t res31; /* + 0x3A */ + volatile uint8_t res32; /* + 0x3B */ + volatile uint8_t idmr6; /* + 0x3C */ + volatile uint8_t idmr7; /* + 0x3D */ + volatile uint8_t res33; /* + 0x3E */ + volatile uint8_t res34; /* + 0x3F */ + volatile uint8_t rxidr0; /* + 0x40 */ + volatile uint8_t rxidr1; /* + 0x41 */ + volatile uint8_t res35; /* + 0x42 */ + volatile uint8_t res36; /* + 0x43 */ + volatile uint8_t rxidr2; /* + 0x44 */ + volatile uint8_t rxidr3; /* + 0x45 */ + volatile uint8_t res37; /* + 0x46 */ + volatile uint8_t res38; /* + 0x47 */ + volatile uint8_t rxdsr0; /* + 0x48 */ + volatile uint8_t rxdsr1; /* + 0x49 */ + volatile uint8_t res39; /* + 0x4A */ + volatile uint8_t res40; /* + 0x4B */ + volatile uint8_t rxdsr2; /* + 0x4C */ + volatile uint8_t rxdsr3; /* + 0x4D */ + volatile uint8_t res41; /* + 0x4E */ + volatile uint8_t res42; /* + 0x4F */ + volatile uint8_t rxdsr4; /* + 0x50 */ + volatile uint8_t rxdsr5; /* + 0x51 */ + volatile uint8_t res43; /* + 0x52 */ + volatile uint8_t res44; /* + 0x53 */ + volatile uint8_t rxdsr6; /* + 0x54 */ + volatile uint8_t rxdsr7; /* + 0x55 */ + volatile uint8_t res45; /* + 0x56 */ + volatile uint8_t res46; /* + 0x57 */ + volatile uint8_t rxdlr; /* + 0x58 */ + volatile uint8_t res47; /* + 0x59 */ + volatile uint8_t res48; /* + 0x5A */ + volatile uint8_t res49; /* + 0x5B */ + volatile uint8_t rxtimh; /* + 0x5C */ + volatile uint8_t rxtiml; /* + 0x5D */ + volatile uint8_t res50; /* + 0x5E */ + volatile uint8_t res51; /* + 0x5F */ + volatile uint8_t txidr0; /* + 0x60 */ + volatile uint8_t txidr1; /* + 0x61 */ + volatile uint8_t res52; /* + 0x62 */ + volatile uint8_t res53; /* + 0x63 */ + volatile uint8_t txidr2; /* + 0x64 */ + volatile uint8_t txidr3; /* + 0x65 */ + volatile uint8_t res54; /* + 0x66 */ + volatile uint8_t res55; /* + 0x67 */ + volatile uint8_t txdsr0; /* + 0x68 */ + volatile uint8_t txdsr1; /* + 0x69 */ + volatile uint8_t res56; /* + 0x6A */ + volatile uint8_t res57; /* + 0x6B */ + volatile uint8_t txdsr2; /* + 0x6C */ + volatile uint8_t txdsr3; /* + 0x6D */ + volatile uint8_t res58; /* + 0x6E */ + volatile uint8_t res59; /* + 0x6F */ + volatile uint8_t txdsr4; /* + 0x70 */ + volatile uint8_t txdsr5; /* + 0x71 */ + volatile uint8_t res60; /* + 0x72 */ + volatile uint8_t res61; /* + 0x73 */ + volatile uint8_t txdsr6; /* + 0x74 */ + volatile uint8_t txdsr7; /* + 0x75 */ + volatile uint8_t res62; /* + 0x76 */ + volatile uint8_t res63; /* + 0x77 */ + volatile uint8_t txdlr; /* + 0x78 */ + volatile uint8_t txtbpr; /* + 0x79 */ + volatile uint8_t res64; /* + 0x7A */ + volatile uint8_t res65; /* + 0x7B */ + volatile uint8_t txtimh; /* + 0x7C */ + volatile uint8_t txtiml; /* + 0x7D */ + volatile uint8_t res66; /* + 0x7E */ + volatile uint8_t res67; /* + 0x7F */ + } mscan[MPC5200_CAN_NO]; + + volatile uint8_t res[0x100]; + + /* + * GPIO standard registers (MBAR + 0xB00) + */ + volatile uint32_t gpiopcr; /* + 0x00 */ + volatile uint32_t gpiosen; /* + 0x04 */ + volatile uint32_t gpiosod; /* + 0x08 */ + volatile uint32_t gpiosdd; /* + 0x0C */ + volatile uint32_t gpiosdo; /* + 0x10 */ + volatile uint32_t gpiosdi; /* + 0x14 */ + volatile uint32_t gpiooe; /* + 0x18 */ + volatile uint32_t gpioodo; /* + 0x1C */ + volatile uint32_t gpiosie; /* + 0x20 */ + volatile uint32_t gpiosiod; /* + 0x24 */ + volatile uint32_t gpiosidd; /* + 0x28 */ + volatile uint32_t gpiosido; /* + 0x2C */ + volatile uint32_t gpiosiie; /* + 0x30 */ + volatile uint32_t gpiosiit; /* + 0x34 */ + volatile uint32_t gpiosime; /* + 0x38 */ + volatile uint32_t gpiosist; /* + 0x3C */ + volatile uint8_t res4[0xC0]; + + /* + * GPIO wakeup registers (MBAR + 0xC00) + */ + volatile uint32_t gpiowe; /* + 0x00 */ + volatile uint32_t gpiowod; /* + 0x04 */ + volatile uint32_t gpiowdd; /* + 0x08 */ + volatile uint32_t gpiowdo; /* + 0x0C */ + volatile uint32_t gpiowue; /* + 0x10 */ + volatile uint32_t gpiowsie; /* + 0x14 */ + volatile uint32_t gpiowt; /* + 0x18 */ + volatile uint32_t gpiowme; /* + 0x1C */ + volatile uint32_t gpiowi; /* + 0x20 */ + volatile uint32_t gpiows; /* + 0x24 */ + volatile uint8_t gpiow_res[0xD8]; + + /* + * PPC PCI registers (MBAR + 0xD00) + */ + volatile uint8_t ppci[0x100]; + + /* + * consumer infrared registers (MBAR + 0xE00) + */ + volatile uint8_t ir[0x100]; + + /* + * serial peripheral interface registers (MBAR + 0xF00) + */ + volatile uint8_t spi[0x100]; + + /* + * universal serial bus registers (MBAR + 0x1000) + */ + volatile uint8_t usb[0x200]; + + /* + * SmartComm DMA registers (MBAR + 0x1200) + */ + volatile uint32_t taskBar; /* + 0x00 sdTpb */ + volatile uint32_t currentPointer; /* + 0x04 sdMdeComplex */ + volatile uint32_t endPointer; /* + 0x08 sdMdeComplex */ + volatile uint32_t variablePointer; /* + 0x0c sdMdeComplex */ + + /* + * The following are Priority Task Decoder (ptd) regs in sdma/rtl_v/sdPtd.v. + * The ptd register map below is from the smartcomm spec, table 3-2, page 3-54. + * The spec shows the ptd map as 20 words, but sdPtd.v has only implemented 19. + * The word commented out below is the one which is not implemented. + */ + + /* volatile uint8_t IntVect; *//* + * + 0xXX sdPtd read only + */ + + /* volatile uint8_t res0[3]; *//* + * + 0xXX sdPtd read only + */ + volatile uint8_t IntVect1; /* + 0x10 sdPtd */ + volatile uint8_t IntVect2; /* + 0x11 sdPtd */ + volatile uint16_t PtdCntrl; /* + 0x12 sdPtd */ + + volatile uint32_t IntPend; /* + 0x14 sdPtd */ + volatile uint32_t IntMask; /* + 0x18 sdPtd */ + + volatile uint32_t TCR01; /* + 0x1c sdPtd */ + volatile uint32_t TCR23; /* + 0x20 sdPtd */ + volatile uint32_t TCR45; /* + 0x24 sdPtd */ + volatile uint32_t TCR67; /* + 0x28 sdPtd */ + volatile uint32_t TCR89; /* + 0x2c sdPtd */ + volatile uint32_t TCRAB; /* + 0x30 sdPtd */ + volatile uint32_t TCRCD; /* + 0x34 sdPtd */ + volatile uint32_t TCREF; /* + 0x38 sdPtd */ + + volatile uint8_t IPR0; /* + 0x3c sdPtd */ + volatile uint8_t IPR1; /* + 0x3d sdPtd */ + volatile uint8_t IPR2; /* + 0x3e sdPtd */ + volatile uint8_t IPR3; /* + 0x3f sdPtd */ + volatile uint8_t IPR4; /* + 0x40 sdPtd */ + volatile uint8_t IPR5; /* + 0x41 sdPtd */ + volatile uint8_t IPR6; /* + 0x42 sdPtd */ + volatile uint8_t IPR7; /* + 0x43 sdPtd */ + volatile uint8_t IPR8; /* + 0x44 sdPtd */ + volatile uint8_t IPR9; /* + 0x45 sdPtd */ + volatile uint8_t IPR10; /* + 0x46 sdPtd */ + volatile uint8_t IPR11; /* + 0x47 sdPtd */ + volatile uint8_t IPR12; /* + 0x48 sdPtd */ + volatile uint8_t IPR13; /* + 0x49 sdPtd */ + volatile uint8_t IPR14; /* + 0x4a sdPtd */ + volatile uint8_t IPR15; /* + 0x4b sdPtd */ + volatile uint8_t IPR16; /* + 0x4c sdPtd */ + volatile uint8_t IPR17; /* + 0x4d sdPtd */ + volatile uint8_t IPR18; /* + 0x4e sdPtd */ + volatile uint8_t IPR19; /* + 0x4f sdPtd */ + volatile uint8_t IPR20; /* + 0x50 sdPtd */ + volatile uint8_t IPR21; /* + 0x51 sdPtd */ + volatile uint8_t IPR22; /* + 0x52 sdPtd */ + volatile uint8_t IPR23; /* + 0x53 sdPtd */ + volatile uint8_t IPR24; /* + 0x54 sdPtd */ + volatile uint8_t IPR25; /* + 0x55 sdPtd */ + volatile uint8_t IPR26; /* + 0x56 sdPtd */ + volatile uint8_t IPR27; /* + 0x57 sdPtd */ + volatile uint8_t IPR28; /* + 0x58 sdPtd */ + volatile uint8_t IPR29; /* + 0x59 sdPtd */ + volatile uint8_t IPR30; /* + 0x5a sdPtd */ + volatile uint8_t IPR31; /* + 0x5b sdPtd */ + + volatile uint32_t res5; /* reserved */ + volatile uint32_t res6; /* reserved */ + volatile uint32_t res7; /* reserved */ + volatile uint32_t MDEDebug; /* + 0x68 sdMdeComplex */ + volatile uint32_t ADSDebug; /* + 0x6c sdAdsTop */ + volatile uint32_t Value1; /* + 0x70 sdDbg */ + volatile uint32_t Value2; /* + 0x74 sdDbg */ + volatile uint32_t Control; /* + 0x78 sdDbg */ + volatile uint32_t Status; /* + 0x7c sdDbg */ + volatile uint32_t EU00; /* + 0x80 sdMac macer reg */ + volatile uint32_t EU01; /* + 0x84 sdMac macemr reg */ + volatile uint32_t EU02; /* + 0x88 unused */ + volatile uint32_t EU03; /* + 0x8c unused */ + volatile uint32_t EU04; /* + 0x90 unused */ + volatile uint32_t EU05; /* + 0x94 unused */ + volatile uint32_t EU06; /* + 0x98 unused */ + volatile uint32_t EU07; /* + 0x9c unused */ + volatile uint32_t EU10; /* + 0xa0 unused */ + volatile uint32_t EU11; /* + 0xa4 unused */ + volatile uint32_t EU12; /* + 0xa8 unused */ + volatile uint32_t EU13; /* + 0xac unused */ + volatile uint32_t EU14; /* + 0xb0 unused */ + volatile uint32_t EU15; /* + 0xb4 unused */ + volatile uint32_t EU16; /* + 0xb8 unused */ + volatile uint32_t EU17; /* + 0xbc unused */ + volatile uint32_t EU20; /* + 0xc0 unused */ + volatile uint32_t EU21; /* + 0xc4 unused */ + volatile uint32_t EU22; /* + 0xc8 unused */ + volatile uint32_t EU23; /* + 0xcc unused */ + volatile uint32_t EU24; /* + 0xd0 unused */ + volatile uint32_t EU25; /* + 0xd4 unused */ + volatile uint32_t EU26; /* + 0xd8 unused */ + volatile uint32_t EU27; /* + 0xdc unused */ + volatile uint32_t EU30; /* + 0xe0 unused */ + volatile uint32_t EU31; /* + 0xe4 unused */ + volatile uint32_t EU32; /* + 0xe8 unused */ + volatile uint32_t EU33; /* + 0xec unused */ + volatile uint32_t EU34; /* + 0xf0 unused */ + volatile uint32_t EU35; /* + 0xf4 unused */ + volatile uint32_t EU36; /* + 0xf8 unused */ + volatile uint32_t EU37; /* + 0xfc unused */ +#if 0 + volatile uint32_t res8[0x340]; +#else + volatile uint8_t res_1300[0xc00]; + + volatile uint32_t reserved0; /* MBAR_XLB_ARB + 0x0000 reserved */ + volatile uint32_t reserved1; /* MBAR_XLB_ARB + 0x0004 reserved */ + volatile uint32_t reserved2; /* MBAR_XLB_ARB + 0x0008 reserved */ + volatile uint32_t reserved3; /* MBAR_XLB_ARB + 0x000c reserved */ + volatile uint32_t reserved4; /* MBAR_XLB_ARB + 0x0010 reserved */ + volatile uint32_t reserved5; /* MBAR_XLB_ARB + 0x0014 reserved */ + volatile uint32_t reserved6; /* MBAR_XLB_ARB + 0x0018 reserved */ + volatile uint32_t reserved7; /* MBAR_XLB_ARB + 0x001c reserved */ + volatile uint32_t reserved8; /* MBAR_XLB_ARB + 0x0020 reserved */ + volatile uint32_t reserved9; /* MBAR_XLB_ARB + 0x0024 reserved */ + volatile uint32_t reserved10; /* MBAR_XLB_ARB + 0x0028 reserved */ + volatile uint32_t reserved11; /* MBAR_XLB_ARB + 0x002c reserved */ + volatile uint32_t reserved12; /* MBAR_XLB_ARB + 0x0030 reserved */ + volatile uint32_t reserved13; /* MBAR_XLB_ARB + 0x0034 reserved */ + volatile uint32_t reserved14; /* MBAR_XLB_ARB + 0x0038 reserved */ + volatile uint32_t reserved15; /* MBAR_XLB_ARB + 0x003c reserved */ + + volatile uint32_t config; /* MBAR_XLB_ARB + 0x0040 */ + volatile uint32_t version; /* MBAR_XLB_ARB + 0x0044 read only = 0x0001 */ + volatile uint32_t xlb_status; /* MBAR_XLB_ARB + 0x0048 */ + volatile uint32_t int_enable; /* MBAR_XLB_ARB + 0x004c */ + volatile uint32_t add_capture; /* MBAR_XLB_ARB + 0x0050 read only */ + volatile uint32_t bus_sig_capture; /* MBAR_XLB_ARB + 0x0054 read only */ + volatile uint32_t add_time_out; /* MBAR_XLB_ARB + 0x0058 */ + volatile uint32_t data_time_out; /* MBAR_XLB_ARB + 0x005c */ + volatile uint32_t bus_time_out; /* MBAR_XLB_ARB + 0x0060 */ + volatile uint32_t priority_enable; /* MBAR_XLB_ARB + 0x0064 */ + volatile uint32_t priority; /* MBAR_XLB_ARB + 0x0068 */ + volatile uint32_t arb_base_addr2; /* MBAR_XLB_ARB + 0x006c */ + volatile uint32_t snoop_window; /* MBAR_XLB_ARB + 0x0070 */ + + volatile uint32_t reserved16; /* MBAR_XLB_ARB + 0x0074 reserved */ + volatile uint32_t reserved17; /* MBAR_XLB_ARB + 0x0078 reserved */ + volatile uint32_t reserved18; /* MBAR_XLB_ARB + 0x007c reserved */ + + volatile uint32_t control; /* MBAR_XLB_ARB + 0x0080 */ + volatile uint32_t init_total_count; /* MBAR_XLB_ARB + 0x0084 */ + volatile uint32_t int_total_count; /* MBAR_XLB_ARB + 0x0088 */ + + volatile uint32_t reserved19; /* MBAR_XLB_ARB + 0x008c reserved */ + + volatile uint32_t lower_address; /* MBAR_XLB_ARB + 0x0090 */ + volatile uint32_t higher_address; /* MBAR_XLB_ARB + 0x0094 */ + volatile uint32_t int_window_count; /* MBAR_XLB_ARB + 0x0098 */ + volatile uint32_t window_ter_count; /* MBAR_XLB_ARB + 0x009c */ + volatile uint8_t res_0x1fa0[0x60]; + + +#endif + /* + * programmable serial controller 1 (MBAR + 0x2000) + */ + + struct mpc5200_psc + { + volatile uint8_t mr; /* +0x00 */ + volatile uint8_t res1[3]; + volatile uint16_t sr_csr; /* +0x04 */ + volatile uint16_t res2[1]; + volatile uint16_t cr; /* +0x08 */ + volatile uint16_t res3[1]; + volatile uint32_t rb_tb; /* +0x0c */ + volatile uint16_t ipcr_acr; /* +0x10 */ + volatile uint16_t res4[1]; + volatile uint16_t isr_imr; /* +0x14 */ +#define ISR_TX_RDY (1 << 8) +#define ISR_RX_RDY_FULL (1 << 9) +#define ISR_RB (1 << 15) +#define ISR_FE (1 << 14) +#define ISR_PE (1 << 13) +#define ISR_OE (1 << 12) +#define ISR_ERROR (ISR_FE | ISR_PE | ISR_OE) + +#define IMR_TX_RDY (1 << 8) +#define IMR_RX_RDY_FULL (1 << 9) + volatile uint16_t res5[1]; + volatile uint8_t ctur; /* +0x18 */ + volatile uint8_t res6[3]; + volatile uint8_t ctlr; /* +0x1C */ + volatile uint8_t res7[0x13]; + volatile uint8_t ivr; /* +0x30 */ + volatile uint8_t res8[3]; + volatile uint8_t ip; /* +0x34 */ + volatile uint8_t res9[3]; + volatile uint8_t op1; /* +0x38 */ + volatile uint8_t res10[3]; + volatile uint8_t op0; /* +0x3C */ + volatile uint8_t res11[3]; + volatile uint8_t sicr; /* +0x40 */ + volatile uint8_t res12[0x17]; + volatile uint16_t rfnum; /* +0x58 */ + volatile uint16_t res13[1]; + volatile uint16_t tfnum; /* +0x5C */ + volatile uint16_t res14[1]; + volatile uint16_t rfdata; /* +0x60 */ + volatile uint16_t res15[1]; + volatile uint16_t rfstat; /* +0x64 */ + volatile uint16_t res16[1]; + volatile uint8_t rfcntl; /* +0x68 */ + volatile uint8_t res17[5]; + volatile uint16_t rfalarm; /* +0x6E */ + volatile uint8_t res18[2]; + volatile uint16_t rfrptr; /* +0x72 */ + volatile uint16_t res19[1]; + volatile uint16_t rfwptr; /* +0x76 */ + volatile uint16_t res20[1]; + volatile uint16_t rflrfptr; /* +0x7A */ + volatile uint16_t rflwfptr; /* +0x7C */ + volatile uint16_t res21[1]; + volatile uint16_t tfdata; /* +0x80 */ + volatile uint16_t res22[1]; + volatile uint16_t tfstat; /* +0x84 */ + volatile uint16_t res23[1]; + volatile uint8_t tfcntl; /* +0x88 */ + volatile uint8_t res24[5]; + volatile uint16_t tfalarm; /* +0x8E */ + volatile uint8_t res25[2]; + volatile uint16_t tfrptr; /* +0x92 */ + volatile uint16_t res26[1]; + volatile uint16_t tfwptr; /* +0x96 */ + volatile uint16_t res27[1]; + volatile uint16_t tflrfptr; /* +0x96 */ + volatile uint16_t tflwfptr; /* +0x9C */ + volatile uint16_t res28[1]; /* end at offset 0x9F */ + volatile uint8_t res29[0x160]; + } psc[MPC5200_PSC_REG_SETS]; + /* XXX: there are only 6 PSCs, but PSC6 has an extra register gap + * from PSC5, therefore we instantiate seven(!) PSC register sets + */ + +#define TX_FIFO_SIZE 256 +#define RX_FIFO_SIZE 512 + + + volatile uint8_t irda[0x200]; + + /* + * ethernet registers (MBAR + 0x3000) + */ + + /* Control and status Registers (offset 000-1FF) */ + + volatile uint32_t fec_id; /* + 0x000 */ + volatile uint32_t ievent; /* + 0x004 */ + volatile uint32_t imask; /* + 0x008 */ + + volatile uint32_t res9[1]; /* + 0x00C */ + volatile uint32_t r_des_active; /* + 0x010 */ + volatile uint32_t x_des_active; /* + 0x014 */ + volatile uint32_t r_des_active_cl; /* + 0x018 */ + volatile uint32_t x_des_active_cl; /* + 0x01C */ + volatile uint32_t ivent_set; /* + 0x020 */ + volatile uint32_t ecntrl; /* + 0x024 */ + + volatile uint32_t res10[6]; /* + 0x028-03C */ + volatile uint32_t mii_data; /* + 0x040 */ + volatile uint32_t mii_speed; /* + 0x044 */ + volatile uint32_t mii_status; /* + 0x048 */ + + volatile uint32_t res11[5]; /* + 0x04C-05C */ + volatile uint32_t mib_data; /* + 0x060 */ + volatile uint32_t mib_control; /* + 0x064 */ + + volatile uint32_t res12[6]; /* + 0x068-7C */ + volatile uint32_t r_activate; /* + 0x080 */ + volatile uint32_t r_cntrl; /* + 0x084 */ + volatile uint32_t r_hash; /* + 0x088 */ + volatile uint32_t r_data; /* + 0x08C */ + volatile uint32_t ar_done; /* + 0x090 */ + volatile uint32_t r_test; /* + 0x094 */ + volatile uint32_t r_mib; /* + 0x098 */ + volatile uint32_t r_da_low; /* + 0x09C */ + volatile uint32_t r_da_high; /* + 0x0A0 */ + + volatile uint32_t res13[7]; /* + 0x0A4-0BC */ + volatile uint32_t x_activate; /* + 0x0C0 */ + volatile uint32_t x_cntrl; /* + 0x0C4 */ + volatile uint32_t backoff; /* + 0x0C8 */ + volatile uint32_t x_data; /* + 0x0CC */ + volatile uint32_t x_status; /* + 0x0D0 */ + volatile uint32_t x_mib; /* + 0x0D4 */ + volatile uint32_t x_test; /* + 0x0D8 */ + volatile uint32_t fdxfc_da1; /* + 0x0DC */ + volatile uint32_t fdxfc_da2; /* + 0x0E0 */ + volatile uint32_t paddr1; /* + 0x0E4 */ + volatile uint32_t paddr2; /* + 0x0E8 */ + volatile uint32_t op_pause; /* + 0x0EC */ + + volatile uint32_t res14[4]; /* + 0x0F0-0FC */ + volatile uint32_t instr_reg; /* + 0x100 */ + volatile uint32_t context_reg; /* + 0x104 */ + volatile uint32_t test_cntrl; /* + 0x108 */ + volatile uint32_t acc_reg; /* + 0x10C */ + volatile uint32_t ones; /* + 0x110 */ + volatile uint32_t zeros; /* + 0x114 */ + volatile uint32_t iaddr1; /* + 0x118 */ + volatile uint32_t iaddr2; /* + 0x11C */ + volatile uint32_t gaddr1; /* + 0x120 */ + volatile uint32_t gaddr2; /* + 0x124 */ + volatile uint32_t random; /* + 0x128 */ + volatile uint32_t rand1; /* + 0x12C */ + volatile uint32_t tmp; /* + 0x130 */ + + volatile uint32_t res15[3]; /* + 0x134-13C */ + volatile uint32_t fifo_id; /* + 0x140 */ + volatile uint32_t x_wmrk; /* + 0x144 */ + volatile uint32_t fcntrl; /* + 0x148 */ + volatile uint32_t r_bound; /* + 0x14C */ + volatile uint32_t r_fstart; /* + 0x150 */ + volatile uint32_t r_count; /* + 0x154 */ + volatile uint32_t r_lag; /* + 0x158 */ + volatile uint32_t r_read; /* + 0x15C */ + volatile uint32_t r_write; /* + 0x160 */ + volatile uint32_t x_count; /* + 0x164 */ + volatile uint32_t x_lag; /* + 0x168 */ + volatile uint32_t x_retry; /* + 0x16C */ + volatile uint32_t x_write; /* + 0x170 */ + volatile uint32_t x_read; /* + 0x174 */ + + volatile uint32_t res16[2]; /* + 0x178-17C */ + volatile uint32_t fm_cntrl; /* + 0x180 */ + volatile uint32_t rfifo_data; /* + 0x184 */ + volatile uint32_t rfifo_status; /* + 0x188 */ + volatile uint32_t rfifo_cntrl; /* + 0x18C */ + volatile uint32_t rfifo_lrf_ptr; /* + 0x190 */ + volatile uint32_t rfifo_lwf_ptr; /* + 0x194 */ + volatile uint32_t rfifo_alarm; /* + 0x198 */ + volatile uint32_t rfifo_rdptr; /* + 0x19C */ + volatile uint32_t rfifo_wrptr; /* + 0x1A0 */ + volatile uint32_t tfifo_data; /* + 0x1A4 */ + volatile uint32_t tfifo_status; /* + 0x1A8 */ + volatile uint32_t tfifo_cntrl; /* + 0x1AC */ + volatile uint32_t tfifo_lrf_ptr; /* + 0x1B0 */ + volatile uint32_t tfifo_lwf_ptr; /* + 0x1B4 */ + volatile uint32_t tfifo_alarm; /* + 0x1B8 */ + volatile uint32_t tfifo_rdptr; /* + 0x1BC */ + volatile uint32_t tfifo_wrptr; /* + 0x1C0 */ + + volatile uint32_t reset_cntrl; /* + 0x1C4 */ + volatile uint32_t xmit_fsm; /* + 0x1C8 */ + + volatile uint32_t res17[3]; /* + 0x1CC-1D4 */ + volatile uint32_t rdes_data0; /* + 0x1D8 */ + volatile uint32_t rdes_data1; /* + 0x1DC */ + volatile uint32_t r_length; /* + 0x1E0 */ + volatile uint32_t x_length; /* + 0x1E4 */ + volatile uint32_t x_addr; /* + 0x1E8 */ + volatile uint32_t cdes_data; /* + 0x1EC */ + volatile uint32_t status; /* + 0x1F0 */ + volatile uint32_t dma_control; /* + 0x1F4 */ + volatile uint32_t des_cmnd; /* + 0x1F8 */ + volatile uint32_t data; /* + 0x1FC */ + + volatile uint8_t RES[0x600]; + + +#if 0 + /* MIB COUNTERS (Offset 200-2FF) */ + + volatile uint32_t rmon_t_drop; /* + 0x200 */ + volatile uint32_t rmon_t_packets; /* + 0x204 */ + volatile uint32_t rmon_t_bc_pkt; /* + 0x208 */ + volatile uint32_t rmon_t_mc_pkt; /* + 0x20C */ + volatile uint32_t rmon_t_crc_align; /* + 0x210 */ + volatile uint32_t rmon_t_undersize; /* + 0x214 */ + volatile uint32_t rmon_t_oversize; /* + 0x218 */ + volatile uint32_t rmon_t_frag; /* + 0x21C */ + volatile uint32_t rmon_t_jab; /* + 0x220 */ + volatile uint32_t rmon_t_col; /* + 0x224 */ + volatile uint32_t rmon_t_p64; /* + 0x228 */ + volatile uint32_t rmon_t_p65to127; /* + 0x22C */ + volatile uint32_t rmon_t_p128to255; /* + 0x230 */ + volatile uint32_t rmon_t_p256to511; /* + 0x234 */ + volatile uint32_t rmon_t_p512to1023; /* + 0x238 */ + volatile uint32_t rmon_t_p1024to2047;/* + 0x23C */ + volatile uint32_t rmon_t_p_gte2048; /* + 0x240 */ + volatile uint32_t rmon_t_octets; /* + 0x244 */ + volatile uint32_t ieee_t_drop; /* + 0x248 */ + volatile uint32_t ieee_t_frame_ok; /* + 0x24C */ + volatile uint32_t ieee_t_1col; /* + 0x250 */ + volatile uint32_t ieee_t_mcol; /* + 0x254 */ + volatile uint32_t ieee_t_def; /* + 0x258 */ + volatile uint32_t ieee_t_lcol; /* + 0x25C */ + volatile uint32_t ieee_t_excol; /* + 0x260 */ + volatile uint32_t ieee_t_macerr; /* + 0x264 */ + volatile uint32_t ieee_t_cserr; /* + 0x268 */ + volatile uint32_t ieee_t_sqe; /* + 0x26C */ + volatile uint32_t t_fdxfc; /* + 0x270 */ + volatile uint32_t ieee_t_octets_ok; /* + 0x274 */ + + volatile uint32_t res18[2]; /* + 0x278-27C */ + volatile uint32_t rmon_r_drop; /* + 0x280 */ + volatile uint32_t rmon_r_packets; /* + 0x284 */ + volatile uint32_t rmon_r_bc_pkt; /* + 0x288 */ + volatile uint32_t rmon_r_mc_pkt; /* + 0x28C */ + volatile uint32_t rmon_r_crc_align; /* + 0x290 */ + volatile uint32_t rmon_r_undersize; /* + 0x294 */ + volatile uint32_t rmon_r_oversize; /* + 0x298 */ + volatile uint32_t rmon_r_frag; /* + 0x29C */ + volatile uint32_t rmon_r_jab; /* + 0x2A0 */ + + volatile uint32_t rmon_r_resvd_0; /* + 0x2A4 */ + + volatile uint32_t rmon_r_p64; /* + 0x2A8 */ + volatile uint32_t rmon_r_p65to127; /* + 0x2AC */ + volatile uint32_t rmon_r_p128to255; /* + 0x2B0 */ + volatile uint32_t rmon_r_p256to511; /* + 0x2B4 */ + volatile uint32_t rmon_r_p512to1023; /* + 0x2B8 */ + volatile uint32_t rmon_r_p1024to2047;/* + 0x2BC */ + volatile uint32_t rmon_r_p_gte2048; /* + 0x2C0 */ + volatile uint32_t rmon_r_octets; /* + 0x2C4 */ + volatile uint32_t ieee_r_drop; /* + 0x2C8 */ + volatile uint32_t ieee_r_frame_ok; /* + 0x2CC */ + volatile uint32_t ieee_r_crc; /* + 0x2D0 */ + volatile uint32_t ieee_r_align; /* + 0x2D4 */ + volatile uint32_t r_macerr; /* + 0x2D8 */ + volatile uint32_t r_fdxfc; /* + 0x2DC */ + volatile uint32_t ieee_r_octets_ok; /* + 0x2E0 */ + + volatile uint32_t res19[6]; /* + 0x2E4-2FC */ + + volatile uint32_t res20[64]; /* + 0x300-3FF */ + + volatile uint32_t res21[256]; /* + 0x400-800 */ +#endif + + /* + * SmartComm DMA PCI registers (MBAR + 0x3800) + */ + volatile uint8_t pci[0x200]; + + /* + * advanced technology attachment registers (MBAR + 0x3A00) + */ + + /* ATA host registers (offset 0x00-0x28) */ + volatile uint32_t ata_hcfg; /* + 0x00 */ + volatile uint32_t ata_hsr; /* + 0x04 */ + volatile uint32_t ata_pio1; /* + 0x08 */ + volatile uint32_t ata_pio2; /* + 0x0C */ + volatile uint32_t ata_dma1; /* + 0x10 */ + volatile uint32_t ata_dma2; /* + 0x14 */ + volatile uint32_t ata_udma1; /* + 0x18 */ + volatile uint32_t ata_udma2; /* + 0x1C */ + volatile uint32_t ata_udma3; /* + 0x20 */ + volatile uint32_t ata_udma4; /* + 0x24 */ + volatile uint32_t ata_udma5; /* + 0x28 */ + volatile uint32_t ata_res1[4]; /* + 0x2C-0x3C */ + + /* ATA FIFO registers (offset 0x3C-0x50) */ + volatile uint32_t ata_rtfdwr; /* + 0x3C */ + volatile uint32_t ata_rtfsr; /* + 0x40 */ + volatile uint32_t ata_rtfcr; /* + 0x44 */ + volatile uint32_t ata_rtfar; /* + 0x48 */ + volatile uint32_t ata_rtfrpr; /* + 0x4C */ + volatile uint32_t ata_rtfwpr; /* + 0x50 */ + volatile uint32_t ata_res2[2]; /* + 0x54-0x5C */ + + /* ATA drive registers (offset 0x5C-0x80) */ + volatile uint32_t ata_dctr_dasr; /* + 0x5C */ + volatile uint32_t ata_ddr; /* + 0x60 */ + volatile uint32_t ata_dfr_der; /* + 0x64 */ + volatile uint32_t ata_dscr; /* + 0x68 */ + volatile uint32_t ata_dsnr; /* + 0x6C */ + volatile uint32_t ata_dclr; /* + 0x70 */ + volatile uint32_t ata_dchr; /* + 0x74 */ + volatile uint32_t ata_ddhr; /* + 0x78 */ + volatile uint32_t ata_dcr_dsr; /* + 0x7C */ + volatile uint32_t ata_res3[0xA0]; /* + 0x80-0x200 */ + + /* + * inter-integrated circuit registers (MBAR + 0x3D00) + */ + struct mpc5200_i2c_regs_s { + volatile uint8_t madr; /* i2c address reg. +0x00 */ + volatile uint8_t res_1[3]; + volatile uint8_t mfdr; /* i2c freq. divider reg. +0x04 */ + volatile uint8_t res_5[3]; + volatile uint8_t mcr; /* i2c control reg. +0x08 */ + volatile uint8_t res_9[3]; + +#define MPC5200_I2C_MCR_MEN (1 << (7-0)) +#define MPC5200_I2C_MCR_MIEN (1 << (7-1)) +#define MPC5200_I2C_MCR_MSTA (1 << (7-2)) +#define MPC5200_I2C_MCR_MTX (1 << (7-3)) +#define MPC5200_I2C_MCR_TXAK (1 << (7-4)) +#define MPC5200_I2C_MCR_RSTA (1 << (7-5)) + + volatile uint8_t msr; /* i2c status reg. +0x0C */ + volatile uint8_t res_d[3]; +#define MPC5200_I2C_MSR_CF (1 << (7-0)) +#define MPC5200_I2C_MSR_MAAS (1 << (7-1)) +#define MPC5200_I2C_MSR_BB (1 << (7-2)) +#define MPC5200_I2C_MSR_MAL (1 << (7-3)) +#define MPC5200_I2C_MSR_SRW (1 << (7-5)) +#define MPC5200_I2C_MSR_MIF (1 << (7-6)) +#define MPC5200_I2C_MSR_RXAK (1 << (7-7)) + volatile uint8_t mdr; /* i2c data I/O reg. +0x10 */ + volatile uint8_t res_11[3]; + volatile uint8_t res_14[12]; /* reserved +0x14 */ + volatile uint8_t icr; /* i2c irq ctrl reg. +0x20 */ +#define MPC5200_I2C_ICR_BNBE2 (1 << (7-0)) +#define MPC5200_I2C_ICR_TE2 (1 << (7-1)) +#define MPC5200_I2C_ICR_RE2 (1 << (7-2)) +#define MPC5200_I2C_ICR_IE2 (1 << (7-3)) +#define MPC5200_I2C_ICR_MASK2 (MPC5200_I2C_ICR_BNBE2|MPC5200_I2C_ICR_TE2\ + |MPC5200_I2C_ICR_RE2|MPC5200_I2C_ICR_IE2) +#define MPC5200_I2C_ICR_BNBE1 (1 << (7-4)) +#define MPC5200_I2C_ICR_TE1 (1 << (7-5)) +#define MPC5200_I2C_ICR_RE1 (1 << (7-6)) +#define MPC5200_I2C_ICR_IE1 (1 << (7-7)) +#define MPC5200_I2C_ICR_MASK1 (MPC5200_I2C_ICR_BNBE1|MPC5200_I2C_ICR_TE1\ + |MPC5200_I2C_ICR_RE1|MPC5200_I2C_ICR_IE1) + volatile uint8_t res_21[3]; + volatile uint32_t res_24[7]; /* reserved +0x24 */ + } i2c_regs[2]; + volatile uint8_t res_3d80[0x280]; + + /* + * on-chip static RAM memory locations (MBAR + 0x4000) + */ + volatile uint8_t sram_res0x4000[0x4000]; + volatile uint8_t sram[0x4000]; + + } mpc5200_t; + +extern volatile mpc5200_t mpc5200; + +#ifdef __cplusplus +} +#endif + +#endif /*ASM*/ + +#endif /* __MPC5200_h__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/raw_exception.h b/c/src/lib/libbsp/powerpc/gen5200/include/raw_exception.h new file mode 100644 index 0000000000..08dc8db736 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/raw_exception.h @@ -0,0 +1,175 @@ +/* + * raw_execption.h + * + * This file contains implementation of C function to + * Instanciate 60x ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Mtorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com> + * to support 603, 603e, 604, 604e exceptions + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * raw_exception.h,v 1.2 2000/01/03 14:06:42 joel Exp + */ + +#ifndef _LIBCPU_MCP750_EXCEPTION_RAW_EXCEPTION_H +#define _LIBCPU_MCP750_EXCEPTION_RAW_EXCEPTION_H + +/* + * Exception Vectors as defined in the MCP750 manual + */ + +#define ASM_RESET_VECTOR 0x01 +#define ASM_MACH_VECTOR 0x02 +#define ASM_PROT_VECTOR 0x03 +#define ASM_ISI_VECTOR 0x04 +#define ASM_EXT_VECTOR 0x05 +#define ASM_ALIGN_VECTOR 0x06 +#define ASM_PROG_VECTOR 0x07 +#define ASM_FLOAT_VECTOR 0x08 +#define ASM_DEC_VECTOR 0x09 +#define ASM_SYS_VECTOR 0x0C +#define ASM_TRACE_VECTOR 0x0D +#define ASM_PERFMON_VECTOR 0x0F +#define ASM_IMISS_VECTOR 0x10 +#define ASM_DLMISS_VECTOR 0x11 +#define ASM_DSMISS_VECTOR 0x12 +#define ASM_ADDR_VECTOR 0x13 +#define ASM_SYSMGMT_VECTOR 0x14 +#define ASM_ITM_VECTOR 0x17 +#define LAST_VALID_EXC ASM_ITM_VECTOR + +/* + * Vector offsets as defined in the MCP750 manual + */ + +#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8) +#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8) +#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8) +#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8) +#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8) +#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8) +#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8) +#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8) +#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8) +#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8) +#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8) +#define ASM_ADDR_VECTOR_OFFSET (ASM_ADDR_VECTOR << 8) +#define ASM_SYSMGMT_VECTOR_OFFSET (ASM_SYSMGMT_VECTOR << 8) +#define ASM_ITM_VECTOR_OFFSET (ASM_ITM_VECTOR << 8) + + +#ifndef ASM + +/* + * Type definition for raw exceptions. + */ + +typedef unsigned char rtems_vector; +struct __rtems_raw_except_connect_data__; +typedef void (*rtems_raw_except_func) (void); +typedef unsigned char rtems_raw_except_hdl_size; + +typedef struct { + rtems_vector vector; + rtems_raw_except_func raw_hdl; + rtems_raw_except_hdl_size raw_hdl_size; +}rtems_raw_except_hdl; + +typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*); +typedef void (*rtems_raw_except_disable) (const struct __rtems_raw_except_connect_data__*); +typedef int (*rtems_raw_except_is_enabled) (const struct __rtems_raw_except_connect_data__*); + +typedef struct __rtems_raw_except_connect_data__{ + /* + * Exception vector (As defined in the manual) + */ + rtems_vector exceptIndex; + /* + * Exception raw handler. See comment on handler properties below in function prototype. + */ + rtems_raw_except_hdl hdl; + /* + * function for enabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must enable the except at processor level only. + * + */ + rtems_raw_except_enable on; + /* + * function for disabling raw exceptions. In order to be consistent + * with the fact that the raw connexion can defined in the + * libcpu library, this library should have no knowledge of + * board specific hardware to manage exceptions and thus the + * "on" routine must disable the except both at device and PIC level. + * + */ + rtems_raw_except_disable off; + /* + * function enabling to know what exception may currently occur + */ + rtems_raw_except_is_enabled isOn; +}rtems_raw_except_connect_data; + +typedef struct { + /* + * size of all the table fields (*Tbl) described below. + */ + unsigned int exceptSize; + /* + * Default handler used when disconnecting exceptions. + */ + rtems_raw_except_connect_data defaultRawEntry; + /* + * Table containing initials/current value. + */ + rtems_raw_except_connect_data* rawExceptHdlTbl; +}rtems_raw_except_global_settings; + +/* + * C callable function enabling to set up one raw idt entry + */ +extern int mpc60x_set_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to get one current raw idt entry + */ +extern int mpc60x_get_current_exception (rtems_raw_except_connect_data*); + +/* + * C callable function enabling to remove one current raw idt entry + */ +extern int mpc60x_delete_exception (const rtems_raw_except_connect_data*); + +/* + * C callable function enabling to check if vector is valid + */ +extern int mpc750_vector_is_valid(rtems_vector vector); + +inline static void* mpc60x_get_vector_addr(rtems_vector vector) +{ + return ((void*) (((unsigned) vector) << 8)); +} +/* + * Exception global init. + */ +extern int mpc60x_init_exceptions (rtems_raw_except_global_settings* config); +extern int mpc60x_get_exception_config (rtems_raw_except_global_settings** config); + +# endif /* ASM */ + +#endif + diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h b/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h new file mode 100644 index 0000000000..d938e07f6e --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h @@ -0,0 +1,42 @@ +/* + * tm27.h + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * tm27.h,v 1.2 2004/04/23 04:47:38 ralf Exp + */ + +#ifndef _RTEMS_TMTEST27 +#error "This is an RTEMS internal file you must not include directly." +#endif + +#ifndef __tm27_h +#define __tm27_h + +/* + * Stuff for Time Test 27 + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) \ + do { \ + static rtems_irq_connect_data scIrqData = { \ + PPC_IRQ_SCALL, \ + (rtems_irq_hdl) handler, \ + NULL, \ + NULL, \ + NULL \ + }; \ + BSP_install_rtems_irq_handler (&scIrqData); \ + } while(0) + +#define Cause_tm27_intr() asm volatile ("sc") + +#define Clear_tm27_intr() /* empty */ + +#define Lower_tm27_intr() /* empty */ + +#endif diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/u-boot.h b/c/src/lib/libbsp/powerpc/gen5200/include/u-boot.h new file mode 100644 index 0000000000..f7aa55f334 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/include/u-boot.h @@ -0,0 +1,133 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef __U_BOOT_H__ +#define __U_BOOT_H__ + +/* + * Board information passed to Linux kernel from U-Boot + * + * include/asm-ppc/u-boot.h + */ + +#ifndef __ASSEMBLY__ + +typedef struct bd_info { + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ + unsigned long bi_sramstart; /* start of SRAM memory */ + unsigned long bi_sramsize; /* size of SRAM memory */ +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ + || defined(CONFIG_E500) + unsigned long bi_immr_base; /* base of IMMR register */ +#endif +#if defined(CONFIG_MPC5xxx) + unsigned long bi_mbar_base; /* base of internal registers */ +#endif +#if defined(CONFIG_MPC83XX) + unsigned long bi_immrbar; +#endif +#if defined(CONFIG_MPC8220) + unsigned long bi_mbar_base; /* base of internal registers */ + unsigned long bi_inpfreq; /* Input Freq, In MHz */ + unsigned long bi_pcifreq; /* PCI Freq, in MHz */ + unsigned long bi_pevfreq; /* PEV Freq, in MHz */ + unsigned long bi_flbfreq; /* Flexbus Freq, in MHz */ + unsigned long bi_vcofreq; /* VCO Freq, in MHz */ +#endif + unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ + unsigned long bi_intfreq; /* Internal Freq, in MHz */ + unsigned long bi_busfreq; /* Bus Freq, in MHz */ +#if defined(CONFIG_CPM2) + unsigned long bi_cpmfreq; /* CPM_CLK Freq, in MHz */ + unsigned long bi_brgfreq; /* BRG_CLK Freq, in MHz */ + unsigned long bi_sccfreq; /* SCC_CLK Freq, in MHz */ + unsigned long bi_vco; /* VCO Out from PLL, in MHz */ +#endif +#if defined(CONFIG_MPC5xxx) + unsigned long bi_ipbfreq; /* IPB Bus Freq, in MHz */ + unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */ +#endif + unsigned long bi_baudrate; /* Console Baudrate */ +#if defined(CONFIG_405) || \ + defined(CONFIG_405GP) || \ + defined(CONFIG_405CR) || \ + defined(CONFIG_405EP) || \ + defined(CONFIG_440) + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[32]; /* Version of the ROM (AMCC) */ + unsigned int bi_procfreq; /* CPU (Internal) Freq, in Hz */ + unsigned int bi_plb_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ + unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */ +#endif +#if defined(CONFIG_HYMOD) + hymod_conf_t bi_hymod_conf; /* hymod configuration information */ +#endif + +#ifdef CONFIG_HAS_ETH1 + /* second onboard ethernet port */ + unsigned char bi_enet1addr[6]; +#endif +#ifdef CONFIG_HAS_ETH2 + /* third onboard ethernet port */ + unsigned char bi_enet2addr[6]; +#endif +#ifdef CONFIG_HAS_ETH3 + unsigned char bi_enet3addr[6]; +#endif + +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined (CONFIG_440GX) || \ + defined(CONFIG_440EP) || defined(CONFIG_440GR) + unsigned int bi_opbfreq; /* OPB clock in Hz */ + int bi_iic_fast[2]; /* Use fast i2c mode */ +#endif +#if defined(CONFIG_NX823) + unsigned char bi_sernum[8]; +#endif +#if defined(CONFIG_4xx) +#if defined(CONFIG_440GX) + int bi_phynum[4]; /* Determines phy mapping */ + int bi_phymode[4]; /* Determines phy mode */ +#elif defined(CONFIG_405EP) || defined(CONFIG_440) + int bi_phynum[2]; /* Determines phy mapping */ + int bi_phymode[2]; /* Determines phy mode */ +#else + int bi_phynum[1]; /* Determines phy mapping */ + int bi_phymode[1]; /* Determines phy mode */ +#endif +#endif /* defined(CONFIG_4xx) */ +} bd_t; + +#endif /* __ASSEMBLY__ */ +#endif /* __U_BOOT_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c new file mode 100644 index 0000000000..2cde1fe025 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c @@ -0,0 +1,1141 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: irq.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the irq controller handler | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.6 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.5 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.4 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: irq.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 CPU main interrupt handler & routines */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This file contains the implementation of the */ +/* functions described in irq.h */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: MPC8260ads main interrupt handler & routines */ +/* Module: irc.c */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 04/18/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Copyright (C) 1998, 1999 valette@crf.canon.fr */ +/* */ +/* Modified for mpc8260 Andy Dachs <a.dachs@sstl.co.uk> */ +/* Surrey Satellite Technology Limited, 2000 */ +/* Nested exception handlers not working yet. */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include <rtems.h> +/*#include "../irq/irq.h"*/ +#include "../irq/irq.h" +/*#include <rtems/score/thread.h>*/ +#include <rtems/score/apiext.h> +#include <rtems/bspIo.h> +#include "../include/raw_exception.h" +#include "../vectors/vectors.h" +#include "../include/mpc5200.h" + + +extern uint32_t irqMaskTable[]; + +/* + * default handler connected on each irq after bsp initialization + */ +static rtems_irq_connect_data default_rtems_entry; + +/* + * location used to store initial tables used for interrupt + * management. + */ +static rtems_irq_global_settings* internal_config; +static rtems_irq_connect_data* rtems_hdl_tbl; + +/* + * bit in the SIU mask registers (PPC bit numbering) that should + * be set to enable the relevant interrupt, mask of 32 is for unused entries + * + */ +const static unsigned int SIU_MaskBit[BSP_SIU_IRQ_NUMBER] = + { + 0, 1, 2, 3, /* smart_comm, psc1, psc2, psc3 */ + 4, 5, 6, 7, /* irda/psc6, eth, usb, ata */ + 8, 9, 10, 11, /* pci_ctrl, pci_sc_rx, pci_sc_tx, psc4 */ + 12, 13, 14, 15, /* psc5,spi_modf, spi_spif, i2c1 */ + 16, 17, 18, 19, /* i2c, can1, can2, ir_rx */ + 20, 21, 15, 16, /* ir_rx, xlb_arb, slice_tim2, irq1, */ + 17, 18, 19, 20, /* irq2, irq3, lo_int, rtc_pint */ + 21, 22, 23, 24, /* rtc_sint, gpio_std, gpio_wkup, tmr0 */ + 25, 26, 27, 28, /* tmr1, tmr2, tmr3, tmr4 */ + 29, 30, 31, 32, /* tmr5, tmr6, tmr7, res */ + 32, 32, 32 /* res, res, res */ + }; + +/* + * Check if symbolic IRQ name is a Processor IRQ + */ +static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine) + { + + return (((int)irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) & ((int)irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)); + + } + +/* + * Check for SIU IRQ and return base index + */ +static inline int is_siu_irq(const rtems_irq_symbolic_name irqLine) + { + + return (((int)irqLine <= BSP_SIU_IRQ_MAX_OFFSET) && ((int)irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET)); + + } + + +/* + * Check for SIU IRQ and return base index + */ +static inline int get_siu_irq_base_index(const rtems_irq_symbolic_name irqLine) + { + + if(irqLine <= BSP_PER_IRQ_MAX_OFFSET) + return BSP_PER_IRQ_LOWEST_OFFSET; + else + if(irqLine <= BSP_MAIN_IRQ_MAX_OFFSET) + return BSP_MAIN_IRQ_LOWEST_OFFSET; + else + if(irqLine <= BSP_CRIT_IRQ_MAX_OFFSET) + return BSP_CRIT_IRQ_LOWEST_OFFSET; + else + return -1; + + } + + +static inline void BSP_enable_per_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + uint8_t lo_hi_ind = 0, prio_index_offset; + uint32_t *reg; + rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl; + volatile uint32_t per_pri_1,main_pri_1, crit_pri_main_mask, per_mask; + + /* calculate the index offset of priority value bit field */ + prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8; + + /* set interrupt priorities */ + if(irqPrioTable[irqLine] <= 15) + { + + /* set peripheral int priority */ + reg = (uint32_t *)(&(mpc5200.per_pri_1)); + + /* choose proper register */ + reg += (irqLine >> 3); + + /* set priority as given in priority table */ + *reg |= (irqPrioTable[irqLine] << (28 - (prio_index_offset<< 2))); + + /* test msb (hash-bit) and set LO_/HI_int indicator */ + if((lo_hi_ind = (irqPrioTable[irqLine] >> 3))) + { + + /* set critical HI_int priority */ + reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask)); + *reg |= (irqPrioTable[BSP_SIU_IRQ_HI_INT] << 26); + + /* + * critical interrupt handling for the 603le core is not + * yet supported, routing of critical interrupts is forced + * to core_int (bit 31 / CEb) + */ + mpc5200.ext_en_type |= 1; + + } + else + { + + if(irqPrioTable[irqLine] <= 15) + { + + /* set main LO_int priority */ + reg = (uint32_t *)(&(mpc5200.main_pri_1)); + *reg |= (irqPrioTable[BSP_SIU_IRQ_LO_INT] << 16); + + } + + } + + } + + /* if LO_int ind., enable (unmask) main interrupt */ + if(!lo_hi_ind) + { + + mpc5200.crit_pri_main_mask &= ~(0x80000000 >> SIU_MaskBit[BSP_SIU_IRQ_LO_INT]); + + } + + + /* enable (unmask) peripheral interrupt */ + mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit[irqLine]); + + main_pri_1 = mpc5200.main_pri_1; + crit_pri_main_mask = mpc5200.crit_pri_main_mask; + per_pri_1 = mpc5200.per_pri_1; + per_mask = mpc5200.per_mask; + + + } + + +static inline void BSP_enable_main_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + + uint8_t prio_index_offset; + uint32_t *reg; + rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl; + + /* calculate the index offset of priority value bit field */ + prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8; + + /* set main interrupt priority */ + if(irqPrioTable[irqLine] <= 15) + { + + /* set main int priority */ + reg = (uint32_t *)(&(mpc5200.main_pri_1)); + + /* choose proper register */ + reg += (irqLine >> 3); + + /* set priority as given in priority table */ + *reg |= (irqPrioTable[irqLine] << (28 - (prio_index_offset << 2))); + + if((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3)) + { + + /* enable external irq-pin */ + mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset)); + + } + + } + + /* enable (unmask) main interrupt */ + mpc5200.crit_pri_main_mask &= ~(0x80000000 >> SIU_MaskBit[irqLine]); + + } + + +static inline void BSP_enable_crit_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + + uint8_t prio_index_offset; + uint32_t *reg; + rtems_irq_prio *irqPrioTable = internal_config->irqPrioTbl; + + prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET; + + /* + * critical interrupt handling for the 603Le core is not + * yet supported, routing of critical interrupts is forced + * to core_int (bit 31 / CEb) + */ + mpc5200.ext_en_type |= 1; + + + /* set critical interrupt priorities */ + if(irqPrioTable[irqLine] <= 3) + { + + /* choose proper register */ + reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask)); + + /* set priority as given in priority table */ + *reg |= (irqPrioTable[irqLine] << (30 - (prio_index_offset << 1))); + + /* external irq0-pin */ + if(irqLine == BSP_SIU_IRQ_IRQ1) + { + + /* enable external irq-pin */ + mpc5200.ext_en_type |= (0x80000000 >> (20 + prio_index_offset)); + + } + + } + + } + + +static inline void BSP_disable_per_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + + uint8_t prio_index_offset; + uint32_t *reg; + + /* calculate the index offset of priority value bit field */ + prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8; + + /* disable (mask) peripheral interrupt */ + mpc5200.per_mask |= (0x80000000 >> SIU_MaskBit[irqLine]); + + /* reset priority to lowest level (reset value) */ + reg = (uint32_t *)(&(mpc5200.per_pri_1)); + reg += (irqLine >> 3); + *reg &= ~(15 << (28 - (prio_index_offset << 2))); + + } + + +static inline void BSP_disable_main_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + + uint8_t prio_index_offset; + uint32_t *reg; + + /* calculate the index offset of priority value bit field */ + prio_index_offset = (irqLine - BSP_MAIN_IRQ_LOWEST_OFFSET) % 8; + + /* disable (mask) main interrupt */ + mpc5200.crit_pri_main_mask |= (0x80000000 >> SIU_MaskBit[irqLine]); + + if((irqLine >= BSP_SIU_IRQ_IRQ1) && (irqLine <= BSP_SIU_IRQ_IRQ3)) + { + + /* disable external irq-pin */ + mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset)); + + } + + /* reset priority to lowest level (reset value) */ + reg = (uint32_t *)(&(mpc5200.main_pri_1)); + reg += (irqLine >> 3); + *reg &= ~(15 << (28 - (prio_index_offset << 2))); + + } + + +static inline void BSP_disable_crit_irq_at_siu(const rtems_irq_symbolic_name irqLine) + { + + uint8_t prio_index_offset; + uint32_t *reg; + + prio_index_offset = irqLine - BSP_CRIT_IRQ_LOWEST_OFFSET; + + /* reset critical int priority to lowest level (reset value) */ + reg = (uint32_t *)(&(mpc5200.crit_pri_main_mask)); + *reg &= ~(3 << (30 - (prio_index_offset << 1))); + + if(irqLine == BSP_SIU_IRQ_IRQ1) + { + + /* disable external irq0-pin */ + mpc5200.ext_en_type &= ~(0x80000000 >> (20 + prio_index_offset)); + + } + + } + + +/* + * ------------------------ RTEMS Irq helper functions ---------------- + */ + + +/* + * This function check that the value given for the irq line + * is valid. + */ +static int isValidInterrupt(int irq) + { + if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET) ) + return 0; + return 1; + } + + + /* + * This function enables a given siu interrupt + */ +int BSP_irq_enable_at_siu(const rtems_irq_symbolic_name irqLine) + { + int base_index; + + if(is_siu_irq(irqLine)) + { + + + if((base_index = get_siu_irq_base_index(irqLine)) != -1) + { + + switch(base_index) + { + + case BSP_PER_IRQ_LOWEST_OFFSET: + BSP_enable_per_irq_at_siu(irqLine); + break; + + case BSP_MAIN_IRQ_LOWEST_OFFSET: + BSP_enable_main_irq_at_siu(irqLine); + break; + + case BSP_CRIT_IRQ_LOWEST_OFFSET: + BSP_enable_crit_irq_at_siu(irqLine); + break; + + default: + printk("No valid base index\n"); + break; + + } + + } + + } + + return 0; + + } + +/* + * This function disables a given siu interrupt + */ +int BSP_irq_disable_at_siu(const rtems_irq_symbolic_name irqLine) + { + int base_index; + + if ( (base_index = get_siu_irq_base_index(irqLine)) == -1) + return 1; + + switch(base_index) + { + + case BSP_PER_IRQ_LOWEST_OFFSET: + BSP_disable_per_irq_at_siu(irqLine); + + break; + + case BSP_MAIN_IRQ_LOWEST_OFFSET: + BSP_disable_main_irq_at_siu(irqLine); + break; + + case BSP_CRIT_IRQ_LOWEST_OFFSET: + BSP_disable_crit_irq_at_siu(irqLine); + break; + + default: + printk("No valid base index\n"); + break; + + } + + return 0; + } + + +/* + * ------------------------ RTEMS Single Irq Handler Mngt Routines ---------------- + */ + + /* + * This function removes the default entry and installs a device interrupt handler + */ +int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) + { + unsigned int level; + + if(!isValidInterrupt(irq->name)) + { + + printk("not a valid interrupt\n"); + return 0; + + } + + /* + * Check if default handler is actually connected. If not issue an error. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) + { + + printk( "Default handler not there\n" ); + return 0; + + } + + _CPU_ISR_Disable(level); + + /* + * store the data provided by user + */ + rtems_hdl_tbl[irq->name] = *irq; + + if(is_siu_irq(irq->name)) + { + + /* + * Enable interrupt at siu level + */ + BSP_irq_enable_at_siu(irq->name); + + } + else + { + + if(is_processor_irq(irq->name)) + { + + /* + * Should Enable exception at processor level but not needed. Will restore + * EE flags at the end of the routine anyway. + */ + + + } + else + { + + printk("not a valid interrupt\n"); + return 0; + + } + + } + + + /* + * Enable interrupt on device + */ + irq->on(irq); + + _CPU_ISR_Enable(level); + + return 1; + + } + + + /* + * This function procures the current interrupt handler + */ +int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq) + { + + if(!isValidInterrupt(irq->name)) + { + + return 0; + + } + + *irq = rtems_hdl_tbl[irq->name]; + return 1; + + } + + + /* + * This function removes a device interrupt handler and restores the default entry + */ +int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) + { + unsigned int level; + + if(!isValidInterrupt(irq->name)) + { + + return 0; + + } + + /* + * Check if default handler is actually connected. If not issue an error. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if(rtems_hdl_tbl[irq->name].hdl != irq->hdl) + { + + return 0; + + } + + _CPU_ISR_Disable(level); + + if(is_siu_irq(irq->name)) + { + + /* + * disable interrupt at PIC level + */ + BSP_irq_disable_at_siu(irq->name); + + } + + if(is_processor_irq(irq->name)) + { + /* + * disable exception at processor level + */ + } + + /* + * Disable interrupt on device + */ + irq->off(irq); + + /* + * restore the default irq value + */ + rtems_hdl_tbl[irq->name] = default_rtems_entry; + + _CPU_ISR_Enable(level); + + return 1; + + } + + +/* + * ------------------------ RTEMS Global Irq Handler Mngt Routines ---------------- + */ + +/* + * This function set up interrupt management dependent on the given configuration + */ +int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) + { + int i; + unsigned int level; + + /* + * Store various code accelerators + */ + internal_config = config; + default_rtems_entry = config->defaultEntry; + rtems_hdl_tbl = config->irqHdlTbl; + + _CPU_ISR_Disable(level); + + /* + * start with SIU IRQs + */ + for (i=BSP_SIU_IRQ_LOWEST_OFFSET; i < BSP_SIU_IRQ_LOWEST_OFFSET + BSP_SIU_IRQ_NUMBER ; i++) + { + + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) + { + + BSP_irq_enable_at_siu(i); + rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); + + } + else + { + + rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); + BSP_irq_disable_at_siu(i); + + } + + } + + /* + * finish with Processor exceptions handled like IRQs + */ + for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) + { + + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) + { + + rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); + + } + else + { + + rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); + + } + + } + + _CPU_ISR_Enable(level); + return 1; + + } + + +int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config) + { + + *config = internal_config; + return 0; + + } + + +/* + * High level IRQ handler called from shared_raw_irq_code_entry + */ +void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum) + { + register unsigned int irq; + register unsigned int msr; + register unsigned int new_msr; + register unsigned int pmce; + register unsigned int crit_pri_main_mask, per_mask; + + switch(excNum) + { + + + /* + * Handle decrementer interrupt + */ + case ASM_DEC_VECTOR: + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[BSP_DECREMENTER].hdl(0); + + return; + + case ASM_SYSMGMT_VECTOR: + + /* get the content of main interrupt status register */ + pmce = mpc5200.pmce; + + /* main interrupts may be routed to SMI, see bit SMI/INT select bit in main int. priorities */ + while(CHK_MSE_STICKY(pmce)) + { + + /* check for main interrupt sources (hirarchical order) -> LO_int indicates peripheral sources */ + if(CHK_MSE_STICKY(pmce)) + { + + /* get source of main interrupt */ + irq = MSE_SOURCE(pmce); + + switch(irq) + { + + /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer 2 is always routed to SMI) */ + case 0: /* slice timer 2 */ + case 1: + case 2: + case 3: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + + /* add proper offset for main interrupts in the siu handler array */ + irq += BSP_MAIN_IRQ_LOWEST_OFFSET; + + /* save original mask and disable all lower priorized main interrupts*/ + crit_pri_main_mask = mpc5200.crit_pri_main_mask; + mpc5200.crit_pri_main_mask |= irqMaskTable[irq]; + + /* enable interrupt nesting */ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(0); + + /* disable interrupt nesting */ + _CPU_MSR_SET(msr); + + /* restore original interrupt mask */ + mpc5200.crit_pri_main_mask = crit_pri_main_mask; + + break; + + /* peripheral LO_int interrupt source detected */ + case 4: + + /* check for valid peripheral interrupt source */ + if(CHK_PSE_STICKY(pmce)) + { + + /* get source of peripheral interrupt */ + irq = PSE_SOURCE(pmce); + + /* add proper offset for peripheral interrupts in the siu handler array */ + irq += BSP_PER_IRQ_LOWEST_OFFSET; + + /* save original mask and disable all lower priorized main interrupts */ + per_mask = mpc5200.per_mask; + mpc5200.per_mask |= irqMaskTable[irq]; + + /* enable interrupt nesting */ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(0); + + + /* disable interrupt nesting */ + _CPU_MSR_SET(msr); + + /* restore original interrupt mask */ + mpc5200.per_mask = per_mask; + + /* force re-evaluation of peripheral interrupts */ + CLR_PSE_STICKY(mpc5200.pmce); + + } + /* this case may not occur: no valid peripheral interrupt source */ + else + { + + printk("No valid peripheral LO_int interrupt source\n"); + + } + + break; + + /* error: unknown interrupt source */ + default: + printk("Unknown peripheral LO_int interrupt source\n"); + break; + + } + + /* force re-evaluation of main interrupts */ + CLR_MSE_STICKY(mpc5200.pmce); + + } + + /* get the content of main interrupt status register */ + pmce = mpc5200.pmce; + + } + + break; + + case ASM_EXT_VECTOR: + + /* get the content of main interrupt status register */ + pmce = mpc5200.pmce; + + /* critical interrupts may be routed to the core_int dependent on premature initialization, see bit 31 (CEbsH) */ + while((CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce)) || CHK_MSE_STICKY(pmce) || CHK_PSE_STICKY(pmce) ) + { + + /* first: check for critical interrupt sources (hirarchical order) -> HI_int indicates peripheral sources */ + if(CHK_CE_SHADOW(pmce) && CHK_CSE_STICKY(pmce)) + { + + /* get source of critical interrupt */ + irq = CSE_SOURCE(pmce); + + switch(irq) + { + /* irq0, slice timer 1 or ccs wakeup detected */ + case 0: + case 1: + case 3: + + /* add proper offset for critical interrupts in the siu handler array */ + irq += BSP_CRIT_IRQ_LOWEST_OFFSET; + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); + + break; + + /* peripheral HI_int interrupt source detected */ + case 2: + + /* check for valid peripheral interrupt source */ + if(CHK_PSE_STICKY(pmce)) + { + + /* get source of peripheral interrupt */ + irq = PSE_SOURCE(pmce); + + /* add proper offset for peripheral interrupts in the siu handler array */ + irq += BSP_PER_IRQ_LOWEST_OFFSET; + + /* save original mask and disable all lower priorized main interrupts */ + per_mask = mpc5200.per_mask; + mpc5200.per_mask |= irqMaskTable[irq]; + + /* enable interrupt nesting */ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); + + + /* disable interrupt nesting */ + _CPU_MSR_SET(msr); + + /* restore original interrupt mask */ + mpc5200.per_mask = per_mask; + + /* force re-evaluation of peripheral interrupts */ + CLR_PSE_STICKY(mpc5200.pmce); + + } + /* this case may not occur: no valid peripheral interrupt source */ + else + { + + printk("No valid peripheral HI_int interrupt source\n"); + + } + + break; + + /* error: unknown interrupt source */ + default: + printk("Unknown HI_int interrupt source\n"); + break; + + } + + /* force re-evaluation of critical interrupts */ + CLR_CSE_STICKY(mpc5200.pmce); + + } + + /* second: check for main interrupt sources (hirarchical order) -> LO_int indicates peripheral sources */ + if(CHK_MSE_STICKY(pmce)) + { + + /* get source of main interrupt */ + irq = MSE_SOURCE(pmce); + + switch(irq) + { + + /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer 2 is always routed to SMI) */ + case 1: + case 2: + case 3: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + + /* add proper offset for main interrupts in the siu handler array */ + irq += BSP_MAIN_IRQ_LOWEST_OFFSET; + + /* save original mask and disable all lower priorized main interrupts*/ + crit_pri_main_mask = mpc5200.crit_pri_main_mask; + mpc5200.crit_pri_main_mask |= irqMaskTable[irq]; + + /* enable interrupt nesting */ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); + + /* disable interrupt nesting */ + _CPU_MSR_SET(msr); + + /* restore original interrupt mask */ + mpc5200.crit_pri_main_mask = crit_pri_main_mask; + + break; + + /* peripheral LO_int interrupt source detected */ + case 4: + + /* check for valid peripheral interrupt source */ + if(CHK_PSE_STICKY(pmce)) + { + + /* get source of peripheral interrupt */ + irq = PSE_SOURCE(pmce); + + /* add proper offset for peripheral interrupts in the siu handler array */ + irq += BSP_PER_IRQ_LOWEST_OFFSET; + + /* save original mask and disable all lower priorized main interrupts */ + per_mask = mpc5200.per_mask; + mpc5200.per_mask |= irqMaskTable[irq]; + + /* enable interrupt nesting */ + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* call the module specific handler and pass the specific handler */ + rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); + + + /* disable interrupt nesting */ + _CPU_MSR_SET(msr); + + /* restore original interrupt mask */ + mpc5200.per_mask = per_mask; + + /* force re-evaluation of peripheral interrupts */ + CLR_PSE_STICKY(mpc5200.pmce); + + } + /* this case may not occur: no valid peripheral interrupt source */ + else + { + + printk("No valid peripheral LO_int interrupt source\n"); + + } + + break; + + /* error: unknown interrupt source */ + default: + printk("Unknown peripheral LO_int interrupt source\n"); + break; + + } + + /* force re-evaluation of main interrupts */ + CLR_MSE_STICKY(mpc5200.pmce); + + } + + + /* get the content of main interrupt status register */ + pmce = mpc5200.pmce; + + } + + break; + + default: + printk("Unknown processor exception\n"); + break; + + } /* end of switch(excNum) */ + + return; + + } + + +void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx) + { + /* + * Process pending signals that have not already been + * processed by _Thread_Displatch. This happens quite + * unfrequently : the ISR must have posted an action + * to the current running thread. + */ + if ( _Thread_Do_post_task_switch_extension || + _Thread_Executing->do_post_task_switch_extension ) + { + + _Thread_Executing->do_post_task_switch_extension = FALSE; + _API_extensions_Run_postswitch(); + + } + /* + * I plan to process other thread related events here. + * This will include DEBUG session requested from keyboard... + */ +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h new file mode 100644 index 0000000000..e0d54fdba7 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq.h @@ -0,0 +1,411 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: irq.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains declarations for the irq controller handler | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.6 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.5 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: irq.h */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 CPU interrupt header file */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This include file describe the data structure and */ +/* the functions implemented by rtems to write */ +/* interrupt handlers. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: MPC8260ads CPU interrupt header file */ +/* Module: irq.h */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.1 */ +/* Date: 10/10/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Copyright (C) 1999 valette@crf.canon.fr */ +/* */ +/* This code is heavilly inspired by the public specification of */ +/* STREAM V2 that can be found at: */ +/* */ +/* <http://www.chorus.com/Documentation/index.html> by following */ +/* the STREAM API Specification Document link. */ +/* */ +/* Modified for mpc8260 by Andy Dachs <a.dachs@sstl.co.uk> */ +/* Surrey Satellite Technology Limited */ +/* The interrupt handling on the mpc8260 seems quite different from */ +/* the 860 (I don't know the 860 well). Although some interrupts */ +/* are routed via the CPM irq and some are direct to the SIU they */ +/* all appear logically the same.Therefore I removed the distinction */ +/* between SIU and CPM interrupts. */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#ifndef LIBBSP_POWERPC_MPC5200_IRQ_IRQ_H +#define LIBBSP_POWERPC_MPC5200_IRQ_IRQ_H + +#define CHK_CE_SHADOW(pmce) ((pmce) & 0x00000001) +#define CHK_CSE_STICKY(pmce) (((pmce) >> 10) & 0x00000001) +#define CHK_MSE_STICKY(pmce) (((pmce) >> 21) & 0x00000001) +#define CHK_PSE_STICKY(pmce) (((pmce) >> 29) & 0x00000001) +#define CLR_CSE_STICKY(pmce) ((pmce) |= (1 << 29 )) +#define CLR_MSE_STICKY(pmce) ((pmce) |= (1 << 21 )) +#define CLR_PSE_STICKY(pmce) ((pmce) |= (1 << 10 )) +#define CSE_SOURCE(source) (((source) >> 8) & 0x00000003) +#define MSE_SOURCE(source) (((source) >> 16) & 0x0000001F) +#define PSE_SOURCE(source) (((source) >> 24) & 0x0000001F) + +/* + * Base index for the module specific irq handlers + */ +#define BSP_ASM_IRQ_VECTOR_BASE 0 +#define BSP_PER_VECTOR_BASE BSP_ASM_IRQ_VECTOR_BASE /* 0 */ +/* + * Peripheral IRQ handlers related definitions + */ +#define BSP_PER_IRQ_NUMBER 22 +#define BSP_PER_IRQ_LOWEST_OFFSET BSP_PER_VECTOR_BASE /* 0 */ +#define BSP_PER_IRQ_MAX_OFFSET BSP_PER_IRQ_LOWEST_OFFSET + BSP_PER_IRQ_NUMBER - 1 /* 21 */ +/* + * Main IRQ handlers related definitions + */ +#define BSP_MAIN_IRQ_NUMBER 17 +#define BSP_MAIN_IRQ_LOWEST_OFFSET BSP_PER_IRQ_MAX_OFFSET + 1 /* 22 */ +#define BSP_MAIN_IRQ_MAX_OFFSET BSP_MAIN_IRQ_LOWEST_OFFSET + BSP_MAIN_IRQ_NUMBER - 1 /* 38 */ +/* + * Critical IRQ handlers related definitions + */ +#define BSP_CRIT_IRQ_NUMBER 4 +#define BSP_CRIT_IRQ_LOWEST_OFFSET BSP_MAIN_IRQ_MAX_OFFSET + 1 /* 39 */ +#define BSP_CRIT_IRQ_MAX_OFFSET BSP_CRIT_IRQ_LOWEST_OFFSET + BSP_CRIT_IRQ_NUMBER - 1 /* 42 */ +/* + * Summary of SIU interrupts + */ +#define BSP_SIU_IRQ_NUMBER BSP_CRIT_IRQ_MAX_OFFSET + 1 /* 43 */ +#define BSP_SIU_IRQ_LOWEST_OFFSET BSP_PER_IRQ_LOWEST_OFFSET /* 0 */ +#define BSP_SIU_IRQ_MAX_OFFSET BSP_CRIT_IRQ_MAX_OFFSET /* 42 */ +/* + * Processor IRQ handlers related definitions + */ +#define BSP_PROCESSOR_IRQ_NUMBER 3 +#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET BSP_CRIT_IRQ_MAX_OFFSET + 1 /* 44 */ +#define BSP_PROCESSOR_IRQ_MAX_OFFSET BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1 /* 46 */ +/* + * Summary + */ +#define BSP_IRQ_NUMBER BSP_PROCESSOR_IRQ_MAX_OFFSET + 1 /* 47 */ +#define BSP_LOWEST_OFFSET BSP_PER_IRQ_LOWEST_OFFSET /* 0 */ +#define BSP_MAX_OFFSET BSP_PROCESSOR_IRQ_MAX_OFFSET /* 46 */ + +#ifndef ASM + +/* +extern volatile unsigned int ppc_cached_irq_mask; +*/ + +/* + * index table for the module specific handlers, a few entries are only placeholders + */ +typedef enum + { + BSP_SIU_IRQ_SMARTCOMM = BSP_PER_IRQ_LOWEST_OFFSET + 0, + BSP_SIU_IRQ_PSC1 = BSP_PER_IRQ_LOWEST_OFFSET + 1, + BSP_SIU_IRQ_PSC2 = BSP_PER_IRQ_LOWEST_OFFSET + 2, + BSP_SIU_IRQ_PSC3 = BSP_PER_IRQ_LOWEST_OFFSET + 3, + BSP_SIU_IRQ_PSC6 = BSP_PER_IRQ_LOWEST_OFFSET + 4, + BSP_SIU_IRQ_ETH = BSP_PER_IRQ_LOWEST_OFFSET + 5, + BSP_SIU_IRQ_USB = BSP_PER_IRQ_LOWEST_OFFSET + 6, + BSP_SIU_IRQ_ATA = BSP_PER_IRQ_LOWEST_OFFSET + 7, + BSP_SIU_IRQ_PCI_CRT = BSP_PER_IRQ_LOWEST_OFFSET + 8, + BSP_SIU_IRQ_PCI_SC_RX = BSP_PER_IRQ_LOWEST_OFFSET + 9, + BSP_SIU_IRQ_PCI_SC_TX = BSP_PER_IRQ_LOWEST_OFFSET + 10, + BSP_SIU_IRQ_PSC4 = BSP_PER_IRQ_LOWEST_OFFSET + 11, + BSP_SIU_IRQ_PSC5 = BSP_PER_IRQ_LOWEST_OFFSET + 12, + BSP_SIU_IRQ_SPI_MODF = BSP_PER_IRQ_LOWEST_OFFSET + 13, + BSP_SIU_IRQ_SPI_SPIF = BSP_PER_IRQ_LOWEST_OFFSET + 14, + BSP_SIU_IRQ_I2C1 = BSP_PER_IRQ_LOWEST_OFFSET + 15, + BSP_SIU_IRQ_I2C2 = BSP_PER_IRQ_LOWEST_OFFSET + 16, + BSP_SIU_IRQ_MSCAN1 = BSP_PER_IRQ_LOWEST_OFFSET + 17, + BSP_SIU_IRQ_MSCAN2 = BSP_PER_IRQ_LOWEST_OFFSET + 18, + BSP_SIU_IRQ_IR_RX = BSP_PER_IRQ_LOWEST_OFFSET + 19, + BSP_SIU_IRQ_IR_TX = BSP_PER_IRQ_LOWEST_OFFSET + 20, + BSP_SIU_IRQ_XLB_ARB = BSP_PER_IRQ_LOWEST_OFFSET + 21, + + BSP_SIU_IRQ_SL_TIMER1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 0, /* handler entry only used in case of SMI */ + BSP_SIU_IRQ_IRQ1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 1, + BSP_SIU_IRQ_IRQ2 = BSP_MAIN_IRQ_LOWEST_OFFSET + 2, + BSP_SIU_IRQ_IRQ3 = BSP_MAIN_IRQ_LOWEST_OFFSET + 3, + BSP_SIU_IRQ_LO_INT = BSP_MAIN_IRQ_LOWEST_OFFSET + 4, /* handler entry never used (only placeholder) */ + BSP_SIU_IRQ_RTC_PER = BSP_MAIN_IRQ_LOWEST_OFFSET + 5, + BSP_SIU_IRQ_RTC_STW = BSP_MAIN_IRQ_LOWEST_OFFSET + 6, + BSP_SIU_IRQ_GPIO_STD = BSP_MAIN_IRQ_LOWEST_OFFSET + 7, + BSP_SIU_IRQ_GPIO_WKUP = BSP_MAIN_IRQ_LOWEST_OFFSET + 8, + BSP_SIU_IRQ_TMR0 = BSP_MAIN_IRQ_LOWEST_OFFSET + 9, + BSP_SIU_IRQ_TMR1 = BSP_MAIN_IRQ_LOWEST_OFFSET + 10, + BSP_SIU_IRQ_TMR2 = BSP_MAIN_IRQ_LOWEST_OFFSET + 1, + BSP_SIU_IRQ_TMR3 = BSP_MAIN_IRQ_LOWEST_OFFSET + 12, + BSP_SIU_IRQ_TMR4 = BSP_MAIN_IRQ_LOWEST_OFFSET + 13, + BSP_SIU_IRQ_TMR5 = BSP_MAIN_IRQ_LOWEST_OFFSET + 14, + BSP_SIU_IRQ_TMR6 = BSP_MAIN_IRQ_LOWEST_OFFSET + 15, + BSP_SIU_IRQ_TMR7 = BSP_MAIN_IRQ_LOWEST_OFFSET + 16, + + BSP_SIU_IRQ_IRQ0 = BSP_CRIT_IRQ_LOWEST_OFFSET + 0, + BSP_SIU_IRQ_SL_TIMER0 = BSP_CRIT_IRQ_LOWEST_OFFSET + 1, + BSP_SIU_IRQ_HI_INT = BSP_CRIT_IRQ_LOWEST_OFFSET + 2, /* handler entry never used (only placeholder) */ + BSP_SIU_IRQ_CSS_WKUP = BSP_CRIT_IRQ_LOWEST_OFFSET + 3, + + BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 0, + BSP_SYSMGMT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 1, + BSP_EXT = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + 2 + + }rtems_irq_symbolic_name; + +#define BSP_CRIT_IRQ_PRIO_LEVELS 4 +/*#define BSP_PERIODIC_TIMER BSP_DECREMENTER*/ +#define BSP_PERIODIC_TIMER BSP_SIU_IRQ_TMR6 +/*#define CPM_INTERRUPT*/ + + +/* + * Type definition for RTEMS managed interrupts + */ +typedef unsigned char rtems_irq_prio; +struct __rtems_irq_connect_data__; /* forward declaratiuon */ + +typedef unsigned int rtems_irq_number; +typedef void *rtems_irq_hdl_param; +typedef void (*rtems_irq_hdl) (rtems_irq_hdl_param); +typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*); +typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*); +typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*); + +typedef struct __rtems_irq_connect_data__ { + /* + * IRQ line + */ + rtems_irq_number name; + /* + * handler. See comment on handler properties below in function prototype. + */ + rtems_irq_hdl hdl; + /* + * Handler handle to store private data + */ + rtems_irq_hdl_param handle; + /* + * function for enabling interrupts at device level (ONLY!). + * The BSP code will automatically enable it at i8259s level. + * RATIONALE : anyway such code has to exist in current driver code. + * It is usually called immediately AFTER connecting the interrupt handler. + * RTEMS may well need such a function when restoring normal interrupt + * processing after a debug session. + * + */ + rtems_irq_enable on; + /* + * function for disabling interrupts at device level (ONLY!). + * The code will disable it at i8259s level. RATIONALE : anyway + * such code has to exist for clean shutdown. It is usually called + * BEFORE disconnecting the interrupt. RTEMS may well need such + * a function when disabling normal interrupt processing for + * a debug session. May well be a NOP function. + */ + rtems_irq_disable off; + /* + * function enabling to know what interrupt may currently occur + * if someone manipulates the i8259s interrupt mask without care... + */ + rtems_irq_is_enabled isOn; + +#ifdef BSP_SHARED_HANDLER_SUPPORT + /* + * Set to -1 for vectors forced to have only 1 handler + */ + void *next_handler; +#endif + +} rtems_irq_connect_data; + +typedef struct { + /* + * size of all the table fields (*Tbl) described below. + */ + unsigned int irqNb; + /* + * Default handler used when disconnecting interrupts. + */ + rtems_irq_connect_data defaultEntry; + /* + * Table containing initials/current value. + */ + rtems_irq_connect_data* irqHdlTbl; + /* + * actual value of BSP_PER_IRQ_VECTOR_BASE... + */ + rtems_irq_symbolic_name irqBase; + /* + * software priorities associated with interrupts. + * if irqPrio [i] > intrPrio [j] it means that + * interrupt handler hdl connected for interrupt name i + * will not be interrupted by the handler connected for interrupt j + * The interrupt source will be physically masked at i8259 level. + */ + rtems_irq_prio* irqPrioTbl; +}rtems_irq_global_settings; + + + +/*-------------------------------------------------------------------------+ +| Function Prototypes. ++--------------------------------------------------------------------------*/ +/* + * ------------------------ PPC CPM Mngt Routines ------- + */ + +/* + * function to disable a particular irq. After calling + * this function, even if the device asserts the interrupt line it will + * not be propagated further to the processor + */ +int BSP_irq_disable_at_siu (const rtems_irq_symbolic_name irqLine); +/* + * function to enable a particular irq. After calling + * this function, if the device asserts the interrupt line it will + * be propagated further to the processor + */ +int BSP_irq_enable_at_siu (const rtems_irq_symbolic_name irqLine); +/* + * function to acknoledge a particular irq. After calling + * this function, if a device asserts an enabled interrupt line it will + * be propagated further to the processor. Mainly usefull for people + * writting raw handlers as this is automagically done for rtems managed + * handlers. + */ +int BSP_irq_ack_at_siu (const rtems_irq_symbolic_name irqLine); +/* + * function to check if a particular irq is enabled. After calling + */ +int BSP_irq_enabled_at_siu (const rtems_irq_symbolic_name irqLine); + + + +/* + * ------------------------ RTEMS Single Irq Handler Mngt Routines ---------------- + */ +/* + * function to connect a particular irq handler. This hanlder will NOT be called + * directly as the result of the corresponding interrupt. Instead, a RTEMS + * irq prologue will be called that will : + * + * 1) save the C scratch registers, + * 2) switch to a interrupt stack if the interrupt is not nested, + * 4) modify them to disable the current interrupt at SIU level (and may + * be others depending on software priorities) + * 5) aknowledge the SIU', + * 6) demask the processor, + * 7) call the application handler + * + * As a result the hdl function provided + * + * a) can perfectly be written is C, + * b) may also well directly call the part of the RTEMS API that can be used + * from interrupt level, + * c) It only responsible for handling the jobs that need to be done at + * the device level including (aknowledging/re-enabling the interrupt at device, + * level, getting the data,...) + * + * When returning from the function, the following will be performed by + * the RTEMS irq epilogue : + * + * 1) masks the interrupts again, + * 2) restore the original SIU interrupt masks + * 3) switch back on the orinal stack if needed, + * 4) perform rescheduling when necessary, + * 5) restore the C scratch registers... + * 6) restore initial execution flow + * + */ +int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*); +/* + * function to get the current RTEMS irq handler for ptr->name. It enables to + * define hanlder chain... + */ +int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr); +/* + * function to get disconnect the RTEMS irq handler for ptr->name. + * This function checks that the value given is the current one for safety reason. + * The user can use the previous function to get it. + */ +int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*); + + +void BSP_rtems_irq_mng_init(unsigned cpuId); + +int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config); + +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S new file mode 100644 index 0000000000..efb2465891 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_asm.S @@ -0,0 +1,445 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: irq_asm.S ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the assembler portion of the irq handling | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.5 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.4 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: irq_asm.S */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS assembly code for PowerPC IRQ veneers */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This file contains the assembly code for the */ +/* PowerPC IRQ veneers for RTEMS. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: RTEMS assembly code for PowerPC IRQ veneers */ +/* Module: irq_asm.S */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 04/18/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/* Modified to support the MCP750. */ +/* Modifications Copyright (C) 1999 Eric Valette.valette@crf.canon.fr*/ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include <bsp/vectors.h>*/ +#include "../vectors/vectors.h" +#include <rtems/score/cpuopts.h> /* for PPC_HAS_FPU */ +#include <rtems/score/cpu.h> +#include <rtems/asm.h> +#include "../include/raw_exception.h" + +#define SYNC \ + sync; \ + isync + + .text + .p2align 5 + + PUBLIC_VAR(decrementer_exception_vector_prolog_code) + +SYM (decrementer_exception_vector_prolog_code): + + /* + * let room for exception frame + */ + stwu r1, - (EXCEPTION_FRAME_END)(r1) + stw r4, GPR4_OFFSET(r1) + li r4, ASM_DEC_VECTOR + ba shared_raw_irq_code_entry + + PUBLIC_VAR (decrementer_exception_vector_prolog_code_size) + + decrementer_exception_vector_prolog_code_size = . - decrementer_exception_vector_prolog_code + + PUBLIC_VAR(external_exception_vector_prolog_code) + +SYM (external_exception_vector_prolog_code): + /* + * let room for exception frame + */ + stwu r1, - (EXCEPTION_FRAME_END)(r1) + stw r4, GPR4_OFFSET(r1) + li r4, ASM_EXT_VECTOR + ba shared_raw_irq_code_entry + + PUBLIC_VAR (external_exception_vector_prolog_code_size) + + external_exception_vector_prolog_code_size = . - external_exception_vector_prolog_code + + PUBLIC_VAR(system_management_exception_vector_prolog_code) + +SYM (system_management_exception_vector_prolog_code): + /* + * let room for exception frame + */ + stwu r1, - (EXCEPTION_FRAME_END)(r1) + stw r4, GPR4_OFFSET(r1) + li r4, ASM_SYSMGMT_VECTOR + ba shared_raw_irq_code_entry + + PUBLIC_VAR (system_management_exception_vector_prolog_code_size) + + system_management_exception_vector_prolog_code_size = . - system_management_exception_vector_prolog_code + + PUBLIC_VAR(shared_raw_irq_code_entry) + PUBLIC_VAR(C_dispatch_irq_handler) + + .p2align 5 +SYM (shared_raw_irq_code_entry): + /* + * Entry conditions : + * Registers already saved : R1, R4 + * R1 : points to a location with enough room for the + * interrupt frame + * R4 : vector number + */ + /* + * Save SRR0/SRR1 As soon As possible as it is the minimal needed + * to reenable exception processing + */ + stw r0, GPR0_OFFSET(r1) + stw r2, GPR2_OFFSET(r1) + stw r3, GPR3_OFFSET(r1) + + mfsrr0 r0 + mfsrr1 r2 + mfmsr r3 + + stw r0, SRR0_FRAME_OFFSET(r1) + stw r2, SRR1_FRAME_OFFSET(r1) + + + /* + * Enable data and instruction address translation, exception recovery + * + * also, on CPUs with FP, enable FP so that FP context can be + * saved and restored (using FP instructions) + */ +#if (PPC_HAS_FPU == 0) + ori r3, r3, MSR_RI | MSR_DR/*| MSR_IR*/ +#else + ori r3, r3, MSR_RI | MSR_DR | /*MSR_IR |*/ MSR_FP +#endif + mtmsr r3 + SYNC + + /* + * Push C scratch registers on the current stack. It may + * actually be the thread stack or the interrupt stack. + * Anyway we have to make it in order to be able to call C/C++ + * functions. Depending on the nesting interrupt level, we will + * switch to the right stack later. + */ + stw r5, GPR5_OFFSET(r1) + stw r6, GPR6_OFFSET(r1) + stw r7, GPR7_OFFSET(r1) + stw r8, GPR8_OFFSET(r1) + stw r9, GPR9_OFFSET(r1) + stw r10, GPR10_OFFSET(r1) + stw r11, GPR11_OFFSET(r1) + stw r12, GPR12_OFFSET(r1) + stw r13, GPR13_OFFSET(r1) + + mfcr r5 + mfctr r6 + mfxer r7 + mflr r8 + + stw r5, EXC_CR_OFFSET(r1) + stw r6, EXC_CTR_OFFSET(r1) + stw r7, EXC_XER_OFFSET(r1) + stw r8, EXC_LR_OFFSET(r1) + + /* + * Add some non volatile registers to store information + * that will be used when returning from C handler + */ + stw r14, GPR14_OFFSET(r1) + stw r15, GPR15_OFFSET(r1) + /* + * save current stack pointer location in R14 + */ + addi r14, r1, 0 + /* + * store part of _Thread_Dispatch_disable_level address in R15 + */ + addis r15,0, _Thread_Dispatch_disable_level@ha + /* + * Get current nesting level in R2 + */ +/* mfspr r2, SPRG0 */ + addis r6, 0, _ISR_Nest_level@ha + lwz r2, _ISR_Nest_level@l( r6 ) + + /* + * Check if stack switch is necessary + */ + cmpwi r2,0 + bne nested + mfspr r1, SPRG1 + +nested: + /* + * Start Incrementing nesting level in R2 + */ + addi r2,r2,1 + + addis r6, 0, _ISR_Nest_level@ha + stw r2, _ISR_Nest_level@l( r6 ) + + /* + * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level + */ + lwz r6,_Thread_Dispatch_disable_level@l(r15) + /* + * store new nesting level in SPRG0 + */ +/* mtspr SPRG0, r2 */ + + addi r6, r6, 1 + mfmsr r5 + /* + * store new _Thread_Dispatch_disable_level value + */ + stw r6, _Thread_Dispatch_disable_level@l(r15) + /* + * We are now running on the interrupt stack. External and decrementer + * exceptions are still disabled. I see no purpose trying to optimize + * further assembler code. + */ + /* + * Call C exception handler for decrementer Interrupt frame is passed just + * in case... + */ + addi r3, r14, 0x8 + bl C_dispatch_irq_handler /* C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4) */ + /* + * start decrementing nesting level. Note : do not test result against 0 + * value as an easy exit condition because if interrupt nesting level > 1 + * then _Thread_Dispatch_disable_level > 1 + */ +/* mfspr r2, SPRG0 */ + + addis r6, 0, _ISR_Nest_level@ha + lwz r2, _ISR_Nest_level@l( r6 ) + + /* + * start decrementing _Thread_Dispatch_disable_level + */ + lwz r3,_Thread_Dispatch_disable_level@l(r15) + addi r2, r2, -1 /* Continue decrementing nesting level */ + addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */ + + stw r2, _ISR_Nest_level@l( r6 ) +/* mtspr SPRG0, r2 */ /* End decrementing nesting level */ + + stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */ + cmpwi r3, 0 + /* + * switch back to original stack (done here just optimize registers + * contention. Could have been done before...) + */ + addi r1, r14, 0 + bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */ + /* + * Here we are running again on the thread system stack. + * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0. + * Interrupt are still disabled. Time to check if scheduler request to + * do something with the current thread... + */ + addis r4, 0, _Context_Switch_necessary@ha + lwz r5, _Context_Switch_necessary@l(r4) + cmpwi r5, 0 + bne switch + + addis r6, 0, _ISR_Signals_to_thread_executing@ha + lwz r7, _ISR_Signals_to_thread_executing@l(r6) + cmpwi r7, 0 + li r8, 0 + beq easy_exit + stw r8, _ISR_Signals_to_thread_executing@l(r6) + /* + * going to call _ThreadProcessSignalsFromIrq + * Push a complete exception like frame... + */ + stmw r16, GPR16_OFFSET(r1) + addi r3, r1, 0x8 + /* + * compute SP at exception entry + */ + addi r2, r1, EXCEPTION_FRAME_END + /* + * store it at the right place + */ + stw r2, GPR1_OFFSET(r1) + /* + * Call High Level signal handling code + */ + bl _ThreadProcessSignalsFromIrq + + + /* + * start restoring exception like frame + */ + lwz r31, EXC_CTR_OFFSET(r1) + lwz r30, EXC_XER_OFFSET(r1) + lwz r29, EXC_CR_OFFSET(r1) + lwz r28, EXC_LR_OFFSET(r1) + + mtctr r31 + mtxer r30 + mtcr r29 + mtlr r28 + + + lmw r4, GPR4_OFFSET(r1) + + + lwz r2, GPR2_OFFSET(r1) + lwz r0, GPR0_OFFSET(r1) + + /* + * Disable data and instruction translation. Make path non recoverable... + */ + mfmsr r3 + xori r3, r3, MSR_RI | MSR_DR/*| MSR_IR */ + mtmsr r3 + SYNC + /* + * Restore rfi related settings + */ + + lwz r3, SRR1_FRAME_OFFSET(r1) + mtsrr1 r3 + lwz r3, SRR0_FRAME_OFFSET(r1) + mtsrr0 r3 + + lwz r3, GPR3_OFFSET(r1) + addi r1,r1, EXCEPTION_FRAME_END + SYNC + rfi + +switch: + bl SYM (_Thread_Dispatch) + +easy_exit: + /* + * start restoring interrupt frame + */ + lwz r3, EXC_CTR_OFFSET(r1) + lwz r4, EXC_XER_OFFSET(r1) + lwz r5, EXC_CR_OFFSET(r1) + lwz r6, EXC_LR_OFFSET(r1) + + mtctr r3 + mtxer r4 + mtcr r5 + mtlr r6 + + lwz r15, GPR15_OFFSET(r1) + lwz r14, GPR14_OFFSET(r1) + lwz r13, GPR13_OFFSET(r1) + lwz r12, GPR12_OFFSET(r1) + lwz r11, GPR11_OFFSET(r1) + lwz r10, GPR10_OFFSET(r1) + lwz r9, GPR9_OFFSET(r1) + lwz r8, GPR8_OFFSET(r1) + lwz r7, GPR7_OFFSET(r1) + lwz r6, GPR6_OFFSET(r1) + lwz r5, GPR5_OFFSET(r1) + + /* + * Disable nested exception processing, data and instruction + * translation. + */ + mfmsr r3 + xori r3, r3, MSR_RI | MSR_DR/*| MSR_IR */ + mtmsr r3 + SYNC + + /* + * Restore rfi related settings + */ + + lwz r4, SRR1_FRAME_OFFSET(r1) + lwz r2, SRR0_FRAME_OFFSET(r1) + lwz r3, GPR3_OFFSET(r1) + lwz r0, GPR0_OFFSET(r1) + + mtsrr1 r4 + mtsrr0 r2 + lwz r4, GPR4_OFFSET(r1) + lwz r2, GPR2_OFFSET(r1) + addi r1,r1, EXCEPTION_FRAME_END + SYNC + rfi + diff --git a/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c new file mode 100644 index 0000000000..87f57626ac --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/irq/irq_init.c @@ -0,0 +1,327 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: irq_init.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the IRQ controller/system initialization | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.6 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.5 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.4 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: irq_init.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 CPU interrupt initialization */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This file contains the implementation of rtems */ +/* initialization related to interrupt handling. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: MBX8xx CPU interrupt initialization */ +/* Module: irq_init.c */ +/* Project: RTEMS 4.6.0pre1 / MBX8xx BSP */ +/* Version 1.1 */ +/* Date: 04/06/2001 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* CopyRight (C) 2001 valette@crf.canon.fr */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include <rtems.h> +/*#include "../irq/irq.h"*/ +#include "../irq/irq.h" +#include <rtems/bspIo.h> +#include "../include/raw_exception.h" +#include "../include/mpc5200.h" + +extern unsigned int external_exception_vector_prolog_code_size; +extern void external_exception_vector_prolog_code(); +extern unsigned int decrementer_exception_vector_prolog_code_size; +extern void decrementer_exception_vector_prolog_code(); +extern unsigned int system_management_exception_vector_prolog_code_size; +extern void system_management_exception_vector_prolog_code(); + +extern void BSP_panic(char *s); +extern void _BSP_Fatal_error(unsigned int v); +/* +volatile unsigned int ppc_cached_irq_mask; +*/ + +/* + * default on/off function + */ +static void nop_func(){} +/* + * default isOn function + */ +static int not_connected() {return 0;} +/* + * default possible isOn function + */ +static int connected() {return 1;} + +static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER]; +static rtems_irq_global_settings initial_config; + +static rtems_irq_connect_data defaultIrq = + { + /* vectorIdex, hdl , param, on , off , isOn */ + 0, nop_func, NULL , nop_func, nop_func, not_connected }; + +static rtems_irq_prio irqPrioTable[BSP_SIU_IRQ_NUMBER] = + { +/* per. int. priorities (0-7) / 4bit coding / msb is HI/LO selection */ +/* msb = 0 -> non-critical per. int. is routed to main int. (LO_int) */ +/* msb = 1 -> critical per. int. is routed to critical int. (HI_int) */ + 0xF, 0, 0, 0, /* smart_comm (do not change!), psc1, psc2, psc3 */ + 0, 0, 0, 0, /* irda, eth, usb, ata */ + 0, 0, 0, 0, /* pci_ctrl, pci_sc_rx, pci_sc_tx, res */ + 0, 0, 0, 0, /* res, spi_modf, spi_spif, i2c1 */ + 0, 0, 0, 0, /* i2c, can1, can2, ir_rx */ + 0, 0, /* ir_rx, xlb_arb */ +/* main interrupt priorities (0-7) / 4bit coding / msb is INT/SMI selection */ +/* msb = 0 -> main int. is routed to processor INT (low vector base 0x500 ) */ +/* msb = 1 -> main int. is routed to processor SMI (low vector base 0x1400 ) */ + 0, 0, /* slice_tim2, irq1 */ + 0, 0, 0, 0, /* irq2, irq3, lo_int, rtc_pint */ + 0, 0, 0, 0, /* rtc_sint, gpio_std, gpio_wkup, tmr0 */ + 0, 0, 0, 0, /* tmr1, tmr2, tmr3, tmr4 */ + 0, 0, 0, /* tmr5, tmr6, tmr7 */ + /* critical interrupt priorities (0-3) / 2bit coding / no special purpose of msb */ + 0, /* irq0 */ + 0, 0, 0 /* slice_tim1, hi_int, ccs_wkup */ + }; + +uint32_t irqMaskTable[BSP_PER_IRQ_NUMBER + BSP_MAIN_IRQ_NUMBER]; + + +/* + * setup irqMaskTable to support a priorized/nested interrupt environment + */ +void setup_irqMaskTable(void) + { + rtems_irq_prio prio = 0; + uint32_t i = 0, j = 0, mask = 0; + + /* set up the priority dependent masks for peripheral interrupts */ + for(i = BSP_PER_IRQ_LOWEST_OFFSET; i <= BSP_PER_IRQ_MAX_OFFSET; i++) + { + + prio = irqPrioTable[i]; + mask = 0; + + for(j = BSP_PER_IRQ_LOWEST_OFFSET; j <= BSP_PER_IRQ_MAX_OFFSET; j++) + { + + if(prio > irqPrioTable[j]) + mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET)); + + if((prio == irqPrioTable[j]) && (j >= i)) + mask |= (1 << (31 - j + BSP_PER_IRQ_LOWEST_OFFSET)); + + } + + irqMaskTable[i] = mask; + + } + + + /* set up the priority dependent masks for main interrupts */ + for(i = BSP_MAIN_IRQ_LOWEST_OFFSET; i <= BSP_MAIN_IRQ_MAX_OFFSET; i++) + { + + prio = irqPrioTable[i]; + mask = 0; + + for(j = BSP_MAIN_IRQ_LOWEST_OFFSET; j <= BSP_MAIN_IRQ_MAX_OFFSET; j++) + { + + if(prio > irqPrioTable[j]) + mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET)); + + if((prio == irqPrioTable[j]) && (j >= i)) + mask |= (1 << (16 - j + BSP_MAIN_IRQ_LOWEST_OFFSET)); + + } + + irqMaskTable[i] = mask; + + } + + } + + +/* + * Initialize MPC5x00 SIU interrupt management + */ +void BSP_SIU_irq_init(void) + { + + /* disable all peripheral interrupts */ + mpc5200.per_mask = 0xFFFFFC00; + + /* peripheral interrupt priorities according to reset value */ + mpc5200.per_pri_1 = 0xF0000000; + mpc5200.per_pri_2 = 0x00000000; + mpc5200.per_pri_3 = 0x00000000; + + /* disable external interrupts IRQ0-4 / critical interrupts are routed to core_int */ + mpc5200.ext_en_type = 0x0F000001; + + /* disable main interrupts / crit. int. priorities according to reset values */ + mpc5200.crit_pri_main_mask = 0x0001FFFF; + + /* main priorities according to reset value */ + mpc5200.main_pri_1 = 0; + mpc5200.main_pri_2 = 0; + + /* reset all status indicators */ + mpc5200.csa = 0x0001FFFF; + mpc5200.msa = 0x0001FFFF; + mpc5200.psa = 0x003FFFFF; + mpc5200.psa_be = 0x03000000; + + setup_irqMaskTable(); + + } + +void BSP_rtems_irq_mng_init(unsigned cpuId) + { + rtems_raw_except_connect_data vectorDesc; + int i; + + BSP_SIU_irq_init(); + /* + * Initialize Rtems management interrupt table + */ + /* + * re-init the rtemsIrq table + */ + for (i = 0; i < BSP_IRQ_NUMBER; i++) + { + rtemsIrq[i] = defaultIrq; + rtemsIrq[i].name = i; + } + /* + * Init initial Interrupt management config + */ + initial_config.irqNb = BSP_IRQ_NUMBER; + initial_config.defaultEntry = defaultIrq; + initial_config.irqHdlTbl = rtemsIrq; + initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE; + initial_config.irqPrioTbl = irqPrioTable; + + if (!BSP_rtems_irq_mngt_set(&initial_config)) + { + /* + * put something here that will show the failure... + */ + BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n"); + } + + /* + * We must connect the raw irq handler for the two + * expected interrupt sources : decrementer and external interrupts. + */ + vectorDesc.exceptIndex = ASM_DEC_VECTOR; + vectorDesc.hdl.vector = ASM_DEC_VECTOR; + vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) &decrementer_exception_vector_prolog_code_size; + vectorDesc.on = nop_func; + vectorDesc.off = nop_func; + vectorDesc.isOn = connected; + + if (!mpc60x_set_exception (&vectorDesc)) + { + BSP_panic("Unable to initialize RTEMS decrementer raw exception\n"); + } + + vectorDesc.exceptIndex = ASM_EXT_VECTOR; + vectorDesc.hdl.vector = ASM_EXT_VECTOR; + vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) &external_exception_vector_prolog_code_size; + + if (!mpc60x_set_exception (&vectorDesc)) + { + BSP_panic("Unable to initialize RTEMS external raw exception\n"); + } + + vectorDesc.exceptIndex = ASM_SYSMGMT_VECTOR; + vectorDesc.hdl.vector = ASM_SYSMGMT_VECTOR; + vectorDesc.hdl.raw_hdl = system_management_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) &system_management_exception_vector_prolog_code_size; + + if (!mpc60x_set_exception (&vectorDesc)) + { + BSP_panic("Unable to initialize RTEMS system management raw exception\n"); + } + +} + diff --git a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c new file mode 100644 index 0000000000..bc9eeb529f --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c @@ -0,0 +1,1376 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the MSCAN driver | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.31 2005/12/11 23:00:27 peter +|* initialization according to bitrate and max. no of tq per can bit +|* +|* Revision 1.30 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.29 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.28 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ + +#include <stdio.h> +#include <stdlib.h> +#include <rtems.h> +#include <rtems/error.h> +#include <rtems/libio.h> +#include <string.h> +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include "../mscan/mscan.h" + +/* #define MSCAN_LOOPBACK */ + +struct mpc5200_rx_cntrl mpc5200_mscan_rx_cntrl[MPC5200_CAN_NO]; +static struct mscan_channel_info chan_info[MPC5200_CAN_NO]; + +/* + * MPC5x00 MSCAN interrupt handler + */ +static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle) + { + rtems_status_code status; + mscan_handle *mscan_hdl = (mscan_handle *)handle; + struct mscan_channel_info *chan = &chan_info[mscan_hdl->mscan_channel]; + struct can_message rx_mess, *rx_mess_ptr; + volatile struct mpc5200_mscan *mscan = chan->regs; + + /* + handle tx interrupts + */ + + /* check and disable tx interrupt for message buffer 0 */ + if(mscan->tier & MSCAN_TX_BUFF0) + mscan->tier &= ~(MSCAN_TX_BUFF0); + + /* check and disable tx interrupt for message buffer 1 */ + if(mscan->tier & MSCAN_TX_BUFF1) + mscan->tier &= ~(MSCAN_TX_BUFF1); + + /* check and disable tx interrupt for message buffer 2 */ + if(mscan->tier & MSCAN_TX_BUFF2) + mscan->tier &= ~(MSCAN_TX_BUFF2); + + /* + handle rx interrupts + */ + + /* check for rx interrupt source */ + if(mscan->rier & RIER_RXFIE) + { + + /* can messages received ? */ + while(mscan->rflg & RFLG_RXF) + { + + if(mscan_hdl->toucan_callback == NULL) + { + + /* select temporary rx buffer */ + rx_mess_ptr = &rx_mess; + + } + else + { + + /* check the rx fliter-match indicators (16-bit filter mode) */ + /* in case of more than one hit, lower hit has priority */ + switch((mscan->idac) & 0x7) + { + + case 0: + rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[0]); + break; + + case 1: + rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[1]); + break; + + case 2: + rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[2]); + break; + + case 3: + rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[3]); + break; + + /* this case should never happen */ + default: + /* reset the rx indication flag */ + mscan->rflg |= RFLG_RXF; + + return; + break; + } + + } + + /* get rx ID */ + rx_mess_ptr->mess_id = GET_IDR0(mscan->rxidr0) | GET_IDR1(mscan->rxidr1); + + /* get rx len */ + rx_mess_ptr->mess_len = ((mscan->rxdlr) & 0x0F); + + /* get time stamp */ + rx_mess_ptr->mess_time_stamp = ((mscan->rxtimh << 8) | (mscan->rxtiml)); + + /* get the data */ + switch(rx_mess_ptr->mess_len) + { + + case 8: + rx_mess_ptr->mess_data[7] = mscan->rxdsr7; + case 7: + rx_mess_ptr->mess_data[6] = mscan->rxdsr6; + case 6: + rx_mess_ptr->mess_data[5] = mscan->rxdsr5; + case 5: + rx_mess_ptr->mess_data[4] = mscan->rxdsr4; + case 4: + rx_mess_ptr->mess_data[3] = mscan->rxdsr3; + case 3: + rx_mess_ptr->mess_data[2] = mscan->rxdsr2; + case 2: + rx_mess_ptr->mess_data[1] = mscan->rxdsr1; + case 1: + rx_mess_ptr->mess_data[0] = mscan->rxdsr0; + case 0: + default: + break; + + } + + if(mscan_hdl->toucan_callback == NULL) + { + + if((status = rtems_message_queue_send(chan->rx_qid, (void *)rx_mess_ptr, sizeof(struct can_message))) != RTEMS_SUCCESSFUL) + { + + chan->int_rx_err++; + + } + + } + else + { + + mscan_hdl->toucan_callback((int16_t)(((mscan->idac) & 0x7) + 3)); + + } + + /* reset the rx indication flag */ + mscan->rflg |= RFLG_RXF; + + } /* end of while(mscan->rflg & RFLG_RXF) */ + + } + + /* status change detected */ + if(mscan->rflg & RFLG_CSCIF) + { + + mscan->rflg |= RFLG_CSCIF; + + if(mscan_hdl->toucan_callback != NULL) + { + + mscan_hdl->toucan_callback((int16_t)(-1)); + + } + + } + + } + + +/* + * Disable MSCAN ints. + */ +void mpc5200_mscan_int_disable(volatile struct mpc5200_mscan *mscan) + { + + /* RX Interrupt Enable on MSCAN_A/_B -----------------------------*/ + /* [07]:WUPIE 0 : WakeUp interrupt disabled */ + /* [06]:CSCIE 0 : Status Change interrupt disabled */ + /* [05]:RSTATE1 0 : Recv. Status Change int. ,Bit 1 */ + /* [04]:RSTATE0 0 : Recv. Status Change int. ,Bit 0 */ + /* -> 00 rx status change int. disabled */ + /* [03]:TSTAT1 0 : Transmit. Status Change int. , Bit 1 */ + /* [02]:TSTAT0 0 : Transmit. Status Change int. , Bit 0 */ + /* -> 00 tx status change int. disabled */ + /* [01]:OVRIE 0 : Overrun Interrupt is disabled */ + /* [00]:RXFIE 0 : Recv. Full interrupt is disabled */ + mscan->rier &= ~(RIER_CSCIE | RIER_RXFIE); + + /* TX Interrupt Enable on MSCAN_A/_B -----------------------------*/ + /* [07]:res. 0 : reserved */ + /* [06]:res. 0 : reserved */ + /* [05]:res. 0 : reserved */ + /* [04]:res. 0 : reserved */ + /* [03]:res. 0 : reserved */ + /* [02]:TSEG12 0 : TX2message buffer int. is disabled */ + /* [01]:TSEG11 0 : TX1 message buffer int. is disabled */ + /* [00]:TSEG10 0 : TX0 message buffer int. is disabled */ + mscan->tier &= ~(TIER_TXEI2 | TIER_TXEI1 | TIER_TXEI0); + + return; + + } + + +/* + * Enable MSCAN ints. + */ +void mpc5200_mscan_int_enable(volatile struct mpc5200_mscan *mscan) + { + + /* RX Interrupt Enable on MSCAN_A/_B -----------------------------*/ + /* [07]:WUPIE 0 : WakeUp interrupt disabled */ + /* [06]:CSCIE 1 : Status Change interrupt enabled */ + /* [05]:RSTATE1 0 : Recv. Status Change int. ,Bit 1 */ + /* [04]:RSTATE0 1 : Recv. Status Change int. ,Bit 0 */ + /* -> 01 BusOff status changes enabled */ + /* [03]:TSTAT1 0 : Transmit. Status Change int. , Bit 1 */ + /* [02]:TSTAT0 1 : Transmit. Status Change int. , Bit 0 */ + /* -> 01 BusOff status changes enabled */ + /* [01]:OVRIE 0 : Overrun Interrupt is disabled */ + /* [00]:RXFIE 1 : Recv. Full interrupt is enabled */ + mscan->rier |= (RIER_CSCIE | RIER_RXFIE | RIER_RSTAT(1) | RIER_TSTAT(1)); + + return; + + } + +/* + * Unmask MPC5x00 MSCAN_A interrupts + */ +void mpc5200_mscan_a_on(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_A])->regs; + + mpc5200_mscan_int_enable(mscan); + + return; + + } + + +/* + * Mask MPC5x00 MSCAN_A interrupts + */ +void mpc5200_mscan_a_off(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_A])->regs; + + mpc5200_mscan_int_disable(mscan); + + return; + + } + + +/* + * Get MSCAN_A interrupt mask setting + */ +int mpc5200_mscan_a_isOn(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_A])->regs; + + if((mscan->rier & RIER_CSCIE) && (mscan->rier & RIER_RXFIE)) + return RTEMS_SUCCESSFUL; + else + return RTEMS_UNSATISFIED; + + return RTEMS_SUCCESSFUL; + + } + + +/* + * Unmask MPC5x00 MSCAN_B interrupts + */ +void mpc5200_mscan_b_on(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_B])->regs; + + mpc5200_mscan_int_enable(mscan); + + return; + + } + + +/* + * Mask MPC5x00 MSCAN_B interrupts + */ +void mpc5200_mscan_b_off(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_B])->regs; + + mpc5200_mscan_int_disable(mscan); + + return; + + } + + +/* + * Get MSCAN_B interrupt mask setting + */ +int mpc5200_mscan_b_isOn(const rtems_irq_connect_data* ptr) + { + volatile struct mpc5200_mscan *mscan = (&chan_info[MSCAN_B])->regs; + + if((mscan->rier & RIER_CSCIE) && (mscan->rier & RIER_RXFIE)) + return RTEMS_SUCCESSFUL; + else + return RTEMS_UNSATISFIED; + + return RTEMS_SUCCESSFUL; + + } + +static mscan_handle mscan_a_handle = + { + MSCAN_A, + NULL + }; + + +static mscan_handle mscan_b_handle = + { + MSCAN_B, + NULL + }; + +/* + * MPC5x00 MSCAN_A/_B irq data + */ +static rtems_irq_connect_data mpc5200_mscan_irq_data[MPC5200_CAN_NO] = + {{ + BSP_SIU_IRQ_MSCAN1, + (rtems_irq_hdl) mpc5200_mscan_interrupt_handler, + (rtems_irq_hdl_param) &mscan_a_handle, + (rtems_irq_enable) mpc5200_mscan_a_on, + (rtems_irq_disable) mpc5200_mscan_a_off, + (rtems_irq_is_enabled) mpc5200_mscan_a_isOn + }, + { + BSP_SIU_IRQ_MSCAN2, + (rtems_irq_hdl) mpc5200_mscan_interrupt_handler, + (rtems_irq_hdl_param) &mscan_b_handle, + (rtems_irq_enable) mpc5200_mscan_b_on, + (rtems_irq_disable) mpc5200_mscan_b_off, + (rtems_irq_is_enabled) mpc5200_mscan_b_isOn + }}; + + +/* + * Enter MSCAN sleep mode + */ +void mpc5200_mscan_enter_sleep_mode(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 1 : WakeUp Enabled */ + /* [01]:SLPRQ 0->1 : Sleep Mode Request */ + /* [00]:INITRQ 0 : No init. Mode Request */ + /* select sleep mode */ + mscan->ctl0 |= (CTL0_SLPRQ); + + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0 : MSCAN Module is disabled */ + /* [06]:CLKSRC 1 : Clock Source -> IPB-Clock (33 MHz) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 0->1 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 0 : Init. Mode Acknowledge (rd. only) */ + /* wait for sleep mode acknowledge */ + while(!(mscan->ctl1 & CTL1_SLPAK)); + + return; + + } + + +/* + * Exit MSCAN sleep mode + */ +void mpc5200_mscan_exit_sleep_mode(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 1 : WakeUp Enabled */ + /* [01]:SLPRQ 0->1 : Sleep Mode Request */ + /* [00]:INITRQ 0 : No init. Mode Request */ + /* select sleep mode */ + mscan->ctl0 &= ~(CTL0_SLPRQ); + + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0 : MSCAN Module is disabled */ + /* [06]:CLKSRC 1 : Clock Source -> IPB-Clock (33 MHz) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 0->1 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 0 : Init. Mode Acknowledge (rd. only) */ + /* wait for sleep mode acknowledge */ + while((mscan->ctl1 & CTL1_SLPAK)); + + return; + + } + + +/* + * Enter MSCAN init mode and disconnect from bus + */ +void mpc5200_mscan_enter_init_mode(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 0 : WakeUp disabled */ + /* [01]:SLPRQ 0 : No Sleep Mode Request */ + /* [00]:INITRQ 0->1 : Init. Mode Request */ + /* select init mode */ + mscan->ctl0 |= (CTL0_INITRQ); + + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0 : MSCAN Module is disabled */ + /* [06]:CLKSRC 1 : Clock Source -> IPB-Clock (33 MHz) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 0 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 0->1 : Init. Mode Acknowledge (rd. only) */ + /* wait for init mode acknowledge */ + while(!(mscan->ctl1 & CTL1_INITAK)); + + return; + + } + + +/* + * Exit MSCAN init mode + */ +void mpc5200_mscan_exit_init_mode(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 0 : WakeUp Disabled */ + /* [01]:SLPRQ 0 : No Sleep Mode Request */ + /* [00]:INITRQ 1->0 : Init. Mode Request */ + /* select normal mode */ + mscan->ctl0 &= ~(CTL0_INITRQ); + + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0 : MSCAN Module is disabled */ + /* [06]:CLKSRC 1 : Clock Source -> IPB-Clock (33 MHz) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 0 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 1->0 : Init. Mode Acknowledge (rd. only) */ + /* wait for normal mode acknowledge */ + while(mscan->ctl1 & CTL1_INITAK); + + return; + + } + + +/* + * MPC5x00 MSCAN wait for sync. with CAN bus + */ +void mpc5200_mscan_wait_sync(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0->1 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 0 : WakeUp Disabled */ + /* [01]:SLPRQ 0 : No Sleep Mode Request */ + /* [00]:INITRQ 0 : No init. Mode Request */ + /* wait for MSCAN A_/_B bus synch. */ + while(!((mscan->ctl0) & CTL0_SYNCH)); + + return; + + } + + +/* + * MPC5x00 MSCAN set up the bit timing + */ +void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *mscan) +{ + uint32_t prescale_val = 0; + uint32_t tq_num; + uint32_t sync_seg,tseg1,tseg2; + + if(IPB_CLOCK%(CAN_BIT_RATE * CAN_MAX_NO_OF_TQ)) + prescale_val = (IPB_CLOCK/(CAN_BIT_RATE * (CAN_MAX_NO_OF_TQ*2/3))) + 1; + else + prescale_val = IPB_CLOCK/(CAN_BIT_RATE* (CAN_MAX_NO_OF_TQ*2/3)); + + tq_num = ((IPB_CLOCK/prescale_val)+CAN_BIT_RATE/2)/CAN_BIT_RATE; + /* + * XXX: make this table controlled according to MPC5200UM/Rev.3,Table 19-34 + */ + sync_seg = 2; + tseg2 = (tq_num-sync_seg)/6; + tseg1 = tq_num - sync_seg - tseg2; + + /* Bus Timing Register 0 MSCAN_A/_B ------------------------------*/ + /* [07]:SJW1 1 : Synchronization jump width, Bit1 */ + /* [06]:SJW0 0 : Synchronization jump width, Bit0 */ + /* SJW = 2 -> 3 Tq clock cycles */ + /* [05]:BRP5 0 : Baud Rate Prescaler, Bit 5 */ + /* [04]:BRP4 0 : Baud Rate Prescaler, Bit 4 */ + /* [03]:BRP3 0 : Baud Rate Prescaler, Bit 3 */ + /* [02]:BRP2 1 : Baud Rate Prescaler, Bit 2 */ + /* [01]:BRP1 0 : Baud Rate Prescaler, Bit 1 */ + /* [00]:BRP0 1 : Baud Rate Prescaler, Bit 0 */ + mscan->btr0 |= (BTR0_SJW(sync_seg-1) | BTR0_BRP(prescale_val - 1)); + + /* Bus Timing Register 1 MSCAN_A/_B ------------------------------*/ + /* [07]:SAMP 0 : One Sample per bit */ + /* [06]:TSEG22 0 : Time Segment 2, Bit 2 */ + /* [05]:TSEG21 1 : Time Segment 2, Bit 1 */ + /* [04]:TSEG20 0 : Time Segment 2, Bit 0 */ + /* -> PHASE_SEG2 = 3 Tq */ + /* [03]:TSEG13 0 : Time Segment 1, Bit 3 */ + /* [02]:TSEG12 1 : Time Segment 1, Bit 2 */ + /* [01]:TSEG11 1 : Time Segment 1, Bit 1 */ + /* [00]:TSEG10 0 : Time Segment 1, Bit 0 */ + mscan->btr1 &= ~(BTR1_SAMP); + mscan->btr1 |= (BTR1_TSEG_22_20(tseg2-1) | BTR1_TSEG_13_10(tseg1-1)); + + return; + + } + + +/* + * MPC5x00 MSCAN perform settings in init mode + */ +void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *mscan) + { + mpc5200_mscan_perform_bit_time_settings(mscan); + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0 : MSCAN Module is disabled */ + /* [06]:CLKSRC 0 : Clock Source -> IPB_CLOCK (bsp.h) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 1->0 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 0 : Init. Mode Acknowledge (rd. only) */ + /* Set CLK source, disable loopback & listen-only mode */ +#ifndef MSCAN_LOOPBACK + mscan->ctl1 &= ~(CTL1_LISTEN | CTL1_LOOPB | CTL1_CLKSRC); +#else + mscan->ctl1 &= ~(CTL1_LISTEN | CTL1_CLKSRC); + mscan->ctl1 |= (CTL1_LOOPB); +#endif + + /* IPB clock -> IPB_CLOCK (bsp.h) */ + /* bitrate -> CAN_BIT_RATE (mscan.h) */ + /* Max. no of Tq -> CAN_MAX_NO_OF_TQ (mscan.h) */ + /* Prescaler value -> prescale_val = ROUND_UP(IPB_CLOCK/(CAN_BIT_RATE * CAN_MAX_NO_OF_TQ)) */ + /* SYNC_SEG -> 1 tq */ + /* time segment 1 -> 16 tq (PROP_SEG+PHASE_SEG), CAN_MAX_NO_OF_TQ_TSEG1 = 15 (mscan.h) */ + /* time segment 2 -> 8 tq (PHASE_SEG2) , CAN_MAX_NO_OF_TQ_TSEG2 = 7 (mscan.h) */ + /* SJW -> 3 (fixed 0...3) , CAN_MAX_NO_OF_TQ_SJW = 2 (mscan.h) */ + + /* ID Acceptance Control MSCAN_A/_B ------------------------------*/ + /* [07]:res. 0 : reserved */ + /* [06]:res. 0 : reserved */ + /* [05]:IDAM1 0 : ID acceptance control, Bit1 */ + /* [04]:IDAM0 1 : ID acceptance control, Bit0 */ + /* -> filter 16 bit mode */ + /* [03]:res. 0 : reserved */ + /* [02]:IDHIT2 0 : ID acceptance hit indication, Bit 2 */ + /* [01]:IDHIT1 0 : ID acceptance hit indication, Bit 1 */ + /* [00]:IDHIT0 0 : ID acceptance hit indication, Bit 0 */ + mscan->idac &= ~(IDAC_IDAM1); + mscan->idac |= (IDAC_IDAM0); + + /* initialize rx filter masks: only accept exact matches */ + mscan->idmr0 = 0x00; + mscan->idmr1 = 0x00; + mscan->idmr2 = 0x00; + mscan->idmr3 = 0x00; + mscan->idmr4 = 0x00; + mscan->idmr5 = 0x00; + mscan->idmr6 = 0x00; + mscan->idmr7 = 0x00; + + /* initialize rx filters: set to illegal values, so no matches occure */ + mscan->idar0 = 0xff; + mscan->idar1 = 0xff; + mscan->idar2 = 0xff; + mscan->idar3 = 0xff; + mscan->idar4 = 0xff; + mscan->idar5 = 0xff; + mscan->idar6 = 0xff; + mscan->idar7 = 0xff; + + /* Control Register 1 --------------------------------------------*/ + /* [07]:CANE 0->1 : MSCAN Module is enabled */ + /* [06]:CLKSRC 1 : Clock Source -> IPB_CLOCK (bsp.h) */ + /* [05]:LOOPB 0 : No Loopback */ + /* [04]:LISTEN 0 : Normal Operation */ + /* [03]:res 0 : reserved */ + /* [02]:WUPM 0 : No protect. from spurious WakeUp */ + /* [01]:SLPAK 0 : Sleep Mode Acknowledge (rd. only) */ + /* [00]:INITAK 0 : Init. Mode Acknowledge (rd. only) */ + /* enable MSCAN A_/_B */ + mscan->ctl1 |= (CTL1_CANE); + + return; + + } + + +/* + * MPC5x00 MSCAN perform settings in normal mode + */ +void mpc5200_mscan_perform_normal_mode_settings(volatile struct mpc5200_mscan *mscan) + { + + /* Control Register 0 --------------------------------------------*/ + /* [07]:RXFRM 0 : Recv. Frame, Flag Bit (rd.&clear only) */ + /* [06]:RXACT 0 : Recv. Active, Status Bit (rd. only) */ + /* [05]:CSWAI 0 : CAN Stops in Wait Mode */ + /* [04]:SYNCH 0 : Synchronized, Status Bit (rd. only) */ + /* [03]:TIME 1 : Generate Timestamps */ + /* [02]:WUPE 0 : WakeUp Disabled */ + /* [01]:SLPRQ 0 : No Sleep Mode Request */ + /* [00]:INITRQ 0 : No init. Mode Request */ + /* Disable wait mode, enable timestamps */ + mscan->ctl0 &= ~(CTL0_CSWAI); + mscan->ctl0 |= (CTL0_TIME); + + return; + + } + +rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number minor, uint8_t mode) + { + struct mscan_channel_info *chan = NULL; + volatile struct mpc5200_mscan *mscan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + mscan = chan->regs; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + if(chan->mode == mode) + return RTEMS_SUCCESSFUL; + + switch(mode) + { + + case MSCAN_NORMAL_MODE: + /* if not already set enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + + if((chan->mode) == MSCAN_INITIALIZED_MODE) + /* perform initialization which has to be done in init mode */ + mpc5200_mscan_perform_init_mode_settings(mscan); + else + /* exit sleep mode */ + mpc5200_mscan_exit_sleep_mode(mscan); + + /* exit init mode */ + mpc5200_mscan_exit_init_mode(mscan); + /* enable ints. */ + mpc5200_mscan_int_enable(mscan); + /* wait for bus sync. */ + mpc5200_mscan_wait_sync(mscan); + return RTEMS_SUCCESSFUL; + break; + + case MSCAN_SLEEP_MODE: + /* enable ints. */ + mpc5200_mscan_int_disable(mscan); + /* if not already set enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + /* exit sleep mode */ + mpc5200_mscan_enter_sleep_mode(mscan); + /* exit init mode */ + mpc5200_mscan_exit_init_mode(mscan); + return RTEMS_SUCCESSFUL; + break; + + default: + return RTEMS_UNSATISFIED; + break; + + } + + /* set new channel mode */ + chan->mode = mode; + + return RTEMS_SUCCESSFUL; + + } + + +/* + * initialization of channel info. + */ +rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtems_device_minor_number minor) + { + rtems_status_code status; + struct mscan_channel_info *chan = &chan_info[minor]; + + /* set registers according to MSCAN channel information */ + switch(minor) + { + + case MSCAN_A: + chan->rx_qname = rtems_build_name ('C', 'N', 'A', 'Q'); + + /* register RTEMS device names for MSCAN A */ + if((status = rtems_io_register_name (MSCAN_A_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL) + return status; + + break; + + case MSCAN_B: + chan->rx_qname = rtems_build_name ('C', 'N', 'B', 'Q'); + + /* register RTEMS device names for MSCAN B */ + if((status = rtems_io_register_name (MSCAN_B_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL) + return status; + + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + /* create RTEMS rx message queue for MSCAN A */ + if((status = rtems_message_queue_create(chan->rx_qname, + (uint32_t) NO_OF_MSCAN_A_RX_BUFF, + (uint32_t) MSCAN_MESSAGE_SIZE(sizeof(struct can_message)), + (rtems_attribute) RTEMS_LOCAL | RTEMS_FIFO, + (rtems_id *)&(chan->rx_qid))) + != RTEMS_SUCCESSFUL) + { + return status; + + } + + /* Set up interrupts MSCAN A */ + if(!BSP_install_rtems_irq_handler(&(mpc5200_mscan_irq_data[minor]))) + rtems_panic("Can't attach MPC5x00 MSCAN interrupt handler %d\n", minor); + + /* basic setup for channel info. struct. */ + chan->regs = (struct mpc5200_mscan *)&(mpc5200.mscan[minor]); + chan->int_rx_err = 0; + chan->id_extended = FALSE; + chan->mode = MSCAN_INITIALIZED_MODE; + + return status; + + } + + +/* + * MPC5x00 MSCAN device initialization + */ +rtems_device_driver mscan_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg + ) + { + rtems_status_code status; + + /* Initialization requested via RTEMS */ + if((status = mscan_channel_initialize(major,MSCAN_A)) != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + if((status = mscan_channel_initialize(major,MSCAN_B)) != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + if((status = mpc5200_mscan_set_mode(MSCAN_A, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + if((status = mpc5200_mscan_set_mode(MSCAN_B, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return status; + + } + + +/* + * MPC5x00 MSCAN device open + */ +rtems_device_driver mscan_open( rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) + { + rtems_status_code status; + struct mscan_channel_info *chan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + /* if not already set enter init mode */ + status = mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE); + + return status; + + } + + +/* + * MPC5x00 MSCAN device close + */ +rtems_device_driver mscan_close( rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) + { + rtems_status_code status; + struct mscan_channel_info *chan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + /* enter deep sleep mode */ + status = mpc5200_mscan_set_mode(minor, MSCAN_SLEEP_MODE); + + return status; + + } + + +/* + * MPC5x00 MSCAN device read + */ +rtems_device_driver mscan_read( rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) + { + rtems_status_code status; + uint32_t message_size = 0; + rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg; + struct mscan_rx_parms *rx_parms = (struct mscan_rx_parms *)(parms->buffer); + struct can_message *rx_mess = (struct can_message *)(rx_parms->rx_mess); + struct mscan_channel_info *chan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + if((status = rtems_message_queue_receive(chan->rx_qid, + (void *)(rx_mess), + (uint32_t *)&message_size, + (uint32_t)(rx_parms->rx_flags), + (rtems_interval)(rx_parms->rx_timeout))) + != RTEMS_SUCCESSFUL) + { + + parms->bytes_moved = 0; + + } + else + { + + parms->bytes_moved = sizeof(struct can_message); + + } + + return status; + + } + + +/* + * MPC5x00 MSCAN device write + */ +rtems_device_driver mscan_write( rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) + { + rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg; + struct mscan_tx_parms *tx_parms = (struct mscan_tx_parms *)(parms->buffer); + struct can_message *tx_mess = (struct can_message *)(tx_parms->tx_mess); + struct mscan_channel_info *chan = NULL; + mscan_handle *mscan_hdl = NULL; + volatile struct mpc5200_mscan *mscan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + mscan_hdl = mpc5200_mscan_irq_data[minor].handle; + mscan = chan->regs; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + /* select one free tx buffer (TOUCAN not registered) */ + if((mscan_hdl->toucan_callback) == NULL) + { + + if(mscan->tflg & MSCAN_TX_BUFF2) + mscan->bsel = MSCAN_TX_BUFF2; + + if(mscan->tflg & MSCAN_TX_BUFF1) + mscan->bsel = MSCAN_TX_BUFF1; + + if(mscan->tflg & MSCAN_TX_BUFF0) + mscan->bsel = MSCAN_TX_BUFF0; + } + else + { + + /* select a specific, preconfigured tx buffer (TOUCAN registered) */ + switch(tx_parms->tx_id) + { + + case 0: + if(mscan->tflg & MSCAN_TX_BUFF0) + mscan->bsel = MSCAN_TX_BUFF0; + break; + + case 1: + if(mscan->tflg & MSCAN_TX_BUFF1) + mscan->bsel = MSCAN_TX_BUFF1; + break; + + case 2: + if(mscan->tflg & MSCAN_TX_BUFF2) + mscan->bsel = MSCAN_TX_BUFF2; + break; + + default: + break; + + } + + } + + /* if no tx buffer is available, teminate the write request */ + if(!(mscan->bsel)) + { + + parms->bytes_moved = 0; + return RTEMS_UNSATISFIED; + + } + + /* prepare tx id and dlc (TOUCAN not initialized) */ + if((mscan_hdl->toucan_callback) == NULL) + { + + /* check for tx length */ + if((tx_mess->mess_len) & 0x000F) + { + + /* set tx id */ + mscan->txidr0 = SET_IDR0(tx_mess->mess_id); + mscan->txidr1 = SET_IDR1(tx_mess->mess_id); + mscan->txidr2 = 0; + mscan->txidr3 = 0; + + /* insert dlc into mscan register */ + mscan->txdlr = (uint8_t)((tx_mess->mess_len) & 0x000F); + + } + else + { + + parms->bytes_moved = 0; + return RTEMS_UNSATISFIED; + + } + + } + + /* copy tx data to MSCAN registers */ + switch(mscan->txdlr) + { + + case 8: + mscan->txdsr7 = tx_mess->mess_data[7]; + case 7: + mscan->txdsr6 = tx_mess->mess_data[6]; + case 6: + mscan->txdsr5 = tx_mess->mess_data[5]; + case 5: + mscan->txdsr4 = tx_mess->mess_data[4]; + case 4: + mscan->txdsr3 = tx_mess->mess_data[3]; + case 3: + mscan->txdsr2 = tx_mess->mess_data[2]; + case 2: + mscan->txdsr1 = tx_mess->mess_data[1]; + case 1: + mscan->txdsr0 = tx_mess->mess_data[0]; + break; + default: + break; + + } + + /* enable message buffer specific interrupt */ + mscan->tier |= mscan->bsel; + + /* start transfer */ + mscan->tflg = mscan->bsel; + + return RTEMS_SUCCESSFUL; + + } + + +/* + * MPC5x00 MSCAN device control + */ +rtems_device_driver mscan_control( rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) + { + uint16_t tx_id; + rtems_libio_ioctl_args_t *parms = (rtems_libio_ioctl_args_t *)arg; + struct mscan_ctrl_parms *ctrl_parms = (struct mscan_ctrl_parms *)(parms->buffer); + struct mscan_channel_info *chan = NULL; + mscan_handle *mscan_hdl = NULL; + volatile struct mpc5200_mscan *mscan = NULL; + + switch(minor) + { + + case MSCAN_A: + case MSCAN_B: + chan = &chan_info[minor]; + mscan_hdl = mpc5200_mscan_irq_data[minor].handle; + mscan = chan->regs; + break; + + default: + return RTEMS_UNSATISFIED; + break; + } + + switch(parms->command) + { + + /* TOUCAN callback initialization for MSCAN */ + case TOUCAN_MSCAN_INIT: + mscan_hdl->toucan_callback = ctrl_parms->toucan_cb_fnc; + break; + + /* set rx buffer ID */ + case MSCAN_SET_RX_ID: + + /* enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + + switch(ctrl_parms->ctrl_reg_no) + { + + case RX_BUFFER_0: + mscan->idar0 = SET_IDR0(ctrl_parms->ctrl_id); + mscan->idar1 = SET_IDR1(ctrl_parms->ctrl_id); + break; + + case RX_BUFFER_1: + mscan->idar2 = SET_IDR2(ctrl_parms->ctrl_id); + mscan->idar3 = SET_IDR3(ctrl_parms->ctrl_id); + break; + + case RX_BUFFER_2: + mscan->idar4 = SET_IDR4(ctrl_parms->ctrl_id); + mscan->idar5 = SET_IDR5(ctrl_parms->ctrl_id); + break; + + case RX_BUFFER_3: + mscan->idar6 = SET_IDR6(ctrl_parms->ctrl_id); + mscan->idar7 = SET_IDR7(ctrl_parms->ctrl_id); + break; + + default: + break; + + } + + /* exit init mode and perform further initialization which is required in the normal mode */ + mpc5200_mscan_exit_init_mode(mscan); + + /* enable ints. */ + mpc5200_mscan_int_enable(mscan); + + /* wait for bus sync. */ + mpc5200_mscan_wait_sync(mscan); + + return RTEMS_SUCCESSFUL; + break; + + /* get rx buffer ID */ + case MSCAN_GET_RX_ID: + + switch(ctrl_parms->ctrl_reg_no) + { + + case RX_BUFFER_0: + ctrl_parms->ctrl_id = GET_IDR0(mscan->idar0) | GET_IDR1(mscan->idar1); + break; + + case RX_BUFFER_1: + ctrl_parms->ctrl_id = GET_IDR2(mscan->idar2) | GET_IDR3(mscan->idar3); + break; + + case RX_BUFFER_2: + ctrl_parms->ctrl_id = GET_IDR4(mscan->idar4) | GET_IDR5(mscan->idar5); + break; + + case RX_BUFFER_3: + ctrl_parms->ctrl_id = GET_IDR6(mscan->idar6) | GET_IDR7(mscan->idar7); + break; + + default: + break; + + } + + break; + + /* set rx buffer ID mask */ + case MSCAN_SET_RX_ID_MASK: + + /* enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + + switch(ctrl_parms->ctrl_reg_no) + { + + case RX_BUFFER_0: + mscan->idmr0 = SET_IDR0(ctrl_parms->ctrl_id_mask); + mscan->idmr1 = SET_IDR1(ctrl_parms->ctrl_id_mask); + break; + + case RX_BUFFER_1: + mscan->idmr2 = SET_IDR2(ctrl_parms->ctrl_id_mask); + mscan->idmr3 = SET_IDR3(ctrl_parms->ctrl_id_mask); + break; + + case RX_BUFFER_2: + mscan->idmr4 = SET_IDR4(ctrl_parms->ctrl_id_mask); + mscan->idmr5 = SET_IDR5(ctrl_parms->ctrl_id_mask); + break; + + case RX_BUFFER_3: + mscan->idmr6 = SET_IDR6(ctrl_parms->ctrl_id_mask); + mscan->idmr7 = SET_IDR7(ctrl_parms->ctrl_id_mask); + break; + + default: + break; + + } + + /* exit init mode and perform further initialization which is required in the normal mode */ + mpc5200_mscan_exit_init_mode(mscan); + + /* enable ints. */ + mpc5200_mscan_int_enable(mscan); + + /* wait for bus sync. */ + mpc5200_mscan_wait_sync(mscan); + + break; + + /* get rx buffer ID mask */ + case MSCAN_GET_RX_ID_MASK: + + switch(ctrl_parms->ctrl_reg_no) + { + + case RX_BUFFER_0: + ctrl_parms->ctrl_id_mask = GET_IDR0(mscan->idmr0) | GET_IDR1(mscan->idmr1); + break; + + case RX_BUFFER_1: + ctrl_parms->ctrl_id_mask = GET_IDR2(mscan->idmr2) | GET_IDR3(mscan->idmr3); + break; + + case RX_BUFFER_2: + ctrl_parms->ctrl_id_mask = GET_IDR4(mscan->idmr4) | GET_IDR5(mscan->idmr5); + break; + + case RX_BUFFER_3: + ctrl_parms->ctrl_id_mask = GET_IDR6(mscan->idmr6) | GET_IDR7(mscan->idmr7); + break; + + default: + break; + + } + + /* set tx buffer ID */ + case MSCAN_SET_TX_ID: + + /* check for availability of tx buffer */ + if(!((mscan->tflg) & (uint8_t)(ctrl_parms->ctrl_reg_no))) + { + + /* do abort tx buf. request */ + mscan->tarq = (uint8_t)(ctrl_parms->ctrl_reg_no); + + /* wait for abort tx buf. ack. */ + while((mscan->taak) & (uint8_t)(ctrl_parms->ctrl_reg_no)); + + } + + /* select tx buf. */ + mscan->bsel = (uint8_t)(ctrl_parms->ctrl_reg_no); + + /* set the tx id of selected buf. */ + tx_id = ctrl_parms->ctrl_id; + mscan->txidr0 = SET_IDR0(tx_id); + mscan->txidr1 = SET_IDR1(tx_id); + mscan->txidr2 = 0; + mscan->txidr3 = 0; + + break; + + /* get tx buffer ID */ + case MSCAN_GET_TX_ID: + + /* select tx buf. */ + mscan->bsel = (uint8_t)(ctrl_parms->ctrl_reg_no); + + /* get tx id. of selected buf. */ + ctrl_parms->ctrl_id = GET_IDR0(mscan->txidr0) | GET_IDR1(mscan->txidr1); + + break; + + default: + break; + + } + + return RTEMS_SUCCESSFUL; + + } + diff --git a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h new file mode 100644 index 0000000000..af4a342537 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h @@ -0,0 +1,333 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file declares stuff for the mscan driver | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.18 2005/12/11 23:02:16 peter +|* added can bitrate and timings +|* +|* Revision 1.17 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +#ifndef __MSCAN_H__ +#define __MSCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define MSCAN_MAX_DATA_BYTES 8 +#define MSCAN_RX_BUFF_NUM 4 +#define MSCAN_TX_BUFF_NUM 3 + + +#define MSCAN_A_DEV_NAME "/dev/mscana" +#define MSCAN_B_DEV_NAME "/dev/mscanb" +#define MSCAN_A 0 +#define MSCAN_B 1 + +#define MSCAN_INITIALIZED_MODE 0 +#define MSCAN_INIT_NORMAL_MODE 1 +#define MSCAN_NORMAL_MODE 2 +#define MSCAN_SLEEP_MODE 4 + +#define CAN_BIT_RATE 100000 +#define CAN_MAX_NO_OF_TQ 25 +#define CAN_MAX_NO_OF_TQ_TSEG1 15 +#define CAN_MAX_NO_OF_TQ_TSEG2 7 +#define CAN_MAX_NO_OF_TQ_SJW 2 + +#define MSCAN_SET_RX_ID 1 +#define MSCAN_GET_RX_ID 2 +#define MSCAN_SET_RX_ID_MASK 3 +#define MSCAN_GET_RX_ID_MASK 4 +#define MSCAN_SET_TX_ID 5 +#define MSCAN_GET_TX_ID 6 +#define TOUCAN_MSCAN_INIT 7 + +#define MSCAN_RX_BUFF_NOACTIVE (0 << 4) +#define MSCAN_RX_BUFF_EMPTY (1 << 6) +#define MSCAN_RX_BUFF_FULL (1 << 5) +#define MSCAN_RX_BUFF_OVERRUN ((MSCAN_RX_BUFF_EMPTY) | (MSCAN_RX_BUFF_FULL)) +#define MSCAN_RX_BUFF_BUSY (1 << 4) + +#define MSCAN_A_MBUFF_MASK 0x07 +#define MSCAN_B_MBUFF_MASK 0x07 + +#define MSCAN_TX_BUFF0 (1 << 0) +#define MSCAN_TX_BUFF1 (1 << 1) +#define MSCAN_TX_BUFF2 (1 << 2) + +#define MSCAN_IDE (1 << 0) +#define MSCAN_RTR (1 << 1) +#define MSCAN_READ_RXBUFF_0 (1 << 2) +#define MSCAN_READ_RXBUFF_1 (1 << 2) +#define MSCAN_READ_RXBUFF_2 (1 << 2) +#define MSCAN_READ_RXBUFF_3 (1 << 2) + +#define CTL0_RXFRM (1 << 7) +#define CTL0_RXACT (1 << 6) +#define CTL0_CSWAI (1 << 5) +#define CTL0_SYNCH (1 << 4) +#define CTL0_TIME (1 << 3) +#define CTL0_WUPE (1 << 2) +#define CTL0_SLPRQ (1 << 1) +#define CTL0_INITRQ (1 << 0) + +#define CTL1_CANE (1 << 7) +#define CTL1_CLKSRC (1 << 6) +#define CTL1_LOOPB (1 << 5) +#define CTL1_LISTEN (1 << 4) +#define CTL1_WUPM (1 << 2) +#define CTL1_SLPAK (1 << 1) +#define CTL1_INITAK (1 << 0) + +#define BTR0_SJW(btr0) ((btr0) << 6) +#define BTR0_BRP(btr0) ((btr0) << 0) + +#define BTR1_SAMP (1 << 7) +#define BTR1_TSEG_22_20(btr1) ((btr1) << 4) +#define BTR1_TSEG_13_10(btr1) ((btr1) << 0) + +#define RFLG_WUPIF (1 << 7) +#define RFLG_CSCIF (1 << 6) +#define RFLG_RSTAT (3 << 4) +#define RFLG_TSTAT (3 << 2) +#define RFLG_OVRIF (1 << 1) +#define RFLG_RXF (1 << 0) +#define RFLG_GET_RX_STATE(rflg) (((rflg) >> 4) & 0x03) +#define RFLG_GET_TX_STATE(rflg) (((rflg) >> 2) & 0x03) + +#define MSCAN_STATE_OK 0 +#define MSCAN_STATE_ERR 1 +#define MSCAN_STATE_WRN 2 +#define MSCAN_STATE_BUSOFF 3 + +#define RIER_WUPIE (1 << 7) +#define RIER_CSCIE (1 << 6) +#define RIER_RSTAT(rier) ((rier) << 4) +#define RIER_TSTAT(rier) ((rier) << 2) +#define RIER_OVRIE (1 << 1) +#define RIER_RXFIE (1 << 0) + +#define TFLG_TXE2 (1 << 2) +#define TFLG_TXE1 (1 << 1) +#define TFLG_TXE0 (1 << 0) + +#define TIER_TXEI2 (1 << 2) +#define TIER_TXEI1 (1 << 1) +#define TIER_TXEI0 (1 << 0) + +#define TARQ_ABTRQ2 (1 << 2) +#define TARQ_ABTRQ1 (1 << 1) +#define TARQ_ABTRQ0 (1 << 0) + +#define TAAK_ABTRQ2 (1 << 2) +#define TAAK_ABTRQ1 (1 << 1) +#define TAAK_ABTRQ0 (1 << 0) + +#define BSEL_TX2 (1 << 2) +#define BSEL_TX1 (1 << 1) +#define BSEL_TX0 (1 << 0) + +#define IDAC_IDAM1 (1 << 5) +#define IDAC_IDAM0 (1 << 4) +#define IDAC_IDHIT(idac) ((idac) & 0x7) + +#define TX_MBUF_SEL(buf_no) (1 << (buf_no)) +#define TX_DATA_LEN(len) ((len) & 0x0F) + +#define TX_MBUF_EMPTY(val) (1 << (val)) + +#define TXIDR1_IDE (1 << 3) +#define TXIDR1_SRR (1 << 4) + +#define TXIDR3_RTR (1 << 0) +#define TXIDR1_RTR (1 << 4) + +#define RXIDR1_IDE (1 << 3) +#define RXIDR1_SRR (1 << 4) + +#define RXIDR3_RTR (1 << 0) +#define RXIDR1_RTR (1 << 4) + +#define SET_IDR0(u16) ((uint8_t)((u16) >> 3)) +#define SET_IDR1(u16) ((uint8_t)(((u16) & 0x0007) << 5)) + +#define SET_IDR2(u16) SET_IDR0(u16) +#define SET_IDR3(u16) SET_IDR1(u16) + +#define SET_IDR4(u16) SET_IDR0(u16) +#define SET_IDR5(u16) SET_IDR1(u16) + +#define SET_IDR6(u16) SET_IDR0(u16) +#define SET_IDR7(u16) SET_IDR1(u16) + +#define GET_IDR0(u16) ((uint16_t) ((u16) << 3)) +#define GET_IDR1(u16) ((uint16_t)((u16) >> 5)) + +#define GET_IDR2(u16) GET_IDR0(u16) +#define GET_IDR3(u16) GET_IDR1(u16) + +#define GET_IDR4(u16) GET_IDR0(u16) +#define GET_IDR5(u16) GET_IDR1(u16) + +#define GET_IDR6(u16) GET_IDR0(u16) +#define GET_IDR7(u16) GET_IDR1(u16) + +#define NO_OF_MSCAN_A_RX_BUFF 20 +#define NO_OF_MSCAN_B_RX_BUFF 20 +#define MSCAN_MESSAGE_SIZE(size) (((size)%CPU_ALIGNMENT) ? (((size) + CPU_ALIGNMENT)-((size) + CPU_ALIGNMENT)%CPU_ALIGNMENT) : (size)) + +#define TX_BUFFER_0 0 +#define TX_BUFFER_1 1 +#define TX_BUFFER_2 2 + +#define RX_BUFFER_0 0 +#define RX_BUFFER_1 1 +#define RX_BUFFER_2 2 +#define RX_BUFFER_3 3 + +typedef struct _mscan_handle + { + uint8_t mscan_channel; + void (*toucan_callback)(int16_t); + } mscan_handle; + +struct can_message + { + /* uint16_t mess_len; */ + uint16_t mess_id; + uint16_t mess_time_stamp; + uint8_t mess_data[MSCAN_MAX_DATA_BYTES]; + uint8_t mess_len; + }; + +struct mpc5200_rx_cntrl + { + struct can_message can_rx_message[MSCAN_RX_BUFF_NUM]; + }; + + +struct mscan_channel_info + { + volatile struct mpc5200_mscan *regs; + uint32_t int_rx_err; + rtems_id rx_qid; + uint32_t rx_qname; + uint8_t id_extended; + uint8_t mode; + }; + +struct mscan_rx_parms + { + struct can_message *rx_mess; + uint32_t rx_timeout; + uint8_t rx_flags; + }; + +struct mscan_tx_parms + { + struct can_message *tx_mess; + uint32_t tx_id; + }; + +struct mscan_ctrl_parms + { + uint32_t ctrl_id; + uint32_t ctrl_id_mask; + uint8_t ctrl_reg_no; + void (*toucan_cb_fnc)(int16_t); + }; + + +extern void CanInterrupt_A(int16_t); +extern void CanInterrupt_B(int16_t); + + +rtems_device_driver mscan_initialize( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +rtems_device_driver mscan_open( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +rtems_device_driver mscan_close( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +rtems_device_driver mscan_read( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +rtems_device_driver mscan_write( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +rtems_device_driver mscan_control( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + + +#define MSCAN_DRIVER_TABLE_ENTRY \ + { mscan_initialize, mscan_open, mscan_close, \ + mscan_read, mscan_write, mscan_control } + +/*MSCAN driver internal functions */ +void mscan_hardware_initialize(rtems_device_major_number, uint32_t, void *); +void mpc5200_mscan_int_enable(volatile struct mpc5200_mscan *); +void mpc5200_mscan_int_disable(volatile struct mpc5200_mscan *); +void mpc5200_mscan_enter_sleep_mode(volatile struct mpc5200_mscan *); +void mpc5200_mscan_exit_sleep_mode(volatile struct mpc5200_mscan *); +void mpc5200_mscan_enter_init_mode(volatile struct mpc5200_mscan *); +void mpc5200_mscan_exit_init_mode(volatile struct mpc5200_mscan *); +void mpc5200_mscan_wait_sync(volatile struct mpc5200_mscan *); +void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *); +void mpc5200_mscan_perform_normal_mode_settings(volatile struct mpc5200_mscan *); +rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number, uint8_t); +rtems_status_code mscan_channel_initialize(rtems_device_major_number, rtems_device_minor_number); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MSCAN_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c b/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c new file mode 100644 index 0000000000..3fa52f7b72 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c @@ -0,0 +1,1596 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the networking driver | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.10 2005/12/06 14:30:42 thomas +|* updated name for peripheral register block +|* +|* Revision 1.9 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/* + * RTEMS/TCPIP driver for MPC5200 FEC Ethernet + * + * Modified for Motorola MPC5200 by Thomas Doerfler, <Thomas.Doerfler@imd-systems.de> + * COPYRIGHT (c) 2003, IMD + * + * Modified for Motorola IceCube (mgt5100) by Peter Rasmussen <prasmus@ipr-engineering.de> + * COPYRIGHT (c) 2003, IPR Engineering + * + * Parts of code are also under property of Driver Information Systems and based + * on Motorola Proprietary Information. + * COPYRIGHT (c) 2002 MOTOROLA INC. + * + * Modified for MPC860 by Jay Monkman (jmonkman@frasca.com) + * + * This supports Ethernet on either SCC1 or the FEC of the MPC860T. + * Right now, we only do 10 Mbps, even with the FEC. The function + * rtems_enet_driver_attach determines which one to use. Currently, + * only one may be used at a time. + * + * Based on the MC68360 network driver by + * W. Eric Norum + * Saskatchewan Accelerator Laboratory + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@skatter.usask.ca + * + * This supports ethernet on SCC1. Right now, we only do 10 Mbps. + * + * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca> + * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca> + * Copyright (c) 1999, National Research Council of Canada + * + * network.c,v 1.7 2001/08/31 14:57:48 joel Exp + * + */ +#include <rtems.h> +#include <rtems/error.h> +#include <rtems/rtems_bsdnet.h> +#include <stdio.h> +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/if_ether.h> +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include <net/if_var.h> +#include <errno.h> + +/* motorola-capi-specifics... */ +#include "../bestcomm/include/ppctypes.h" /* uint32, et. al. */ +#include "../bestcomm/dma_image.h" +#include "../bestcomm/bestcomm_glue.h" + + +#define SDMA_BD_TFD 0x08000000 /*< Transmit Frame Done */ +#define SDMA_BD_INT 0x04000000 /*< Interrupt on frame done */ +#define SDMA_BD_RX_NUM 32 /* Number of receive buffer descriptors */ +#define SDMA_BD_TX_NUM 48 /* Number of transmit buffer descriptors */ + +#define SET_BD_STATUS(bd, stat) { \ + (bd)->Status &= 0x0000ffff; \ + (bd)->Status |= 0xffff0000 & stat; \ +} +#define SET_BD_LENGTH(bd, len) { \ + (bd)->Status &= 0xffff0000; \ + (bd)->Status |= 0x0000ffff & len; \ +} +#define GET_BD_STATUS(bd) ((bd)->Status & 0xffff0000) +#define GET_BD_LENGTH(bd) ((bd)->Status & 0x0000ffff) +#define GET_SDMA_PENDINGBIT(Bit) \ + (mpc5200.IntPend & (uint32)(1<<Bit)) + +#include "../bestcomm/bestcomm_api.h" +#include "../bestcomm/task_api/bestcomm_cntrl.h" +#include "../bestcomm/task_api/tasksetup_bdtable.h" + +extern TaskBDIdxTable_t TaskBDIdxTable[MAX_TASKS]; + +static TaskId rxTaskId; /* SDMA RX task ID */ +static TaskId txTaskId; /* SDMA TX task ID */ + +/*#define ETH_DEBUG*/ + +/* + * Number of interfaces supported by this driver + */ +#define NIFACES 1 + +/* + * Default number of buffer descriptors set aside for this driver. + * The number of transmit buffer descriptors has to be quite large + * since a single frame often uses four or more buffer descriptors. + */ +#define RX_BUF_COUNT SDMA_BD_RX_NUM +#define TX_BUF_COUNT SDMA_BD_TX_NUM +#define TX_BD_PER_BUF 1 + +#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255") + + +/* + * RTEMS event used by interrupt handler to signal daemons. + * This must *not* be the same event used by the TCP/IP task synchronization. + */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 + +/* + * RTEMS event used to start transmit daemon. + * This must not be the same as INTERRUPT_EVENT. + */ +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + +/* Task number assignment */ +#define FEC_RECV_TASK_NO TASK_FEC_RX +#define FEC_XMIT_TASK_NO TASK_FEC_TX + + +/* BD and parameters are stored in SRAM(refer to sdma.h) */ +#define MPC5200_FEC_BD_BASE ETH_BD_BASE + +/* FEC transmit watermark settings */ +#define MPC5200_FEC_X_WMRK_64 0x0 /* or 0x1 */ +#define MPC5200_FEC_X_WMRK_128 0x2 +#define MPC5200_FEC_X_WMRK_192 0x3 + +/* RBD bits definitions */ +#define MPC5200_FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ +#define MPC5200_FEC_RBD_WRAP 0x2000 /* Last BD in ring */ +#define MPC5200_FEC_RBD_INT 0x1000 /* Interrupt */ +#define MPC5200_FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ +#define MPC5200_FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ +#define MPC5200_FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ +#define MPC5200_FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ +#define MPC5200_FEC_RBD_LG 0x0020 /* Frame length violation */ +#define MPC5200_FEC_RBD_NO 0x0010 /* Nonoctet align frame */ +#define MPC5200_FEC_RBD_SH 0x0008 /* Short frame, FEC does not support SH and this bit is always cleared */ +#define MPC5200_FEC_RBD_CR 0x0004 /* CRC error */ +#define MPC5200_FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ +#define MPC5200_FEC_RBD_TR 0x0001 /* The receive frame is truncated */ +#define MPC5200_FEC_RBD_ERR (MPC5200_FEC_RBD_LG | \ + MPC5200_FEC_RBD_NO | \ + MPC5200_FEC_RBD_CR | \ + MPC5200_FEC_RBD_OV | \ + MPC5200_FEC_RBD_TR) + +/* TBD bits definitions */ +#define MPC5200_FEC_TBD_READY 0x8000 /* Buffer is ready */ +#define MPC5200_FEC_TBD_WRAP 0x2000 /* Last BD in ring */ +#define MPC5200_FEC_TBD_INT 0x1000 /* Interrupt */ +#define MPC5200_FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ +#define MPC5200_FEC_TBD_TC 0x0400 /* Transmit the CRC */ +#define MPC5200_FEC_TBD_ABC 0x0200 /* Append bad CRC */ + +/* MII-related definitios */ +#define MPC5200_FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ +#define MPC5200_FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ +#define MPC5200_FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ +#define MPC5200_FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ +#define MPC5200_FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ +#define MPC5200_FEC_MII_DATA_TA 0x00020000 /* Turnaround */ +#define MPC5200_FEC_MII_DATA_DATAMSK 0x0000fff /* PHY data field */ + +#define MPC5200_FEC_MII_DATA_RA_SHIFT 0x12 /* MII Register address bits */ +#define MPC5200_FEC_MII_DATA_PA_SHIFT 0x17 /* MII PHY address bits */ + + +/* Receive & Transmit Buffer Descriptor definitions */ +typedef struct mpc5200_buffer_desc_ + { + volatile uint16_t status; + volatile uint16_t length; + volatile void *buffer; + } mpc5200_buffer_desc_t; + + +/* + * Device data + */ +struct mpc5200_enet_struct { +#if 0 + struct ifnet ac_if; +#else + struct arpcom arpcom; +#endif + struct mbuf **rxMbuf; + struct mbuf **txMbuf; + int acceptBroadcast; + int rxBdCount; + int txBdCount; + int txBdHead; + int txBdTail; + int txBdActiveCount; + + rtems_id rxDaemonTid; + rtems_id txDaemonTid; + + unsigned long rxInterrupts; + unsigned long rxNotLast; + unsigned long rxGiant; + unsigned long rxNonOctet; + unsigned long rxBadCRC; + unsigned long rxOverrun; + unsigned long rxCollision; + + unsigned long txInterrupts; + unsigned long txDeferred; + unsigned long txLateCollision; + unsigned long txUnderrun; + unsigned long txMisaligned; + unsigned long rxNotFirst; + unsigned long txRetryLimit; + }; + +uint8_t tx_shadow_buffer[TX_BUF_COUNT][(ETHER_MAX_LEN+3)&~3]; + +static struct mpc5200_enet_struct enet_driver[NIFACES]; + +extern int taskTable; + + + +/* + * Function: mpc5200_fec_rx_bd_init + * + * Description: Initialize the receive buffer descriptor ring. + * + * Returns: void + * + * Notes: Space for the buffers of rx BDs is allocated by the rx deamon + * + */ +static void mpc5200_fec_rx_bd_init(struct mpc5200_enet_struct *sc) { + int rxBdIndex; + struct mbuf *m; + struct ifnet *ifp = &sc->arpcom.ac_if; + BDIdx bdi; + + /* + * Fill RX buffer descriptor ring. + */ + for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) { + MGETHDR (m, M_WAIT, MT_DATA); + MCLGET (m, M_WAIT); + + m->m_pkthdr.rcvif = ifp; + sc->rxMbuf[rxBdIndex] = m; + bdi = TaskBDAssign( rxTaskId, + mtod(m, void *), + NULL, + ETHER_MAX_LEN, + 0 ); + if (bdi != rxBdIndex) { + rtems_panic("network rx buffer indices out of sync"); + } + } +} + +/* + * Function: MPC5200_eth_addr_filter_set + * + * Description: Set individual address filter for unicast address and + * set physical address registers. + * + * Returns: void + * + * Notes: + * + */ +static void mpc5200_eth_addr_filter_set(struct mpc5200_enet_struct *sc) { + unsigned char *mac; + unsigned char currByte; /* byte for which to compute the CRC */ + int byte; /* loop - counter */ + int bit; /* loop - counter */ + unsigned long crc = 0xffffffff; /* initial value */ + + /* + * Get the mac address of ethernet controller + */ + mac = (unsigned char *)(&sc->arpcom.ac_enaddr); + + /* + * The algorithm used is the following: + * we loop on each of the six bytes of the provided address, + * and we compute the CRC by left-shifting the previous + * value by one position, so that each bit in the current + * byte of the address may contribute the calculation. If + * the latter and the MSB in the CRC are different, then + * the CRC value so computed is also ex-ored with the + * "polynomium generator". The current byte of the address + * is also shifted right by one bit at each iteration. + * This is because the CRC generatore in hardware is implemented + * as a shift-register with as many ex-ores as the radixes + * in the polynomium. This suggests that we represent the + * polynomiumm itself as a 32-bit constant. + */ + for(byte = 0; byte < 6; byte++) + { + + currByte = mac[byte]; + + for(bit = 0; bit < 8; bit++) + { + + if((currByte & 0x01) ^ (crc & 0x01)) + { + + crc >>= 1; + crc = crc ^ 0xedb88320; + + } + else + { + + crc >>= 1; + + } + + currByte >>= 1; + + } + + } + + crc = crc >> 26; + + /* + * Set individual hash table register + */ + if(crc >= 32) + { + + mpc5200.iaddr1 = (1 << (crc - 32)); + mpc5200.iaddr2 = 0; + + } + else + { + + mpc5200.iaddr1 = 0; + mpc5200.iaddr2 = (1 << crc); + + } + + /* + * Set physical address + */ + mpc5200.paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; + mpc5200.paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808; + + } + + +/* + * Function: mpc5200_eth_mii_read + * + * Description: Read a media independent interface (MII) register on an + * 18-wire ethernet tranceiver (PHY). Please see your PHY + * documentation for the register map. + * + * Returns: 32-bit register value + * + * Notes: + * + */ +int mpc5200_eth_mii_read(struct mpc5200_enet_struct *sc, unsigned char phyAddr, unsigned char regAddr, unsigned short * retVal) + { + unsigned long reg; /* convenient holder for the PHY register */ + unsigned long phy; /* convenient holder for the PHY */ + int timeout = 0xffff; + + /* + * reading from any PHY's register is done by properly + * programming the FEC's MII data register. + */ + reg = regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT; + phy = phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT; + + mpc5200.mii_data = (MPC5200_FEC_MII_DATA_ST | MPC5200_FEC_MII_DATA_OP_RD | MPC5200_FEC_MII_DATA_TA | phy | reg); + + /* + * wait for the related interrupt + */ + while ((timeout--) && (!(mpc5200.ievent & 0x00800000))); + + if(timeout == 0) + { + +#ifdef ETH_DEBUG + printf ("Read MDIO failed..." "\r\n"); +#endif + + return FALSE; + + } + + /* + * clear mii interrupt bit + */ + mpc5200.ievent = 0x00800000; + + /* + * it's now safe to read the PHY's register + */ + *retVal = (unsigned short)mpc5200.mii_data; + + return TRUE; + + } + +/* + * Function: mpc5200_eth_mii_write + * + * Description: Write a media independent interface (MII) register on an + * 18-wire ethernet tranceiver (PHY). Please see your PHY + * documentation for the register map. + * + * Returns: Success (boolean) + * + * Notes: + * + */ +static int mpc5200_eth_mii_write(struct mpc5200_enet_struct *sc, unsigned char phyAddr, unsigned char regAddr, unsigned short data) + { + unsigned long reg; /* convenient holder for the PHY register */ + unsigned long phy; /* convenient holder for the PHY */ + int timeout = 0xffff; + + reg = regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT; + phy = phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT; + + mpc5200.mii_data = (MPC5200_FEC_MII_DATA_ST | MPC5200_FEC_MII_DATA_OP_WR | MPC5200_FEC_MII_DATA_TA | phy | reg | data); + + /* + * wait for the MII interrupt + */ + while ((timeout--) && (!(mpc5200.ievent & 0x00800000))); + + if(timeout == 0) + { + +#ifdef ETH_DEBUG + printf ("Write MDIO failed..." "\r\n"); +#endif + + return FALSE; + + } + + /* + * clear MII interrupt bit + */ + mpc5200.ievent = 0x00800000; + + return TRUE; + + } + + +/* + * Function: mpc5200_fec_reset + * + * Description: Reset a running ethernet driver including the hardware + * FIFOs and the FEC. + * + * Returns: Success (boolean) + * + * Notes: + * + */ +static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) { + /* + * Clear FIFO status registers + */ + mpc5200.rfifo_status &= FEC_FIFO_STAT_ERROR; + mpc5200.tfifo_status &= FEC_FIFO_STAT_ERROR; + + /* + * + */ + mpc5200.reset_cntrl = 0x01000000; + + /* + * Issue a reset command to the FEC chip + */ + mpc5200.ecntrl |= FEC_ECNTRL_RESET; + + /* + * wait at least 16 clock cycles + */ + rtems_task_wake_after(2); + + return TRUE; +} + + +/* + * Function: mpc5200_fec_off + * + * Description: Stop the FEC and disable the ethernet SmartComm tasks. + * This function "turns off" the driver. + * + * Returns: void + * + * Notes: + * + */ +void mpc5200_fec_off(struct mpc5200_enet_struct *sc) + { + int counter = 0xffff; + +#if defined(ETH_DEBUG) + unsigned short phyStatus, i; + unsigned char phyAddr = 0; + + for(i = 0; i < 9; i++) + { + + mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus); + printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus); + + } + + for(i = 16; i < 21; i++) + { + + mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus); + printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus); + + } +#endif /* ETH_DEBUG */ + + /* + * mask FEC chip interrupts + */ + mpc5200.imask = FEC_INTR_MASK_ALL; + + /* + * issue graceful stop command to the FEC transmitter if necessary + */ + mpc5200.x_cntrl |= FEC_XCNTRL_GTS; + + /* + * wait for graceful stop to register + */ + while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA))); + + /* + * Disable the SmartDMA transmit and receive tasks. + */ + TaskStop( rxTaskId ); + TaskStop( txTaskId ); + /* + * Disable transmit / receive interrupts + */ + bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO); + bestcomm_glue_irq_disable(FEC_RECV_TASK_NO); + + /* + * Disable the Ethernet Controller + */ + mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN); + + } + + +/* + * MPC5200 SmartComm ethernet interrupt handler + */ +void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused) + { + volatile uint32_t ievent; + + ievent = mpc5200.ievent; + + + /* Frame received? */ + if(GET_SDMA_PENDINGBIT(FEC_RECV_TASK_NO)) + { + + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,FEC_RECV_TASK_NO); + + bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);/*Disable receive ints*/ + + enet_driver[0].rxInterrupts++; /* Rx int has occurred */ + + rtems_event_send(enet_driver[0].rxDaemonTid, INTERRUPT_EVENT); + + } + } + +/* + * MPC5200 SmartComm ethernet interrupt handler + */ +void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused) + { + volatile uint32_t ievent; + + ievent = mpc5200.ievent; + + + /* Buffer transmitted or transmitter error? */ + if(GET_SDMA_PENDINGBIT(FEC_XMIT_TASK_NO)) + { + + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,FEC_XMIT_TASK_NO); + + bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);/*Disable tx ints*/ + + enet_driver[0].txInterrupts++; /* Tx int has occurred */ + + rtems_event_send(enet_driver[0].txDaemonTid, INTERRUPT_EVENT); + + } + + } + + + + + + /* + * Function: mpc5200_fec_retire_tbd + * + * Description: Soak up buffer descriptors that have been sent. + * + * Returns: void + * + * Notes: + * + */ +static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc) +{ + struct mbuf *n; + TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );; + /* + * Clear already transmitted BDs first. Will not work calling same + * from fecExceptionHandler(TFINT). + */ + + while ((sc->txBdActiveCount > 0) && + (bdRing[sc->txBdTail].Status == 0x0)) { + if (sc->txMbuf[sc->txBdTail] != NULL) { + /* + * NOTE: txMbuf can be NULL, if mbuf has been split into different BDs + */ + MFREE (sc->txMbuf[sc->txBdTail],n); + sc->txMbuf[sc->txBdTail] = NULL; + } + sc->txBdActiveCount--; + if(++sc->txBdTail >= sc->txBdCount) { + sc->txBdTail = 0; + } + } +} + + +static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) { + struct mpc5200_enet_struct *sc = ifp->if_softc; + struct mbuf *l = NULL; + int nAdded; + uint32_t status; + rtems_event_set events; + TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId ); + TaskBD1_t *thisBd; + TaskBD1_t *firstBd = NULL; + void *data_ptr; + size_t data_len; + + /* + * Free up buffer descriptors + */ + mpc5200_fec_retire_tbd(sc); + + /* + * Set up the transmit buffer descriptors. + * No need to pad out short packets since the + * hardware takes care of that automatically. + * No need to copy the packet to a contiguous buffer + * since the hardware is capable of scatter/gather DMA. + */ + nAdded = 0; + + for(;;) { + + /* + * Wait for buffer descriptor to become available. + */ + if((sc->txBdActiveCount + nAdded) == sc->txBdCount) { + + /* + * Clear old events + */ + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,FEC_XMIT_TASK_NO); + + /* + * Wait for buffer descriptor to become available. + * Note that the buffer descriptors are checked + * *before* * entering the wait loop -- this catches + * the possibility that a buffer descriptor became + * available between the `if' above, and the clearing + * of the event register. + * This is to catch the case where the transmitter + * stops in the middle of a frame -- and only the + * last buffer descriptor in a frame can generate + * an interrupt. + */ + mpc5200_fec_retire_tbd(sc); + + while((sc->txBdActiveCount + nAdded) == sc->txBdCount) { + bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO); + rtems_bsdnet_event_receive(INTERRUPT_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + mpc5200_fec_retire_tbd(sc); + } + } + + if(m->m_len == 0) { + /* + * Just toss empty mbufs + */ + struct mbuf *n; + MFREE(m, n); + m = n; + if(l != NULL) { + l->m_next = m; + } + } + else { + /* + * Flush the buffer for this descriptor + */ + /*rtems_cache_flush_multiple_data_lines((const void *)mtod(m, void *), m->m_len);*/ + /* + * Fill in the buffer descriptor, + * set "end of frame" bit in status, + * if last mbuf in chain + */ + thisBd = bdRing + sc->txBdHead; + /* + * FIXME: do not send interrupt after every frame + * doing this every quarter of BDs is much more efficent + */ + status = ((m->m_next == NULL) + ? TASK_BD_TFD | TASK_BD_INT + : 0); + /* + * Don't set the READY flag till the + * whole packet has been readied. + */ + if (firstBd != NULL) { + status |= (uint32)SDMA_BD_MASK_READY; + } + else { + firstBd = thisBd; + } + + data_ptr = mtod(m, void *); + data_len = (uint32)m->m_len; + sc->txMbuf[sc->txBdHead] = m; + /* go to next part in chain */ + l = m; + m = m->m_next; + + thisBd->DataPtr[0] = (uint32)data_ptr; + thisBd->Status = (status + |((uint32)SDMA_DRD_MASK_LENGTH & data_len)); + + nAdded++; + if(++(sc->txBdHead) == sc->txBdCount) { + sc->txBdHead = 0; + } + } + /* + * Set the transmit buffer status. + * Break out of the loop if this mbuf is the last in the frame. + */ + if(m == NULL) { + if(nAdded) { + firstBd->Status |= SDMA_BD_MASK_READY; + SDMA_TASK_ENABLE(SDMA_TCR, txTaskId); + sc->txBdActiveCount += nAdded; + } + break; + } + } /* end of for(;;) */ +} + + +/* + * Driver transmit daemon + */ +void mpc5200_fec_txDaemon(void *arg) + { + struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + struct mbuf *m; + rtems_event_set events; + + for(;;) + { + /* + * Wait for packet + */ + rtems_bsdnet_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events); + + /* + * Send packets till queue is empty + */ + for(;;) + { + + /* + * Get the next mbuf chain to transmit. + */ + IF_DEQUEUE(&ifp->if_snd, m); + + if (!m) + break; + + mpc5200_fec_sendpacket(ifp, m); + + } + + ifp->if_flags &= ~IFF_OACTIVE; + + } + + } + + +/* + * reader task + */ +static void mpc5200_fec_rxDaemon(void *arg){ + struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + struct mbuf *m; + struct ether_header *eh; + int rxBdIndex; + uint32_t status; + size_t size; + rtems_event_set events; + uint16 len = 1; + TaskBD1_t *bd; + void *dptr; + TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( rxTaskId );; + + /* + * Input packet handling loop + */ + rxBdIndex = 0; + + for (;;) { + /* + * Clear old events + */ + SDMA_CLEAR_IEVENT(&mpc5200.IntPend,FEC_RECV_TASK_NO); + /* + * Get the first BD pointer and its length. + */ + bd = bdRing + rxBdIndex; + status = bd->Status; + len = (uint16)GET_BD_LENGTH( bd ); + + /* + * Loop through BDs until we find an empty one. This indicates that + * the SmartDMA is still using it. + */ + while( !(status & SDMA_BD_MASK_READY) ) { + + /* + * Remember the data pointer from this transfer. + */ + dptr = (void *)bd->DataPtr[0]; + m = sc->rxMbuf[rxBdIndex]; + m->m_len = m->m_pkthdr.len = (len + - sizeof(uint32_t) + - sizeof(struct ether_header)); + eh = mtod(m, struct ether_header *); + m->m_data += sizeof(struct ether_header); + ether_input(ifp, eh, m); + + /* + * Done w/ the BD. Clean it. + */ + sc->rxMbuf[rxBdIndex] = NULL; + + /* + * Add a new buffer to the ring. + */ + MGETHDR (m, M_WAIT, MT_DATA); + MCLGET (m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + size = ETHER_MAX_LEN; + + sc->rxMbuf[rxBdIndex] = m; + bd->DataPtr[0] = (uint32)mtod(m, void *); + bd->Status = ( ( (uint32)SDMA_DRD_MASK_LENGTH & (uint32)size) + | ((uint32)SDMA_BD_MASK_READY)); + + /* + * advance to next BD + */ + if (++rxBdIndex >= sc->rxBdCount) { + rxBdIndex = 0; + } + /* + * Get next BD pointer and its length. + */ + bd = bdRing + rxBdIndex; + status = bd->Status; + len = (uint16)GET_BD_LENGTH( bd ); + } + /* + * Unmask RXF (Full frame received) event + */ + bestcomm_glue_irq_enable(FEC_RECV_TASK_NO); + + rtems_bsdnet_event_receive (INTERRUPT_EVENT, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + + } +} + + +/* + * Function: mpc5200_fec_initialize_hardware + * + * Description: Configure the MPC5200 FEC registers and enable the + * SmartComm tasks. This function "turns on" the driver. + * + * Returns: void + * + * Notes: + * + */ +static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc) + { + int timeout; + unsigned short phyAddr = 0; + + /* + * Reset mpc5200 FEC + */ + mpc5200_fec_reset(sc); + + /* + * Clear FEC-Lite interrupt event register (IEVENT) + */ + mpc5200.ievent = FEC_INTR_CLEAR_ALL; + + /* + * Set interrupt mask register + */ + mpc5200.imask = (FEC_INTR_HBEEN + | FEC_INTR_BREN + | FEC_INTR_BTEN + | FEC_INTR_GRAEN + | FEC_INTR_LATE_COL + | FEC_INTR_COL_RETRY + | FEC_INTR_XFIFO_UN + | FEC_INTR_XFIFO_ERR + | FEC_INTR_RFIFO_ERR + | FEC_INTR_TFINT + ); + /* + * Set FEC-Lite receive control register (R_CNTRL) + * frame length=1518, MII mode for 18-wire-transceiver + */ + mpc5200.r_cntrl = ((ETHER_MAX_LEN << FEC_RCNTRL_MAX_FL_SHIFT) + | FEC_RCNTRL_FCE + | FEC_RCNTRL_MII_MODE); + + /* + * Set FEC-Lite transmit control register (X_CNTRL) + * full-duplex, heartbeat disabled + */ + mpc5200.x_cntrl = FEC_XCNTRL_FDEN; + + + + /* + * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(33Mhz) + * and do not drop the Preamble. + */ + mpc5200.mii_speed = (7 << 1); /* ipb_clk = 33 MHz */ + + /* + * Set Opcode/Pause Duration Register + */ + mpc5200.op_pause = 0x00010020; + + /* + * Set Rx FIFO alarm and granularity value + */ + mpc5200.rfifo_cntrl = (FEC_FIFO_CNTRL_FRAME + | (0x7 << FEC_FIFO_CNTRL_GR_SHIFT)); + mpc5200.rfifo_alarm = 0x0000030c; + + /* + * Set Tx FIFO granularity value + */ + mpc5200.tfifo_cntrl = (FEC_FIFO_CNTRL_FRAME + | (0x7 << FEC_FIFO_CNTRL_GR_SHIFT)); + + /* + * Set transmit fifo watermark register (X_WMRK), default = 64 + */ + mpc5200.tfifo_alarm = 0x00000100; /* 256 bytes */ + mpc5200.x_wmrk = FEC_XWMRK_256; /* 256 bytes */ + + /* + * Set individual address filter for unicast address + * and set physical address registers. + */ + mpc5200_eth_addr_filter_set(sc); + + /* + * Set multicast address filter + */ + mpc5200.gaddr1 = 0x00000000; + mpc5200.gaddr2 = 0x00000000; + + /* + * enable CRC in finite state machine register + */ + mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM; + + /* + * Initialize PHY(LXT971A): + * + * Generally, on power up, the LXT971A reads its configuration + * pins to check for forced operation, If not cofigured for + * forced operation, it uses auto-negotiation/parallel detection + * to automatically determine line operating conditions. + * If the PHY device on the other side of the link supports + * auto-negotiation, the LXT971A auto-negotiates with it + * using Fast Link Pulse(FLP) Bursts. If the PHY partner does not + * support auto-negotiation, the LXT971A automatically detects + * the presence of either link pulses(10Mbps PHY) or Idle + * symbols(100Mbps) and sets its operating conditions accordingly. + * + * When auto-negotiation is controlled by software, the following + * steps are recommended. + * + * Note: + * The physical address is dependent on hardware configuration. + * + */ + + /* + * Reset PHY, then delay 300ns + */ + mpc5200_eth_mii_write(sc, phyAddr, 0x0, 0x8000); + + rtems_task_wake_after(2); + + /* MII100 */ + + /* + * Set the auto-negotiation advertisement register bits + */ + mpc5200_eth_mii_write(sc, phyAddr, 0x4, 0x01e1); + + /* + * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation + */ + mpc5200_eth_mii_write(sc, phyAddr, 0x0, 0x1200); + + /* + * Wait for AN completion + */ + timeout = 0x100; +#if 0 + do + { + + rtems_task_wake_after(2); + + if((timeout--) == 0) + { + +#if defined(ETH_DEBUG) + printf ("MPC5200FEC PHY auto neg failed." "\r\n"); +#endif + + } + + if(mpc5200_eth_mii_read(sc, phyAddr, 0x1, &phyStatus) != TRUE) + { + +#if defined(ETH_DEBUG) + printf ("MPC5200FEC PHY auto neg failed: 0x%04x." "\r\n", phyStatus); +#endif + + return; + + } + + } while((phyStatus & 0x0020) != 0x0020); + +#endif +#if ETH_PROMISCOUS_MODE + mpc5200.r_cntrl |= 0x00000008; // set to promiscous mode +#endif + +#if ETH_LOOP_MODE + mpc5200.r_cntrl |= 0x00000001; // set to loop mode +#endif + +#if defined(ETH_DEBUG) + int i; + /* + * Print PHY registers after initialization. + */ + for(i = 0; i < 9; i++) + { + + mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus); + printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus); + + } + + for(i = 16; i < 21; i++) + { + + mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus); + printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus); + + } +#endif /* ETH_DEBUG */ + + } + + +/* + * Send packet (caller provides header). + */ +static void mpc5200_fec_tx_start(struct ifnet *ifp) + { + + struct mpc5200_enet_struct *sc = ifp->if_softc; + + ifp->if_flags |= IFF_OACTIVE; + + rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT); + + } + + +/* + * set up sdma tasks for ethernet + */ +static void mpc5200_sdma_task_setup(void) { + TaskSetupParamSet_t rxParam; /* RX task setup parameters */ + TaskSetupParamSet_t txParam; /* TX task setup parameters */ + + /* + * Setup the SDMA RX task. + */ + rxParam.NumBD = SDMA_BD_RX_NUM; + rxParam.Size.MaxBuf = ETHER_MAX_LEN; + rxParam.Initiator = 0; + rxParam.StartAddrSrc = (uint32)&(mpc5200.rfifo_data); + rxParam.IncrSrc = 0; + rxParam.SzSrc = sizeof(uint32_t); + rxParam.StartAddrDst = (uint32)NULL; + rxParam.IncrDst = sizeof(uint32_t); + rxParam.SzDst = sizeof(uint32_t); + rxTaskId = TaskSetup(TASK_FEC_RX,&rxParam ); + + /* + * Setup the TX task. + */ + txParam.NumBD = SDMA_BD_TX_NUM; + txParam.Size.MaxBuf = ETHER_MAX_LEN; + txParam.Initiator = 0; + txParam.StartAddrSrc = (uint32)NULL; + txParam.IncrSrc = sizeof(uint32_t); + txParam.SzSrc = sizeof(uint32_t); + txParam.StartAddrDst = (uint32)&(mpc5200.tfifo_data); + txParam.IncrDst = 0; + txParam.SzDst = sizeof(uint32_t); + + txTaskId = TaskSetup( TASK_FEC_TX, &txParam ); + +} + + +/* + * Initialize and start the device + */ +static void mpc5200_fec_init(void *arg) +{ + struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + + if(sc->txDaemonTid == 0) + { + /* + * Allocate a set of mbuf pointers + */ + sc->rxMbuf = + malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT); + sc->txMbuf = + malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT); + + if(!sc->rxMbuf || !sc->txMbuf) + rtems_panic ("No memory for mbuf pointers"); + + bestcomm_glue_init(); + + mpc5200_sdma_task_setup(); + + /* + * Set up interrupts + */ + bestcomm_glue_irq_install(FEC_RECV_TASK_NO, + mpc5200_smartcomm_rx_irq_handler, + NULL); + bestcomm_glue_irq_install(FEC_XMIT_TASK_NO, + mpc5200_smartcomm_tx_irq_handler, + NULL); + /* mpc5200_fec_tx_bd_init(sc); */ + mpc5200_fec_rx_bd_init(sc); + + /* + * reset and Set up mpc5200 FEC hardware + */ + mpc5200_fec_initialize_hardware(sc); + /* + * Set priority of different initiators + */ + mpc5200.IPR0 = 7; /* always initiator */ + mpc5200.IPR3 = 6; /* eth rx initiator */ + mpc5200.IPR4 = 5; /* eth tx initiator */ + + /* + * Start driver tasks + */ + sc->txDaemonTid = rtems_bsdnet_newproc("FEtx", 4096, mpc5200_fec_txDaemon, sc); + sc->rxDaemonTid = rtems_bsdnet_newproc("FErx", 4096, mpc5200_fec_rxDaemon, sc); + /* + * Clear SmartDMA task interrupt pending bits. + */ + TaskIntClear( rxTaskId ); + + /* + * Enable the SmartDMA receive task. + */ + TaskStart( rxTaskId, 1, rxTaskId, 1 ); + TaskStart( txTaskId, 1, txTaskId, 1 ); + /* + * Enable FEC-Lite controller + */ + mpc5200.ecntrl |= (FEC_ECNTRL_OE | FEC_ECNTRL_EN); + + + } + + /* + * Set flags appropriately + */ + if(ifp->if_flags & IFF_PROMISC) + mpc5200.r_cntrl |= 0x08; + else + mpc5200.r_cntrl &= ~0x08; + + /* + * Tell the world that we're running. + */ + ifp->if_flags |= IFF_RUNNING; +} + + +static void enet_stats (struct mpc5200_enet_struct *sc) +{ + printf (" Rx Interrupts:%-8lu", sc->rxInterrupts); + printf (" Not First:%-8lu", sc->rxNotFirst); + printf (" Not Last:%-8lu\n", sc->rxNotLast); + printf (" Giant:%-8lu", sc->rxGiant); + printf (" Non-octet:%-8lu\n", sc->rxNonOctet); + printf (" Bad CRC:%-8lu", sc->rxBadCRC); + printf (" Overrun:%-8lu", sc->rxOverrun); + printf (" Collision:%-8lu\n", sc->rxCollision); + + printf (" Tx Interrupts:%-8lu", sc->txInterrupts); + printf (" Deferred:%-8lu", sc->txDeferred); + printf (" Late Collision:%-8lu\n", sc->txLateCollision); + printf (" Retransmit Limit:%-8lu", sc->txRetryLimit); + printf (" Underrun:%-8lu", sc->txUnderrun); + printf (" Misaligned:%-8lu\n", sc->txMisaligned); + +} + + +/* + * Driver ioctl handler + */ +static int mpc5200_fec_ioctl (struct ifnet *ifp, u_long command, caddr_t data) + { + struct mpc5200_enet_struct *sc = ifp->if_softc; + int error = 0; + + switch(command) + { + + case SIOCGIFADDR: + case SIOCSIFADDR: + + ether_ioctl(ifp, command, data); + + break; + + case SIOCSIFFLAGS: + + switch(ifp->if_flags & (IFF_UP | IFF_RUNNING)) + { + + case IFF_RUNNING: + + mpc5200_fec_off(sc); + + break; + + case IFF_UP: + + mpc5200_fec_init(sc); + + break; + + case IFF_UP | IFF_RUNNING: + + mpc5200_fec_off(sc); + mpc5200_fec_init(sc); + + break; + + default: + break; + + } + + break; + + case SIO_RTEMS_SHOW_STATS: + + enet_stats(sc); + + break; + + /* + * FIXME: All sorts of multicast commands need to be added here! + */ + default: + + error = EINVAL; + + break; + + } + + return error; + + } + + +/* + * Attach the MPC5200 fec driver to the system + */ +int rtems_mpc5200_fec_driver_attach(struct rtems_bsdnet_ifconfig *config) + { + struct mpc5200_enet_struct *sc; + struct ifnet *ifp; + int mtu; + int unitNumber; + char *unitName; + + /* + * Parse driver name + */ + if((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0) + return 0; + + /* + * Is driver free? + */ + if ((unitNumber <= 0) || (unitNumber > NIFACES)) + { + + printf ("Bad FEC unit number.\n"); + return 0; + + } + + sc = &enet_driver[unitNumber - 1]; + ifp = &sc->arpcom.ac_if; + + if(ifp->if_softc != NULL) + { + + printf ("Driver already in use.\n"); + return 0; + + } + + /* + * Process options + */ +#if NVRAM_CONFIGURE == 1 + + /* Configure from NVRAM */ + if(addr = nvram->ipaddr) + { + + /* We have a non-zero entry, copy the value */ + if(pAddr = malloc(INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT)) + config->ip_address = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1); + else + rtems_panic("Can't allocate ip_address buffer!\n"); + + } + + if(addr = nvram->netmask) + { + + /* We have a non-zero entry, copy the value */ + if (pAddr = malloc (INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT)) + config->ip_netmask = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1); + else + rtems_panic("Can't allocate ip_netmask buffer!\n"); + + } + + /* Ethernet address requires special handling -- it must be copied into + * the arpcom struct. The following if construct serves only to give the + * User Area NVRAM parameter the highest priority. + * + * If the ethernet address is specified in NVRAM, go ahead and copy it. + * (ETHER_ADDR_LEN = 6 bytes). + */ + if(nvram->enaddr[0] || nvram->enaddr[1] || nvram->enaddr[2]) + { + + /* Anything in the first three bytes indicates a non-zero entry, copy value */ + memcpy((void *)sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN); + + } + else + if(config->hardware_address) + { + + /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */ + memcpy((void *)sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); + } + else + { + /* There is no ethernet address provided, so it could be read + * from the Ethernet protocol block of SCC1 in DPRAM. + */ + rtems_panic("No Ethernet address specified!\n"); + } + +#else /* NVRAM_CONFIGURE != 1 */ + + if(config->hardware_address) + { + + memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); + + } + else + { + + /* There is no ethernet address provided, so it could be read + * from the Ethernet protocol block of SCC1 in DPRAM. + */ + rtems_panic("No Ethernet address specified!\n"); + + } + +#endif /* NVRAM_CONFIGURE != 1 */ +#ifdef HAS_UBOOT + if ((sc->arpcom.ac_enaddr[0] == 0) && + (sc->arpcom.ac_enaddr[1] == 0) && + (sc->arpcom.ac_enaddr[2] == 0)) { + memcpy((void *)sc->arpcom.ac_enaddr, uboot_bdinfo_ptr->bi_enetaddr, ETHER_ADDR_LEN); + } +#endif + if(config->mtu) + mtu = config->mtu; + else + mtu = ETHERMTU; + + if(config->rbuf_count) + sc->rxBdCount = config->rbuf_count; + else + sc->rxBdCount = RX_BUF_COUNT; + + if(config->xbuf_count) + sc->txBdCount = config->xbuf_count; + else + sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF; + + sc->acceptBroadcast = !config->ignore_broadcast; + + /* + * Set up network interface values + */ + ifp->if_softc = sc; + ifp->if_unit = unitNumber; + ifp->if_name = unitName; + ifp->if_mtu = mtu; + ifp->if_init = mpc5200_fec_init; + ifp->if_ioctl = mpc5200_fec_ioctl; + ifp->if_start = mpc5200_fec_tx_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST; + /*ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;*/ + + if(ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + /* + * Attach the interface + */ + if_attach(ifp); + + ether_ifattach(ifp); + + return 1; + } + + +int rtems_mpc5200_fec_driver_attach_detach(struct rtems_bsdnet_ifconfig *config, int attaching) +{ + if (attaching) { + return rtems_mpc5200_fec_driver_attach(config); + } + else { + return 0; + } +} + + diff --git a/c/src/lib/libbsp/powerpc/gen5200/nvram/m93cxx.h b/c/src/lib/libbsp/powerpc/gen5200/nvram/m93cxx.h new file mode 100644 index 0000000000..f043d696e3 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/nvram/m93cxx.h @@ -0,0 +1,180 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: m93cxx.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains definitions for the M93Cxx EEPROM devices | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: m93cxx.h */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS M93C64-based header file */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: M93C46 is a serial microwire EEPROM which contains */ +/* 1Kbit (128 bytes/64 words) of non-volatile memory. */ +/* The device can be configured for byte- or word- */ +/* access. The driver provides a file-like interface */ +/* to this memory. */ +/* */ +/* MPC5x00 PIN settings: */ +/* */ +/* PSC3_6 (output) -> MC93C46 serial data in (D) */ +/* PSC3_7 (input) -> MC93C46 serial data out (Q) */ +/* PSC3_8 (output) -> MC93C46 chip select input (S) */ +/* PSC3_9 (output) -> MC93C46 serial clock (C) */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: none */ +/* Module: */ +/* Project: */ +/* Version */ +/* Date: */ +/* Author: */ +/* Copyright: */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#ifndef __M93CXX_H__ +#define __M93CXX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +static void m93cxx_enable_write(void); +static void m93cxx_disable_write(void); +static void m93cxx_write_byte(uint32_t, uint8_t); +static uint8_t m93cxx_read_byte(uint32_t); +void wait_usec(unsigned long); + +#define M93CXX_MODE_WORD +/*#define M93C46_MODE_BYTE*/ +#define M93C46 +#define M93C46_NVRAM_SIZE 128 + +#define GPIO_PSC3_6 (1 << 12) +#define GPIO_PSC3_7 (1 << 13) +#define GPIO_PSC3_8 (1 << 26) +#define GPIO_PSC3_9 (1 << 26) + +#define START_BIT 0x1 +#define EWDS_OPCODE 0x0 +#define WRAL_OPCODE 0x1 +#define ERAL_OPCODE 0x2 +#define EWEN_OPCODE 0x3 +#define WRITE_OPCODE 0x4 +#define READ_OPCODE 0x8 +#define ERASE_OPCODE 0xC + +#define WAIT(i) wait_usec(i) + +#define ENABLE_CHIP_SELECT mpc5200.gpiosido |= GPIO_PSC3_8 +#define DISABLE_CHIP_SELECT mpc5200.gpiosido &= ~GPIO_PSC3_8 +#define SET_DATA_BIT_HIGH mpc5200.gpiosdo |= GPIO_PSC3_6 +#define SET_DATA_BIT_LOW mpc5200.gpiosdo &= ~GPIO_PSC3_6 + +#ifdef M93CXX_MODE_BYTE +#define GET_DATA_BYTE_SHIFT(val) ((val) |= ((mpc5200.gpiosdi & GPIO_PSC3_7) >> 13)); \ + ((val) <<= 1) +#define SET_DATA_BYTE_SHIFT(val) (((val) & 0x80) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \ + ((val) <<= 1) +#else +#define GET_DATA_WORD_SHIFT(val) ((val) |= ((mpc5200.gpiosdi & GPIO_PSC3_7) >> 13)); \ + ((val) <<= 1) +#define SET_DATA_WORD_SHIFT(val) (((val) & 0x8000) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \ + ((val) <<= 1) +#endif + +#define MASK_HEAD_SHIFT(head) ((((head) & 0x80000000) >> 31) ? (mpc5200.gpiosdo |= GPIO_PSC3_6) : (mpc5200.gpiosdo &= ~GPIO_PSC3_6)); \ + ((head) <<= 1) +#define DO_CLOCK_CYCLE mpc5200.gpiowdo |= GPIO_PSC3_9; \ + WAIT(1000); \ + mpc5200.gpiowdo &= ~GPIO_PSC3_9 +#define CHECK_WRITE_BUSY while(!(mpc5200.gpiosdi & GPIO_PSC3_7)) + + +#ifdef M93CXX_MODE_BYTE +#ifdef M93C46 +#define M93C46_EWDS ((START_BIT << 31) | (EWDS_OPCODE << 27)) +#define M93C46_WRAL ((START_BIT << 31) | (WRAL_OPCODE << 27)) +#define M93C46_ERAL ((START_BIT << 31) | (ERAL_OPCODE << 27)) +#define M93C46_EWEN ((START_BIT << 31) | (EWEN_OPCODE << 27)) +#define M93C46_READ(addr) ((START_BIT << 31) | (READ_OPCODE << 27) | ((addr) << 22)) +#define M93C46_WRITE(addr) ((START_BIT << 31) | (WRITE_OPCODE << 27) | ((addr) << 22)) +#define M93C46_ERASE(addr) ((START_BIT << 31) | (ERASE_OPCODE << 27) | ((addr) << 22)) +#define M93C46_CLOCK_CYCLES 10 +#endif +#else +#ifdef M93C46 +#define M93C46_EWDS ((START_BIT << 31) | (EWDS_OPCODE << 27)) +#define M93C46_WRAL ((START_BIT << 31) | (WRAL_OPCODE << 27)) +#define M93C46_ERAL ((START_BIT << 31) | (ERAL_OPCODE << 27)) +#define M93C46_EWEN ((START_BIT << 31) | (EWEN_OPCODE << 27)) +#define M93C46_READ(addr) ((START_BIT << 31) | (READ_OPCODE << 27) | ((addr) << 23)) +#define M93C46_WRITE(addr) ((START_BIT << 31) | (WRITE_OPCODE << 27) | ((addr) << 23)) +#define M93C46_ERASE(addr) ((START_BIT << 31) | (ERASE_OPCODE << 27) | ((addr) << 23)) +#define M93C46_CLOCK_CYCLES 9 +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __M93CXX_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.c b/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.c new file mode 100644 index 0000000000..85b2c4a13e --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.c @@ -0,0 +1,622 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: nvram.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the nvram functions | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: nvram.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS M93C64-based NV memory device driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: M93C46 is a serial microwire EEPROM which contains */ +/* 1Kbit (128 bytes/64 words) of non-volatile memory. */ +/* The device can be coigured for byte- or word- */ +/* access. The driver provides a file-like interface */ +/* to this memory. */ +/* */ +/* MPC5x00 PIN settings: */ +/* */ +/* PSC3_6 (output) -> MC93C46 serial data in (D) */ +/* PSC3_7 (input) -> MC93C46 serial data out (Q) */ +/* PSC3_8 (output) -> MC93C46 chip select input (S) */ +/* PSC3_9 (output) -> MC93C46 serial clock (C) */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: DS1307-based Non-Volatile memory device driver */ +/* Module: nvram.c */ +/* Project: RTEMS 4.6.0pre1 / MCF5206Elite BSP */ +/* Version 1.2 */ +/* Date: 11/04/2002 */ +/* Author: Victor V. Vengerov */ +/* Copyright: Copyright (C) 2000 OKTET Ltd.,St.-Petersburg,Russia */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include <rtems.h> +#include <rtems/libio.h> +#include <errno.h> +#include <string.h> +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include "../include/mpc5200.h" +/*#include "../nvram/nvram.h"*/ +#include "../nvram/nvram.h" +#include "../nvram/m93cxx.h" +#include <stdio.h> + +/* + * Simple usec delay function using lower half of HARPO Time Base Register + */ +void wait_usec(unsigned long usec) + { + unsigned long start_count = 0, update_count; + unsigned long delay_count; + + if(TMBASE_CLOCK < 1000000) + delay_count = (TMBASE_CLOCK * usec )/1000000; + else + delay_count = (TMBASE_CLOCK / 1000000) * usec; + + TBL_READ(start_count); + + update_count = start_count; + + while((update_count - start_count) < delay_count) + TBL_READ(update_count); + + } + + +/* + * Enable M93Cxx chip-write + */ +static void m93cxx_enable_write() + { + uint32_t header, i; + + ENABLE_CHIP_SELECT; + + WAIT(1); + + header = M93C46_EWEN; + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + DISABLE_CHIP_SELECT; + + return; + + } + + +/* + * Disable M93Cxx chip-write + */ +static void m93cxx_disable_write() + { + uint32_t header, i; + + ENABLE_CHIP_SELECT; + + WAIT(1); + + header = M93C46_EWDS; + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + DISABLE_CHIP_SELECT; + + return; + + } + + +/* + * Read one byte from specified offset + */ +static uint8_t m93cxx_read_byte(uint32_t offset) + { + uint8_t byte2read; + uint32_t header, tmp_offset, i; +#ifdef M93CXX_MODE_BYTE + uint8_t byte_recv = 0; +#else + uint32_t word_recv = 0; +#endif + + ENABLE_CHIP_SELECT; + + WAIT(1); + +#ifdef M93CXX_MODE_BYTE + + header = M93C46_READ(offset); + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + for(i = 0; i < 8; i++) + { + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + GET_DATA_BYTE_SHIFT(byte_recv); + + } + + byte_recv >>= 1; + + byte2read = byte_recv; + +#else + tmp_offset = offset/2; + + header = M93C46_READ(tmp_offset); + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + for(i = 0; i < 16; i++) + { + + DO_CLOCK_CYCLE; + + WAIT(1); + + GET_DATA_WORD_SHIFT(word_recv); + + WAIT(1); + + } + + word_recv >>= 1; + + if(offset%2) + { + + byte2read = (uint8_t)((word_recv & 0xFF00) >> 8); + +#ifdef NVRAM_DEBUG + printf("\nbyte_read(o) = %x", byte2read); +#endif + + } + else + { + + byte2read = (uint8_t)(word_recv & 0x00FF); + +#ifdef NVRAM_DEBUG + printf("\nbyte_read(e) = %x", byte2read); +#endif + } + +#endif + + WAIT(1); + + DISABLE_CHIP_SELECT; + + return byte2read; + + } + + +/* + * Write one byte to specified offset + */ +void m93cxx_write_byte(uint32_t offset, uint8_t byte2write) + { + uint32_t header, tmp_offset, i; +#ifdef M93CXX_MODE_BYTE + uint8_t byte_send; +#else + uint16_t word_send; +#endif + + ENABLE_CHIP_SELECT; + + WAIT(1); + +#ifdef M93CXX_MODE_BYTE + header = M93C46_WRITE(offset); + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + byte_send = byte2write; + + for(i = 0; i < 8; i++) + { + + SET_DATA_BYTE_SHIFT(byte_send); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + } +#else + + if(offset%2) + { + + word_send = (uint16_t)m93cxx_read_byte(offset-1); + word_send |= (uint16_t)(m93cxx_read_byte(offset) << 8); + + } + else + { + + word_send = (uint16_t)m93cxx_read_byte(offset); + word_send |= (uint16_t)(m93cxx_read_byte(offset + 1) << 8); + + } + + tmp_offset = offset/2; + + WAIT(1); + + ENABLE_CHIP_SELECT; + + WAIT(1); + + header = M93C46_WRITE(tmp_offset); + + for(i = 0; i < M93C46_CLOCK_CYCLES; i++) + { + + MASK_HEAD_SHIFT(header); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + if(offset%2) + { + + word_send = (word_send & 0x00FF) | ((uint16_t)(byte2write << 8)); + +#ifdef NVRAM_DEBUG + printf("\nword_send = %x", word_send); +#endif + + } + else + { + + word_send = (word_send & 0xFF00) | (uint16_t)byte2write; +#ifdef NVRAM_DEBUG + printf("\nword_send = %x", word_send); +#endif + + } + + for(i = 0; i < 16; i++) + { + + SET_DATA_WORD_SHIFT(word_send); + + WAIT(1); + + DO_CLOCK_CYCLE; + + WAIT(1); + + } + + DISABLE_CHIP_SELECT; + + WAIT(1); + + ENABLE_CHIP_SELECT; + + WAIT(1); + + CHECK_WRITE_BUSY; + +#endif + + WAIT(1); + + DISABLE_CHIP_SELECT; + + return; + + } + + +/* nvram_driver_initialize -- + * Non-volatile memory device driver initialization. + */ +rtems_device_driver nvram_driver_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + rtems_status_code sc; + + /* enable PSC3_6/PSC3_7 as general purpose pins */ + mpc5200.gpiosen |= (GPIO_PSC3_6 | GPIO_PSC3_7); + + /* PSC3_6/PSC3_7 has normal CMOS output */ + mpc5200.gpiosod &= ~(GPIO_PSC3_6 | GPIO_PSC3_7); + + /* switch PSC3_6 (MC93C46 serial data in (D)) to low */ + mpc5200.gpiosdo &= ~GPIO_PSC3_6; + + /* PSC3_6 is an output (MC93C46 serial data in (D)) and PSC3_7 (MC93C46 serial data out (Q)) is an input pin */ + mpc5200.gpiosdd |= GPIO_PSC3_6; + mpc5200.gpiosdd &= ~GPIO_PSC3_7; + + /* disable PSC3_8 interrupt capabilities */ + mpc5200.gpiosiie &= ~GPIO_PSC3_8; + + /* enable PSC3_8 as general purpose pin */ + mpc5200.gpiosie |= GPIO_PSC3_8; + + /* PSC3_8 has normal CMOS output */ + mpc5200.gpiosiod &= ~GPIO_PSC3_8; + + /* switch PSC3_8 (MC93C46 chip select input (S)) to low (high activ) */ + mpc5200.gpiosido &= ~GPIO_PSC3_8; + + /* PSC3_8 is an output (MC93C46 chip select input (S)) pin */ + mpc5200.gpiosidd |= GPIO_PSC3_8; + + /* disable PSC3_9 interrupt capabilities */ + mpc5200.gpiowue &= ~GPIO_PSC3_9; + + /* enable PSC3_9 as general purpose pins */ + mpc5200.gpiowe |= GPIO_PSC3_9; + + /* PSC3_9 has normal CMOS output */ + mpc5200.gpiowod &= ~GPIO_PSC3_9; + + /* switch PSC3_9 (MC93C46 serial clock (C)) to low */ + mpc5200.gpiowdo &= ~GPIO_PSC3_9; + + /* PSC3_9 is an output (MC93C46 serial clock (C)) pin */ + mpc5200.gpiowdd |= GPIO_PSC3_9; + + sc = rtems_io_register_name("/dev/nvram", major, 0); + + if(sc != RTEMS_SUCCESSFUL) + { + + errno = EIO; + /*errno = ENODEV;*/ + return RTEMS_UNSATISFIED; + + } + else + return RTEMS_SUCCESSFUL; + + } + + +/* nvram_driver_open -- + * Non-volatile memory device driver open primitive. + */ +rtems_device_driver nvram_driver_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + + return RTEMS_SUCCESSFUL; + + } + + +/* nvram_driver_close -- + * Non-volatile memory device driver close primitive. + */ +rtems_device_driver nvram_driver_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + + return RTEMS_SUCCESSFUL; + + } + + +/* nvram_driver_read -- + * Non-volatile memory device driver read primitive. + */ +rtems_device_driver nvram_driver_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + rtems_libio_rw_args_t *args = arg; + uint32_t count, i; + +#ifdef NVRAM_DEBUG + printf("\nread count = %2x", (int)(args->count)); + printf("\nread offset = %2x", (int)(args->offset)); +#endif + + if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE)) + { + + args->bytes_moved = 0; + errno = EINVAL; + return RTEMS_UNSATISFIED; + + } + else + count = args->count; + + for(i = 0; i < count; i++) + { + + (args->buffer)[i] = m93cxx_read_byte((args->offset) + i); + (args->bytes_moved) += 1; + + } + + return RTEMS_SUCCESSFUL; + + } + + +/* nvram_driver_write -- + * Non-volatile memory device driver write primitive. + */ +rtems_device_driver nvram_driver_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) + { + rtems_libio_rw_args_t *args = arg; + uint32_t count, i; + +#ifdef NVRAM_DEBUG + printf("\nwrite count = %2x", (int)(args->count)); + printf("\nwrite offset = %2x", (int)(args->offset)); +#endif + + if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE)) + { + + args->bytes_moved = 0; + errno = EINVAL; + return RTEMS_UNSATISFIED; + + } + else + count = args->count; + + m93cxx_enable_write(); + + WAIT(1); + + for(i = 0; i < count; i++) + { + + m93cxx_write_byte((args->offset) + i, (args->buffer)[i]); + (args->bytes_moved) += 1; + + } + + WAIT(1); + + m93cxx_disable_write(); + + return RTEMS_SUCCESSFUL; + + } diff --git a/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.h b/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.h new file mode 100644 index 0000000000..80c47aea25 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/nvram/nvram.h @@ -0,0 +1,158 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: nvram.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the nvram declarations | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.3 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: nvram.h */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS M93C64-based header file */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: M93C46 is a serial microwire EEPROM which contains */ +/* 1Kbit (128 bytes/64 words) of non-volatile memory. */ +/* The device can be configured for byte- or word- */ +/* access. The driver provides a file-like interface */ +/* to this memory. */ +/* */ +/* MPC5x00 PIN settings: */ +/* */ +/* PSC3_6 (output) -> MC93C46 serial data in (D) */ +/* PSC3_7 (input) -> MC93C46 serial data out (Q) */ +/* PSC3_8 (output) -> MC93C46 chip select input (S) */ +/* PSC3_9 (output) -> MC93C46 serial clock (C) */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: DS1307-based Non-Volatile memory device driver */ +/* Module: nvram.h */ +/* Project: RTEMS 4.6.0pre1 / MCF5206Elite BSP */ +/* Version 1.1 */ +/* Date: 10/26/2001 */ +/* Author: Victor V. Vengerov */ +/* Copyright: Copyright (C) 2000 OKTET Ltd.,St.-Petersburg,Russia */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#ifndef __NVRAM_H__ +#define __NVRAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* include "../include/bsp.h" */ +#include "../include/bsp.h" + +/* Macros for TBL read access */ +#define TBL_READ(count) __asm__ volatile ("mftb %0\n" : "=r" (count) : "0" (count)) +#define TMBASE_CLOCK (G2_CLOCK/4) + +/* Simple usec delay function prototype */ +void wait_usec(unsigned long); + +/* nvram_driver_initialize -- + * Non-volatile memory device driver initialization. + */ +rtems_device_driver +nvram_driver_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +/* nvram_driver_open -- + * Non-volatile memory device driver open primitive. + */ +rtems_device_driver +nvram_driver_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +/* nvram_driver_close -- + * Non-volatile memory device driver close primitive. + */ +rtems_device_driver +nvram_driver_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +/* nvram_driver_read -- + * Non-volatile memory device driver read primitive. + */ +rtems_device_driver +nvram_driver_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +/* nvram_driver_write -- + * Non-volatile memory device driver write primitive. + */ +rtems_device_driver +nvram_driver_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +#ifdef __cplusplus +} +#endif + +#endif /* __NVRAM_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.c b/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.c new file mode 100644 index 0000000000..173e4c3891 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.c @@ -0,0 +1,385 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: slicetimer.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains functions to implement a slice timer | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.7 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: slicetimer.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 slicetimer driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: MPC5x00 slice timer routines for cyclic short time */ +/* trigger */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: Clock driver for PPC403 */ +/* Module: clock.c */ +/* Project: RTEMS 4.6.0pre1 / PPC403 BSP */ +/* Version 1.16 */ +/* Date: 2002/11/01 */ +/* Author(s) / Copyright(s): */ +/* */ +/* Author: Jay Monkman (jmonkman@frasca.com) */ +/* Copyright (C) 1998 by Frasca International, Inc. */ +/* */ +/* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c: */ +/* */ +/* Author: Andrew Bray <andy@i-cubed.co.uk> */ +/* */ +/* COPYRIGHT (c) 1995 by i-cubed ltd. */ +/* */ +/* To anyone who acknowledges that this file is provided "AS IS" */ +/* without any express or implied warranty: */ +/* permission to use, copy, modify, and distribute this file */ +/* for any purpose is hereby granted without fee, provided that */ +/* the above copyright notice and this notice appears in all */ +/* copies, and that the name of i-cubed limited not be used in */ +/* advertising or publicity pertaining to distribution of the */ +/* software without specific, written prior permission. */ +/* i-cubed limited makes no representations about the suitability */ +/* of this software for any purpose. */ +/* */ +/* Derived from c/src/lib/libcpu/hppa1.1/clock/clock.c: */ +/* */ +/* Modifications for deriving timer clock from cpu system clock by */ +/* Thomas Doerfler <td@imd.m.isar.de> */ +/* for these modifications: */ +/* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany. */ +/* */ +/* COPYRIGHT (c) 1989-1999. */ +/* On-Line Applications Research Corporation (OAR). */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/* Modifications for PPC405GP by Dennis Ehlin */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include <rtems/bspIo.h> +/*#include "../irq/irq.h"*/ +#include "../irq/irq.h" + +#include <rtems.h> +#include <rtems/clockdrv.h> +#include <rtems/libio.h> + +#include "../include/bsp.h" +#include "../irq/irq.h" +#include "../include/mpc5200.h" +#include "../slicetimer/slicetimer.h" +#include <stdio.h> + +uint32_t value0 = 0; +uint32_t value1 = 0; + +/* + * ISR Handlers + */ +void mpc5200_slt_isr(uint32_t slt_no) + { + uint32_t status; + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + status = slt->tsr; + + if(status & SLT_TSR_ST) + { + + slt->tsr |= SLT_TSR_ST; + + /*if(slt_no == SLT0) + slt0_user_defined_handler */ + + /*if(slt_no == SLT1) + slt1_user_defined_handler */ + + } + + } + + +rtems_isr mpc5200_slt0_isr(rtems_irq_hdl_param unused) + { + + mpc5200_slt_isr(SLT0); + + } + + +rtems_isr mpc5200_slt1_isr(rtems_irq_hdl_param unused) + { + + mpc5200_slt_isr(SLT1); + + } + + +/* + * Initialize MPC5x00 slt + */ +void mpc5200_init_slt(uint32_t slt_no) + { + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + slt->tsr = SLT_TSR_ST; + slt->cntrl = SLT_CNTRL_RW; + + } + + +/* + * Set MPC5x00 slt counter + */ +void mpc5200_set_slt_count(uint32_t slt_no) + { + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + if(slt_no == SLT0) + /* Calculate counter value 24 bit (must be greater than 255) => IPB_Clock=33MHz -> Int. every 7,75us - 508ms */ + if((SLT_TSR_COUNT(SLT0_INT_FREQUENCY) > 0xFF) && (SLT_TSR_COUNT(SLT0_INT_FREQUENCY) < 0x1000000)) + slt->tcr = SLT_TSR_COUNT(SLT0_INT_FREQUENCY); + + if(slt_no == SLT1) + /* Calculate counter value 24 bit (must be greater than 255) => IPB_Clock=33MHz -> Int. every 7,75us - 508ms */ + if((SLT_TSR_COUNT(SLT1_INT_FREQUENCY) > 0xFF) && (SLT_TSR_COUNT(SLT1_INT_FREQUENCY) < 0x1000000)) + slt->tcr = SLT_TSR_COUNT(SLT1_INT_FREQUENCY); + + } + + +/* + * Enable MPC5x00 slt interrupt + */ +void mpc5200_enable_slt_int(uint32_t slt_no) + { + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + slt->cntrl |= SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN; + + } + + +/* + * Disable MPC5x00 slt interrupt + */ +void mpc5200_disable_slt_int(uint32_t slt_no) + { + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + slt->cntrl &= ~(SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN); + + } + + +/* + * Check MPC5x00 slt status + */ +uint32_t mpc5200_check_slt_status(uint32_t slt_no) + { + struct mpc5200_slt *slt = (struct mpc5200_slt *)(&mpc5200.slt[slt_no]); + + if(((slt->cntrl) & (SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN)) == (SLT_CNTRL_TIMEN | SLT_CNTRL_INTEN)) + return 1; + else + return 0; + + } + +/* + * switch MPC5x00 slt on + */ +void sltOn(const rtems_irq_connect_data* irq) + { + uint32_t slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER0) + slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER1) + slt_no = 1; + + mpc5200_set_slt_count((uint32_t)slt_no); + mpc5200_enable_slt_int((uint32_t)slt_no); + + } + +/* + * switch MPC5x00 slt off + */ +void sltOff(const rtems_irq_connect_data* irq) + { + uint32_t slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER0) + slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER1) + slt_no = 1; + + mpc5200_disable_slt_int((uint32_t)slt_no); + + } + +/* + * get status of MPC5x00 slt + */ +int sltIsOn(const rtems_irq_connect_data* irq) + { + uint32_t slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER0) + slt_no = 0; + + if((irq->name) == BSP_SIU_IRQ_SL_TIMER1) + slt_no = 1; + + if(mpc5200_check_slt_status(slt_no)) + return 1; + else + return 0; + } + +/* + * MPC5x00 slt0 irq connect data + */ +static rtems_irq_connect_data slt0_IrqData = + { + BSP_SIU_IRQ_SL_TIMER0, + mpc5200_slt0_isr, + (rtems_irq_hdl_param) NULL, + (rtems_irq_enable)sltOn, + (rtems_irq_disable)sltOff, + (rtems_irq_is_enabled)sltIsOn + }; + +/* + * MPC5x00 slt1 irq connect data + */ +static rtems_irq_connect_data slt1_IrqData = + { + BSP_SIU_IRQ_SL_TIMER1, + mpc5200_slt1_isr, + (rtems_irq_hdl_param) NULL, + (rtems_irq_enable)sltOn, + (rtems_irq_disable)sltOff, + (rtems_irq_is_enabled)sltIsOn + }; + +/* + * call MPC5x00 slt install routines + */ +void Install_slt(rtems_device_minor_number slt_no) + { + + mpc5200_init_slt((uint32_t)slt_no); + mpc5200_set_slt_count((uint32_t)slt_no); + + } + +/* + * MPC5x00 slt device driver initialize + */ +rtems_device_driver slt_initialize + ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp + ) + { + + /* force minor according to definitions in bsp.h */ + if(USE_SLICETIMER_0) + { + + Install_slt(0); + + if(!BSP_install_rtems_irq_handler(&slt0_IrqData)) + { + + printk("Unable to connect PSC Irq handler\n"); + rtems_fatal_error_occurred(1); + + } + + } + + if(USE_SLICETIMER_1) + { + + Install_slt(1); + + if(!BSP_install_rtems_irq_handler(&slt1_IrqData)) + { + + printk("Unable to connect PSC Irq handler\n"); + rtems_fatal_error_occurred(1); + + } + + } + + return RTEMS_SUCCESSFUL; + + } + diff --git a/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.h b/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.h new file mode 100644 index 0000000000..822135ba86 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/slicetimer/slicetimer.h @@ -0,0 +1,86 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: slicetimer.h ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file declares functions to use the slice timer module ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +#ifndef __SLICETIMER_H__ +#define __SLICETIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SLT0 0 +#define SLT1 1 + +#define SLT0_INT_FREQUENCY 10000 +#define SLT1_INT_FREQUENCY 0 + +#define SLT_CNTRL_RW (1 << 26) +#define SLT_CNTRL_INTEN (1 << 25) +#define SLT_CNTRL_TIMEN (1 << 24) + +#define SLT_TSR_ST (1 << 24) + +#define SLT_TSR_COUNT(freq) ((freq) ? ((IPB_CLOCK)/(freq)) : (0xFFFFFF)) + +rtems_device_driver slt_initialize( rtems_device_major_number, + rtems_device_minor_number, + void * + ); + +#define SLTIME_DRIVER_TABLE_ENTRY \ + { slt_initialize, NULL, NULL, \ + NULL, NULL, NULL } + +void mpc5200_slt_isr(uint32_t); +rtems_isr mpc5200_slt0_isr(rtems_irq_hdl_param); +rtems_isr mpc5200_slt1_isr(rtems_irq_hdl_param); +void mpc5200_init_slt(uint32_t); +void mpc5200_set_slt_count(uint32_t); +void mpc5200_enable_slt_int(uint32_t); +void mpc5200_disable_slt_int(uint32_t); +uint32_t mpc5200_check_slt_status(uint32_t); +/*void sltOn(const rtems_irq_connect_data *); +void sltOff(const rtems_irq_connect_data *); +int sltIsOn(const rtems_irq_connect_data *);*/ +void Install_slt(rtems_device_minor_number); + +#ifdef __cplusplus +} +#endif + +#endif /* __SLICETIMER_H__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/start/start.S b/c/src/lib/libbsp/powerpc/gen5200/start/start.S new file mode 100644 index 0000000000..b09fcdcb57 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/start/start.S @@ -0,0 +1,917 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the startup assembly code | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.10 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.9 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: start.S */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 CPU assembly startup */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This file contains the assembler portion of MPC5x00 */ +/* startup code */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: startup code for Motorola PQII ADS board */ +/* Module: start.S */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 04/18/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Modified for the Motorola PQII ADS board by */ +/* Andy Dachs <a.dachs@sstl.co.uk> 23-11-00. */ +/* Surrey Satellite Technology Limited */ +/* */ +/* I have a proprietary bootloader programmed into the flash */ +/* on the board which initialises the SDRAM prior to calling */ +/* this function. */ +/* */ +/* This file is based on the one by Jay Monkman (jmonkman@fracsa.com)*/ +/* which in turn was based on the dlentry.s file for the Papyrus BSP,*/ +/* written by: */ +/* */ +/* Author: Andrew Bray <andy@i-cubed.co.uk> */ +/* */ +/* COPYRIGHT (c) 1995 by i-cubed ltd. */ +/* */ +/* To anyone who acknowledges that this file is provided "AS IS" */ +/* without any express or implied warranty: */ +/* permission to use, copy, modify, and distribute this file */ +/* for any purpose is hereby granted without fee, provided that */ +/* the above copyright notice and this notice appears in all */ +/* copies, and that the name of i-cubed limited not be used in */ +/* advertising or publicity pertaining to distribution of the */ +/* software without specific, written prior permission. */ +/* i-cubed limited makes no representations about the suitability */ +/* of this software for any purpose. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include <rtems/asm.h> +#include <rtems/powerpc/cache.h> +#include <rtems/powerpc/registers.h> +#include "../include/mpc5200.h" +#include "../include/bsp.h" + +/* Macro definitions to load a register with a 32-bit address. + Both functions identically. Sometimes one mnemonic is more + appropriate than the other. + reg -> register to load + value -> value to be loaded + LA reg,value ("Load Address") + LWI reg,value ("Load Word Immediate") */ + +.macro LA reg, value + lis \reg , \value@h + ori \reg , \reg, \value@l + sync +.endm + +.macro LWI reg, value + lis \reg , \value@h + ori \reg , \reg, \value@l + sync +.endm + +/* Macro definitions to test, set or clear a single + bit or bit pattern in a given 32bit GPR. + reg1 -> register content to be tested + reg2 -> 2nd register only needed for computation + mask -> any bit pattern */ + +.macro TSTBITS reg1, reg2, mask /* Match is indicated by EQ=0 (CR) */ + LWI \reg2, \mask /* Unmatch is indicated by EQ=1 (CR) */ + and \reg1, \reg1, \reg2 + cmplw \reg1, \reg2 + sync +.endm + +.macro SETBITS reg1, reg2, mask + LWI \reg2, \mask + or \reg1, \reg1, \reg2 + sync +.endm + +.macro CLRBITS reg1, reg2, mask + LWI \reg2, \mask + andc \reg1, \reg1, \reg2 + sync +.endm + +/* Some register offsets of MPC5x00 memory map registers */ +.set CS0STR, 0x04 +.set CS0STP, 0x08 +.set CS1STR, 0x0C +.set CS1STP, 0x10 +.set SDRAMCS0, 0x34 +.set SDRAMCS1, 0x38 +.set BOOTSTR, 0x4C +.set BOOTSTP, 0x50 +.set ADREN, 0x54 +.set CSSR0, 0x58 /* Critical Interrupt SSR0 (603le only) */ +.set CSSR1, 0x59 /* Critical Interrupt SSR1 (603le only) */ +.set CFG, 0x20C +.set CSBOOTROM, 0x300 +.set CSCONTROL, 0x318 +.set CS1CONF, 0x304 + + +/* Register offsets of MPC5x00 SDRAM memory controller registers */ +.set MOD, 0x100 +.set CTRL, 0x104 +.set CFG1, 0x108 +.set CFG2, 0x10C +.set ADRSEL, 0x110 + +/* Register offsets of MPC5x00 GPIO registers needed */ +.set GPIOPCR, 0xb00 +.set GPIOWE, 0xc00 +.set GPIOWOD, 0xc04 +.set GPIOWDD, 0xc08 +.set GPIOWDO, 0xc0c + +.set GPIOSEN, 0xb04 +.set GPIOSDD, 0xb0c +.set GPIOSDO, 0xb10 + +/* Register offsets of MPC5x00 Arbiter registers */ +.set ARBCFG, 0x1f40 +.set ARBMPREN, 0x1f64 +.set ARBMPRIO, 0x1f68 +.set ARBSNOOP, 0x1f70 + +/* Some bit encodings for MGT5100 registers */ +.set ADREN_SDRAM_EN, (1<<22) +.set ADREN_BOOT_EN, (1<<25) +.set ADREN_CS0_EN, (1<<16) +.set ADREN_CS1_EN, (1<<17) + +.set CTRL_PRECHARGE, (1<<1) +.set CTRL_REFRESH, (1<<2) +.set CTRL_BA1, (1<<31) + +.set CSCONF_CE, (1<<12) + +/* Some fixed values for MPC5x00 registers */ +.set CSBOOTROM_VAL, 0x0101D910 +.set CSCONTROL_VAL, 0x91000000 +.set CFG_VAL, 0x00000100 + +.extern _bss_start +.extern _bss_size +.extern _data_start +.extern _data_size +.extern _text_start +.extern _text_size +/*.extern _s_got*/ +.extern boot_card +.extern MBAR + +.section ".entry" +PUBLIC_VAR (start) +start: +/* 1st: initialization work (common for RAM/ROM startup) */ + mfmsr r30 + SETBITS r30, r29, MSR_ME|MSR_RI + CLRBITS r30, r29, MSR_EE + mtmsr r30 /* Set RI/ME, Clr EE in MSR */ + +#if defined(HAS_UBOOT) +/* store pointer to UBoot bd_info board info structure */ + LWI r31,uboot_bdinfo_ptr + stw r3,0(r31) +#endif /* defined(HAS_UBOOT) */ + +#if defined(NEED_LOW_LEVEL_INIT) +/* initialize the MBAR (common RAM/ROM startup) */ + LWI r31, MBAR_RESET + LWI r29, MBAR + rlwinm r30, r29,16,16,31 + stw r30, 0(r31) /* Set the MBAR */ +#endif + + LWI r31, MBAR /* set r31 to current MBAR */ + /* init GPIOPCR */ + lwz r29,GPIOPCR(r31) + LWI r30, GPIOPCR_INITMASK + not r30,r30 + and r29,r29,r30 + LWI r30, GPIOPCR_INITVAL + or r29,r29,r30 + stw r29, GPIOPCR(r31) + +/* further initialization work (common RAM/ROM startup) */ + bl TLB_init /* Initialize TLBs */ + + + bl FID_DCache /* Flush, inhibit and disable data cache */ + + + bl IDUL_ICache /* Inhibit, disable and unlock instruction cache */ + + + bl FPU_init /* Initialize FPU */ + + +#if defined(NEED_LOW_LEVEL_INIT) + bl SPRG_init /* Initialize special purpose registers */ +#endif + +#if defined(NEED_LOW_LEVEL_INIT) +/* detect RAM/ROM startup (common for RAM/ROM startup) */ + LWI r20, ROM_START /* set the relocation offset */ + + + LWI r30, CFG_VAL /* get CFG register content */ + lwz r30, CFG(r31) /* set SDRAM single data rate / XLB_CLK=FVCO/4 / IPB_CLK=XLB_CLK/2 / PCICLK=IPB_CLK */ + + + + lwz r30, ADREN(r31) /* get content of ADREN */ + + + + TSTBITS r30, r29, ADREN_BOOT_EN + bne skip_ROM_start /* If BOOT_ROM is not enabled, skip further initialization */ + +/* do some board dependent configuration (unique for ROM startup) */ + bl SPRG_brk_init /* Initialize special purpose onchip breakpoint registers */ + + + LWI r30, CSCONTROL_VAL /* get CSCONTROL register content */ + stw r30, CSCONTROL(r31) /* enable internal/external bus error and master for CS */ + + + +#ifdef RSM5LOG + LWI r30, CSBOOTROM_VAL + stw r30, CSBOOTROM(r31) /* Set CSBOOTROM */ + + +#endif + + + /* FIXME: map BOOT ROM into final location with CS0 registers */ + LWI r30, ROM_START + rlwinm r30, r30,17,15,31 + stw r30, CS0STR(r31) /* Set CS0STR */ + + LWI r30, ROM_END + rlwinm r30, r30,17,15,31 + stw r30, CS0STP(r31) /* Set CS0STP */ + + lwz r30, ADREN(r31) /* get content of ADREN */ + SETBITS r30, r29, ADREN_CS0_EN + stw r30, ADREN(r31) /* enable CS0 mapping */ + isync + /* jump to same code in final BOOT ROM location */ + LWI r30, reloc_in_CS0 + LWI r29, RAM_START + sub r30,r30,r29 + LWI r29, ROM_START + add r30,r30,r29 + mtctr r30 + bctr + +reloc_in_CS0: + /* disable CSBOOT (or map it to CS0 range) */ + lwz r30, ADREN(r31) /* get content of ADREN */ + CLRBITS r30, r29, ADREN_BOOT_EN + stw r30, ADREN(r31) /* disable BOOT mapping */ + + /* init SDRAM */ + LWI r30, RAM_START + ori r30,r30,0x1a /* size code: bank is 128MByte */ + stw r30,SDRAMCS0(r31) /* Set SDRAMCS0 */ + + LWI r30,(RAM_END+1-RAM_START)/2 + ori r30,r30,0x1a /* size code: bank is 128MByte */ + stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */ + + bl SDRAM_init /* Initialize SDRAM controller */ + +/* init arbiter and stuff... */ + LWI r30, 0x8000a06e + stw r30, ARBCFG(r31) /* Set ARBCFG */ + + LWI r30, 0x000000ff + stw r30, ARBMPREN(r31) /* Set ARBMPREN */ + + LWI r30, 0x00001234 + stw r30, ARBMPRIO(r31) /* Set ARBPRIO */ + + LWI r30, 0x0000001e + stw r30, ARBSNOOP(r31) /* Set ARBSNOOP */ +/* copy .text section from ROM to RAM location (unique for ROM startup) */ + LA r30, _text_start /* get start address of text section in RAM */ + + + add r30, r20, r30 /* get start address of text section in ROM (add reloc offset) */ + + + LA r29, _text_start /* get start address of text section in RAM */ + + + LA r28, _text_size /* get size of RAM image */ + + + bl copy_image /* copy text section from ROM to RAM location */ + + +/* copy .data section from ROM to RAM location (unique for ROM startup) */ + LA r30, _data_start /* get start address of data section in RAM */ + + + add r30, r20, r30 /* get start address of data section in ROM (add reloc offset) */ + + + LA r29, _data_start /* get start address of data section in RAM */ + + + LA r28, _data_size /* get size of RAM image */ + + + bl copy_image /* copy initialized data section from ROM to RAM location */ + + + LA r29, remap_rom /* get compile time address of label */ + mtlr r29 + + blrl /* now further execution RAM */ + +remap_rom: +/* remap BOOT ROM to CS0 (common for RAM/ROM startup) */ + lwz r30, CSBOOTROM(r31) /* get content of CSBOOTROM */ + + + + CLRBITS r30, r29, CSCONF_CE + stw r30, CSBOOTROM(r31) /* disable BOOT CS */ + + + + lwz r30, ADREN(r31) /* get content of ADREN */ + + + + mr r29, r30 /* move content of r30 to r29 */ + + + LWI r30, ADREN_BOOT_EN /* mask ADREN_BOOT_EN */ + andc r29,r29,r30 + + + LWI r30, ADREN_CS0_EN /* unmask ADREN_CS0_EN */ + or r29,r29,r30 + + + stw r29,ADREN(r31) /* Simultaneous enable CS0 and disable BOOT address space */ + + + + lwz r30, CSBOOTROM(r31) /* get content of CSBOOTROM */ + + + + SETBITS r30, r29, CSCONF_CE + stw r30, CSBOOTROM(r31) /* disable BOOT CS */ + + + +skip_ROM_start: +/* configure external DPRAM CS1 */ + LWI r30,0xFFFFFB10 + stw r30,CS1CONF(r31) + +/* map external DPRAM (CS1) */ + LWI r30,(DPRAM_START>>16) + stw r30,CS1STR(r31) + + LWI r30,((DPRAM_END)>>16) + stw r30,CS1STP(r31) + + lwz r30, ADREN(r31) /* get content of ADREN */ + + LWI r29, ADREN_CS1_EN /* unmask ADREN_CS1_EN */ + or r30,r30,r29 + + stw r30,ADREN(r31) /* enable CS1 */ + +/* clear entire on chip SRAM (unique for ROM startup) */ + LWI r30, (MBAR+ONCHIP_SRAM_OFFSET) /* get start address of onchip SRAM */ + LWI r29, ONCHIP_SRAM_SIZE /* get size of onchip SRAM */ + + bl clr_mem /* Clear onchip SRAM */ + +#endif /* defined(RSM5LOG) */ +/* clear .bss section (unique for ROM startup) */ + LWI r30, _bss_start /* get start address of bss section */ + LWI r29, _bss_size /* get size of bss section */ + + + bl clr_mem /* Clear the bss section */ + + +/* set stack pointer (common for RAM/ROM startup) */ + LA r1, _text_start + addi r1, r1, -0x10 /* Set up stack pointer = beginning of text section - 0x10 */ + + +/* enable dynamic power management(common for RAM/ROM startup) */ + bl PPC_HID0_rd /* Get the content of HID0 */ + + SETBITS r30, r29, HID0_DPM + bl PPC_HID0_wr /* Set DPM in HID0 */ + +/* clear arguments and do further init. in C (common for RAM/ROM startup) */ + xor r3, r3, r3 + xor r4, r4, r4 /* Clear argc and argv */ + +#if 1 + bl SYM (boot_card) /* Call the first C routine */ +#endif + +#if defined(BRS5L) +twiddle: + b twiddle /* We don't expect to return from boot_card but if we do */ + /* wait here for watchdog to kick us into hard reset */ + +SDRAM_init: +#if defined (BRS5L) + /* set GPIO_WKUP7 pin low for 66MHz buffering */ + /* or high for 133MHz registered buffering */ + LWI r30, 0x80000000 + + lwz r29, GPIOWE(r31) + or r29,r29,r30 /* set bit 0 in r29/GPIOWE */ + stw r29,GPIOWE(r31) + + lwz r29, GPIOWOD(r31) + andc r29,r29,r30 /* clear bit 0 in r29/GPIOWOD */ + stw r29,GPIOWOD(r31) + + lwz r29, GPIOWDO(r31) + andc r29,r29,r30 /* clear bit 0 in r29/GPIOWDO */ + stw r29,GPIOWDO(r31) + + lwz r29, GPIOWDD(r31) + or r29,r29,r30 /* set bit 0 in r29/GPIOWDD */ + stw r29,GPIOWDD(r31) + + /* activate MEM_CS1 output */ + lwz r29, GPIOPCR(r31) + or r29,r29,r30 /* set bit 0 in r29/GPIOPCR */ + stw r29,GPIOPCR(r31) + +#endif +#if 0 + LWI r30, 0xC2222600 /* Single Read2Read/Write delay=0xC, Single Write2Read/Prec. delay=0x2 */ + stw r30, CFG1(r31) /* Read CAS latency=0x2, Active2Read delay=0x2, Prec.2active delay=0x2 */ + /* Refr.2No-Read delay=0x06, Write latency=0x0 */ +#else + /* See Erratum 342/339 in MPC5200_Errata_L25R_3_June.pdf: */ + /* set 5 delays to their maximum to support two banks */ + LWI r30, 0xCC222600 /* Single Read2Read/Write delay=0xC, Single Write2Read/Prec. delay=0x2 */ + stw r30, CFG1(r31) /* Read CAS latency=0x2, Active2Read delay=0x2, Prec.2active delay=0x2 */ + /* Refr.2No-Read delay=0x06, Write latency=0x0 */ +#endif + + LWI r30, 0xCCC70004 /* Burst2Read Prec.delay=0x8, Burst Write delay=0x8 */ + stw r30, CFG2(r31) /* Burst Read2Write delay=0xB, Burst length=0x7, Read Tap=0x4 */ + +#ifdef RSM5LOG + LWI r30, 0xD1470000 /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */ + stw r30, CTRL(r31) /* Refresh counter=0xFFFF */ + + +#else + LWI r30, 0xD04F0000 /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */ + stw r30, CTRL(r31) /* Refresh counter=0xFFFF */ + + +#endif + lwz r30, CTRL(r31) + + + SETBITS r30, r29, CTRL_PRECHARGE /* send two times precharge */ + stw r30, CTRL(r31) + + + stw r30, CTRL(r31) + + + + lwz r30, CTRL(r31) + + + SETBITS r30, r29, CTRL_REFRESH /* send two times refresh */ + stw r30, CTRL(r31) + + + stw r30, CTRL(r31) + + + + LWI r30, 0x008D0000 /* Op.Mode=0x0, Read CAS latency=0x2, Burst length=0x3, Write strobe puls */ + stw r30, MOD(r31) + + + + lwz r30, CTRL(r31) /* Clock enabled, Auto refresh enabled, Mem. data drv. Refresh counter=0xFFFF */ + + + CLRBITS r30, r29, CTRL_BA1 + stw r30, CTRL(r31) + + + + blr + + +copy_image: + mr r27, r28 + srwi r28, r28, 2 + mtctr r28 + + + slwi r28, r28, 2 + sub r27, r27, r28 /* maybe some residual bytes */ + + +copy_image_word: + lswi r28, r30, 0x04 + + stswi r28, r29, 0x04 /* do word copy ROM -> RAM */ + + + addi r30, r30, 0x04 /* increment source pointer */ + addi r29, r29, 0x04 /* increment destination pointer */ + + bdnz copy_image_word /* decrement ctr and branch if not 0 */ + + cmpwi r27, 0x00 /* copy image finished ? */ + beq copy_image_end; + mtctr r27 /* reload counter for residual bytes */ +copy_image_byte: + lswi r28, r30, 0x01 + + stswi r28, r29, 0x01 /* do byte copy ROM -> RAM */ + + + addi r30, r30, 0x01 /* increment source pointer */ + addi r29, r29, 0x01 /* increment destination pointer */ + + bdnz copy_image_byte /* decrement ctr and branch if not 0 */ + +copy_image_end: + blr +#endif /* defined(RSM5LOG) */ + +FID_DCache: + mflr r26 + + bl PPC_HID0_rd + TSTBITS r30, r29, HID0_DCE + bne FID_DCache_exit /* If data cache is switched of, skip further actions */ + + li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */ + LWI r28, _text_start /* Load base address (begin of RAM) */ + +FID_DCache_loop_1: + lwz r27, 0(r28) /* Load data at address */ + + addi r28, r28, PPC_CACHE_ALIGNMENT /* increment cache line address */ + subi r29, r29, PPC_CACHE_ALIGNMENT /* increment loop counter */ + cmpwi r29, 0x0 + bne FID_DCache_loop_1 /* Loop until cache size is reached */ + + li r29, PPC_D_CACHE /* 16 Kb data cache on 603e */ + LWI r28, _text_start /* Reload base address (begin of RAM) */ + xor r27, r27, r27 +FID_DCache_loop_2: + + dcbf r27, r28 /* Flush and invalidate cache */ + + addi r28, r28, PPC_CACHE_ALIGNMENT /* increment cache line address */ + subi r29, r29, PPC_CACHE_ALIGNMENT /* increment loop counter */ + cmpwi r29, 0x0 + bne FID_DCache_loop_2 /* Loop around until cache size is reached */ + + bl PPC_HID0_rd /* Read HID0 */ + CLRBITS r30, r29, HID0_DCE + bl PPC_HID0_wr /* Clear DCE */ + +FID_DCache_exit: + mtlr r26 + blr + +IDUL_ICache: + mflr r26 + + bl PPC_HID0_rd + TSTBITS r30, r29, HID0_ICE + bne IDUL_ICache_exit /* If instruction cache is switched of, skip further actions */ + + CLRBITS r30, r29, HID0_ICE + bl PPC_HID0_wr /* Disable ICE bit */ + + SETBITS r30, r29, HID0_ICFI + bl PPC_HID0_wr /* Invalidate instruction cache */ + + CLRBITS r30, r29, HID0_ICFI + bl PPC_HID0_wr /* Disable cache invalidate */ + + CLRBITS r30, r29, HID0_ILOCK + bl PPC_HID0_wr /* Disable instruction cache lock */ + +IDUL_ICache_exit: + mtlr r26 + blr + + +TLB_init: /* Initialize translation lookaside buffers (TLBs) */ + xor r30, r30, r30 + xor r29, r29, r29 + +TLB_init_loop: + tlbie r29 + tlbsync + addi r29, r29, 0x1000 + addi r30, r30, 0x01 + cmpli 0, 0, r30, 0x0080 + bne TLB_init_loop + blr + +FPU_init: + mfmsr r30 /* get content of MSR */ + + + SETBITS r30, r29, MSR_FP + mtmsr r30 /* enable FPU and FPU exceptions */ + +#if 0 + LA r29, RAM_START + stw r29, 0x0(r29) +#endif + + lfd f0, 0(r29) + fmr f1, f0 + fmr f2, f0 + fmr f3, f0 + fmr f4, f0 + fmr f5, f0 + fmr f6, f0 + fmr f7, f0 + fmr f8, f0 + fmr f9, f0 + fmr f10, f0 + fmr f11, f0 + fmr f12, f0 + fmr f13, f0 + fmr f14, f0 + fmr f15, f0 + fmr f16, f0 + fmr f17, f0 + fmr f18, f0 + fmr f19, f0 + fmr f20, f0 + fmr f21, f0 + fmr f22, f0 + fmr f23, f0 + fmr f24, f0 + fmr f25, f0 + fmr f26, f0 + fmr f27, f0 + fmr f28, f0 + fmr f29, f0 + fmr f30, f0 + fmr f31, f0 + + + mtfsfi 0, 0 /* initialize bit positons in FPSCR */ + mtfsfi 1, 0 + mtfsfi 2, 0 + mtfsfi 3, 0 + mtfsfi 4, 0 + mtfsfi 5, 0 + mtfsfi 6, 0 + mtfsfi 7, 0 + + + CLRBITS r30, r29, MSR_FP /* disable FPU and FPU exceptions */ + mtmsr r30 + + blr + +SPRG_init: /* initialize registers */ + xor r30, r30, r30 + + mtspr XER, r30 + mtspr CTR, r30 + mtspr DSISR, r30 + mtspr DAR, r30 + mtspr DEC, r30 + mtspr SDR1, r30 + mtspr SRR0, r30 + mtspr SRR1, r30 + mtspr CSSR0, r30 + mtspr CSSR1, r30 + mtspr SPRG0, r30 + mtspr SPRG1, r30 + mtspr SPRG2, r30 + mtspr SPRG3, r30 + mtspr SPRG4, r30 + mtspr SPRG5, r30 + mtspr SPRG6, r30 + mtspr SPRG7, r30 + mtspr EAR, r30 + mtspr TBWU, r30 + mtspr TBWL, r30 + mtspr IBAT0U, r30 + mtspr IBAT0L, r30 + mtspr IBAT1U, r30 + mtspr IBAT1L, r30 + mtspr IBAT2U, r30 + mtspr IBAT2L, r30 + mtspr IBAT3U, r30 + mtspr IBAT3L, r30 + mtspr IBAT4U, r30 + mtspr IBAT4L, r30 + mtspr IBAT5U, r30 + mtspr IBAT5L, r30 + mtspr IBAT6U, r30 + mtspr IBAT6L, r30 + mtspr IBAT7U, r30 + mtspr IBAT7L, r30 + mtspr DBAT0U, r30 + mtspr DBAT0L, r30 + mtspr DBAT1U, r30 + mtspr DBAT1L, r30 + mtspr DBAT2U, r30 + mtspr DBAT2L, r30 + mtspr DBAT3U, r30 + mtspr DBAT3L, r30 + mtspr DBAT4U, r30 + mtspr DBAT4L, r30 + mtspr DBAT5U, r30 + mtspr DBAT5L, r30 + mtspr DBAT6U, r30 + mtspr DBAT6L, r30 + mtspr DBAT7U, r30 + mtspr DBAT7L, r30 + mtspr DMISS, r30 + mtspr DCMP, r30 + mtspr HASH1, r30 + mtspr HASH2, r30 + mtspr IMISS, r30 + mtspr ICMP, r30 + mtspr RPA, r30 + mtsr SR0, r30 + mtsr SR1, r30 + mtsr SR2, r30 + mtsr SR3, r30 + mtsr SR4, r30 + mtsr SR5, r30 + mtsr SR6, r30 + mtsr SR7, r30 + mtsr SR8, r30 + mtsr SR9, r30 + mtsr SR10, r30 + mtsr SR12, r30 + mtsr SR13, r30 + mtsr SR14, r30 + mtsr SR15, r30 + + + + + + blr + +SPRG_brk_init: + xor r30, r30, r30 + + mtspr DABR2, r30 + mtspr DBCR, r30 + mtspr IBCR, r30 + mtspr IABR, r30 + mtspr HID2, r30 + mtspr DABR, r30 + mtspr IABR2, r30 + + + + + blr + + +PPC_HID0_rd: /* get HID0 content to r30 */ + + + mfspr r30, HID0 + + blr + + +PPC_HID0_wr: /* put r30 content to HID0 */ + + + mtspr HID0, r30 + + blr + +clr_mem: + mr r28, r29 + srwi r29, r29, 2 + mtctr r29 /* set ctr reg */ + + + slwi r29, r29, 2 + sub r28, r28, r29 /* maybe some residual bytes */ + xor r29, r29, r29 + + +clr_mem_word: + stswi r29, r30, 0x04 /* store r29 (word) to r30 memory location */ + addi r30, r30, 0x04 /* increment r30 */ + + bdnz clr_mem_word /* dec counter and loop */ + + + cmpwi r28, 0x00 /* clear mem. finished ? */ + beq clr_mem_end; + mtctr r28 /* reload counter for residual bytes */ +clr_mem_byte: + stswi r29, r30, 0x01 /* store r29 (byte) to r30 memory location */ + addi r30, r30, 0x01 /* update r30 */ + + bdnz clr_mem_byte /* dec counter and loop */ + +clr_mem_end: + blr /* return */ + + + diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c new file mode 100644 index 0000000000..f7a8ad2b59 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c @@ -0,0 +1,384 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the BSP initialization code | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.8 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.7 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: bspstart.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 C level startup code */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This routine starts the application. It includes */ +/* application, board, and monitor specific */ +/* initialization and configuration. The generic CPU */ +/* dependent initialization has been performed before */ +/* this routine is invoked. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: MPC8260ads C level startup code */ +/* Module: bspstart.c */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 04/17/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* The MPC860 specific stuff was written by Jay Monkman */ +/* (jmonkman@frasca.com) */ +/* */ +/* Modified for the MPC8260ADS board by Andy Dachs */ +/* <a.dachs@sstl.co.uk> */ +/* Surrey Satellite Technology Limited, 2001 */ +/* A 40MHz system clock is assumed. */ +/* The PON. RST.CONF. Dip switches (DS1) are */ +/* 1 - Off */ +/* 2 - On */ +/* 3 - Off */ +/* 4 - On */ +/* 5 - Off */ +/* 6 - Off */ +/* 7 - Off */ +/* 8 - Off */ +/* Dip switches on DS2 and DS3 are all set to ON */ +/* The LEDs on the board are used to signal panic and fatal_error */ +/* conditions. */ +/* The mmu is unused at this time. */ +/* */ +/* COPYRIGHT (c) 1989-1999. */ +/* On-Line Applications Research Corporation (OAR). */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" + +#include <rtems/libio.h> +#include <rtems/libcsupport.h> +#include <rtems/powerpc/powerpc.h> +#include <rtems/score/thread.h> + +#include <rtems/bspIo.h> +#include <libcpu/cpuIdent.h> +#include <libcpu/spr.h> +#include "../irq/irq.h" + +#include <string.h> + +#ifdef STACK_CHECKER_ON +#include <stackchk.h> +#endif + +#if defined(HAS_UBOOT) +bd_t *uboot_bdinfo_ptr = (bd_t *)1; /* will be overwritten from startup code */ +bd_t uboot_bdinfo_copy; /* will be overwritten with copy of bdinfo */ +#endif + +SPR_RW(SPRG0) +SPR_RW(SPRG1) + +/* + * The original table from the application (in ROM) and our copy of it with + * some changes. Configuration is defined in <confdefs.h>. Make sure that + * our configuration tables are uninitialized so that they get allocated in + * the .bss section (RAM). + */ +extern rtems_configuration_table Configuration; +extern unsigned long intrStackPtr; +rtems_configuration_table BSP_Configuration; +rtems_cpu_table Cpu_table; +char *rtems_progname; + + +/* + * Use the shared implementations of the following routines. + * Look in rtems/c/src/lib/libbsp/shared/bsppost.c and + * rtems/c/src/lib/libbsp/shared/bsplibc.c. + */ +void bsp_postdriver_hook(void); +void bsp_libc_init( void *, uint32_t, int ); +extern void initialize_exceptions(void); +extern void cpu_init(void); + +void BSP_panic(char *s) + { + printk("%s PANIC %s\n",_RTEMS_version, s); + __asm__ __volatile ("sc"); + } + +void _BSP_Fatal_error(unsigned int v) + { + printk("%s PANIC ERROR %x\n",_RTEMS_version, v); + __asm__ __volatile ("sc"); + } + +/* + * Function: bsp_pretasking_hook + * Created: 95/03/10 + * + * Description: + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + * + * NOTES: + * Must not use libc (to do io) from here, since drivers are + * not yet initialized. + * + */ + +void +bsp_pretasking_hook(void) +{ + /* + * These are assigned addresses in the linkcmds file for the BSP. This + * approach is better than having these defined as manifest constants and + * compiled into the kernel, but it is still not ideal when dealing with + * multiprocessor configuration in which each board as a different memory + * map. A better place for defining these symbols might be the makefiles. + * Consideration should also be given to developing an approach in which + * the kernel and the application can be linked and burned into ROM + * independently of each other. + */ + +#if defined(HAS_UBOOT) + extern unsigned char _HeapStart; + + bsp_libc_init( &_HeapStart, + uboot_bdinfo_ptr->bi_memstart + + uboot_bdinfo_ptr->bi_memsize + - (uint32_t)&_HeapStart + , 0 ); +#else + extern unsigned char _HeapStart; + extern unsigned char _HeapEnd; + + bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 ); +#endif + + +#ifdef STACK_CHECKER_ON + /* + * Initialize the stack bounds checker + * We can either turn it on here or from the app. + */ + + Stack_check_Initialize(); +#endif + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif +} + + + +void bsp_predriver_hook(void) + { +#if 0 + init_RTC(); + + init_PCI(); + initialize_universe(); + initialize_PCI_bridge (); + +#if (HAS_PMC_PSC8) + initialize_PMC(); +#endif + + /* + * Initialize Bsp General purpose vector table. + */ + initialize_external_exception_vector(); + +#if (0) + /* + * XXX - Modify this to write a 48000000 (loop to self) command + * to each interrupt location. This is better for debug. + */ + bsp_spurious_initialize(); +#endif + +#endif +} + + + +void bsp_start(void) +{ + extern void *_WorkspaceBase; + ppc_cpu_id_t myCpu; + ppc_cpu_revision_t myCpuRevision; + register unsigned char* intrStack; + + /* + * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function + * store the result in global variables so that it can be used latter... + */ + myCpu = get_ppc_cpu_type(); + myCpuRevision = get_ppc_cpu_revision(); + +#if defined(HAS_UBOOT) + uboot_bdinfo_copy = *uboot_bdinfo_ptr; + uboot_bdinfo_ptr = &uboot_bdinfo_copy; +#endif + cpu_init(); + + /* + * Initialize some SPRG registers related to irq handling + */ + + intrStack = (((unsigned char*)&intrStackPtr) - PPC_MINIMUM_STACK_FRAME_SIZE); + + _write_SPRG1((unsigned int)intrStack); + + /* Signal them that this BSP has fixed PR288 - eventually, this should go away */ + _write_SPRG0(PPC_BSP_HAS_FIXED_PR288); + + /* + * initialize the CPU table for this BSP + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + Cpu_table.predriver_hook = bsp_predriver_hook; /* init PCI / RTC ... */ + Cpu_table.postdriver_hook = bsp_postdriver_hook; + Cpu_table.clicks_per_usec = (IPB_CLOCK/1000000); + Cpu_table.do_zero_of_workspace = TRUE; + Cpu_table.exceptions_in_RAM = TRUE; + + if( Cpu_table.interrupt_stack_size < 4*1024 ) + Cpu_table.interrupt_stack_size = 4 * 1024; + + /* + * Install our own set of exception vectors + */ + + initialize_exceptions(); + + /* + * Enable instruction and data caches. Do not force writethrough mode. + */ +#if INSTRUCTION_CACHE_ENABLE + rtems_cache_enable_instruction(); +#endif +#if DATA_CACHE_ENABLE + rtems_cache_enable_data(); +#endif + + /* + * Allocate the memory for the RTEMS Work Space. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + + /* + * Need to "allocate" the memory for the RTEMS Workspace and + * tell the RTEMS configuration where it is. This memory is + * not malloc'ed. It is just "pulled from the air". + */ + BSP_Configuration.work_space_start = (void *)&_WorkspaceBase; + + + /* + BSP_Configuration.microseconds_per_tick = 1000; + */ + + /* + * Initalize RTEMS IRQ system + */ + BSP_rtems_irq_mng_init(0); + +#ifdef SHOW_MORE_INIT_SETTINGS + printk("Exit from bspstart\n"); +#endif + + } + +/* + * + * _Thread_Idle_body + * + * Replaces the one in c/src/exec/score/src/threadidlebody.c + * The MSR[POW] bit is set to put the CPU into the low power mode + * defined in HID0. HID0 is set during starup in start.S. + * + */ +Thread _Thread_Idle_body(uint32_t ignored ) + { + + for(;;) + { + + asm volatile("mfmsr 3; oris 3,3,4; sync; mtmsr 3; isync; ori 3,3,0; ori 3,3,0"); + + } + + return 0; + + } + diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c b/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c new file mode 100644 index 0000000000..6542123c44 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c @@ -0,0 +1,209 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the code to initialize the cpu | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.8 2005/12/09 09:05:16 thomas +|* changed names of board variations +|* +|* Revision 1.7 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* +|* Revision 1.6 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: cpuinit.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 C level startup code */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This file contains additional functions for */ +/* initializing the MPC5x00 CPU */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: MPC8260ads additional CPU initialization */ +/* Module: cpuinit.c */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.1 */ +/* Date: 10/22/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Written by Jay Monkman (jmonkman@frasca.com) */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include "../include/bsp.h" +#include <rtems/powerpc/registers.h> +#include "../include/mpc5200.h" + +#include <libcpu/mmu.h> +#include <libcpu/spr.h> +#include <string.h> + +/* Macros for HID0 access */ +#define SET_HID0(r) __asm__ volatile ("mtspr 0x3F0,%0\n" ::"r"(r)) +#define GET_HID0(r) __asm__ volatile ("mfspr %0,0x3F0\n" :"=r"(r)) + +#define DBAT_MTSPR(val,name) __MTSPR(val,name); +#define SET_DBAT(n,uv,lv) {DBAT_MTSPR(uv,DBAT##n##U);DBAT_MTSPR(lv,DBAT##n##L);} +void calc_dbat_regvals(BAT *bat_ptr, + uint32_t base_addr, + uint32_t size, + boolean flg_w, + boolean flg_i, + boolean flg_m, + boolean flg_g, + boolean flg_bpp) +{ + uint32_t block_mask; + uint32_t end_addr; + + /* + * determine block mask, that overlaps the whole block + */ + end_addr = base_addr+size-1; + block_mask = ~0; + while ((end_addr & block_mask) != (base_addr & block_mask)) { + block_mask <<= 1; + } + + bat_ptr->batu.bepi = base_addr >> (32-15); + bat_ptr->batu.bl = ~(block_mask >> (28-11)); + bat_ptr->batu.vs = 1; + bat_ptr->batu.vp = 1; + + bat_ptr->batl.brpn = base_addr >> (32-15); + bat_ptr->batl.w = flg_w; + bat_ptr->batl.i = flg_i; + bat_ptr->batl.m = flg_m; + bat_ptr->batl.g = flg_g; + bat_ptr->batl.pp = flg_bpp; +} + +void cpu_init(void) + { + register unsigned long reg; + BAT dbat; + + /* + * clear dbat + */ + memset(&dbat, 0,sizeof(dbat)); + + /* enable instruction cache */ + GET_HID0(reg); + reg |= HID0_ICE; + SET_HID0(reg); + + + /* + * set up DBAT registers in MMU + */ +#if defined (BRS5L) + calc_dbat_regvals(&dbat,RAM_START,RAM_SIZE,1,0,0,0,BPP_RW); + SET_DBAT(0,dbat.batu,dbat.batl); + + calc_dbat_regvals(&dbat,ROM_START,ROM_SIZE,1,0,0,0,BPP_RX); + SET_DBAT(1,dbat.batu,dbat.batl); + + calc_dbat_regvals(&dbat,MBAR,128*1024,1,1,1,1,BPP_RW); + SET_DBAT(2,dbat.batu,dbat.batl); + + calc_dbat_regvals(&dbat,DPRAM_START,128*1024,1,1,1,1,BPP_RW); + SET_DBAT(3,dbat.batu,dbat.batl); +#endif +#if defined (HAS_UBOOT) + calc_dbat_regvals(&dbat, + uboot_bdinfo_ptr->bi_memstart, + uboot_bdinfo_ptr->bi_memsize, + 1,0,0,0,BPP_RW); + SET_DBAT(0,dbat.batu,dbat.batl); + + calc_dbat_regvals(&dbat, + uboot_bdinfo_ptr->bi_flashstart, + uboot_bdinfo_ptr->bi_flashsize, + 1,0,0,0,BPP_RX); + SET_DBAT(1,dbat.batu,dbat.batl); + + calc_dbat_regvals(&dbat,MBAR,128*1024,1,1,1,1,BPP_RW); + SET_DBAT(2,dbat.batu,dbat.batl); + + if (uboot_bdinfo_ptr->bi_sramsize != 0) { + calc_dbat_regvals(&dbat, + uboot_bdinfo_ptr->bi_sramstart, + uboot_bdinfo_ptr->bi_sramsize, + 0,1,1,1,BPP_RW); + SET_DBAT(3,dbat.batu,dbat.batl); + } +#endif + + /* + * enable data MMU in MSR + */ + _write_MSR(_read_MSR() | MSR_DR); + +#if 1 /* TRACE32 now supports data cache for MGT5x00 */ + /* + * enable data cache + */ + GET_HID0(reg); + reg |= HID0_DCE; + SET_HID0(reg); +#endif + } diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds b/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds new file mode 100644 index 0000000000..d02ef4a720 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds @@ -0,0 +1,303 @@ +/* + * This file contains directives for the GNU linker which are specific + * to a gen5200 Board + * + * linkcmds,v 1.3 2003/01/20 19:53:27 joel Exp + */ + +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", + "elf32-powerpc") +OUTPUT_ARCH(powerpc) + SEARCH_DIR(/usr/local/rtems/powerpc-rtems/lib); + +ENTRY(start) + +/* + * Declare some sizes. + * XXX: The assignment of ". += XyzSize;" fails in older gld's if the + * number used there is not constant. If this happens to you, edit + * the lines marked XXX below to use a constant value. + */ +HeapSize = DEFINED(HeapSize) ? HeapSize : 0x6800000; /* 104M Heap */ +StackSize = DEFINED(StackSize) ? StackSize : 0x80000; /* 512 kB */ +WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */ +RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x80000; /* 512 ram disk */ + +MEMORY + { + ram : org = 0x0, l = 256M + mpc5200_regs : org = 0xF0000000, l = 24K + dpram : org = 0xFF000000, l = 0x400 + flash : org = 0xFFE00000, l = 2M + } + + +SECTIONS +{ + + .vectors 0x100 : + { + *(.vectors) + } + > ram + + /* + * The stack will live in this area - between the vectors and + * the text section. + */ + + .text 0x10000: + { + _textbase = .; + + + text.start = .; + + /* Entry point is the .entry section */ + *(.entry) + *(.entry2) + + /* Actual Code */ + *(.text) + *(.text.*) + + + *(.rodata*) + *(.rodata1) + + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + /* C++ constructors/destructors */ + *(.gnu.linkonce.t*) + + /* Initialization and finalization code. + * + * Various files can provide initialization and finalization functions. + * The bodies of these functions are in .init and .fini sections. We + * accumulate the bodies here, and prepend function prologues from + * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked + * first; ecrtn.o must be linked last. Because these are wildcards, it + * doesn't matter if the user does not actually link against ecrti.o and + * ecrtn.o; the linker won't look for a file to match a wildcard. The + * wildcard also means that it doesn't matter which directory ecrti.o + * and ecrtn.o are in. + */ + PROVIDE (_init = .); + *ecrti.o(.init) + *(.init) + *ecrtn.o(.init) + + PROVIDE (_fini = .); + *ecrti.o(.fini) + *(.fini) + *ecrtn.o(.init) + + /* + * C++ constructors and destructors for static objects. + * PowerPC EABI does not use crtstuff yet, so we build "old-style" + * constructor and destructor lists that begin with the list lenght + * end terminate with a NULL entry. + */ + + PROVIDE (__CTOR_LIST__ = .); + /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */ + *crtbegin.o(.ctors) + *(.ctors) + *crtend.o(.ctors) + LONG(0) + PROVIDE (__CTOR_END__ = .); + + PROVIDE (__DTOR_LIST__ = .); + /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */ + *crtbegin.o(.dtors) + *(.dtors) + *crtend.o(.dtors) + LONG(0) + PROVIDE (__DTOR_END__ = .); + + /* Exception frame info */ + *(.eh_frame) + + /* Miscellaneous read-only data */ + _rodata_start = . ; + *(.gnu.linkonce.r*) + *(.lit) + *(.shdata) + *(.rodata) + *(.rodata1) + *(.descriptors) + *(rom_ver) + _erodata = .; + + PROVIDE (__EXCEPT_START__ = .); + *(.gcc_except_table) + PROVIDE (__EXCEPT_END__ = .); + __GOT_START__ = .; + s.got = .; + *(.got.plt) + *(.got) + *(.got1) + PROVIDE (__GOT2_START__ = .); + PROVIDE (_GOT2_START_ = .); + *(.got2) + PROVIDE (__GOT2_END__ = .); + PROVIDE (_GOT2_END_ = .); + + PROVIDE (__FIXUP_START__ = .); + PROVIDE (_FIXUP_START_ = .); + *(.fixup) + PROVIDE (_FIXUP_END_ = .); + PROVIDE (__FIXUP_END__ = .); + + /* Various possible names for the end of the .text section */ + etext = ALIGN(0x10); + _etext = .; + _endtext = .; + text.end = .; + PROVIDE (etext = .); + PROVIDE (__etext = .); + + } > ram + + PROVIDE (__SDATA2_START__ = .); + .sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >ram + .sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >ram + PROVIDE (__SBSS2_END__ = .); + + .sbss2 : { *(.sbss2) } >ram + PROVIDE (__SBSS2_END__ = .); + + /* R/W Data */ + .data ( . ) : + { + . = ALIGN (4); + + data.start = .; + + *(.data) + *(.data1) + *(.data.* .gnu.linkonce.d.*) + PROVIDE (__SDATA_START__ = .); + *(.sdata) + *(.gnu.linkonce.s.*) + data.end = .; + } > ram + + __SBSS_START__ = .; + .bss : + { + bss.start = .; + *(.bss) *(.sbss) *(COMMON) + . = ALIGN(4); + bss.end = .; + } > ram + __SBSS_END__ = .; + + PROVIDE(_bss_start = ADDR(.bss)); + PROVIDE(_bss_size = SIZEOF(.bss)); + PROVIDE(_data_start = ADDR(.data)); + PROVIDE(_data_size = SIZEOF(.data)); + PROVIDE(_text_start = ADDR(.text)); + PROVIDE(_text_size = SIZEOF(.text)); + PROVIDE(_end = data.end); + + .gzipmalloc : { + . = ALIGN (16); + _startmalloc = .; + } >ram + + + /* + * Interrupt stack setup + */ + IntrStack_start = ALIGN(0x10); + . += 0x4000; + intrStack = .; + PROVIDE(intrStackPtr = intrStack); + + + + + _WorkspaceBase = .; + __WorkspaceBase = .; + . += WorkSpaceSize; + + _RamDiskBase = .; + __RamDiskBase = .; + . += RamDiskSize; + _RamDiskEnd = .; + __RamDiskEnd = .; + PROVIDE( _RamDiskSize = _RamDiskEnd - _RamDiskBase ); + + _HeapStart = .; + __HeapStart = .; + . += HeapSize; + _HeapEnd = .; + __HeapEnd = .; + + clear_end = .; + + /* Sections for compressed .text and .data */ + /* after the .datarom section is an int specifying */ + /* the length of the following compressed image */ + /* Executes once then could get overwritten */ + .textrom 0x100000 : + { + *(.textrom) + _endloader = .; + } > ram + + .datarom : + { + _dr_start = .; + *(.datarom) + _dr_end = .; + } > ram + dr_len = _dr_end - _dr_start; + + mpc5200_regs : + { + MBAR = .; + mpc5200 = .; + _mpc5200 = .; + . += (0x6000); + } > mpc5200_regs + + .dpram : + { + dp_ram = .; + _dp_ram = .; + . += (0x400); + } > dpram + + + /* the reset vector is at 0xfff00000 which is */ + /* located at offset 0x400000 from the base */ + /* of flash */ + .bootrom 0xFFE00000 : + { + *(.bootrom) + _endboot = .; + } > flash + + + .line 0 : { *(.line) } + .debug 0 : { *(.debug) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_aregion 0 : { *(.debug_aregion) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520 b/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520 new file mode 100644 index 0000000000..571b83170b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520 @@ -0,0 +1,316 @@ +/* + * This file contains directives for the GNU linker which are specific + * to a MicroSys PM520 Board + * + * linkcmds,v 1.3 2003/01/20 19:53:27 joel Exp + */ + +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", + "elf32-powerpc") +OUTPUT_ARCH(powerpc) + +ENTRY(start) + +/* + * Declare some sizes. + * XXX: The assignment of ". += XyzSize;" fails in older gld's if the + * number used there is not constant. If this happens to you, edit + * the lines marked XXX below to use a constant value. + */ +HeapSize = DEFINED(HeapSize) ? HeapSize : 0x100000; /* 1M Heap */ +StackSize = DEFINED(StackSize) ? StackSize : 0x80000; /* 512 kB */ +WorkSpaceSize = DEFINED(WorkSpaceSize) ? WorkSpaceSize : 0x80000; /* 512k */ +RamDiskSize = DEFINED(RamDiskSize) ? RamDiskSize : 0x80000; /* 512 ram disk */ + +MEMORY + { + ram : org = 0x0, l = 64M + mpc5200_regs : org = 0xF0000000, l = 24K + dpram : org = 0xFF000000, l = 0x400 + flash : org = 0xFFE00000, l = 2M + } + + +SECTIONS +{ + + .vectors 0x100 : + { + *(.vectors) + } + > ram + + /* + * The stack will live in this area - between the vectors and + * the text section. + */ + + .text 0x10000: + { + _textbase = .; + + + text.start = .; + + /* Entry point is the .entry section */ + *(.entry) + *(.entry2) + + /* Actual Code */ + *(.text) + *(.text.*) + + + *(.rodata*) + *(.rodata1) + + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + /* C++ constructors/destructors */ + *(.gnu.linkonce.t*) + + /* Initialization and finalization code. + * + * Various files can provide initialization and finalization functions. + * The bodies of these functions are in .init and .fini sections. We + * accumulate the bodies here, and prepend function prologues from + * ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked + * first; ecrtn.o must be linked last. Because these are wildcards, it + * doesn't matter if the user does not actually link against ecrti.o and + * ecrtn.o; the linker won't look for a file to match a wildcard. The + * wildcard also means that it doesn't matter which directory ecrti.o + * and ecrtn.o are in. + */ + PROVIDE (_init = .); + *ecrti.o(.init) + *(.init) + *ecrtn.o(.init) + + PROVIDE (_fini = .); + *ecrti.o(.fini) + *(.fini) + *ecrtn.o(.init) + + /* + * C++ constructors and destructors for static objects. + * PowerPC EABI does not use crtstuff yet, so we build "old-style" + * constructor and destructor lists that begin with the list lenght + * end terminate with a NULL entry. + */ + + PROVIDE (__CTOR_LIST__ = .); + /* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */ + *crtbegin.o(.ctors) + *(.ctors) + *crtend.o(.ctors) + LONG(0) + PROVIDE (__CTOR_END__ = .); + + PROVIDE (__DTOR_LIST__ = .); + /* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */ + *crtbegin.o(.dtors) + *(.dtors) + *crtend.o(.dtors) + LONG(0) + PROVIDE (__DTOR_END__ = .); + + /* Exception frame info */ + *(.eh_frame) + + /* Miscellaneous read-only data */ + _rodata_start = . ; + *(.gnu.linkonce.r*) + *(.lit) + *(.shdata) + *(.rodata) + *(.rodata1) + *(.descriptors) + *(rom_ver) + _erodata = .; + + + /* Various possible names for the end of the .text section */ + etext = ALIGN(0x10); + _etext = .; + _endtext = .; + text.end = .; + PROVIDE (etext = .); + PROVIDE (__etext = .); + + } > ram + + + PROVIDE (__EXCEPT_START__ = .); + .gcc_except_table : { *(.gcc_except_table) } >ram + PROVIDE (__EXCEPT_END__ = .); + __GOT_START__ = .; + .got : + { + s.got = .; + *(.got.plt) *(.got) + } > ram + __GOT_END__ = .; + + .got1 : { *(.got1) } >ram + PROVIDE (__GOT2_START__ = .); + PROVIDE (_GOT2_START_ = .); + .got2 : { *(.got2) } >ram + PROVIDE (__GOT2_END__ = .); + PROVIDE (_GOT2_END_ = .); + + PROVIDE (__FIXUP_START__ = .); + PROVIDE (_FIXUP_START_ = .); + .fixup : { *(.fixup) } >ram + PROVIDE (_FIXUP_END_ = .); + PROVIDE (__FIXUP_END__ = .); + + PROVIDE (__SDATA2_START__ = .); + .sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) } >ram + .sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) } >ram + PROVIDE (__SBSS2_END__ = .); + + .sbss2 : { *(.sbss2) } >ram + PROVIDE (__SBSS2_END__ = .); + + __SBSS_START__ = .; + .bss : + { + bss.start = .; + *(.bss) *(.sbss) *(COMMON) + . = ALIGN(4); + bss.end = .; + } > ram + __SBSS_END__ = .; + + + + + + /* R/W Data */ + .data ( . ) : + { + . = ALIGN (4); + + data.start = .; + + *(.data) + *(.data.rel.*) + *(.data1) + *(.data.* .gnu.linkonce.d.*) + PROVIDE (__SDATA_START__ = .); + *(.sdata) + *(.gnu.linkonce.s.*) + data.end = .; + } > ram + + data.size = data.end - data.start; + bss.size = bss.end - bss.start; + text.size = text.end - text.start; + + PROVIDE(_bss_start = ADDR(.bss)); + PROVIDE(_bss_size = SIZEOF(.bss)); + PROVIDE(_data_start = ADDR(.data)); + PROVIDE(_data_size = SIZEOF(.data)); + PROVIDE(_text_start = ADDR(.text)); + PROVIDE(_text_size = SIZEOF(.text)); + PROVIDE(_end = data.end); + + .gzipmalloc : { + . = ALIGN (16); + _startmalloc = .; + } >ram + + + /* + * Interrupt stack setup + */ + IntrStack_start = ALIGN(0x10); + . += 0x4000; + intrStack = .; + PROVIDE(intrStackPtr = intrStack); + + + + _WorkspaceBase = .; + __WorkspaceBase = .; + . += WorkSpaceSize; + + _RamDiskBase = .; + __RamDiskBase = .; + . += RamDiskSize; + _RamDiskEnd = .; + __RamDiskEnd = .; + PROVIDE( _RamDiskSize = _RamDiskEnd - _RamDiskBase ); + + _HeapStart = .; + __HeapStart = .; + . += HeapSize; + _HeapEnd = .; + __HeapEnd = .; + + clear_end = .; + + /* Sections for compressed .text and .data */ + /* after the .datarom section is an int specifying */ + /* the length of the following compressed image */ + /* Executes once then could get overwritten */ + .textrom 0x100000 : + { + *(.textrom) + _endloader = .; + } > ram + + .datarom : + { + _dr_start = .; + *(.datarom) + _dr_end = .; + } > ram + dr_len = _dr_end - _dr_start; + + mpc5200_regs : + { + MBAR = .; + mpc5200 = .; + _mpc5200 = .; + . += (0x6000); + } > mpc5200_regs + + .dpram : + { + dp_ram = .; + _dp_ram = .; + . += (0x400); + } > dpram + + + /* the reset vector is at 0xfff00000 which is */ + /* located at offset 0x400000 from the base */ + /* of flash */ + .bootrom 0xFFE00000 : + { + *(.bootrom) + _endboot = .; + } > flash + + + .line 0 : { *(.line) } + .debug 0 : { *(.debug) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_aregion 0 : { *(.debug_aregion) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c new file mode 100644 index 0000000000..932e0004a3 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c @@ -0,0 +1,247 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the tod driver for a Philips pcf8563 I2C RTC | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.3 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/* + * This file interfaces with the real-time clock found in a + * Philips PCF8563 serial real-time clock chip. + * This RTC have I2C bus interface. BSP have to provide I2C bus primitives + * to make this driver working. getRegister and setRegister primitives is + * not used here to avoid multiple transactions over I2C bus (each transaction + * require significant time and error when date/time information red may + * occurs). ulControlPort contains I2C bus number; ulDataPort contains + * RTC I2C device address. + * + * Based on a ds1307 driver from: + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) ds1307.c,v 1.5 2004/04/21 10:42:52 ralf Exp + */ + +#include <rtems.h> +#include <libchip/rtc.h> +#include <string.h> +#include "../tod/pcf8563.h" +#include "../include/i2c.h" + +/* Convert from/to Binary-Coded Decimal representation */ +#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F)) +#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10)) + +/* pcf8563_initialize -- + * Initialize PCF8563 real-time clock chip. If RTC is halted, this + * function resume counting. + * + * PARAMETERS: + * minor -- minor RTC device number + */ +void +pcf8563_initialize(int minor) +{ + i2c_message_status status; + int try; + uint8_t ctrl1; + i2c_bus_number bus; + i2c_address addr; + + bus = RTC_Table[minor].ulCtrlPort1; + addr = RTC_Table[minor].ulDataPort; + + /* Read SECONDS register */ + try = 0; + do { + status = i2c_wbrd(bus, addr, PCF8563_CONTROL1_ADR, + &ctrl1, sizeof(ctrl1)); + try++; + } while ((status != I2C_SUCCESSFUL) && (try < 15)); + + /* If clock is halted, reset and start the clock */ + if ((ctrl1 & PCF8563_CONTROL1_STOP) != 0) + { + uint8_t start[8]; + memset(start, 0, sizeof(start)); + start[0] = PCF8563_CONTROL1_ADR; + try = 0; + do { + status = i2c_write(bus, addr, start, 2); + } while ((status != I2C_SUCCESSFUL) && (try < 15)); + } +} + +/* pcf8563_get_time -- + * read current time from PCF8563 real-time clock chip and convert it + * to the rtems_time_of_day structure. + * + * PARAMETERS: + * minor -- minor RTC device number + * time -- place to put return value (date and time) + * + * RETURNS: + * 0, if time obtained successfully + * -1, if error occured + */ +int +pcf8563_get_time(int minor, rtems_time_of_day *time) +{ + i2c_bus_number bus; + i2c_address addr; + uint8_t info[10]; + uint32_t v1, v2; + i2c_message_status status; + int try; + + if (time == NULL) + return -1; + + bus = RTC_Table[minor].ulCtrlPort1; + addr = RTC_Table[minor].ulDataPort; + + memset(time, 0, sizeof(rtems_time_of_day)); + try = 0; + do { + status = i2c_wbrd(bus, addr, PCF8563_SECOND_ADR, info, sizeof(info)); + try++; + } while ((status != I2C_SUCCESSFUL) && (try < 10)); + + if (status != I2C_SUCCESSFUL) + { + return -1; + } + + v1 = info[PCF8563_YEAR_ADR-PCF8563_SECOND_ADR]; + v2 = From_BCD(v1); + if ((info[PCF8563_MONTH_ADR-PCF8563_SECOND_ADR] + & PCF8563_MONTH_CENTURY) == 0) { + time->year = 1900 + v2; + } + else { + time->year = 2000 + v2; + } + + v1 = info[PCF8563_MONTH_ADR-PCF8563_SECOND_ADR] & PCF8563_MONTH_MASK; + time->month = From_BCD(v1); + + v1 = info[PCF8563_DAY_ADR-PCF8563_SECOND_ADR] & PCF8563_DAY_MASK; + time->day = From_BCD(v1); + + v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_ADR; + time->hour = From_BCD(v1); + + v1 = info[PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] & PCF8563_MINUTE_MASK; + time->minute = From_BCD(v1); + + v1 = info[PCF8563_SECOND_ADR-PCF8563_SECOND_ADR] & PCF8563_SECOND_MASK; + time->second = From_BCD(v1); + + return 0; +} + +/* pcf8563_set_time -- + * set time to the PCF8563 real-time clock chip + * + * PARAMETERS: + * minor -- minor RTC device number + * time -- new date and time to be written to PCF8563 + * + * RETURNS: + * 0, if time obtained successfully + * -1, if error occured + */ +int +pcf8563_set_time(int minor, rtems_time_of_day *time) +{ + i2c_bus_number bus; + i2c_address addr; + uint8_t info[8]; + i2c_message_status status; + int try; + + if (time == NULL) + return -1; + + bus = RTC_Table[minor].ulCtrlPort1; + addr = RTC_Table[minor].ulDataPort; + + if ((time->year >= 2100) || + (time->year < 1900)) { + rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER); + } + info[0] = PCF8563_SECOND_ADR; + info[1 + PCF8563_YEAR_ADR -PCF8563_SECOND_ADR] = To_BCD(time->year % 100); + info[1 + PCF8563_MONTH_ADR -PCF8563_SECOND_ADR] = To_BCD(time->month); + info[1 + PCF8563_DAY_ADR -PCF8563_SECOND_ADR] = To_BCD(time->day); + info[1 + PCF8563_HOUR_ADR -PCF8563_SECOND_ADR] = To_BCD(time->hour); + info[1 + PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] = To_BCD(time->minute); + info[1 + PCF8563_SECOND_ADR-PCF8563_SECOND_ADR] = To_BCD(time->second); + /* Do not set day of week */ + info[1 + PCF8563_DAY_OF_WEEK_ADR-PCF8563_SECOND_ADR] = 1; + + /* + * add century info + */ + if (time->year >= 2000) { + info[1 + PCF8563_MONTH_ADR -PCF8563_SECOND_ADR] |= PCF8563_MONTH_CENTURY; + } + /* + * send to device + */ + try = 0; + do { + status = i2c_write(bus, addr, info, 8); + try++; + } while ((status != I2C_SUCCESSFUL) && (try < 10)); + + if (status != I2C_SUCCESSFUL) + return -1; + else + return 0; +} + +/* Driver function table */ + +rtc_fns pcf8563_fns = { + pcf8563_initialize, + pcf8563_get_time, + pcf8563_set_time +}; diff --git a/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.h b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.h new file mode 100644 index 0000000000..916a723010 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.h @@ -0,0 +1,118 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains declarations for the pcf8563 RTC driver | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.2 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/* + * This file contains the definitions for Dallas Semiconductor + * DS1307/DS1308 serial real-time clock/NVRAM. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) ds1307.h,v 1.2 2003/09/04 18:51:56 joel Exp + */ + +#ifndef __RTC_PCF8563__ +#define __RTC_PCF8563__ + +#define PCF8563_I2C_ADDRESS (0xA2) /* I2C bus address assigned to PCF8563 */ + +#define PCF8563_CONTROL1_ADR (0x00) +#define PCF8563_CONTROL1_TEST1 (0x80) /* EXT_CLK test mode */ +#define PCF8563_CONTROL1_STOP (0x20) /* stop RTC source clock, clear divider*/ +#define PCF8563_CONTROL1_TESTC (0x08) /* enable power-on reset override */ + /***********/ +#define PCF8563_CONTROL2_ADR (0x01) +#define PCF8563_CONTROL2_TITP (0x10) /* 0: int output is level */ +#define PCF8563_CONTROL2_AF (0x08) /* alarm flag */ +#define PCF8563_CONTROL2_TF (0x04) /* timer flag */ +#define PCF8563_CONTROL2_AIE (0x02) /* alarm interrupt enable */ +#define PCF8563_CONTROL2_TIE (0x01) /* timer interrupt enable */ + /***********/ + +#define PCF8563_SECOND_ADR (0x02) +#define PCF8563_SECOND_VL (0x80) /* clock integrity no longer guaranteed */ +#define PCF8563_SECOND_MASK (0x7f) + /***********/ + +#define PCF8563_MINUTE_ADR (0x03) +#define PCF8563_MINUTE_MASK (0x7f) + /***********/ + +#define PCF8563_HOUR_ADR (0x04) +#define PCF8563_HOUR_MASK (0x3f) + /***********/ + +#define PCF8563_DAY_ADR (0x05) +#define PCF8563_DAY_MASK (0x3f) + +#define PCF8563_DAY_OF_WEEK_ADR (0x06) +#define PCF8563_DAY_OF_WEEK_MASK (0x07) + +#define PCF8563_MONTH_ADR (0x07) +#define PCF8563_MONTH_MASK (0x1f) +#define PCF8563_MONTH_CENTURY (0x80) + /***********/ + +#define PCF8563_YEAR_ADR (0x08) +#define PCF8563_YEAR_MASK (0xff) + +#define PCF8563_MINUTE_ALARM_ADR (0x09) +#define PCF8563_HOUR_ALARM_ADR (0x0A) +#define PCF8563_DAY_ALARM_ADR (0x0B) +#define PCF8563_DAY_OF_WEEK_ALARM_ADR (0x0C) +#define PCF8563_XXX_ALARM_AE (0x80) + /***********/ + +#define PCF8563_CLKOUTCTL_ADR (0x0D) +#define PCF8563_CLKOUTCTL_FE (0x80) /* */ +#define PCF8563_CLKOUTCTL_FD (0x03) /* */ + /***********/ + +#define PCF8563_TIMERCTL_ADR (0x0E) +#define PCF8563_TIMERCTL_FE (0x80) /* */ +#define PCF8563_TIMERCTL_FD (0x03) /* */ + /***********/ + +#define PCF8563_TIMER_ADR (0x0F) + +#endif /* __RTC_PCF8563__ */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/tod/todcfg.c b/c/src/lib/libbsp/powerpc/gen5200/tod/todcfg.c new file mode 100644 index 0000000000..381c91b70b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/tod/todcfg.c @@ -0,0 +1,123 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: $File$ ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file configures the pcf8563 RTC for a PM520 board | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.4 2005/12/06 14:11:12 thomas +|* added EB file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/* + * This file contains the RTC driver table for Motorola MCF5206eLITE + * ColdFire evaluation board. + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov <vvv@oktet.ru> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * @(#) todcfg.c,v 1.4 2005/01/22 04:12:39 ralf Exp + */ + +#include "../include/bsp.h" +#include "../include/i2c.h" +#include <libchip/rtc.h> +#include "../tod/pcf8563.h" + +/* Forward function declaration */ +boolean mpc5200_pcf8563_probe(int minor); + +extern rtc_fns pcf8563_fns; + +/* The following table configures the RTC drivers used in this BSP */ +rtc_tbl RTC_Table[] = { + { + "/dev/rtc", /* sDeviceName */ + RTC_CUSTOM, /* deviceType */ + &pcf8563_fns, /* pDeviceFns */ + mpc5200_pcf8563_probe, /* deviceProbe */ + NULL, /* pDeviceParams */ + 0x01, /* ulCtrlPort1, for PCF8563-I2C bus number */ + PCF8563_I2C_ADDRESS, /* ulDataPort, for PCF8563-I2C device addr */ + NULL, /* getRegister - not applicable to PCF8563 */ + NULL /* setRegister - not applicable to PCF8563 */ + } +}; + +/* Some information used by the RTC driver */ + +#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl)) + +size_t RTC_Count = NUM_RTCS; + +rtems_device_minor_number RTC_Minor; + +/* mpc5200_pcf8563_probe -- + * RTC presence probe function. Return TRUE, if device is present. + * Device presence checked by probe access to RTC device over I2C bus. + * + * PARAMETERS: + * minor - minor RTC device number + * + * RETURNS: + * TRUE, if RTC device is present + */ +boolean +mpc5200_pcf8563_probe(int minor) +{ + int try = 0; + i2c_message_status status; + rtc_tbl *rtc; + i2c_bus_number bus; + i2c_address addr; + + if (minor >= NUM_RTCS) + return FALSE; + + rtc = RTC_Table + minor; + + bus = rtc->ulCtrlPort1; + addr = rtc->ulDataPort; + do { + status = i2c_wrbyte(bus, addr, 0); + if (status == I2C_NO_DEVICE) + return FALSE; + try++; + } while ((try < 15) && (status != I2C_SUCCESSFUL)); + if (status == I2C_SUCCESSFUL) + return TRUE; + else + return FALSE; +} diff --git a/c/src/lib/libbsp/powerpc/gen5200/vectors/asm_utils.S b/c/src/lib/libbsp/powerpc/gen5200/vectors/asm_utils.S new file mode 100644 index 0000000000..16b3651f53 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/vectors/asm_utils.S @@ -0,0 +1,71 @@ +/*---------------------------------------------------------------------------*/ +/* Actually no changes made in this file but its presence is required in the */ +/* cygwin /shared directory due to development purposes! */ +/* */ +/* IPR Engineering, 07/17/2003 */ +/*---------------------------------------------------------------------------*/ + +/* + * asm_utils.s + * + * asm_utils.S,v 1.2 2002/04/18 20:55:36 joel Exp + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * + * This file contains the low-level support for moving exception + * exception code to appropriate location. + * + */ + +#include <rtems/asm.h> +#include <rtems/score/cpu.h> +#include <libcpu/io.h> + + .globl codemove +codemove: + .type codemove,@function +/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */ + cmplw cr1,r3,r4 + addi r0,r5,3 + srwi. r0,r0,2 + beq cr1,4f /* In place copy is not necessary */ + beq 7f /* Protect against 0 count */ + mtctr r0 + bge cr1,2f + + la r8,-4(r4) + la r7,-4(r3) +1: lwzu r0,4(r8) + stwu r0,4(r7) + bdnz 1b + b 4f + +2: slwi r0,r0,2 + add r8,r4,r0 + add r7,r3,r0 +3: lwzu r0,-4(r8) + stwu r0,-4(r7) + bdnz 3b + +/* Now flush the cache: note that we must start from a cache aligned + * address. Otherwise we might miss one cache line. + */ +4: cmpwi r6,0 + add r5,r3,r5 + beq 7f /* Always flush prefetch queue in any case */ + subi r0,r6,1 + andc r3,r3,r0 + mr r4,r3 +5: cmplw r4,r5 + dcbst 0,r4 + add r4,r4,r6 + blt 5b + sync /* Wait for all dcbst to complete on bus */ + mr r4,r3 +6: cmplw r4,r5 + icbi 0,r4 + add r4,r4,r6 + blt 6b +7: sync /* Wait for all icbi to complete on bus */ + isync + blr diff --git a/c/src/lib/libbsp/powerpc/gen5200/vectors/raw_exception.c b/c/src/lib/libbsp/powerpc/gen5200/vectors/raw_exception.c new file mode 100644 index 0000000000..0d1dd37a6a --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/vectors/raw_exception.c @@ -0,0 +1,276 @@ +/*---------------------------------------------------------------------------*/ +/* Only modified header pathes due to development environment requirements. */ +/* Changes will be obsolete with the complete integration of the MPC5x00 BSP */ +/* into the RTEMS directory tree. */ +/* */ +/* IPR Engineering, 07/17/2003 */ +/*---------------------------------------------------------------------------*/ + +/* + * raw_exception.c - This file contains implementation of C function to + * Instanciate 60x ppc primary exception entries. + * More detailled information can be found on motorola + * site and more precisely in the following book : + * + * MPC750 + * Risc Microporcessor User's Manual + * Motorola REF : MPC750UM/AD 8/97 + * + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com> + * to support 603, 603e, 604, 604e exceptions + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * raw_exception.c,v 1.8 2002/10/31 20:12:42 joel Exp + */ +#include <rtems/system.h> +#include <rtems/score/powerpc.h> +#include <rtems/bspIo.h> +#include "../include/raw_exception.h" +#include <libcpu/cpuIdent.h> + +#include <string.h> + +static rtems_raw_except_connect_data* raw_except_table; +static rtems_raw_except_connect_data default_raw_except_entry; +static rtems_raw_except_global_settings* local_settings; + +void * codemove(void *, const void *, unsigned int, unsigned long); +int mpc750_vector_is_valid(rtems_vector vector) + +{ + switch(vector) { + case ASM_RESET_VECTOR: /* fall through */ + case ASM_MACH_VECTOR: + case ASM_PROT_VECTOR: + case ASM_ISI_VECTOR: + case ASM_EXT_VECTOR: + case ASM_ALIGN_VECTOR: + case ASM_PROG_VECTOR: + case ASM_FLOAT_VECTOR: + case ASM_DEC_VECTOR: + case ASM_SYS_VECTOR: + case ASM_TRACE_VECTOR: + case ASM_ADDR_VECTOR: + case ASM_SYSMGMT_VECTOR: + case ASM_ITM_VECTOR: + return 1; + default: return 0; + } +} + +int mpc603_vector_is_valid(rtems_vector vector) +{ + switch(vector) { + case ASM_RESET_VECTOR: /* fall through */ + case ASM_MACH_VECTOR: + case ASM_PROT_VECTOR: + case ASM_ISI_VECTOR: + case ASM_EXT_VECTOR: + case ASM_ALIGN_VECTOR: + case ASM_PROG_VECTOR: + case ASM_FLOAT_VECTOR: + case ASM_DEC_VECTOR: + case ASM_SYS_VECTOR: + case ASM_TRACE_VECTOR: + return 1; + case ASM_PERFMON_VECTOR: + return 0; + case ASM_IMISS_VECTOR: /* fall through */ + case ASM_DLMISS_VECTOR: + case ASM_DSMISS_VECTOR: + case ASM_ADDR_VECTOR: + case ASM_SYSMGMT_VECTOR: + return 1; + case ASM_ITM_VECTOR: + return 0; + } + return 0; +} + +int mpc604_vector_is_valid(rtems_vector vector) +{ + switch(vector) { + case ASM_RESET_VECTOR: /* fall through */ + case ASM_MACH_VECTOR: + case ASM_PROT_VECTOR: + case ASM_ISI_VECTOR: + case ASM_EXT_VECTOR: + case ASM_ALIGN_VECTOR: + case ASM_PROG_VECTOR: + case ASM_FLOAT_VECTOR: + case ASM_DEC_VECTOR: + case ASM_SYS_VECTOR: + case ASM_TRACE_VECTOR: + case ASM_PERFMON_VECTOR: + return 1; + case ASM_IMISS_VECTOR: /* fall through */ + case ASM_DLMISS_VECTOR: + case ASM_DSMISS_VECTOR: + return 0; + case ASM_ADDR_VECTOR: /* fall through */ + case ASM_SYSMGMT_VECTOR: + return 1; + case ASM_ITM_VECTOR: + return 0; + } + return 0; +} + +int mpc60x_vector_is_valid(rtems_vector vector) +{ + switch (current_ppc_cpu) { + case PPC_7400: + case PPC_750: + if (!mpc750_vector_is_valid(vector)) { + return 0; + } + break; + case PPC_604: + case PPC_604e: + /* case PPC_604r: -- same value as PPC_750 */ + if (!mpc604_vector_is_valid(vector)) { + return 0; + } + break; + case PPC_603: + case PPC_603e: + case PPC_603le: + if (!mpc603_vector_is_valid(vector)) { + return 0; + } + break; + default: + printk("Please complete libcpu/powerpc/mpc6xx/raw_exception.c\n"); + printk("current_ppc_cpu = %x\n", current_ppc_cpu); + return 0; + } + return 1; +} + +int mpc60x_set_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (!mpc60x_vector_is_valid(except->exceptIndex)) { + return 0; + } + /* + * Check if default handler is actually connected. If not issue an error. + * You must first get the current handler via mpc60x_get_current_exception + * and then disconnect it using mpc60x_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc60x_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) { + return 0; + } + + _CPU_ISR_Disable(level); + + raw_except_table [except->exceptIndex] = *except; + codemove((void*)mpc60x_get_vector_addr(except->exceptIndex), + except->hdl.raw_hdl, + except->hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + except->on(except); + + _CPU_ISR_Enable(level); + return 1; +} + +int mpc60x_get_current_exception (rtems_raw_except_connect_data* except) +{ + if (!mpc60x_vector_is_valid(except->exceptIndex)){ + return 0; + } + + *except = raw_except_table [except->exceptIndex]; + + return 1; +} + +int mpc60x_delete_exception (const rtems_raw_except_connect_data* except) +{ + unsigned int level; + + if (!mpc60x_vector_is_valid(except->exceptIndex)){ + return 0; + } + /* + * Check if handler passed is actually connected. If not issue an error. + * You must first get the current handler via mpc60x_get_current_exception + * and then disconnect it using mpc60x_delete_exception. + * RATIONALE : to always have the same transition by forcing the user + * to get the previous handler before accepting to disconnect. + */ + if (memcmp(mpc60x_get_vector_addr(except->exceptIndex), + (void*)except->hdl.raw_hdl, + except->hdl.raw_hdl_size)) { + return 0; + } + _CPU_ISR_Disable(level); + + except->off(except); + codemove((void*)mpc60x_get_vector_addr(except->exceptIndex), + default_raw_except_entry.hdl.raw_hdl, + default_raw_except_entry.hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + + + raw_except_table[except->exceptIndex] = default_raw_except_entry; + raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex; + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * Exception global init. + */ +int mpc60x_init_exceptions (rtems_raw_except_global_settings* config) +{ + unsigned i; + unsigned int level; + + /* + * store various accelerators + */ + raw_except_table = config->rawExceptHdlTbl; + local_settings = config; + default_raw_except_entry = config->defaultRawEntry; + + _CPU_ISR_Disable(level); + + for (i=0; i <= LAST_VALID_EXC; i++) { + if (!mpc60x_vector_is_valid(i)){ + continue; + } + codemove((void*)mpc60x_get_vector_addr(i), + raw_except_table[i].hdl.raw_hdl, + raw_except_table[i].hdl.raw_hdl_size, + PPC_CACHE_ALIGNMENT); + if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) { + raw_except_table[i].on(&raw_except_table[i]); + } + else { + raw_except_table[i].off(&raw_except_table[i]); + } + } + _CPU_ISR_Enable(level); + + return 1; +} + +int mpc60x_get_exception_config (rtems_raw_except_global_settings** config) +{ + *config = local_settings; + return 1; +} + diff --git a/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.S b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.S new file mode 100644 index 0000000000..29b6b972f0 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.S @@ -0,0 +1,282 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: vectors.S ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the irq controller handler | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.3 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: vectors.s */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS assembly code for PowerPC exception veneers */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: This file contains the assembly code for the */ +/* PowerPC exception veneers for RTEMS. */ +/* Module: vectors.s */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 04/18/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* (c) 1999, Eric Valette valette@crf.canon.fr */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include <rtems/asm.h> +#include <rtems/score/cpu.h> +/*#include <bsp/vectors.h>*/ +#include "vectors.h" + +#define SYNC \ + sync; \ + isync + + .text + .p2align 5 + +PUBLIC_VAR(default_exception_vector_code_prolog) +SYM (default_exception_vector_code_prolog): + /* + * let room for exception frame + */ + stwu r1, - (EXCEPTION_FRAME_END)(r1) + stw r3, GPR3_OFFSET(r1) + stw r2, GPR2_OFFSET(r1) + mflr r2 + stw r2, EXC_LR_OFFSET(r1) + bl 0f +0: /* + * r3 = exception vector entry point + * (256 * vector number) + few instructions + */ + mflr r3 + /* + * r3 = r3 >> 8 = vector + */ + srwi r3,r3,8 + ba push_normalized_frame + + PUBLIC_VAR (default_exception_vector_code_prolog_size) + + default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog + + .p2align 5 +PUBLIC_VAR (push_normalized_frame) +SYM (push_normalized_frame): + stw r3, EXCEPTION_NUMBER_OFFSET(r1) + stw r0, GPR0_OFFSET(r1) + mfsrr0 r2 + stw r2, SRR0_FRAME_OFFSET(r1) + mfsrr1 r3 + stw r3, SRR1_FRAME_OFFSET(r1) + /* + * Save general purpose registers + * Already saved in prolog : R1, R2, R3, LR. + * Saved a few line above : R0 + * + * Manual says that "stmw" instruction may be slower than + * series of individual "stw" but who cares about performance + * for the DEFAULT exception handler? + */ + stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */ + + mfcr r31 + stw r31, EXC_CR_OFFSET(r1) + mfctr r30 + stw r30, EXC_CTR_OFFSET(r1) + mfxer r28 + stw r28, EXC_XER_OFFSET(r1) + /* + * compute SP at exception entry + */ + addi r2, r1, EXCEPTION_FRAME_END + /* + * store it at the right place + */ + stw r2, GPR1_OFFSET(r1) + + /* + * Enable data and instruction address translation, exception nesting + */ + mfmsr r3 + ori r3,r3, MSR_RI|MSR_DR /*| MSR_IR*/ + mtmsr r3 + SYNC + + /* + * Call C exception handler + */ + /* + * store the execption frame address in r3 (first param) + */ + addi r3, r1, 0x8 + /* + * globalExceptHdl(r3) + */ + addis r4, 0, globalExceptHdl@ha + lwz r5, globalExceptHdl@l(r4) + mtlr r5 + blrl + /* + * Restore registers status + */ + lwz r31, EXC_CR_OFFSET(r1) + mtcr r31 + lwz r30, EXC_CTR_OFFSET(r1) + mtctr r30 + lwz r29, EXC_LR_OFFSET(r1) + mtlr r29 + lwz r28, EXC_XER_OFFSET(r1) + mtxer r28 + + lmw r4, GPR4_OFFSET(r1) + lwz r2, GPR2_OFFSET(r1) + lwz r0, GPR0_OFFSET(r1) + + /* + * Disable data and instruction translation. Make path non recoverable... + */ + mfmsr r3 + xori r3, r3, MSR_RI|MSR_DR /*| MSR_IR */ + mtmsr r3 + SYNC + + /* + * Restore rfi related settings + */ + + lwz r3, SRR1_FRAME_OFFSET(r1) + mtsrr1 r3 + lwz r3, SRR0_FRAME_OFFSET(r1) + mtsrr0 r3 + + lwz r3, GPR3_OFFSET(r1) + addi r1,r1, EXCEPTION_FRAME_END + SYNC + rfi + + .section .vectors,"awx",@progbits + + PUBLIC_VAR (__vectors) + SYM (__vectors): + bl start + .rep 63 + .long 0x04000400 + .endr +__vec2: b __vec2 + .rep 63 + .long 0x04000400 + .endr +__vec3: b __vec3 + .rep 63 + .long 0x04000400 + .endr +__vec4: b __vec4 + .rep 63 + .long 0x04000400 + .endr +__vec5: b __vec5 + .rep 63 + .long 0x04000400 + .endr +__vec6: b __vec6 + .rep 63 + .long 0x04000400 + .endr +__vec7: b __vec7 + .rep 63 + .long 0x04000400 + .endr +__vec8: b __vec8 + .rep 63 + .long 0x04000400 + .endr +__vec9: b __vec9 + .rep 63 + .long 0x04000400 + .endr +__veca: b __veca + .rep 63 + .long 0x04000400 + .endr +__vecb: b __vecb + .rep 63 + .long 0x04000400 + .endr +__vecc: b __vecc + .rep 63 + .long 0x04000400 + .endr +__vecd: b __vecd + .rep 63 + .long 0x04000400 + .endr +__vece: b __vece + .rep 63 + .long 0x04000400 + .endr +__vecf: b __vecf + .rep 63+1024 + .long 0x04000400 + .endr + diff --git a/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.h b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.h new file mode 100644 index 0000000000..83da6fd0e7 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors.h @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------*/ +/* Actually no changes made in this file but its presence is required in the */ +/* cygwin /shared directory due to development purposes! */ +/* */ +/* IPR Engineering, 07/17/2003 */ +/*---------------------------------------------------------------------------*/ + +/* + * vectors.h Exception frame related contant and API. + * + * This include file describe the data structure and the functions implemented + * by rtems to handle exceptions. + * + * CopyRight (C) 1999 valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * vectors.h,v 1.2 2002/05/14 17:10:17 joel Exp + */ +#ifndef LIBBSP_POWERPC_MCP750_VECTORS_H +#define LIBBSP_POWERPC_MCP750_VECTORS_H + +/* + * The callee (high level exception code written in C) + * will store the Link Registers (return address) at entry r1 + 4 !!!. + * So let room for it!!!. + */ +#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4 +#define SRR0_FRAME_OFFSET 8 +#define SRR1_FRAME_OFFSET 12 +#define EXCEPTION_NUMBER_OFFSET 16 +#define GPR0_OFFSET 20 +#define GPR1_OFFSET 24 +#define GPR2_OFFSET 28 +#define GPR3_OFFSET 32 +#define GPR4_OFFSET 36 +#define GPR5_OFFSET 40 +#define GPR6_OFFSET 44 +#define GPR7_OFFSET 48 +#define GPR8_OFFSET 52 +#define GPR9_OFFSET 56 +#define GPR10_OFFSET 60 +#define GPR11_OFFSET 64 +#define GPR12_OFFSET 68 +#define GPR13_OFFSET 72 +#define GPR14_OFFSET 76 +#define GPR15_OFFSET 80 +#define GPR16_OFFSET 84 +#define GPR17_OFFSET 88 +#define GPR18_OFFSET 92 +#define GPR19_OFFSET 96 +#define GPR20_OFFSET 100 +#define GPR21_OFFSET 104 +#define GPR22_OFFSET 108 +#define GPR23_OFFSET 112 +#define GPR24_OFFSET 116 +#define GPR25_OFFSET 120 +#define GPR26_OFFSET 124 +#define GPR27_OFFSET 128 +#define GPR28_OFFSET 132 +#define GPR29_OFFSET 136 +#define GPR30_OFFSET 140 +#define GPR31_OFFSET 144 +#define EXC_CR_OFFSET 148 +#define EXC_CTR_OFFSET 152 +#define EXC_XER_OFFSET 156 +#define EXC_LR_OFFSET 160 +#define EXC_MSR_OFFSET 164 +#define EXC_DAR_OFFSET 168 +/* + * maintain the EABI requested 8 bytes aligment + * As SVR4 ABI requires 16, make it 16 (as some + * exception may need more registers to be processed...) + */ +#define EXCEPTION_FRAME_END 176 + +#ifndef ASM +/* + * default raw exception handlers + */ + +extern void default_exception_vector_code_prolog(); +extern int default_exception_vector_code_prolog_size; + +/* codemove is like memmove, but it also gets the cache line size + * as 4th parameter to synchronize them. If this last parameter is + * zero, it performs more or less like memmove. No copy is performed if + * source and destination addresses are equal. However the caches + * are synchronized. Note that the size is always rounded up to the + * next mutiple of 4. + */ +extern void * codemove(void *, const void *, unsigned int, unsigned long); +extern void initialize_exceptions(); + +typedef struct { + unsigned EXC_SRR0; + unsigned EXC_SRR1; + unsigned _EXC_number; + unsigned GPR0; + unsigned GPR1; + unsigned GPR2; + unsigned GPR3; + unsigned GPR4; + unsigned GPR5; + unsigned GPR6; + unsigned GPR7; + unsigned GPR8; + unsigned GPR9; + unsigned GPR10; + unsigned GPR11; + unsigned GPR12; + unsigned GPR13; + unsigned GPR14; + unsigned GPR15; + unsigned GPR16; + unsigned GPR17; + unsigned GPR18; + unsigned GPR19; + unsigned GPR20; + unsigned GPR21; + unsigned GPR22; + unsigned GPR23; + unsigned GPR24; + unsigned GPR25; + unsigned GPR26; + unsigned GPR27; + unsigned GPR28; + unsigned GPR29; + unsigned GPR30; + unsigned GPR31; + unsigned EXC_CR; + unsigned EXC_CTR; + unsigned EXC_XER; + unsigned EXC_LR; + unsigned EXC_MSR; + unsigned EXC_DAR; +}BSP_Exception_frame; + + +typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr); +extern exception_handler_t globalExceptHdl; +/* + * Compatibility with pc386 + */ +typedef BSP_Exception_frame CPU_Exception_frame; +typedef exception_handler_t cpuExcHandlerType; + +#endif /* ASM */ + +#endif /* LIBBSP_POWERPC_MCP750_VECTORS_H */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors_init.c b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors_init.c new file mode 100644 index 0000000000..a04d0b1a86 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/gen5200/vectors/vectors_init.c @@ -0,0 +1,224 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| File: vectors_init.c ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.com/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the irq controller handler | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 01.12.05 creation doe | +|*****************************************************************| +|*CVS information: | +|*(the following information is created automatically, | +|*do not edit here) | +|*****************************************************************| +|* $Log$ +|* Revision 1.2 2005/12/09 08:57:03 thomas +|* added/modifed file headers +|* + * +|*****************************************************************| +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: vectors_init.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS exception handling initialization */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: This include file describe the data structure and */ +/* the functions implemented by rtems to handle */ +/* exceptions. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: RTEMS exception handling initialization */ +/* */ +/* Module: vectors_init.c */ +/* Project: RTEMS 4.6.0pre1 / MCF8260ads BSP */ +/* Version 1.2 */ +/* Date: 11/04/2002 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* CopyRight (C) 1999 valette@crf.canon.fr */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in found in the file LICENSE in this distribution or at */ +/* http://www.OARcorp.com/rtems/license.html. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +/*#include "../vectors/vectors.h"*/ +#include "../vectors/vectors.h" +#include "../include/raw_exception.h" +/*#include "../include/bsp.h"*/ +#include "../include/bsp.h" +#include <rtems/bspIo.h> + +extern int mpc60x_vector_is_valid(rtems_vector); +static rtems_raw_except_global_settings exception_config; +static rtems_raw_except_connect_data exception_table[LAST_VALID_EXC + 1]; + +exception_handler_t globalExceptHdl; + +void C_exception_handler(BSP_Exception_frame* excPtr) +{ + int recoverable = 0; + + printk("exception handler called for exception %d\n", excPtr->_EXC_number); + printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0); + printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1); + printk("\t R0 = %x\n", excPtr->GPR0); + printk("\t R1 = %x\n", excPtr->GPR1); + printk("\t R2 = %x\n", excPtr->GPR2); + printk("\t R3 = %x\n", excPtr->GPR3); + printk("\t R4 = %x\n", excPtr->GPR4); + printk("\t R5 = %x\n", excPtr->GPR5); + printk("\t R6 = %x\n", excPtr->GPR6); + printk("\t R7 = %x\n", excPtr->GPR7); + printk("\t R8 = %x\n", excPtr->GPR8); + printk("\t R9 = %x\n", excPtr->GPR9); + printk("\t R10 = %x\n", excPtr->GPR10); + printk("\t R11 = %x\n", excPtr->GPR11); + printk("\t R12 = %x\n", excPtr->GPR12); + printk("\t R13 = %x\n", excPtr->GPR13); + printk("\t R14 = %x\n", excPtr->GPR14); + printk("\t R15 = %x\n", excPtr->GPR15); + printk("\t R16 = %x\n", excPtr->GPR16); + printk("\t R17 = %x\n", excPtr->GPR17); + printk("\t R18 = %x\n", excPtr->GPR18); + printk("\t R19 = %x\n", excPtr->GPR19); + printk("\t R20 = %x\n", excPtr->GPR20); + printk("\t R21 = %x\n", excPtr->GPR21); + printk("\t R22 = %x\n", excPtr->GPR22); + printk("\t R23 = %x\n", excPtr->GPR23); + printk("\t R24 = %x\n", excPtr->GPR24); + printk("\t R25 = %x\n", excPtr->GPR25); + printk("\t R26 = %x\n", excPtr->GPR26); + printk("\t R27 = %x\n", excPtr->GPR27); + printk("\t R28 = %x\n", excPtr->GPR28); + printk("\t R29 = %x\n", excPtr->GPR29); + printk("\t R30 = %x\n", excPtr->GPR30); + printk("\t R31 = %x\n", excPtr->GPR31); + printk("\t CR = %x\n", excPtr->EXC_CR); + printk("\t CTR = %x\n", excPtr->EXC_CTR); + printk("\t XER = %x\n", excPtr->EXC_XER); + printk("\t LR = %x\n", excPtr->EXC_LR); + printk("\t MSR = %x\n", excPtr->EXC_MSR); + + if(excPtr->_EXC_number == ASM_DEC_VECTOR) + recoverable = 1; + + if(excPtr->_EXC_number == ASM_SYS_VECTOR) + recoverable = 1; + +#if 0 +#ifdef TEST_RAW_EXCEPTION_CODE + recoverable = 1; +#else + recoverable = 0; +#endif + if (!recoverable) { + printk("unrecoverable exception!!! Push reset button\n"); + while(1); + + } +#endif + + +} + +void nop_except_enable(const rtems_raw_except_connect_data* ptr) +{ +} +int except_always_enabled(const rtems_raw_except_connect_data* ptr) +{ + return 1; +} + +void initialize_exceptions() + { + int i; + + /* + * Initialize pointer used by low level execption handling + */ + globalExceptHdl = C_exception_handler; + /* + * Put default_exception_vector_code_prolog at relevant exception + * code entry addresses + */ + exception_config.exceptSize = LAST_VALID_EXC + 1; + exception_config.rawExceptHdlTbl = &exception_table[0]; + exception_config.defaultRawEntry.exceptIndex = 0; + exception_config.defaultRawEntry.hdl.vector = 0; + exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_vector_code_prolog; + /* + * Note that next line the '&' before default_exception_vector_code_prolog_size + * is not a bug as it is defined a .set directly in asm... + */ + exception_config.defaultRawEntry.hdl.raw_hdl_size = (unsigned) &default_exception_vector_code_prolog_size; + + + for (i=0; i <= exception_config.exceptSize; i++) + { + + printk("installing exception number %d\n", i); + + if (!mpc60x_vector_is_valid(i)) + continue; + + exception_table[i].exceptIndex = i; + exception_table[i].hdl = exception_config.defaultRawEntry.hdl; + exception_table[i].hdl.vector = i; + exception_table[i].on = nop_except_enable; + exception_table[i].off = nop_except_enable; + exception_table[i].isOn = except_always_enabled; + } + + if (!mpc60x_init_exceptions(&exception_config)) + BSP_panic("Exception handling initialization failed\n"); + else + printk("Exception handling initialization done\n"); + + } |