summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJennifer Averett <Jennifer.Averett@OARcorp.com>2005-04-28 14:05:14 +0000
committerJennifer Averett <Jennifer.Averett@OARcorp.com>2005-04-28 14:05:14 +0000
commit0329aae1b2cd18215ac8d19cbb1a69f502eddd71 (patch)
tree84188ee210ca807c9af4393c93684ff491a789ee /c
parent2005-04-27 Ralf Corsepius <ralf.corsepius@rtems.org> (diff)
downloadrtems-0329aae1b2cd18215ac8d19cbb1a69f502eddd71.tar.bz2
2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
* acinclude.m4: Initial release of ep1a bsp * ep1a/Makefile.am, ep1a/bsp_specs, ep1a/configure.ac, ep1a/console/alloc360.c, ep1a/console/console.c, ep1a/console/console.h, ep1a/console/init68360.c, ep1a/console/m68360.h, ep1a/console/mc68360_scc.c, ep1a/console/ns16550cfg.c, ep1a/console/ns16550cfg.h, ep1a/console/rsPMCQ1.c, ep1a/console/rsPMCQ1.h, ep1a/include/bsp.h, ep1a/irq/irq.c, ep1a/irq/irq_init.c, ep1a/pci/no_host_bridge.c, ep1a/start/start.S, ep1a/startup/bspstart.c, ep1a/startup/linkcmds, ep1a/vme/vmeconfig.c: New files.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/powerpc/ChangeLog13
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/Makefile.am242
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/bsp_specs22
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/configure.ac30
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c104
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/console.c350
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/console.h38
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/init68360.c670
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/m68360.h973
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c836
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c47
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h57
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c558
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h148
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/include/bsp.h209
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/include/tm27.h60
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/irq/irq.c570
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c332
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c31
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/start/start.S151
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c523
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds191
-rw-r--r--c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c142
23 files changed, 6297 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog
index 2107c24e57..7deb73c52e 100644
--- a/c/src/lib/libbsp/powerpc/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/ChangeLog
@@ -1,3 +1,16 @@
+2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
+
+ * acinclude.m4: Initial release of ep1a bsp
+ * ep1a/Makefile.am, ep1a/bsp_specs, ep1a/configure.ac,
+ ep1a/console/alloc360.c, ep1a/console/console.c,
+ ep1a/console/console.h, ep1a/console/init68360.c,
+ ep1a/console/m68360.h, ep1a/console/mc68360_scc.c,
+ ep1a/console/ns16550cfg.c, ep1a/console/ns16550cfg.h,
+ ep1a/console/rsPMCQ1.c, ep1a/console/rsPMCQ1.h, ep1a/include/bsp.h,
+ ep1a/irq/irq.c, ep1a/irq/irq_init.c, ep1a/pci/no_host_bridge.c,
+ ep1a/start/start.S, ep1a/startup/bspstart.c, ep1a/startup/linkcmds,
+ ep1a/vme/vmeconfig.c: New files.
+
2004-12-30 Ralf Corsepius <ralf.corsepius@rtems.org>
* acinclude.m4: Reflect eth_comm having been removed.
diff --git a/c/src/lib/libbsp/powerpc/ep1a/Makefile.am b/c/src/lib/libbsp/powerpc/ep1a/Makefile.am
new file mode 100644
index 0000000000..c185844d3a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/Makefile.am
@@ -0,0 +1,242 @@
+##
+## Makefile.am,v 1.8.4.1 2003/02/20 21:55:34 joel Exp
+##
+
+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_HEADERS += include/tm27.h
+
+nodist_include_HEADERS = include/bspopts.h
+DISTCLEANFILES = include/bspopts.h
+nodist_include_HEADERS += ../../shared/include/coverhd.h
+
+noinst_PROGRAMS =
+
+include_bspdir = $(includedir)/bsp
+
+###
+dist_project_lib_DATA += startup/linkcmds
+
+noinst_PROGRAMS += startup.rel
+startup_rel_SOURCES = startup/bspstart.c \
+ ../../shared/bootcard.c ../../shared/main.c ../../shared/bsppost.c \
+ ../../shared/bsplibc.c ../../powerpc/shared/startup/sbrk.c \
+ ../../shared/bspclean.c ../../shared/gnatinstallhandler.c \
+ ../../powerpc/shared/startup/pgtbl_setup.c \
+ ../../powerpc/shared/startup/pgtbl_activate.c
+startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
+startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+###
+noinst_PROGRAMS += pclock.rel
+pclock_rel_SOURCES = ../../powerpc/shared/clock/p_clock.c
+pclock_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pclock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+###
+include_bsp_HEADERS = ../../powerpc/shared/console/uart.h \
+ ../../powerpc/shared/console/consoleIo.h \
+ ../../powerpc/shared/motorola/motorola.h \
+ ../../powerpc/shared/residual/residual.h \
+ ../../powerpc/shared/residual/pnp.h \
+ ../../powerpc/shared/console/consoleIo.h \
+ console/rsPMCQ1.h
+
+noinst_PROGRAMS += console.rel
+console_rel_SOURCES = console/console.c \
+ console/ns16550cfg.c console/mc68360_scc.c console/rsPMCQ1.c \
+ console/alloc360.c console/init68360.c
+console_rel_CPPFLAGS = $(AM_CPPFLAGS)
+console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+###
+include_bsp_HEADERS += ../../powerpc/shared/openpic/openpic.h
+
+noinst_PROGRAMS += openpic.rel
+openpic_rel_SOURCES = ../../powerpc/shared/openpic/openpic.h \
+ ../../powerpc/shared/openpic/openpic.c
+
+openpic_rel_CPPFLAGS = $(AM_CPPFLAGS)
+openpic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+###
+include_bsp_HEADERS += ../../powerpc/shared/pci/pci.h
+
+noinst_PROGRAMS += pci.rel
+pci_rel_SOURCES = pci/no_host_bridge.c ../../powerpc/shared/pci/pci.c \
+ ../../powerpc/shared/pci/pcifinddevice.c
+pci_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pci_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+###
+include_bsp_HEADERS += ../../powerpc/shared/irq/irq.h
+
+noinst_PROGRAMS += irq.rel
+irq_rel_SOURCES = irq/irq_init.c irq/irq.c \
+ ../../powerpc/shared/irq/i8259.c \
+ ../../powerpc/shared/irq/irq_asm.S
+irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
+irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+##
+include_bsp_HEADERS += ../../powerpc/shared/vectors/vectors.h
+
+noinst_PROGRAMS += vectors.rel
+vectors_rel_SOURCES = ../../powerpc/shared/vectors/vectors_init.c \
+ ../../powerpc/shared/vectors/vectors.S
+vectors_rel_CPPFLAGS = $(AM_CPPFLAGS)
+vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+##
+include_bsp_HEADERS += ../../shared/vmeUniverse/vmeUniverse.h \
+ ../../powerpc/shared/vme/VMEConfig.h ../../powerpc/shared/vme/VME.h
+
+noinst_PROGRAMS += vme.rel
+vme_rel_SOURCES = ../../shared/vmeUniverse/vmeUniverse.c \
+ vme/vmeconfig.c
+vme_rel_CPPFLAGS = $(AM_CPPFLAGS)
+vme_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+##
+
+EXTRA_DIST = start/start.S
+start.$(OBJEXT): start/start.S
+ $(CPPASCOMPILE) -DASM -o $@ -c $<
+project_lib_DATA = start.$(OBJEXT)
+
+EXTRA_DIST += ../../powerpc/shared/start/rtems_crti.S
+rtems_crti.$(OBJEXT): ../../powerpc/shared/start/rtems_crti.S
+ $(CPPASCOMPILE) -DASM -o $@ -c $<
+project_lib_DATA += rtems_crti.$(OBJEXT)
+
+noinst_LIBRARIES = libbsp.a
+libbsp_a_SOURCES =
+libbsp_a_LIBADD = pclock.rel console.rel irq.rel openpic.rel \
+ pci.rel vectors.rel startup.rel vme.rel
+if HAS_NETWORKING
+endif
+libbsp_a_LIBADD += ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
+ ../../../libcpu/@RTEMS_CPU@/shared/stack.rel \
+ ../../../libcpu/@RTEMS_CPU@/@exceptions@/rtems-cpu.rel \
+ ../../../libcpu/@RTEMS_CPU@/mpc6xx/clock.rel \
+ ../../../libcpu/@RTEMS_CPU@/mpc6xx/exceptions.rel \
+ ../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \
+ ../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel
+
+all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
+
+###
+
+PREINSTALL_DIRS =
+PREINSTALL_FILES =
+TMPINSTALL_FILES =
+
+$(PROJECT_INCLUDE)/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)
+ @: > $(PROJECT_INCLUDE)/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(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)/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: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
+
+$(PROJECT_INCLUDE)/bsp/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/bsp
+ @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+
+$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
+PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
+
+$(PROJECT_INCLUDE)/bsp/consoleIo.h: ../../powerpc/shared/console/consoleIo.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/consoleIo.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/consoleIo.h
+
+$(PROJECT_INCLUDE)/bsp/uart.h: ../../powerpc/shared/console/uart.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/uart.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/uart.h
+
+$(PROJECT_INCLUDE)/bsp/motorola.h: ../../powerpc/shared/motorola/motorola.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/motorola.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/motorola.h
+
+$(PROJECT_INCLUDE)/bsp/openpic.h: ../../powerpc/shared/openpic/openpic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/openpic.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/openpic.h
+
+$(PROJECT_INCLUDE)/bsp/pci.h: ../../powerpc/shared/pci/pci.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pci.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pci.h
+
+$(PROJECT_INCLUDE)/bsp/residual.h: ../../powerpc/shared/residual/residual.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/residual.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/residual.h
+
+$(PROJECT_INCLUDE)/bsp/pnp.h: ../../powerpc/shared/residual/pnp.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/pnp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/pnp.h
+
+$(PROJECT_INCLUDE)/bsp/irq.h: ../../powerpc/shared/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: ../../powerpc/shared/vectors/vectors.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vectors.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vectors.h
+
+$(PROJECT_INCLUDE)/bsp/vmeUniverse.h: ../../shared/vmeUniverse/vmeUniverse.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/vmeUniverse.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/vmeUniverse.h
+
+$(PROJECT_INCLUDE)/bsp/VMEConfig.h: ../../powerpc/shared/vme/VMEConfig.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VMEConfig.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VMEConfig.h
+
+$(PROJECT_INCLUDE)/bsp/VME.h: ../../powerpc/shared/vme/VME.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/VME.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/VME.h
+
+if HAS_NETWORKING
+endif
+
+$(PROJECT_LIB)/rtems_crti.$(OBJEXT): rtems_crti.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/rtems_crti.$(OBJEXT)
+
+$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
+TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
+
+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/ep1a/bsp_specs b/c/src/lib/libbsp/powerpc/ep1a/bsp_specs
new file mode 100644
index 0000000000..de37ca1f7f
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/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 rtems_crti%O%s crtbegin.o%s \
+%{!qrtems_debug: start.o%s} \
+%{qrtems_debug: start_g.o%s}}}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -e __rtems_entry_point -u __vectors}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s ecrtn.o%s}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/configure.ac b/c/src/lib/libbsp/powerpc/ep1a/configure.ac
new file mode 100644
index 0000000000..3e63bc14ed
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/configure.ac
@@ -0,0 +1,30 @@
+## Process this file with autoconf to produce a configure script.
+##
+## $Id$
+
+AC_PREREQ(2.59)
+AC_INIT([rtems-c-src-lib-libbsp-powerpc-ep1a],[_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([CONSOLE_USE_INTERRUPTS],[*],[0])
+RTEMS_BSPOPTS_HELP([CONSOLE_USE_INTERRUPTS],
+[whether using console interrupts])
+
+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/ep1a/console/alloc360.c b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
new file mode 100644
index 0000000000..1ed1aca3f4
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
@@ -0,0 +1,104 @@
+/*
+ * MC68360 buffer descriptor allocation routines
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "m68360.h"
+#include <rtems/error.h>
+#include "rsPMCQ1.h"
+#include <rtems/bspIo.h>
+
+void M360SetupMemory( M68360_t ptr ){
+ volatile m360_t *m360;
+
+ m360 = ptr->m360;
+
+ ptr->bdregions[0].base = (char *)&m360->dpram1[0];
+ ptr->bdregions[0].size = sizeof m360->dpram1;
+ ptr->bdregions[0].used = 0;
+
+ ptr->bdregions[1].base = (char *)&m360->dpram3[0];
+ ptr->bdregions[1].size = sizeof m360->dpram3;
+ ptr->bdregions[1].used = 0;
+
+ ptr->bdregions[2].base = (char *)&m360->dpram0[0];
+ ptr->bdregions[2].size = sizeof m360->dpram0;
+ ptr->bdregions[2].used = 0;
+
+ ptr->bdregions[3].base = (char *)&m360->dpram2[0];
+ ptr->bdregions[3].size = sizeof m360->dpram2;
+ ptr->bdregions[3].used = 0;
+}
+
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+void *
+M360AllocateBufferDescriptors (M68360_t ptr, int count)
+{
+ unsigned int i;
+ ISR_Level level;
+ void *bdp = NULL;
+ unsigned int want = count * sizeof(m360BufferDescriptor_t);
+ int have;
+
+ /*
+ * Running with interrupts disabled is usually considered bad
+ * form, but this routine is probably being run as part of an
+ * initialization sequence so the effect shouldn't be too severe.
+ */
+ _ISR_Disable (level);
+
+ for (i = 0 ; i < M360_NUM_DPRAM_REAGONS ; i++) {
+
+ /*
+ * Verify that the region exists.
+ * This test is necessary since some chips have
+ * less dual-port RAM.
+ */
+ if (ptr->bdregions[i].used == 0) {
+ volatile unsigned char *cp = ptr->bdregions[i].base;
+ *cp = 0xAA;
+ if (*cp != 0xAA) {
+ ptr->bdregions[i].used = ptr->bdregions[i].size;
+ continue;
+ }
+ *cp = 0x55;
+ if (*cp != 0x55) {
+ ptr->bdregions[i].used = ptr->bdregions[i].size;
+ continue;
+ }
+ *cp = 0x0;
+ }
+
+ have = ptr->bdregions[i].size - ptr->bdregions[i].used;
+ if (have >= want) {
+ bdp = ptr->bdregions[i].base + ptr->bdregions[i].used;
+ ptr->bdregions[i].used += want;
+ break;
+ }
+ }
+ _ISR_Enable (level);
+ if (bdp == NULL){
+ printk("rtems_panic can't allocate %d buffer descriptor(s).\n");
+ rtems_panic ("Can't allocate %d buffer descriptor(s).\n", count);
+ }
+ return bdp;
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.c b/c/src/lib/libbsp/powerpc/ep1a/console/console.c
new file mode 100644
index 0000000000..87f40d1c3c
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.c
@@ -0,0 +1,350 @@
+/*
+ * This file contains the TTY driver for the ep1a
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <termios.h>
+
+#include "console.h"
+#include <rtems/bspIo.h>
+
+/*
+ * Load configuration table
+ */
+#include "config.c"
+
+#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
+
+console_data Console_Port_Data[NUM_CONSOLE_PORTS];
+unsigned long Console_Port_Count;
+rtems_device_minor_number Console_Port_Minor;
+
+/* PAGE
+ *
+ * console_open
+ *
+ * open a port as a termios console.
+ *
+ */
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code status;
+ rtems_libio_open_close_args_t *args = arg;
+ rtems_libio_ioctl_args_t IoctlArgs;
+ struct termios Termios;
+ rtems_termios_callbacks Callbacks;
+ console_fns *c;
+
+ /*
+ * Verify the port number is valid.
+ */
+ if(minor>Console_Port_Count)
+ {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /*
+ * open the port as a termios console driver.
+ */
+ c = Console_Port_Tbl[minor].pDeviceFns;
+ Callbacks.firstOpen = c->deviceFirstOpen;
+ Callbacks.lastClose = c->deviceLastClose;
+ Callbacks.pollRead = c->deviceRead;
+ Callbacks.write = c->deviceWrite;
+ Callbacks.setAttributes = c->deviceSetAttributes;
+ Callbacks.stopRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx;
+ Callbacks.startRemoteTx =
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx;
+ Callbacks.outputUsesInterrupts = c->deviceOutputUsesInterrupts;
+ status = rtems_termios_open ( major, minor, arg, &Callbacks);
+ Console_Port_Data[minor].termios_data = args->iop->data1;
+
+ if(minor!=Console_Port_Minor)
+ {
+ /*
+ * If this is not the console we do not want ECHO and
+ * so forth
+ */
+ IoctlArgs.iop=args->iop;
+ IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
+ IoctlArgs.buffer=&Termios;
+ rtems_termios_ioctl(&IoctlArgs);
+ Termios.c_lflag=ICANON;
+ IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
+ rtems_termios_ioctl(&IoctlArgs);
+ }
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
+ }
+
+ return status;
+}
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_open_close_args_t *args = arg;
+
+ if((args->iop->flags&LIBIO_FLAGS_READ) &&
+ Console_Port_Tbl[minor].pDeviceFlow &&
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx)
+ {
+ Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
+ }
+
+ return rtems_termios_close (arg);
+}
+
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * Routine called to initialize the console device driver.
+ */
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+ Console_Port_Count=NUM_CONSOLE_PORTS;
+
+ for(minor=0;
+ minor<Console_Port_Count;
+ minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ /*
+ * Use this device for the console
+ */
+ break;
+ }
+ }
+ if(minor==Console_Port_Count)
+ {
+ /*
+ * Failed to find a working device
+ */
+ rtems_fatal_error_occurred(RTEMS_IO_ERROR);
+ }
+
+ Console_Port_Minor=minor;
+
+ /*
+ * Register Device Names
+ */
+
+ status = rtems_io_register_name("/dev/console",
+ major,
+ Console_Port_Minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+ if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(
+ Console_Port_Minor);
+
+ for(minor++;minor<Console_Port_Count;minor++)
+ {
+ /*
+ * First perform the configuration dependant probe, then the
+ * device dependant probe
+ */
+ if((!Console_Port_Tbl[minor].deviceProbe ||
+ Console_Port_Tbl[minor].deviceProbe(minor)) &&
+ Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
+ {
+ status = rtems_io_register_name(
+ Console_Port_Tbl[minor].sDeviceName,
+ major,
+ minor );
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+
+ /*
+ * Initialize the hardware device.
+ */
+ if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
+ Console_Port_Tbl[minor].pDeviceFns->deviceInitialize( minor);
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * DEBUG_puts
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * string - pointer to debug output string
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void DEBUG_puts(
+ char *string
+)
+{
+ char *s;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ for ( s = string ; *s ; s++ )
+ {
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, *s);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
+/* PAGE
+ *
+ * DEBUG_puth
+ *
+ * This should be safe in the event of an error. It attempts to ensure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * ulHexNum - value to display
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void
+DEBUG_puth(
+ unsigned32 ulHexNum
+ )
+{
+ unsigned long i,d;
+ unsigned32 Irql;
+
+ rtems_interrupt_disable(Irql);
+
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, '0');
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor, 'x');
+
+ for(i=32;i;)
+ {
+ i-=4;
+ d=(ulHexNum>>i)&0xf;
+ Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
+ deviceWritePolled(Console_Port_Minor,
+ (d<=9) ? d+'0' : d+'a'-0xa);
+ }
+
+ rtems_interrupt_enable(Irql);
+}
+
+
+/* const char arg to be compatible with BSP_output_char decl. */
+void
+debug_putc_onlcr(const char c)
+{
+ volatile int i;
+
+ /*
+ * Note: Hack to get printk to work. Depends upon bit
+ * and silverchip to initialize the port and just
+ * forces a character to be polled out of com1
+ * regardless of where the console is.
+ */
+
+ volatile unsigned char *ptr = (void *)0xff800000;
+
+ if ('\n'==c){
+ *ptr = '\r';
+ asm volatile("sync");
+ for (i=0;i<0x0fff;i++);
+ }
+
+ *ptr = c;
+ asm volatile("sync");
+ for (i=0;i<0x0fff;i++);
+}
+
+BSP_output_char_function_type BSP_output_char = debug_putc_onlcr;
+/* const char arg to be compatible with BSP_output_char decl. */
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.h b/c/src/lib/libbsp/powerpc/ep1a/console/console.h
new file mode 100644
index 0000000000..1ea45595bd
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.h
@@ -0,0 +1,38 @@
+/*
+ * This file contains the TTY driver table definition for the PPCn_60x
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ *
+ * 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.
+ *
+ * $Id$
+*/
+
+#include <rtems/ringbuf.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+
+extern console_tbl Console_Port_Tbl[];
+extern console_data Console_Port_Data[];
+extern unsigned long Console_Port_Count;
+
+boolean Console_Port_Tbl_Init_ppc8245(int minor);
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c b/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
new file mode 100644
index 0000000000..1bc1be3aad
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
@@ -0,0 +1,670 @@
+/*
+ * MC68360 support routines
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "m68360.h"
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+
+void M360ExecuteRISC( volatile m360_t *m360, rtems_unsigned16 command)
+{
+ rtems_unsigned16 sr;
+
+ rtems_interrupt_disable(sr);
+ while (m360->cr & M360_CR_FLG)
+ continue;
+ m360->cr = command | M360_CR_FLG;
+ rtems_interrupt_enable(sr);
+}
+
+
+#if 0
+/*
+ * Initialize MC68360
+ */
+void _Init68360 (void)
+{
+ int i;
+ m68k_isr_entry *vbr;
+ unsigned long ramSize;
+ extern void _CopyDataClearBSSAndStart (unsigned long ramSize);
+
+#if (defined (__mc68040__))
+ /*
+ *******************************************
+ * Motorola 68040 and companion-mode 68360 *
+ *******************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x83; /* No more writes, full-power CLKO2 */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT standard M68000 family interrupt level encoding
+ * CF1MODE=10 (BCLRO* output)
+ * No RAS1* double drive
+ * A31 - A28
+ * AMUX output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ */
+ m360.pepar = 0x3440;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ */
+ /*
+ * 512 addresses per DRAM page (256K DRAM chips)
+ * 70 nsec DRAM
+ * 180 nsec ROM (3 wait states)
+ */
+ m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN |
+ M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
+ M360_GMR_DPS_32BIT | M360_GMR_NCS |
+ M360_GMR_TSS40;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_32BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ */
+ /*
+ * Set up option/base registers
+ * 1M DRAM
+ * 70 nsec DRAM
+ * Enable burst mode
+ * No parity checking
+ * Wait for chips to power up
+ * Perform 8 read cycles
+ */
+ ramSize = 1 * 1024 * 1024;
+ m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
+ M360_MEMC_OR_1MB |
+ M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase |
+ M360_MEMC_BR_BACK40 |
+ M360_MEMC_BR_V;
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Bus request MC68040 Arbitration ID 3
+ * Bus asynchronous timing mode (work around bug in Rev. B)
+ * Arbitration asynchronous timing mode
+ * Disable timers during FREEZE
+ * Disable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear in arbitration ID level 3
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x6000EC3F;
+
+#elif (defined (M68360_ATLAS_HSB))
+ /*
+ ******************************************
+ * Standalone Motorola 68360 -- ATLAS HSB *
+ ******************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a CPU32+ reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * RAS1* double drive
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0180;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ */
+ m360.gmr = M360_GMR_RCNT(12) | M360_GMR_RFEN |
+ M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
+ M360_GMR_DPS_32BIT | M360_GMR_DWQ |
+ M360_GMR_GAMX;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_8BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ */
+ ramSize = 2 * 1024 * 1024;
+ /* first bank 1MByte DRAM */
+ m360.memc[1].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+
+ /* second bank 1MByte DRAM */
+ m360.memc[2].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
+ m360.memc[2].br = ((unsigned long)&_RamBase + 0x100000) |
+ M360_MEMC_BR_V;
+
+ /* flash rom socket U6 on CS5 */
+ m360.memc[5].br = (unsigned long)ATLASHSB_ROM_U6 | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[5].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
+ M360_MEMC_OR_8BIT;
+
+ /* CSRs on CS7 */
+ m360.memc[7].or = M360_MEMC_OR_TCYC(4) | M360_MEMC_OR_64KB |
+ M360_MEMC_OR_8BIT;
+ m360.memc[7].br = ATLASHSB_ESR | 0x01;
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ */
+
+#elif (defined (GEN68360_WITH_SRAM))
+ /*
+ ***************************************************
+ * Generic Standalone Motorola 68360 *
+ * As described in MC68360 User's Manual *
+ * But uses SRAM instead of DRAM *
+ * CS0* - 512kx8 flash memory *
+ * CS1* - 512kx32 static RAM *
+ * CS2* - 512kx32 static RAM *
+ ***************************************************
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external oscillator which
+ * oscillates at the system clock rate.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * IPIPE1*
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0080;
+
+ /*
+ * Step 11: Set up GMR
+ *
+ */
+ m360.gmr = 0x0;
+
+ /*
+ * Step 11a: Remap 512Kx8 flash memory on CS0*
+ * 2 wait states
+ * Make it read-only for now
+ */
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
+ M360_MEMC_OR_8BIT;
+ /*
+ * Step 12: Set up main memory
+ * 512Kx32 SRAM on CS1*
+ * 512Kx32 SRAM on CS2*
+ * 0 wait states
+ */
+ ramSize = 4 * 1024 * 1024;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+ m360.memc[1].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
+ M360_MEMC_OR_32BIT;
+ m360.memc[2].br = ((unsigned long)&_RamBase + 0x200000) | M360_MEMC_BR_V;
+ m360.memc[2].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
+ M360_MEMC_OR_32BIT;
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear interrupt service level 7
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x4C7F;
+
+#else
+ /*
+ ***************************************************
+ * Generic Standalone Motorola 68360 *
+ * As described in MC68360 User's Manual *
+ * Atlas ACE360 *
+ ***************************************************
+ */
+
+ /*
+ * Step 6: Is this a power-up reset?
+ * For now we just ignore this and do *all* the steps
+ * Someday we might want to:
+ * if (Hard, Loss of Clock, Power-up)
+ * Do all steps
+ * else if (Double bus fault, watchdog or soft reset)
+ * Skip to step 12
+ * else (must be a CPU32+ reset command)
+ * Skip to step 14
+ */
+
+ /*
+ * Step 7: Deal with clock synthesizer
+ * HARDWARE:
+ * Change if you're not using an external 25 MHz oscillator.
+ */
+ m360.clkocr = 0x8F; /* No more writes, no clock outputs */
+ m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
+ no LPSTOP slowdown, PLL X1 */
+ m360.cdvcr = 0x8000; /* No more writes, no clock division */
+
+ /*
+ * Step 8: Initialize system protection
+ * Enable watchdog
+ * Watchdog causes system reset
+ * Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
+ * Enable double bus fault monitor
+ * Enable bus monitor for external cycles
+ * 1024 clocks for external timeout
+ */
+ m360.sypcr = 0xEC;
+
+ /*
+ * Step 9: Clear parameter RAM and reset communication processor module
+ */
+ for (i = 0 ; i < 192 ; i += sizeof (long)) {
+ *((long *)((char *)&m360 + 0xC00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xD00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xE00 + i)) = 0;
+ *((long *)((char *)&m360 + 0xF00 + i)) = 0;
+ }
+ M360ExecuteRISC (M360_CR_RST);
+
+ /*
+ * Step 10: Write PEPAR
+ * SINTOUT not used (CPU32+ mode)
+ * CF1MODE=00 (CONFIG1 input)
+ * RAS1* double drive
+ * WE0* - WE3*
+ * OE* output
+ * CAS2* - CAS3*
+ * CAS0* - CAS1*
+ * CS7*
+ * AVEC*
+ * HARDWARE:
+ * Change if you are using a different memory configuration
+ * (static RAM, external address multiplexing, etc).
+ */
+ m360.pepar = 0x0180;
+
+ /*
+ * Step 11: Remap Chip Select 0 (CS0*), set up GMR
+ * 32-bit DRAM
+ * Internal DRAM address multiplexing
+ * 60 nsec DRAM
+ * 180 nsec ROM (3 wait states)
+ * 15.36 usec DRAM refresh interval
+ * The DRAM page size selection is not modified since this
+ * startup code may be running in a bootstrap PROM or in
+ * a program downloaded by the bootstrap PROM.
+ */
+ m360.gmr = (m360.gmr & 0x001C0000) | M360_GMR_RCNT(23) |
+ M360_GMR_RFEN | M360_GMR_RCYC(0) |
+ M360_GMR_DPS_32BIT | M360_GMR_NCS |
+ M360_GMR_GAMX;
+ m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
+ M360_MEMC_BR_V;
+ m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
+ M360_MEMC_OR_8BIT;
+
+ /*
+ * Step 12: Initialize the system RAM
+ * Do this only if the DRAM has not already been set up
+ */
+ if ((m360.memc[1].br & M360_MEMC_BR_V) == 0) {
+ /*
+ * Set up GMR DRAM page size, option and base registers
+ * Assume 16Mbytes of DRAM
+ * 60 nsec DRAM
+ */
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(5);
+ m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
+ M360_MEMC_OR_16MB |
+ M360_MEMC_OR_DRAM;
+ m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
+
+ /*
+ * Wait for chips to power up
+ * Perform 8 read cycles
+ */
+ for (i = 0; i < 50000; i++)
+ continue;
+ for (i = 0; i < 8; ++i)
+ *((volatile unsigned long *)(unsigned long)&_RamBase);
+
+ /*
+ * Determine memory size (1, 4, or 16 Mbytes)
+ * Set GMR DRAM page size appropriately.
+ * The OR is left at 16 Mbytes. The bootstrap PROM places its
+ * .data and .bss segments at the top of the 16 Mbyte space.
+ * A 1 Mbyte or 4 Mbyte DRAM will show up several times in
+ * the memory map, but will work with the same bootstrap PROM.
+ */
+ *(volatile char *)&_RamBase = 0;
+ *((volatile char *)&_RamBase+0x00C01800) = 1;
+ if (*(volatile char *)&_RamBase) {
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(1);
+ }
+ else {
+ *((volatile char *)&_RamBase+0x00801000) = 1;
+ if (*(volatile char *)&_RamBase) {
+ m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(3);
+ }
+ }
+
+ /*
+ * Enable parity checking
+ */
+ m360.memc[1].br |= M360_MEMC_BR_PAREN;
+ }
+ switch (m360.gmr & 0x001C0000) {
+ default: ramSize = 4 * 1024 * 1024; break;
+ case M360_GMR_PGS(1): ramSize = 1 * 1024 * 1024; break;
+ case M360_GMR_PGS(3): ramSize = 4 * 1024 * 1024; break;
+ case M360_GMR_PGS(5): ramSize = 16 * 1024 * 1024; break;
+ }
+
+ /*
+ * Step 13: Copy the exception vector table to system RAM
+ */
+ m68k_get_vbr (vbr);
+ for (i = 0; i < 256; ++i)
+ M68Kvec[i] = vbr[i];
+ m68k_set_vbr (M68Kvec);
+
+ /*
+ * Step 14: More system initialization
+ * SDCR (Serial DMA configuration register)
+ * Enable SDMA during FREEZE
+ * Give SDMA priority over all interrupt handlers
+ * Set DMA arbiration level to 4
+ * CICR (CPM interrupt configuration register):
+ * SCC1 requests at SCCa position
+ * SCC2 requests at SCCb position
+ * SCC3 requests at SCCc position
+ * SCC4 requests at SCCd position
+ * Interrupt request level 4
+ * Maintain original priority order
+ * Vector base 128
+ * SCCs priority grouped at top of table
+ */
+ m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
+ m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
+ (4 << 13) | (0x1F << 8) | (128);
+
+ /*
+ * Step 15: Set module configuration register
+ * Disable timers during FREEZE
+ * Enable bus monitor during FREEZE
+ * BCLRO* arbitration level 3
+ * No show cycles
+ * User/supervisor access
+ * Bus clear interrupt service level 7
+ * SIM60 interrupt sources higher priority than CPM
+ */
+ m360.mcr = 0x4C7F;
+#endif
+
+ /*
+ * Copy data, clear BSS, switch stacks and call main()
+ * Must pass ramSize as argument since the data/bss segment
+ * may be overwritten.
+ */
+ _CopyDataClearBSSAndStart (ramSize);
+}
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
new file mode 100644
index 0000000000..b5c972107a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
@@ -0,0 +1,973 @@
+/*
+ * MOTOROLA MC68360 QUAD INTEGRATED COMMUNICATIONS CONTROLLER (QUICC)
+ *
+ * HARDWARE DECLARATIONS
+ *
+ *
+ * Submitted By:
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * 107 North Road
+ * Saskatoon, Saskatchewan, CANADA
+ * S7N 5C6
+ *
+ * eric@skatter.usask.ca
+ *
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __MC68360_h
+#define __MC68360_h
+
+#include "rsPMCQ1.h"
+
+/*
+ *************************************************************************
+ * REGISTER SUBBLOCKS *
+ *************************************************************************
+ */
+
+/*
+ * Memory controller registers
+ */
+typedef struct m360MEMCRegisters_ {
+ uint32_t br;
+ uint32_t or;
+ uint32_t _pad[2];
+} m360MEMCRegisters_t;
+
+
+#define M360_GSMR_RFW 0x00000020
+#define M360_GSMR_TDCR_16X 0x00020000
+#define M360_GSMR_RDCR_16X 0x00008000
+#define M360_GSMR_MODE_UART 0x00000004
+#define M360_GSMR_DIAG_LLOOP 0x00000040
+#define M360_GSMR_ENR 0x00000020
+#define M360_GSMR_ENT 0x00000010
+
+#define M360_PSMR_FLC 0x8000
+#define M360_PSMR_SL 0x4000
+#define M360_PSMR_CL8 0x3000
+#define M360_PSMR_UM_NORMAL 0x0000
+#define M360_PSMR_FRZ 0x0200
+#define M360_PSMR_RZS 0x0100
+#define M360_PSMR_SYN 0x0080
+#define M360_PSMR_DRT 0x0040
+#define M360_PSMR_PEN 0x0010
+#define M360_PSMR_RPM_ODD 0x0000
+#define M360_PSMR_RPM_LOW 0x0004
+#define M360_PSMR_RPM_EVEN 0x0008
+#define M360_PSMR_RPM_HI 0x000c
+#define M360_PSMR_TPM_ODD 0x0000
+#define M360_PSMR_TPM_LOW 0x0001
+#define M360_PSMR_TPM_EVEN 0x0002
+#define M360_PSMR_TPM_HI 0x0003
+
+/*
+ * Serial Communications Controller registers
+ */
+typedef struct m360SCCRegisters_ {
+ uint32_t gsmr_l;
+ uint32_t gsmr_h;
+ uint16_t psmr;
+ uint16_t _pad0;
+ uint16_t todr;
+ uint16_t dsr;
+ uint16_t scce;
+ uint16_t _pad1;
+ uint16_t sccm;
+ uint8_t _pad2;
+ uint8_t sccs;
+ uint32_t _pad3[2];
+} m360SCCRegisters_t;
+
+/*
+ * Serial Management Controller registers
+ */
+typedef struct m360SMCRegisters_ {
+ uint16_t _pad0;
+ uint16_t smcmr;
+ uint16_t _pad1;
+ uint8_t smce;
+ uint8_t _pad2;
+ uint16_t _pad3;
+ uint8_t smcm;
+ uint8_t _pad4;
+ uint32_t _pad5;
+} m360SMCRegisters_t;
+
+
+/*
+ *************************************************************************
+ * Miscellaneous Parameters *
+ *************************************************************************
+ */
+typedef struct m360MiscParms_ {
+ uint16_t rev_num;
+ uint16_t _res1;
+ uint32_t _res2;
+ uint32_t _res3;
+} m360MiscParms_t;
+
+/*
+ *************************************************************************
+ * RISC Timers *
+ *************************************************************************
+ */
+typedef struct m360TimerParms_ {
+ uint16_t tm_base;
+ uint16_t _tm_ptr;
+ uint16_t _r_tmr;
+ uint16_t _r_tmv;
+ uint32_t tm_cmd;
+ uint32_t tm_cnt;
+} m360TimerParms_t;
+
+/*
+ * RISC Controller Configuration Register (RCCR)
+ * All other bits in this register are either reserved or
+ * used only with a Motorola-supplied RAM microcode packge.
+ */
+#define M360_RCCR_TIME (1<<15) /* Enable timer */
+#define M360_RCCR_TIMEP(x) ((x)<<8) /* Timer period */
+
+/*
+ * Command register
+ * Set up this register before issuing a M360_CR_OP_SET_TIMER command.
+ */
+#define M360_TM_CMD_V (1<<31) /* Set to enable timer */
+#define M360_TM_CMD_R (1<<30) /* Set for automatic restart */
+#define M360_TM_CMD_TIMER(x) ((x)<<16) /* Select timer */
+#define M360_TM_CMD_PERIOD(x) (x) /* Timer period (16 bits) */
+
+/*
+ *************************************************************************
+ * DMA Controllers *
+ *************************************************************************
+ */
+typedef struct m360IDMAparms_ {
+ uint16_t ibase;
+ uint16_t ibptr;
+ uint32_t _istate;
+ uint32_t _itemp;
+} m360IDMAparms_t;
+
+/*
+ *************************************************************************
+ * Serial Communication Controllers *
+ *************************************************************************
+ */
+typedef struct m360SCCparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ uint32_t _rcrc;
+ uint32_t _tcrc;
+ union {
+ struct {
+ uint32_t _res0;
+ uint32_t _res1;
+ uint16_t max_idl;
+ uint16_t _idlc;
+ uint16_t brkcr;
+ uint16_t parec;
+ uint16_t frmec;
+ uint16_t nosec;
+ uint16_t brkec;
+ uint16_t brklen;
+ uint16_t uaddr[2];
+ uint16_t _rtemp;
+ uint16_t toseq;
+ uint16_t character[8];
+ uint16_t rccm;
+ uint16_t rccr;
+ uint16_t rlbc;
+ } uart;
+ struct {
+ uint32_t crc_p;
+ uint32_t crc_c;
+ } transparent;
+
+ } un;
+} m360SCCparms_t;
+
+typedef struct m360SCCENparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ uint32_t _rcrc;
+ uint32_t _tcrc;
+ union {
+ struct {
+ uint32_t _res0;
+ uint32_t _res1;
+ uint16_t max_idl;
+ uint16_t _idlc;
+ uint16_t brkcr;
+ uint16_t parec;
+ uint16_t frmec;
+ uint16_t nosec;
+ uint16_t brkec;
+ uint16_t brklen;
+ uint16_t uaddr[2];
+ uint16_t _rtemp;
+ uint16_t toseq;
+ uint16_t character[8];
+ uint16_t rccm;
+ uint16_t rccr;
+ uint16_t rlbc;
+ } uart;
+ struct {
+ uint32_t c_pres;
+ uint32_t c_mask;
+ uint32_t crcec;
+ uint32_t alec;
+ uint32_t disfc;
+ uint16_t pads;
+ uint16_t ret_lim;
+ uint16_t _ret_cnt;
+ uint16_t mflr;
+ uint16_t minflr;
+ uint16_t maxd1;
+ uint16_t maxd2;
+ uint16_t _maxd;
+ uint16_t dma_cnt;
+ uint16_t _max_b;
+ uint16_t gaddr1;
+ uint16_t gaddr2;
+ uint16_t gaddr3;
+ uint16_t gaddr4;
+ uint32_t _tbuf0data0;
+ uint32_t _tbuf0data1;
+ uint32_t _tbuf0rba0;
+ uint32_t _tbuf0crc;
+ uint16_t _tbuf0bcnt;
+ uint16_t paddr_h;
+ uint16_t paddr_m;
+ uint16_t paddr_l;
+ uint16_t p_per;
+ uint16_t _rfbd_ptr;
+ uint16_t _tfbd_ptr;
+ uint16_t _tlbd_ptr;
+ uint32_t _tbuf1data0;
+ uint32_t _tbuf1data1;
+ uint32_t _tbuf1rba0;
+ uint32_t _tbuf1crc;
+ uint16_t _tbuf1bcnt;
+ uint16_t _tx_len;
+ uint16_t iaddr1;
+ uint16_t iaddr2;
+ uint16_t iaddr3;
+ uint16_t iaddr4;
+ uint16_t _boff_cnt;
+ uint16_t taddr_h;
+ uint16_t taddr_m;
+ uint16_t taddr_l;
+ } ethernet;
+ struct {
+ uint32_t crc_p;
+ uint32_t crc_c;
+ } transparent;
+ } un;
+} m360SCCENparms_t;
+
+/*
+ * Receive and transmit function code register bits
+ * These apply to the function code registers of all devices, not just SCC.
+ */
+#define M360_RFCR_MOT (1<<4)
+#define M360_RFCR_DMA_SPACE 0x8
+#define M360_TFCR_MOT (1<<4)
+#define M360_TFCR_DMA_SPACE 0x8
+
+/*
+ *************************************************************************
+ * Serial Management Controllers *
+ *************************************************************************
+ */
+typedef struct m360SMCparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+ union {
+ struct {
+ uint16_t max_idl;
+ uint16_t _pad0;
+ uint16_t brklen;
+ uint16_t brkec;
+ uint16_t brkcr;
+ uint16_t _r_mask;
+ } uart;
+ struct {
+ uint16_t _pad0[5];
+ } transparent;
+ } un;
+} m360SMCparms_t;
+
+/*
+ * Mode register
+ */
+#define M360_SMCMR_CLEN(x) ((x)<<11) /* Character length */
+#define M360_SMCMR_2STOP (1<<10) /* 2 stop bits */
+#define M360_SMCMR_PARITY (1<<9) /* Enable parity */
+#define M360_SMCMR_EVEN (1<<8) /* Even parity */
+#define M360_SMCMR_SM_GCI (0<<4) /* GCI Mode */
+#define M360_SMCMR_SM_UART (2<<4) /* UART Mode */
+#define M360_SMCMR_SM_TRANSPARENT (3<<4) /* Transparent Mode */
+#define M360_SMCMR_DM_LOOPBACK (1<<2) /* Local loopback mode */
+#define M360_SMCMR_DM_ECHO (2<<2) /* Echo mode */
+#define M360_SMCMR_TEN (1<<1) /* Enable transmitter */
+#define M360_SMCMR_REN (1<<0) /* Enable receiver */
+
+/*
+ * Event and mask registers (SMCE, SMCM)
+ */
+#define M360_SMCE_BRK (1<<4)
+#define M360_SMCE_BSY (1<<2)
+#define M360_SMCE_TX (1<<1)
+#define M360_SMCE_RX (1<<0)
+
+/*
+ *************************************************************************
+ * Serial Peripheral Interface *
+ *************************************************************************
+ */
+typedef struct m360SPIparms_ {
+ uint16_t rbase;
+ uint16_t tbase;
+ uint8_t rfcr;
+ uint8_t tfcr;
+ uint16_t mrblr;
+ uint32_t _rstate;
+ uint32_t _pad0;
+ uint16_t _rbptr;
+ uint16_t _pad1;
+ uint32_t _pad2;
+ uint32_t _tstate;
+ uint32_t _pad3;
+ uint16_t _tbptr;
+ uint16_t _pad4;
+ uint32_t _pad5;
+} m360SPIparms_t;
+
+/*
+ * Mode register (SPMODE)
+ */
+#define M360_SPMODE_LOOP (1<<14) /* Local loopback mode */
+#define M360_SPMODE_CI (1<<13) /* Clock invert */
+#define M360_SPMODE_CP (1<<12) /* Clock phase */
+#define M360_SPMODE_DIV16 (1<<11) /* Divide BRGCLK by 16 */
+#define M360_SPMODE_REV (1<<10) /* Reverse data */
+#define M360_SPMODE_MASTER (1<<9) /* SPI is master */
+#define M360_SPMODE_EN (1<<8) /* Enable SPI */
+#define M360_SPMODE_CLEN(x) ((x)<<4) /* Character length */
+#define M360_SPMODE_PM(x) (x) /* Prescaler modulus */
+
+/*
+ * Mode register (SPCOM)
+ */
+#define M360_SPCOM_STR (1<<7) /* Start transmit */
+
+/*
+ * Event and mask registers (SPIE, SPIM)
+ */
+#define M360_SPIE_MME (1<<5) /* Multi-master error */
+#define M360_SPIE_TXE (1<<4) /* Tx error */
+#define M360_SPIE_BSY (1<<2) /* Busy condition*/
+#define M360_SPIE_TXB (1<<1) /* Tx buffer */
+#define M360_SPIE_RXB (1<<0) /* Rx buffer */
+
+/*
+ *************************************************************************
+ * SDMA (SCC, SMC, SPI) Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360BufferDescriptor_ {
+ uint16_t status;
+ uint16_t length;
+ uint32_t buffer; /* this is a void * to the 360 */
+} m360BufferDescriptor_t;
+
+/*
+ * Bits in receive buffer descriptor status word
+ */
+#define M360_BD_EMPTY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_WRAP (1<<13) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_INTERRUPT (1<<12) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_LAST (1<<11) /* Ethernet, SPI */
+#define M360_BD_CONTROL_CHAR (1<<11) /* SCC UART */
+#define M360_BD_FIRST_IN_FRAME (1<<10) /* Ethernet */
+#define M360_BD_ADDRESS (1<<10) /* SCC UART */
+#define M360_BD_CONTINUOUS (1<<9) /* SCC UART, SMC UART, SPI */
+#define M360_BD_MISS (1<<8) /* Ethernet */
+#define M360_BD_IDLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_ADDRSS_MATCH (1<<7) /* SCC UART */
+#define M360_BD_LONG (1<<5) /* Ethernet */
+#define M360_BD_BREAK (1<<5) /* SCC UART, SMC UART */
+#define M360_BD_NONALIGNED (1<<4) /* Ethernet */
+#define M360_BD_FRAMING_ERROR (1<<4) /* SCC UART, SMC UART */
+#define M360_BD_SHORT (1<<3) /* Ethernet */
+#define M360_BD_PARITY_ERROR (1<<3) /* SCC UART, SMC UART */
+#define M360_BD_CRC_ERROR (1<<2) /* Ethernet */
+#define M360_BD_OVERRUN (1<<1) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_COLLISION (1<<0) /* Ethernet */
+#define M360_BD_CARRIER_LOST (1<<0) /* SCC UART */
+#define M360_BD_MASTER_ERROR (1<<0) /* SPI */
+
+/*
+ * Bits in transmit buffer descriptor status word
+ * Many bits have the same meaning as those in receiver buffer descriptors.
+ */
+#define M360_BD_READY (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M360_BD_PAD (1<<14) /* Ethernet */
+#define M360_BD_CTS_REPORT (1<<11) /* SCC UART */
+#define M360_BD_TX_CRC (1<<10) /* Ethernet */
+#define M360_BD_DEFER (1<<9) /* Ethernet */
+#define M360_BD_HEARTBEAT (1<<8) /* Ethernet */
+#define M360_BD_PREAMBLE (1<<8) /* SCC UART, SMC UART */
+#define M360_BD_LATE_COLLISION (1<<7) /* Ethernet */
+#define M360_BD_NO_STOP_BIT (1<<7) /* SCC UART */
+#define M360_BD_RETRY_LIMIT (1<<6) /* Ethernet */
+#define M360_BD_RETRY_COUNT(x) (((x)&0x3C)>>2) /* Ethernet */
+#define M360_BD_UNDERRUN (1<<1) /* Ethernet, SPI */
+#define M360_BD_CARRIER_LOST (1<<0) /* Ethernet */
+#define M360_BD_CTS_LOST (1<<0) /* SCC UART */
+
+/*
+ *************************************************************************
+ * IDMA Buffer Descriptors *
+ *************************************************************************
+ */
+typedef struct m360IDMABufferDescriptor_ {
+ uint16_t status;
+ uint16_t _pad;
+ uint32_t length;
+ void *source;
+ void *destination;
+} m360IDMABufferDescriptor_t;
+
+/*
+ *************************************************************************
+ * RISC Communication Processor Module Command Register (CR) *
+ *************************************************************************
+ */
+#define M360_CR_RST (1<<15) /* Reset communication processor */
+#define M360_CR_OP_INIT_RX_TX (0<<8) /* SCC, SMC UART, SMC GCI, SPI */
+#define M360_CR_OP_INIT_RX (1<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_TX (2<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_INIT_HUNT (3<<8) /* SCC, SMC UART */
+#define M360_CR_OP_STOP_TX (4<<8) /* SCC, SMC UART */
+#define M360_CR_OP_GR_STOP_TX (5<<8) /* SCC */
+#define M360_CR_OP_INIT_IDMA (5<<8) /* IDMA */
+#define M360_CR_OP_RESTART_TX (6<<8) /* SCC, SMC UART */
+#define M360_CR_OP_CLOSE_RX_BD (7<<8) /* SCC, SMC UART, SPI */
+#define M360_CR_OP_SET_GRP_ADDR (8<<8) /* SCC */
+#define M360_CR_OP_SET_TIMER (8<<8) /* Timer */
+#define M360_CR_OP_GCI_TIMEOUT (9<<8) /* SMC GCI */
+#define M360_CR_OP_RESERT_BCS (10<<8) /* SCC */
+#define M360_CR_OP_GCI_ABORT (10<<8) /* SMC GCI */
+#define M360_CR_CHAN_SCC1 (0<<4) /* Channel selection */
+#define M360_CR_CHAN_SCC2 (4<<4)
+#define M360_CR_CHAN_SPI (5<<4)
+#define M360_CR_CHAN_TIMER (5<<4)
+#define M360_CR_CHAN_SCC3 (8<<4)
+#define M360_CR_CHAN_SMC1 (9<<4)
+#define M360_CR_CHAN_IDMA1 (9<<4)
+#define M360_CR_CHAN_SCC4 (12<<4)
+#define M360_CR_CHAN_SMC2 (13<<4)
+#define M360_CR_CHAN_IDMA2 (13<<4)
+#define M360_CR_FLG (1<<0) /* Command flag */
+
+/*
+ *************************************************************************
+ * System Protection Control Register (SYPCR) *
+ *************************************************************************
+ */
+#define M360_SYPCR_SWE (1<<7) /* Software watchdog enable */
+#define M360_SYPCR_SWRI (1<<6) /* Software watchdog reset select */
+#define M360_SYPCR_SWT1 (1<<5) /* Software watchdog timing bit 1 */
+#define M360_SYPCR_SWT0 (1<<4) /* Software watchdog timing bit 0 */
+#define M360_SYPCR_DBFE (1<<3) /* Double bus fault monitor enable */
+#define M360_SYPCR_BME (1<<2) /* Bus monitor external enable */
+#define M360_SYPCR_BMT1 (1<<1) /* Bus monitor timing bit 1 */
+#define M360_SYPCR_BMT0 (1<<0) /* Bus monitor timing bit 0 */
+
+/*
+ *************************************************************************
+ * Memory Control Registers *
+ *************************************************************************
+ */
+#define M360_GMR_RCNT(x) ((x)<<24) /* Refresh count */
+#define M360_GMR_RFEN (1<<23) /* Refresh enable */
+#define M360_GMR_RCYC(x) ((x)<<21) /* Refresh cycle length */
+#define M360_GMR_PGS(x) ((x)<<18) /* Page size */
+#define M360_GMR_DPS_32BIT (0<<16) /* DRAM port size */
+#define M360_GMR_DPS_16BIT (1<<16)
+#define M360_GMR_DPS_8BIT (2<<16)
+#define M360_GMR_DPS_DSACK (3<<16)
+#define M360_GMR_WBT40 (1<<15) /* Wait between 040 transfers */
+#define M360_GMR_WBTQ (1<<14) /* Wait between 360 transfers */
+#define M360_GMR_SYNC (1<<13) /* Synchronous external access */
+#define M360_GMR_EMWS (1<<12) /* External master wait state */
+#define M360_GMR_OPAR (1<<11) /* Odd parity */
+#define M360_GMR_PBEE (1<<10) /* Parity bus error enable */
+#define M360_GMR_TSS40 (1<<9) /* TS* sample for 040 */
+#define M360_GMR_NCS (1<<8) /* No CPU space */
+#define M360_GMR_DWQ (1<<7) /* Delay write for 360 */
+#define M360_GMR_DW40 (1<<6) /* Delay write for 040 */
+#define M360_GMR_GAMX (1<<5) /* Global address mux enable */
+
+#define M360_MEMC_BR_FC(x) ((x)<<7) /* Function code limit */
+#define M360_MEMC_BR_TRLXQ (1<<6) /* Relax timing requirements */
+#define M360_MEMC_BR_BACK40 (1<<5) /* Burst acknowledge to 040 */
+#define M360_MEMC_BR_CSNT40 (1<<4) /* CS* negate timing for 040 */
+#define M360_MEMC_BR_CSNTQ (1<<3) /* CS* negate timing for 360 */
+#define M360_MEMC_BR_PAREN (1<<2) /* Enable parity checking */
+#define M360_MEMC_BR_WP (1<<1) /* Write Protect */
+#define M360_MEMC_BR_V (1<<0) /* Base/Option register are valid */
+
+#define M360_MEMC_OR_TCYC(x) ((x)<<28) /* Cycle length (clocks) */
+#define M360_MEMC_OR_WAITS(x) M360_MEMC_OR_TCYC((x)+1)
+#define M360_MEMC_OR_2KB 0x0FFFF800 /* Address range */
+#define M360_MEMC_OR_4KB 0x0FFFF000
+#define M360_MEMC_OR_8KB 0x0FFFE000
+#define M360_MEMC_OR_16KB 0x0FFFC000
+#define M360_MEMC_OR_32KB 0x0FFF8000
+#define M360_MEMC_OR_64KB 0x0FFF0000
+#define M360_MEMC_OR_128KB 0x0FFE0000
+#define M360_MEMC_OR_256KB 0x0FFC0000
+#define M360_MEMC_OR_512KB 0x0FF80000
+#define M360_MEMC_OR_1MB 0x0FF00000
+#define M360_MEMC_OR_2MB 0x0FE00000
+#define M360_MEMC_OR_4MB 0x0FC00000
+#define M360_MEMC_OR_8MB 0x0F800000
+#define M360_MEMC_OR_16MB 0x0F000000
+#define M360_MEMC_OR_32MB 0x0E000000
+#define M360_MEMC_OR_64MB 0x0C000000
+#define M360_MEMC_OR_128MB 0x08000000
+#define M360_MEMC_OR_256MB 0x00000000
+#define M360_MEMC_OR_FCMC(x) ((x)<<7) /* Function code mask */
+#define M360_MEMC_OR_BCYC(x) ((x)<<5) /* Burst cycle length (clocks) */
+#define M360_MEMC_OR_PGME (1<<3) /* Page mode enable */
+#define M360_MEMC_OR_32BIT (0<<1) /* Port size */
+#define M360_MEMC_OR_16BIT (1<<1)
+#define M360_MEMC_OR_8BIT (2<<1)
+#define M360_MEMC_OR_DSACK (3<<1)
+#define M360_MEMC_OR_DRAM (1<<0) /* Dynamic RAM select */
+
+/*
+ *************************************************************************
+ * SI Mode Register (SIMODE) *
+ *************************************************************************
+ */
+#define M360_SI_SMC2_BITS 0xFFFF0000 /* All SMC2 bits */
+#define M360_SI_SMC2_TDM (1<<31) /* Multiplexed SMC2 */
+#define M360_SI_SMC2_BRG1 (0<<28) /* SMC2 clock souce */
+#define M360_SI_SMC2_BRG2 (1<<28)
+#define M360_SI_SMC2_BRG3 (2<<28)
+#define M360_SI_SMC2_BRG4 (3<<28)
+#define M360_SI_SMC2_CLK5 (0<<28)
+#define M360_SI_SMC2_CLK6 (1<<28)
+#define M360_SI_SMC2_CLK7 (2<<28)
+#define M360_SI_SMC2_CLK8 (3<<28)
+#define M360_SI_SMC1_BITS 0x0000FFFF /* All SMC1 bits */
+#define M360_SI_SMC1_TDM (1<<15) /* Multiplexed SMC1 */
+#define M360_SI_SMC1_BRG1 (0<<12) /* SMC1 clock souce */
+#define M360_SI_SMC1_BRG2 (1<<12)
+#define M360_SI_SMC1_BRG3 (2<<12)
+#define M360_SI_SMC1_BRG4 (3<<12)
+#define M360_SI_SMC1_CLK1 (0<<12)
+#define M360_SI_SMC1_CLK2 (1<<12)
+#define M360_SI_SMC1_CLK3 (2<<12)
+#define M360_SI_SMC1_CLK4 (3<<12)
+
+/*
+ *************************************************************************
+ * SDMA Configuration Register (SDMA) *
+ *************************************************************************
+ */
+#define M360_SDMA_FREEZE (2<<13) /* Freeze on next bus cycle */
+#define M360_SDMA_SISM_7 (7<<8) /* Normal interrupt service mask */
+#define M360_SDMA_SAID_4 (4<<4) /* Normal arbitration ID */
+#define M360_SDMA_INTE (1<<1) /* SBER interrupt enable */
+#define M360_SDMA_INTB (1<<0) /* SBKP interrupt enable */
+
+/*
+ *************************************************************************
+ * Baud (sic) Rate Generators *
+ *************************************************************************
+ */
+#define M360_BRG_RST (1<<17) /* Reset generator */
+#define M360_BRG_EN (1<<16) /* Enable generator */
+#define M360_BRG_EXTC_BRGCLK (0<<14) /* Source is BRGCLK */
+#define M360_BRG_EXTC_CLK2 (1<<14) /* Source is CLK2 pin */
+#define M360_BRG_EXTC_CLK6 (2<<14) /* Source is CLK6 pin */
+#define M360_BRG_ATB (1<<13) /* Autobaud */
+#define M360_BRG_115200 (13<<1) /* Assume 25 MHz clock */
+#define M360_BRG_57600 (26<<1)
+#define M360_BRG_38400 (40<<1)
+#define M360_BRG_19200 (80<<1)
+#define M360_BRG_9600 (162<<1)
+#define M360_BRG_4800 (324<<1)
+#define M360_BRG_2400 (650<<1)
+#define M360_BRG_1200 (1301<<1)
+#define M360_BRG_600 (2603<<1)
+#define M360_BRG_300 ((324<<1) | 1)
+#define M360_BRG_150 ((650<<1) | 1)
+#define M360_BRG_75 ((1301<<1) | 1)
+
+/*
+ *************************************************************************
+ * sccm Bit Settings *
+ *************************************************************************
+ */
+#define M360_SCCE_TX 0x02
+#define M360_SCCE_RX 0x01
+
+#define M360_CR_INIT_TX_RX_PARAMS 0x0000
+#define M360_CR_CH_NUM 0x0040
+
+#define M360_NUM_DPRAM_REAGONS 4
+/*
+ *************************************************************************
+ * MC68360 DUAL-PORT RAM AND REGISTERS *
+ *************************************************************************
+ */
+typedef struct m360_ {
+ /*
+ * Dual-port RAM
+ */
+ volatile uint8_t dpram0[0x400]; /* Microcode program */
+ volatile uint8_t dpram1[0x200];
+ volatile uint8_t dpram2[0x100]; /* Microcode scratch */
+ volatile uint8_t dpram3[0x100]; /* Not on REV A or B masks */
+ volatile uint8_t _rsv0[0xC00-0x800];
+ volatile m360SCCENparms_t scc1p;
+ volatile uint8_t _rsv1[0xCB0-0xC00-sizeof(m360SCCENparms_t)];
+ volatile m360MiscParms_t miscp;
+ volatile uint8_t _rsv2[0xD00-0xCB0-sizeof(m360MiscParms_t)];
+ volatile m360SCCparms_t scc2p;
+ volatile uint8_t _rsv3[0xD80-0xD00-sizeof(m360SCCparms_t)];
+ volatile m360SPIparms_t spip;
+ volatile uint8_t _rsv4[0xDB0-0xD80-sizeof(m360SPIparms_t)];
+ volatile m360TimerParms_t tmp;
+ volatile uint8_t _rsv5[0xE00-0xDB0-sizeof(m360TimerParms_t)];
+ volatile m360SCCparms_t scc3p;
+ volatile uint8_t _rsv6[0xE70-0xE00-sizeof(m360SCCparms_t)];
+ volatile m360IDMAparms_t idma1p;
+ volatile uint8_t _rsv7[0xE80-0xE70-sizeof(m360IDMAparms_t)];
+ volatile m360SMCparms_t smc1p;
+ volatile uint8_t _rsv8[0xF00-0xE80-sizeof(m360SMCparms_t)];
+ volatile m360SCCparms_t scc4p;
+ volatile uint8_t _rsv9[0xF70-0xF00-sizeof(m360SCCparms_t)];
+ volatile m360IDMAparms_t idma2p;
+ volatile uint8_t _rsv10[0xF80-0xF70-sizeof(m360IDMAparms_t)];
+ volatile m360SMCparms_t smc2p;
+ volatile uint8_t _rsv11[0x1000-0xF80-sizeof(m360SMCparms_t)];
+
+ /*
+ * SIM Block
+ */
+ volatile uint32_t mcr;
+ volatile uint32_t _pad00;
+ volatile uint8_t avr;
+ volatile uint8_t rsr;
+ volatile uint16_t _pad01;
+ volatile uint8_t clkocr;
+ volatile uint8_t _pad02;
+ volatile uint16_t _pad03;
+ volatile uint16_t pllcr;
+ volatile uint16_t _pad04;
+ volatile uint16_t cdvcr;
+ volatile uint16_t pepar;
+ volatile uint32_t _pad05[2];
+ volatile uint16_t _pad06;
+ volatile uint8_t sypcr;
+ volatile uint8_t swiv;
+ volatile uint16_t _pad07;
+ volatile uint16_t picr;
+ volatile uint16_t _pad08;
+ volatile uint16_t pitr;
+ volatile uint16_t _pad09;
+ volatile uint8_t _pad10;
+ volatile uint8_t swsr;
+ volatile uint32_t bkar;
+ volatile uint32_t bcar;
+ volatile uint32_t _pad11[2];
+
+ /*
+ * MEMC Block
+ */
+ volatile uint32_t gmr;
+ volatile uint16_t mstat;
+ volatile uint16_t _pad12;
+ volatile uint32_t _pad13[2];
+ volatile m360MEMCRegisters_t memc[8];
+ volatile uint8_t _pad14[0xF0-0xD0];
+ volatile uint8_t _pad15[0x100-0xF0];
+ volatile uint8_t _pad16[0x500-0x100];
+
+ /*
+ * IDMA1 Block
+ */
+ volatile uint16_t iccr;
+ volatile uint16_t _pad17;
+ volatile uint16_t cmr1;
+ volatile uint16_t _pad18;
+ volatile uint32_t sapr1;
+ volatile uint32_t dapr1;
+ volatile uint32_t bcr1;
+ volatile uint8_t fcr1;
+ volatile uint8_t _pad19;
+ volatile uint8_t cmar1;
+ volatile uint8_t _pad20;
+ volatile uint8_t csr1;
+ volatile uint8_t _pad21;
+ volatile uint16_t _pad22;
+
+ /*
+ * SDMA Block
+ */
+ volatile uint8_t sdsr;
+ volatile uint8_t _pad23;
+ volatile uint16_t sdcr;
+ volatile uint32_t sdar;
+
+ /*
+ * IDMA2 Block
+ */
+ volatile uint16_t _pad24;
+ volatile uint16_t cmr2;
+ volatile uint32_t sapr2;
+ volatile uint32_t dapr2;
+ volatile uint32_t bcr2;
+ volatile uint8_t fcr2;
+ volatile uint8_t _pad26;
+ volatile uint8_t cmar2;
+ volatile uint8_t _pad27;
+ volatile uint8_t csr2;
+ volatile uint8_t _pad28;
+ volatile uint16_t _pad29;
+ volatile uint32_t _pad30;
+
+ /*
+ * CPIC Block
+ */
+ volatile uint32_t cicr;
+ volatile uint32_t cipr;
+ volatile uint32_t cimr;
+ volatile uint32_t cisr;
+
+ /*
+ * Parallel I/O Block
+ */
+ volatile uint16_t padir;
+ volatile uint16_t papar;
+ volatile uint16_t paodr;
+ volatile uint16_t padat;
+ volatile uint32_t _pad31[2];
+ volatile uint16_t pcdir;
+ volatile uint16_t pcpar;
+ volatile uint16_t pcso;
+ volatile uint16_t pcdat;
+ volatile uint16_t pcint;
+ volatile uint16_t _pad32;
+ volatile uint32_t _pad33[5];
+
+ /*
+ * TIMER Block
+ */
+ volatile uint16_t tgcr;
+ volatile uint16_t _pad34;
+ volatile uint32_t _pad35[3];
+ volatile uint16_t tmr1;
+ volatile uint16_t tmr2;
+ volatile uint16_t trr1;
+ volatile uint16_t trr2;
+ volatile uint16_t tcr1;
+ volatile uint16_t tcr2;
+ volatile uint16_t tcn1;
+ volatile uint16_t tcn2;
+ volatile uint16_t tmr3;
+ volatile uint16_t tmr4;
+ volatile uint16_t trr3;
+ volatile uint16_t trr4;
+ volatile uint16_t tcr3;
+ volatile uint16_t tcr4;
+ volatile uint16_t tcn3;
+ volatile uint16_t tcn4;
+ volatile uint16_t ter1;
+ volatile uint16_t ter2;
+ volatile uint16_t ter3;
+ volatile uint16_t ter4;
+ volatile uint32_t _pad36[2];
+
+ /*
+ * CP Block
+ */
+ volatile uint16_t cr;
+ volatile uint16_t _pad37;
+ volatile uint16_t rccr;
+ volatile uint16_t _pad38;
+ volatile uint32_t _pad39[3];
+ volatile uint16_t _pad40;
+ volatile uint16_t rter;
+ volatile uint16_t _pad41;
+ volatile uint16_t rtmr;
+ volatile uint32_t _pad42[5];
+
+ /*
+ * BRG Block
+ */
+ volatile uint32_t brgc1;
+ volatile uint32_t brgc2;
+ volatile uint32_t brgc3;
+ volatile uint32_t brgc4;
+
+ /*
+ * SCC Block
+ */
+ volatile m360SCCRegisters_t scc1;
+ volatile m360SCCRegisters_t scc2;
+ volatile m360SCCRegisters_t scc3;
+ volatile m360SCCRegisters_t scc4;
+
+ /*
+ * SMC Block
+ */
+ volatile m360SMCRegisters_t smc1;
+ volatile m360SMCRegisters_t smc2;
+
+ /*
+ * SPI Block
+ */
+ volatile uint16_t spmode;
+ volatile uint16_t _pad43[2];
+ volatile uint8_t spie;
+ volatile uint8_t _pad44;
+ volatile uint16_t _pad45;
+ volatile uint8_t spim;
+ volatile uint8_t _pad46[2];
+ volatile uint8_t spcom;
+ volatile uint16_t _pad47[2];
+
+ /*
+ * PIP Block
+ */
+ volatile uint16_t pipc;
+ volatile uint16_t _pad48;
+ volatile uint16_t ptpr;
+ volatile uint32_t pbdir;
+ volatile uint32_t pbpar;
+ volatile uint16_t _pad49;
+ volatile uint16_t pbodr;
+ volatile uint32_t pbdat;
+ volatile uint32_t _pad50[6];
+
+ /*
+ * SI Block
+ */
+ volatile uint32_t simode;
+ volatile uint8_t sigmr;
+ volatile uint8_t _pad51;
+ volatile uint8_t sistr;
+ volatile uint8_t sicmr;
+ volatile uint32_t _pad52;
+ volatile uint32_t sicr;
+ volatile uint16_t _pad53;
+ volatile uint16_t sirp[2];
+ volatile uint16_t _pad54;
+ volatile uint32_t _pad55[2];
+ volatile uint8_t siram[256];
+} m360_t;
+
+struct bdregions_t {
+ char *base;
+ unsigned int size;
+ unsigned int used;
+};
+
+#define M68360_RX_BUF_SIZE 1
+#define M68360_TX_BUF_SIZE 0x100
+
+struct _m68360_per_chip;
+typedef struct _m68360_per_chip *M68360_t;
+
+typedef struct _m68360_per_port {
+ uint32_t channel;
+ M68360_t chip;
+ volatile uint32_t *pBRGC; /* m360->brgc# */
+ volatile m360SCCparms_t *pSCCB; /* m360->scc#p */
+ volatile m360SCCRegisters_t *pSCCR; /* m360->scc# */
+ uint32_t baud;
+ int minor;
+ volatile uint8_t *rxBuf;
+ volatile uint8_t *txBuf;
+ volatile m360BufferDescriptor_t *sccRxBd;
+ volatile m360BufferDescriptor_t *sccTxBd;
+}m68360_per_port_t, *M68360_serial_ports_t;
+
+typedef struct _m68360_per_chip {
+ struct _m68360_per_chip *next;
+ struct bdregions_t bdregions[4];
+ volatile m360_t *m360; /* Pointer to base Address */
+ int m360_interrupt;
+ int m360_clock_rate;
+ PPMCQ1BoardData board_data;
+ m68360_per_port_t port[4];
+} m68360_per_chip_t;
+
+extern M68360_t M68360_chips;
+
+void M360SetupMemory( M68360_t ptr );
+void *M360AllocateBufferDescriptors (M68360_t ptr, int count);
+void M360ExecuteRISC( volatile m360_t *m360, uint16_t command);
+int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector );
+
+#endif /* __MC68360_h */
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
new file mode 100644
index 0000000000..773f85b93a
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
@@ -0,0 +1,836 @@
+/* This file contains the termios TTY driver for the Motorola MC68360 SCC ports.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <termios.h>
+#include <bsp.h>
+#include <libcpu/io.h>
+#include <rtems/libio.h>
+#include <bsp/pci.h>
+#include <bsp/irq.h>
+#include <libchip/serial.h>
+#include "m68360.h"
+#include <libchip/sersupp.h>
+#include <stdlib.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+
+#define MC68360_LENGHT_SIZE 100
+int mc68360_length_array[ MC68360_LENGHT_SIZE ];
+int mc68360_length_count=0;
+
+void mc68360_Show_length_array() {
+ int i;
+ for (i=0; i<MC68360_LENGHT_SIZE; i++)
+ printf(" %d", mc68360_length_array[i] );
+ printf("\n\n");
+}
+
+M68360_t M68360_chips = NULL;
+
+#define SYNC eieio
+
+void mc68360_scc_nullFunc() {}
+
+uint8_t scc_read8(
+ const char *name,
+ volatile uint8_t *address
+)
+{
+ uint8_t value;
+
+#ifdef DEBUG_360
+ printk( "RD8 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%02x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write8(
+ const char *name,
+ volatile uint8_t *address,
+ uint8_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR8 %s 0x%08x 0x%02x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+
+uint16_t scc_read16(
+ const char *name,
+ volatile uint16_t *address
+)
+{
+ uint16_t value;
+
+#ifdef DEBUG_360
+ printk( "RD16 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%04x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write16(
+ const char *name,
+ volatile uint16_t *address,
+ uint16_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR16 %s 0x%08x 0x%04x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+
+uint32_t scc_read32(
+ const char *name,
+ volatile uint32_t *address
+)
+{
+ uint32_t value;
+
+#ifdef DEBUG_360
+ printk( "RD32 %s 0x%08x ", name, address );
+#endif
+ value = *address;
+#ifdef DEBUG_360
+ printk( "0x%08x\n", value );
+#endif
+
+ return value;
+}
+
+void scc_write32(
+ const char *name,
+ volatile uint32_t *address,
+ uint32_t value
+)
+{
+#ifdef DEBUG_360
+ printk( "WR32 %s 0x%08x 0x%08x\n", name, address, value );
+#endif
+ *address = value;
+}
+
+void mc68360_sccShow_Regs(int minor){
+ M68360_serial_ports_t ptr;
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+
+ printk( "scce 0x%08x", &ptr->pSCCR->scce );
+ printk( " 0x%04x\n", ptr->pSCCR->scce );
+
+}
+
+#define TX_BUFFER_ADDRESS( _ptr ) \
+ ((char *)ptr->txBuf - (char *)ptr->chip->board_data->baseaddr)
+#define RX_BUFFER_ADDRESS( _ptr ) \
+ ((char *)ptr->rxBuf - (char *)ptr->chip->board_data->baseaddr)
+
+
+/**************************************************************************
+ * Function: mc68360_sccBRGC *
+ **************************************************************************
+ * Description: *
+ * *
+ * This function is called to compute the divisor register values for *
+ * a given baud rate. *
+ * *
+ * *
+ * Inputs: *
+ * *
+ * int baud - Baud rate (in bps). *
+ * *
+ * Output: *
+ * *
+ * int - baud rate generator configuration. *
+ * *
+ **************************************************************************/
+static int
+mc68360_sccBRGC(int baud, int m360_clock_rate)
+{
+ int data;
+
+ /*
+ * configure baud rate generator for 16x bit rate, where.....
+ * b = desired baud rate
+ * clk = system clock (33mhz)
+ * d = clock dividor value
+ *
+ * for b > 300 : d = clk/(b*16)
+ * for b<= 300 : d = (clk/ (b*16*16))-1)
+ */
+
+ SYNC();
+ if( baud > 300 ) data = 33333333 / (baud * 16 );
+ else data = (33333333 / (baud * 16 * 16) ) - 1;
+ data *= 2;
+ data &= 0x00001ffe ;
+
+ /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
+ data |= ((baud>300)? 0 : 1 ) ;
+ data |= 0x010000 ;
+
+ return data;
+}
+
+
+/**************************************************************************
+ * Function: sccInterruptHandler *
+ **************************************************************************
+ * Description: *
+ * *
+ * This is the interrupt service routine for the console UART. It *
+ * handles both receive and transmit interrupts. The bulk of the *
+ * work is done by termios. *
+ * *
+ * Inputs: *
+ * *
+ * chip - structure of chip specific information *
+ * *
+ * Output: *
+ * *
+ * none *
+ * *
+ **************************************************************************/
+void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle )
+{
+ volatile m360_t *m360;
+ int port;
+ uint16_t status;
+ uint16_t length;
+ int i;
+ char data;
+ int clear_isr;
+ M68360_t chip = (M68360_t)handle;
+
+ for (port=0; port<4; port++) {
+
+ clear_isr = FALSE;
+ m360 = chip->m360;
+
+ /*
+ * Handle a RX interrupt.
+ */
+ if ( scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x1)
+ {
+ clear_isr = TRUE;
+ scc_write16("scce", &chip->port[port].pSCCR->scce, 0x1 );
+ status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
+ while ((status & M360_BD_EMPTY) == 0)
+ {
+ length= scc_read16("sccRxBd->length",&chip->port[port].sccRxBd->length);
+ for (i=0;i<length;i++) {
+ data= chip->port[port].rxBuf[i];
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[ chip->port[port].minor ].termios_data,
+ &data,
+ 1);
+ }
+ scc_write16( "sccRxBd->status", &chip->port[port].sccRxBd->status,
+ M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
+ status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
+ }
+ }
+
+ /*
+ * Handle a TX interrupt.
+ */
+ if (scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x2)
+ {
+ clear_isr = TRUE;
+ scc_write16("scce", &chip->port[port].pSCCR->scce, 0x2);
+ status = scc_read16("sccTxBd->status", &chip->port[port].sccTxBd->status);
+ if ((status & M360_BD_EMPTY) == 0)
+ {
+ scc_write16("sccTxBd->status",&chip->port[port].sccTxBd->status,0);
+ rtems_termios_dequeue_characters(
+ Console_Port_Data[chip->port[port].minor].termios_data,
+ chip->port[port].sccTxBd->length);
+ }
+ }
+
+ /*
+ * Clear SCC interrupt-in-service bit.
+ */
+ if ( clear_isr )
+ scc_write32( "cisr", &m360->cisr, (0x80000000 >> chip->port[port].channel) );
+ }
+}
+
+/*
+ * mc68360_scc_open
+ *
+ * This function opens a port for communication.
+ *
+ * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
+ */
+
+int mc68360_scc_open(
+ int major,
+ int minor,
+ void * arg
+)
+{
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * mc68360_scc_initialize_interrupts
+ *
+ * This routine initializes the console's receive and transmit
+ * ring buffers and loads the appropriate vectors to handle the interrupts.
+ */
+
+void mc68360_scc_initialize_interrupts(int minor)
+{
+ M68360_serial_ports_t ptr;
+ volatile m360_t *m360;
+ uint32_t data;
+ uint32_t buffers_start;
+ uint32_t tmp_u32;
+
+#ifdef DEBUG_360
+ printk("mc68360_scc_initialize_interrupts: minor %d\n", minor );
+ printk("Console_Port_Tbl[minor].pDeviceParams 0x%08x\n",
+ Console_Port_Tbl[minor].pDeviceParams );
+#endif
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+ m360 = ptr->chip->m360;
+#ifdef DEBUG_360
+ printk("m360 0x%08x baseaddr 0x%08x\n",
+ m360, ptr->chip->board_data->baseaddr);
+#endif
+
+ buffers_start = ptr->chip->board_data->baseaddr + 0x00200000 +
+ ( (M68360_RX_BUF_SIZE + M68360_TX_BUF_SIZE) * (ptr->channel-1));
+ ptr->rxBuf = (uint8_t *) buffers_start;
+ ptr->txBuf = (uint8_t *)(buffers_start + M68360_RX_BUF_SIZE);
+#ifdef DEBUG_360
+ printk("rxBuf 0x%08x txBuf 0x%08x\n", ptr->rxBuf, ptr->txBuf );
+#endif
+ /*
+ * Set Channel Drive Enable bits in EPLD
+ */
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
+ SYNC();
+ data |= (PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 |
+ PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE, data);
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
+ SYNC();
+
+ /*
+ * Disable the receiver and the transmitter.
+ */
+
+ SYNC();
+ tmp_u32 = scc_read32( "gsmr_l", &ptr->pSCCR->gsmr_l );
+ tmp_u32 &= (~(M360_GSMR_ENR | M360_GSMR_ENT ) ) ;
+ scc_write32( "gsmr_l", &ptr->pSCCR->gsmr_l, tmp_u32 );
+
+ /*
+ * Disable Interrupt Error and Interrupt Breakpoint
+ * Set SAID to 4 XXX - Shouldn't it be 7 for slave mode
+ * Set SAISM to 7
+ */
+ SYNC();
+ scc_write16( "sdcr", &m360->sdcr, 0x0740 );
+
+ /*
+ * Clear status -- reserved interrupt, SDMA channel error, SDMA breakpoint
+ */
+ scc_write8( "sdsr", &m360->sdsr, 0x07 );
+ SYNC();
+
+ /*
+ * Initialize timer information in RISC Controller Configuration Register
+ */
+ scc_write16( "rccr", &m360->rccr, 0x8100 );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write16( "papar", &m360->papar, 0xffff );
+ scc_write16( "padir", &m360->padir, 0x5500 ); /* From Memo */
+ scc_write16( "paodr", &m360->paodr, 0x0000 );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write32( "pbpar", &m360->pbpar, 0x00000000 );
+ scc_write32( "pbdir", &m360->pbdir, 0x0003ffff );
+ scc_write32( "pbdat", &m360->pbdat, 0x0000003f );
+ SYNC();
+
+ /*
+ * XXX
+ */
+ scc_write16( "pcpar", &m360->pcpar, 0x0000 );
+ scc_write16( "pcdir", &m360->pcdir, 0x0000 );
+ scc_write16( "pcso", &m360->pcso, 0x0000 );
+ SYNC();
+
+ /*
+ * configure baud rate generator for 16x bit rate, where.....
+ * b = desired baud rate
+ * clk = system clock (33mhz)
+ * d = clock dividor value
+ *
+ * for b > 300 : d = clk/(b*16)
+ * for b<= 300 : d = (clk/ (b*16*16))-1)
+ */
+ SYNC();
+ if( ptr->baud > 300 ) data = 33333333 / (ptr->baud * 16 );
+ else data = (33333333 / (ptr->baud * 16 * 16) ) - 1;
+ data *= 2 ;
+ data &= 0x00001ffe ;
+
+ /* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
+ data |= ((ptr->baud>300)? 0 : 1 ) ;
+ data |= 0x010000 ;
+
+ scc_write32( "pBRGC", ptr->pBRGC, data );
+
+ data = (((ptr->channel-1)*8) | (ptr->channel-1)) ;
+ data = data << ((ptr->channel-1)*8) ;
+ data |= scc_read32( "sicr", &m360->sicr );
+ scc_write32( "sicr", &m360->sicr, data );
+
+ /*
+ * initialise SCC parameter ram
+ */
+ SYNC();
+ scc_write16( "pSCCB->rbase", &ptr->pSCCB->rbase,
+ (char *)(ptr->sccRxBd) - (char *)m360 );
+ scc_write16( "pSCCB->tbase", &ptr->pSCCB->tbase,
+ (char *)(ptr->sccTxBd) - (char *)m360 );
+
+ scc_write8( "pSCCB->rfcr", &ptr->pSCCB->rfcr, 0x15 ); /* 0x15 0x18 */
+ scc_write8( "pSCCB->tfcr", &ptr->pSCCB->tfcr, 0x15 ); /* 0x15 0x18 */
+
+ scc_write16( "pSCCB->mrblr", &ptr->pSCCB->mrblr, M68360_RX_BUF_SIZE );
+
+ /*
+ * initialise tx and rx scc parameters
+ */
+ SYNC();
+ data = M360_CR_INIT_TX_RX_PARAMS | 0x01;
+ data |= (M360_CR_CH_NUM * (ptr->channel-1) );
+ scc_write16( "CR", &m360->cr, data );
+
+ /*
+ * initialise uart specific parameter RAM
+ */
+ SYNC();
+ scc_write16( "pSCCB->un.uart.max_idl", &ptr->pSCCB->un.uart.max_idl, 15000 );
+ scc_write16( "pSCCB->un.uart.brkcr", &ptr->pSCCB->un.uart.brkcr, 0x0001 );
+ scc_write16( "pSCCB->un.uart.parec", &ptr->pSCCB->un.uart.parec, 0x0000 );
+
+ scc_write16( "pSCCB->un,uart.frmec", &ptr->pSCCB->un.uart.frmec, 0x0000 );
+
+ scc_write16( "pSCCB->un.uart.nosec", &ptr->pSCCB->un.uart.nosec, 0x0000 );
+ scc_write16( "pSCCB->un.uart.brkec", &ptr->pSCCB->un.uart.brkec, 0x0000 );
+ scc_write16( "pSCCB->un.uart.uaddr0", &ptr->pSCCB->un.uart.uaddr[0], 0x0000 );
+ scc_write16( "pSCCB->un.uart.uaddr1", &ptr->pSCCB->un.uart.uaddr[1], 0x0000 );
+ scc_write16( "pSCCB->un.uart.toseq", &ptr->pSCCB->un.uart.toseq, 0x0000 );
+ scc_write16( "pSCCB->un.uart.char0",
+ &ptr->pSCCB->un.uart.character[0], 0x0039 );
+ scc_write16( "pSCCB->un.uart.char1",
+ &ptr->pSCCB->un.uart.character[1], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char2",
+ &ptr->pSCCB->un.uart.character[2], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char3",
+ &ptr->pSCCB->un.uart.character[3], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char4",
+ &ptr->pSCCB->un.uart.character[4], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char5",
+ &ptr->pSCCB->un.uart.character[5], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char6",
+ &ptr->pSCCB->un.uart.character[6], 0x8000 );
+ scc_write16( "pSCCB->un.uart.char7",
+ &ptr->pSCCB->un.uart.character[7], 0x8000 );
+
+ scc_write16( "pSCCB->un.uart.rccm", &ptr->pSCCB->un.uart.rccm, 0xc0ff );
+
+ /*
+ * setup buffer descriptor stuff
+ */
+ SYNC();
+ scc_write16( "sccRxBd->status", &ptr->sccRxBd->status, 0x0000 );
+ SYNC();
+ scc_write16( "sccRxBd->length", &ptr->sccRxBd->length, 0x0000 );
+ scc_write16( "sccRxBd->status", &ptr->sccRxBd->status,
+ M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
+ /* XXX Radstone Example writes RX buffer ptr as two u16's */
+ scc_write32( "sccRxBd->buffer", &ptr->sccRxBd->buffer,
+ RX_BUFFER_ADDRESS( ptr ) );
+
+ SYNC();
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0x0000 );
+ SYNC();
+ scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, 0x0000 );
+ /* XXX Radstone Example writes TX buffer ptr as two u16's */
+ scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
+ TX_BUFFER_ADDRESS( ptr ) );
+
+ /*
+ * clear previous events and set interrupt priorities
+ */
+ scc_write16( "pSCCR->scce", &ptr->pSCCR->scce, 0x1bef ); /* From memo */
+ SYNC();
+ SYNC();
+ scc_write32( "cicr", &m360->cicr, 0x001b9f40 );
+ SYNC();
+
+ /* scc_write32( "cicr", &m360->cicr, scc_read32( "cicr", &m360->cicr ) ); */
+
+ scc_write16( "pSCCR->sccm", &ptr->pSCCR->sccm, M360_SCCE_TX | M360_SCCE_RX );
+
+ data = scc_read32("cimr", &m360->cimr);
+ data |= (0x80000000 >> ptr->channel);
+ scc_write32( "cimr", &m360->cimr, data );
+ SYNC();
+ scc_write32( "cipr", &m360->cipr, scc_read32( "cipr", &m360->cipr ) );
+
+ scc_write32( "pSCCR->gsmr_h", &ptr->pSCCR->gsmr_h, M360_GSMR_RFW );
+ scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
+ (M360_GSMR_TDCR_16X | M360_GSMR_RDCR_16X | M360_GSMR_MODE_UART) );
+
+ scc_write16( "pSCCR->dsr", &ptr->pSCCR->dsr, 0x7e7e );
+ SYNC();
+
+ scc_write16( "pSCCR->psmr", &ptr->pSCCR->psmr,
+ (M360_PSMR_CL8 | M360_PSMR_UM_NORMAL | M360_PSMR_TPM_ODD) );
+ SYNC();
+
+ /*
+ * Enable the receiver and the transmitter.
+ */
+
+ SYNC();
+ data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l);
+ scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
+ (data | M360_GSMR_ENR | M360_GSMR_ENT) );
+
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK );
+ data &= (~PMCQ1_INT_MASK_QUICC);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK, data );
+
+ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS );
+ data &= (~PMCQ1_INT_STATUS_QUICC);
+ PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data );
+}
+
+/*
+ * mc68360_scc_write_support_int
+ *
+ * Console Termios output entry point when using interrupt driven output.
+ */
+
+int mc68360_scc_write_support_int(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ rtems_interrupt_level Irql;
+ M68360_serial_ports_t ptr;
+
+ mc68360_length_array[ mc68360_length_count ] = len;
+ mc68360_length_count++;
+ if ( mc68360_length_count >= MC68360_LENGHT_SIZE )
+ mc68360_length_count=0;
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+
+ /*
+ * We are using interrupt driven output and termios only sends us
+ * one character at a time.
+ */
+
+ if ( !len )
+ return 0;
+
+ /*
+ *
+ */
+#ifdef DEBUG_360
+ printk("mc68360_scc_write_support_int: char 0x%x length %d\n",
+ (unsigned int)*buf, len );
+#endif
+ /*
+ * We must copy the data from the global memory space to MC68360 space
+ */
+
+ rtems_interrupt_disable(Irql);
+
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0 );
+ memcpy((void *) ptr->txBuf, buf, len);
+ scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
+ TX_BUFFER_ADDRESS(ptr->txBuf) );
+ scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, len );
+ scc_write16( "sccTxBd->status", &ptr->sccTxBd->status,
+ (M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT) );
+
+ rtems_interrupt_enable(Irql);
+
+ return len;
+}
+
+/*
+ * mc68360_scc_write_polled
+ *
+ * This routine polls out the requested character.
+ */
+
+void mc68360_scc_write_polled(
+ int minor,
+ char cChar
+)
+{
+#ifdef DEBUG_360
+ printk("mc68360_scc_write_polled: %c\n", cChar);
+#endif
+}
+
+/*
+ * mc68681_set_attributes
+ *
+ * This function sets the DUART channel to reflect the requested termios
+ * port settings.
+ */
+
+int mc68360_scc_set_attributes(
+ int minor,
+ const struct termios *t
+)
+{
+ int baud;
+ volatile m360_t *m360;
+ M68360_serial_ports_t ptr;
+
+ ptr = Console_Port_Tbl[minor].pDeviceParams;
+ m360 = ptr->chip->m360;
+
+ switch (t->c_cflag & CBAUD)
+ {
+ 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;
+ default: baud = -1; break;
+ }
+
+ if (baud > 0)
+ {
+ scc_write32(
+ "pBRGC",
+ ptr->pBRGC,
+ mc68360_sccBRGC(baud, ptr->chip->m360_clock_rate)
+ );
+ }
+
+ return 0;
+}
+
+/*
+ * mc68360_scc_close
+ *
+ * This function shuts down the requested port.
+ */
+
+int mc68360_scc_close(
+ int major,
+ int minor,
+ void *arg
+)
+{
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * mc68360_scc_inbyte_nonblocking_polled
+ *
+ * Console Termios polling input entry point.
+ */
+
+int mc68360_scc_inbyte_nonblocking_polled(
+ int minor
+)
+{
+ return -1;
+}
+
+/*
+ * mc68360_scc_write_support_polled
+ *
+ * Console Termios output entry point when using polled output.
+ *
+ */
+
+int mc68360_scc_write_support_polled(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ printk("mc68360_scc_write_support_polled: minor %d char %c len %d\n",
+ minor, buf, len );
+ return 0;
+}
+
+/*
+ * mc68360_scc_init
+ *
+ * This function initializes the DUART to a quiecsent state.
+ */
+
+void mc68360_scc_init(int minor)
+{
+#ifdef DEBUG_360
+ printk("mc68360_scc_init\n");
+#endif
+}
+
+int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector )
+{
+ M68360_t chip;
+ int i;
+
+#ifdef DEBUG_360
+ printk("mc68360_scc_create_chip\n");
+#endif
+
+ /*
+ * Create console structure for this card
+ * XXX - Note Does this need to be moved up to if a QUICC is fitted
+ * section?
+ */
+ if ((chip = malloc(sizeof(struct _m68360_per_chip))) == NULL)
+ {
+ printk("Error Unable to allocate memory for _m68360_per_chip\n");
+ return RTEMS_IO_ERROR;
+ }
+
+ chip->next = M68360_chips;
+ chip->m360 = (void *)BoardData->baseaddr;
+ chip->m360_interrupt = int_vector;
+ chip->m360_clock_rate = 25000000;
+ chip->board_data = BoardData;
+ M68360_chips = chip;
+
+ for (i=1; i<=4; i++) {
+ chip->port[i-1].channel = i;
+ chip->port[i-1].chip = chip;
+ chip->port[i-1].baud = 9600;
+
+ switch( i ) {
+ case 1:
+ chip->port[i-1].pBRGC = &chip->m360->brgc1;
+ chip->port[i-1].pSCCB = (m360SCCparms_t *) &chip->m360->scc1p;
+ chip->port[i-1].pSCCR = &chip->m360->scc1;
+ M360SetupMemory( chip ); /* Do this first time through */
+ break;
+ case 2:
+ chip->port[i-1].pBRGC = &chip->m360->brgc2;
+ chip->port[i-1].pSCCB = &chip->m360->scc2p;
+ chip->port[i-1].pSCCR = &chip->m360->scc2;
+ break;
+ case 3:
+ chip->port[i-1].pBRGC = &chip->m360->brgc3;
+ chip->port[i-1].pSCCB = &chip->m360->scc3p;
+ chip->port[i-1].pSCCR = &chip->m360->scc3;
+ break;
+ case 4:
+ chip->port[i-1].pBRGC = &chip->m360->brgc4;
+ chip->port[i-1].pSCCB = &chip->m360->scc4p;
+ chip->port[i-1].pSCCR = &chip->m360->scc4;
+ break;
+ default:
+ printk("Invalid mc68360 channel %d\n", i);
+ return RTEMS_IO_ERROR;
+ }
+
+ /*
+ * Allocate buffer descriptors.
+ */
+
+ chip->port[i-1].sccRxBd = M360AllocateBufferDescriptors(chip, 1);
+ chip->port[i-1].sccTxBd = M360AllocateBufferDescriptors(chip, 1);
+ }
+
+ rsPMCQ1QuiccIntConnect(
+ chip->board_data->busNo,
+ chip->board_data->slotNo,
+ chip->board_data->funcNo,
+ &mc68360_sccInterruptHandler,
+ chip
+ );
+
+ return RTEMS_SUCCESSFUL;
+}
+
+console_fns mc68360_scc_fns = {
+ libchip_serial_default_probe, /* deviceProbe */
+ mc68360_scc_open, /* deviceFirstOpen */
+ NULL, /* deviceLastClose */
+ NULL, /* deviceRead */
+ mc68360_scc_write_support_int, /* deviceWrite */
+ mc68360_scc_initialize_interrupts, /* deviceInitialize */
+ mc68360_scc_write_polled, /* deviceWritePolled */
+ mc68360_scc_set_attributes, /* deviceSetAttributes */
+ TRUE /* deviceOutputUsesInterrupts */
+};
+
+console_fns mc68360_scc_polled = {
+ libchip_serial_default_probe, /* deviceProbe */
+ mc68360_scc_open, /* deviceFirstOpen */
+ mc68360_scc_close, /* deviceLastClose */
+ mc68360_scc_inbyte_nonblocking_polled, /* deviceRead */
+ mc68360_scc_write_support_polled, /* deviceWrite */
+ mc68360_scc_init, /* deviceInitialize */
+ mc68360_scc_write_polled, /* deviceWritePolled */
+ mc68360_scc_set_attributes, /* deviceSetAttributes */
+ FALSE /* deviceOutputUsesInterrupts */
+};
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
new file mode 100644
index 0000000000..849b10af54
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
@@ -0,0 +1,47 @@
+/*
+ * This include file contains all console driver definations for the nc16550
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include "console.h"
+
+typedef struct uart_reg
+{
+ unsigned char reg;
+ unsigned char pad[7];
+} uartReg;
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+)
+{
+ struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
+ unsigned8 ucData;
+ ucData = p[ucRegNum].reg;
+ asm volatile("sync");
+ return ucData;
+}
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+)
+{
+ struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
+ volatile int i;
+ p[ucRegNum].reg = ucData;
+ asm volatile("sync");
+ for (i=0;i<0x08ff;i++);
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
new file mode 100644
index 0000000000..c2aa368b28
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
@@ -0,0 +1,57 @@
+/* nc16550cfg.h
+ *
+ * This include file contains all console driver definations for the nc16550
+ *
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __NS16550_CONFIG_H
+#define __NS16550_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Board specific register access routines
+ */
+
+unsigned8 Read_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum
+);
+
+void Write_ns16550_register(
+ unsigned32 ulCtrlPort,
+ unsigned8 ucRegNum,
+ unsigned8 ucData
+);
+
+extern console_fns ns16550_fns_8245;
+extern console_fns ns16550_fns_polled_8245;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
new file mode 100644
index 0000000000..088502e3b2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
@@ -0,0 +1,558 @@
+/* rsPMCQ1.c - Radstone PMCQ1 Common Initialisation Code
+ *
+ * Copyright 2000 Radstone Technology
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 2005.
+ * 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.
+ *
+ */
+
+/*
+DESCRIPTION
+These functions are responsible for scanning for PMCQ1's and setting up
+the Motorola MC68360's if present.
+
+USAGE
+call rsPMCQ1Init() to perform ba sic initialisation of the PMCQ1's.
+*/
+
+/* includes */
+#include <libcpu/io.h>
+#include <bsp/irq.h>
+#include <stdlib.h>
+#include <rtems/bspIo.h>
+#include <bsp/pci.h>
+#include <bsp.h>
+#include "rsPMCQ1.h"
+#include "m68360.h"
+
+/* defines */
+#if 0
+#define DEBUG_360
+#endif
+
+/* Local data */
+PPMCQ1BoardData pmcq1BoardData = NULL;
+
+static unsigned char rsPMCQ1Initialized = FALSE;
+
+/* forward declarations */
+
+/* local Qspan II serial eeprom table */
+static unsigned char rsPMCQ1eeprom[] =
+ {
+ 0x00, /* Byte 0 - PCI_SID */
+ 0x00, /* Byte 1 - PCI_SID */
+ 0x00, /* Byte 2 - PCI_SID */
+ 0x00, /* Byte 3 - PCI_SID */
+ 0x00, /* Byte 4 - PBROM_CTL */
+ 0x00, /* Byte 5 - PBROM_CTL */
+ 0x00, /* Byte 6 - PBROM_CTL */
+ 0x2C, /* Byte 7 - PBTI0_CTL */
+ 0xB0, /* Byte 8 - PBTI1_CTL */
+ 0x00, /* Byte 9 - QBSI0_AT */
+ 0x00, /* Byte 10 - QBSI0_AT */
+ 0x02, /* Byte 11 - QBSI0_AT */
+ 0x00, /* Byte 12 - PCI_ID */
+ 0x07, /* Byte 13 - PCI_ID */
+ 0x11, /* Byte 14 - PCI_ID */
+ 0xB5, /* Byte 15 - PCI_ID */
+ 0x06, /* Byte 16 - PCI_CLASS */
+ 0x80, /* Byte 17 - PCI_CLASS */
+ 0x00, /* Byte 18 - PCI_CLASS */
+ 0x00, /* Byte 19 - PCI_MISC1 */
+ 0x00, /* Byte 20 - PCI_MISC1 */
+ 0xC0, /* Byte 21 - PCI_PMC */
+ 0x00 /* Byte 22 - PCI_BST */
+};
+
+void MsDelay()
+{
+ printk(".");
+}
+
+void write8( int addr, int data ){
+ out_8((void *)addr, (unsigned char)data);
+}
+
+void write16( int addr, int data ) {
+ out_be16((void *)addr, (short)data );
+}
+
+void write32( int addr, int data ) {
+ out_be32((unsigned int *)addr, data );
+}
+
+int read32( int addr){
+ return in_be32((unsigned int *)addr);
+}
+
+
+void rsPMCQ1_scc_nullFunc() {}
+
+/*******************************************************************************
+* rsPMCQ1Int - handle a PMCQ1 interrupt
+*
+* This routine gets called when the QUICC or MA causes
+* an interrupt.
+*
+* RETURNS: NONE.
+*/
+
+void rsPMCQ1Int( void *ptr )
+{
+ unsigned long status;
+ unsigned long status1;
+ unsigned long mask;
+ PPMCQ1BoardData boardData = ptr;
+
+ status = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS );
+ mask = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_MASK );
+
+ if (((mask & PMCQ1_INT_MASK_QUICC) == 0) && (status & PMCQ1_INT_STATUS_QUICC))
+ {
+ /* If there is a handler call it otherwise mask the interrupt */
+ if (boardData->quiccInt) {
+ boardData->quiccInt(boardData->quiccArg);
+ } else {
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
+ }
+ }
+
+ if (((mask & PMCQ1_INT_MASK_MA) == 0) && (status & PMCQ1_INT_STATUS_MA))
+ {
+ /* If there is a handler call it otherwise mask the interrupt */
+ if (boardData->maInt) {
+ boardData->maInt(boardData->maArg);
+ } else {
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
+ }
+ }
+
+ /* Clear Interrupt on QSPAN */
+ *(unsigned long *)(boardData->bridgeaddr + 0x600) = 0x00001000;
+
+ /* read back the status register to ensure that the pci write has completed */
+ status1 = *(volatile unsigned long *)(boardData->bridgeaddr + 0x600);
+}
+
+
+/*******************************************************************************
+*
+* rsPMCQ1MaIntConnect - connect a MiniAce interrupt routine
+*
+* This routine is called to connect a MiniAce interrupt handler
+* upto a PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1MaIntConnect (
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo, /* Pci Function number of PMCQ1 */
+ rtems_irq_hdl routine,/* interrupt routine */
+ rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->maInt = routine;
+ boardData->maArg = arg;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1MaIntDisconnect - disconnect a MiniAce interrupt routine
+*
+* This routine is called to disconnect a MiniAce interrupt handler
+* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1MaIntDisconnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo /* Pci Function number of PMCQ1 */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext) {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->maInt = NULL;
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1QuiccIntConnect - connect a Quicc interrupt routine
+*
+* This routine is called to connect a Quicc interrupt handler
+* upto a PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1QuiccIntConnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo, /* Pci Function number of PMCQ1 */
+ rtems_irq_hdl routine,/* interrupt routine */
+ rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->quiccInt = routine;
+ boardData->quiccArg = arg;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+ return (status);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1QuiccIntDisconnect - disconnect a Quicc interrupt routine
+*
+* This routine is called to disconnect a Quicc interrupt handler
+* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1QuiccIntDisconnect(
+ unsigned long busNo, /* Pci Bus number of PMCQ1 */
+ unsigned long slotNo, /* Pci Slot number of PMCQ1 */
+ unsigned long funcNo /* Pci Function number of PMCQ1 */
+)
+{
+ PPMCQ1BoardData boardData;
+ unsigned int status = RTEMS_IO_ERROR;
+
+ for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
+ {
+ if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
+ (boardData->funcNo == funcNo))
+ {
+ boardData->quiccInt = NULL;
+ *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
+ status = RTEMS_SUCCESSFUL;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+*
+* rsPMCQ1Init - initialize the PMCQ1's
+*
+* This routine is called to initialize the PCI card to a quiescent state.
+*
+* RETURNS: OK if PMCQ1 found, ERROR if not.
+*/
+
+unsigned int rsPMCQ1Init()
+{
+ int busNo;
+ int slotNo;
+ unsigned int baseaddr = 0;
+ unsigned int bridgeaddr = 0;
+ unsigned long pbti0_ctl;
+ int i;
+ unsigned char int_vector;
+ int fun;
+ int temp;
+ PPMCQ1BoardData boardData;
+ rtems_irq_connect_data IrqData = {0,
+ rsPMCQ1Int,
+ NULL,
+ (rtems_irq_enable)rsPMCQ1_scc_nullFunc,
+ (rtems_irq_disable)rsPMCQ1_scc_nullFunc,
+ (rtems_irq_is_enabled)rsPMCQ1_scc_nullFunc,
+ NULL};
+
+ if (rsPMCQ1Initialized)
+ {
+ return RTEMS_SUCCESSFUL;
+ }
+ for (i=0;;i++){
+ if ( pci_find_device(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1, i, &busNo, &slotNo, &fun) != 0 )
+ break;
+
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_2, &baseaddr);
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
+#ifdef DEBUG_360
+ printk("PMCQ1 baseaddr 0x%08x bridgeaddr 0x%08x\n", baseaddr, bridgeaddr );
+#endif
+
+ /* Set function code to normal mode and enable window */
+ pbti0_ctl = *(unsigned long *)(bridgeaddr + 0x100) & 0xff0fffff;
+ eieio();
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
+ eieio();
+
+ /* Assert QBUS reset */
+ *(unsigned long *)(bridgeaddr + 0x800) |= 0x00000080;
+ eieio();
+
+ /*
+ * Hold QBus in reset for 1ms
+ */
+ MsDelay();
+
+ /* Take QBUS out of reset */
+ *(unsigned long *)(bridgeaddr + 0x800) &= ~0x00000080;
+ eieio();
+
+ MsDelay();
+
+ /* If a QUICC is fitted initialise it */
+ if (PMCQ1_Read_EPLD(baseaddr, PMCQ1_BUILD_OPTION) & PMCQ1_QUICC_FITTED)
+ {
+#ifdef DEBUG_360
+ printk(" Found QUICC busNo %d slotNo %d\n", busNo, slotNo);
+#endif
+
+ /* Initialise MBAR (must use function code of 7) */
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00700080;
+ eieio();
+
+ /* place internal 8K SRAM and registers at address 0x0 */
+ *(unsigned long *)(baseaddr + Q1_360_MBAR) = 0x1;
+ eieio();
+
+ /* Set function code to normal mode */
+ *(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
+ eieio();
+
+ /* Disable the SWT and perform basic initialisation */
+ write8(baseaddr+Q1_360_SIM_SYPCR,0);
+ eieio();
+
+ write32(baseaddr+Q1_360_SIM_MCR,0xa0001029);
+ write16(baseaddr+Q1_360_SIM_PICR,0);
+ write16(baseaddr+Q1_360_SIM_PITR,0);
+
+ write16(baseaddr+Q1_360_CPM_ICCR,0x770);
+ write16(baseaddr+Q1_360_CPM_SDCR,0x770);
+ write32(baseaddr+Q1_360_CPM_CICR,0x00e49f00);
+ write16(baseaddr+Q1_360_SIM_PEPAR,0x2080);
+ eieio();
+
+ /* Enable SRAM */
+ write32(baseaddr+Q1_360_SIM_GMR,0x00001000); /* external master wait state */
+ eieio();
+ write32(baseaddr+Q1_360_SIM_OR0,0x1ff00000); /*| MEMC_OR_FC*/
+ eieio();
+ write32(baseaddr+Q1_360_SIM_BR0,0);
+ eieio();
+ write32(baseaddr+Q1_360_SIM_OR1,(0x5ff00000 | 0x00000780)); /*| MEMC_OR_FC*/
+ eieio();
+ write32(baseaddr+Q1_360_SIM_BR1,(0x00000040 | 0x00000001 | 0x00200280) );
+ eieio();
+ }
+
+ /*
+ * If a second PCI window is present then make it opposite
+ * endian to simplify 1553 integration.
+ */
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_3, &temp);
+ if (temp) {
+ *(unsigned long *)(bridgeaddr + 0x110) |= 0x00500880;
+ }
+
+ /*
+ * Create descriptor structure for this card
+ */
+ if ((boardData = malloc(sizeof(struct _PMCQ1BoardData))) == NULL)
+ {
+ printk("Error Unable to allocate memory for _PMCQ1BoardData\n");
+ return(RTEMS_IO_ERROR);
+ }
+
+ boardData->pNext = pmcq1BoardData;
+ boardData->busNo = busNo;
+ boardData->slotNo = slotNo;
+ boardData->funcNo = 0;
+ boardData->baseaddr = baseaddr;
+ boardData->bridgeaddr = bridgeaddr;
+ boardData->quiccInt = NULL;
+ boardData->maInt = NULL;
+ pmcq1BoardData = boardData;
+ mc68360_scc_create_chip( boardData, int_vector );
+
+ /*
+ * Connect PMCQ1 interrupt handler.
+ */
+ pci_read_config_byte(busNo, slotNo, 0, 0x3c, &int_vector);
+#ifdef DEBUG_360
+ printk("PMCQ1 int_vector %d\n", int_vector);
+#endif
+ IrqData.name = (rtems_irq_symbolic_name)((unsigned int)BSP_PCI_IRQ0 + int_vector);
+ IrqData.handle = boardData;
+ if (!BSP_install_rtems_shared_irq_handler (&IrqData)) {
+ printk("Error installing interrupt handler!\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ /*
+ * Enable PMCQ1 Interrupts from QSPAN-II
+ */
+
+ *(unsigned long *)(bridgeaddr + 0x600) = 0x00001000;
+ eieio();
+ *(unsigned long *)(bridgeaddr + 0x604) |= 0x00001000;
+
+ eieio();
+ }
+
+ if (i > 0)
+ {
+ rsPMCQ1Initialized = TRUE;
+ }
+ return((i > 0) ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
+}
+
+/*******************************************************************************
+*
+* rsPMCQ1Commission - initialize the serial EEPROM on the QSPAN
+*
+* This routine is called to initialize the EEPROM attached to the QSPAN
+* on the PMCQ1 module. It will load standard settings into any QSPAN's
+* found with apparently uninitialised EEPROM's or PMCQ1's (to allow
+* EEPROM modifications to be performed).
+*/
+
+unsigned int rsPMCQ1Commission( unsigned long busNo, unsigned long slotNo )
+{
+ unsigned int status = RTEMS_IO_ERROR;
+ unsigned int bridgeaddr = 0;
+ unsigned long val;
+ int i;
+ int venId1;
+ int venId2;
+
+ pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId1);
+ pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId2);
+ if ((venId1 == 0x086210e3) ||
+ (venId2 == PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1)))
+ {
+ pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
+ status = RTEMS_SUCCESSFUL;
+
+ /*
+ * The On board PMCQ1 on an EP1A has a subVendor ID of 0.
+ * A real PMCQ1 also has the sub vendor ID set up.
+ */
+ if ((busNo == 0) && (slotNo == 1)) {
+ *(unsigned long *)rsPMCQ1eeprom = 0;
+ } else {
+ *(unsigned long *)rsPMCQ1eeprom = PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1);
+ }
+
+ for (i = 0; i < 23; i++) {
+ /* Wait until interface not active */
+ while(read32(bridgeaddr + 0x804) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ /* Write value */
+ write32(bridgeaddr + 0x804, (rsPMCQ1eeprom[i] << 8) | i);
+
+ /* delay for > 31 usec to allow active bit to become set */
+ rtems_bsp_delay(100);
+
+ /* Wait until interface not active */
+ while(read32(bridgeaddr + 0x804) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ /* Re-read value */
+ write32(bridgeaddr + 0x804, 0x40000000 | i);
+
+ /* delay for > 31 usec to allow active bit to become set */
+ rtems_bsp_delay(100);
+
+ /* Wait until interface not active */
+ while((val = read32(bridgeaddr + 0x804)) & 0x80000000) {
+ rtems_bsp_delay(1);
+ }
+
+ if (((val >> 8) & 0xff) != rsPMCQ1eeprom[i]) {
+ printk("Error writing byte %d expected 0x%02x got 0x%02x\n",
+ i, rsPMCQ1eeprom[i], (unsigned char)(val >> 8));
+ status = RTEMS_IO_ERROR;
+ break;
+ }
+ }
+ }
+ return(status);
+}
+
+uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg )
+{
+ uint32_t data;
+
+ data = ( *((unsigned long *) (base + reg)) );
+#ifdef DEBUG_360
+ printk("EPLD Read 0x%x: 0x%08x\n", reg + base, data );
+#endif
+ return data;
+}
+
+void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data )
+{
+ *((unsigned long *) (base + reg)) = data;
+#ifdef DEBUG_360
+ printk("EPLD Write 0x%x: 0x%08x\n", reg+base, data );
+#endif
+}
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
new file mode 100644
index 0000000000..a38d24db35
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
@@ -0,0 +1,148 @@
+/* rsPMCQ1.h - Radstone PMCQ1 private header
+ *
+ * Copyright 2000 Radstone Technology
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ * COPYRIGHT (c) 2005.
+ * 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.
+ *
+ */
+
+/*
+ modification history
+ --------------------
+ 01a,20Dec00,jpb created
+ */
+
+#ifndef __INCPMCQ1H
+#define __INCPMCQ1H
+
+#include <libcpu/io.h>
+#include <bsp/irq.h>
+
+/*
+ * PMCQ1 definitions
+ */
+
+/*
+ * 360 definitions
+ */
+
+#define Q1_360_MBAR 0x0003ff00 /* master base address register */
+
+#define REG_B_OFFSET 0x1000 /* offset to the internal registers */
+
+#define Q1_360_SIM_MCR (REG_B_OFFSET+0x00)
+#define Q1_360_SIM_PEPAR (REG_B_OFFSET+0x16)
+#define Q1_360_SIM_SYPCR (REG_B_OFFSET+0x22)
+#define Q1_360_SIM_PICR (REG_B_OFFSET+0x26)
+#define Q1_360_SIM_PITR (REG_B_OFFSET+0x2A)
+#define Q1_360_SIM_GMR (REG_B_OFFSET+0x40)
+#define Q1_360_SIM_BR0 (REG_B_OFFSET+0x50)
+#define Q1_360_SIM_OR0 (REG_B_OFFSET+0x54)
+#define Q1_360_SIM_BR1 (REG_B_OFFSET+0x60)
+#define Q1_360_SIM_OR1 (REG_B_OFFSET+0x64)
+
+#define Q1_360_CPM_ICCR (REG_B_OFFSET+0x500)
+#define Q1_360_CPM_SDCR (REG_B_OFFSET+0x51E)
+#define Q1_360_CPM_CICR (REG_B_OFFSET+0x540)
+
+/*
+ * EPLD offsets
+ *
+ * Only top 4 data bits are used
+ */
+#define PMCQ1_CODE_VERSION 0x00040000 /* Code Version */
+
+#define PMCQ1_BOARD_REVISION 0x00040004 /* Board Revision */
+
+#define PMCQ1_BUILD_OPTION 0x00040008 /* Build Option */
+#define PMCQ1_ACE_FITTED 0x80000000
+#define PMCQ1_QUICC_FITTED 0x40000000
+#define PMCQ1_SRAM_SIZE 0x30000000 /* 01 - 1MB */
+#define PMCQ1_SRAM_FITTED 0x20000000
+
+#define PMCQ1_INT_STATUS 0x0004000c /* Interrupt Status */
+#define PMCQ1_INT_STATUS_MA 0x20000000
+#define PMCQ1_INT_STATUS_QUICC 0x10000000
+
+#define PMCQ1_INT_MASK 0x00040010 /* Interrupt Mask */
+#define PMCQ1_INT_MASK_QUICC 0x20000000
+#define PMCQ1_INT_MASK_MA 0x10000000
+
+#define PMCQ1_RT_ADDRESS 0x00040014 /* RT Address Latch */
+
+#define PMCQ1_DRIVER_ENABLE 0x0004001c /* Channel Drive Enable */
+#define PMCQ1_DRIVER_ENABLE_3 0x80000000
+#define PMCQ1_DRIVER_ENABLE_2 0x40000000
+#define PMCQ1_DRIVER_ENABLE_1 0x20000000
+#define PMCQ1_DRIVER_ENABLE_0 0x10000000
+
+#define PMCQ1_MINIACE_REGS 0x000c0000
+#define PMCQ1_MINIACE_MEM 0x00100000
+#define PMCQ1_RAM 0x00200000
+
+/*
+#define PMCQ1_Read_EPLD( _base, _reg ) ( *((unsigned long *) ((unsigned32)_base + _reg)) )
+#define PMCQ1_Write_EPLD( _base, _reg, _data ) *((unsigned long *) ((unsigned32)_base + _reg)) = _data
+*/
+uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg );
+void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data );
+
+/*
+ * QSPAN-II register offsets
+ */
+
+#define QSPAN2_INT_STATUS 0x00000600
+
+
+#define PCI_ID(v, d) ((d << 16) | v)
+
+
+#define PCI_VEN_ID_RADSTONE 0x11b5
+#define PCI_DEV_ID_PMC1553 0x0001
+#define PCI_DEV_ID_PMCF1 0x0002
+#define PCI_DEV_ID_PMCMMA 0x0003
+#define PCI_DEV_ID_PMCQ1 0x0007
+#define PCI_DEV_ID_PMCQ2 0x0008
+#define PCI_DEV_ID_PMCF1V2 0x0012
+
+
+
+typedef struct _PMCQ1BoardData
+{
+ struct _PMCQ1BoardData *pNext;
+ unsigned long busNo;
+ unsigned long slotNo;
+ unsigned long funcNo;
+ unsigned long baseaddr;
+ unsigned long bridgeaddr;
+ rtems_irq_hdl quiccInt;
+ rtems_irq_hdl_param quiccArg;
+ rtems_irq_hdl maInt;
+ rtems_irq_hdl_param maArg;
+} PMCQ1BoardData, *PPMCQ1BoardData;
+
+extern PPMCQ1BoardData pmcq1BoardData;
+
+/*
+ * Function declarations
+ */
+extern unsigned int rsPMCQ1QuiccIntConnect(
+ unsigned long busNo, unsigned long slotNo,unsigned long funcNo, rtems_irq_hdl routine,rtems_irq_hdl_param arg );
+unsigned int rsPMCQ1Init();
+
+#endif /* __INCPMCQ1H */
diff --git a/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h b/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h
new file mode 100644
index 0000000000..8c13a506d7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef EP1A_BSP_H
+#define EP1A_BSP_H
+
+#include <bspopts.h>
+
+#include <rtems.h>
+#include <rtems/console.h>
+#include <libcpu/io.h>
+#include <rtems/clockdrv.h>
+#include <bsp/vectors.h>
+
+
+/*
+ * confdefs.h overrides for this BSP:
+ * - termios serial ports (defaults to 1)
+ * - Interrupt stack space is not minimum if defined.
+ */
+
+#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
+#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024)
+
+/* fundamental addresses for BSP (CHRPxxx and PREPxxx are from libcpu/io.h) */
+#define _IO_BASE CHRP_ISA_IO_BASE
+#define _ISA_MEM_BASE CHRP_ISA_MEM_BASE
+/* address of our ram on the PCI bus */
+#define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET
+#define PCI_MEM_BASE 0x80000000
+#define PCI_MEM_BASE_ADJUSTMENT 0
+
+/* address of our ram on the PCI bus */
+#define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET
+
+/* offset of pci memory as seen from the CPU */
+#define PCI_MEM_BASE 0x00000000
+
+/* Override the default values for the following DEFAULT */
+#define PCI_CONFIG_ADDR 0xfec00000 /* 0xcf8 */
+#define PCI_CONFIG_DATA 0xfee00000 /* 0xcfc */
+
+/*
+ * EP1A configuration Registers.
+ * Note: All addresses assume flash boot.
+ */
+
+#define EQUIPMENT_PRESENT_REGISTER1 ((volatile unsigned char *)0xffa00000)
+#define EQUIPMENT_PRESENT_REGISTER2 ((volatile unsigned char *)0xffa00008)
+#define BOARD_REVISION_REGISTER1 ((volatile unsigned char *)0xffa00010)
+#define BOARD_REVISION_REGISTER2 ((volatile unsigned char *)0xffa00018)
+#define GENERAL_REGISTER1 ((volatile unsigned char *)0xffa00020)
+#define GENERAL_REGISTER2 ((volatile unsigned char *)0xffa00028)
+#define WATCHDOG_TRIGGER ((volatile unsigned char *)0xffa00030)
+
+/* EQUIPMENT_PRESENT_REGISTER1 */
+#define BANK_MEMORY_SIZE_128MB 0x20
+#define BANK_MEMORY_SIZE_64MB 0x10
+#define ECC_ENABLED 0x04
+
+/* EQUIPMENT-PRESENT_REGISTER2 */
+#define PLL_CFG_MASK 0xf8
+#define MHZ_33_66_200 0x70 /* PCI MEM CPU Frequency */
+#define MHZ_33_100_200 0x80 /* PCI MEM CPU Frequency */
+#define MHZ_33_66_266 0xb0 /* PCI MEM CPU Frequency */
+#define MHZ_33_66_333 0x50 /* PCI MEM CPU Frequency */
+#define MHZ_33_100_333 0x08 /* PCI MEM CPU Frequency */
+#define MHZ_33_100_350 0x78 /* PCI MEM CPU Frequency */
+
+#define PMC_SLOT1_PRESENT 0x02
+#define PMC_SLOT2_PRESENT 0x01
+
+/* BOARD_REVISION_REGISTER1 */
+#define ARTWORK_REVISION_MASK 0xf0
+#define BUILD_REVISION_MASK 0x0f
+
+/* BOARD_REVISION_REGISTER2 */
+#define HARDWARE_ID_MASK 0xe0
+#define HARDWARE_ID_PPC5_EP1A 0xe0
+#define HARDWARE_ID_EP1B 0xc0
+
+/* GENERAL_REGISTER1 */
+#define DISABLE_WATCHDOG 0x80
+#define DISABLE_RESET_SWITCH 0x40
+#define DISABLE_USER_FLASH 0x20
+#define DISABLE_BOOT_FLASH 0x10
+#define LED4_OFF 0x08
+#define LED3_OFF 0x04
+#define LED2_OFF 0x02
+#define LED1_OFF 0x01
+
+
+/* GENERAL_REGISTER2 */
+#define BSP_FLASH_VPP_ENABLE 0x01
+#define BSP_FLASH_PAGE_MASK 0x38
+#define BSP_FLASH_PAGE_SHIFT 0x03
+#define BSP_BIT_SLOWSTART 0x04
+#define BSP_OFFLINE 0x02
+#define BSP_SYSFAIL 0x01
+
+/* WATCHDOG_TRIGGER */
+#define BSP_FLASH_BASE 0xff000000
+#define BSP_VME_A16_BASE 0x9fff0000
+#define BSP_VME_A24_BASE 0x9f000000
+
+/*
+ * address definitions for several devices
+ *
+ */
+#define UART_OFFSET_1_8245 (0x04500)
+#define UART_OFFSET_2_8245 (0x04600)
+#define UART_BASE_COM1 0xff800000
+#define UART_BASE_COM2 0xff800040
+
+#include <bsp/openpic.h>
+
+/* Note docs list 0x41000 but OpenPIC has a 0x1000 pad at the start
+ * assume that open pic specifies this pad but not mentioned in
+ * 8245 docs.
+ * This is an offset from EUMBBAR
+ */
+#define BSP_OPEN_PIC_BASE_OFFSET 0x40000
+#define BSP_PIC_DO_EOI openpic_eoi(0)
+
+
+#ifndef ASM
+#define outport_byte(port,value) outb(value,port)
+#define outport_word(port,value) outw(value,port)
+#define outport_long(port,value) outl(value,port)
+
+#define inport_byte(port,value) (value = inb(port))
+#define inport_word(port,value) (value = inw(port))
+#define inport_long(port,value) (value = inl(port))
+
+/*
+ * EUMMBAR
+ */
+extern unsigned int EUMBBAR;
+
+/*
+ * Total memory
+ */
+extern unsigned int BSP_mem_size;
+
+/*
+ * PCI Bus Frequency
+ */
+extern unsigned int BSP_bus_frequency;
+
+/*
+ * processor clock frequency
+ */
+extern unsigned int BSP_processor_frequency;
+
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+extern unsigned int BSP_time_base_divisor;
+
+#define BSP_Convert_decrementer( _value ) \
+ ((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value)))
+
+#define Processor_Synchronize() \
+ asm(" eieio ")
+
+extern rtems_configuration_table BSP_Configuration;
+extern void BSP_panic(char *s);
+extern void rtemsReboot(void);
+extern int BSP_disconnect_clock_handler (void);
+extern int BSP_connect_clock_handler (void);
+
+/*
+ * FLASH
+ */
+int BSP_FLASH_Enable_writes( rtems_unsigned32 area );
+int BSP_FLASH_Disable_writes( rtems_unsigned32 area );
+void BSP_FLASH_set_page( rtems_unsigned8 page );
+
+#define BSP_FLASH_ENABLE_WRITES( _area) BSP_FLASH_Enable_writes( _area )
+#define BSP_FLASH_DISABLE_WRITES(_area) BSP_FLASH_Disable_writes( _area )
+#define BSP_FLASH_SET_PAGE(_page) BSP_FLASH_set_page( _page )
+
+
+/* clear hostbridge errors
+ *
+ * enableMCP: whether to enable MCP checkstop / machine check interrupts
+ * on the hostbridge and in HID0.
+ *
+ * NOTE: HID0 and MEREN are left alone if this flag is 0
+ *
+ * quiet : be silent
+ *
+ * RETURNS : raven MERST register contents (lowermost 16 bits), 0 if
+ * there were no errors
+ */
+extern unsigned long _BSP_clear_hostbridge_errors(int enableMCP, int quiet);
+
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/include/tm27.h b/c/src/lib/libbsp/powerpc/ep1a/include/tm27.h
new file mode 100644
index 0000000000..c62810edda
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/include/tm27.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+#include <bsp/irq.h>
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+void nullFunc() {}
+
+static rtems_irq_connect_data clockIrqData = {BSP_DECREMENTER,
+ 0,
+ (rtems_irq_enable)nullFunc,
+ (rtems_irq_disable)nullFunc,
+ (rtems_irq_is_enabled) nullFunc};
+void Install_tm27_vector(void (*_handler)())
+{
+ clockIrqData.hdl = _handler;
+ if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
+ printk("Error installing clock interrupt handler!\n");
+ rtems_fatal_error_occurred(1);
+ }
+}
+
+#define Cause_tm27_intr() \
+ do { \
+ unsigned32 _clicks = 8; \
+ asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
+ } while (0)
+
+
+#define Clear_tm27_intr() \
+ do { \
+ unsigned32 _clicks = 0xffffffff; \
+ asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
+ } while (0)
+
+#define Lower_tm27_intr() \
+ do { \
+ unsigned32 _msr = 0; \
+ _ISR_Set_level( 0 ); \
+ asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
+ _msr |= 0x8002; \
+ asm volatile( "mtmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
+ } while (0)
+#endif
diff --git a/c/src/lib/libbsp/powerpc/ep1a/irq/irq.c b/c/src/lib/libbsp/powerpc/ep1a/irq/irq.c
new file mode 100644
index 0000000000..1c83338e6d
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/irq/irq.c
@@ -0,0 +1,570 @@
+/*
+ *
+ * This file contains the implementation of the function described in irq.h
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/VME.h>
+#include <bsp/openpic.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/io.h>
+#include <bsp/vectors.h>
+#include <stdlib.h>
+#include <rtems/bspIo.h> /* for printk */
+#define RAVEN_INTR_ACK_REG 0xfeff0030
+
+/*
+ * pointer to the mask representing the additionnal irq vectors
+ * that must be disabled when a particular entry is activated.
+ * They will be dynamically computed from teh prioruty table given
+ * in BSP_rtems_irq_mngt_set();
+ * CAUTION : this table is accessed directly by interrupt routine
+ * prologue.
+ */
+rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER];
+/*
+ * 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;
+
+/*
+ * Check if IRQ is an ISA IRQ
+ */
+static inline int is_isa_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * Check if IRQ is an OPENPIC IRQ
+ */
+static inline int is_pci_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * Check if IRQ is a Porcessor 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)
+ );
+}
+
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * Caution : this function assumes the variable "internal_config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_i8259_masks_from_prio ()
+{
+ int i;
+ int j;
+ /*
+ * Always mask at least current interrupt to prevent re-entrance
+ */
+ for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
+ * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
+ for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
+ /*
+ * Mask interrupts at i8259 level that have a lower priority
+ */
+ if (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) {
+ * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
+ }
+ }
+ }
+}
+
+/*
+ * 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;
+}
+
+
+/*
+ * ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
+ */
+int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+ rtems_irq_connect_data* vchain;
+
+ if (!isValidInterrupt(irq->name)) {
+ printk("Invalid interrupt vector %d\n",irq->name);
+ return 0;
+ }
+ printk("Install Shared interrupt %d\n", irq->name);
+
+ _CPU_ISR_Disable(level);
+
+ if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) {
+ _CPU_ISR_Enable(level);
+ printk("IRQ vector %d already connected to an unshared handler\n",irq->name);
+ return 0;
+ }
+
+ vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
+
+ /* save off topmost handler */
+ vchain[0]= rtems_hdl_tbl[irq->name];
+
+ /*
+ * store the data provided by user
+ */
+ rtems_hdl_tbl[irq->name] = *irq;
+
+ /* link chain to new topmost handler */
+ rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
+
+
+ if (is_isa_irq(irq->name)) {
+ /*
+ * Enable interrupt at PIC level
+ */
+ BSP_irq_enable_at_i8259s (irq->name);
+ }
+
+ if (is_pci_irq(irq->name)) {
+ /*
+ * Enable interrupt at OPENPIC level
+ */
+ printk(" openpic_enable_irq %d\n", (int)irq->name );
+ openpic_enable_irq ((int) irq->name ); /* - BSP_PCI_IRQ_LOWEST_OFFSET); */
+ }
+
+ if (is_processor_irq(irq->name)) {
+ /*
+ * Enable exception at processor level
+ */
+ }
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ printk("Invalid interrupt vector %d\n",irq->name);
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via i386_get_current_idt_entry
+ * and then disconnect it using i386_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ _CPU_ISR_Disable(level);
+ if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
+ _CPU_ISR_Enable(level);
+ printk("IRQ vector %d already connected\n",irq->name);
+ return 0;
+ }
+
+ /*
+ * store the data provided by user
+ */
+ rtems_hdl_tbl[irq->name] = *irq;
+ rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
+
+ if (is_isa_irq(irq->name)) {
+ /*
+ * Enable interrupt at PIC level
+ */
+ BSP_irq_enable_at_i8259s (irq->name);
+ }
+
+ if (is_pci_irq(irq->name)) {
+ /*
+ * Enable interrupt at OPENPIC level
+ */
+ openpic_enable_irq ((int) irq->name ); /* - BSP_PCI_IRQ_LOWEST_OFFSET); */
+ }
+
+ if (is_processor_irq(irq->name)) {
+ /*
+ * Enable exception at processor level
+ */
+ }
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+ *irq = rtems_hdl_tbl[irq->name];
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via i386_get_current_idt_entry
+ * and then disconnect it using i386_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ _CPU_ISR_Disable(level);
+ if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+
+ if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
+ {
+ int found = 0;
+
+ for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
+ (vchain->hdl != default_rtems_entry.hdl);
+ (pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
+ {
+ if( vchain->hdl == irq->hdl )
+ {
+ found= -1; break;
+ }
+ }
+
+ if( !found )
+ {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ }
+ else
+ {
+ if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
+ {
+ _CPU_ISR_Enable(level);
+ return 0;
+ }
+ }
+
+ if (is_isa_irq(irq->name)) {
+ /*
+ * disable interrupt at PIC level
+ */
+ BSP_irq_disable_at_i8259s (irq->name);
+ }
+ if (is_pci_irq(irq->name)) {
+ /*
+ * disable interrupt at OPENPIC level
+ */
+ openpic_disable_irq ((int) 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
+ */
+ if( !vchain )
+ {
+ /* single handler vector... */
+ rtems_hdl_tbl[irq->name] = default_rtems_entry;
+ }
+ else
+ {
+ if( pchain )
+ {
+ /* non-first handler being removed */
+ pchain->next_handler = vchain->next_handler;
+ }
+ else
+ {
+ /* first handler isn't malloc'ed, so just overwrite it. Since
+ the contents of vchain are being struct copied, vchain itself
+ goes away */
+ rtems_hdl_tbl[irq->name]= *vchain;
+ }
+ free(vchain);
+ }
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+
+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;
+ return 1;
+
+ _CPU_ISR_Disable(level);
+ /*
+ * set up internal tables used by rtems interrupt prologue
+ */
+ for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
+ /*
+ * Note that openpic_set_priority() sets the TASK priority of the PIC
+ */
+ openpic_set_source_priority(i, internal_config->irqPrioTbl[i]);
+ if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+ openpic_enable_irq ((int) i);
+ {
+ rtems_irq_connect_data* vchain;
+ for( vchain = &rtems_hdl_tbl[i];
+ ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->on(vchain);
+ }
+ }
+
+ }
+ else {
+ /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
+ {
+ rtems_irq_connect_data* vchain;
+ for( vchain = &rtems_hdl_tbl[i];
+ ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->off(vchain);
+ }
+ }
+
+ openpic_disable_irq ((int) i );
+ }
+ }
+ /*
+ * Must enable PCI/ISA bridge IRQ
+ */
+ openpic_enable_irq (0);
+ /*
+ * finish with Processor exceptions handled like IRQ
+ */
+ 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]); */
+ {
+ rtems_irq_connect_data* vchain;
+ for( vchain = &rtems_hdl_tbl[i];
+ ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->on(vchain);
+ }
+ }
+
+ }
+ else {
+ /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
+ {
+ rtems_irq_connect_data* vchain;
+ for( vchain = &rtems_hdl_tbl[i];
+ ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->off(vchain);
+ }
+ }
+
+ }
+ }
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+{
+ *config = internal_config;
+ return 0;
+}
+
+int _BSP_vme_bridge_irq = -1;
+
+unsigned BSP_spuriousIntr = 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 isaIntr; /* boolean */
+ register unsigned oldMask = 0; /* old isa pic masks */
+ register unsigned newMask; /* new isa pic masks */
+ register unsigned msr;
+ register unsigned new_msr;
+
+ if (excNum == ASM_DEC_VECTOR) {
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ rtems_hdl_tbl[BSP_DECREMENTER].hdl( rtems_hdl_tbl[BSP_DECREMENTER].handle );
+
+ _CPU_MSR_SET(msr);
+ return;
+
+ }
+
+ irq = openpic_irq(0);
+
+ if (irq == OPENPIC_VEC_SPURIOUS) {
+ ++BSP_spuriousIntr;
+ return;
+ }
+
+ isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
+ if (isaIntr) {
+ /*
+ * Acknowledge and read 8259 vector
+ */
+ irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
+ /*
+ * store current PIC mask
+ */
+ oldMask = i8259s_cache;
+ newMask = oldMask | irq_mask_or_tbl [irq];
+ i8259s_cache = newMask;
+ outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+ outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+ BSP_irq_ack_at_i8259s (irq);
+ openpic_eoi(0);
+ }
+
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ {
+ rtems_irq_connect_data* vchain;
+ irq -= 16; /* Correct the vector for the 8240 */
+ for( vchain = &rtems_hdl_tbl[irq];
+ ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
+ vchain = (rtems_irq_connect_data*)vchain->next_handler )
+ {
+ vchain->hdl( vchain->handle );
+ }
+ }
+ _CPU_MSR_SET(msr);
+
+ if (isaIntr) {
+ i8259s_cache = oldMask;
+ outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
+ outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
+ }
+ else {
+#ifdef BSP_PCI_VME_DRIVER_DOES_EOI
+ /* leave it to the VME bridge driver to do EOI, so
+ * it can re-enable the openpic while handling
+ * VME interrupts (-> VME priorities in software)
+ */
+ if (_BSP_vme_bridge_irq != irq)
+#endif
+ openpic_eoi(0);
+ }
+}
+
+
+
+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/ep1a/irq/irq_init.c b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c
new file mode 100644
index 0000000000..5ef8467619
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c
@@ -0,0 +1,332 @@
+/* irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
+ * to make it valid for MVME2300 Motorola boards.
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
+ * Use the new interface to openpic_init
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+#include <bsp/pci.h>
+#include <bsp/residual.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <libcpu/raw_exception.h>
+#include <bsp/motorola.h>
+#include <rtems/bspIo.h>
+
+/*
+#define SHOW_ISA_PCI_BRIDGE_SETTINGS
+*/
+
+typedef struct {
+ unsigned char bus; /* few chance the PCI/ISA bridge is not on first bus but ... */
+ unsigned char device;
+ unsigned char function;
+} pci_isa_bridge_device;
+
+pci_isa_bridge_device* via_82c586 = 0;
+static pci_isa_bridge_device bridge;
+
+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();
+
+/*
+ * 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 , handle , on , off , isOn */
+ 0, nop_func , NULL , nop_func , nop_func , not_connected
+};
+static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
+ /*
+ * actual rpiorities for interrupt :
+ * 0 means that only current interrupt is masked
+ * 255 means all other interrupts are masked
+ */
+ /*
+ * ISA interrupts.
+ * The second entry has a priority of 255 because
+ * it is the slave pic entry and is should always remain
+ * unmasked.
+ */
+ 0,0,
+ 255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /*
+ * PCI Interrupts
+ */
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
+ /*
+ * Processor exceptions handled as interrupts
+ */
+ 0
+};
+
+static unsigned char mcp750_openpic_initpolarities[] = {
+ 1, /* 0 8259 cascade */
+ 0, /* 1 all the rest of them */
+ 0, /* 2 all the rest of them */
+ 0, /* 3 all the rest of them */
+ 0, /* 4 all the rest of them */
+ 0, /* 5 all the rest of them */
+ 0, /* 6 all the rest of them */
+ 0, /* 7 all the rest of them */
+ 0, /* 8 all the rest of them */
+ 0, /* 9 all the rest of them */
+ 0, /* 10 all the rest of them */
+ 0, /* 11 all the rest of them */
+ 0, /* 12 all the rest of them */
+ 0, /* 13 all the rest of them */
+ 0, /* 14 all the rest of them */
+ 0, /* 15 all the rest of them */
+ 0, /* 16 all the rest of them */
+ 0, /* 17 all the rest of them */
+ 1, /* 18 all the rest of them */
+ 1, /* 19 all the rest of them */
+ 1, /* 20 all the rest of them */
+ 1, /* 21 all the rest of them */
+ 1, /* 22 all the rest of them */
+ 1, /* 23 all the rest of them */
+ 1, /* 24 all the rest of them */
+ 1, /* 25 all the rest of them */
+};
+
+static unsigned char mcp750_openpic_initsenses[] = {
+ 1, /* 0 MCP750_INT_PCB(8259) */
+ 0, /* 1 MCP750_INT_FALCON_ECC_ERR */
+ 1, /* 2 MCP750_INT_PCI_ETHERNET */
+ 1, /* 3 MCP750_INT_PCI_PMC */
+ 1, /* 4 MCP750_INT_PCI_WATCHDOG_TIMER1 */
+ 1, /* 5 MCP750_INT_PCI_PRST_SIGNAL */
+ 1, /* 6 MCP750_INT_PCI_FALL_SIGNAL */
+ 1, /* 7 MCP750_INT_PCI_DEG_SIGNAL */
+ 1, /* 8 MCP750_INT_PCI_BUS1_INTA */
+ 1, /* 9 MCP750_INT_PCI_BUS1_INTB */
+ 1, /*10 MCP750_INT_PCI_BUS1_INTC */
+ 1, /*11 MCP750_INT_PCI_BUS1_INTD */
+ 1, /*12 MCP750_INT_PCI_BUS2_INTA */
+ 1, /*13 MCP750_INT_PCI_BUS2_INTB */
+ 1, /*14 MCP750_INT_PCI_BUS2_INTC */
+ 1, /*15 MCP750_INT_PCI_BUS2_INTD */
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1
+};
+
+void VIA_isa_bridge_interrupts_setup(void)
+{
+ pci_isa_bridge_device pci_dev;
+ unsigned int temp;
+ unsigned char tmp;
+ unsigned char maxBus;
+ unsigned found = 0;
+
+ maxBus = BusCountPCI();
+ pci_dev.function = 0; /* Assumes the bidge is the first function */
+
+ for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
+#ifdef SCAN_PCI_PRINT
+ printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
+#endif
+ for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
+#ifdef SCAN_PCI_PRINT
+ printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
+#endif
+ pci_read_config_dword(pci_dev.bus, pci_dev.device, pci_dev.function,
+ PCI_VENDOR_ID, &temp);
+#ifdef SCAN_PCI_PRINT
+ printk("Vendor/device = %x\n", temp);
+#endif
+ if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
+ ) {
+ bridge = pci_dev;
+ via_82c586 = &bridge;
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ /*
+ * Should print : bus = 0, device = 11, function = 0 on a MCP750.
+ */
+ printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
+ via_82c586->bus,
+ via_82c586->device,
+ via_82c586->function);
+#endif
+ found = 1;
+ goto loop_exit;
+
+ }
+ }
+ }
+loop_exit:
+ if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n");
+
+ tmp = inb(0x810);
+ if ( !(tmp & 0x2)) {
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk("This is a second generation MCP750 board\n");
+ printk("We must reprogram the PCI/ISA bridge...\n");
+#endif
+ pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x47, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
+#endif
+ /*
+ * Enable 4D0/4D1 ISA interrupt level/edge config registers
+ */
+ tmp |= 0x20;
+ pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x47, tmp);
+ /*
+ * Now program the ISA interrupt edge/level
+ */
+ tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
+ outb(tmp, ISA8259_S_ELCR);
+ tmp = ELCRM_INT5_LVL;
+ outb(tmp, ISA8259_M_ELCR);;
+ /*
+ * Set the Interrupt inputs to non-inverting level interrupt
+ */
+ pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x54, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
+#endif
+ tmp = 0;
+ pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x54, tmp);
+ }
+ else {
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk("This is a first generation MCP750 board\n");
+ printk("We just show the actual value used by PCI/ISA bridge\n");
+#endif
+ pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x47, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
+#endif
+ /*
+ * Show the Interrupt inputs inverting/non-inverting level status
+ */
+ pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
+ 0x54, &tmp);
+#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
+ printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
+#endif
+ }
+}
+
+ /*
+ * This code assumes the exceptions management setup has already
+ * been done. We just need to replace the exceptions that will
+ * be handled like interrupt. On mcp750/mpc750 and many PPC processors
+ * this means the decrementer exception and the external exception.
+ */
+void BSP_rtems_irq_mng_init(unsigned cpuId)
+{
+ rtems_raw_except_connect_data vectorDesc;
+ int i;
+
+ /*
+ * First initialize the Interrupt management hardware
+ */
+#ifdef TRACE_IRQ_INIT
+ printk("Going to initialize openpic compliant device\n");
+#endif
+ openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses);
+
+#ifdef TRACE_IRQ_INIT
+ printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
+#endif
+
+ /*
+ * 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");
+ }
+#ifdef TRACE_IRQ_INIT
+ printk("RTEMS IRQ management is now operationnal\n");
+#endif
+}
+
diff --git a/c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c b/c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c
new file mode 100644
index 0000000000..8a441899c2
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <libcpu/io.h>
+#include <libcpu/spr.h>
+
+#include <bsp.h>
+#include <bsp/pci.h>
+#include <bsp/consoleIo.h>
+#include <bsp/residual.h>
+#include <bsp/openpic.h>
+
+#include <rtems/bspIo.h>
+
+/*
+ * For the 8240 and the 8245 there is no host bridge the
+ * Open PIC device is built into the processor chip.
+ */
+
+void detect_host_bridge()
+{
+ OpenPIC=(volatile struct OpenPIC *) (EUMBBAR + BSP_OPEN_PIC_BASE_OFFSET );
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/start/start.S b/c/src/lib/libbsp/powerpc/ep1a/start/start.S
new file mode 100644
index 0000000000..873d729787
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/start/start.S
@@ -0,0 +1,151 @@
+/*
+ * This is based on the mvme-crt0.S file from libgloss/rs6000.
+ * crt0.S -- startup file for PowerPC systems.
+ *
+ * (c) 1998, Radstone Technology plc.
+ *
+ *
+ * This is an unpublished work the copyright in which vests
+ * in Radstone Technology plc. All rights reserved.
+ *
+ * The information contained herein is the property of Radstone
+ * Technology plc. and is supplied without liability for
+ * errors or omissions and no part may be reproduced, used or
+ * disclosed except as authorized by contract or other written
+ * permission. The copyright and the foregoing
+ * restriction on reproduction, use and disclosure extend to
+ * all the media in which this information may be
+ * embodied.
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * start.S,v 1.4 2002/04/19 13:25:27 joel Exp
+ */
+/*
+#include <ppc-asm.h>
+#include <bsp.h>
+*/
+
+#include <asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/io.h>
+#include <ppc-asm.h>
+
+#define H0_60X_ICE 0x8000 /* HID0 I-Cache Enable */
+#define H0_60X_DCE 0x4000 /* HID0 D-Cache Enable */
+
+ .file "start.s"
+
+ .extern FUNC_NAME(atexit)
+ .globl FUNC_NAME(__atexit)
+ .section ".sdata","aw"
+ .align 2
+FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
+ .long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
+
+ .section ".fixup","aw"
+ .align 2
+ .long FUNC_NAME(__atexit)
+
+ .text
+ .globl __rtems_entry_point
+ .type __rtems_entry_point,@function
+__rtems_entry_point:
+
+ /* Set MSR */
+ /*
+ * Enable data and instruction address translation and floating point
+ */
+ li r3,MSR_IR | MSR_DR | MSR_FP
+ mtmsr r3
+
+ /* XXX - ADD BACK IN CACHING INSTRUCTIONS */
+
+ /* clear bss */
+ lis r6,__bss_start@h
+ ori r6,r6,__bss_start@l
+ lis r7,__bss_end@h
+ ori r7,r7,__bss_end@l
+
+ cmplw 1,r6,r7
+ bc 4,4,.Lbss_done
+
+ subf r8,r6,r7 /* number of bytes to zero */
+ srwi r9,r8,2 /* number of words to zero */
+ mtctr r9
+ li r0,0 /* zero to clear memory */
+ addi r6,r6,-4 /* adjust so we can use stwu */
+.Lbss_loop:
+ stwu r0,4(r6) /* zero bss */
+ bdnz .Lbss_loop
+
+.Lbss_done:
+
+ /* clear sbss */
+ lis r6,__sbss_start@h
+ ori r6,r6,__sbss_start@l
+ lis r7,__sbss_end@h
+ ori r7,r7,__sbss_end@l
+
+ cmplw 1,r6,r7
+ bc 4,4,.Lsbss_done
+
+ subf r8,r6,r7 /* number of bytes to zero */
+ srwi r9,r8,2 /* number of words to zero */
+ mtctr r9
+ li r0,0 /* zero to clear memory */
+ addi r6,r6,-4 /* adjust so we can use stwu */
+.Lsbss_loop:
+ stwu r0,4(r6) /* zero sbss */
+ bdnz .Lsbss_loop
+
+.Lsbss_done:
+
+ lis sp,__stack@h
+ ori sp,sp,__stack@l
+
+ /* set up initial stack frame */
+ addi sp,sp,-4 /* make sure we don't overwrite debug mem */
+ lis r0,0
+ stw r0,0(sp) /* clear back chain */
+ stwu sp,-56(sp) /* push another stack frame */
+
+ lis r5,environ@ha
+ la r5,environ@l(r5) /* environp */
+ li r4, 0 /* argv */
+ li r3, 0 /* argc */
+
+ /* Let her rip */
+ bl FUNC_NAME(boot_card)
+
+ /*
+ * This should never get reached
+ */
+ /*
+ * Return MSR to its reset state
+ */
+ li r3,0
+ mtmsr r3
+ isync
+
+ /*
+ * Call reset entry point
+ */
+ lis r3,0xfff0
+ ori r3,r3,0x100
+ mtlr r3
+ blr
+.Lstart:
+ .size _start,.Lstart-_start
+
+ .comm environ,4,4
diff --git a/c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c b/c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c
new file mode 100644
index 0000000000..7a786b0c68
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c
@@ -0,0 +1,523 @@
+/*
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * COPYRIGHT (c) 1989-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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <bsp/consoleIo.h>
+#include <libcpu/spr.h>
+#include <bsp/residual.h>
+#include <bsp/pci.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <bsp/VME.h>
+#include <bsp.h>
+#include <libcpu/bat.h>
+#include <libcpu/pte121.h>
+#include <libcpu/cpuIdent.h>
+#include <bsp/vectors.h>
+#include <rtems/powerpc/powerpc.h>
+
+extern unsigned long __rtems_end[];
+extern void L1_caches_enables();
+extern unsigned get_L2CR();
+extern void set_L2CR(unsigned);
+extern void bsp_cleanup(void);
+extern Triv121PgTbl BSP_pgtbl_setup();
+extern void BSP_pgtbl_activate();
+extern void BSP_vme_config();
+unsigned int rsPMCQ1Init();
+
+SPR_RW(SPRG0)
+SPR_RW(SPRG1)
+
+void ShowBATS(){
+ unsigned32 lower;
+ unsigned32 upper;
+
+ __MFSPR(536, upper);
+ __MFSPR(537, lower);
+ printk("BAT0 %08x %08x\n", upper, lower );
+
+ __MFSPR(538, upper);
+ __MFSPR(539, lower);
+ printk("BAT1 %08x %08x\n", upper, lower );
+
+ __MFSPR(540, upper);
+ __MFSPR(541, lower);
+ printk("BAT2 %08x %08x\n", upper, lower );
+
+ __MFSPR(542, upper);
+ __MFSPR(543, lower);
+ printk("BAT3 %08x %08x\n", upper, lower );
+
+}
+
+uint8_t LightIdx = 0;
+void BSP_Increment_Light(){
+ uint8_t data;
+ data = *GENERAL_REGISTER1;
+ data &= 0xf0;
+ data |= LightIdx++;
+ *GENERAL_REGISTER1 = data;
+}
+
+void BSP_Fatal_Fault_Light() {
+ uint8_t data;
+ data = *GENERAL_REGISTER1;
+ data &= 0xf0;
+ data |= 0x7;
+ while(1)
+ *GENERAL_REGISTER1 = data;
+}
+
+void write_to_Q2ram(int offset, unsigned int data )
+{
+printk("0x%x ==> %d\n", offset, data );
+#if 0
+ unsigned int *ptr = 0x82000000;
+ ptr += offset;
+ *ptr = data;
+#endif
+}
+
+/*
+ * Vital Board data Start using DATA RESIDUAL
+ */
+
+unsigned32 VME_Slot1 = FALSE;
+
+/*
+ * Total memory.
+ * Note: RAM_END is defined in linkcmds. We want to verify that the application
+ * is only using 10M of memory, and we do this by only accounting for this
+ * much memory.
+ */
+extern int RAM_END;
+unsigned int BSP_mem_size = (unsigned int)&RAM_END;
+
+/*
+ * PCI Bus Frequency
+ */
+unsigned int BSP_bus_frequency;
+
+/*
+ * processor clock frequency
+ */
+unsigned int BSP_processor_frequency;
+
+/*
+ * Time base divisior (how many tick for 1 second).
+ */
+unsigned int BSP_time_base_divisor = 1000; /* XXX - Just a guess */
+
+/*
+ * system init stack and soft ir stack size
+ */
+#define INIT_STACK_SIZE 0x1000
+#define INTR_STACK_SIZE CONFIGURE_INTERRUPT_STACK_MEMORY
+
+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");
+}
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern rtems_configuration_table Configuration;
+
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+int BSP_FLASH_Disable_writes(
+ rtems_unsigned32 area
+)
+{
+ unsigned char data;
+
+ data = *GENERAL_REGISTER1;
+ data |= DISABLE_USER_FLASH;
+ *GENERAL_REGISTER1 = data;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+int BSP_FLASH_Enable_writes(
+ rtems_unsigned32 area /* IN */
+)
+{
+ unsigned char data;
+
+ data = *GENERAL_REGISTER1;
+ data &= (~DISABLE_USER_FLASH);
+ *GENERAL_REGISTER1 = data;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+void BSP_FLASH_set_page(
+ rtems_unsigned8 page
+)
+{
+ unsigned char data;
+
+ /* Set the flash page register. */
+ data = *GENERAL_REGISTER2;
+ data &= ~(BSP_FLASH_PAGE_MASK);
+ data |= 0x80 | (page << BSP_FLASH_PAGE_SHIFT);
+ *GENERAL_REGISTER2 = data;
+}
+
+/*
+ * Use the shared implementations of the following routines
+ */
+
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ * 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)
+{
+ rtems_unsigned32 heap_start;
+ rtems_unsigned32 heap_size;
+ rtems_unsigned32 heap_sbrk_spared;
+ extern rtems_unsigned32 _bsp_sbrk_init(rtems_unsigned32, rtems_unsigned32*);
+ heap_start = ((rtems_unsigned32) __rtems_end) +INIT_STACK_SIZE + INTR_STACK_SIZE;
+ if (heap_start & (CPU_ALIGNMENT-1))
+ heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+ heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
+
+ heap_sbrk_spared=_bsp_sbrk_init(heap_start, &heap_size);
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk(" HEAP start %x size %x (%x bytes spared for sbrk)\n", heap_start, heap_size, heap_sbrk_spared);
+#endif
+
+ bsp_libc_init((void *) 0, heap_size, heap_sbrk_spared);
+ rsPMCQ1Init();
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+void zero_bss()
+{
+ /* prevent these from being accessed in the short data areas */
+ extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
+ extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
+ memset(__SBSS_START__, 0, ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__));
+ memset(__SBSS2_START__, 0, ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__));
+ memset(__bss_start, 0, ((unsigned) __rtems_end) - ((unsigned)__bss_start));
+}
+
+void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
+{
+#if 0
+ residualCopy = *r3;
+ strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
+ loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
+#endif
+}
+
+unsigned int EUMBBAR;
+
+unsigned int get_eumbbar() {
+ register int a, e;
+
+ asm volatile( "lis %0,0xfec0; ori %0,%0,0x0000": "=r" (a) );
+ asm volatile("sync");
+
+ asm volatile("lis %0,0x8000; ori %0,%0,0x0078": "=r"(e) );
+ asm volatile("stwbrx %0,0x0,%1": "=r"(e): "r"(a));
+ asm volatile("sync");
+
+ asm volatile("lis %0,0xfee0; ori %0,%0,0x0000": "=r" (a) );
+ asm volatile("sync");
+
+ asm volatile("lwbrx %0,0x0,%1": "=r" (e): "r" (a));
+ asm volatile("isync");
+ return e;
+}
+
+void Read_ep1a_config_registers( ppc_cpu_id_t myCpu ) {
+ unsigned char value;
+
+ /*
+ * Print out the board and revision.
+ */
+
+ printk("Board: ");
+ printk( get_ppc_cpu_type_name(myCpu) );
+
+ value = *BOARD_REVISION_REGISTER2 & HARDWARE_ID_MASK;
+ if ( value == HARDWARE_ID_PPC5_EP1A )
+ printk(" EP1A ");
+ else if ( value == HARDWARE_ID_EP1B )
+ printk(" EP1B ");
+ else
+ printk(" Unknown ");
+
+ value = *BOARD_REVISION_REGISTER2&0x1;
+ printk("Board ID %08x", value);
+ if(value == 0x0){
+ VME_Slot1 = TRUE;
+ printk("VME Slot 1\n");
+ }
+ else{
+ VME_Slot1 = FALSE;
+ printk("\n");
+ }
+
+ printk("Revision: ");
+ value = *BOARD_REVISION_REGISTER1;
+ printk("%d%c\n\n", value>>4, 'A'+(value&BUILD_REVISION_MASK) );
+
+ /*
+ * Get the CPU, XXX frequency
+ */
+ value = *EQUIPMENT_PRESENT_REGISTER2 & PLL_CFG_MASK;
+ switch( value ) {
+ case MHZ_33_66_200: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 200000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ case MHZ_33_100_200: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 200000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ case MHZ_33_66_266: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 266000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ case MHZ_33_66_333: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 333000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ case MHZ_33_100_333: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 333000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ case MHZ_33_100_350: /* PCI, MEM, & CPU Frequency */
+ BSP_processor_frequency = 350000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ default:
+ printk("ERROR: Unknown Processor frequency 0x%02x please fill in bspstart.c\n",value);
+ BSP_processor_frequency = 350000000;
+ BSP_bus_frequency = 33000000;
+ break;
+ }
+}
+
+/*
+ * bsp_start
+ *
+ * This routine does the bulk of the system initialization.
+ */
+
+void bsp_start( void )
+{
+ unsigned char *stack;
+ register uint32_t intrStack;
+ register uint32_t *intrStackPtr;
+ unsigned char *work_space_start;
+ ppc_cpu_id_t myCpu;
+ ppc_cpu_revision_t myCpuRevision;
+ Triv121PgTbl pt=0; /* R = e; */
+
+ /*
+ * 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...
+ */
+ BSP_Increment_Light();
+ myCpu = get_ppc_cpu_type();
+ myCpuRevision = get_ppc_cpu_revision();
+
+ EUMBBAR = get_eumbbar();
+ printk("EUMBBAR 0x%08x\n", EUMBBAR );
+
+ /*
+ * Note this sets BSP_processor_frequency based upon register settings.
+ * It must be done prior to setting up hooks.
+ */
+ Read_ep1a_config_registers( myCpu );
+
+ /*
+ * Set up our hooks
+ * Make sure libc_init is done before drivers initialized so that
+ * they can use atexit()
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+ Cpu_table.do_zero_of_workspace = TRUE;
+ Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
+ Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
+ Cpu_table.exceptions_in_RAM = TRUE;
+
+ShowBATS();
+#if 0 /* XXX - Add back in cache enable when we get this up and running!! */
+ /*
+ * enables L1 Cache. Note that the L1_caches_enables() codes checks for
+ * relevant CPU type so that the reason why there is no use of myCpu...
+ */
+ L1_caches_enables();
+#endif
+
+ /*
+ * the initial stack has aready been set to this value in start.S
+ * so there is no need to set it in r1 again... It is just for info
+ * so that It can be printed without accessing R1.
+ */
+ stack = ((unsigned char*) __rtems_end) + INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
+
+ /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
+ *((unsigned32 *)stack) = 0;
+
+ /*
+ * Initialize the interrupt related settings
+ * SPRG1 = software managed IRQ stack
+ *
+ * This could be done latter (e.g in IRQ_INIT) but it helps to understand
+ * some settings below...
+ */
+ intrStack = ((uint32_t) __rtems_end) +
+ INIT_STACK_SIZE + INTR_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
+
+ /* make sure it's properly aligned */
+ intrStack &= ~(CPU_STACK_ALIGNMENT-1);
+
+ /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
+ intrStackPtr = (uint32_t*) intrStack;
+ *intrStackPtr = 0;
+
+ _write_SPRG1((unsigned int)intrStack);
+
+ /* signal them that we have fixed PR288 - eventually, this should go away */
+ _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
+
+ /*
+ * Initialize default raw exception hanlders. See vectors/vectors_init.c
+ */
+ initialize_exceptions();
+
+ /*
+ * Init MMU block address translation to enable hardware
+ * access
+ */
+ setdbat(1, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
+ setdbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
+
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Going to start PCI buses scanning and initialization\n");
+#endif
+ pci_initialize();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Number of PCI buses found is : %d\n", BusCountPCI());
+#endif
+#ifdef TEST_RAW_EXCEPTION_CODE
+ printk("Testing exception handling Part 1\n");
+
+ /*
+ * Cause a software exception
+ */
+ __asm__ __volatile ("sc");
+
+ /*
+ * Check we can still catch exceptions and returned coorectly.
+ */
+ printk("Testing exception handling Part 2\n");
+ __asm__ __volatile ("sc");
+#endif
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
+#endif
+ work_space_start =
+ (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
+
+ if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE) {
+ printk( "bspstart: Not enough RAM!!!\n" );
+ bsp_cleanup();
+ }
+
+ BSP_Configuration.work_space_start = work_space_start;
+
+ /*
+ * Initalize RTEMS IRQ system
+ */
+ BSP_rtems_irq_mng_init(0);
+
+ /* Activate the page table mappings only after
+ * initializing interrupts because the irq_mng_init()
+ * routine needs to modify the text
+ */
+ if (pt) {
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Page table setup finished; will activate it NOW...\n");
+#endif
+ BSP_pgtbl_activate(pt);
+ }
+
+ /*
+ * Initialize VME bridge - needs working PCI
+ * and IRQ subsystems...
+ */
+#ifdef SHOW_MORE_INIT_SETTINGS
+ printk("Going to initialize VME bridge\n");
+#endif
+ /* VME initialization is in a separate file so apps which don't use
+ * VME or want a different configuration may link against a customized
+ * routine.
+ */
+ BSP_vme_config();
+
+#ifdef SHOW_MORE_INIT_SETTINGS
+ ShowBATS();
+ printk("Exit from bspstart\n");
+#endif
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds b/c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds
new file mode 100644
index 0000000000..f1f6db5726
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds
@@ -0,0 +1,191 @@
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+
+/*
+ * Number of Decrementer countdowns per millisecond
+ *
+ * Calculated by: (66.67 Mhz * 1000) / 4 cycles per click
+ */
+
+SECTIONS
+{
+ .vectors 0x00100 :
+ {
+ *(.vectors)
+ }
+
+ /* Read-only sections, merged into text segment: */
+ /* SDS ROM worked at 0x30000 */
+ . = 0x30000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rela.text : { *(.rela.text) }
+ .rela.data : { *(.rela.data) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rela.init : { *(.rela.init) }
+ .rela.fini : { *(.rela.fini) }
+ .rela.bss : { *(.rela.bss) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.sdata : { *(.rela.sdata2) }
+ .rela.sbss : { *(.rela.sbss2) }
+ .rela.sdata2 : { *(.rela.sdata2) }
+ .rela.sbss2 : { *(.rela.sbss2) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ _start = .;
+ *(.text)
+ /*
+ * Special FreeBSD sysctl sections.
+ */
+ . = ALIGN (16);
+ __start_set_sysctl_set = .;
+ *(set_sysctl_*);
+ __stop_set_sysctl_set = ABSOLUTE(.);
+ *(set_domain_*);
+ *(set_pseudo_*);
+
+ *(.gnu.linkonce.t.*)
+ *(.descriptors)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ .init : { _init = .; *(.init) }
+ .fini : { _fini = .; *(.fini) }
+ .rodata : { *(.rodata*) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ .eh_frame : { *.(eh_frame) }
+ _etext = .;
+ PROVIDE (etext = .);
+ PROVIDE (__SDATA2_START__ = .);
+ .sdata2 : { *(.sdata2) *(.gnu.linkonce.s2.*) }
+ .sbss2 : { *(.sbss2) *(.gnu.linkonce.sb2.*) }
+ PROVIDE (__SBSS2_START__ = .);
+ .sbss2 : { *(.sbss2) }
+ PROVIDE (__SBSS2_END__ = .);
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = ALIGN(8) + 0x40000;
+ PROVIDE (sdata = .);
+ .data :
+ {
+ PROVIDE(__DATA_START__ = ABSOLUTE(.) );
+ *(.data)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ }
+ PROVIDE (__EXCEPT_START__ = .);
+ .gcc_except_table : { *(.gcc_except_table) }
+ PROVIDE (__EXCEPT_END__ = .);
+
+ .data1 : { *(.data1) }
+ .got1 : { *(.got1) }
+ .dynamic : { *(.dynamic) }
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) }
+ PROVIDE (__GOT2_END__ = .);
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) }
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) }
+ PROVIDE (__DTOR_END__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) }
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (__FIXUP_END__ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+ s.got = .;
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
+ PROVIDE (__GOT_END__ = .);
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ PROVIDE (__SDATA_START__ = .);
+ .sdata : { *(.sdata) *(.gnu.linkonce.s.*) }
+ _edata = .;
+ PROVIDE (edata = .);
+ PROVIDE (RAM_END = ADDR(.text) + 10M);
+ . = ALIGN(8) + 0x1000;
+ PROVIDE (__SBSS_START__ = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ }
+ PROVIDE (__SBSS_END__ = .);
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ PROVIDE (__bss_end = .);
+ }
+ . = ALIGN(8) + 0x8000;
+ PROVIDE (__stack = .);
+ _end = . ;
+ __rtems_end = . ;
+ PROVIDE (end = .);
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c b/c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c
new file mode 100644
index 0000000000..4f0c633526
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/* Standard VME bridge configuration for VGM type boards */
+
+/* Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002 */
+
+#include <bsp.h>
+#include <bsp/VME.h>
+#include <bsp/irq.h>
+#include <libcpu/bat.h>
+#include <libcpu/spr.h>
+#include <bsp/motorola.h>
+
+/* Use a weak alias for the VME configuration.
+ * This permits individual applications to override
+ * this routine.
+ * They may even create an 'empty'
+ *
+ * void BSP_vme_config(void) {}
+ *
+ * which will avoid linking in the Universe driver
+ * at all :-).
+ */
+
+void BSP_vme_config(void) __attribute__ (( weak, alias("__BSP_default_vme_config") ));
+
+SPR_RO(DBAT0U)
+
+extern unsigned32 VME_Slot1;
+
+void
+__BSP_default_vme_config(void)
+{
+union {
+ struct _BATU bat;
+ unsigned long batbits;
+} dbat0u;
+
+ vmeUniverseInit();
+ vmeUniverseReset();
+
+ /* setup a PCI area to map the VME bus */
+
+ dbat0u.batbits = _read_DBAT0U();
+
+ /* map VME address ranges */
+ vmeUniverseMasterPortCfg(
+ 0,
+ VME_AM_EXT_SUP_DATA,
+ _VME_A32_WIN0_ON_VME,
+ _VME_A32_WIN0_ON_PCI,
+ 0x0F000000);
+ vmeUniverseMasterPortCfg(
+ 1,
+ VME_AM_STD_SUP_DATA,
+ 0x00000000,
+ _VME_A24_ON_PCI,
+ 0x00ff0000);
+ vmeUniverseMasterPortCfg(
+ 2,
+ VME_AM_SUP_SHORT_IO,
+ 0x00000000,
+ _VME_A16_ON_PCI,
+ 0x00010000);
+
+#ifdef _VME_DRAM_OFFSET
+#if 0
+ if (VME_Slot1){
+ /* map our memory to VME */
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", BSP_mem_size);
+ vmeUniverseSlavePortCfg(
+ 0,
+ VME_AM_EXT_SUP_DATA,
+ _VME_DRAM_32_OFFSET1,
+ PCI_DRAM_OFFSET,
+ BSP_mem_size);
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A24_SIZE);
+ vmeUniverseSlavePortCfg(
+ 1,
+ VME_AM_STD_SUP_DATA,
+ _VME_DRAM_24_OFFSET1,
+ PCI_DRAM_OFFSET,
+ _VME_A24_SIZE);
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A16_SIZE);
+ vmeUniverseSlavePortCfg(
+ 2,
+ VME_AM_SUP_SHORT_IO,
+ _VME_DRAM_16_OFFSET1,
+ PCI_DRAM_OFFSET,
+ _VME_A16_SIZE);
+ }
+ else {
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", BSP_mem_size);
+ vmeUniverseSlavePortCfg(
+ 0,
+ VME_AM_EXT_SUP_DATA,
+ _VME_DRAM_32_OFFSET2,
+ PCI_DRAM_OFFSET,
+ BSP_mem_size);
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A24_SIZE);
+ vmeUniverseSlavePortCfg(
+ 1,
+ VME_AM_STD_SUP_DATA,
+ _VME_DRAM_24_OFFSET2,
+ PCI_DRAM_OFFSET,
+ _VME_A24_SIZE);
+printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A16_SIZE);
+ vmeUniverseSlavePortCfg(
+ 2,
+ VME_AM_SUP_SHORT_IO,
+ _VME_DRAM_16_OFFSET2,
+ PCI_DRAM_OFFSET,
+ _VME_A16_SIZE);
+ }
+#endif
+
+ /* make sure the host bridge PCI master is enabled */
+ vmeUniverseWriteReg(
+ vmeUniverseReadReg(UNIV_REGOFF_PCI_CSR) | UNIV_PCI_CSR_BM,
+ UNIV_REGOFF_PCI_CSR);
+#endif
+
+
+ /* stdio is not yet initialized; the driver will revert to printk */
+ vmeUniverseMasterPortsShow(0);
+ vmeUniverseSlavePortsShow(0);
+
+ /* install the VME insterrupt manager */
+ vmeUniverseInstallIrqMgr(0,5,1,6);
+ if (vmeUniverse0PciIrqLine<0)
+ BSP_panic("Unable to get interrupt line info from PCI config");
+ _BSP_vme_bridge_irq=BSP_PCI_IRQ_LOWEST_OFFSET+vmeUniverse0PciIrqLine;
+}