forked from Imagelibrary/rtems
2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
* acinclude.m4: Initial release of ep1a bsp * ep1a/Makefile.am, ep1a/bsp_specs, ep1a/configure.ac, ep1a/console/alloc360.c, ep1a/console/console.c, ep1a/console/console.h, ep1a/console/init68360.c, ep1a/console/m68360.h, ep1a/console/mc68360_scc.c, ep1a/console/ns16550cfg.c, ep1a/console/ns16550cfg.h, ep1a/console/rsPMCQ1.c, ep1a/console/rsPMCQ1.h, ep1a/include/bsp.h, ep1a/irq/irq.c, ep1a/irq/irq_init.c, ep1a/pci/no_host_bridge.c, ep1a/start/start.S, ep1a/startup/bspstart.c, ep1a/startup/linkcmds, ep1a/vme/vmeconfig.c: New files.
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
2005-04-28 Jennifer Averett <jennifer.averett@oarcorp.com>
|
||||
|
||||
* acinclude.m4: Initial release of ep1a bsp
|
||||
* ep1a/Makefile.am, ep1a/bsp_specs, ep1a/configure.ac,
|
||||
ep1a/console/alloc360.c, ep1a/console/console.c,
|
||||
ep1a/console/console.h, ep1a/console/init68360.c,
|
||||
ep1a/console/m68360.h, ep1a/console/mc68360_scc.c,
|
||||
ep1a/console/ns16550cfg.c, ep1a/console/ns16550cfg.h,
|
||||
ep1a/console/rsPMCQ1.c, ep1a/console/rsPMCQ1.h, ep1a/include/bsp.h,
|
||||
ep1a/irq/irq.c, ep1a/irq/irq_init.c, ep1a/pci/no_host_bridge.c,
|
||||
ep1a/start/start.S, ep1a/startup/bspstart.c, ep1a/startup/linkcmds,
|
||||
ep1a/vme/vmeconfig.c: New files.
|
||||
|
||||
2004-12-30 Ralf Corsepius <ralf.corsepius@rtems.org>
|
||||
|
||||
* acinclude.m4: Reflect eth_comm having been removed.
|
||||
|
||||
242
c/src/lib/libbsp/powerpc/ep1a/Makefile.am
Normal file
242
c/src/lib/libbsp/powerpc/ep1a/Makefile.am
Normal file
@@ -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
|
||||
22
c/src/lib/libbsp/powerpc/ep1a/bsp_specs
Normal file
22
c/src/lib/libbsp/powerpc/ep1a/bsp_specs
Normal file
@@ -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}
|
||||
30
c/src/lib/libbsp/powerpc/ep1a/configure.ac
Normal file
30
c/src/lib/libbsp/powerpc/ep1a/configure.ac
Normal file
@@ -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
|
||||
104
c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
Normal file
104
c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* MC68360 buffer descriptor allocation routines
|
||||
*
|
||||
* W. Eric Norum
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include "m68360.h"
|
||||
#include <rtems/error.h>
|
||||
#include "rsPMCQ1.h"
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
void M360SetupMemory( M68360_t ptr ){
|
||||
volatile m360_t *m360;
|
||||
|
||||
m360 = ptr->m360;
|
||||
|
||||
ptr->bdregions[0].base = (char *)&m360->dpram1[0];
|
||||
ptr->bdregions[0].size = sizeof m360->dpram1;
|
||||
ptr->bdregions[0].used = 0;
|
||||
|
||||
ptr->bdregions[1].base = (char *)&m360->dpram3[0];
|
||||
ptr->bdregions[1].size = sizeof m360->dpram3;
|
||||
ptr->bdregions[1].used = 0;
|
||||
|
||||
ptr->bdregions[2].base = (char *)&m360->dpram0[0];
|
||||
ptr->bdregions[2].size = sizeof m360->dpram0;
|
||||
ptr->bdregions[2].used = 0;
|
||||
|
||||
ptr->bdregions[3].base = (char *)&m360->dpram2[0];
|
||||
ptr->bdregions[3].size = sizeof m360->dpram2;
|
||||
ptr->bdregions[3].used = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send a command to the CPM RISC processer
|
||||
*/
|
||||
void *
|
||||
M360AllocateBufferDescriptors (M68360_t ptr, int count)
|
||||
{
|
||||
unsigned int i;
|
||||
ISR_Level level;
|
||||
void *bdp = NULL;
|
||||
unsigned int want = count * sizeof(m360BufferDescriptor_t);
|
||||
int have;
|
||||
|
||||
/*
|
||||
* Running with interrupts disabled is usually considered bad
|
||||
* form, but this routine is probably being run as part of an
|
||||
* initialization sequence so the effect shouldn't be too severe.
|
||||
*/
|
||||
_ISR_Disable (level);
|
||||
|
||||
for (i = 0 ; i < M360_NUM_DPRAM_REAGONS ; i++) {
|
||||
|
||||
/*
|
||||
* Verify that the region exists.
|
||||
* This test is necessary since some chips have
|
||||
* less dual-port RAM.
|
||||
*/
|
||||
if (ptr->bdregions[i].used == 0) {
|
||||
volatile unsigned char *cp = ptr->bdregions[i].base;
|
||||
*cp = 0xAA;
|
||||
if (*cp != 0xAA) {
|
||||
ptr->bdregions[i].used = ptr->bdregions[i].size;
|
||||
continue;
|
||||
}
|
||||
*cp = 0x55;
|
||||
if (*cp != 0x55) {
|
||||
ptr->bdregions[i].used = ptr->bdregions[i].size;
|
||||
continue;
|
||||
}
|
||||
*cp = 0x0;
|
||||
}
|
||||
|
||||
have = ptr->bdregions[i].size - ptr->bdregions[i].used;
|
||||
if (have >= want) {
|
||||
bdp = ptr->bdregions[i].base + ptr->bdregions[i].used;
|
||||
ptr->bdregions[i].used += want;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ISR_Enable (level);
|
||||
if (bdp == NULL){
|
||||
printk("rtems_panic can't allocate %d buffer descriptor(s).\n");
|
||||
rtems_panic ("Can't allocate %d buffer descriptor(s).\n", count);
|
||||
}
|
||||
return bdp;
|
||||
}
|
||||
350
c/src/lib/libbsp/powerpc/ep1a/console/console.c
Normal file
350
c/src/lib/libbsp/powerpc/ep1a/console/console.c
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* This file contains the TTY driver for the ep1a
|
||||
*
|
||||
* This driver uses the termios pseudo driver.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "console.h"
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
/*
|
||||
* Load configuration table
|
||||
*/
|
||||
#include "config.c"
|
||||
|
||||
#define NUM_CONSOLE_PORTS (sizeof(Console_Port_Tbl)/sizeof(console_tbl))
|
||||
|
||||
console_data Console_Port_Data[NUM_CONSOLE_PORTS];
|
||||
unsigned long Console_Port_Count;
|
||||
rtems_device_minor_number Console_Port_Minor;
|
||||
|
||||
/* PAGE
|
||||
*
|
||||
* console_open
|
||||
*
|
||||
* open a port as a termios console.
|
||||
*
|
||||
*/
|
||||
rtems_device_driver console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
rtems_libio_ioctl_args_t IoctlArgs;
|
||||
struct termios Termios;
|
||||
rtems_termios_callbacks Callbacks;
|
||||
console_fns *c;
|
||||
|
||||
/*
|
||||
* Verify the port number is valid.
|
||||
*/
|
||||
if(minor>Console_Port_Count)
|
||||
{
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
/*
|
||||
* open the port as a termios console driver.
|
||||
*/
|
||||
c = Console_Port_Tbl[minor].pDeviceFns;
|
||||
Callbacks.firstOpen = c->deviceFirstOpen;
|
||||
Callbacks.lastClose = c->deviceLastClose;
|
||||
Callbacks.pollRead = c->deviceRead;
|
||||
Callbacks.write = c->deviceWrite;
|
||||
Callbacks.setAttributes = c->deviceSetAttributes;
|
||||
Callbacks.stopRemoteTx =
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx;
|
||||
Callbacks.startRemoteTx =
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx;
|
||||
Callbacks.outputUsesInterrupts = c->deviceOutputUsesInterrupts;
|
||||
status = rtems_termios_open ( major, minor, arg, &Callbacks);
|
||||
Console_Port_Data[minor].termios_data = args->iop->data1;
|
||||
|
||||
if(minor!=Console_Port_Minor)
|
||||
{
|
||||
/*
|
||||
* If this is not the console we do not want ECHO and
|
||||
* so forth
|
||||
*/
|
||||
IoctlArgs.iop=args->iop;
|
||||
IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
|
||||
IoctlArgs.buffer=&Termios;
|
||||
rtems_termios_ioctl(&IoctlArgs);
|
||||
Termios.c_lflag=ICANON;
|
||||
IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
|
||||
rtems_termios_ioctl(&IoctlArgs);
|
||||
}
|
||||
|
||||
if((args->iop->flags&LIBIO_FLAGS_READ) &&
|
||||
Console_Port_Tbl[minor].pDeviceFlow &&
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx)
|
||||
{
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
|
||||
if((args->iop->flags&LIBIO_FLAGS_READ) &&
|
||||
Console_Port_Tbl[minor].pDeviceFlow &&
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx)
|
||||
{
|
||||
Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
|
||||
}
|
||||
|
||||
return rtems_termios_close (arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_write (arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
|
||||
/* PAGE
|
||||
*
|
||||
* console_initialize
|
||||
*
|
||||
* Routine called to initialize the console device driver.
|
||||
*/
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
/*
|
||||
* initialize the termio interface.
|
||||
*/
|
||||
rtems_termios_initialize();
|
||||
|
||||
Console_Port_Count=NUM_CONSOLE_PORTS;
|
||||
|
||||
for(minor=0;
|
||||
minor<Console_Port_Count;
|
||||
minor++)
|
||||
{
|
||||
/*
|
||||
* First perform the configuration dependant probe, then the
|
||||
* device dependant probe
|
||||
*/
|
||||
if((!Console_Port_Tbl[minor].deviceProbe ||
|
||||
Console_Port_Tbl[minor].deviceProbe(minor)) &&
|
||||
Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
|
||||
{
|
||||
/*
|
||||
* Use this device for the console
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(minor==Console_Port_Count)
|
||||
{
|
||||
/*
|
||||
* Failed to find a working device
|
||||
*/
|
||||
rtems_fatal_error_occurred(RTEMS_IO_ERROR);
|
||||
}
|
||||
|
||||
Console_Port_Minor=minor;
|
||||
|
||||
/*
|
||||
* Register Device Names
|
||||
*/
|
||||
|
||||
status = rtems_io_register_name("/dev/console",
|
||||
major,
|
||||
Console_Port_Minor );
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_fatal_error_occurred(status);
|
||||
}
|
||||
if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
|
||||
Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(
|
||||
Console_Port_Minor);
|
||||
|
||||
for(minor++;minor<Console_Port_Count;minor++)
|
||||
{
|
||||
/*
|
||||
* First perform the configuration dependant probe, then the
|
||||
* device dependant probe
|
||||
*/
|
||||
if((!Console_Port_Tbl[minor].deviceProbe ||
|
||||
Console_Port_Tbl[minor].deviceProbe(minor)) &&
|
||||
Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor))
|
||||
{
|
||||
status = rtems_io_register_name(
|
||||
Console_Port_Tbl[minor].sDeviceName,
|
||||
major,
|
||||
minor );
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_fatal_error_occurred(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the hardware device.
|
||||
*/
|
||||
if ( Console_Port_Tbl[minor].pDeviceFns->deviceInitialize )
|
||||
Console_Port_Tbl[minor].pDeviceFns->deviceInitialize( minor);
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/* PAGE
|
||||
*
|
||||
* DEBUG_puts
|
||||
*
|
||||
* This should be safe in the event of an error. It attempts to ensure
|
||||
* that no TX empty interrupts occur while it is doing polled IO. Then
|
||||
* it restores the state of that external interrupt.
|
||||
*
|
||||
* Input parameters:
|
||||
* string - pointer to debug output string
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values: NONE
|
||||
*/
|
||||
|
||||
void DEBUG_puts(
|
||||
char *string
|
||||
)
|
||||
{
|
||||
char *s;
|
||||
unsigned32 Irql;
|
||||
|
||||
rtems_interrupt_disable(Irql);
|
||||
|
||||
for ( s = string ; *s ; s++ )
|
||||
{
|
||||
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
|
||||
deviceWritePolled(Console_Port_Minor, *s);
|
||||
}
|
||||
|
||||
rtems_interrupt_enable(Irql);
|
||||
}
|
||||
|
||||
/* PAGE
|
||||
*
|
||||
* DEBUG_puth
|
||||
*
|
||||
* This should be safe in the event of an error. It attempts to ensure
|
||||
* that no TX empty interrupts occur while it is doing polled IO. Then
|
||||
* it restores the state of that external interrupt.
|
||||
*
|
||||
* Input parameters:
|
||||
* ulHexNum - value to display
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values: NONE
|
||||
*/
|
||||
void
|
||||
DEBUG_puth(
|
||||
unsigned32 ulHexNum
|
||||
)
|
||||
{
|
||||
unsigned long i,d;
|
||||
unsigned32 Irql;
|
||||
|
||||
rtems_interrupt_disable(Irql);
|
||||
|
||||
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
|
||||
deviceWritePolled(Console_Port_Minor, '0');
|
||||
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
|
||||
deviceWritePolled(Console_Port_Minor, 'x');
|
||||
|
||||
for(i=32;i;)
|
||||
{
|
||||
i-=4;
|
||||
d=(ulHexNum>>i)&0xf;
|
||||
Console_Port_Tbl[Console_Port_Minor].pDeviceFns->
|
||||
deviceWritePolled(Console_Port_Minor,
|
||||
(d<=9) ? d+'0' : d+'a'-0xa);
|
||||
}
|
||||
|
||||
rtems_interrupt_enable(Irql);
|
||||
}
|
||||
|
||||
|
||||
/* const char arg to be compatible with BSP_output_char decl. */
|
||||
void
|
||||
debug_putc_onlcr(const char c)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
/*
|
||||
* Note: Hack to get printk to work. Depends upon bit
|
||||
* and silverchip to initialize the port and just
|
||||
* forces a character to be polled out of com1
|
||||
* regardless of where the console is.
|
||||
*/
|
||||
|
||||
volatile unsigned char *ptr = (void *)0xff800000;
|
||||
|
||||
if ('\n'==c){
|
||||
*ptr = '\r';
|
||||
asm volatile("sync");
|
||||
for (i=0;i<0x0fff;i++);
|
||||
}
|
||||
|
||||
*ptr = c;
|
||||
asm volatile("sync");
|
||||
for (i=0;i<0x0fff;i++);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = debug_putc_onlcr;
|
||||
/* const char arg to be compatible with BSP_output_char decl. */
|
||||
|
||||
38
c/src/lib/libbsp/powerpc/ep1a/console/console.h
Normal file
38
c/src/lib/libbsp/powerpc/ep1a/console/console.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file contains the TTY driver table definition for the PPCn_60x
|
||||
*
|
||||
* This driver uses the termios pseudo driver.
|
||||
*
|
||||
* COPYRIGHT (c) 1998 by Radstone Technology
|
||||
*
|
||||
*
|
||||
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
|
||||
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
|
||||
*
|
||||
* You are hereby granted permission to use, copy, modify, and distribute
|
||||
* this file, provided that this notice, plus the above copyright notice
|
||||
* and disclaimer, appears in all copies. Radstone Technology will provide
|
||||
* no support for this code.
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/ringbuf.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
extern console_tbl Console_Port_Tbl[];
|
||||
extern console_data Console_Port_Data[];
|
||||
extern unsigned long Console_Port_Count;
|
||||
|
||||
boolean Console_Port_Tbl_Init_ppc8245(int minor);
|
||||
670
c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
Normal file
670
c/src/lib/libbsp/powerpc/ep1a/console/init68360.c
Normal file
@@ -0,0 +1,670 @@
|
||||
/*
|
||||
* MC68360 support routines
|
||||
*
|
||||
* W. Eric Norum
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include "m68360.h"
|
||||
|
||||
/*
|
||||
* Send a command to the CPM RISC processer
|
||||
*/
|
||||
|
||||
void M360ExecuteRISC( volatile m360_t *m360, rtems_unsigned16 command)
|
||||
{
|
||||
rtems_unsigned16 sr;
|
||||
|
||||
rtems_interrupt_disable(sr);
|
||||
while (m360->cr & M360_CR_FLG)
|
||||
continue;
|
||||
m360->cr = command | M360_CR_FLG;
|
||||
rtems_interrupt_enable(sr);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Initialize MC68360
|
||||
*/
|
||||
void _Init68360 (void)
|
||||
{
|
||||
int i;
|
||||
m68k_isr_entry *vbr;
|
||||
unsigned long ramSize;
|
||||
extern void _CopyDataClearBSSAndStart (unsigned long ramSize);
|
||||
|
||||
#if (defined (__mc68040__))
|
||||
/*
|
||||
*******************************************
|
||||
* Motorola 68040 and companion-mode 68360 *
|
||||
*******************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x83; /* No more writes, full-power CLKO2 */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT standard M68000 family interrupt level encoding
|
||||
* CF1MODE=10 (BCLRO* output)
|
||||
* No RAS1* double drive
|
||||
* A31 - A28
|
||||
* AMUX output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
*/
|
||||
m360.pepar = 0x3440;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
*/
|
||||
/*
|
||||
* 512 addresses per DRAM page (256K DRAM chips)
|
||||
* 70 nsec DRAM
|
||||
* 180 nsec ROM (3 wait states)
|
||||
*/
|
||||
m360.gmr = M360_GMR_RCNT(23) | M360_GMR_RFEN |
|
||||
M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_NCS |
|
||||
M360_GMR_TSS40;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
*/
|
||||
/*
|
||||
* Set up option/base registers
|
||||
* 1M DRAM
|
||||
* 70 nsec DRAM
|
||||
* Enable burst mode
|
||||
* No parity checking
|
||||
* Wait for chips to power up
|
||||
* Perform 8 read cycles
|
||||
*/
|
||||
ramSize = 1 * 1024 * 1024;
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
|
||||
M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&_RamBase |
|
||||
M360_MEMC_BR_BACK40 |
|
||||
M360_MEMC_BR_V;
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i)
|
||||
*((volatile unsigned long *)(unsigned long)&_RamBase);
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Bus request MC68040 Arbitration ID 3
|
||||
* Bus asynchronous timing mode (work around bug in Rev. B)
|
||||
* Arbitration asynchronous timing mode
|
||||
* Disable timers during FREEZE
|
||||
* Disable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear in arbitration ID level 3
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x6000EC3F;
|
||||
|
||||
#elif (defined (M68360_ATLAS_HSB))
|
||||
/*
|
||||
******************************************
|
||||
* Standalone Motorola 68360 -- ATLAS HSB *
|
||||
******************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a CPU32+ reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* RAS1* double drive
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0180;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
*/
|
||||
m360.gmr = M360_GMR_RCNT(12) | M360_GMR_RFEN |
|
||||
M360_GMR_RCYC(0) | M360_GMR_PGS(1) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_DWQ |
|
||||
M360_GMR_GAMX;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
*/
|
||||
ramSize = 2 * 1024 * 1024;
|
||||
/* first bank 1MByte DRAM */
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
|
||||
|
||||
/* second bank 1MByte DRAM */
|
||||
m360.memc[2].or = M360_MEMC_OR_TCYC(2) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_PGME | M360_MEMC_OR_DRAM;
|
||||
m360.memc[2].br = ((unsigned long)&_RamBase + 0x100000) |
|
||||
M360_MEMC_BR_V;
|
||||
|
||||
/* flash rom socket U6 on CS5 */
|
||||
m360.memc[5].br = (unsigned long)ATLASHSB_ROM_U6 | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[5].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/* CSRs on CS7 */
|
||||
m360.memc[7].or = M360_MEMC_OR_TCYC(4) | M360_MEMC_OR_64KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
m360.memc[7].br = ATLASHSB_ESR | 0x01;
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i)
|
||||
*((volatile unsigned long *)(unsigned long)&_RamBase);
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
*/
|
||||
|
||||
#elif (defined (GEN68360_WITH_SRAM))
|
||||
/*
|
||||
***************************************************
|
||||
* Generic Standalone Motorola 68360 *
|
||||
* As described in MC68360 User's Manual *
|
||||
* But uses SRAM instead of DRAM *
|
||||
* CS0* - 512kx8 flash memory *
|
||||
* CS1* - 512kx32 static RAM *
|
||||
* CS2* - 512kx32 static RAM *
|
||||
***************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external oscillator which
|
||||
* oscillates at the system clock rate.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* IPIPE1*
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0080;
|
||||
|
||||
/*
|
||||
* Step 11: Set up GMR
|
||||
*
|
||||
*/
|
||||
m360.gmr = 0x0;
|
||||
|
||||
/*
|
||||
* Step 11a: Remap 512Kx8 flash memory on CS0*
|
||||
* 2 wait states
|
||||
* Make it read-only for now
|
||||
*/
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(2) | M360_MEMC_OR_512KB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
/*
|
||||
* Step 12: Set up main memory
|
||||
* 512Kx32 SRAM on CS1*
|
||||
* 512Kx32 SRAM on CS2*
|
||||
* 0 wait states
|
||||
*/
|
||||
ramSize = 4 * 1024 * 1024;
|
||||
m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
|
||||
m360.memc[1].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
m360.memc[2].br = ((unsigned long)&_RamBase + 0x200000) | M360_MEMC_BR_V;
|
||||
m360.memc[2].or = M360_MEMC_OR_WAITS(0) | M360_MEMC_OR_2MB |
|
||||
M360_MEMC_OR_32BIT;
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear interrupt service level 7
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x4C7F;
|
||||
|
||||
#else
|
||||
/*
|
||||
***************************************************
|
||||
* Generic Standalone Motorola 68360 *
|
||||
* As described in MC68360 User's Manual *
|
||||
* Atlas ACE360 *
|
||||
***************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 6: Is this a power-up reset?
|
||||
* For now we just ignore this and do *all* the steps
|
||||
* Someday we might want to:
|
||||
* if (Hard, Loss of Clock, Power-up)
|
||||
* Do all steps
|
||||
* else if (Double bus fault, watchdog or soft reset)
|
||||
* Skip to step 12
|
||||
* else (must be a CPU32+ reset command)
|
||||
* Skip to step 14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 7: Deal with clock synthesizer
|
||||
* HARDWARE:
|
||||
* Change if you're not using an external 25 MHz oscillator.
|
||||
*/
|
||||
m360.clkocr = 0x8F; /* No more writes, no clock outputs */
|
||||
m360.pllcr = 0xD000; /* PLL, no writes, no prescale,
|
||||
no LPSTOP slowdown, PLL X1 */
|
||||
m360.cdvcr = 0x8000; /* No more writes, no clock division */
|
||||
|
||||
/*
|
||||
* Step 8: Initialize system protection
|
||||
* Enable watchdog
|
||||
* Watchdog causes system reset
|
||||
* Next-to-slowest watchdog timeout (21 seconds with 25 MHz oscillator)
|
||||
* Enable double bus fault monitor
|
||||
* Enable bus monitor for external cycles
|
||||
* 1024 clocks for external timeout
|
||||
*/
|
||||
m360.sypcr = 0xEC;
|
||||
|
||||
/*
|
||||
* Step 9: Clear parameter RAM and reset communication processor module
|
||||
*/
|
||||
for (i = 0 ; i < 192 ; i += sizeof (long)) {
|
||||
*((long *)((char *)&m360 + 0xC00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xD00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xE00 + i)) = 0;
|
||||
*((long *)((char *)&m360 + 0xF00 + i)) = 0;
|
||||
}
|
||||
M360ExecuteRISC (M360_CR_RST);
|
||||
|
||||
/*
|
||||
* Step 10: Write PEPAR
|
||||
* SINTOUT not used (CPU32+ mode)
|
||||
* CF1MODE=00 (CONFIG1 input)
|
||||
* RAS1* double drive
|
||||
* WE0* - WE3*
|
||||
* OE* output
|
||||
* CAS2* - CAS3*
|
||||
* CAS0* - CAS1*
|
||||
* CS7*
|
||||
* AVEC*
|
||||
* HARDWARE:
|
||||
* Change if you are using a different memory configuration
|
||||
* (static RAM, external address multiplexing, etc).
|
||||
*/
|
||||
m360.pepar = 0x0180;
|
||||
|
||||
/*
|
||||
* Step 11: Remap Chip Select 0 (CS0*), set up GMR
|
||||
* 32-bit DRAM
|
||||
* Internal DRAM address multiplexing
|
||||
* 60 nsec DRAM
|
||||
* 180 nsec ROM (3 wait states)
|
||||
* 15.36 usec DRAM refresh interval
|
||||
* The DRAM page size selection is not modified since this
|
||||
* startup code may be running in a bootstrap PROM or in
|
||||
* a program downloaded by the bootstrap PROM.
|
||||
*/
|
||||
m360.gmr = (m360.gmr & 0x001C0000) | M360_GMR_RCNT(23) |
|
||||
M360_GMR_RFEN | M360_GMR_RCYC(0) |
|
||||
M360_GMR_DPS_32BIT | M360_GMR_NCS |
|
||||
M360_GMR_GAMX;
|
||||
m360.memc[0].br = (unsigned long)&_RomBase | M360_MEMC_BR_WP |
|
||||
M360_MEMC_BR_V;
|
||||
m360.memc[0].or = M360_MEMC_OR_WAITS(3) | M360_MEMC_OR_1MB |
|
||||
M360_MEMC_OR_8BIT;
|
||||
|
||||
/*
|
||||
* Step 12: Initialize the system RAM
|
||||
* Do this only if the DRAM has not already been set up
|
||||
*/
|
||||
if ((m360.memc[1].br & M360_MEMC_BR_V) == 0) {
|
||||
/*
|
||||
* Set up GMR DRAM page size, option and base registers
|
||||
* Assume 16Mbytes of DRAM
|
||||
* 60 nsec DRAM
|
||||
*/
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(5);
|
||||
m360.memc[1].or = M360_MEMC_OR_TCYC(0) |
|
||||
M360_MEMC_OR_16MB |
|
||||
M360_MEMC_OR_DRAM;
|
||||
m360.memc[1].br = (unsigned long)&_RamBase | M360_MEMC_BR_V;
|
||||
|
||||
/*
|
||||
* Wait for chips to power up
|
||||
* Perform 8 read cycles
|
||||
*/
|
||||
for (i = 0; i < 50000; i++)
|
||||
continue;
|
||||
for (i = 0; i < 8; ++i)
|
||||
*((volatile unsigned long *)(unsigned long)&_RamBase);
|
||||
|
||||
/*
|
||||
* Determine memory size (1, 4, or 16 Mbytes)
|
||||
* Set GMR DRAM page size appropriately.
|
||||
* The OR is left at 16 Mbytes. The bootstrap PROM places its
|
||||
* .data and .bss segments at the top of the 16 Mbyte space.
|
||||
* A 1 Mbyte or 4 Mbyte DRAM will show up several times in
|
||||
* the memory map, but will work with the same bootstrap PROM.
|
||||
*/
|
||||
*(volatile char *)&_RamBase = 0;
|
||||
*((volatile char *)&_RamBase+0x00C01800) = 1;
|
||||
if (*(volatile char *)&_RamBase) {
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(1);
|
||||
}
|
||||
else {
|
||||
*((volatile char *)&_RamBase+0x00801000) = 1;
|
||||
if (*(volatile char *)&_RamBase) {
|
||||
m360.gmr = (m360.gmr & ~0x001C0000) | M360_GMR_PGS(3);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable parity checking
|
||||
*/
|
||||
m360.memc[1].br |= M360_MEMC_BR_PAREN;
|
||||
}
|
||||
switch (m360.gmr & 0x001C0000) {
|
||||
default: ramSize = 4 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(1): ramSize = 1 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(3): ramSize = 4 * 1024 * 1024; break;
|
||||
case M360_GMR_PGS(5): ramSize = 16 * 1024 * 1024; break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 13: Copy the exception vector table to system RAM
|
||||
*/
|
||||
m68k_get_vbr (vbr);
|
||||
for (i = 0; i < 256; ++i)
|
||||
M68Kvec[i] = vbr[i];
|
||||
m68k_set_vbr (M68Kvec);
|
||||
|
||||
/*
|
||||
* Step 14: More system initialization
|
||||
* SDCR (Serial DMA configuration register)
|
||||
* Enable SDMA during FREEZE
|
||||
* Give SDMA priority over all interrupt handlers
|
||||
* Set DMA arbiration level to 4
|
||||
* CICR (CPM interrupt configuration register):
|
||||
* SCC1 requests at SCCa position
|
||||
* SCC2 requests at SCCb position
|
||||
* SCC3 requests at SCCc position
|
||||
* SCC4 requests at SCCd position
|
||||
* Interrupt request level 4
|
||||
* Maintain original priority order
|
||||
* Vector base 128
|
||||
* SCCs priority grouped at top of table
|
||||
*/
|
||||
m360.sdcr = M360_SDMA_SISM_7 | M360_SDMA_SAID_4;
|
||||
m360.cicr = (3 << 22) | (2 << 20) | (1 << 18) | (0 << 16) |
|
||||
(4 << 13) | (0x1F << 8) | (128);
|
||||
|
||||
/*
|
||||
* Step 15: Set module configuration register
|
||||
* Disable timers during FREEZE
|
||||
* Enable bus monitor during FREEZE
|
||||
* BCLRO* arbitration level 3
|
||||
* No show cycles
|
||||
* User/supervisor access
|
||||
* Bus clear interrupt service level 7
|
||||
* SIM60 interrupt sources higher priority than CPM
|
||||
*/
|
||||
m360.mcr = 0x4C7F;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy data, clear BSS, switch stacks and call main()
|
||||
* Must pass ramSize as argument since the data/bss segment
|
||||
* may be overwritten.
|
||||
*/
|
||||
_CopyDataClearBSSAndStart (ramSize);
|
||||
}
|
||||
#endif
|
||||
973
c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
Normal file
973
c/src/lib/libbsp/powerpc/ep1a/console/m68360.h
Normal file
@@ -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 */
|
||||
836
c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
Normal file
836
c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c
Normal file
@@ -0,0 +1,836 @@
|
||||
/* This file contains the termios TTY driver for the Motorola MC68360 SCC ports.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <bsp.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <libchip/serial.h>
|
||||
#include "m68360.h"
|
||||
#include <libchip/sersupp.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MC68360_LENGHT_SIZE 100
|
||||
int mc68360_length_array[ MC68360_LENGHT_SIZE ];
|
||||
int mc68360_length_count=0;
|
||||
|
||||
void mc68360_Show_length_array() {
|
||||
int i;
|
||||
for (i=0; i<MC68360_LENGHT_SIZE; i++)
|
||||
printf(" %d", mc68360_length_array[i] );
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
M68360_t M68360_chips = NULL;
|
||||
|
||||
#define SYNC eieio
|
||||
|
||||
void mc68360_scc_nullFunc() {}
|
||||
|
||||
uint8_t scc_read8(
|
||||
const char *name,
|
||||
volatile uint8_t *address
|
||||
)
|
||||
{
|
||||
uint8_t value;
|
||||
|
||||
#ifdef DEBUG_360
|
||||
printk( "RD8 %s 0x%08x ", name, address );
|
||||
#endif
|
||||
value = *address;
|
||||
#ifdef DEBUG_360
|
||||
printk( "0x%02x\n", value );
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void scc_write8(
|
||||
const char *name,
|
||||
volatile uint8_t *address,
|
||||
uint8_t value
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk( "WR8 %s 0x%08x 0x%02x\n", name, address, value );
|
||||
#endif
|
||||
*address = value;
|
||||
}
|
||||
|
||||
|
||||
uint16_t scc_read16(
|
||||
const char *name,
|
||||
volatile uint16_t *address
|
||||
)
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
#ifdef DEBUG_360
|
||||
printk( "RD16 %s 0x%08x ", name, address );
|
||||
#endif
|
||||
value = *address;
|
||||
#ifdef DEBUG_360
|
||||
printk( "0x%04x\n", value );
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void scc_write16(
|
||||
const char *name,
|
||||
volatile uint16_t *address,
|
||||
uint16_t value
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk( "WR16 %s 0x%08x 0x%04x\n", name, address, value );
|
||||
#endif
|
||||
*address = value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t scc_read32(
|
||||
const char *name,
|
||||
volatile uint32_t *address
|
||||
)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
#ifdef DEBUG_360
|
||||
printk( "RD32 %s 0x%08x ", name, address );
|
||||
#endif
|
||||
value = *address;
|
||||
#ifdef DEBUG_360
|
||||
printk( "0x%08x\n", value );
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void scc_write32(
|
||||
const char *name,
|
||||
volatile uint32_t *address,
|
||||
uint32_t value
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk( "WR32 %s 0x%08x 0x%08x\n", name, address, value );
|
||||
#endif
|
||||
*address = value;
|
||||
}
|
||||
|
||||
void mc68360_sccShow_Regs(int minor){
|
||||
M68360_serial_ports_t ptr;
|
||||
ptr = Console_Port_Tbl[minor].pDeviceParams;
|
||||
|
||||
printk( "scce 0x%08x", &ptr->pSCCR->scce );
|
||||
printk( " 0x%04x\n", ptr->pSCCR->scce );
|
||||
|
||||
}
|
||||
|
||||
#define TX_BUFFER_ADDRESS( _ptr ) \
|
||||
((char *)ptr->txBuf - (char *)ptr->chip->board_data->baseaddr)
|
||||
#define RX_BUFFER_ADDRESS( _ptr ) \
|
||||
((char *)ptr->rxBuf - (char *)ptr->chip->board_data->baseaddr)
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Function: mc68360_sccBRGC *
|
||||
**************************************************************************
|
||||
* Description: *
|
||||
* *
|
||||
* This function is called to compute the divisor register values for *
|
||||
* a given baud rate. *
|
||||
* *
|
||||
* *
|
||||
* Inputs: *
|
||||
* *
|
||||
* int baud - Baud rate (in bps). *
|
||||
* *
|
||||
* Output: *
|
||||
* *
|
||||
* int - baud rate generator configuration. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
static int
|
||||
mc68360_sccBRGC(int baud, int m360_clock_rate)
|
||||
{
|
||||
int data;
|
||||
|
||||
/*
|
||||
* configure baud rate generator for 16x bit rate, where.....
|
||||
* b = desired baud rate
|
||||
* clk = system clock (33mhz)
|
||||
* d = clock dividor value
|
||||
*
|
||||
* for b > 300 : d = clk/(b*16)
|
||||
* for b<= 300 : d = (clk/ (b*16*16))-1)
|
||||
*/
|
||||
|
||||
SYNC();
|
||||
if( baud > 300 ) data = 33333333 / (baud * 16 );
|
||||
else data = (33333333 / (baud * 16 * 16) ) - 1;
|
||||
data *= 2;
|
||||
data &= 0x00001ffe ;
|
||||
|
||||
/* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
|
||||
data |= ((baud>300)? 0 : 1 ) ;
|
||||
data |= 0x010000 ;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Function: sccInterruptHandler *
|
||||
**************************************************************************
|
||||
* Description: *
|
||||
* *
|
||||
* This is the interrupt service routine for the console UART. It *
|
||||
* handles both receive and transmit interrupts. The bulk of the *
|
||||
* work is done by termios. *
|
||||
* *
|
||||
* Inputs: *
|
||||
* *
|
||||
* chip - structure of chip specific information *
|
||||
* *
|
||||
* Output: *
|
||||
* *
|
||||
* none *
|
||||
* *
|
||||
**************************************************************************/
|
||||
void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle )
|
||||
{
|
||||
volatile m360_t *m360;
|
||||
int port;
|
||||
uint16_t status;
|
||||
uint16_t length;
|
||||
int i;
|
||||
char data;
|
||||
int clear_isr;
|
||||
M68360_t chip = (M68360_t)handle;
|
||||
|
||||
for (port=0; port<4; port++) {
|
||||
|
||||
clear_isr = FALSE;
|
||||
m360 = chip->m360;
|
||||
|
||||
/*
|
||||
* Handle a RX interrupt.
|
||||
*/
|
||||
if ( scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x1)
|
||||
{
|
||||
clear_isr = TRUE;
|
||||
scc_write16("scce", &chip->port[port].pSCCR->scce, 0x1 );
|
||||
status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
|
||||
while ((status & M360_BD_EMPTY) == 0)
|
||||
{
|
||||
length= scc_read16("sccRxBd->length",&chip->port[port].sccRxBd->length);
|
||||
for (i=0;i<length;i++) {
|
||||
data= chip->port[port].rxBuf[i];
|
||||
rtems_termios_enqueue_raw_characters(
|
||||
Console_Port_Data[ chip->port[port].minor ].termios_data,
|
||||
&data,
|
||||
1);
|
||||
}
|
||||
scc_write16( "sccRxBd->status", &chip->port[port].sccRxBd->status,
|
||||
M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
|
||||
status =scc_read16( "sccRxBd->status", &chip->port[port].sccRxBd->status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a TX interrupt.
|
||||
*/
|
||||
if (scc_read16("scce", &chip->port[port].pSCCR->scce) & 0x2)
|
||||
{
|
||||
clear_isr = TRUE;
|
||||
scc_write16("scce", &chip->port[port].pSCCR->scce, 0x2);
|
||||
status = scc_read16("sccTxBd->status", &chip->port[port].sccTxBd->status);
|
||||
if ((status & M360_BD_EMPTY) == 0)
|
||||
{
|
||||
scc_write16("sccTxBd->status",&chip->port[port].sccTxBd->status,0);
|
||||
rtems_termios_dequeue_characters(
|
||||
Console_Port_Data[chip->port[port].minor].termios_data,
|
||||
chip->port[port].sccTxBd->length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear SCC interrupt-in-service bit.
|
||||
*/
|
||||
if ( clear_isr )
|
||||
scc_write32( "cisr", &m360->cisr, (0x80000000 >> chip->port[port].channel) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_open
|
||||
*
|
||||
* This function opens a port for communication.
|
||||
*
|
||||
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
|
||||
*/
|
||||
|
||||
int mc68360_scc_open(
|
||||
int major,
|
||||
int minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_initialize_interrupts
|
||||
*
|
||||
* This routine initializes the console's receive and transmit
|
||||
* ring buffers and loads the appropriate vectors to handle the interrupts.
|
||||
*/
|
||||
|
||||
void mc68360_scc_initialize_interrupts(int minor)
|
||||
{
|
||||
M68360_serial_ports_t ptr;
|
||||
volatile m360_t *m360;
|
||||
uint32_t data;
|
||||
uint32_t buffers_start;
|
||||
uint32_t tmp_u32;
|
||||
|
||||
#ifdef DEBUG_360
|
||||
printk("mc68360_scc_initialize_interrupts: minor %d\n", minor );
|
||||
printk("Console_Port_Tbl[minor].pDeviceParams 0x%08x\n",
|
||||
Console_Port_Tbl[minor].pDeviceParams );
|
||||
#endif
|
||||
|
||||
ptr = Console_Port_Tbl[minor].pDeviceParams;
|
||||
m360 = ptr->chip->m360;
|
||||
#ifdef DEBUG_360
|
||||
printk("m360 0x%08x baseaddr 0x%08x\n",
|
||||
m360, ptr->chip->board_data->baseaddr);
|
||||
#endif
|
||||
|
||||
buffers_start = ptr->chip->board_data->baseaddr + 0x00200000 +
|
||||
( (M68360_RX_BUF_SIZE + M68360_TX_BUF_SIZE) * (ptr->channel-1));
|
||||
ptr->rxBuf = (uint8_t *) buffers_start;
|
||||
ptr->txBuf = (uint8_t *)(buffers_start + M68360_RX_BUF_SIZE);
|
||||
#ifdef DEBUG_360
|
||||
printk("rxBuf 0x%08x txBuf 0x%08x\n", ptr->rxBuf, ptr->txBuf );
|
||||
#endif
|
||||
/*
|
||||
* Set Channel Drive Enable bits in EPLD
|
||||
*/
|
||||
data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
|
||||
SYNC();
|
||||
data |= (PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 |
|
||||
PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0);
|
||||
PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE, data);
|
||||
data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* Disable the receiver and the transmitter.
|
||||
*/
|
||||
|
||||
SYNC();
|
||||
tmp_u32 = scc_read32( "gsmr_l", &ptr->pSCCR->gsmr_l );
|
||||
tmp_u32 &= (~(M360_GSMR_ENR | M360_GSMR_ENT ) ) ;
|
||||
scc_write32( "gsmr_l", &ptr->pSCCR->gsmr_l, tmp_u32 );
|
||||
|
||||
/*
|
||||
* Disable Interrupt Error and Interrupt Breakpoint
|
||||
* Set SAID to 4 XXX - Shouldn't it be 7 for slave mode
|
||||
* Set SAISM to 7
|
||||
*/
|
||||
SYNC();
|
||||
scc_write16( "sdcr", &m360->sdcr, 0x0740 );
|
||||
|
||||
/*
|
||||
* Clear status -- reserved interrupt, SDMA channel error, SDMA breakpoint
|
||||
*/
|
||||
scc_write8( "sdsr", &m360->sdsr, 0x07 );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* Initialize timer information in RISC Controller Configuration Register
|
||||
*/
|
||||
scc_write16( "rccr", &m360->rccr, 0x8100 );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
scc_write16( "papar", &m360->papar, 0xffff );
|
||||
scc_write16( "padir", &m360->padir, 0x5500 ); /* From Memo */
|
||||
scc_write16( "paodr", &m360->paodr, 0x0000 );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
scc_write32( "pbpar", &m360->pbpar, 0x00000000 );
|
||||
scc_write32( "pbdir", &m360->pbdir, 0x0003ffff );
|
||||
scc_write32( "pbdat", &m360->pbdat, 0x0000003f );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
scc_write16( "pcpar", &m360->pcpar, 0x0000 );
|
||||
scc_write16( "pcdir", &m360->pcdir, 0x0000 );
|
||||
scc_write16( "pcso", &m360->pcso, 0x0000 );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* configure baud rate generator for 16x bit rate, where.....
|
||||
* b = desired baud rate
|
||||
* clk = system clock (33mhz)
|
||||
* d = clock dividor value
|
||||
*
|
||||
* for b > 300 : d = clk/(b*16)
|
||||
* for b<= 300 : d = (clk/ (b*16*16))-1)
|
||||
*/
|
||||
SYNC();
|
||||
if( ptr->baud > 300 ) data = 33333333 / (ptr->baud * 16 );
|
||||
else data = (33333333 / (ptr->baud * 16 * 16) ) - 1;
|
||||
data *= 2 ;
|
||||
data &= 0x00001ffe ;
|
||||
|
||||
/* really data = 0x010000 | data | ((baud>300)? 0 : 1 ) ; */
|
||||
data |= ((ptr->baud>300)? 0 : 1 ) ;
|
||||
data |= 0x010000 ;
|
||||
|
||||
scc_write32( "pBRGC", ptr->pBRGC, data );
|
||||
|
||||
data = (((ptr->channel-1)*8) | (ptr->channel-1)) ;
|
||||
data = data << ((ptr->channel-1)*8) ;
|
||||
data |= scc_read32( "sicr", &m360->sicr );
|
||||
scc_write32( "sicr", &m360->sicr, data );
|
||||
|
||||
/*
|
||||
* initialise SCC parameter ram
|
||||
*/
|
||||
SYNC();
|
||||
scc_write16( "pSCCB->rbase", &ptr->pSCCB->rbase,
|
||||
(char *)(ptr->sccRxBd) - (char *)m360 );
|
||||
scc_write16( "pSCCB->tbase", &ptr->pSCCB->tbase,
|
||||
(char *)(ptr->sccTxBd) - (char *)m360 );
|
||||
|
||||
scc_write8( "pSCCB->rfcr", &ptr->pSCCB->rfcr, 0x15 ); /* 0x15 0x18 */
|
||||
scc_write8( "pSCCB->tfcr", &ptr->pSCCB->tfcr, 0x15 ); /* 0x15 0x18 */
|
||||
|
||||
scc_write16( "pSCCB->mrblr", &ptr->pSCCB->mrblr, M68360_RX_BUF_SIZE );
|
||||
|
||||
/*
|
||||
* initialise tx and rx scc parameters
|
||||
*/
|
||||
SYNC();
|
||||
data = M360_CR_INIT_TX_RX_PARAMS | 0x01;
|
||||
data |= (M360_CR_CH_NUM * (ptr->channel-1) );
|
||||
scc_write16( "CR", &m360->cr, data );
|
||||
|
||||
/*
|
||||
* initialise uart specific parameter RAM
|
||||
*/
|
||||
SYNC();
|
||||
scc_write16( "pSCCB->un.uart.max_idl", &ptr->pSCCB->un.uart.max_idl, 15000 );
|
||||
scc_write16( "pSCCB->un.uart.brkcr", &ptr->pSCCB->un.uart.brkcr, 0x0001 );
|
||||
scc_write16( "pSCCB->un.uart.parec", &ptr->pSCCB->un.uart.parec, 0x0000 );
|
||||
|
||||
scc_write16( "pSCCB->un,uart.frmec", &ptr->pSCCB->un.uart.frmec, 0x0000 );
|
||||
|
||||
scc_write16( "pSCCB->un.uart.nosec", &ptr->pSCCB->un.uart.nosec, 0x0000 );
|
||||
scc_write16( "pSCCB->un.uart.brkec", &ptr->pSCCB->un.uart.brkec, 0x0000 );
|
||||
scc_write16( "pSCCB->un.uart.uaddr0", &ptr->pSCCB->un.uart.uaddr[0], 0x0000 );
|
||||
scc_write16( "pSCCB->un.uart.uaddr1", &ptr->pSCCB->un.uart.uaddr[1], 0x0000 );
|
||||
scc_write16( "pSCCB->un.uart.toseq", &ptr->pSCCB->un.uart.toseq, 0x0000 );
|
||||
scc_write16( "pSCCB->un.uart.char0",
|
||||
&ptr->pSCCB->un.uart.character[0], 0x0039 );
|
||||
scc_write16( "pSCCB->un.uart.char1",
|
||||
&ptr->pSCCB->un.uart.character[1], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char2",
|
||||
&ptr->pSCCB->un.uart.character[2], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char3",
|
||||
&ptr->pSCCB->un.uart.character[3], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char4",
|
||||
&ptr->pSCCB->un.uart.character[4], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char5",
|
||||
&ptr->pSCCB->un.uart.character[5], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char6",
|
||||
&ptr->pSCCB->un.uart.character[6], 0x8000 );
|
||||
scc_write16( "pSCCB->un.uart.char7",
|
||||
&ptr->pSCCB->un.uart.character[7], 0x8000 );
|
||||
|
||||
scc_write16( "pSCCB->un.uart.rccm", &ptr->pSCCB->un.uart.rccm, 0xc0ff );
|
||||
|
||||
/*
|
||||
* setup buffer descriptor stuff
|
||||
*/
|
||||
SYNC();
|
||||
scc_write16( "sccRxBd->status", &ptr->sccRxBd->status, 0x0000 );
|
||||
SYNC();
|
||||
scc_write16( "sccRxBd->length", &ptr->sccRxBd->length, 0x0000 );
|
||||
scc_write16( "sccRxBd->status", &ptr->sccRxBd->status,
|
||||
M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT );
|
||||
/* XXX Radstone Example writes RX buffer ptr as two u16's */
|
||||
scc_write32( "sccRxBd->buffer", &ptr->sccRxBd->buffer,
|
||||
RX_BUFFER_ADDRESS( ptr ) );
|
||||
|
||||
SYNC();
|
||||
scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0x0000 );
|
||||
SYNC();
|
||||
scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, 0x0000 );
|
||||
/* XXX Radstone Example writes TX buffer ptr as two u16's */
|
||||
scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
|
||||
TX_BUFFER_ADDRESS( ptr ) );
|
||||
|
||||
/*
|
||||
* clear previous events and set interrupt priorities
|
||||
*/
|
||||
scc_write16( "pSCCR->scce", &ptr->pSCCR->scce, 0x1bef ); /* From memo */
|
||||
SYNC();
|
||||
SYNC();
|
||||
scc_write32( "cicr", &m360->cicr, 0x001b9f40 );
|
||||
SYNC();
|
||||
|
||||
/* scc_write32( "cicr", &m360->cicr, scc_read32( "cicr", &m360->cicr ) ); */
|
||||
|
||||
scc_write16( "pSCCR->sccm", &ptr->pSCCR->sccm, M360_SCCE_TX | M360_SCCE_RX );
|
||||
|
||||
data = scc_read32("cimr", &m360->cimr);
|
||||
data |= (0x80000000 >> ptr->channel);
|
||||
scc_write32( "cimr", &m360->cimr, data );
|
||||
SYNC();
|
||||
scc_write32( "cipr", &m360->cipr, scc_read32( "cipr", &m360->cipr ) );
|
||||
|
||||
scc_write32( "pSCCR->gsmr_h", &ptr->pSCCR->gsmr_h, M360_GSMR_RFW );
|
||||
scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
|
||||
(M360_GSMR_TDCR_16X | M360_GSMR_RDCR_16X | M360_GSMR_MODE_UART) );
|
||||
|
||||
scc_write16( "pSCCR->dsr", &ptr->pSCCR->dsr, 0x7e7e );
|
||||
SYNC();
|
||||
|
||||
scc_write16( "pSCCR->psmr", &ptr->pSCCR->psmr,
|
||||
(M360_PSMR_CL8 | M360_PSMR_UM_NORMAL | M360_PSMR_TPM_ODD) );
|
||||
SYNC();
|
||||
|
||||
/*
|
||||
* Enable the receiver and the transmitter.
|
||||
*/
|
||||
|
||||
SYNC();
|
||||
data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l);
|
||||
scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l,
|
||||
(data | M360_GSMR_ENR | M360_GSMR_ENT) );
|
||||
|
||||
data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK );
|
||||
data &= (~PMCQ1_INT_MASK_QUICC);
|
||||
PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK, data );
|
||||
|
||||
data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS );
|
||||
data &= (~PMCQ1_INT_STATUS_QUICC);
|
||||
PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data );
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_write_support_int
|
||||
*
|
||||
* Console Termios output entry point when using interrupt driven output.
|
||||
*/
|
||||
|
||||
int mc68360_scc_write_support_int(
|
||||
int minor,
|
||||
const char *buf,
|
||||
int len
|
||||
)
|
||||
{
|
||||
rtems_interrupt_level Irql;
|
||||
M68360_serial_ports_t ptr;
|
||||
|
||||
mc68360_length_array[ mc68360_length_count ] = len;
|
||||
mc68360_length_count++;
|
||||
if ( mc68360_length_count >= MC68360_LENGHT_SIZE )
|
||||
mc68360_length_count=0;
|
||||
|
||||
ptr = Console_Port_Tbl[minor].pDeviceParams;
|
||||
|
||||
/*
|
||||
* We are using interrupt driven output and termios only sends us
|
||||
* one character at a time.
|
||||
*/
|
||||
|
||||
if ( !len )
|
||||
return 0;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
#ifdef DEBUG_360
|
||||
printk("mc68360_scc_write_support_int: char 0x%x length %d\n",
|
||||
(unsigned int)*buf, len );
|
||||
#endif
|
||||
/*
|
||||
* We must copy the data from the global memory space to MC68360 space
|
||||
*/
|
||||
|
||||
rtems_interrupt_disable(Irql);
|
||||
|
||||
scc_write16( "sccTxBd->status", &ptr->sccTxBd->status, 0 );
|
||||
memcpy((void *) ptr->txBuf, buf, len);
|
||||
scc_write32( "sccTxBd->buffer", &ptr->sccTxBd->buffer,
|
||||
TX_BUFFER_ADDRESS(ptr->txBuf) );
|
||||
scc_write16( "sccTxBd->length", &ptr->sccTxBd->length, len );
|
||||
scc_write16( "sccTxBd->status", &ptr->sccTxBd->status,
|
||||
(M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT) );
|
||||
|
||||
rtems_interrupt_enable(Irql);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_write_polled
|
||||
*
|
||||
* This routine polls out the requested character.
|
||||
*/
|
||||
|
||||
void mc68360_scc_write_polled(
|
||||
int minor,
|
||||
char cChar
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk("mc68360_scc_write_polled: %c\n", cChar);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68681_set_attributes
|
||||
*
|
||||
* This function sets the DUART channel to reflect the requested termios
|
||||
* port settings.
|
||||
*/
|
||||
|
||||
int mc68360_scc_set_attributes(
|
||||
int minor,
|
||||
const struct termios *t
|
||||
)
|
||||
{
|
||||
int baud;
|
||||
volatile m360_t *m360;
|
||||
M68360_serial_ports_t ptr;
|
||||
|
||||
ptr = Console_Port_Tbl[minor].pDeviceParams;
|
||||
m360 = ptr->chip->m360;
|
||||
|
||||
switch (t->c_cflag & CBAUD)
|
||||
{
|
||||
case B50: baud = 50; break;
|
||||
case B75: baud = 75; break;
|
||||
case B110: baud = 110; break;
|
||||
case B134: baud = 134; break;
|
||||
case B150: baud = 150; break;
|
||||
case B200: baud = 200; break;
|
||||
case B300: baud = 300; break;
|
||||
case B600: baud = 600; break;
|
||||
case B1200: baud = 1200; break;
|
||||
case B1800: baud = 1800; break;
|
||||
case B2400: baud = 2400; break;
|
||||
case B4800: baud = 4800; break;
|
||||
case B9600: baud = 9600; break;
|
||||
case B19200: baud = 19200; break;
|
||||
case B38400: baud = 38400; break;
|
||||
case B57600: baud = 57600; break;
|
||||
case B115200: baud = 115200; break;
|
||||
case B230400: baud = 230400; break;
|
||||
case B460800: baud = 460800; break;
|
||||
default: baud = -1; break;
|
||||
}
|
||||
|
||||
if (baud > 0)
|
||||
{
|
||||
scc_write32(
|
||||
"pBRGC",
|
||||
ptr->pBRGC,
|
||||
mc68360_sccBRGC(baud, ptr->chip->m360_clock_rate)
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_close
|
||||
*
|
||||
* This function shuts down the requested port.
|
||||
*/
|
||||
|
||||
int mc68360_scc_close(
|
||||
int major,
|
||||
int minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return(RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_inbyte_nonblocking_polled
|
||||
*
|
||||
* Console Termios polling input entry point.
|
||||
*/
|
||||
|
||||
int mc68360_scc_inbyte_nonblocking_polled(
|
||||
int minor
|
||||
)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_write_support_polled
|
||||
*
|
||||
* Console Termios output entry point when using polled output.
|
||||
*
|
||||
*/
|
||||
|
||||
int mc68360_scc_write_support_polled(
|
||||
int minor,
|
||||
const char *buf,
|
||||
int len
|
||||
)
|
||||
{
|
||||
printk("mc68360_scc_write_support_polled: minor %d char %c len %d\n",
|
||||
minor, buf, len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mc68360_scc_init
|
||||
*
|
||||
* This function initializes the DUART to a quiecsent state.
|
||||
*/
|
||||
|
||||
void mc68360_scc_init(int minor)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk("mc68360_scc_init\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector )
|
||||
{
|
||||
M68360_t chip;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG_360
|
||||
printk("mc68360_scc_create_chip\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create console structure for this card
|
||||
* XXX - Note Does this need to be moved up to if a QUICC is fitted
|
||||
* section?
|
||||
*/
|
||||
if ((chip = malloc(sizeof(struct _m68360_per_chip))) == NULL)
|
||||
{
|
||||
printk("Error Unable to allocate memory for _m68360_per_chip\n");
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
chip->next = M68360_chips;
|
||||
chip->m360 = (void *)BoardData->baseaddr;
|
||||
chip->m360_interrupt = int_vector;
|
||||
chip->m360_clock_rate = 25000000;
|
||||
chip->board_data = BoardData;
|
||||
M68360_chips = chip;
|
||||
|
||||
for (i=1; i<=4; i++) {
|
||||
chip->port[i-1].channel = i;
|
||||
chip->port[i-1].chip = chip;
|
||||
chip->port[i-1].baud = 9600;
|
||||
|
||||
switch( i ) {
|
||||
case 1:
|
||||
chip->port[i-1].pBRGC = &chip->m360->brgc1;
|
||||
chip->port[i-1].pSCCB = (m360SCCparms_t *) &chip->m360->scc1p;
|
||||
chip->port[i-1].pSCCR = &chip->m360->scc1;
|
||||
M360SetupMemory( chip ); /* Do this first time through */
|
||||
break;
|
||||
case 2:
|
||||
chip->port[i-1].pBRGC = &chip->m360->brgc2;
|
||||
chip->port[i-1].pSCCB = &chip->m360->scc2p;
|
||||
chip->port[i-1].pSCCR = &chip->m360->scc2;
|
||||
break;
|
||||
case 3:
|
||||
chip->port[i-1].pBRGC = &chip->m360->brgc3;
|
||||
chip->port[i-1].pSCCB = &chip->m360->scc3p;
|
||||
chip->port[i-1].pSCCR = &chip->m360->scc3;
|
||||
break;
|
||||
case 4:
|
||||
chip->port[i-1].pBRGC = &chip->m360->brgc4;
|
||||
chip->port[i-1].pSCCB = &chip->m360->scc4p;
|
||||
chip->port[i-1].pSCCR = &chip->m360->scc4;
|
||||
break;
|
||||
default:
|
||||
printk("Invalid mc68360 channel %d\n", i);
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate buffer descriptors.
|
||||
*/
|
||||
|
||||
chip->port[i-1].sccRxBd = M360AllocateBufferDescriptors(chip, 1);
|
||||
chip->port[i-1].sccTxBd = M360AllocateBufferDescriptors(chip, 1);
|
||||
}
|
||||
|
||||
rsPMCQ1QuiccIntConnect(
|
||||
chip->board_data->busNo,
|
||||
chip->board_data->slotNo,
|
||||
chip->board_data->funcNo,
|
||||
&mc68360_sccInterruptHandler,
|
||||
chip
|
||||
);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
console_fns mc68360_scc_fns = {
|
||||
libchip_serial_default_probe, /* deviceProbe */
|
||||
mc68360_scc_open, /* deviceFirstOpen */
|
||||
NULL, /* deviceLastClose */
|
||||
NULL, /* deviceRead */
|
||||
mc68360_scc_write_support_int, /* deviceWrite */
|
||||
mc68360_scc_initialize_interrupts, /* deviceInitialize */
|
||||
mc68360_scc_write_polled, /* deviceWritePolled */
|
||||
mc68360_scc_set_attributes, /* deviceSetAttributes */
|
||||
TRUE /* deviceOutputUsesInterrupts */
|
||||
};
|
||||
|
||||
console_fns mc68360_scc_polled = {
|
||||
libchip_serial_default_probe, /* deviceProbe */
|
||||
mc68360_scc_open, /* deviceFirstOpen */
|
||||
mc68360_scc_close, /* deviceLastClose */
|
||||
mc68360_scc_inbyte_nonblocking_polled, /* deviceRead */
|
||||
mc68360_scc_write_support_polled, /* deviceWrite */
|
||||
mc68360_scc_init, /* deviceInitialize */
|
||||
mc68360_scc_write_polled, /* deviceWritePolled */
|
||||
mc68360_scc_set_attributes, /* deviceSetAttributes */
|
||||
FALSE /* deviceOutputUsesInterrupts */
|
||||
};
|
||||
|
||||
47
c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
Normal file
47
c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This include file contains all console driver definations for the nc16550
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include "console.h"
|
||||
|
||||
typedef struct uart_reg
|
||||
{
|
||||
unsigned char reg;
|
||||
unsigned char pad[7];
|
||||
} uartReg;
|
||||
|
||||
unsigned8 Read_ns16550_register(
|
||||
unsigned32 ulCtrlPort,
|
||||
unsigned8 ucRegNum
|
||||
)
|
||||
{
|
||||
struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
|
||||
unsigned8 ucData;
|
||||
ucData = p[ucRegNum].reg;
|
||||
asm volatile("sync");
|
||||
return ucData;
|
||||
}
|
||||
|
||||
void Write_ns16550_register(
|
||||
unsigned32 ulCtrlPort,
|
||||
unsigned8 ucRegNum,
|
||||
unsigned8 ucData
|
||||
)
|
||||
{
|
||||
struct uart_reg *p = (struct uart_reg *)ulCtrlPort;
|
||||
volatile int i;
|
||||
p[ucRegNum].reg = ucData;
|
||||
asm volatile("sync");
|
||||
for (i=0;i<0x08ff;i++);
|
||||
}
|
||||
57
c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
Normal file
57
c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.h
Normal file
@@ -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
|
||||
558
c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
Normal file
558
c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c
Normal file
@@ -0,0 +1,558 @@
|
||||
/* rsPMCQ1.c - Radstone PMCQ1 Common Initialisation Code
|
||||
*
|
||||
* Copyright 2000 Radstone Technology
|
||||
*
|
||||
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
|
||||
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
|
||||
*
|
||||
* You are hereby granted permission to use, copy, modify, and distribute
|
||||
* this file, provided that this notice, plus the above copyright notice
|
||||
* and disclaimer, appears in all copies. Radstone Technology will provide
|
||||
* no support for this code.
|
||||
*
|
||||
* COPYRIGHT (c) 2005.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
These functions are responsible for scanning for PMCQ1's and setting up
|
||||
the Motorola MC68360's if present.
|
||||
|
||||
USAGE
|
||||
call rsPMCQ1Init() to perform ba sic initialisation of the PMCQ1's.
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
#include <libcpu/io.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp.h>
|
||||
#include "rsPMCQ1.h"
|
||||
#include "m68360.h"
|
||||
|
||||
/* defines */
|
||||
#if 0
|
||||
#define DEBUG_360
|
||||
#endif
|
||||
|
||||
/* Local data */
|
||||
PPMCQ1BoardData pmcq1BoardData = NULL;
|
||||
|
||||
static unsigned char rsPMCQ1Initialized = FALSE;
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
/* local Qspan II serial eeprom table */
|
||||
static unsigned char rsPMCQ1eeprom[] =
|
||||
{
|
||||
0x00, /* Byte 0 - PCI_SID */
|
||||
0x00, /* Byte 1 - PCI_SID */
|
||||
0x00, /* Byte 2 - PCI_SID */
|
||||
0x00, /* Byte 3 - PCI_SID */
|
||||
0x00, /* Byte 4 - PBROM_CTL */
|
||||
0x00, /* Byte 5 - PBROM_CTL */
|
||||
0x00, /* Byte 6 - PBROM_CTL */
|
||||
0x2C, /* Byte 7 - PBTI0_CTL */
|
||||
0xB0, /* Byte 8 - PBTI1_CTL */
|
||||
0x00, /* Byte 9 - QBSI0_AT */
|
||||
0x00, /* Byte 10 - QBSI0_AT */
|
||||
0x02, /* Byte 11 - QBSI0_AT */
|
||||
0x00, /* Byte 12 - PCI_ID */
|
||||
0x07, /* Byte 13 - PCI_ID */
|
||||
0x11, /* Byte 14 - PCI_ID */
|
||||
0xB5, /* Byte 15 - PCI_ID */
|
||||
0x06, /* Byte 16 - PCI_CLASS */
|
||||
0x80, /* Byte 17 - PCI_CLASS */
|
||||
0x00, /* Byte 18 - PCI_CLASS */
|
||||
0x00, /* Byte 19 - PCI_MISC1 */
|
||||
0x00, /* Byte 20 - PCI_MISC1 */
|
||||
0xC0, /* Byte 21 - PCI_PMC */
|
||||
0x00 /* Byte 22 - PCI_BST */
|
||||
};
|
||||
|
||||
void MsDelay()
|
||||
{
|
||||
printk(".");
|
||||
}
|
||||
|
||||
void write8( int addr, int data ){
|
||||
out_8((void *)addr, (unsigned char)data);
|
||||
}
|
||||
|
||||
void write16( int addr, int data ) {
|
||||
out_be16((void *)addr, (short)data );
|
||||
}
|
||||
|
||||
void write32( int addr, int data ) {
|
||||
out_be32((unsigned int *)addr, data );
|
||||
}
|
||||
|
||||
int read32( int addr){
|
||||
return in_be32((unsigned int *)addr);
|
||||
}
|
||||
|
||||
|
||||
void rsPMCQ1_scc_nullFunc() {}
|
||||
|
||||
/*******************************************************************************
|
||||
* rsPMCQ1Int - handle a PMCQ1 interrupt
|
||||
*
|
||||
* This routine gets called when the QUICC or MA causes
|
||||
* an interrupt.
|
||||
*
|
||||
* RETURNS: NONE.
|
||||
*/
|
||||
|
||||
void rsPMCQ1Int( void *ptr )
|
||||
{
|
||||
unsigned long status;
|
||||
unsigned long status1;
|
||||
unsigned long mask;
|
||||
PPMCQ1BoardData boardData = ptr;
|
||||
|
||||
status = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS );
|
||||
mask = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_MASK );
|
||||
|
||||
if (((mask & PMCQ1_INT_MASK_QUICC) == 0) && (status & PMCQ1_INT_STATUS_QUICC))
|
||||
{
|
||||
/* If there is a handler call it otherwise mask the interrupt */
|
||||
if (boardData->quiccInt) {
|
||||
boardData->quiccInt(boardData->quiccArg);
|
||||
} else {
|
||||
*(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
|
||||
}
|
||||
}
|
||||
|
||||
if (((mask & PMCQ1_INT_MASK_MA) == 0) && (status & PMCQ1_INT_STATUS_MA))
|
||||
{
|
||||
/* If there is a handler call it otherwise mask the interrupt */
|
||||
if (boardData->maInt) {
|
||||
boardData->maInt(boardData->maArg);
|
||||
} else {
|
||||
*(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear Interrupt on QSPAN */
|
||||
*(unsigned long *)(boardData->bridgeaddr + 0x600) = 0x00001000;
|
||||
|
||||
/* read back the status register to ensure that the pci write has completed */
|
||||
status1 = *(volatile unsigned long *)(boardData->bridgeaddr + 0x600);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1MaIntConnect - connect a MiniAce interrupt routine
|
||||
*
|
||||
* This routine is called to connect a MiniAce interrupt handler
|
||||
* upto a PMCQ1.
|
||||
*
|
||||
* RETURNS: OK if PMCQ1 found, ERROR if not.
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1MaIntConnect (
|
||||
unsigned long busNo, /* Pci Bus number of PMCQ1 */
|
||||
unsigned long slotNo, /* Pci Slot number of PMCQ1 */
|
||||
unsigned long funcNo, /* Pci Function number of PMCQ1 */
|
||||
rtems_irq_hdl routine,/* interrupt routine */
|
||||
rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
|
||||
)
|
||||
{
|
||||
PPMCQ1BoardData boardData;
|
||||
unsigned int status = RTEMS_IO_ERROR;
|
||||
|
||||
for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
|
||||
{
|
||||
if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
|
||||
(boardData->funcNo == funcNo))
|
||||
{
|
||||
boardData->maInt = routine;
|
||||
boardData->maArg = arg;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1MaIntDisconnect - disconnect a MiniAce interrupt routine
|
||||
*
|
||||
* This routine is called to disconnect a MiniAce interrupt handler
|
||||
* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
|
||||
*
|
||||
* RETURNS: OK if PMCQ1 found, ERROR if not.
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1MaIntDisconnect(
|
||||
unsigned long busNo, /* Pci Bus number of PMCQ1 */
|
||||
unsigned long slotNo, /* Pci Slot number of PMCQ1 */
|
||||
unsigned long funcNo /* Pci Function number of PMCQ1 */
|
||||
)
|
||||
{
|
||||
PPMCQ1BoardData boardData;
|
||||
unsigned int status = RTEMS_IO_ERROR;
|
||||
|
||||
for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext) {
|
||||
if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
|
||||
(boardData->funcNo == funcNo))
|
||||
{
|
||||
boardData->maInt = NULL;
|
||||
*(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1QuiccIntConnect - connect a Quicc interrupt routine
|
||||
*
|
||||
* This routine is called to connect a Quicc interrupt handler
|
||||
* upto a PMCQ1.
|
||||
*
|
||||
* RETURNS: OK if PMCQ1 found, ERROR if not.
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1QuiccIntConnect(
|
||||
unsigned long busNo, /* Pci Bus number of PMCQ1 */
|
||||
unsigned long slotNo, /* Pci Slot number of PMCQ1 */
|
||||
unsigned long funcNo, /* Pci Function number of PMCQ1 */
|
||||
rtems_irq_hdl routine,/* interrupt routine */
|
||||
rtems_irq_hdl_param arg /* argument to pass to interrupt routine */
|
||||
)
|
||||
{
|
||||
PPMCQ1BoardData boardData;
|
||||
unsigned int status = RTEMS_IO_ERROR;
|
||||
|
||||
for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
|
||||
{
|
||||
if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
|
||||
(boardData->funcNo == funcNo))
|
||||
{
|
||||
boardData->quiccInt = routine;
|
||||
boardData->quiccArg = arg;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1QuiccIntDisconnect - disconnect a Quicc interrupt routine
|
||||
*
|
||||
* This routine is called to disconnect a Quicc interrupt handler
|
||||
* from a PMCQ1. It also masks the interrupt source on the PMCQ1.
|
||||
*
|
||||
* RETURNS: OK if PMCQ1 found, ERROR if not.
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1QuiccIntDisconnect(
|
||||
unsigned long busNo, /* Pci Bus number of PMCQ1 */
|
||||
unsigned long slotNo, /* Pci Slot number of PMCQ1 */
|
||||
unsigned long funcNo /* Pci Function number of PMCQ1 */
|
||||
)
|
||||
{
|
||||
PPMCQ1BoardData boardData;
|
||||
unsigned int status = RTEMS_IO_ERROR;
|
||||
|
||||
for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext)
|
||||
{
|
||||
if ((boardData->busNo == busNo) && (boardData->slotNo == slotNo) &&
|
||||
(boardData->funcNo == funcNo))
|
||||
{
|
||||
boardData->quiccInt = NULL;
|
||||
*(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1Init - initialize the PMCQ1's
|
||||
*
|
||||
* This routine is called to initialize the PCI card to a quiescent state.
|
||||
*
|
||||
* RETURNS: OK if PMCQ1 found, ERROR if not.
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1Init()
|
||||
{
|
||||
int busNo;
|
||||
int slotNo;
|
||||
unsigned int baseaddr = 0;
|
||||
unsigned int bridgeaddr = 0;
|
||||
unsigned long pbti0_ctl;
|
||||
int i;
|
||||
unsigned char int_vector;
|
||||
int fun;
|
||||
int temp;
|
||||
PPMCQ1BoardData boardData;
|
||||
rtems_irq_connect_data IrqData = {0,
|
||||
rsPMCQ1Int,
|
||||
NULL,
|
||||
(rtems_irq_enable)rsPMCQ1_scc_nullFunc,
|
||||
(rtems_irq_disable)rsPMCQ1_scc_nullFunc,
|
||||
(rtems_irq_is_enabled)rsPMCQ1_scc_nullFunc,
|
||||
NULL};
|
||||
|
||||
if (rsPMCQ1Initialized)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
for (i=0;;i++){
|
||||
if ( pci_find_device(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1, i, &busNo, &slotNo, &fun) != 0 )
|
||||
break;
|
||||
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_2, &baseaddr);
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
|
||||
#ifdef DEBUG_360
|
||||
printk("PMCQ1 baseaddr 0x%08x bridgeaddr 0x%08x\n", baseaddr, bridgeaddr );
|
||||
#endif
|
||||
|
||||
/* Set function code to normal mode and enable window */
|
||||
pbti0_ctl = *(unsigned long *)(bridgeaddr + 0x100) & 0xff0fffff;
|
||||
eieio();
|
||||
*(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
|
||||
eieio();
|
||||
|
||||
/* Assert QBUS reset */
|
||||
*(unsigned long *)(bridgeaddr + 0x800) |= 0x00000080;
|
||||
eieio();
|
||||
|
||||
/*
|
||||
* Hold QBus in reset for 1ms
|
||||
*/
|
||||
MsDelay();
|
||||
|
||||
/* Take QBUS out of reset */
|
||||
*(unsigned long *)(bridgeaddr + 0x800) &= ~0x00000080;
|
||||
eieio();
|
||||
|
||||
MsDelay();
|
||||
|
||||
/* If a QUICC is fitted initialise it */
|
||||
if (PMCQ1_Read_EPLD(baseaddr, PMCQ1_BUILD_OPTION) & PMCQ1_QUICC_FITTED)
|
||||
{
|
||||
#ifdef DEBUG_360
|
||||
printk(" Found QUICC busNo %d slotNo %d\n", busNo, slotNo);
|
||||
#endif
|
||||
|
||||
/* Initialise MBAR (must use function code of 7) */
|
||||
*(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00700080;
|
||||
eieio();
|
||||
|
||||
/* place internal 8K SRAM and registers at address 0x0 */
|
||||
*(unsigned long *)(baseaddr + Q1_360_MBAR) = 0x1;
|
||||
eieio();
|
||||
|
||||
/* Set function code to normal mode */
|
||||
*(unsigned long *)(bridgeaddr + 0x100) = pbti0_ctl | 0x00500080;
|
||||
eieio();
|
||||
|
||||
/* Disable the SWT and perform basic initialisation */
|
||||
write8(baseaddr+Q1_360_SIM_SYPCR,0);
|
||||
eieio();
|
||||
|
||||
write32(baseaddr+Q1_360_SIM_MCR,0xa0001029);
|
||||
write16(baseaddr+Q1_360_SIM_PICR,0);
|
||||
write16(baseaddr+Q1_360_SIM_PITR,0);
|
||||
|
||||
write16(baseaddr+Q1_360_CPM_ICCR,0x770);
|
||||
write16(baseaddr+Q1_360_CPM_SDCR,0x770);
|
||||
write32(baseaddr+Q1_360_CPM_CICR,0x00e49f00);
|
||||
write16(baseaddr+Q1_360_SIM_PEPAR,0x2080);
|
||||
eieio();
|
||||
|
||||
/* Enable SRAM */
|
||||
write32(baseaddr+Q1_360_SIM_GMR,0x00001000); /* external master wait state */
|
||||
eieio();
|
||||
write32(baseaddr+Q1_360_SIM_OR0,0x1ff00000); /*| MEMC_OR_FC*/
|
||||
eieio();
|
||||
write32(baseaddr+Q1_360_SIM_BR0,0);
|
||||
eieio();
|
||||
write32(baseaddr+Q1_360_SIM_OR1,(0x5ff00000 | 0x00000780)); /*| MEMC_OR_FC*/
|
||||
eieio();
|
||||
write32(baseaddr+Q1_360_SIM_BR1,(0x00000040 | 0x00000001 | 0x00200280) );
|
||||
eieio();
|
||||
}
|
||||
|
||||
/*
|
||||
* If a second PCI window is present then make it opposite
|
||||
* endian to simplify 1553 integration.
|
||||
*/
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_3, &temp);
|
||||
if (temp) {
|
||||
*(unsigned long *)(bridgeaddr + 0x110) |= 0x00500880;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create descriptor structure for this card
|
||||
*/
|
||||
if ((boardData = malloc(sizeof(struct _PMCQ1BoardData))) == NULL)
|
||||
{
|
||||
printk("Error Unable to allocate memory for _PMCQ1BoardData\n");
|
||||
return(RTEMS_IO_ERROR);
|
||||
}
|
||||
|
||||
boardData->pNext = pmcq1BoardData;
|
||||
boardData->busNo = busNo;
|
||||
boardData->slotNo = slotNo;
|
||||
boardData->funcNo = 0;
|
||||
boardData->baseaddr = baseaddr;
|
||||
boardData->bridgeaddr = bridgeaddr;
|
||||
boardData->quiccInt = NULL;
|
||||
boardData->maInt = NULL;
|
||||
pmcq1BoardData = boardData;
|
||||
mc68360_scc_create_chip( boardData, int_vector );
|
||||
|
||||
/*
|
||||
* Connect PMCQ1 interrupt handler.
|
||||
*/
|
||||
pci_read_config_byte(busNo, slotNo, 0, 0x3c, &int_vector);
|
||||
#ifdef DEBUG_360
|
||||
printk("PMCQ1 int_vector %d\n", int_vector);
|
||||
#endif
|
||||
IrqData.name = (rtems_irq_symbolic_name)((unsigned int)BSP_PCI_IRQ0 + int_vector);
|
||||
IrqData.handle = boardData;
|
||||
if (!BSP_install_rtems_shared_irq_handler (&IrqData)) {
|
||||
printk("Error installing interrupt handler!\n");
|
||||
rtems_fatal_error_occurred(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable PMCQ1 Interrupts from QSPAN-II
|
||||
*/
|
||||
|
||||
*(unsigned long *)(bridgeaddr + 0x600) = 0x00001000;
|
||||
eieio();
|
||||
*(unsigned long *)(bridgeaddr + 0x604) |= 0x00001000;
|
||||
|
||||
eieio();
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
rsPMCQ1Initialized = TRUE;
|
||||
}
|
||||
return((i > 0) ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* rsPMCQ1Commission - initialize the serial EEPROM on the QSPAN
|
||||
*
|
||||
* This routine is called to initialize the EEPROM attached to the QSPAN
|
||||
* on the PMCQ1 module. It will load standard settings into any QSPAN's
|
||||
* found with apparently uninitialised EEPROM's or PMCQ1's (to allow
|
||||
* EEPROM modifications to be performed).
|
||||
*/
|
||||
|
||||
unsigned int rsPMCQ1Commission( unsigned long busNo, unsigned long slotNo )
|
||||
{
|
||||
unsigned int status = RTEMS_IO_ERROR;
|
||||
unsigned int bridgeaddr = 0;
|
||||
unsigned long val;
|
||||
int i;
|
||||
int venId1;
|
||||
int venId2;
|
||||
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId1);
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_VENDOR_ID, &venId2);
|
||||
if ((venId1 == 0x086210e3) ||
|
||||
(venId2 == PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1)))
|
||||
{
|
||||
pci_read_config_dword(busNo, slotNo, 0, PCI_BASE_ADDRESS_0, &bridgeaddr);
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
|
||||
/*
|
||||
* The On board PMCQ1 on an EP1A has a subVendor ID of 0.
|
||||
* A real PMCQ1 also has the sub vendor ID set up.
|
||||
*/
|
||||
if ((busNo == 0) && (slotNo == 1)) {
|
||||
*(unsigned long *)rsPMCQ1eeprom = 0;
|
||||
} else {
|
||||
*(unsigned long *)rsPMCQ1eeprom = PCI_ID(PCI_VEN_ID_RADSTONE, PCI_DEV_ID_PMCQ1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 23; i++) {
|
||||
/* Wait until interface not active */
|
||||
while(read32(bridgeaddr + 0x804) & 0x80000000) {
|
||||
rtems_bsp_delay(1);
|
||||
}
|
||||
|
||||
/* Write value */
|
||||
write32(bridgeaddr + 0x804, (rsPMCQ1eeprom[i] << 8) | i);
|
||||
|
||||
/* delay for > 31 usec to allow active bit to become set */
|
||||
rtems_bsp_delay(100);
|
||||
|
||||
/* Wait until interface not active */
|
||||
while(read32(bridgeaddr + 0x804) & 0x80000000) {
|
||||
rtems_bsp_delay(1);
|
||||
}
|
||||
|
||||
/* Re-read value */
|
||||
write32(bridgeaddr + 0x804, 0x40000000 | i);
|
||||
|
||||
/* delay for > 31 usec to allow active bit to become set */
|
||||
rtems_bsp_delay(100);
|
||||
|
||||
/* Wait until interface not active */
|
||||
while((val = read32(bridgeaddr + 0x804)) & 0x80000000) {
|
||||
rtems_bsp_delay(1);
|
||||
}
|
||||
|
||||
if (((val >> 8) & 0xff) != rsPMCQ1eeprom[i]) {
|
||||
printk("Error writing byte %d expected 0x%02x got 0x%02x\n",
|
||||
i, rsPMCQ1eeprom[i], (unsigned char)(val >> 8));
|
||||
status = RTEMS_IO_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg )
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
data = ( *((unsigned long *) (base + reg)) );
|
||||
#ifdef DEBUG_360
|
||||
printk("EPLD Read 0x%x: 0x%08x\n", reg + base, data );
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data )
|
||||
{
|
||||
*((unsigned long *) (base + reg)) = data;
|
||||
#ifdef DEBUG_360
|
||||
printk("EPLD Write 0x%x: 0x%08x\n", reg+base, data );
|
||||
#endif
|
||||
}
|
||||
|
||||
148
c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
Normal file
148
c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/* rsPMCQ1.h - Radstone PMCQ1 private header
|
||||
*
|
||||
* Copyright 2000 Radstone Technology
|
||||
*
|
||||
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
|
||||
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
|
||||
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
|
||||
*
|
||||
* You are hereby granted permission to use, copy, modify, and distribute
|
||||
* this file, provided that this notice, plus the above copyright notice
|
||||
* and disclaimer, appears in all copies. Radstone Technology will provide
|
||||
* no support for this code.
|
||||
*
|
||||
* COPYRIGHT (c) 2005.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,20Dec00,jpb created
|
||||
*/
|
||||
|
||||
#ifndef __INCPMCQ1H
|
||||
#define __INCPMCQ1H
|
||||
|
||||
#include <libcpu/io.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
/*
|
||||
* PMCQ1 definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* 360 definitions
|
||||
*/
|
||||
|
||||
#define Q1_360_MBAR 0x0003ff00 /* master base address register */
|
||||
|
||||
#define REG_B_OFFSET 0x1000 /* offset to the internal registers */
|
||||
|
||||
#define Q1_360_SIM_MCR (REG_B_OFFSET+0x00)
|
||||
#define Q1_360_SIM_PEPAR (REG_B_OFFSET+0x16)
|
||||
#define Q1_360_SIM_SYPCR (REG_B_OFFSET+0x22)
|
||||
#define Q1_360_SIM_PICR (REG_B_OFFSET+0x26)
|
||||
#define Q1_360_SIM_PITR (REG_B_OFFSET+0x2A)
|
||||
#define Q1_360_SIM_GMR (REG_B_OFFSET+0x40)
|
||||
#define Q1_360_SIM_BR0 (REG_B_OFFSET+0x50)
|
||||
#define Q1_360_SIM_OR0 (REG_B_OFFSET+0x54)
|
||||
#define Q1_360_SIM_BR1 (REG_B_OFFSET+0x60)
|
||||
#define Q1_360_SIM_OR1 (REG_B_OFFSET+0x64)
|
||||
|
||||
#define Q1_360_CPM_ICCR (REG_B_OFFSET+0x500)
|
||||
#define Q1_360_CPM_SDCR (REG_B_OFFSET+0x51E)
|
||||
#define Q1_360_CPM_CICR (REG_B_OFFSET+0x540)
|
||||
|
||||
/*
|
||||
* EPLD offsets
|
||||
*
|
||||
* Only top 4 data bits are used
|
||||
*/
|
||||
#define PMCQ1_CODE_VERSION 0x00040000 /* Code Version */
|
||||
|
||||
#define PMCQ1_BOARD_REVISION 0x00040004 /* Board Revision */
|
||||
|
||||
#define PMCQ1_BUILD_OPTION 0x00040008 /* Build Option */
|
||||
#define PMCQ1_ACE_FITTED 0x80000000
|
||||
#define PMCQ1_QUICC_FITTED 0x40000000
|
||||
#define PMCQ1_SRAM_SIZE 0x30000000 /* 01 - 1MB */
|
||||
#define PMCQ1_SRAM_FITTED 0x20000000
|
||||
|
||||
#define PMCQ1_INT_STATUS 0x0004000c /* Interrupt Status */
|
||||
#define PMCQ1_INT_STATUS_MA 0x20000000
|
||||
#define PMCQ1_INT_STATUS_QUICC 0x10000000
|
||||
|
||||
#define PMCQ1_INT_MASK 0x00040010 /* Interrupt Mask */
|
||||
#define PMCQ1_INT_MASK_QUICC 0x20000000
|
||||
#define PMCQ1_INT_MASK_MA 0x10000000
|
||||
|
||||
#define PMCQ1_RT_ADDRESS 0x00040014 /* RT Address Latch */
|
||||
|
||||
#define PMCQ1_DRIVER_ENABLE 0x0004001c /* Channel Drive Enable */
|
||||
#define PMCQ1_DRIVER_ENABLE_3 0x80000000
|
||||
#define PMCQ1_DRIVER_ENABLE_2 0x40000000
|
||||
#define PMCQ1_DRIVER_ENABLE_1 0x20000000
|
||||
#define PMCQ1_DRIVER_ENABLE_0 0x10000000
|
||||
|
||||
#define PMCQ1_MINIACE_REGS 0x000c0000
|
||||
#define PMCQ1_MINIACE_MEM 0x00100000
|
||||
#define PMCQ1_RAM 0x00200000
|
||||
|
||||
/*
|
||||
#define PMCQ1_Read_EPLD( _base, _reg ) ( *((unsigned long *) ((unsigned32)_base + _reg)) )
|
||||
#define PMCQ1_Write_EPLD( _base, _reg, _data ) *((unsigned long *) ((unsigned32)_base + _reg)) = _data
|
||||
*/
|
||||
uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg );
|
||||
void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data );
|
||||
|
||||
/*
|
||||
* QSPAN-II register offsets
|
||||
*/
|
||||
|
||||
#define QSPAN2_INT_STATUS 0x00000600
|
||||
|
||||
|
||||
#define PCI_ID(v, d) ((d << 16) | v)
|
||||
|
||||
|
||||
#define PCI_VEN_ID_RADSTONE 0x11b5
|
||||
#define PCI_DEV_ID_PMC1553 0x0001
|
||||
#define PCI_DEV_ID_PMCF1 0x0002
|
||||
#define PCI_DEV_ID_PMCMMA 0x0003
|
||||
#define PCI_DEV_ID_PMCQ1 0x0007
|
||||
#define PCI_DEV_ID_PMCQ2 0x0008
|
||||
#define PCI_DEV_ID_PMCF1V2 0x0012
|
||||
|
||||
|
||||
|
||||
typedef struct _PMCQ1BoardData
|
||||
{
|
||||
struct _PMCQ1BoardData *pNext;
|
||||
unsigned long busNo;
|
||||
unsigned long slotNo;
|
||||
unsigned long funcNo;
|
||||
unsigned long baseaddr;
|
||||
unsigned long bridgeaddr;
|
||||
rtems_irq_hdl quiccInt;
|
||||
rtems_irq_hdl_param quiccArg;
|
||||
rtems_irq_hdl maInt;
|
||||
rtems_irq_hdl_param maArg;
|
||||
} PMCQ1BoardData, *PPMCQ1BoardData;
|
||||
|
||||
extern PPMCQ1BoardData pmcq1BoardData;
|
||||
|
||||
/*
|
||||
* Function declarations
|
||||
*/
|
||||
extern unsigned int rsPMCQ1QuiccIntConnect(
|
||||
unsigned long busNo, unsigned long slotNo,unsigned long funcNo, rtems_irq_hdl routine,rtems_irq_hdl_param arg );
|
||||
unsigned int rsPMCQ1Init();
|
||||
|
||||
#endif /* __INCPMCQ1H */
|
||||
209
c/src/lib/libbsp/powerpc/ep1a/include/bsp.h
Normal file
209
c/src/lib/libbsp/powerpc/ep1a/include/bsp.h
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef EP1A_BSP_H
|
||||
#define EP1A_BSP_H
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/console.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <rtems/clockdrv.h>
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
|
||||
/*
|
||||
* confdefs.h overrides for this BSP:
|
||||
* - termios serial ports (defaults to 1)
|
||||
* - Interrupt stack space is not minimum if defined.
|
||||
*/
|
||||
|
||||
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
|
||||
#define CONFIGURE_INTERRUPT_STACK_MEMORY (16 * 1024)
|
||||
|
||||
/* fundamental addresses for BSP (CHRPxxx and PREPxxx are from libcpu/io.h) */
|
||||
#define _IO_BASE CHRP_ISA_IO_BASE
|
||||
#define _ISA_MEM_BASE CHRP_ISA_MEM_BASE
|
||||
/* address of our ram on the PCI bus */
|
||||
#define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET
|
||||
#define PCI_MEM_BASE 0x80000000
|
||||
#define PCI_MEM_BASE_ADJUSTMENT 0
|
||||
|
||||
/* address of our ram on the PCI bus */
|
||||
#define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET
|
||||
|
||||
/* offset of pci memory as seen from the CPU */
|
||||
#define PCI_MEM_BASE 0x00000000
|
||||
|
||||
/* Override the default values for the following DEFAULT */
|
||||
#define PCI_CONFIG_ADDR 0xfec00000 /* 0xcf8 */
|
||||
#define PCI_CONFIG_DATA 0xfee00000 /* 0xcfc */
|
||||
|
||||
/*
|
||||
* EP1A configuration Registers.
|
||||
* Note: All addresses assume flash boot.
|
||||
*/
|
||||
|
||||
#define EQUIPMENT_PRESENT_REGISTER1 ((volatile unsigned char *)0xffa00000)
|
||||
#define EQUIPMENT_PRESENT_REGISTER2 ((volatile unsigned char *)0xffa00008)
|
||||
#define BOARD_REVISION_REGISTER1 ((volatile unsigned char *)0xffa00010)
|
||||
#define BOARD_REVISION_REGISTER2 ((volatile unsigned char *)0xffa00018)
|
||||
#define GENERAL_REGISTER1 ((volatile unsigned char *)0xffa00020)
|
||||
#define GENERAL_REGISTER2 ((volatile unsigned char *)0xffa00028)
|
||||
#define WATCHDOG_TRIGGER ((volatile unsigned char *)0xffa00030)
|
||||
|
||||
/* EQUIPMENT_PRESENT_REGISTER1 */
|
||||
#define BANK_MEMORY_SIZE_128MB 0x20
|
||||
#define BANK_MEMORY_SIZE_64MB 0x10
|
||||
#define ECC_ENABLED 0x04
|
||||
|
||||
/* EQUIPMENT-PRESENT_REGISTER2 */
|
||||
#define PLL_CFG_MASK 0xf8
|
||||
#define MHZ_33_66_200 0x70 /* PCI MEM CPU Frequency */
|
||||
#define MHZ_33_100_200 0x80 /* PCI MEM CPU Frequency */
|
||||
#define MHZ_33_66_266 0xb0 /* PCI MEM CPU Frequency */
|
||||
#define MHZ_33_66_333 0x50 /* PCI MEM CPU Frequency */
|
||||
#define MHZ_33_100_333 0x08 /* PCI MEM CPU Frequency */
|
||||
#define MHZ_33_100_350 0x78 /* PCI MEM CPU Frequency */
|
||||
|
||||
#define PMC_SLOT1_PRESENT 0x02
|
||||
#define PMC_SLOT2_PRESENT 0x01
|
||||
|
||||
/* BOARD_REVISION_REGISTER1 */
|
||||
#define ARTWORK_REVISION_MASK 0xf0
|
||||
#define BUILD_REVISION_MASK 0x0f
|
||||
|
||||
/* BOARD_REVISION_REGISTER2 */
|
||||
#define HARDWARE_ID_MASK 0xe0
|
||||
#define HARDWARE_ID_PPC5_EP1A 0xe0
|
||||
#define HARDWARE_ID_EP1B 0xc0
|
||||
|
||||
/* GENERAL_REGISTER1 */
|
||||
#define DISABLE_WATCHDOG 0x80
|
||||
#define DISABLE_RESET_SWITCH 0x40
|
||||
#define DISABLE_USER_FLASH 0x20
|
||||
#define DISABLE_BOOT_FLASH 0x10
|
||||
#define LED4_OFF 0x08
|
||||
#define LED3_OFF 0x04
|
||||
#define LED2_OFF 0x02
|
||||
#define LED1_OFF 0x01
|
||||
|
||||
|
||||
/* GENERAL_REGISTER2 */
|
||||
#define BSP_FLASH_VPP_ENABLE 0x01
|
||||
#define BSP_FLASH_PAGE_MASK 0x38
|
||||
#define BSP_FLASH_PAGE_SHIFT 0x03
|
||||
#define BSP_BIT_SLOWSTART 0x04
|
||||
#define BSP_OFFLINE 0x02
|
||||
#define BSP_SYSFAIL 0x01
|
||||
|
||||
/* WATCHDOG_TRIGGER */
|
||||
#define BSP_FLASH_BASE 0xff000000
|
||||
#define BSP_VME_A16_BASE 0x9fff0000
|
||||
#define BSP_VME_A24_BASE 0x9f000000
|
||||
|
||||
/*
|
||||
* address definitions for several devices
|
||||
*
|
||||
*/
|
||||
#define UART_OFFSET_1_8245 (0x04500)
|
||||
#define UART_OFFSET_2_8245 (0x04600)
|
||||
#define UART_BASE_COM1 0xff800000
|
||||
#define UART_BASE_COM2 0xff800040
|
||||
|
||||
#include <bsp/openpic.h>
|
||||
|
||||
/* Note docs list 0x41000 but OpenPIC has a 0x1000 pad at the start
|
||||
* assume that open pic specifies this pad but not mentioned in
|
||||
* 8245 docs.
|
||||
* This is an offset from EUMBBAR
|
||||
*/
|
||||
#define BSP_OPEN_PIC_BASE_OFFSET 0x40000
|
||||
#define BSP_PIC_DO_EOI openpic_eoi(0)
|
||||
|
||||
|
||||
#ifndef ASM
|
||||
#define outport_byte(port,value) outb(value,port)
|
||||
#define outport_word(port,value) outw(value,port)
|
||||
#define outport_long(port,value) outl(value,port)
|
||||
|
||||
#define inport_byte(port,value) (value = inb(port))
|
||||
#define inport_word(port,value) (value = inw(port))
|
||||
#define inport_long(port,value) (value = inl(port))
|
||||
|
||||
/*
|
||||
* EUMMBAR
|
||||
*/
|
||||
extern unsigned int EUMBBAR;
|
||||
|
||||
/*
|
||||
* Total memory
|
||||
*/
|
||||
extern unsigned int BSP_mem_size;
|
||||
|
||||
/*
|
||||
* PCI Bus Frequency
|
||||
*/
|
||||
extern unsigned int BSP_bus_frequency;
|
||||
|
||||
/*
|
||||
* processor clock frequency
|
||||
*/
|
||||
extern unsigned int BSP_processor_frequency;
|
||||
|
||||
/*
|
||||
* Time base divisior (how many tick for 1 second).
|
||||
*/
|
||||
extern unsigned int BSP_time_base_divisor;
|
||||
|
||||
#define BSP_Convert_decrementer( _value ) \
|
||||
((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value)))
|
||||
|
||||
#define Processor_Synchronize() \
|
||||
asm(" eieio ")
|
||||
|
||||
extern rtems_configuration_table BSP_Configuration;
|
||||
extern void BSP_panic(char *s);
|
||||
extern void rtemsReboot(void);
|
||||
extern int BSP_disconnect_clock_handler (void);
|
||||
extern int BSP_connect_clock_handler (void);
|
||||
|
||||
/*
|
||||
* FLASH
|
||||
*/
|
||||
int BSP_FLASH_Enable_writes( rtems_unsigned32 area );
|
||||
int BSP_FLASH_Disable_writes( rtems_unsigned32 area );
|
||||
void BSP_FLASH_set_page( rtems_unsigned8 page );
|
||||
|
||||
#define BSP_FLASH_ENABLE_WRITES( _area) BSP_FLASH_Enable_writes( _area )
|
||||
#define BSP_FLASH_DISABLE_WRITES(_area) BSP_FLASH_Disable_writes( _area )
|
||||
#define BSP_FLASH_SET_PAGE(_page) BSP_FLASH_set_page( _page )
|
||||
|
||||
|
||||
/* clear hostbridge errors
|
||||
*
|
||||
* enableMCP: whether to enable MCP checkstop / machine check interrupts
|
||||
* on the hostbridge and in HID0.
|
||||
*
|
||||
* NOTE: HID0 and MEREN are left alone if this flag is 0
|
||||
*
|
||||
* quiet : be silent
|
||||
*
|
||||
* RETURNS : raven MERST register contents (lowermost 16 bits), 0 if
|
||||
* there were no errors
|
||||
*/
|
||||
extern unsigned long _BSP_clear_hostbridge_errors(int enableMCP, int quiet);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
60
c/src/lib/libbsp/powerpc/ep1a/include/tm27.h
Normal file
60
c/src/lib/libbsp/powerpc/ep1a/include/tm27.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_TMTEST27
|
||||
#error "This is an RTEMS internal file you must not include directly."
|
||||
#endif
|
||||
|
||||
#ifndef __tm27_h
|
||||
#define __tm27_h
|
||||
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#define MUST_WAIT_FOR_INTERRUPT 1
|
||||
|
||||
void nullFunc() {}
|
||||
|
||||
static rtems_irq_connect_data clockIrqData = {BSP_DECREMENTER,
|
||||
0,
|
||||
(rtems_irq_enable)nullFunc,
|
||||
(rtems_irq_disable)nullFunc,
|
||||
(rtems_irq_is_enabled) nullFunc};
|
||||
void Install_tm27_vector(void (*_handler)())
|
||||
{
|
||||
clockIrqData.hdl = _handler;
|
||||
if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
|
||||
printk("Error installing clock interrupt handler!\n");
|
||||
rtems_fatal_error_occurred(1);
|
||||
}
|
||||
}
|
||||
|
||||
#define Cause_tm27_intr() \
|
||||
do { \
|
||||
unsigned32 _clicks = 8; \
|
||||
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define Clear_tm27_intr() \
|
||||
do { \
|
||||
unsigned32 _clicks = 0xffffffff; \
|
||||
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
|
||||
} while (0)
|
||||
|
||||
#define Lower_tm27_intr() \
|
||||
do { \
|
||||
unsigned32 _msr = 0; \
|
||||
_ISR_Set_level( 0 ); \
|
||||
asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
|
||||
_msr |= 0x8002; \
|
||||
asm volatile( "mtmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
|
||||
} while (0)
|
||||
#endif
|
||||
570
c/src/lib/libbsp/powerpc/ep1a/irq/irq.c
Normal file
570
c/src/lib/libbsp/powerpc/ep1a/irq/irq.c
Normal file
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
*
|
||||
* This file contains the implementation of the function described in irq.h
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/VME.h>
|
||||
#include <bsp/openpic.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/apiext.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <bsp/vectors.h>
|
||||
#include <stdlib.h>
|
||||
#include <rtems/bspIo.h> /* for printk */
|
||||
#define RAVEN_INTR_ACK_REG 0xfeff0030
|
||||
|
||||
/*
|
||||
* pointer to the mask representing the additionnal irq vectors
|
||||
* that must be disabled when a particular entry is activated.
|
||||
* They will be dynamically computed from teh prioruty table given
|
||||
* in BSP_rtems_irq_mngt_set();
|
||||
* CAUTION : this table is accessed directly by interrupt routine
|
||||
* prologue.
|
||||
*/
|
||||
rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER];
|
||||
/*
|
||||
* default handler connected on each irq after bsp initialization
|
||||
*/
|
||||
static rtems_irq_connect_data default_rtems_entry;
|
||||
|
||||
/*
|
||||
* location used to store initial tables used for interrupt
|
||||
* management.
|
||||
*/
|
||||
static rtems_irq_global_settings* internal_config;
|
||||
static rtems_irq_connect_data* rtems_hdl_tbl;
|
||||
|
||||
/*
|
||||
* Check if IRQ is an ISA IRQ
|
||||
*/
|
||||
static inline int is_isa_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if IRQ is an OPENPIC IRQ
|
||||
*/
|
||||
static inline int is_pci_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if IRQ is a Porcessor IRQ
|
||||
*/
|
||||
static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine)
|
||||
{
|
||||
return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
|
||||
((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Irq helper functions ----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Caution : this function assumes the variable "internal_config"
|
||||
* is already set and that the tables it contains are still valid
|
||||
* and accessible.
|
||||
*/
|
||||
static void compute_i8259_masks_from_prio ()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
/*
|
||||
* Always mask at least current interrupt to prevent re-entrance
|
||||
*/
|
||||
for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
|
||||
* ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
|
||||
for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
|
||||
/*
|
||||
* Mask interrupts at i8259 level that have a lower priority
|
||||
*/
|
||||
if (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) {
|
||||
* ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function check that the value given for the irq line
|
||||
* is valid.
|
||||
*/
|
||||
|
||||
static int isValidInterrupt(int irq)
|
||||
{
|
||||
if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Shared Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
|
||||
{
|
||||
unsigned int level;
|
||||
rtems_irq_connect_data* vchain;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
printk("Invalid interrupt vector %d\n",irq->name);
|
||||
return 0;
|
||||
}
|
||||
printk("Install Shared interrupt %d\n", irq->name);
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
|
||||
if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) {
|
||||
_CPU_ISR_Enable(level);
|
||||
printk("IRQ vector %d already connected to an unshared handler\n",irq->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
|
||||
|
||||
/* save off topmost handler */
|
||||
vchain[0]= rtems_hdl_tbl[irq->name];
|
||||
|
||||
/*
|
||||
* store the data provided by user
|
||||
*/
|
||||
rtems_hdl_tbl[irq->name] = *irq;
|
||||
|
||||
/* link chain to new topmost handler */
|
||||
rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
|
||||
|
||||
|
||||
if (is_isa_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at PIC level
|
||||
*/
|
||||
BSP_irq_enable_at_i8259s (irq->name);
|
||||
}
|
||||
|
||||
if (is_pci_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at OPENPIC level
|
||||
*/
|
||||
printk(" openpic_enable_irq %d\n", (int)irq->name );
|
||||
openpic_enable_irq ((int) irq->name ); /* - BSP_PCI_IRQ_LOWEST_OFFSET); */
|
||||
}
|
||||
|
||||
if (is_processor_irq(irq->name)) {
|
||||
/*
|
||||
* Enable exception at processor level
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* Enable interrupt on device
|
||||
*/
|
||||
irq->on(irq);
|
||||
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
|
||||
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||
{
|
||||
unsigned int level;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
printk("Invalid interrupt vector %d\n",irq->name);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if default handler is actually connected. If not issue an error.
|
||||
* You must first get the current handler via i386_get_current_idt_entry
|
||||
* and then disconnect it using i386_delete_idt_entry.
|
||||
* RATIONALE : to always have the same transition by forcing the user
|
||||
* to get the previous handler before accepting to disconnect.
|
||||
*/
|
||||
_CPU_ISR_Disable(level);
|
||||
if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
|
||||
_CPU_ISR_Enable(level);
|
||||
printk("IRQ vector %d already connected\n",irq->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* store the data provided by user
|
||||
*/
|
||||
rtems_hdl_tbl[irq->name] = *irq;
|
||||
rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
|
||||
|
||||
if (is_isa_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at PIC level
|
||||
*/
|
||||
BSP_irq_enable_at_i8259s (irq->name);
|
||||
}
|
||||
|
||||
if (is_pci_irq(irq->name)) {
|
||||
/*
|
||||
* Enable interrupt at OPENPIC level
|
||||
*/
|
||||
openpic_enable_irq ((int) irq->name ); /* - BSP_PCI_IRQ_LOWEST_OFFSET); */
|
||||
}
|
||||
|
||||
if (is_processor_irq(irq->name)) {
|
||||
/*
|
||||
* Enable exception at processor level
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* Enable interrupt on device
|
||||
*/
|
||||
irq->on(irq);
|
||||
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
|
||||
{
|
||||
unsigned int level;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
return 0;
|
||||
}
|
||||
_CPU_ISR_Disable(level);
|
||||
*irq = rtems_hdl_tbl[irq->name];
|
||||
_CPU_ISR_Enable(level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
|
||||
{
|
||||
rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
|
||||
unsigned int level;
|
||||
|
||||
if (!isValidInterrupt(irq->name)) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Check if default handler is actually connected. If not issue an error.
|
||||
* You must first get the current handler via i386_get_current_idt_entry
|
||||
* and then disconnect it using i386_delete_idt_entry.
|
||||
* RATIONALE : to always have the same transition by forcing the user
|
||||
* to get the previous handler before accepting to disconnect.
|
||||
*/
|
||||
_CPU_ISR_Disable(level);
|
||||
if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
|
||||
_CPU_ISR_Enable(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 )
|
||||
{
|
||||
int found = 0;
|
||||
|
||||
for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
|
||||
(vchain->hdl != default_rtems_entry.hdl);
|
||||
(pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) )
|
||||
{
|
||||
if( vchain->hdl == irq->hdl )
|
||||
{
|
||||
found= -1; break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
_CPU_ISR_Enable(level);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rtems_hdl_tbl[irq->name].hdl != irq->hdl)
|
||||
{
|
||||
_CPU_ISR_Enable(level);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_isa_irq(irq->name)) {
|
||||
/*
|
||||
* disable interrupt at PIC level
|
||||
*/
|
||||
BSP_irq_disable_at_i8259s (irq->name);
|
||||
}
|
||||
if (is_pci_irq(irq->name)) {
|
||||
/*
|
||||
* disable interrupt at OPENPIC level
|
||||
*/
|
||||
openpic_disable_irq ((int) irq->name );
|
||||
}
|
||||
if (is_processor_irq(irq->name)) {
|
||||
/*
|
||||
* disable exception at processor level
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable interrupt on device
|
||||
*/
|
||||
irq->off(irq);
|
||||
|
||||
/*
|
||||
* restore the default irq value
|
||||
*/
|
||||
if( !vchain )
|
||||
{
|
||||
/* single handler vector... */
|
||||
rtems_hdl_tbl[irq->name] = default_rtems_entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pchain )
|
||||
{
|
||||
/* non-first handler being removed */
|
||||
pchain->next_handler = vchain->next_handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* first handler isn't malloc'ed, so just overwrite it. Since
|
||||
the contents of vchain are being struct copied, vchain itself
|
||||
goes away */
|
||||
rtems_hdl_tbl[irq->name]= *vchain;
|
||||
}
|
||||
free(vchain);
|
||||
}
|
||||
|
||||
_CPU_ISR_Enable(level);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
|
||||
*/
|
||||
|
||||
int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
|
||||
{
|
||||
int i;
|
||||
unsigned int level;
|
||||
/*
|
||||
* Store various code accelerators
|
||||
*/
|
||||
internal_config = config;
|
||||
default_rtems_entry = config->defaultEntry;
|
||||
rtems_hdl_tbl = config->irqHdlTbl;
|
||||
return 1;
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
/*
|
||||
* set up internal tables used by rtems interrupt prologue
|
||||
*/
|
||||
for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
|
||||
/*
|
||||
* Note that openpic_set_priority() sets the TASK priority of the PIC
|
||||
*/
|
||||
openpic_set_source_priority(i, internal_config->irqPrioTbl[i]);
|
||||
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||
openpic_enable_irq ((int) i);
|
||||
{
|
||||
rtems_irq_connect_data* vchain;
|
||||
for( vchain = &rtems_hdl_tbl[i];
|
||||
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
|
||||
vchain = (rtems_irq_connect_data*)vchain->next_handler )
|
||||
{
|
||||
vchain->on(vchain);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
|
||||
{
|
||||
rtems_irq_connect_data* vchain;
|
||||
for( vchain = &rtems_hdl_tbl[i];
|
||||
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
|
||||
vchain = (rtems_irq_connect_data*)vchain->next_handler )
|
||||
{
|
||||
vchain->off(vchain);
|
||||
}
|
||||
}
|
||||
|
||||
openpic_disable_irq ((int) i );
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Must enable PCI/ISA bridge IRQ
|
||||
*/
|
||||
openpic_enable_irq (0);
|
||||
/*
|
||||
* finish with Processor exceptions handled like IRQ
|
||||
*/
|
||||
for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER; i++) {
|
||||
if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
|
||||
/* rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]); */
|
||||
{
|
||||
rtems_irq_connect_data* vchain;
|
||||
for( vchain = &rtems_hdl_tbl[i];
|
||||
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
|
||||
vchain = (rtems_irq_connect_data*)vchain->next_handler )
|
||||
{
|
||||
vchain->on(vchain);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */
|
||||
{
|
||||
rtems_irq_connect_data* vchain;
|
||||
for( vchain = &rtems_hdl_tbl[i];
|
||||
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
|
||||
vchain = (rtems_irq_connect_data*)vchain->next_handler )
|
||||
{
|
||||
vchain->off(vchain);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
_CPU_ISR_Enable(level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
|
||||
{
|
||||
*config = internal_config;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _BSP_vme_bridge_irq = -1;
|
||||
|
||||
unsigned BSP_spuriousIntr = 0;
|
||||
/*
|
||||
* High level IRQ handler called from shared_raw_irq_code_entry
|
||||
*/
|
||||
void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
|
||||
{
|
||||
register unsigned int irq;
|
||||
register unsigned isaIntr; /* boolean */
|
||||
register unsigned oldMask = 0; /* old isa pic masks */
|
||||
register unsigned newMask; /* new isa pic masks */
|
||||
register unsigned msr;
|
||||
register unsigned new_msr;
|
||||
|
||||
if (excNum == ASM_DEC_VECTOR) {
|
||||
_CPU_MSR_GET(msr);
|
||||
new_msr = msr | MSR_EE;
|
||||
_CPU_MSR_SET(new_msr);
|
||||
|
||||
rtems_hdl_tbl[BSP_DECREMENTER].hdl( rtems_hdl_tbl[BSP_DECREMENTER].handle );
|
||||
|
||||
_CPU_MSR_SET(msr);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
irq = openpic_irq(0);
|
||||
|
||||
if (irq == OPENPIC_VEC_SPURIOUS) {
|
||||
++BSP_spuriousIntr;
|
||||
return;
|
||||
}
|
||||
|
||||
isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
|
||||
if (isaIntr) {
|
||||
/*
|
||||
* Acknowledge and read 8259 vector
|
||||
*/
|
||||
irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
|
||||
/*
|
||||
* store current PIC mask
|
||||
*/
|
||||
oldMask = i8259s_cache;
|
||||
newMask = oldMask | irq_mask_or_tbl [irq];
|
||||
i8259s_cache = newMask;
|
||||
outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
|
||||
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
|
||||
BSP_irq_ack_at_i8259s (irq);
|
||||
openpic_eoi(0);
|
||||
}
|
||||
|
||||
_CPU_MSR_GET(msr);
|
||||
new_msr = msr | MSR_EE;
|
||||
_CPU_MSR_SET(new_msr);
|
||||
|
||||
{
|
||||
rtems_irq_connect_data* vchain;
|
||||
irq -= 16; /* Correct the vector for the 8240 */
|
||||
for( vchain = &rtems_hdl_tbl[irq];
|
||||
((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
|
||||
vchain = (rtems_irq_connect_data*)vchain->next_handler )
|
||||
{
|
||||
vchain->hdl( vchain->handle );
|
||||
}
|
||||
}
|
||||
_CPU_MSR_SET(msr);
|
||||
|
||||
if (isaIntr) {
|
||||
i8259s_cache = oldMask;
|
||||
outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
|
||||
outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
|
||||
}
|
||||
else {
|
||||
#ifdef BSP_PCI_VME_DRIVER_DOES_EOI
|
||||
/* leave it to the VME bridge driver to do EOI, so
|
||||
* it can re-enable the openpic while handling
|
||||
* VME interrupts (-> VME priorities in software)
|
||||
*/
|
||||
if (_BSP_vme_bridge_irq != irq)
|
||||
#endif
|
||||
openpic_eoi(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
|
||||
{
|
||||
/*
|
||||
* Process pending signals that have not already been
|
||||
* processed by _Thread_Displatch. This happens quite
|
||||
* unfrequently : the ISR must have posted an action
|
||||
* to the current running thread.
|
||||
*/
|
||||
if ( _Thread_Do_post_task_switch_extension ||
|
||||
_Thread_Executing->do_post_task_switch_extension ) {
|
||||
_Thread_Executing->do_post_task_switch_extension = FALSE;
|
||||
_API_extensions_Run_postswitch();
|
||||
}
|
||||
/*
|
||||
* I plan to process other thread related events here.
|
||||
* This will include DEBUG session requested from keyboard...
|
||||
*/
|
||||
}
|
||||
332
c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c
Normal file
332
c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c
Normal file
@@ -0,0 +1,332 @@
|
||||
/* irq_init.c
|
||||
*
|
||||
* This file contains the implementation of rtems initialization
|
||||
* related to interrupt handling.
|
||||
*
|
||||
* CopyRight (C) 1999 valette@crf.canon.fr
|
||||
*
|
||||
* Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
|
||||
* to make it valid for MVME2300 Motorola boards.
|
||||
*
|
||||
* Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
|
||||
* Use the new interface to openpic_init
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <libcpu/io.h>
|
||||
#include <libcpu/spr.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp/residual.h>
|
||||
#include <bsp/openpic.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp.h>
|
||||
#include <libcpu/raw_exception.h>
|
||||
#include <bsp/motorola.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
/*
|
||||
#define SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned char bus; /* few chance the PCI/ISA bridge is not on first bus but ... */
|
||||
unsigned char device;
|
||||
unsigned char function;
|
||||
} pci_isa_bridge_device;
|
||||
|
||||
pci_isa_bridge_device* via_82c586 = 0;
|
||||
static pci_isa_bridge_device bridge;
|
||||
|
||||
extern unsigned int external_exception_vector_prolog_code_size[];
|
||||
extern void external_exception_vector_prolog_code();
|
||||
extern unsigned int decrementer_exception_vector_prolog_code_size[];
|
||||
extern void decrementer_exception_vector_prolog_code();
|
||||
|
||||
/*
|
||||
* default on/off function
|
||||
*/
|
||||
static void nop_func(){}
|
||||
/*
|
||||
* default isOn function
|
||||
*/
|
||||
static int not_connected() {return 0;}
|
||||
/*
|
||||
* default possible isOn function
|
||||
*/
|
||||
static int connected() {return 1;}
|
||||
|
||||
static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
|
||||
static rtems_irq_global_settings initial_config;
|
||||
static rtems_irq_connect_data defaultIrq = {
|
||||
/* vectorIdex, hdl , handle , on , off , isOn */
|
||||
0, nop_func , NULL , nop_func , nop_func , not_connected
|
||||
};
|
||||
static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
|
||||
/*
|
||||
* actual rpiorities for interrupt :
|
||||
* 0 means that only current interrupt is masked
|
||||
* 255 means all other interrupts are masked
|
||||
*/
|
||||
/*
|
||||
* ISA interrupts.
|
||||
* The second entry has a priority of 255 because
|
||||
* it is the slave pic entry and is should always remain
|
||||
* unmasked.
|
||||
*/
|
||||
0,0,
|
||||
255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*
|
||||
* PCI Interrupts
|
||||
*/
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
|
||||
/*
|
||||
* Processor exceptions handled as interrupts
|
||||
*/
|
||||
0
|
||||
};
|
||||
|
||||
static unsigned char mcp750_openpic_initpolarities[] = {
|
||||
1, /* 0 8259 cascade */
|
||||
0, /* 1 all the rest of them */
|
||||
0, /* 2 all the rest of them */
|
||||
0, /* 3 all the rest of them */
|
||||
0, /* 4 all the rest of them */
|
||||
0, /* 5 all the rest of them */
|
||||
0, /* 6 all the rest of them */
|
||||
0, /* 7 all the rest of them */
|
||||
0, /* 8 all the rest of them */
|
||||
0, /* 9 all the rest of them */
|
||||
0, /* 10 all the rest of them */
|
||||
0, /* 11 all the rest of them */
|
||||
0, /* 12 all the rest of them */
|
||||
0, /* 13 all the rest of them */
|
||||
0, /* 14 all the rest of them */
|
||||
0, /* 15 all the rest of them */
|
||||
0, /* 16 all the rest of them */
|
||||
0, /* 17 all the rest of them */
|
||||
1, /* 18 all the rest of them */
|
||||
1, /* 19 all the rest of them */
|
||||
1, /* 20 all the rest of them */
|
||||
1, /* 21 all the rest of them */
|
||||
1, /* 22 all the rest of them */
|
||||
1, /* 23 all the rest of them */
|
||||
1, /* 24 all the rest of them */
|
||||
1, /* 25 all the rest of them */
|
||||
};
|
||||
|
||||
static unsigned char mcp750_openpic_initsenses[] = {
|
||||
1, /* 0 MCP750_INT_PCB(8259) */
|
||||
0, /* 1 MCP750_INT_FALCON_ECC_ERR */
|
||||
1, /* 2 MCP750_INT_PCI_ETHERNET */
|
||||
1, /* 3 MCP750_INT_PCI_PMC */
|
||||
1, /* 4 MCP750_INT_PCI_WATCHDOG_TIMER1 */
|
||||
1, /* 5 MCP750_INT_PCI_PRST_SIGNAL */
|
||||
1, /* 6 MCP750_INT_PCI_FALL_SIGNAL */
|
||||
1, /* 7 MCP750_INT_PCI_DEG_SIGNAL */
|
||||
1, /* 8 MCP750_INT_PCI_BUS1_INTA */
|
||||
1, /* 9 MCP750_INT_PCI_BUS1_INTB */
|
||||
1, /*10 MCP750_INT_PCI_BUS1_INTC */
|
||||
1, /*11 MCP750_INT_PCI_BUS1_INTD */
|
||||
1, /*12 MCP750_INT_PCI_BUS2_INTA */
|
||||
1, /*13 MCP750_INT_PCI_BUS2_INTB */
|
||||
1, /*14 MCP750_INT_PCI_BUS2_INTC */
|
||||
1, /*15 MCP750_INT_PCI_BUS2_INTD */
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
void VIA_isa_bridge_interrupts_setup(void)
|
||||
{
|
||||
pci_isa_bridge_device pci_dev;
|
||||
unsigned int temp;
|
||||
unsigned char tmp;
|
||||
unsigned char maxBus;
|
||||
unsigned found = 0;
|
||||
|
||||
maxBus = BusCountPCI();
|
||||
pci_dev.function = 0; /* Assumes the bidge is the first function */
|
||||
|
||||
for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
|
||||
#ifdef SCAN_PCI_PRINT
|
||||
printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
|
||||
#endif
|
||||
for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
|
||||
#ifdef SCAN_PCI_PRINT
|
||||
printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
|
||||
#endif
|
||||
pci_read_config_dword(pci_dev.bus, pci_dev.device, pci_dev.function,
|
||||
PCI_VENDOR_ID, &temp);
|
||||
#ifdef SCAN_PCI_PRINT
|
||||
printk("Vendor/device = %x\n", temp);
|
||||
#endif
|
||||
if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
|
||||
) {
|
||||
bridge = pci_dev;
|
||||
via_82c586 = &bridge;
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
/*
|
||||
* Should print : bus = 0, device = 11, function = 0 on a MCP750.
|
||||
*/
|
||||
printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
|
||||
via_82c586->bus,
|
||||
via_82c586->device,
|
||||
via_82c586->function);
|
||||
#endif
|
||||
found = 1;
|
||||
goto loop_exit;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
loop_exit:
|
||||
if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n");
|
||||
|
||||
tmp = inb(0x810);
|
||||
if ( !(tmp & 0x2)) {
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk("This is a second generation MCP750 board\n");
|
||||
printk("We must reprogram the PCI/ISA bridge...\n");
|
||||
#endif
|
||||
pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x47, &tmp);
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
|
||||
#endif
|
||||
/*
|
||||
* Enable 4D0/4D1 ISA interrupt level/edge config registers
|
||||
*/
|
||||
tmp |= 0x20;
|
||||
pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x47, tmp);
|
||||
/*
|
||||
* Now program the ISA interrupt edge/level
|
||||
*/
|
||||
tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
|
||||
outb(tmp, ISA8259_S_ELCR);
|
||||
tmp = ELCRM_INT5_LVL;
|
||||
outb(tmp, ISA8259_M_ELCR);;
|
||||
/*
|
||||
* Set the Interrupt inputs to non-inverting level interrupt
|
||||
*/
|
||||
pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x54, &tmp);
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
|
||||
#endif
|
||||
tmp = 0;
|
||||
pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x54, tmp);
|
||||
}
|
||||
else {
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk("This is a first generation MCP750 board\n");
|
||||
printk("We just show the actual value used by PCI/ISA bridge\n");
|
||||
#endif
|
||||
pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x47, &tmp);
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
|
||||
#endif
|
||||
/*
|
||||
* Show the Interrupt inputs inverting/non-inverting level status
|
||||
*/
|
||||
pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
|
||||
0x54, &tmp);
|
||||
#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
|
||||
printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This code assumes the exceptions management setup has already
|
||||
* been done. We just need to replace the exceptions that will
|
||||
* be handled like interrupt. On mcp750/mpc750 and many PPC processors
|
||||
* this means the decrementer exception and the external exception.
|
||||
*/
|
||||
void BSP_rtems_irq_mng_init(unsigned cpuId)
|
||||
{
|
||||
rtems_raw_except_connect_data vectorDesc;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First initialize the Interrupt management hardware
|
||||
*/
|
||||
#ifdef TRACE_IRQ_INIT
|
||||
printk("Going to initialize openpic compliant device\n");
|
||||
#endif
|
||||
openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses);
|
||||
|
||||
#ifdef TRACE_IRQ_INIT
|
||||
printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize Rtems management interrupt table
|
||||
*/
|
||||
/*
|
||||
* re-init the rtemsIrq table
|
||||
*/
|
||||
for (i = 0; i < BSP_IRQ_NUMBER; i++) {
|
||||
rtemsIrq[i] = defaultIrq;
|
||||
rtemsIrq[i].name = i;
|
||||
}
|
||||
/*
|
||||
* Init initial Interrupt management config
|
||||
*/
|
||||
initial_config.irqNb = BSP_IRQ_NUMBER;
|
||||
initial_config.defaultEntry = defaultIrq;
|
||||
initial_config.irqHdlTbl = rtemsIrq;
|
||||
initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
|
||||
initial_config.irqPrioTbl = irqPrioTable;
|
||||
|
||||
if (!BSP_rtems_irq_mngt_set(&initial_config)) {
|
||||
/*
|
||||
* put something here that will show the failure...
|
||||
*/
|
||||
BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* We must connect the raw irq handler for the two
|
||||
* expected interrupt sources : decrementer and external interrupts.
|
||||
*/
|
||||
vectorDesc.exceptIndex = ASM_DEC_VECTOR;
|
||||
vectorDesc.hdl.vector = ASM_DEC_VECTOR;
|
||||
vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code;
|
||||
vectorDesc.hdl.raw_hdl_size = (unsigned) decrementer_exception_vector_prolog_code_size;
|
||||
vectorDesc.on = nop_func;
|
||||
vectorDesc.off = nop_func;
|
||||
vectorDesc.isOn = connected;
|
||||
if (!mpc60x_set_exception (&vectorDesc)) {
|
||||
BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
|
||||
}
|
||||
vectorDesc.exceptIndex = ASM_EXT_VECTOR;
|
||||
vectorDesc.hdl.vector = ASM_EXT_VECTOR;
|
||||
vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code;
|
||||
vectorDesc.hdl.raw_hdl_size = (unsigned) external_exception_vector_prolog_code_size;
|
||||
if (!mpc60x_set_exception (&vectorDesc)) {
|
||||
BSP_panic("Unable to initialize RTEMS external raw exception\n");
|
||||
}
|
||||
#ifdef TRACE_IRQ_INIT
|
||||
printk("RTEMS IRQ management is now operationnal\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
31
c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c
Normal file
31
c/src/lib/libbsp/powerpc/ep1a/pci/no_host_bridge.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <libcpu/io.h>
|
||||
#include <libcpu/spr.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp/consoleIo.h>
|
||||
#include <bsp/residual.h>
|
||||
#include <bsp/openpic.h>
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
/*
|
||||
* For the 8240 and the 8245 there is no host bridge the
|
||||
* Open PIC device is built into the processor chip.
|
||||
*/
|
||||
|
||||
void detect_host_bridge()
|
||||
{
|
||||
OpenPIC=(volatile struct OpenPIC *) (EUMBBAR + BSP_OPEN_PIC_BASE_OFFSET );
|
||||
}
|
||||
151
c/src/lib/libbsp/powerpc/ep1a/start/start.S
Normal file
151
c/src/lib/libbsp/powerpc/ep1a/start/start.S
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* This is based on the mvme-crt0.S file from libgloss/rs6000.
|
||||
* crt0.S -- startup file for PowerPC systems.
|
||||
*
|
||||
* (c) 1998, Radstone Technology plc.
|
||||
*
|
||||
*
|
||||
* This is an unpublished work the copyright in which vests
|
||||
* in Radstone Technology plc. All rights reserved.
|
||||
*
|
||||
* The information contained herein is the property of Radstone
|
||||
* Technology plc. and is supplied without liability for
|
||||
* errors or omissions and no part may be reproduced, used or
|
||||
* disclosed except as authorized by contract or other written
|
||||
* permission. The copyright and the foregoing
|
||||
* restriction on reproduction, use and disclosure extend to
|
||||
* all the media in which this information may be
|
||||
* embodied.
|
||||
*
|
||||
* Copyright (c) 1995 Cygnus Support
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||
* and license this software and its documentation for any purpose, provided
|
||||
* that existing copyright notices are retained in all copies and that this
|
||||
* notice is included verbatim in any distributions. No written agreement,
|
||||
* license, or royalty fee is required for any of the authorized uses.
|
||||
* Modifications to this software may be copyrighted by their authors
|
||||
* and need not follow the licensing terms described here, provided that
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*
|
||||
* start.S,v 1.4 2002/04/19 13:25:27 joel Exp
|
||||
*/
|
||||
/*
|
||||
#include <ppc-asm.h>
|
||||
#include <bsp.h>
|
||||
*/
|
||||
|
||||
#include <asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
#include <libcpu/io.h>
|
||||
#include <ppc-asm.h>
|
||||
|
||||
#define H0_60X_ICE 0x8000 /* HID0 I-Cache Enable */
|
||||
#define H0_60X_DCE 0x4000 /* HID0 D-Cache Enable */
|
||||
|
||||
.file "start.s"
|
||||
|
||||
.extern FUNC_NAME(atexit)
|
||||
.globl FUNC_NAME(__atexit)
|
||||
.section ".sdata","aw"
|
||||
.align 2
|
||||
FUNC_NAME(__atexit): /* tell C's eabi-ctor's we have an atexit function */
|
||||
.long FUNC_NAME(atexit)@fixup /* and that it is to register __do_global_dtors */
|
||||
|
||||
.section ".fixup","aw"
|
||||
.align 2
|
||||
.long FUNC_NAME(__atexit)
|
||||
|
||||
.text
|
||||
.globl __rtems_entry_point
|
||||
.type __rtems_entry_point,@function
|
||||
__rtems_entry_point:
|
||||
|
||||
/* Set MSR */
|
||||
/*
|
||||
* Enable data and instruction address translation and floating point
|
||||
*/
|
||||
li r3,MSR_IR | MSR_DR | MSR_FP
|
||||
mtmsr r3
|
||||
|
||||
/* XXX - ADD BACK IN CACHING INSTRUCTIONS */
|
||||
|
||||
/* clear bss */
|
||||
lis r6,__bss_start@h
|
||||
ori r6,r6,__bss_start@l
|
||||
lis r7,__bss_end@h
|
||||
ori r7,r7,__bss_end@l
|
||||
|
||||
cmplw 1,r6,r7
|
||||
bc 4,4,.Lbss_done
|
||||
|
||||
subf r8,r6,r7 /* number of bytes to zero */
|
||||
srwi r9,r8,2 /* number of words to zero */
|
||||
mtctr r9
|
||||
li r0,0 /* zero to clear memory */
|
||||
addi r6,r6,-4 /* adjust so we can use stwu */
|
||||
.Lbss_loop:
|
||||
stwu r0,4(r6) /* zero bss */
|
||||
bdnz .Lbss_loop
|
||||
|
||||
.Lbss_done:
|
||||
|
||||
/* clear sbss */
|
||||
lis r6,__sbss_start@h
|
||||
ori r6,r6,__sbss_start@l
|
||||
lis r7,__sbss_end@h
|
||||
ori r7,r7,__sbss_end@l
|
||||
|
||||
cmplw 1,r6,r7
|
||||
bc 4,4,.Lsbss_done
|
||||
|
||||
subf r8,r6,r7 /* number of bytes to zero */
|
||||
srwi r9,r8,2 /* number of words to zero */
|
||||
mtctr r9
|
||||
li r0,0 /* zero to clear memory */
|
||||
addi r6,r6,-4 /* adjust so we can use stwu */
|
||||
.Lsbss_loop:
|
||||
stwu r0,4(r6) /* zero sbss */
|
||||
bdnz .Lsbss_loop
|
||||
|
||||
.Lsbss_done:
|
||||
|
||||
lis sp,__stack@h
|
||||
ori sp,sp,__stack@l
|
||||
|
||||
/* set up initial stack frame */
|
||||
addi sp,sp,-4 /* make sure we don't overwrite debug mem */
|
||||
lis r0,0
|
||||
stw r0,0(sp) /* clear back chain */
|
||||
stwu sp,-56(sp) /* push another stack frame */
|
||||
|
||||
lis r5,environ@ha
|
||||
la r5,environ@l(r5) /* environp */
|
||||
li r4, 0 /* argv */
|
||||
li r3, 0 /* argc */
|
||||
|
||||
/* Let her rip */
|
||||
bl FUNC_NAME(boot_card)
|
||||
|
||||
/*
|
||||
* This should never get reached
|
||||
*/
|
||||
/*
|
||||
* Return MSR to its reset state
|
||||
*/
|
||||
li r3,0
|
||||
mtmsr r3
|
||||
isync
|
||||
|
||||
/*
|
||||
* Call reset entry point
|
||||
*/
|
||||
lis r3,0xfff0
|
||||
ori r3,r3,0x100
|
||||
mtlr r3
|
||||
blr
|
||||
.Lstart:
|
||||
.size _start,.Lstart-_start
|
||||
|
||||
.comm environ,4,4
|
||||
523
c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c
Normal file
523
c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c
Normal file
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* This routine starts the application. It includes application,
|
||||
* board, and monitor specific initialization and configuration.
|
||||
* The generic CPU dependent initialization has been performed
|
||||
* before this routine is invoked.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/libcsupport.h>
|
||||
#include <bsp/consoleIo.h>
|
||||
#include <libcpu/spr.h>
|
||||
#include <bsp/residual.h>
|
||||
#include <bsp/pci.h>
|
||||
#include <bsp/openpic.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/VME.h>
|
||||
#include <bsp.h>
|
||||
#include <libcpu/bat.h>
|
||||
#include <libcpu/pte121.h>
|
||||
#include <libcpu/cpuIdent.h>
|
||||
#include <bsp/vectors.h>
|
||||
#include <rtems/powerpc/powerpc.h>
|
||||
|
||||
extern unsigned long __rtems_end[];
|
||||
extern void L1_caches_enables();
|
||||
extern unsigned get_L2CR();
|
||||
extern void set_L2CR(unsigned);
|
||||
extern void bsp_cleanup(void);
|
||||
extern Triv121PgTbl BSP_pgtbl_setup();
|
||||
extern void BSP_pgtbl_activate();
|
||||
extern void BSP_vme_config();
|
||||
unsigned int rsPMCQ1Init();
|
||||
|
||||
SPR_RW(SPRG0)
|
||||
SPR_RW(SPRG1)
|
||||
|
||||
void ShowBATS(){
|
||||
unsigned32 lower;
|
||||
unsigned32 upper;
|
||||
|
||||
__MFSPR(536, upper);
|
||||
__MFSPR(537, lower);
|
||||
printk("BAT0 %08x %08x\n", upper, lower );
|
||||
|
||||
__MFSPR(538, upper);
|
||||
__MFSPR(539, lower);
|
||||
printk("BAT1 %08x %08x\n", upper, lower );
|
||||
|
||||
__MFSPR(540, upper);
|
||||
__MFSPR(541, lower);
|
||||
printk("BAT2 %08x %08x\n", upper, lower );
|
||||
|
||||
__MFSPR(542, upper);
|
||||
__MFSPR(543, lower);
|
||||
printk("BAT3 %08x %08x\n", upper, lower );
|
||||
|
||||
}
|
||||
|
||||
uint8_t LightIdx = 0;
|
||||
void BSP_Increment_Light(){
|
||||
uint8_t data;
|
||||
data = *GENERAL_REGISTER1;
|
||||
data &= 0xf0;
|
||||
data |= LightIdx++;
|
||||
*GENERAL_REGISTER1 = data;
|
||||
}
|
||||
|
||||
void BSP_Fatal_Fault_Light() {
|
||||
uint8_t data;
|
||||
data = *GENERAL_REGISTER1;
|
||||
data &= 0xf0;
|
||||
data |= 0x7;
|
||||
while(1)
|
||||
*GENERAL_REGISTER1 = data;
|
||||
}
|
||||
|
||||
void write_to_Q2ram(int offset, unsigned int data )
|
||||
{
|
||||
printk("0x%x ==> %d\n", offset, data );
|
||||
#if 0
|
||||
unsigned int *ptr = 0x82000000;
|
||||
ptr += offset;
|
||||
*ptr = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Vital Board data Start using DATA RESIDUAL
|
||||
*/
|
||||
|
||||
unsigned32 VME_Slot1 = FALSE;
|
||||
|
||||
/*
|
||||
* Total memory.
|
||||
* Note: RAM_END is defined in linkcmds. We want to verify that the application
|
||||
* is only using 10M of memory, and we do this by only accounting for this
|
||||
* much memory.
|
||||
*/
|
||||
extern int RAM_END;
|
||||
unsigned int BSP_mem_size = (unsigned int)&RAM_END;
|
||||
|
||||
/*
|
||||
* PCI Bus Frequency
|
||||
*/
|
||||
unsigned int BSP_bus_frequency;
|
||||
|
||||
/*
|
||||
* processor clock frequency
|
||||
*/
|
||||
unsigned int BSP_processor_frequency;
|
||||
|
||||
/*
|
||||
* Time base divisior (how many tick for 1 second).
|
||||
*/
|
||||
unsigned int BSP_time_base_divisor = 1000; /* XXX - Just a guess */
|
||||
|
||||
/*
|
||||
* system init stack and soft ir stack size
|
||||
*/
|
||||
#define INIT_STACK_SIZE 0x1000
|
||||
#define INTR_STACK_SIZE CONFIGURE_INTERRUPT_STACK_MEMORY
|
||||
|
||||
void BSP_panic(char *s)
|
||||
{
|
||||
printk("%s PANIC %s\n",_RTEMS_version, s);
|
||||
__asm__ __volatile ("sc");
|
||||
}
|
||||
|
||||
void _BSP_Fatal_error(unsigned int v)
|
||||
{
|
||||
printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
|
||||
__asm__ __volatile ("sc");
|
||||
}
|
||||
|
||||
/*
|
||||
* The original table from the application and our copy of it with
|
||||
* some changes.
|
||||
*/
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
|
||||
rtems_configuration_table BSP_Configuration;
|
||||
|
||||
rtems_cpu_table Cpu_table;
|
||||
|
||||
char *rtems_progname;
|
||||
|
||||
int BSP_FLASH_Disable_writes(
|
||||
rtems_unsigned32 area
|
||||
)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
data = *GENERAL_REGISTER1;
|
||||
data |= DISABLE_USER_FLASH;
|
||||
*GENERAL_REGISTER1 = data;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
int BSP_FLASH_Enable_writes(
|
||||
rtems_unsigned32 area /* IN */
|
||||
)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
data = *GENERAL_REGISTER1;
|
||||
data &= (~DISABLE_USER_FLASH);
|
||||
*GENERAL_REGISTER1 = data;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
void BSP_FLASH_set_page(
|
||||
rtems_unsigned8 page
|
||||
)
|
||||
{
|
||||
unsigned char data;
|
||||
|
||||
/* Set the flash page register. */
|
||||
data = *GENERAL_REGISTER2;
|
||||
data &= ~(BSP_FLASH_PAGE_MASK);
|
||||
data |= 0x80 | (page << BSP_FLASH_PAGE_SHIFT);
|
||||
*GENERAL_REGISTER2 = data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the shared implementations of the following routines
|
||||
*/
|
||||
|
||||
void bsp_postdriver_hook(void);
|
||||
void bsp_libc_init( void *, unsigned32, int );
|
||||
|
||||
/*
|
||||
* Function: bsp_pretasking_hook
|
||||
* Created: 95/03/10
|
||||
*
|
||||
* Description:
|
||||
* BSP pretasking hook. Called just before drivers are initialized.
|
||||
* Used to setup libc and install any BSP extensions.
|
||||
*
|
||||
* NOTES:
|
||||
* Must not use libc (to do io) from here, since drivers are
|
||||
* not yet initialized.
|
||||
*
|
||||
*/
|
||||
|
||||
void bsp_pretasking_hook(void)
|
||||
{
|
||||
rtems_unsigned32 heap_start;
|
||||
rtems_unsigned32 heap_size;
|
||||
rtems_unsigned32 heap_sbrk_spared;
|
||||
extern rtems_unsigned32 _bsp_sbrk_init(rtems_unsigned32, rtems_unsigned32*);
|
||||
heap_start = ((rtems_unsigned32) __rtems_end) +INIT_STACK_SIZE + INTR_STACK_SIZE;
|
||||
if (heap_start & (CPU_ALIGNMENT-1))
|
||||
heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
|
||||
|
||||
heap_size = (BSP_mem_size - heap_start) - BSP_Configuration.work_space_size;
|
||||
|
||||
heap_sbrk_spared=_bsp_sbrk_init(heap_start, &heap_size);
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk(" HEAP start %x size %x (%x bytes spared for sbrk)\n", heap_start, heap_size, heap_sbrk_spared);
|
||||
#endif
|
||||
|
||||
bsp_libc_init((void *) 0, heap_size, heap_sbrk_spared);
|
||||
rsPMCQ1Init();
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
|
||||
#endif
|
||||
}
|
||||
|
||||
void zero_bss()
|
||||
{
|
||||
/* prevent these from being accessed in the short data areas */
|
||||
extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
|
||||
extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
|
||||
memset(__SBSS_START__, 0, ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__));
|
||||
memset(__SBSS2_START__, 0, ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__));
|
||||
memset(__bss_start, 0, ((unsigned) __rtems_end) - ((unsigned)__bss_start));
|
||||
}
|
||||
|
||||
void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
|
||||
{
|
||||
#if 0
|
||||
residualCopy = *r3;
|
||||
strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
|
||||
loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int EUMBBAR;
|
||||
|
||||
unsigned int get_eumbbar() {
|
||||
register int a, e;
|
||||
|
||||
asm volatile( "lis %0,0xfec0; ori %0,%0,0x0000": "=r" (a) );
|
||||
asm volatile("sync");
|
||||
|
||||
asm volatile("lis %0,0x8000; ori %0,%0,0x0078": "=r"(e) );
|
||||
asm volatile("stwbrx %0,0x0,%1": "=r"(e): "r"(a));
|
||||
asm volatile("sync");
|
||||
|
||||
asm volatile("lis %0,0xfee0; ori %0,%0,0x0000": "=r" (a) );
|
||||
asm volatile("sync");
|
||||
|
||||
asm volatile("lwbrx %0,0x0,%1": "=r" (e): "r" (a));
|
||||
asm volatile("isync");
|
||||
return e;
|
||||
}
|
||||
|
||||
void Read_ep1a_config_registers( ppc_cpu_id_t myCpu ) {
|
||||
unsigned char value;
|
||||
|
||||
/*
|
||||
* Print out the board and revision.
|
||||
*/
|
||||
|
||||
printk("Board: ");
|
||||
printk( get_ppc_cpu_type_name(myCpu) );
|
||||
|
||||
value = *BOARD_REVISION_REGISTER2 & HARDWARE_ID_MASK;
|
||||
if ( value == HARDWARE_ID_PPC5_EP1A )
|
||||
printk(" EP1A ");
|
||||
else if ( value == HARDWARE_ID_EP1B )
|
||||
printk(" EP1B ");
|
||||
else
|
||||
printk(" Unknown ");
|
||||
|
||||
value = *BOARD_REVISION_REGISTER2&0x1;
|
||||
printk("Board ID %08x", value);
|
||||
if(value == 0x0){
|
||||
VME_Slot1 = TRUE;
|
||||
printk("VME Slot 1\n");
|
||||
}
|
||||
else{
|
||||
VME_Slot1 = FALSE;
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
printk("Revision: ");
|
||||
value = *BOARD_REVISION_REGISTER1;
|
||||
printk("%d%c\n\n", value>>4, 'A'+(value&BUILD_REVISION_MASK) );
|
||||
|
||||
/*
|
||||
* Get the CPU, XXX frequency
|
||||
*/
|
||||
value = *EQUIPMENT_PRESENT_REGISTER2 & PLL_CFG_MASK;
|
||||
switch( value ) {
|
||||
case MHZ_33_66_200: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 200000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
case MHZ_33_100_200: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 200000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
case MHZ_33_66_266: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 266000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
case MHZ_33_66_333: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 333000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
case MHZ_33_100_333: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 333000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
case MHZ_33_100_350: /* PCI, MEM, & CPU Frequency */
|
||||
BSP_processor_frequency = 350000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
default:
|
||||
printk("ERROR: Unknown Processor frequency 0x%02x please fill in bspstart.c\n",value);
|
||||
BSP_processor_frequency = 350000000;
|
||||
BSP_bus_frequency = 33000000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bsp_start
|
||||
*
|
||||
* This routine does the bulk of the system initialization.
|
||||
*/
|
||||
|
||||
void bsp_start( void )
|
||||
{
|
||||
unsigned char *stack;
|
||||
register uint32_t intrStack;
|
||||
register uint32_t *intrStackPtr;
|
||||
unsigned char *work_space_start;
|
||||
ppc_cpu_id_t myCpu;
|
||||
ppc_cpu_revision_t myCpuRevision;
|
||||
Triv121PgTbl pt=0; /* R = e; */
|
||||
|
||||
/*
|
||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
||||
* store the result in global variables so that it can be used latter...
|
||||
*/
|
||||
BSP_Increment_Light();
|
||||
myCpu = get_ppc_cpu_type();
|
||||
myCpuRevision = get_ppc_cpu_revision();
|
||||
|
||||
EUMBBAR = get_eumbbar();
|
||||
printk("EUMBBAR 0x%08x\n", EUMBBAR );
|
||||
|
||||
/*
|
||||
* Note this sets BSP_processor_frequency based upon register settings.
|
||||
* It must be done prior to setting up hooks.
|
||||
*/
|
||||
Read_ep1a_config_registers( myCpu );
|
||||
|
||||
/*
|
||||
* Set up our hooks
|
||||
* Make sure libc_init is done before drivers initialized so that
|
||||
* they can use atexit()
|
||||
*/
|
||||
|
||||
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
||||
Cpu_table.do_zero_of_workspace = TRUE;
|
||||
Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
|
||||
Cpu_table.clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
|
||||
Cpu_table.exceptions_in_RAM = TRUE;
|
||||
|
||||
ShowBATS();
|
||||
#if 0 /* XXX - Add back in cache enable when we get this up and running!! */
|
||||
/*
|
||||
* enables L1 Cache. Note that the L1_caches_enables() codes checks for
|
||||
* relevant CPU type so that the reason why there is no use of myCpu...
|
||||
*/
|
||||
L1_caches_enables();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the initial stack has aready been set to this value in start.S
|
||||
* so there is no need to set it in r1 again... It is just for info
|
||||
* so that It can be printed without accessing R1.
|
||||
*/
|
||||
stack = ((unsigned char*) __rtems_end) + INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
|
||||
|
||||
/* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
|
||||
*((unsigned32 *)stack) = 0;
|
||||
|
||||
/*
|
||||
* Initialize the interrupt related settings
|
||||
* SPRG1 = software managed IRQ stack
|
||||
*
|
||||
* This could be done latter (e.g in IRQ_INIT) but it helps to understand
|
||||
* some settings below...
|
||||
*/
|
||||
intrStack = ((uint32_t) __rtems_end) +
|
||||
INIT_STACK_SIZE + INTR_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
|
||||
|
||||
/* make sure it's properly aligned */
|
||||
intrStack &= ~(CPU_STACK_ALIGNMENT-1);
|
||||
|
||||
/* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
|
||||
intrStackPtr = (uint32_t*) intrStack;
|
||||
*intrStackPtr = 0;
|
||||
|
||||
_write_SPRG1((unsigned int)intrStack);
|
||||
|
||||
/* signal them that we have fixed PR288 - eventually, this should go away */
|
||||
_write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
|
||||
|
||||
/*
|
||||
* Initialize default raw exception hanlders. See vectors/vectors_init.c
|
||||
*/
|
||||
initialize_exceptions();
|
||||
|
||||
/*
|
||||
* Init MMU block address translation to enable hardware
|
||||
* access
|
||||
*/
|
||||
setdbat(1, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
|
||||
setdbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
|
||||
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Going to start PCI buses scanning and initialization\n");
|
||||
#endif
|
||||
pci_initialize();
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Number of PCI buses found is : %d\n", BusCountPCI());
|
||||
#endif
|
||||
#ifdef TEST_RAW_EXCEPTION_CODE
|
||||
printk("Testing exception handling Part 1\n");
|
||||
|
||||
/*
|
||||
* Cause a software exception
|
||||
*/
|
||||
__asm__ __volatile ("sc");
|
||||
|
||||
/*
|
||||
* Check we can still catch exceptions and returned coorectly.
|
||||
*/
|
||||
printk("Testing exception handling Part 2\n");
|
||||
__asm__ __volatile ("sc");
|
||||
#endif
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size);
|
||||
#endif
|
||||
work_space_start =
|
||||
(unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
|
||||
|
||||
if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE) {
|
||||
printk( "bspstart: Not enough RAM!!!\n" );
|
||||
bsp_cleanup();
|
||||
}
|
||||
|
||||
BSP_Configuration.work_space_start = work_space_start;
|
||||
|
||||
/*
|
||||
* Initalize RTEMS IRQ system
|
||||
*/
|
||||
BSP_rtems_irq_mng_init(0);
|
||||
|
||||
/* Activate the page table mappings only after
|
||||
* initializing interrupts because the irq_mng_init()
|
||||
* routine needs to modify the text
|
||||
*/
|
||||
if (pt) {
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Page table setup finished; will activate it NOW...\n");
|
||||
#endif
|
||||
BSP_pgtbl_activate(pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize VME bridge - needs working PCI
|
||||
* and IRQ subsystems...
|
||||
*/
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
printk("Going to initialize VME bridge\n");
|
||||
#endif
|
||||
/* VME initialization is in a separate file so apps which don't use
|
||||
* VME or want a different configuration may link against a customized
|
||||
* routine.
|
||||
*/
|
||||
BSP_vme_config();
|
||||
|
||||
#ifdef SHOW_MORE_INIT_SETTINGS
|
||||
ShowBATS();
|
||||
printk("Exit from bspstart\n");
|
||||
#endif
|
||||
}
|
||||
191
c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds
Normal file
191
c/src/lib/libbsp/powerpc/ep1a/startup/linkcmds
Normal file
@@ -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 . */
|
||||
}
|
||||
142
c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c
Normal file
142
c/src/lib/libbsp/powerpc/ep1a/vme/vmeconfig.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/* Standard VME bridge configuration for VGM type boards */
|
||||
|
||||
/* Author: Till Straumann <strauman@slac.stanford.edu>, 3/2002 */
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/VME.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <libcpu/bat.h>
|
||||
#include <libcpu/spr.h>
|
||||
#include <bsp/motorola.h>
|
||||
|
||||
/* Use a weak alias for the VME configuration.
|
||||
* This permits individual applications to override
|
||||
* this routine.
|
||||
* They may even create an 'empty'
|
||||
*
|
||||
* void BSP_vme_config(void) {}
|
||||
*
|
||||
* which will avoid linking in the Universe driver
|
||||
* at all :-).
|
||||
*/
|
||||
|
||||
void BSP_vme_config(void) __attribute__ (( weak, alias("__BSP_default_vme_config") ));
|
||||
|
||||
SPR_RO(DBAT0U)
|
||||
|
||||
extern unsigned32 VME_Slot1;
|
||||
|
||||
void
|
||||
__BSP_default_vme_config(void)
|
||||
{
|
||||
union {
|
||||
struct _BATU bat;
|
||||
unsigned long batbits;
|
||||
} dbat0u;
|
||||
|
||||
vmeUniverseInit();
|
||||
vmeUniverseReset();
|
||||
|
||||
/* setup a PCI area to map the VME bus */
|
||||
|
||||
dbat0u.batbits = _read_DBAT0U();
|
||||
|
||||
/* map VME address ranges */
|
||||
vmeUniverseMasterPortCfg(
|
||||
0,
|
||||
VME_AM_EXT_SUP_DATA,
|
||||
_VME_A32_WIN0_ON_VME,
|
||||
_VME_A32_WIN0_ON_PCI,
|
||||
0x0F000000);
|
||||
vmeUniverseMasterPortCfg(
|
||||
1,
|
||||
VME_AM_STD_SUP_DATA,
|
||||
0x00000000,
|
||||
_VME_A24_ON_PCI,
|
||||
0x00ff0000);
|
||||
vmeUniverseMasterPortCfg(
|
||||
2,
|
||||
VME_AM_SUP_SHORT_IO,
|
||||
0x00000000,
|
||||
_VME_A16_ON_PCI,
|
||||
0x00010000);
|
||||
|
||||
#ifdef _VME_DRAM_OFFSET
|
||||
#if 0
|
||||
if (VME_Slot1){
|
||||
/* map our memory to VME */
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", BSP_mem_size);
|
||||
vmeUniverseSlavePortCfg(
|
||||
0,
|
||||
VME_AM_EXT_SUP_DATA,
|
||||
_VME_DRAM_32_OFFSET1,
|
||||
PCI_DRAM_OFFSET,
|
||||
BSP_mem_size);
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A24_SIZE);
|
||||
vmeUniverseSlavePortCfg(
|
||||
1,
|
||||
VME_AM_STD_SUP_DATA,
|
||||
_VME_DRAM_24_OFFSET1,
|
||||
PCI_DRAM_OFFSET,
|
||||
_VME_A24_SIZE);
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A16_SIZE);
|
||||
vmeUniverseSlavePortCfg(
|
||||
2,
|
||||
VME_AM_SUP_SHORT_IO,
|
||||
_VME_DRAM_16_OFFSET1,
|
||||
PCI_DRAM_OFFSET,
|
||||
_VME_A16_SIZE);
|
||||
}
|
||||
else {
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", BSP_mem_size);
|
||||
vmeUniverseSlavePortCfg(
|
||||
0,
|
||||
VME_AM_EXT_SUP_DATA,
|
||||
_VME_DRAM_32_OFFSET2,
|
||||
PCI_DRAM_OFFSET,
|
||||
BSP_mem_size);
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A24_SIZE);
|
||||
vmeUniverseSlavePortCfg(
|
||||
1,
|
||||
VME_AM_STD_SUP_DATA,
|
||||
_VME_DRAM_24_OFFSET2,
|
||||
PCI_DRAM_OFFSET,
|
||||
_VME_A24_SIZE);
|
||||
printk("vmeUniverseSlavePortCfg length of 0x%x\n", _VME_A16_SIZE);
|
||||
vmeUniverseSlavePortCfg(
|
||||
2,
|
||||
VME_AM_SUP_SHORT_IO,
|
||||
_VME_DRAM_16_OFFSET2,
|
||||
PCI_DRAM_OFFSET,
|
||||
_VME_A16_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* make sure the host bridge PCI master is enabled */
|
||||
vmeUniverseWriteReg(
|
||||
vmeUniverseReadReg(UNIV_REGOFF_PCI_CSR) | UNIV_PCI_CSR_BM,
|
||||
UNIV_REGOFF_PCI_CSR);
|
||||
#endif
|
||||
|
||||
|
||||
/* stdio is not yet initialized; the driver will revert to printk */
|
||||
vmeUniverseMasterPortsShow(0);
|
||||
vmeUniverseSlavePortsShow(0);
|
||||
|
||||
/* install the VME insterrupt manager */
|
||||
vmeUniverseInstallIrqMgr(0,5,1,6);
|
||||
if (vmeUniverse0PciIrqLine<0)
|
||||
BSP_panic("Unable to get interrupt line info from PCI config");
|
||||
_BSP_vme_bridge_irq=BSP_PCI_IRQ_LOWEST_OFFSET+vmeUniverse0PciIrqLine;
|
||||
}
|
||||
Reference in New Issue
Block a user