From 0329aae1b2cd18215ac8d19cbb1a69f502eddd71 Mon Sep 17 00:00:00 2001 From: Jennifer Averett Date: Thu, 28 Apr 2005 14:05:14 +0000 Subject: 2005-04-28 Jennifer Averett * 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. --- c/src/lib/libbsp/powerpc/ChangeLog | 13 + c/src/lib/libbsp/powerpc/ep1a/Makefile.am | 242 +++++ c/src/lib/libbsp/powerpc/ep1a/bsp_specs | 22 + c/src/lib/libbsp/powerpc/ep1a/configure.ac | 30 + c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c | 104 +++ c/src/lib/libbsp/powerpc/ep1a/console/console.c | 350 ++++++++ c/src/lib/libbsp/powerpc/ep1a/console/console.h | 38 + c/src/lib/libbsp/powerpc/ep1a/console/init68360.c | 670 ++++++++++++++ c/src/lib/libbsp/powerpc/ep1a/console/m68360.h | 973 +++++++++++++++++++++ .../lib/libbsp/powerpc/ep1a/console/mc68360_scc.c | 836 ++++++++++++++++++ c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c | 47 + c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h | 57 ++ c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c | 558 ++++++++++++ c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h | 148 ++++ c/src/lib/libbsp/powerpc/ep1a/include/bsp.h | 209 +++++ c/src/lib/libbsp/powerpc/ep1a/include/tm27.h | 60 ++ c/src/lib/libbsp/powerpc/ep1a/irq/irq.c | 570 ++++++++++++ c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c | 332 +++++++ c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c | 31 + c/src/lib/libbsp/powerpc/ep1a/start/start.S | 151 ++++ c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c | 523 +++++++++++ c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds | 191 ++++ c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c | 142 +++ 23 files changed, 6297 insertions(+) create mode 100644 c/src/lib/libbsp/powerpc/ep1a/Makefile.am create mode 100644 c/src/lib/libbsp/powerpc/ep1a/bsp_specs create mode 100644 c/src/lib/libbsp/powerpc/ep1a/configure.ac create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/console.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/console.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/init68360.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/m68360.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/include/bsp.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/include/tm27.h create mode 100644 c/src/lib/libbsp/powerpc/ep1a/irq/irq.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/start/start.S create mode 100644 c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds create mode 100644 c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c (limited to 'c/src') 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 + + * 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 * 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 +#include +#include "m68360.h" +#include +#include "rsPMCQ1.h" +#include + +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 +#include +#include +#include +#include + +#include "console.h" +#include + +/* + * 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; + minordeviceProbe(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++;minordeviceProbe(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 +#include +#include + +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 +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include "m68360.h" +#include +#include +#include +#include + +#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; ipSCCR->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;iport[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 +#include +#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 +#include +#include +#include +#include +#include +#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 +#include + +/* + * 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 + +#include +#include +#include +#include +#include + + +/* + * 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 + +/* 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 + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* 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 + * to make it valid for MVME2300 Motorola boards. + * + * Till Straumann , 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +#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 +#include + +#include +#include +#include +#include +#include + +#include + +/* + * 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 +#include +*/ + +#include +#include +#include +#include + +#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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 ) */ + *((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 ) */ + 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 , 3/2002 */ + +#include +#include +#include +#include +#include +#include + +/* 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; +} -- cgit v1.2.3